Webhooks failing
Events don’t arrive, arrive twice, or your signature check rejects them.
Symptom: Events don’t arrive, arrive twice, or your signature check rejects them.
Why this happens
A webhook is Swop calling your server when something happens, like a sale (checkout.paid) or a payout (payout.released). Each call is signed so you can prove it came from Swop. Delivery problems come from your endpoint being slow or erroring; signature problems come from checking the signature against the wrong bytes, the wrong secret, or a wrong clock.
Walk through it
Answer one question at a time. The first no is almost always the cause.
Does your endpoint return a 2xx within 10 seconds?
How to check: Send a test event from the Developer page and time your response. Redirects, 4xx, 5xx and timeouts all count as failures.
Check these in order
1. Does your endpoint return a 2xx within 10 seconds?
How to check: Send a test event from the Developer page and time your response. Redirects, 4xx, 5xx and timeouts all count as failures.
If not: Verify, store the event and return 200 straight away; do slow work in a background job. See Retries and de-duplication.
2. Do you verify the signature over the raw request body?
How to check: The HMAC covers the exact bytes Swop sent. Re-serialised JSON won’t match.
If not: Read the raw body (express.raw, request.get_data()) before any JSON parsing. See Verify signatures.
3. Is the secret the one shown when you added this webhook?
How to check: Each webhook has its own signing secret. Removing and re-adding a webhook issues a new one.
If not: Update SWOP_WEBHOOK_SECRET to the current webhook’s secret.
4. Is your server clock within 5 minutes of real time?
How to check: Signatures with a timestamp more than 5 minutes off are rejected, which shows up as failures that come and go.
If not: Sync the clock with NTP.
5. Does the Swop-Signature header reach your code unchanged?
How to check: If it works locally but not when deployed, a proxy or framework is stripping the header or rewriting the body.
If not: Pass the header and raw body through your proxy untouched.
6. Is the webhook active (not paused)?
How to check: After 25 failed deliveries in a row Swop pauses the webhook. The Developer page shows it as paused.
If not: Fix the endpoint, then remove the webhook and add it again (you’ll get a new secret). See Retries and de-duplication.
7. Do you de-duplicate events by ID?
How to check: Retries mean the same event can arrive more than once, and events can take a minute or two after the sale.
If not: Store each event ID and ignore ones you’ve already processed.
Still stuck?
Email support@swopme.co with your swop.id, roughly when it happened, and any order, checkout or request ID. Never send your secret key. You can also use the Ask button on any page.