Webhook Delivery
Problem
When a transaction succeeds, Paymob must notify the merchant's server by POSTing a signed JSON payload to the URL they configured. Merchant servers are unreliable. Implement the delivery component in Python (we use Django + Celery): sign the payload with HMAC-SHA512 over a canonical string using the merchant's secret, deliver it, retry on failure with exponential backoff and jitter up to a maximum number of attempts, keep per-merchant ordering when the merchant opts in, and make sure a retry never sends a different body or a different signature than the first attempt did.
Examples
Example 1 — Merchant M1, secret s3cr3t, event {"id": "evt_1", "type": "transaction.success", "amount_cents": 15000}. Attempt 1 → 502 → retry after ~2 s → 200. Delivery is delivered with
attempts = 2, and both attempts carried the same X-Paymob-Signature.
Example 2 — Merchant M2 times out eight times in a row → delivery is failed and a "redeliver" button
lights up in the merchant dashboard.
Constraints
- Backoff:
min(2 ** attempt, 300)seconds plus up to 1 s of jitter; max 8 attempts - Retry only on network errors, timeouts, 5xx and 429; any other 4xx is terminal
- Signature string = the payload's values in key-sorted order, concatenated; hex-encoded HMAC
What they look for
An outbox row per event (so an event survives a worker crash), a Celery task using retry(countdown=...)
with max_retries, per-merchant ordering via a dedicated queue or a next_attempt_at chain, storing the
exact bytes sent so the signature is stable across retries, and how the merchant verifies the signature on
their side.