Lovable·FixsecurityStripeintermediate

Stripe Webhook Replay or Duplicate Events Are Double-Applying Changes

Quick Answer

Stripe can retry webhook delivery, and duplicate event handling becomes dangerous if your endpoint is not idempotent. If each webhook blindly writes state again, retries look like extra purchases or extra upgrades. Start with "Store processed event IDs" before making broader code changes.

Quick Fix Summary

Most likely causeStripe can retry webhook delivery, and duplicate event handling becomes dangerous if your endpoint is not idempotent. If each webhook blindly writes state again, retries look like extra purchases or extra upgrades.
Fastest fixStore processed event IDs
Use this page ifCredits are added twice after one payment

You're in the right place if...

  • !Credits are added twice after one payment
  • !A subscription update runs more than once
  • !Webhook retries create duplicate rows or duplicate entitlements

Why this happens

Stripe can retry webhook delivery, and duplicate event handling becomes dangerous if your endpoint is not idempotent. If each webhook blindly writes state again, retries look like extra purchases or extra upgrades.

Fix

1

Store processed event IDs

Make the webhook idempotent by recording each Stripe event ID and ignoring repeats once the first valid processing succeeds.

2

Guard writes with unique constraints

For credits, orders, or entitlements, use a unique key that makes duplicate inserts fail safely instead of duplicating state.

create table if not exists stripe_events (
  event_id text primary key,
  event_type text not null,
  processed_at timestamptz not null default now()
);
3

Separate verification from mutation

Verify the signature first, then check whether the event was already processed, and only then apply state changes.

4

Patch the generated webhook handler

Tell Lovable to make the Stripe webhook idempotent instead of assuming each event arrives once.

Copy this prompt

Audit the Stripe webhook handler in this app for replay and duplicate-event safety. Verify the signature, persist the Stripe event ID, and skip any mutation if that event was already processed once successfully.

Prevent this next time

Every payment webhook should be written as if Stripe may send it twice, because in real systems it often will.

Frequently Asked Questions

Retries happen when the endpoint times out, errors, or Stripe does not get a clear success response quickly enough.

No. Signature verification proves the event came from Stripe, not that you have not already processed it.

Related fixes

Weekly Signals

Get the next fix, switch, or warning before it hits your build.

Join builders getting the community signals, fix patterns, and tool shifts that matter before they show up everywhere else.

Follow the signals →