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

FieldDescription
referenceYour order id (customer transaction id)
transaction_idPlatform transaction id
amountOrder amount (fiat)
tokenPaid token
networkPaid network
amount_dueAmount actually received
transaction_hashOn-chain transaction hash
status2 = paid
signatureSignature (HMAC-SHA256 for Alsopay, MD5 for EPay)

Verification

  1. Take every parameter except signature (sign for EPay)
  2. Sort the names in ASCII order and join as key1=value1&key2=value2...
  3. Alsopay notification: hex(HMAC-SHA256(joined, secret_key)), lowercase
  4. 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_key on your server only — never ship it to the frontend
  • You may receive the same transaction_id more than once; make your handler idempotent