Payment Expert
The Payment Expert agent specializes in payment processing, subscription management, Stripe integration, and billing systems for SaaS applications.
Expertise Areas#
- Stripe Integration - SDK setup and configuration
- Checkout Sessions - One-time and subscription payments
- Webhook Handling - Payment event processing
- Customer Portal - Self-service billing management
- Usage-Based Billing - Metered subscription tracking
- Subscription Management - Plan changes, cancellations
- Pricing Components - UI for pricing pages
Usage Examples#
Stripe Setup#
Use the payment-expert agent to set up Stripe integration for a SaaS with multiple pricing tiers.
Response includes:
- SDK configuration
- Price ID management
- Customer creation
- Checkout flow
Webhook Handler#
Use the payment-expert agent to implement a comprehensive Stripe webhook handler for subscription events.
Response includes:
- Signature verification
- Event type handling
- Database synchronization
- Error handling
Billing Portal#
Use the payment-expert agent to add a customer billing portal for subscription management.
Response includes:
- Portal session creation
- Return URL handling
- UI integration
- Permission checking
Best Practices Applied#
1. Payment Processing#
- Secure API key handling
- Webhook signature verification
- Idempotent event processing
- Error recovery patterns
2. Subscription Management#
- Database synchronization
- Status tracking
- Grace period handling
- Dunning management
3. User Experience#
- Clear pricing display
- Smooth checkout flow
- Self-service portal
- Invoice access
4. Security#
- PCI compliance via Stripe
- Secure webhook endpoints
- Proper authentication
- Audit logging
Common Patterns#
Stripe Setup#
1// lib/stripe.ts
2import Stripe from 'stripe';
3
4export const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
5 apiVersion: '2024-12-18.acacia',
6 typescript: true,
7});
8
9export const PLANS = {
10 FREE: { priceId: null, name: 'Free', price: 0 },
11 PRO: {
12 priceId: process.env.STRIPE_PRO_PRICE_ID!,
13 name: 'Pro',
14 price: 29,
15 },
16 TEAM: {
17 priceId: process.env.STRIPE_TEAM_PRICE_ID!,
18 name: 'Team',
19 price: 99,
20 },
21} as const;Checkout Session#
1// app/api/checkout/route.ts
2import { stripe } from '@/lib/stripe';
3import { auth } from '@/lib/auth';
4
5export async function POST(req: Request) {
6 const session = await auth();
7 if (!session?.user) {
8 return Response.json({ error: 'Unauthorized' }, { status: 401 });
9 }
10
11 const { priceId } = await req.json();
12
13 const checkoutSession = await stripe.checkout.sessions.create({
14 customer: customerId,
15 mode: 'subscription',
16 payment_method_types: ['card'],
17 line_items: [{ price: priceId, quantity: 1 }],
18 success_url: `${process.env.NEXT_PUBLIC_APP_URL}/dashboard?success=true`,
19 cancel_url: `${process.env.NEXT_PUBLIC_APP_URL}/pricing?canceled=true`,
20 subscription_data: {
21 metadata: { userId: session.user.id },
22 },
23 });
24
25 return Response.json({ url: checkoutSession.url });
26}Webhook Handler#
1// app/api/webhooks/stripe/route.ts
2import { stripe } from '@/lib/stripe';
3import { headers } from 'next/headers';
4import Stripe from 'stripe';
5
6export async function POST(req: Request) {
7 const body = await req.text();
8 const signature = headers().get('stripe-signature')!;
9
10 let event: Stripe.Event;
11
12 try {
13 event = stripe.webhooks.constructEvent(
14 body,
15 signature,
16 process.env.STRIPE_WEBHOOK_SECRET!
17 );
18 } catch (err) {
19 return Response.json({ error: 'Invalid signature' }, { status: 400 });
20 }
21
22 switch (event.type) {
23 case 'checkout.session.completed':
24 await handleCheckoutComplete(event.data.object);
25 break;
26 case 'customer.subscription.updated':
27 await handleSubscriptionUpdate(event.data.object);
28 break;
29 case 'customer.subscription.deleted':
30 await handleSubscriptionCanceled(event.data.object);
31 break;
32 case 'invoice.payment_failed':
33 await handlePaymentFailed(event.data.object);
34 break;
35 }
36
37 return Response.json({ received: true });
38}Customer Portal#
1// app/api/portal/route.ts
2import { stripe } from '@/lib/stripe';
3import { auth } from '@/lib/auth';
4
5export async function POST() {
6 const session = await auth();
7 if (!session?.user) {
8 return Response.json({ error: 'Unauthorized' }, { status: 401 });
9 }
10
11 const customerId = await getStripeCustomerId(session.user.id);
12 if (!customerId) {
13 return Response.json({ error: 'No subscription' }, { status: 400 });
14 }
15
16 const portalSession = await stripe.billingPortal.sessions.create({
17 customer: customerId,
18 return_url: `${process.env.NEXT_PUBLIC_APP_URL}/dashboard`,
19 });
20
21 return Response.json({ url: portalSession.url });
22}Sample Prompts#
| Task | Prompt |
|---|---|
| Stripe setup | "Set up Stripe integration with multiple pricing tiers" |
| Checkout | "Implement checkout flow for subscription purchases" |
| Webhooks | "Create webhook handler for subscription lifecycle events" |
| Portal | "Add customer billing portal integration" |
| Usage billing | "Implement usage-based billing with metered subscriptions" |
Configuration#
1// bootspring.config.js
2module.exports = {
3 agents: {
4 customInstructions: {
5 'payment-expert': `
6 - Use Stripe for payment processing
7 - Implement comprehensive webhook handling
8 - Set up customer portal for self-service
9 - Track subscription status in database
10 - Handle failed payments gracefully
11 `,
12 },
13 },
14 payments: {
15 provider: 'stripe',
16 plans: ['free', 'pro', 'team', 'enterprise'],
17 },
18};Related Agents#
- Backend Expert - API implementation
- Database Expert - Subscription data management
- Security Expert - Payment security