Stripe is used to handle payments, invoicing, customer portals, subscriptions and more. The standard database schema comes with a stripeCustomerId field on the User model, so you can easily relate payments and subscriptions to users.

Please, read how Stripe works at stripe.com/docs, to learn about webhooks, checkout_session, “test mode” and more.

Setting up Stripe

1

Create a Stripe account

2

Activate payments

You’ll need to activate payments on your account. You’ll need to be registered as a business (anywhere on earth), and you’ll need to provide some details about your business.

3

Branding, Emails, Customer Portal

  • In Settings > Branding you can set your logo and colors
  • In Settings > Customer Emails turn on emails for successful payments and refunds.
  • In Settings > Customer Portal turn on the customer portal, (users can manage their subscriptions and payment methods and view invoices here)
4

Add webhooks endpoint

In Developers > Webhooks add a webhook with the url https://[YOUR DOMAIN]/api/webhooks/stripe and select the events you want to receive (see below).

  • Testing: enable test mode and use the Stripe CLI to enable webhooks on your local machine. Follow their guide here for more info.
5

Copy keys to .env

In Developers > API Keys copy the keys to your .env file. The webhook secret is found in the Webhooks section. Make sure you use the test keys when in test mode and the live keys when in production.

.env
PRIVATE_STRIPE_SECRET_KEY=sk_test_1
PRIVATE_STRIPE_WEBHOOK_SECRET=whsec_1
PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_1

Webhooks

Webhooks are used to receive events from Stripe, like when a payment is made or a subscription is cancelled. Some commonly used events are added in the src/routes/api/webhooks/stripe/+server.ts file.

src/routes/api/webhooks/stripe/+server.ts
switch (event.type) {
    case 'checkout.session.completed': { // handle new payment (one-time or subscription)
        const checkoutSession = event.data.object;
        break;
    }
    case 'checkout.session.expired': { // handle expired payment
        const checkoutSession = event.data.object;
        break;
    }
    case 'customer.created': { // handle new customer
        const customer = event.data.object;
        break;
    }
    case 'customer.source.expiring': { // handle expiring card, notify user
        const customerCardOrSource = event.data.object;
        break;
    }
    case 'customer.subscription.deleted': { // handle cancelled subscription, revoke access, send winback email
        const subscription = event.data.object;
        break;
    }
    case 'customer.subscription.updated': { // handle subscription changes, revoke access, notify user
        const subscription = event.data.object;
        break;
    }