Callback verification
Notification fields, both signing algorithms and the expected response.
When it fires
Once a payment succeeds, the platform sends a POST notification to the callback_url you supplied when creating the order.
Callback fields
| Field | Description |
|---|---|
reference | Your order id (customer transaction id) |
transaction_id | Platform transaction id |
amount | Order amount (fiat) |
token | Paid token |
network | Paid network |
amount_due | Amount actually received |
transaction_hash | On-chain transaction hash |
status | 2 = paid |
signature | Signature (HMAC-SHA256 for Alsopay, MD5 for EPay) |
Verification
- Take every parameter except
signature(signfor EPay) - Sort the names in ASCII order and join as
key1=value1&key2=value2... - Alsopay notification:
hex(HMAC-SHA256(joined, secret_key)), lowercase - EPay notification:
md5(joined + secret_key), lowercase
function verifyNotify(params, secretKey, useMd5 = false) {
const signature = params.signature ?? params.sign
const sorted = Object.keys(params)
.filter((k) => k !== 'signature' && k !== 'sign')
.sort()
.map((k) => k + '=' + params[k])
.join('&')
if (useMd5) {
return crypto.createHash('md5').update(sorted + secretKey).digest('hex') === signature
}
return crypto.createHmac('sha256', secretKey).update(sorted).digest('hex') === signature
}
Expected response
- Verify first, then change the order status; ignore the request outright if verification fails
- Reply with the string
{"status":"success"}to acknowledge - If you do not acknowledge in the expected way, the platform retries according to its configuration; retries and manual handling are visible in the platform's ops view
Notes
- The callback is server-to-server and is not affected by browser CORS
- Keep
secret_keyon your server only — never ship it to the frontend - You may receive the same
transaction_idmore than once; make your handler idempotent
