Payments (Stripe)

Payments (Stripe)

The Payments module in CodebaseUp brings seamless Stripe billing to your application. This documentation outlines the features introduced, the billing flow, and the steps to set up and use the module.

This module leverages the power of Stripe. Instead of developing all features internally (which can take time and be somewhat risky if not approached thoroughly), it seamlessly integrates with Stripe, performing checkout and providing access to the billing portal directly on Stripe while maintaining a tight connection to your app's flow. This approach ensures a robust and efficient billing experience for your users.

Billing Flow

If the user is authenticated, they proceed to checkout via client-side redirect.

If the user is not authenticated, authentication is facilitated using built-in methods (e.g., magic link, Google) docs, followed by a server-side redirect to checkout.

Features

1. Webhooks

The web app provides an API endpoint /api/stripe/webhooks that monitors webhook events from Stripe.

Currently, it handles product and price creation, with upcoming updates set to include additional events (e.g., product/price updates, subscription-related events). This allows for maintaining synchronized data (product/price) in our database for efficient access (you can still access other data directly via Stripe API if needed).

2. Checkout Session

A short-lived Stripe checkout session (hosted by Stripe) to facilitate the completion of purchases.

3. Billing Portal Session

A short-lived Stripe billing portal session (hosted by Stripe) is provided to manage billing details, including personal details, payment information, and subscriptions.

Activation

  1. Make sure the Authentication module works (remember, authentication must be performed first).
  2. Open a Stripe account
  3. Add STRIPE_SECRET_KEY to your .env.local file (the testing one by having the "Test Mode" toggle switched on).
  4. Install Stripe CLI official docs. I recommend authenticating manually by running stripe login --api-key sk_test_****** to make sure you use the right Secret key (the testing one from the previous step).
  5. Activate the Stripe webhook listener - from apps/web folder, run pnpm run stripe:listen. It will print a webhook secret (such as, whsec_***) to the console. Set STRIPE_WEBHOOK_SECRET to this value in your .env.local file.
  6. The Stripe webhook listener forwards all Stripe events to localhost:3000/api/stripe/webhooks. Therefore, our web app must run too. Launch it by pnpm run dev --filter=web.
  7. Add products and prices. As both the webhook listener and the web app are running, you can create products and prices directly from the Stripe dashboard and it'll get captured by the web app (it'll create products/prices in a database). Alternatively, you can run fixtures from the new payments package - cd packages/payments && pnpm run stripe:fixtures - it's an easy way how to populate both Stripe and your database by sample data.
  8. Configure the Stripe Customer Portal
  9. Give the Payment module a spin. Launch http://localhost:3000, visit Payments from the Navbar and click on the product price button. Then proceed with authentication/checkout and verify the successful payment by visiting the billing portal or the Stripe dashboard.

When in testing mode, use testing credit card details provided by Stripe.

Visa: 4242424242424242
CVC: Any 3 digits
Date: Any future date

Production setup

  1. Use production environment variables - The SECRET_KEY can be found on Stripe (API keys)

  2. Make sure to set up NEXT_PUBLIC_APP_URL so the back-button redirects from Stripe (checkout & billing portal) to your app works well.

  3. Set up the hosted webhook endpoint (not needed for localhost development). Direct Stripe to your API endpoint:

    https://your-domain.com/api/stripe/webhooks

    Add the given signing secret as STRIPE_WEBHOOK_SECRET to your environment variables.

When you change environment variables, you must redeploy your application. On localhost, simply restart the development server.

Demo

Run the codebase locally and access Payments at:

http://localhost:3000/payments

Configurations:

  • Fixtures & Stripe instance: /packages/payments/providers/stripe
  • Stripe API endpoints: apps/web/app/api/stripe/
  • Demo Payments page: apps/web/app/[locale]/payments/
  • Redirect middleware: apps/web/middlewares/redirects.ts
  • Database schema: packages/database/prisma/schema.prisma