Skip to main content

Migrating Callbacks from v3 to v4

This page walks through moving a sub-merchant's callbacks from v3 to v4. The payment callback and checkout callback are versioned independently — payment_callback_version and checkout_callback_version — so you can migrate one before the other. Neither is self-serve; [email protected] makes the change once your endpoint is ready.

Deploy and Verify Before Requesting the Flip

You can't run v3 and v4 side by side on either field: the moment payment_callback_version or checkout_callback_version flips to v4, v3 deliveries on that callback stop entirely. If your endpoint isn't already updated to read the v4 shape and validate the v4 signature, every callback on that surface fails from the first delivery after the flip.

  1. Deploy and verify your v4 parsing and signature logic first.
  2. Prove it in test mode (below) before requesting anything on your live sub-merchant.
  3. Only then ask [email protected] to flip the live version field(s).

Confirm the expected turnaround for a rollback request with Nimbbl before you flip, since it is not fixed.

Payment Callback: What Changes

v3v4
Deliveryresponse=<base64> query parameter (redirect only); full plain JSON body for no-redirect/webhookpayload/nimbbl_signature/version as query params (redirect) or the same fields as a JSON body (no-redirect/webhook)
Where the signature livesInside the decoded JSON, as nimbbl_signatureA separate field alongside payload, not inside the decoded JSON
Payload sizeFull payload — transaction, order, and user objectsCompact — order and transaction summary. authorization_details for pre-authorization is present on both — it is not a v4 addition.
Signature inputPer-field concatenation (invoice_id|transaction_id|...)Entire compact JSON string

sub_merchant_id is not part of the unencrypted v4 payment callback response — it's added only when encryption is enabled for the sub-merchant. If you run multiple sub-merchants against one unencrypted callback URL, there's nothing in the response to tell you which access_secret to verify with; route by URL or enable encryption per sub-merchant.

Checkout Callback: What Changes

v3v4
Wrapper event_typeglobalHandleCheckoutResponseglobalHandleCheckoutResponse (unchanged)
PayloadFull transaction and order objects nested inside payloadLightweight status object: checkout_status, nimbbl_order_id, nimbbl_transaction_id, invoice_id, retry, reason, message
Signaturenimbbl_signature and transaction.signature inside the payload, per-field concatenationnimbbl_signature at the top level (alongside payload and version), HMAC-SHA256 of the entire compact JSON string

Migration Steps

  1. Update your endpoint(s) to parse the new shape.
    • Payment callback: read payload, nimbbl_signature, and version (from query params on redirect, or JSON body otherwise) instead of the v3 response parameter or flat JSON body.
    • Checkout callback: event_type stays globalHandleCheckoutResponse — no change needed there. Update your callback_handler to read the nested payload.payload / payload.nimbbl_signature / payload.version instead of the v3 payload shape. payload.sub_merchant_id is present only when encryption is enabled.
  2. Base64-decode the payload field on each to recover the compact JSON. For the checkout callback, switch your UI logic from the old status field to checkout_status plus the new reason values.
  3. Switch signature validation from per-field concatenation to HMAC-SHA256(compact_json_string, access_secret) — the same algorithm for both callbacks, both using the field name nimbbl_signature. See Validating Payment Response with Signature for code samples in Java, C#, PHP, and Python.
  4. Handle pre-authorization if relevant. transaction.authorization_details on the payment callback is present on v3 as well as v4, so this isn't strictly a migration step — but if your sub-merchant uses manual capture, make sure you're already handling it, plus the payment_authorized reason on the checkout callback. See Pre-Auth and Capture.
  5. If you use Transaction Enquiry, note that moving payment_callback_version to v4 also changes that endpoint: nimbbl_signature and signature_version are both returned as null there for v4 sub-merchants. Update any code that validates the enquiry signature before you flip.
  6. Test in test mode. Ask [email protected] to set payment_callback_version and/or checkout_callback_version to v4 for your test sub-merchant, then run test transactions end to end.
  7. Go live. Once test-mode traffic validates cleanly, ask [email protected] to flip the corresponding version field(s) on your live sub-merchant.
Migrate Independently, Verify Together

Because payment_callback_version and checkout_callback_version are separate fields, you can move one callback to v4 while the other stays on v3. If you rely on both together (e.g. checkout callback for UI, payment callback to confirm), test the combination you'll actually run in production before requesting the live cutover.