Allowed R6 · Within policy
{
"slug": "webhook-delivery",
"title": "Webhook Delivery",
"difficulty": "medium",
"tags": [
"coding",
"technical",
"backend"
],
"is_free": true,
"locked": false,
"frequency": 0.8,
"last_reported_at": "2026-08-13T16:54:49.080136Z",
"url": "https://www.mokabla.com/en/c/paymob/webhook-delivery",
"agent": {
"page": "https://www.mokabla.com/agent/en/c/paymob/webhook-delivery",
"question": "https://www.mokabla.com/agent/_call/get_question?company=paymob&question=webhook-delivery"
},
"company": {
"slug": "paymob",
"name_en": "Paymob"
},
"body_md": "## Problem\nWhen a transaction succeeds, Paymob must notify the merchant's server by POSTing a signed JSON payload to the\nURL they configured. Merchant servers are unreliable. Implement the delivery component in Python (we use\nDjango + Celery): sign the payload with HMAC-SHA512 over a canonical string using the merchant's secret,\ndeliver it, retry on failure with exponential backoff and jitter up to a maximum number of attempts, keep\nper-merchant ordering when the merchant opts in, and make sure a retry never sends a different body or a\ndifferent signature than the first attempt did.\n\n## Examples\n**Example 1**, Merchant M1, secret `s3cr3t`, event `{\"id\": \"evt_1\", \"type\": \"transaction.success\",\n\"amount_cents\": 15000}`. Attempt 1 → 502 → retry after ~2 s → 200. Delivery is `delivered` with\n`attempts = 2`, and both attempts carried the same `X-Paymob-Signature`.\n\n**Example 2**, Merchant M2 times out eight times in a row → delivery is `failed` and a \"redeliver\" button\nlights up in the merchant dashboard.\n\n## Constraints\n- Backoff: `min(2 ** attempt, 300)` seconds plus up to 1 s of jitter; max 8 attempts\n- Retry only on network errors, timeouts, 5xx and 429; any other 4xx is terminal\n- Signature string = the payload's values in key-sorted order, concatenated; hex-encoded HMAC\n\n## What they look for\nAn outbox row per event (so an event survives a worker crash), a Celery task using `retry(countdown=...)`\nwith `max_retries`, per-merchant ordering via a dedicated queue or a `next_attempt_at` chain, storing the\nexact bytes sent so the signature is stable across retries, and how the merchant verifies the signature on\ntheir side.",
"follow_ups_md": "- The merchant rotates their secret while a delivery is mid-retry. Which secret signs attempt 5?\n- How do you stop one merchant with a dead endpoint from consuming all workers?",
"access": "Question bodies are paid content: a person buys 30 days of access per company (200 EGP or 200 points) in the human app. Agents get titles, tags and difficulty; bodies only for free questions."
}