I'm currently building a web app called Revu using Bubble.io and today I wanted to add the functionality to take subscription payments. I've never integrated any kind of payments into Bubble before (I've only been using it since October) so this was a journey of discovery. I didn't really find any good tutorials so I thought I'd write down my steps in case it's helpful to anyone else.
A quick overview of the app I'm building
A quick overview of Revu for those who are interested - it's an app which makes collecting feedback on video content easier. The user uploads a video > inputs email address of people to get feedback from > these people click a link in the email and watch the video > as they type comments, the video automatically pauses and restarts when they press enter > all comments are time-tagged to the moment they started typing. The user gets a video with all the combined time-tagged comments from the people they invited.
The initial use case is pretty niche - for people learning sign-language to get feedback on their signing from their teacher. But my wife, who's a filmmaker, has already said she would use it with clients to get edits annotated, so that's another future market.
Now down to business...
Implementing payments using Stripe
1. Setting up the plugin
I'd initially read on the Bubble Forum that the plugin Stripe.js was the best way to implement payments, but after installing it I found that there was absolutely zero documentation (shocking!) and the only tutorial I could find on YouTube was outdated.
After a bit of digging around I realised that Bubble has its own Stripe plugin which seemed to offer everything I needed.
After installing it I set up my Stripe account, which is quite simple, and then found the API keys, which connect your Stripe account to the Stripe plugin on your Bubble account.
There are two types of API key you need: Publishable key and Secret key. I'm currently in Test mode on Stripe so these both start with the word "test". You copy and paste these into the corresponding places on the plugins page of your Bubble app. I put them in the development section as I'm currently just testing the app. When I put it live I will need to get my live IDs from Stripe and put them in the right place.
As I understand it, Client ID is only needed if you are operating a marketplace where one user is paying another. In my case they're just paying me (hopefully), so I left that bit blank.
2. Setting up my subscription plans
For the purposes of testing I made up three different plans. I may stick with them, I may not, but really it was just to test if I could get Stripe to work. I created a data type called Plan in Bubble with the below fields. I included one called stripeId so I could easily link it to the plans I create in Stripe (you need to create them in both places).
I have three plans as follows:
I then needed to create the same plans in Stripe. This wasn't quite as intuitive as it should be but it's not difficult.
I needed to go to Billing > Products > Create a new product (I named this Revu as that's what the site is called) > Add a pricing plan. The resulting page is shown below. As you can see, there are only a couple of fields that need filling out, in my case the:
- Plan nickname
- Price per unit
I repeated the steps for the other two plans. Each one was automatically assigned an ID by Stripe.
3. Setting up the workflows
This part is beautifully simple. On my subscriptions page in the app I have a custom state set up called selectedPlan and when a user clicks on one of the three plans it changes the selectedPlan state to that plan. I only just learnt about states today and already it's super useful, so if you want me to write a post about that please let me know.
But the custom state isn't necessary, you could just as easily use a dropdown box for the user to select the plan.
Please note: for these to work your user needs to be signed in the Bubble app already as the workflows work on the current user.
So once the user has selected a plan they click on a confirm button, and this triggers the following workflow.
When you click "Click here to add an action" you'll notice a load of new options in the Payment menu. The first one I used is Collect the user's CC information.
The options are almost none. The most important thing to know is - you can ignore where it says "Enter your API Key". I spent ages clicking that button and seeing that I already had my API key entered and then Googling the issue. It turns out you can just ignore it, it will still work. Hopefully Bubble will remove it in the future to avoid confusion!
The second workflow is Subscribe the User to a Plan. My options are shown below. The main ones are:
- I've chosen to dynamically specify the plan because I want it to vary depending on which one the user has selected. In this case I refer to my custom state (selectedPlan) and within that the stripeId field which I previously updated to match the Stripe ID generated by Stripe for each plan.
- (Optional) I also included a text input field for discount coupons and created a coupon on my Stripe dashboard to see if it worked. It did! So in my options I refer to the Coupon ID that was entered into that input field. If it matches the one in Stripe then the discount should work.
4. Testing and seeing the results in Stripe
This is the exciting part. I preview the test version of my app and log in so that I have a current user. I select a plan and click confirm.
This shows a popup which takes my card details (below). For Stripe test transactions use their test credentials:
- Card number: 4242424242424242
- Expiry: Any date in the future
- CVC: Any number
- Zip code: Anything
I then see a success dialog box.
I check my Stripe dashboard and sure enough there is a payment there.
Clicking on the customer email address I can see that I am subscribed to the plan as expected (I've been playing around a bit so you can see I also managed to update my subscription).
I also tested this with a discount code and it worked perfectly.
5. Showing customer subscription information and allowing them to cancel
Once I had setting up a subscription working I wanted to enable customers to view what plan they were on and cancel if needed.
This turned out to be really simple.
I added a regular text field in Bubble and chose add dynamic data > Current User. There are suddenly a load of options to display Stripe data.
Within Stripe Customer's subscription were more options:
Using these I put together a passage of text that provided information to the user.
The resulting text looks like this:
The cancel subscription button simply uses the payment workflow option "Cancel the current user's plan".
That's as far as I've got with implementing subscriptions in my app. I will update this post if I find any errors or when I go live and have it working for real. Likewise if anyone reads this and thinks "this guy has made a right mess of this" please let me know.
I hope it's useful. Please subscribe to my mailing list to hear more about my continued adventures in no-code.