Skip to content
Development
Command

/paymob-check-hmac

Audit a Paymob webhook HMAC verification implementation for correctness and safe failure behavior.

From plugin
paymob-integration
367 skills7 commands1 MCP
> /plugin marketplace add PaymobAccept/Paymob-AI-Integration-Skill
> /plugin install paymob-integration@paymob

Command definition

paymob-check-hmac.md
description: Audit a Paymob webhook HMAC verification implementation for correctness and safe failure behavior.
argument-hint: "[path to the webhook handler, optional]"
disable-model-invocation: true
allowed-tools: Read Glob Grep

Audit the user's Paymob webhook HMAC verification code: $ARGUMENTS

**Non-negotiable ground rules for this command, before anything else:**

  • Never ask the user to paste their HMAC secret, API key, or Secret Key into this conversation.
  • Never read a `.env` file's actual secret value, and never echo, print, or write any secret into chat output, logs, or a file you create.
  • The default mode is a **static code audit** — no computation is required to complete it.
  • **Never audit the field order, digest, or callback shape from memory.** This command deliberately carries no copy of the spec. If you cannot read `hmac-verification.md`, you cannot do this audit — say so and stop. An audit performed from recall can pass a wrong field order as correct, which is the exact failure this command exists to catch: HMAC verification that looks verified and silently is not.

Step 0 — locate the spec

`hmac-verification.md` lives in the skill's `references/` directory. Use the first of these that exists:

1. `${CLAUDE_PLUGIN_ROOT}/skills/paymob-integration/references/` — plugin install 2. `~/.claude/skills/paymob-integration/references/` — personal skill install. `~` is the user's home directory; on Windows expand it yourself (`%USERPROFILE%\.claude\skills\…`), since a literal `~` will not resolve there. 3. `skills/paymob-integration/references/` — repository checkout, relative to the working directory. This only resolves if the user happens to be working inside the skill repo, so treat path 2 as the reliable one for a personal install.

`${CLAUDE_PLUGIN_ROOT}` is substituted only for plugin installs. If you see it unexpanded, you are not in one — use path 2 or 3. If none resolve, search for `hmac-verification.md` under any `paymob-integration` directory. Confirm you have actually read the file before starting Step 2.

Step 1 — locate the code

If `$ARGUMENTS` names a path, start there. Otherwise search for the callback route bound to `notification_url` / the `hmac` query parameter, or for `PAYMOB_HMAC_SECRET` usage.

Step 2 — audit against `references/hmac-verification.md`

Read that file first, from the root you resolved in Step 0 — don't rely on memory for the field order or algorithm. Then check each item below and report pass/fail with file/line references:

1. **Digest**: HMAC-**SHA-512**, not SHA-256 or any other digest. 2. **Source and order**: the concatenation reads fields from `body.obj` (the POST payload) in exactly the field order given in `hmac-verification.md` — flag any other ordering, including "alphabetical by key name," as a failure. 3. **No id/order.id conflation**: the code must not treat `obj.id` (the transaction/event id) and `obj.order.id` (the order id) as interchangeable — both are distinct fields in the concatenation. 4. **Raw values**: fields are concatenated as received — no reformatted timestamps, no rounded or reformatted numbers, no inserted whitespace. 5. **Fail closed**: a non-matching computed HMAC results in **no state change** — the handler returns/rejects before any database write, with no fallback path that updates order status anyway. 6. **Idempotency**: enforced via a **unique constraint on `obj.id`** plus a transactional outbox, not a bare application-level "already processed" flag with no backing unique index. Flag an in-memory set, a non-unique-indexed boolean column, or a check-then-write pattern without a DB constraint as a failure, even if it looks like it works in testing. 7. **Safe comparison**: the computed lowercase-hex digest is compared to the received value with a constant-time function (`crypto.timingSafeEqual`, `hmac.compare_digest`, `hash_equals`, `CryptographicOperations.FixedTimeEquals`, `OpenSSL.fixed_length_secure_compare`), and a missing, empty, or wrong-length `hmac` is rejected cleanly instead of throwing (for example, Node's `timingSafeEqual` throws on unequal buffer lengths, so the lengths must be checked first). 8. **Value stringification**: booleans concatenate as lowercase `true`/`false` (flag Python `str(True)`, PHP `(string) true`, or anything else that produces `True` or `1`). Also check how null values are stringified, against the null-handling note in `hmac-verification.md`. 9. **Where the `hmac` is read from**: transaction and card-token callbacks carry it in the query string; subscription callbacks carry it in the request body (see `hmac-verification.md` and `advanced-features.md`).

If the merchant's integration also handles card-token or subscription callbacks, note that those use a different field list per `hmac-verification.md` and must not be assumed to share the transaction-callback order — check whether the code accounts for that separately.

Present the result as a pass/fail checklist per item, plus anything missing entirely (e.g., no idempotency handling at all) rather than assuming it exists elsewhere in the codebase.

Step 3 — only if the user explicitly asks you to compute or verify an HMAC against a real callback payload

  • Do this by writing and running a short script that reads the secret from the environment (`process.env.PAYMOB_HMAC_SECRET` or the equivalent in the user's language) at run time — never by hardcoding the secret, never by asking the user to paste it here, and never by having the script print, log, or return the secret itself.
  • Only surface the computed hash and whether it matches; avoid printing the full concatenated string if it contains payload PII the user hasn't already shown you.
  • Delete or avoid committing any throwaway script that touches the secret.

Step 4 — isolated testing

For testing outside the codebase, point the user to two Paymob tools:

  • The **HMAC Signature Troubleshooter** on `https://wizard.paymob.com/`. It takes the HMAC hex v
Read more
@paymobaccept
Ships withpaymob-integration

Claude.ai / ChatGPT / Lovable skill upload: Download paymob-integration.zip — do not use GitHub's Code → Download ZIP. Give any AI coding agent expert, workflow-driven knowledge of the Paymob payment gateway across Egypt, UAE, KSA, and Oman.

361 skill1 MCP
Get the whole plugin

Stars on GitHub

Momentum

stars in total
36
Star history of PaymobAccept/Paymob-AI-Integration-Skill on GitHub, a chart by star-history.com

Other commands on paymob-integration.

More commands from other plugins.

build
Auto-invoked

build

Command

Implement tasks incrementally — build, test, verify, commit. Add "auto" to run the whole plan in one approved pass.

@addyosmani@addyosmaniInstall Command