Learn how to integrate Stripe with SvelteKit and Lucia Auth to create a subscription-based website.
Live Demo First, start by cloning this folder. We will use tiged
for cloning subdirectories in Git repositories.
code loading...
Next, install the dependencies:
pnpm i
You will need to create a .env
file in the root of the project. There is an .env.example
file that you can use as a template.
The .env
file should contain the following variables:
SQLITE_DB_URL
: The URL of the SQLite database.
TURSO_AUTH_TOKEN
: The Turso authentication token.
STRIPE_WEBHOOK_SECRET
: The secret key for the Stripe webhooks.
STRIPE_SECRET_API_KEY
: The secret key for the Stripe API.
STRIPE_CHECKOUT_SUCCESS_PATH
: The path to redirect to after a successful checkout.
STRIPE_CHECKOUT_CANCEL_PATH
: The path to redirect to after a canceled checkout.
The first step is to create some products in Stripe. This integration uses Stripe subscriptions (at the difference of one-time payments).
Make sure to set the products types to “Recurring”.
Once that's done, update the src/lib/products.ts
file with the product IDs, prices, intervals, etc.
In development, run pnpm stripe:listen
to start the Stripe webhook listener. This will forward the webhooks to the webhooks' endpoint in the application at /api/stripe/webhooks
. It will also output a test webhook secret to the console that you can use as the value for the STRIPE_WEBHOOK_SECRET
environment variable.
In production, you will need to set up a webhook listener in your Stripe dashboard by going to Developers > Webhooks.
From there, create a new webhook endpoint, and set the endpoint URL to your-production-app-url/api/stripe/webhooks.
They are a few events that the application will listen to:
customer.subscription.created
customer.subscription.updated
customer.subscription.deleted
customer.subscription.paused
customer.subscription.resumed
You can either specifically listen to these events, or listen to all events.
After creating the webhook, you will get a signing secret that you can use as the value for the STRIPE_WEBHOOK_SECRET
environment variable in production.
Stripe allows you to create products, customers, subscriptions, API keys, webhooks, etc. in both test and production environments.
So, depending on the environment you are in, make sure to use the correct values for the environment variables and the prices IDs for the products.
To start, here is what the database schema looks like:
code loading...
In addition to the users
and sessions
tables for a classic authentication system, we also have a stripe_customers
table that stores the Stripe customer IDs and subscription IDs for each user.
When the user signs up to the application, we create a new Stripe customer (in Stripe) and add it to the stripe_customers
table. This new customer is associated with the user's ID in the users
table.
The product and pricing are displayed on the /pricing
page, and the user can choose which plan they want to subscribe to. When they click on the “Buy” button, we create a new subscription in Stripe for the selected plan, and update the stripe_customers
table with the new subscription ID.
There is a /success
page that is displayed after a successful checkout. There is also a /cancel
page that is displayed after a canceled checkout. Both of these pages can be customized to display different content and styles.
Learn how to create an AI Chatbot with OpenAI, SvelteKit, SQLite and Vercel AI SDK
Use Google OAuth 2.0 to authenticate users in your SvelteKit app
Authentication with email and password
This recipes uses Cloudflare R2 for uploading and storing assets in the cloud. Cloudflare R2 is a S3 compatible object storage service that is optimized for performance and cost efficiency.