Webhooks aren't delivered in the order the events happened. A retry, a slow queue on the provider's side or parallel delivery can mean invoice.paid arrives before invoice.created, or customer.subscription.updated arrives after customer.subscription.deleted.
A handler that assumes order may create records it can't link, overwrite newer state with older state, or fail with "not found" and depend on a retry that never fixes it.
Replay a real sequence in a different order
hwcli events list --hook payments --since 1h # find the events hwcli replay evt_c3 evt_a1 evt_b2 --target :8080/webhooks
Events are sent one after another in the order you list them. Each one's result is reported separately. Sequences can have up to 3 events on Free and 25 on Pro.
Patterns that hold up
- Compare the event's own timestamp or version (for example Stripe's
created) with what you stored, and ignore older updates. - When the event is a notification only, fetch the current state from the provider's API instead of trusting the payload.
- When a dependency is missing, return a 5xx so the provider retries later. Don't drop the event.