Founderflow Logo

Stripe Integration

Complete guide to integrating Stripe payments in your Founderflow Boilerplate. Learn how to set up subscriptions, handle webhooks, and process payments securely.

Overview

💳

Stripe Payment Processing

The boilerplate includes a complete Stripe integration with support for one-time payments, subscriptions, webhooks, and customer management. All payment flows are secure and PCI-compliant.

Checkout Sessions

Secure payment processing with hosted checkout

Subscriptions

Recurring billing and subscription management

Webhooks

Real-time payment status updates

Customer Portal

Self-service billing management

Multiple Payment Methods

Cards, digital wallets, and bank transfers

International Support

Multi-currency and global payment methods

Setup & Configuration

Environment Variables

Configure your Stripe integration with the following environment variables:

.env.local
# Stripe Configuration
STRIPE_SECRET_KEY=sk_test_...
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...
# For production, use live keys:
# STRIPE_SECRET_KEY=sk_live_...
# NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_live_...

Stripe Configuration

The Stripe client is configured in lib/stripe.ts:

lib/stripe.ts
import Stripe from 'stripe';
if (!process.env.STRIPE_SECRET_KEY) {
throw new Error('STRIPE_SECRET_KEY is not set');
}
export const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
apiVersion: '2024-12-18.acacia',
typescript: true,
});
export const stripePublishableKey = process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY!;

Payment Flow

Creating a Checkout Session

Create a secure checkout session for one-time or subscription payments:

app/api/stripe/checkout/route.ts
import { stripe } from '@/lib/stripe';
export async function POST(request: Request) {
try {
const { priceId, userId, planId } = await request.json();
const session = await stripe.checkout.sessions.create({
mode: 'subscription',
line_items: [{
price: priceId,
quantity: 1,
}],
success_url: `{process.env.NEXT_PUBLIC_APP_URL}/success?session_id={CHECKOUT_SESSION_ID}`,
cancel_url: `{process.env.NEXT_PUBLIC_APP_URL}/pricing`,
customer_email: userId,
metadata: {
userId,
planId
}
});
return Response.json({ url: session.url });
} catch (error) {
return Response.json({ error: error.message }, { status: 500 });
}
}

Webhook Handling

Process Stripe webhooks to update user subscriptions and payment status:

app/api/webhook/stripe/route.ts
import { stripe } from '@/lib/stripe';
import dbConnect from '@/lib/mongodb';
import User from '@/models/User';
export async function POST(request: Request) {
const body = await request.text();
const signature = request.headers.get('stripe-signature');
let event: Stripe.Event;
try {
event = stripe.webhooks.constructEvent(body, signature!, process.env.STRIPE_WEBHOOK_SECRET!);
} catch (err) {
return Response.json({ error: 'Webhook signature verification failed' }, { status: 400 });
}
if (event.type === 'checkout.session.completed') {
await dbConnect();
const session = event.data.object as Stripe.Checkout.Session;
// Update user subscription status
await User.findOneAndUpdate(
{ id: session.metadata.userId },
{ $set: { 'plan.isPremium': true } }
);
}
return Response.json({ received: true });
}

Frontend Integration

Stripe Elements

Use Stripe Elements for secure payment collection in your React components:

components/payments/StripeCheckout.tsx
'use client';
import { loadStripe } from '@stripe/stripe-js';
import { Elements, CardElement } from '@stripe/react-stripe-js';
const stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY!);
export default function StripeCheckout({ priceId, userId }: { priceId: string; userId: string; }) {
const handleSubmit = async () => {
const response = await fetch('/api/stripe/checkout', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ priceId, userId })
});
const { url } = await response.json();
if (url) window.location.href = url;
};
return (
<Elements stripe={stripePromise}>
<button onClick={handleSubmit}>
Subscribe Now
</button>
</Elements>
);
}

Pricing Configuration

Creating Products & Prices

Set up your products and pricing in the Stripe Dashboard or via API:

Stripe Dashboard
1. Go to Products in your Stripe Dashboard
2. Create a new product (e.g., "Premium Plan")
3. Add pricing (e.g., $9.99/month)
4. Copy the Price ID (price_xxx...)
5. Add to your pricing configuration

Pricing Configuration

Configure your pricing plans in the application:

lib/config/pricing.ts
export const PricingPlans = [
{
id: 'free',
name: 'Free Plan',
price: '0',
stripePriceId: null,
features: [...]
},
{
id: 'premium',
name: 'Premium Plan',
price: '9.99',
stripePriceId: 'price_1234567890',
features: [...]
}
];

Testing

Test Cards

Use these test card numbers for development and testing:

Successful Payment

Card: 4242 4242 4242 4242
Expiry: Any future date
CVC: Any 3 digits

Declined Payment

Card: 4000 0000 0000 0002
Expiry: Any future date
CVC: Any 3 digits

Webhook Testing

Test webhooks using Stripe CLI or webhook testing tools:

Stripe CLI
# Install Stripe CLI
# https://stripe.com/docs/stripe-cli
stripe listen --forward-to localhost:3000/api/webhook/stripe
# Test a webhook event
stripe trigger checkout.session.completed