Documentation Index
Fetch the complete documentation index at: https://docs.builderbox.ai/llms.txt
Use this file to discover all available pages before exploring further.
Note: This guide walks you how we setup stripe in the boilerplate. you don’t need to implement it in the boiler plate since its already implemented.
Prerequisites
- A Stripe account (Sign up at stripe.com)
- Go to your dashboard top right corner and turn on test mode
- Create a product in the dashboard
- Required environment variables: in
apps/server/.env
STRIPE_SECRET_KEY=your_stripe_secret_key
NEXT_PUBLIC_STRIPE_PRODUCT_PRICE_ID=your_product_price_id
Installation
Install the required dependencies:
bun add @better-auth/stripe stripe @stripe
Server-Side Configuration
- Initialize the Stripe client: in
apps/server/src/lib/stripe.ts
import Stripe from "stripe";
export const stripeClient = new Stripe(process.env.STRIPE_SECRET_KEY!, {
apiVersion: "2023-10-16",
});
- Configure BetterAuth with Stripe plugin: in
apps/server/src/lib/auth.ts
import { betterAuth } from "better-auth";
import { stripe } from "@better-auth/stripe";
export const auth = betterAuth({
plugins: [
stripe({
stripeClient,
createCustomerOnSignUp: true,
subscription: {
enabled: true,
plans: stripeProduct.map((product) => ({
name: product.plan,
priceId: product.priceId,
})),
getCheckoutSessionParams: () => ({
params: {
allow_promotion_codes: true,
},
}),
},
}),
],
});
Client-Side Configuration
Set up the auth client with Stripe support:
import { createAuthClient } from "better-auth/react";
import { stripeClient } from "@better-auth/stripe/client";
export const authClient = createAuthClient({
baseURL: process.env.NEXT_PUBLIC_SERVER_URL!,
plugins: [
stripeClient({
subscription: true,
}),
],
});
Product Configuration
Define your products in a configuration file: in apps/server/src/utils/stripeProduct.ts
// src/utils/stripeProduct.ts
export const stripeProduct = [
{
plan: "Basic",
priceId: "price_basic",
features: ["Feature 1", "Feature 2"],
},
{
plan: "Pro",
priceId: "price_pro",
features: ["Feature 1", "Feature 2", "Feature 3"],
},
];
// better auth handles webhooks for you already. but if you want to handle them manually, you can do so by creating a webhook handler in apps/server/src/lib/auth.ts
Webhook Handling
The plugin automatically handles common webhook events:
checkout.session.completed: Updates subscription status after checkout
customer.subscription.updated: Updates subscription details when changed
customer.subscription.deleted: Marks subscription as canceled
You can also handle custom events:
in apps/server/src/lib/auth.ts
stripe({
// ... other options
onEvent: async (event) => {
// Handle any Stripe event
switch (event.type) {
case "invoice.paid":
// Handle paid invoice
break;
case "payment_intent.succeeded":
// Handle successful payment
break;
}
}
})
Managing Subscription
Users can manage their subscription through the Stripe Customer Portal:
const portalUrl = await authClient.createPortalSession();
window.location.href = portalUrl;
UI Components
The boilerplate includes pre-built UI components for Stripe integration:
// Example subscription status display
<Card>
<CardHeader>
<CardTitle>Stripe Subscription</CardTitle>
<CardDescription>
Your current subscription details
</CardDescription>
</CardHeader>
<CardContent>
{/* Subscription details */}
</CardContent>
</Card>
Common Issues
-
Webhook Signature Verification
- Ensure the webhook secret is correctly set
- Verify the signature in the webhook handler
-
Subscription Status Sync
- Implement proper webhook handling
- Update the database on subscription changes
-
Checkout Session
- Set correct success and cancel URLs
- Handle failed payments gracefully
Next Steps