Your Paddle Webhook Is Signed. The Seat Count Is Not.
Paddle custom_data can come from browser checkout code. Verify the signature, then grant seats from paid line items, not client metadata.

Search for a command to run...
Paddle custom_data can come from browser checkout code. Verify the signature, then grant seats from paid line items, not client metadata.

A timeout makes your app retry a PayPal refund. The second call returns 422, even though the money is already back. Test that branch before launch.

Lovable and Bolt apps now ship real payment integrations. Mocks don't fire the retry twice and staging won't replay a 401 mid-flow. Run the lifecycle against a service twin and attach the receipt to the PR.

An AI agent "fixed" a Stripe webhook that double-granted seats. CI went green. Paying customers got nothing. The check only asked whether the count stopped growing

You'd think webhook events fire in order. Paddle disagrees. Here's what happens and how to handle it.
We tried UAT, staging with IP whitelists, and finally production access — all to let partners test our API. Every option was worse than the last.

AgentMail webhook creation can look done after a 200 OK. The real test is whether the persisted webhook is still scoped to the inboxes you sent.

A narrow Clerk webhook failure: replayed user.created events can duplicate local user rows unless your handler reconciles by provider ID.

Okta group renames can arrive through WorkOS directory sync as partial webhook events. If feature gates trust the payload, users split by cache state. Re-fetch the group and users before gating.
