Mike Stowe
Jan 15 · 5 min read

Life happens. We’ve all (at least I hope it’s not me) forgotten about a bill (such as our cell phone), or to update our account after receiving a new card.

But from a business standpoint, these forgotten or late payments are not just inconveniences, they’re downright expensive — with late payments costing businesses around $3 billion globally each year!

But what if we could make the process a little bit easier — for everyone. What if you could let customers pay with their already stored payment information on a provider like Stripe — via SMS?

The best part is — it’s super easy to do! Although, if you haven’t tried our first PHP tutorial on sending and receiving SMS messages, you may want to start here first.

Step 1: Pull in SDKs, Setup Auth

First let’s create a file called “pastdue.php” and pull in the SDK libraries/ setup our authentication.

You can install the RingCentral SDK and the Stripe SDK via Composer. Then you can call in each using vendor/autoload.php, like so:

<?php
// File: pastdue.php
require_once('vendor/autoload.php');// Auth for Stripe
\Stripe\Stripe::setApiKey(MY_STRIPE_API_KEY);
// Auth for RingCentral
$sdk = new RingCentral\SDK\SDK(CLIENT_ID, CLIENT_SECRET, RingCentral\SDK\SDK::SERVER_SANDBOX);
if (!$sdk->platform()->loggedIn()) {
$sdk->platform()->login(username, extension, password);
}

Step 2: Find Past-Due Invoices

Using Stripe’s APIs we can find invoices that are two days past due. We could repeat this step if we wanted to do a reminder at 5 days, 7 days, etc.

$invoices = \Stripe\Invoice::all(['due_date' => ['gt' => strtotime('-2 days')], "billing" => "send_invoice"])['data'];

Step 3: Get Customer Phone Number

With the invoices we also have the customer’s Stripe ID. Using a lookup table we can pull either their RingCentral contact ID, our CMS ID, or other identifiable information to retrieve their name and cell phone number from our records.

To simplify things for this tutorial, I’m going to pretend I have a function that does just that:

foreach ($invoices as $invoice) {
// Do not send if invoice paid
if ($invoice->paid) { continue; }
$name = getNameByStripeCust($invoice->customer);
$phone = getPhoneNoByStripeCust($invoice->customer);
if (!$name || !$phone) { die('customer not found'); }

Step 4: Send the Text

Now we can send the text to our customers, giving them a friendly reminder that their payment is past due:

  $data = [
'from' => ['phoneNumber' => RINGCENTRAL_NUMBER],
'to' => [['phoneNumber'] => $phone]],
'text' => 'Hi '.$name.', it looks like you forgot to pay your bill. But no worries, you can pay $'.($invoice->amount_due/100).' with your card on file by replying with "PAY NOW"';
$sdk->platform()->post('/account/~/extension/~/sms', $data);
}
echo 'Past Due Customers Notified';// END pastdue.php
?>

Note, with Stripe’s API you can do even more, such as get the last four numbers of their default card, or provide different payment options (such as paying online, choosing a card on file, etc).

Step 5: Receive the Response

Step 5a: Create our Webhook Script

To receive the response, we first need to create a file to receive the incoming text. We’ll call this file “payviatext.php

For this file we’ll include the appropriate SDKs, authenticate, perform the webhook handshake, and then get incoming content.

First to include the SDKs and handle authentication (just like in our previous file):

<?php
// File: payviatext.php
require_once('vendor/autoload.php');// Auth for Stripe
\Stripe\Stripe::setApiKey(MY_STRIPE_API_KEY);
// Auth for RingCentral
$sdk = new RingCentral\SDK\SDK(CLIENT_ID, CLIENT_SECRET, RingCentral\SDK\SDK::SERVER_SANDBOX);
if (!$sdk->platform()->loggedIn()) {
$sdk->platform()->login(username, extension, password);
}

Now we can add the handshake check (RingCentral requires the script to send back a validation token to ensure it is talking to the right script):

// RingCentral Webhook Validation
if (!empty($_SERVER['HTTP_VALIDATION_TOKEN'])) {
header('Validation-Token: '.$_SERVER['HTTP_VALIDATION_TOKEN']');
}

And now we can get the incoming content, specifically being concerned with the phone number it is from, and their response:

$incoming = file_get_contents("php://input");// Sanity Check
if (empty($incoming)) { die('nothing here'); }
// Decode JSON
$incoming_data = json_decode($incoming);
$phone = $incoming_data->body->from->phoneNumber;
$text = $incoming_data->body->subject;
// Validate Message
if(strtolower($text) != 'pay now') { die('did not want to pay'); }

Step 5b: Activate the Webhook

Ooops — I forgot to add this. Will add in a bit :)

Step 6: Check if Payment is Due — And Apply!

Now that we know the incoming message says “PAY NOW,” the last thing we need to do is double check the invoice, apply the payment, and send them a confirmation.

To do this, we can create reverse lookup functions (just as we did to get the phone number by the stripe ID) and find their invoices, like so:

$customer = getStripeCustByPhone($phone);if (!$customer) { die('customer not found'); }$invoices = \Stripe\Invoice::all(['due_date' => ['gt' => strtotime('-2 days')], "billing" => "send_invoice", "limit" => 1, "customer" => $customer]);if (!$invoices || !isset($invoices['data'][0]['id']) {
die('no invoice found, nothing to do');
}

Now that we have their invoice ID, we can use Stripe’s Invoice class to pay the invoice using their default payment method:

$invoice = \Stripe\Invoice::retrieve($invoices['data'][0]['id']);
$invoice->pay();

And finally, text the user to let them know their invoice has been paid (of course you might want to add some sanity checks to ensure the payment was successful first).

$data = [
'from' => ['phoneNumber' => RINGCENTRAL_NUMBER],
'to' => [['phoneNumber'] => $phone]],
'text' => 'Thank you. A payment of $'.$invoices['data'][0](['amount_due']/100).' has been applied to your account';
$sdk->platform()->post('/account/~/extension/~/sms', $data);

Disclaimer

This is a very quick tutorial to demonstrate how quick and easy it is to use the Stripe API along with RingCentral’s API to automate message based payments.

But it shouldn’t be viewed as a production level example of what your company needs — instead you should make sure you build in the appropriate systems to ensure your users want to receive SMS messages, track correspondences including ensuring the invoice they’re paying is the one you messaged them about (since a new invoice could be created between now and the time they reply), and that you take into account all security requirements (including PCI).

In other words — check with your legal and engineering teams to make sure everything is developed correctly ;)

Optional — Don’t Forget to Automate the Process

Keep in mind this script gets run every time it’s called, and it has to be called manually. It’s a much better idea to setup a cronjob, and also put a PHP_SAPI check to ensure it is only being called via the command line (PHP_SAPI == ‘cli’).

$crontab -e0 13 * * * php /path/to/pastdue.php

RingCentral Developers

Cloud Business Communications

Mike Stowe

Written by

Developer, actor, and a *really* bad singer. Fan of APIs, Microservices, and #K8s.

RingCentral Developers

Cloud Business Communications

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade