Next.js payment webhook refund rollback test
A refund webhook test should prove rollback behavior before a live customer asks why access, downloads, license keys, or support notes changed.
Rollback contract
Do not treat refund handling as a support-only task. The webhook route needs a contract that says which provider event is trusted, how it maps back to the original checkout, and what access change is allowed.
Verify the exact raw body with the provider signature header before parsing JSON or touching access records.
Connect the refund ID to the order, invoice, transaction, subscription, customer, and product or price ID.
Apply the policy: revoke now, revoke at period end, hold for support review, or keep access for partial refunds.
Record secret-free notes: event ID, refund amount, decision, replay result, and delivery or license state.
Next.js test shape
Put refund rollback in CI with signed fixtures. The route should reject mutated bodies, run one rollback under duplicate replay, and keep unknown refund-like events from changing access.
it("rolls back a signed refund event once", async () => {
const event = signedFixture("refund.created");
await postWebhook(event);
await postWebhook(event);
await postWebhook(event);
expect(await entitlementState(event.paymentId)).toEqual("revoked");
expect(await rollbackRecords(event.refundId)).toHaveLength(1);
});
Minimum test list
Signed provider fixture returns 2xx, maps to the original payment, and writes the expected rollback record.
Changing one byte after signing returns 400 before access, delivery, license, email, or support side effects run.
Replaying the same event three times produces one rollback decision and one support evidence entry.
Partial refunds follow the documented policy instead of silently revoking all access.
Unknown signed events are logged or quarantined without granting or revoking access by default.
Provider event names
- Stripe: start with
charge.refunded,refund.created, disputes, and the original checkout or invoice mapping. - Lemon Squeezy: cover refund-related order events, paid-state checks, delivery rollback, and buyer support evidence.
- Paddle: cover adjustment or refund events and link them back to
transaction.completed. - Polar: cover order refund or dispute equivalents and product entitlement decisions.
FAQ
What should a refund webhook rollback test prove?
It should prove the signed refund event is accepted once, maps to the original payment, revokes or flags access according to policy, records support evidence, and stays safe under duplicate replay.
Should a refund webhook always revoke access immediately?
No. The test should match the product policy: immediate revoke, period-end revoke, manual review, or support hold depending on the refund type, dispute state, and delivery model.
Turn refund rollback into launch evidence
The free report generator creates a PR-ready refund rollback note. The CNY 69 Pro Kit packages fixtures, idempotency tests, review templates, and runbooks for teams that want the evidence already organized.