Checkout
Create Stripe checkout sessions to collect payment and start subscriptions.
How Checkout Works
StackBE uses Stripe Checkout for secure, PCI-compliant payment collection:
- Your app creates a checkout session via StackBE API
- Redirect the customer to the Stripe-hosted checkout page
- Customer enters payment details on Stripe's secure page
- On success, Stripe redirects to your success URL
- StackBE receives the webhook and creates the subscription
Important: Always create checkout sessions through StackBE, not directly with Stripe. This ensures subscriptions are properly tracked with the right metadata.
Create Checkout Session
Create a checkout session and redirect the customer to complete payment.
Using the SDK
import { StackBE } from '@stackbe/sdk';
const stackbe = new StackBE({
apiKey: process.env.STACKBE_API_KEY!,
appId: process.env.STACKBE_APP_ID!,
});
// Create checkout session
const { url } = await stackbe.checkout.createSession({
// Customer identification (one of these required)
customerId: 'cust_abc123', // Existing customer ID
// OR
email: 'user@example.com', // Email for new customers
// Plan to subscribe to
planId: 'plan_pro',
// Redirect URLs
successUrl: 'https://yourapp.com/success?session_id={CHECKOUT_SESSION_ID}',
cancelUrl: 'https://yourapp.com/pricing',
});
// Redirect to Stripe Checkout
redirect(url);Via API
curl -X POST "https://api.stackbe.io/v1/checkout/session" \
-H "Authorization: Bearer sk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"customerId": "cust_abc123",
"planId": "plan_pro",
"successUrl": "https://yourapp.com/success",
"cancelUrl": "https://yourapp.com/pricing"
}'
# Response:
# { "url": "https://checkout.stripe.com/c/pay/cs_xxx..." }Apply Coupon Code
Apply a promo code to give customers a discount.
// With coupon code
const { url } = await stackbe.checkout.createSession({
customerId: 'cust_abc123',
planId: 'plan_pro',
couponCode: 'SAVE20', // 20% off coupon
successUrl: 'https://yourapp.com/success',
cancelUrl: 'https://yourapp.com/pricing',
});
// Validate coupon before checkout (optional)
const coupon = await stackbe.coupons.validate('SAVE20', {
planId: 'plan_pro',
});
if (!coupon.valid) {
return { error: coupon.reason }; // "Coupon expired" or "Not valid for this plan"
}Trial Periods
Trials are configured on your plans in the StackBE dashboard. When a plan has a trial period, checkout automatically applies it.
// Checkout automatically uses the plan's trial period
const { url } = await stackbe.checkout.createSession({
email: 'new@example.com',
planId: 'plan_pro', // Has 14-day trial configured
successUrl: 'https://yourapp.com/welcome',
cancelUrl: 'https://yourapp.com/pricing',
});
// Customer gets 14-day trial, then billing startsTrial behavior: Configure whether payment method is required during trial in your app settings. Options are require_payment_method or no_payment_method.
Organization Checkout (B2B)
Create a checkout for an organization instead of an individual customer.
// Checkout for an organization
const { url } = await stackbe.checkout.createSession({
organizationId: 'org_xyz789', // Organization ID
planId: 'plan_enterprise',
successUrl: 'https://yourapp.com/org/settings?upgraded=true',
cancelUrl: 'https://yourapp.com/org/settings',
});
// All org members share this subscriptionHandling Success
After successful payment, Stripe redirects to your success URL. You can include the session ID to verify the purchase.
// Success page: app/success/page.tsx
export default async function SuccessPage({ searchParams }) {
const sessionId = searchParams.session_id;
// Option 1: Just show success message (subscription created via webhook)
return (
<div>
<h1>Welcome to Pro!</h1>
<p>Your subscription is now active.</p>
<a href="/dashboard">Go to Dashboard</a>
</div>
);
// Option 2: Fetch subscription details to show specifics
// (The subscription is created by webhook, which is near-instant)
const subscription = await stackbe.subscriptions.get(customerId, {
expand: ['plan'],
});
return (
<div>
<h1>Welcome to {subscription.plan.name}!</h1>
<p>Your subscription is active until {subscription.currentPeriodEnd}</p>
</div>
);
}Checkout Options
const { url } = await stackbe.checkout.createSession({
// Required
planId: 'plan_pro',
successUrl: 'https://yourapp.com/success',
cancelUrl: 'https://yourapp.com/pricing',
// Customer (one required)
customerId: 'cust_abc123', // Existing customer
email: 'user@example.com', // New customer (will be created)
organizationId: 'org_xyz789', // For B2B checkout
// Optional
couponCode: 'SAVE20', // Apply promo code
collectBillingAddress: true, // Require billing address
metadata: { // Custom metadata (stored on subscription)
referral: 'partner_abc',
campaign: 'summer_2025',
},
});Best Practices
- Always use StackBE for checkout — Don't create Stripe checkout sessions directly. StackBE adds required metadata for tracking.
- Handle webhooks — The subscription is created via webhook. Set up webhook handling before going live.
- Use absolute URLs — Success and cancel URLs must be absolute (include https://).
- Don't block on session verification — The success page should work without fetching data. Webhook processing might take a second.