When a message or payment reaches a notable state, Wavetop notifies your server with a signed HTTP callback. Provide a callback_url on the requests that support it (for example, messaging) to receive these updates.
callback_url with a JSON body.signature header so you can confirm it came from Wavetop.200 to acknowledge receipt.Every callback body includes status, account_uid, and service, plus a service-specific reference/id pair and, for some services, a data object:
| Field | Description |
|---|---|
status | The reported state, e.g. PAYMENT_OK, MSG_FAILED, MSG_DELIVERED. |
account_uid | The account the callback relates to. |
service | The service that produced it, e.g. AIRTIME, DATA, SMS, FLASH, MOMO. |
payment_reference / message_reference | Reference of the original request: payment_* for payments, message_* for messaging. |
payment_id / message_id | Your own client-side identifier, echoed back from the original request. Empty if you didn't supply one. |
data | An optional object carrying additional, service-specific detail about the transaction. For Mobile Money it holds a result object with a code and message. May be omitted or empty for services that send no extra detail. |
POST https://your-server.example/callback
{
"status": "PAYMENT_OK",
"account_uid": "BS-0000-00000",
"service": "AIRTIME",
"payment_reference": "ac736bb9-0b41-4be4-a17c-2037eccef645",
"payment_id": "",
"data": {}
}
POST https://your-server.example/callback
{
"status": "MSG_FAILED",
"account_uid": "BS-0000-00000",
"service": "SMS",
"message_reference": "bc736bb9-6b41-4be4-a17c-2037eccbf611",
"message_id": "",
"data": {}
}
POST https://your-server.example/callback
{
"status": "PAYMENT_FAILED",
"account_uid": "BS-0000-00000",
"service": "MOMO",
"payment_reference": "momo-712-3f43-4609-a1e1-33f3e6464329",
"payment_id": "",
"data": {
"result": {
"code": "05",
"message": "Payment request 2fa failed"
}
}
}
Callbacks are signed with your account's signature key using HMAC-SHA512, the same primitive documented under Signature. Read the signature header, recompute the hash over the request body with your signature key, and compare the two with a constant-time comparison before trusting the payload.
const crypto = require('crypto');
function verifyCallback(rawBody, headerSignature, secret_key) {
const expected = crypto
.createHmac('sha512', secret_key)
.update(rawBody) // hash the exact bytes received
.digest('hex')
.toLowerCase();
const a = Buffer.from(expected);
const b = Buffer.from(String(headerSignature || '').toLowerCase());
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
Match the serialization exactly. The hash depends on the precise bytes hashed, so hash the raw request body as received rather than re-serialising a parsed object, or the signatures will not match.