Webhook Integration
Setting up and handling payment provider webhooks for subscription events.
Note: This is mock/placeholder content for demonstration purposes.
Webhooks notify your application when billing events occur, ensuring your app stays synchronized with your payment provider.
Why Webhooks?
Webhooks are essential for:
- Real-time updates - Instant notification of payment events
- Reliability - Handles events even if users close their browser
- Security - Server-to-server communication
- Automation - Automatic subscription status updates
Webhook Endpoint
Your webhook endpoint receives events from the payment provider:
// app/api/billing/webhook/route.ts
export async function POST(request: Request) {
const body = await request.text();
const signature = request.headers.get('stripe-signature');
// Verify webhook signature
const event = stripe.webhooks.constructEvent(
body,
signature,
process.env.STRIPE_WEBHOOK_SECRET
);
// Handle the event
await handleBillingEvent(event);
return new Response('OK', { status: 200 });
}
Common Events
Subscription Created
case 'customer.subscription.created':
await prisma.subscription.create({
data: {
id: event.data.object.id,
accountId: event.data.object.metadata.accountId,
status: 'active',
planId: event.data.object.items.data[0].price.id,
currentPeriodEnd: new Date(event.data.object.current_period_end * 1000),
},
});
break;
Subscription Updated
case 'customer.subscription.updated':
await prisma.subscription.update({
where: { id: event.data.object.id },
data: {
status: event.data.object.status,
planId: event.data.object.items.data[0].price.id,
currentPeriodEnd: new Date(event.data.object.current_period_end * 1000),
},
});
break;
Subscription Deleted
case 'customer.subscription.deleted':
await prisma.subscription.update({
where: { id: event.data.object.id },
data: {
status: 'canceled',
canceledAt: new Date(),
},
});
break;
Payment Failed
case 'invoice.payment_failed':
const subscription = await prisma.subscription.findUnique({
where: { id: event.data.object.subscription },
});
// Send payment failure notification
await sendPaymentFailureEmail(subscription.accountId);
break;
Setting Up Webhooks
Stripe
- Local Development (using Stripe CLI):
stripe listen --forward-to localhost:3000/api/billing/webhook