Migrating Webhooks from v3 to v4
This page walks through moving a sub-merchant's webhook delivery from v3 to v4. Webhook version is set per sub-merchant via the webhook_version field — stored as v100–v400 (defaulting to v300, i.e. v3) and displayed as v1.0.0–v4.0.0 in Command Center. It isn't something you toggle yourself; [email protected] makes the change once you've confirmed your endpoint is ready.
You can't run v3 and v4 side by side: webhook_version is a single per-sub-merchant setting, and the moment it flips to v4, v3 deliveries stop entirely — there is no phased or parallel rollout. If your endpoint isn't already updated to read the v4 format and validate the v4 signature, every webhook fails from the first delivery after the flip. Failed deliveries are retried for roughly 16 hours and then abandoned permanently — they are not recoverable by flipping back.
- Deploy and verify your v4 parsing and signature logic first.
- Prove it in test mode (below) before requesting anything on your live sub-merchant.
- Only then ask [email protected] to flip your live
webhook_versionto v4.
If you need to roll back after flipping, request it the same way — but any events that failed and expired while your endpoint was unprepared are gone; rolling back does not recover them. Confirm the expected turnaround for a rollback request with Nimbbl before you flip, since it is not fixed.
What Changes
| v3 | v4 | |
|---|---|---|
| Delivery | Full payload sent as-is | Same payload Base64-encoded and signed, then sent inside {payload, signature, sub_merchant_id, version} |
Top-level version | Present, inside the payload | Moved out of the payload, up to the top level |
Top-level nimbbl_signature | Present | Removed — replaced by the top-level signature |
transaction.signature_version | Present | Removed |
transaction.signature | Present | Removed |
| Signature algorithm | HMAC-SHA256 of concatenated fields (invoice_id|transaction_id|...) | HMAC-SHA256 of the entire compact JSON string (the Base64-decoded payload) |
The event payload itself — event_type, transaction, and the rest — is unchanged between versions; only the outer delivery shape, the top-level version field, and the signature move.
Migration Steps
- Update your endpoint to read the new format. Instead of reading the webhook body directly as the event payload, read
payload,signature,sub_merchant_id, andversionfrom the POST body. - Base64-decode
payloadto recover the compact JSON string — this is your existing event payload, minusversionand the two removed fields below. - Switch signature validation from the v3 field-based formula to
HMAC-SHA256(compact_json_string, access_secret), compared against the top-levelsignaturefield. See Validating Payment Response with Signature for code samples in Java, C#, PHP, and Python. - Stop reading the top-level
versionfield,nimbbl_signature, andtransaction.signature_versionfrom the payload —versionhas moved up to the top level, and the other two are gone in v4. - Test in test mode. Ask [email protected] to set
webhook_versiontov4for your test sub-merchant, then trigger test transactions and confirm your updated endpoint validates and processes events correctly. - Go live. Once test-mode traffic validates cleanly, ask [email protected] to flip
webhook_versiontov4on your live sub-merchant.
webhook_version is a single per-sub-merchant setting — a sub-merchant is on v3 or v4 at any given time, not both. Complete and verify your endpoint changes before requesting the live cutover.