Check the basics first
Every delivery carriesX-Pazy-Webhook-Attempt and X-Pazy-Webhook-Subscription-Id. Log them, along with the event id and your response status. Most problems show up straight away in those logs.
Every request fails signature verification
Every request fails signature verification
Work through these in order:
- Raw body. Verify against the exact bytes received. If your framework parses JSON first, configure it to keep the raw body (
express.rawin Express,request.get_data()in Flask). Never re-serialize the parsed object. - Secret. Use the secret for this endpoint. Sandbox and production endpoints have different secrets. Check there’s no trailing whitespace or newline from an environment file.
- Signed string. It is
<timestamp>.<raw_body>, with a literal dot, where the timestamp is the header value as sent. - Prefix. The header looks like
sha256=<hex>. Strip the prefix before comparing, or compare against the prefixed value. - Known-good test. Run your code against the test vector. If it fails there, the bug is in your HMAC code and not in your setup.
Signatures verify, but old requests get rejected
Signatures verify, but old requests get rejected
Your timestamp check rejects requests more than 5 minutes from your server’s clock. Check that your server’s clock is synced with NTP. Retries are re-signed with a fresh timestamp each time, so a late retry isn’t rejected for its age.
I'm not receiving any events
I'm not receiving any events
- Confirm Pazy has your endpoint registered for the right environment (sandbox or production) and organization.
- Confirm you’re subscribed to the event type. An event you aren’t subscribed to is never sent.
- Confirm the action that raises the event actually happened. For example,
payment.invoice.completedfires when money reaches a final outcome, not when a payment request is created. - Check the URL requirements. In production,
http://,localhost, private IPs and redirecting URLs all fail. - Check that your firewall allows Pazy’s egress IPs. Ask support for the list.
- Check your server and load balancer logs. Is the request reaching your app?
I'm receiving the same event more than once
I'm receiving the same event more than once
That’s expected. Delivery is at-least-once, so duplicates happen. Deduplicate on the event
id, as described in Delivery and retries.If duplicates are frequent, your endpoint is probably responding too slowly or with a non-2xx status, so Pazy retries. Check the X-Pazy-Webhook-Attempt header: values above 1 confirm retries. Acknowledge faster and move processing to a background job.Deliveries time out
Deliveries time out
Pazy waits 10 seconds by default, and 30 at most. Your handler should return in well under a second:
- Don’t call other services, and don’t run heavy database work, before responding.
- Save the event or enqueue it, then return
200. - If you need more time for cold starts, ask support to raise your timeout.
My endpoint returns 200 but Pazy keeps retrying
My endpoint returns 200 but Pazy keeps retrying
- Redirects count as failures. If your URL redirects (for example
httptohttps, or a trailing-slash redirect), register the final URL. - A response body over 64 KB counts as a failure. Return an empty body.
- Check that the
200really comes from your handler and not from a proxy or WAF that then drops the connection.
Events arrive out of order
Events arrive out of order
Ordering isn’t guaranteed. A retried event can arrive after a newer one. Compare timestamps in the payload, or fetch the current state from the API. See Don’t rely on ordering.
My endpoint was down and I missed events
My endpoint was down and I missed events
After 5 attempts (about 8 minutes) Pazy stops retrying. Reconcile with the API by listing recent records, and contact customer-support@pazy.io if you need events replayed. Self-serve redelivery is coming soon.
A field I expected is missing or null
A field I expected is missing or null
Check the event’s page in the event reference. Fields marked nullable are present with a
null value.Still stuck?
Email customer-support@pazy.io with:- The endpoint URL and environment
- The event
idandtype(or the approximate time) - The
X-Pazy-Webhook-Attemptvalue and the status your endpoint returned