Stripe SMS Notifications via Twilio, Heroku, and Python
Time to read: 7 minutes
I recently started a small business using the online platform Storenvy. Storenvy integrates with Stripe, a popular online payments platform. As a small business owner, receiving notifications as soon as orders come in is critical.
Emails are easy to miss, forget about, or overlook, but one thing I never fail to read is a text message. What if it were possible to receive a text message every time my store makes a sale?
Neither Storenvy nor Stripe have SMS notifications built into their platforms, so let’s build a custom SMS notification system using Twilio, Heroku, and Python.
Note: If you’re only interested in the code, it can be found on Github here, along with a “Deploy to Heroku” button.
What You’ll Need- git – Git will handle source control and make Heroku deployments easier.
- Python 3.6 – Heroku’s supported Python runtimes are python-2.7.13 and python-3.6.0. I’ll be using Python 3, although the Python 2 code should be the same.
- ngrok – ngrok will let us create secure tunnels to our local machine. (See download instructions)
- A Heroku account. We’ll only be needing the Free tier.
- A Twilio account. It’s free to sign up and the Free Trial will be sufficient.
- A Stripe account. Also free, other than transaction fees.
- (Recommended) virtualenv and virtualenvwrapper – These tools will allow us to create virtual Python environments to avoid cluttering our default environment. You can install these tools by running the following in your terminal (you may need to use sudo):
Getting Started
Here is an outline of what we’ll accomplish:
- Build a simple app to handle incoming POST requests using Flask and send outgoing text messages with Twilio.
- Use ngrok to securely tunnel to the Flask app.
- Configure a webhook on your Stripe account to point to your app.
- Deploy the app to Heroku and reconfigure the webhook to point the app in the cloud.
If you are are using virtualenvwrapper you should first set up a new Python environment using the following commands:
Your terminal prompt will prepend (stripe-sms-notifications) to every line to indicate the virtual environment you are currently in. If at any point you want to leave this virtual environment and return to your default Python environment, you can use the command $ deactivate and use the $ workon stripe-sms-notifications command to re-enter it.
With the environment ready, run the following command to install the Python packages we need:
The above command will install Flask, the micro-framework we are using to handle incoming requests, as well as the Twilio Python helper library and all of its dependencies.
Now in the editor of your choice create a new file named app.py. Add the following code:
At the top of the file we are importing the os
module, and two flask
modules, Flask
and request
. The os
module is needed to access environment variables, which you can see being used towards the bottom of the file and which we will also need when we import Twilio.
The app = Flask(__name__) and app.run(host='0.0.0.0', port=port) lines are creating and starting our Flask app, respectively. The most important lines are the ones in the middle.
- @app.route("/", methods=['POST']) represents a rule we are defining for our app’s routing system. Here we are handling
POST
requests sent to the/
route. - def receive_order(): defines the function that will handle requests sent to the route above. It does not take any arguments because we are not handling any URL parameters.
- return '', 200 simply returns a
200
response with an empty body.
Save this file and run python app.py
in the same directory that app.py
is located in. Your terminal should hang and the following line should be displayed:
Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
This means your Flask app was able to start without errors. We can test out our app by making some requests to it. With your app still running, open another, separate terminal and run the following command:
You’ll notice that you receive a 405 Method Not Allowed
response. This is fine because we set up our route to only accept POST
requests and we sent it a GET request. Use the following command to send a POST
request instead:
It will look like nothing happened because our app returned an empty response body. If you switch back to your other terminal you’ll notice that a POST
request was received and a 200 OK
response was returned. Our Flask app is ready to go.
The next step is to import Twilio into our app so that we can send outgoing SMS messages. If you have never worked with Twilio before it might help to first check out their Python Quickstart as we will borrow most of our code from there.
Open up app.py again and add the following lines:
At the top of the file we are importing the TwilioRestClient
and building a client object using our Twilio account credentials and phone numbers. Your account sid and auth token can be found in your Twilio console.
I’ve set my credentials as environment variables using the $ export
command. If you decide to hard-code your credentials, do not push your source code to a public github repo as it will expose them to the world.
The message = client.messages.create(...)
line uses the client
object to send an outgoing SMS with the given parameters.
Save the file again, restart the app, run your curl command ($ curl -d '' localhost:5000
), and check your phone. You should have received a text message from your Twilio number that says “Hello, World!” If you did not receive a text or your app displays an error, double check that you copy and pasted your Twilio credentials properly.
The next step is to configure an endpoint in our Stripe account to send data to our application.
If you want to know more about Stripe’s webhooks and how they work, check out their documentation or this blog post. Basically, webhooks allow you to send data to a specific URL whenever events involving your Stripe account occur.
But first we need to make our app publicly accessible so that it can be reached by Stripe. We are going to use ngrok to accomplish this. In a separate terminal run the following command:
Your terminal will transform into a window that looks similar to this:
Copy the first Forwarding URL to your clipboard (http://7dbabaa4.ngrok.io in this case, but yours will be different). This will be the URL we use to configure our Stripe webhook.
Go to your Stripe dashboard and select Webhooks -> Settings (or click here). You should see a menu that looks like this:
Select “+ Add endpoint…” and configure it like this (using the ngrok URL you copied):
We want to be notified whenever we receive a Stripe payment successfully, so the event we are interested in is charge.succeeded
. We’re also setting the “Mode” to “Test” so we don’t have to wait for actual payments to come in to test it.
In app.py
modify receive_order()
to look like this:
Here we are parsing the incoming request object as JSON and extracting Stripe’s amount
value from it. We have to divide amount
by 100 to convert from cents to dollars. This value gets concatenated to the string message_body
, which is then used as the body
of our outgoing SMS. Save this file one more time and restart your app.
All the Python code for our app is now finished and we can test it with Stripe. In your Stripe webhook settings select the “Send test webhook…” button. Use the endpoint we just created to send a charge.succeeded
event. You should see the message “Test webhook sent successfully” and receive a text message like in the image below:
Excellent! Now it’s time to deploy our app.
We are using Heroku in order to avoid the large hassle of renting, configuring, and securing our own server. If you’d like to use your own server, you can skip to the “Wrapping Up” section below.
If you are unfamiliar with the Heroku platform it might be a good idea to at least read through their Getting Started on Heroku with Python guide or check out other Twilio articles that feature Heroku.
However, you’ll find a list of all the commands you’ll need to run below followed by a brief explanation of what the commands are doing.
Make sure you have the Heroku CLI installed and then run the following commands:
Replace your_project_name
in the command above with whatever you want to name your app. You’ll have to come up with your own name because “stripe-sms-notifications” is already taken by me. Sorry!
The commands above create a Procfile, write our Python dependencies to requirements.txt
, initialize and commit all our files to a new Git repo, and create/deploy our app to Heroku.
Once the deployment finishes, run heroku ps:scale web=1
to assign a worker process for your app. (Read more about this step here.)
Finally, before we can send text messages we need to set a number of config vars for the app. Config vars are Heroku’s equivalent to environment variables. If you previously hard-coded your Twilio credentials you can skip this step.
Run the following commands to set all the necessary config vars, making sure to use your actual Twilio credentials.
Heroku will take care of restarting the app once the config vars are set.
Testing Our Heroku AppNow that your app is configured and deployed, head back to your Stripe webhook settings and edit the URL of your webhook to point to your Heroku app instead of your ngrok tunnel.
Send another test request using the “Send test webhook…” button as we did earlier. You should receive the same text message as before.
Now that your app is working and deployed to Heroku, we need to go back and tell Stripe to use live data instead of the test endpoints we’ve been working with.
We’ll need to create a new endpoint as Stripe will not allow to you edit an endpoint’s Mode after you set it. In your Stripe webhooks select “Add endpoint…”.
As seen below, set the URL to the URL of your Heroku app (remember that yours will be different than mine), set Mode to Live and select the charge.succeeded
event.
Note: If you are using your own server instead of Heroku, the URL field should point to your publicly accessible server.
Congratulations! You will now receive an SMS message every time you receive a payment via Stripe. Check your phone for those orders and start makin’ money!
Related Posts
Related Resources
Twilio Docs
From APIs to SDKs to sample apps
API reference documentation, SDKs, helper libraries, quickstarts, and tutorials for your language and platform.
Resource Center
The latest ebooks, industry reports, and webinars
Learn from customer engagement experts to improve your own communication.
Ahoy
Twilio's developer community hub
Best practices, code samples, and inspiration to build communications and digital engagement experiences.