BillingWebhookKit

Stripe invoice.payment_failed webhook in Next.js

A failed renewal should not randomly revoke, resend, or downgrade access. Test the signature, billing reason, dunning state, and duplicate replay before failed-payment traffic reaches production.

Generate Stripe fixtures Build a test plan

Fields to trust

invoice.payment_failed

Use the invoice ID, customer ID, subscription ID, attempted amount, currency, attempt count, and hosted invoice URL only after signature verification.

billing_reason

Separate subscription renewal, subscription creation, manual invoice, and update flows so failed first payments do not follow the same path as failed renewals.

Dunning state

Record grace-period, retry, or past-due state explicitly. Avoid deleting access until your policy and Stripe subscription status agree.

Idempotency key

Key on the provider event or invoice identity so duplicate replay cannot send repeated dunning email, write duplicate risk rows, or downgrade twice.

Next.js route order

Read await request.text(), verify Stripe-Signature, parse the event, verify the subscription mapping, then hold or mark risk inside an idempotency guard.

export async function POST(request: Request) {
  const rawBody = await request.text();
  const signature = request.headers.get("Stripe-Signature");
  const event = verifyStripeEvent(rawBody, signature);

  if (event.type === "invoice.payment_failed") {
    await runOnce(`stripe-payment-failed:${event.data.object.id}`, async () => {
      await markSubscriptionPaymentRisk(event.data.object);
    });
  }

  return new Response("ok", { status: 200 });
}

CI gates

FAQ

Should invoice.payment_failed immediately revoke SaaS access?

Usually no. Treat it as a dunning or grace-period signal unless your policy explicitly requires immediate hold. Test the entitlement decision before production.

How do I test duplicate Stripe failed payment webhooks?

Replay the same signed invoice.payment_failed fixture and assert the route writes one risk record, sends at most one dunning action, and does not repeatedly downgrade the account.

Turn failed-payment handling into release evidence

The free fixture and test plan tools cover failed renewals. The CNY 69 Pro Kit is for teams that want fixtures, idempotency tests, entitlement matrices, and review templates already packaged.