Skip to content
MrIvoryMrIvory
Connect processor Merchant panel

Signing

HASH

Requests and signed responses use one algorithm. This is what src/hash.js does.

  1. Take every field you will send except HASH itself. Skip keys whose value is undefined or null.
  2. Sort the field names ascending (ASCII / Unicode code point order).
  3. Join NAME=VALUE pairs with a tilde ~. Keep spaces inside values. Do not URL-encode.
  4. Append the Secret Key in lowercase with no separator and no extra ~.
  5. SHA-512 the UTF-8 bytes. Hex digest, then UPPERCASE. Length is 128 characters.
  6. Send that string as HASH.

Worked example (this sandbox)

Fields actually hashed (already in sort order). Demo merchant APP_ID is the seeded sandbox merchant — use your APP_ID when you have one.

Fields
AMOUNT=1000
APP_ID=1000221129001154
CURRENCY_CODE=784
CUST_CITY=Dubai
CUST_COUNTRY=AE
CUST_EMAIL=buyer@example.test
CUST_FIRST_NAME=Sara
CUST_LAST_NAME=Khan
CUST_PHONE=0501234567
CUST_STATE=DU
CUST_ZIP=00000
ORDER_ID=ORD-SANDBOX-1
RETURN_URL=https://merchant.example/return
TXNTYPE=SALE

Joined string, then the lowercase secret 5cd925b2d0254be0 glued on the end:

Canonical string
AMOUNT=1000~APP_ID=1000221129001154~CURRENCY_CODE=784~CUST_CITY=Dubai~CUST_COUNTRY=AE~CUST_EMAIL=buyer@example.test~CUST_FIRST_NAME=Sara~CUST_LAST_NAME=Khan~CUST_PHONE=0501234567~CUST_STATE=DU~CUST_ZIP=00000~ORDER_ID=ORD-SANDBOX-1~RETURN_URL=https://merchant.example/return~TXNTYPE=SALE5cd925b2d0254be0

SHA-512 hex uppercase:

HASH
9DD1824DBEF36703783B4C44572ABA9B1217735E915E69D02BEDF28DB662390AA0BAFAC5C3C73F90512F826C3813C318D60D7FA59C5A050711A7B201305C612A

Node

JavaScript
const crypto = require('crypto');
function computeHash(fields, secret) {
  const keys = Object.keys(fields)
    .filter((k) => k !== 'HASH' && fields[k] != null)
    .sort();
  const raw = keys.map((k) => `${k}=${fields[k]}`).join('~')
    + String(secret).toLowerCase();
  return crypto.createHash('sha512').update(raw, 'utf8').digest('hex').toUpperCase();
}

Responses

The gateway signs JSON and return-URL fields the same way, using only scalar properties (nested objects such as TRAIL are skipped). Verify HASH with your secret before you fulfil an order. Wrong hash on a request returns 323 Invalid Hash. Missing HASH returns 326.