Skip to content

Callbacks and webhooks ​

Give Mamlaka these two addresses. Both are public HTTPS endpoints, and the exchange checks the provider's own record before acting on either.

ForAddress
Payment gateway callbackshttps://apiexchange.yeshara.network/api/v1/hooks/mamlaka/payments
Virtual card webhookshttps://apiexchange.yeshara.network/api/v1/hooks/mamlaka/cards

The gateway address is also sent as callbackUrl on every gateway request, so a merchant set up without a default callback still reaches it.

Signatures ​

Both endpoints check the same signature, over the raw request body exactly as sent:

X-Mamlaka-Signature: sha256=<hex HMAC-SHA256 of the raw body, keyed with the signing secret>

The comparison is constant-time. Re-serialising the JSON before signing (a different key order, different whitespace) produces a different signature, so sign the bytes you send.

EndpointWith a signing secret setWithout one
PaymentsA wrong or missing signature is refused with 401 bad_signatureAccepted, but only used as a prompt to look up the transaction
CardsA wrong or missing signature is refused with 401 bad_signatureEvery webhook is refused; the card webhook requires a secret

Payment gateway callback ​

The exchange reads one field from the body: externalId, which is the key it sent with the payment. It then calls GET /transaction?reference=<externalId> and settles the payment on that answer:

Gateway statusThe payment becomes
COMPLETEConfirmed, and what it was for is written: the invoice payment, the funded escrow, the payout or advance
FAILEDFailed, with the gateway's reason
PENDING, or no answerLeft open; the poller asks again

Answer: always 200, unless the signature is wrong.

json
{ "ok": true, "acted": true, "transfer": "TRF-0042" }

acted: false means the callback named no payment the exchange is waiting on: an unknown key, or one already settled. Sending the same callback twice is harmless.

Card webhook ​

Event typeWhat the exchange does
kyc.status_changedReads the cardholder's KYC decision back from the Partner API
card.updatedReads the driver's cards back: status, balance
operation.updatedReads the issue or load back by its data.reference and settles it

Each event is acted on once. The event id is taken from the X-Mamlaka-Event-Id header, or the body's id; a repeat is answered { "ok": true, "acted": false, "duplicate": true }.

If a callback never arrives ​

Nothing waits on one. A poller in the exchange checks every open payment on a short interval (10 seconds by default), and Finance can run a check at once with Check the network now on Finance → Transfers. A payment confirmed by the poller and then by a late callback is settled once.

AgriTrade Exchange