Theo's easy and simple way to integrate Stripe
Jan 26, 2025
Ayush, Autumn Co-Founder
This is the easiest way to integrate Stripe, popularized by youtuber Theo Browne. It syncs all Stripe data to your database with 1 function.

This article is based on Theo Browne's method for integrating Stripe—huge credit to him. Follow him on Twitter @theo and check out his site.
Stripe's APIs are powerful, low-level blocks that enable us to bill in any way we want.
Unfortunately, this makes integration pretty painful. Theo Browne summarises the problem best:
IMO, the biggest issue with Stripe is the "split brain" it inherently introduces to your code base. When a customer checks out, the "state of the purchase" is in Stripe. You're then expected to track the purchase in your own database via webhooks.
There are over 258 event types. They all have different amounts of data. The order you get them is not guaranteed. None of them should be trusted. It's far too easy to have a payment be failed in stripe and "subscribed" in your app.
Here's how he does it. At the end you can check out what we've built at Autumn to make this 10x easier.
Overall Flow
Here's the easiest way of going about it, making use of the functions in his GitHub repo. The overall flow is:
User clicks "Subscribe" button on frontend, triggering backend endpoint to generate Stripe checkout
Backend creates Stripe customer, stores customerId/userId mapping in database
Backend creates checkout session, returns it to frontend
User completes payment, gets redirected to /success page
/success page triggers backend to sync Stripe data for that customer
Backend fetches customerId from database (referred to as key-value/KV store), and syncs latest data from Stripe API using
syncStripeDataToKV
After sync, frontend redirects user to final destination
On all relevant Stripe webhook events, sync again via
syncStripeDataToKV
Customer Checkout
Authenticate user and get their ID
Check database for existing Stripe customer ID for this user
If no customer ID found, create a new Stripe customer and store the ID in the database, mapped to the user ID
Create a Stripe Checkout session using the customer ID
Return the session data to the frontend
Sync Stripe Data
This is the function that will be used to sync Stripe subscription status with your application. We'll use it in the next step when we're processing webhook events.
Fetch the latest subscription data for the given customer ID from Stripe's API
If no subscriptions found, store an empty state object in the database
If subscriptions found, extract the relevant fields (subscription ID, status, price ID, billing period, payment method details)
Store the subscription data object in the database, keyed by the customer ID
Return the subscription data
Listening to webhook events
Define a list of relevant subscription-related event types to handle
When a webhook is received, call this function to check if the received event type is in the list of relevant events
If so, extract the customer ID from the webhook payload
Call the
syncStripeDataToKV
function to update the customer's subscription data in the database
/success
endpoint
While this isn't 'necessary', there's a good chance your user will make it back to your site before the webhooks do. It's a nasty race condition to handle. Eagerly calling syncStripeDataToKV
will prevent any weird states you might otherwise end up in.
This doesn't solve everything…
Maintaining billing is hard. This guide only applies to simple subscriptions and there are still some things you have to deal with:
Managing STRIPE_SECRET_KEY
and STRIPE_PUBLISHABLE_KEY
env vars for both testing and production
Managing
STRIPE_PRICE_ID
s for all subscription tiers for dev and prod (I can't believe this is still a thing)Exposing sub data from your KV to your user (a dumb endpoint is probably fine)
Tracking "usage" (i.e. a user gets 100 messages per month)
Managing "free trials" ...the list goes on
This is pretty easy, but Autumn made it 10x easier
Transparently, we wrote this article because we've built a system to make this stupidly simple. With Autumn, you can define any pricing model you want (subscriptions, usage-based, credits, add-ons etc) and handle all the logic in 4 steps.
Define your pricing models in our dashboard
Get a stripe checkout URL with
/attach
Check if a user can access a feature with
/check
Track any usage with
/track
Hundreds of builders and fast growing startups use Autumn because we take care of everything— so you can spend more time building what matters.
Give Autumn a try if you're interested!