Menu

A webhook retry can pay a customer twice, and two checks that stop it
📰

A webhook retry can pay a customer twice, and two checks that stop it

DEV Community: postgres·Mohsindev369·about 12 hours ago
#ALWEQDve
#devtopostgresql#devto#dev#event#balance
Reading 0:00
15s threshold

If you sell credits or usage through Stripe, LemonSqueezy or Polar, your webhook handler will receive the same event more than once. Providers retry when your server is slow, when a deploy lands mid-request, when a response gets lost. If the handler does balance += 100 every time it sees checkout.session.completed , somebody eventually gets paid twice.

The fix is two checks, not one. Here is what each one does and why the second exists.

Check 1: de-dupe on the event id, inside the same transaction

Keep a table of events you have handled, keyed by provider and event id. Insert before you do any work, and skip the work if the insert did nothing:

await db . transaction ( async ( tx ) => { const inserted = await tx . insert ( billingWebhookEvents ) . values ({ provider , eventId , type : eventType }) . onConflictDoNothing () . returning ({ eventId : billingWebhookEvents . eventId });

if ( inserted .…

Continue reading — create a free account

Join HashtagPLUS to read full articles, follow hashtags, vote, and join the conversation.