Stripe subscription cancellation webhook in Next.js
Cancellation handling is an entitlement decision. Test whether users keep access until period end, lose access immediately, enter a grace state, or need support review.
Events to test
Test cancel_at_period_end, plan changes, paused states, and period end timestamps before changing access.
Revoke access only when the subscription is terminal according to your policy and the paid period has ended.
Move the user into grace, hold, or support review without granting new paid access.
Keep the original grant fixture so cancellation tests can prove rollback is tied to the same customer and subscription.
Next.js route order
Read the exact raw body, verify Stripe-Signature, parse once, build an idempotency key, then evaluate the subscription entitlement matrix.
export async function POST(request: Request) {
const rawBody = await request.text();
const signature = request.headers.get("Stripe-Signature");
const event = verifyStripeEvent(rawBody, signature);
await runOnce(`stripe:${event.id}`, async () => {
const decision = decideSubscriptionAccess(event);
await applyEntitlementDecision(decision);
});
return new Response("ok", { status: 200 });
}
CI gates
- Valid signed cancellation fixture returns 2xx and writes one entitlement decision.
- Mutated raw body returns 400 before access, email, license, or support side effects.
- Duplicate replay of the same subscription event runs the decision once.
cancel_at_period_end=truepreserves access untilcurrent_period_end.invoice.payment_failedfollows the grace or hold policy and never grants new access.
FAQ
Which Stripe cancellation events should a Next.js webhook test cover?
Cover customer.subscription.updated for cancel_at_period_end changes, customer.subscription.deleted for terminal cancellation, invoice.payment_failed for grace or hold policy, and checkout or invoice events that originally granted access.
Should customer.subscription.deleted revoke access immediately?
Only if the subscription is actually past the paid period or your product policy says immediate revoke. Cancellation-at-period-end should usually preserve access until current_period_end.
Turn cancellation policy into release evidence
The free test plan generator builds the release checklist. The CNY 69 Pro Kit is for teams that want fixtures, idempotency tests, entitlement matrices, and review templates already organized.