User Avatar

Checkout

StartStack uses Stripe Checkout for the checkout process. Specifically it uses the embedded mode, which allows you to customize the checkout page to match your branding and it ensures the user never leaves your site.

Let's take a look at how this all works.

First we create a checkout session. You can find this function in the /services/checkout.ts file. To create a checkout session for a particular price, you simply route the user to the /checkout page with the price ID as a query parameter. For example:

/checkout?p=price_123

This will create a checkout session for the price with ID price_123. The /app/(marketing)/checkout/page.tsx React Server Component simply calls the service, that creates the checkout session and returns the clientSecret that is then passed into the EmbeddedCheckout component.

// create a checkout session
const { clientSecret, status } = await checkout.sessions.create({
priceId: p,
})
if (status === "requiresSession") {
redirect(`/sign-in?redirectTo=/checkout?p=${p}`)
}

Note: If the user is subscribing to a plan they will need to have a valid session. If they don't they will be redirected to the sign-in page and redirected back to the checkout page once they have signed in/up. If the user is making a one time purchase they will not be required to sign in and will be able to complete the purchase immediately.

Once the user finishes the checkout process, they will be redirected to the thank you page located at /app/(marketing)/checkout/thank-you/page.tsx. If the user did not have a session while starting the checkout process they will receive a magic link sent to the email they entered during the stripe checkout to sign in and then be redirected to their account.

You could of course change this behavior to require a session for one time purchases, but if you don't need to do that I recommend leaving it as is. The less friction the better when it comes to purchases. For a subscription purchase users are accustomed to signing up as part of the purchase process.

While all this is going on, after the user completes the checkout process, Stripe will fire off several events that the webhook handler will pick up. The primary one in this instance that we are listening for is the checkout.session.completed event. This is fired off anytime a checkout session completes successfully. We use this event to save all the relevant data associated with the purchase into the database. You can view / customize this business logic in the /services/checkout.ts file. See: checkout.sessions.complete({ sessionId }: { sessionId: string }).

  • To learn more examine the /services/checkout.ts service, as it is well documented.
  • Also learn more about creating a checkout session and all the available options in the Stripe docs.
  • Be sure to checkout the checkout.session.completed event in the Stripe docs.
  • Finally, learn about Stripe Checkout in general here.