Skip to main content

Verify Signature

note

When RM sends a callback (webhook) to your notifyUrl, the response includes an X-Signature header. You should verify this signature using the RM Server Public Key to confirm the callback genuinely came from Revenue Monster and was not tampered with.

You can find the RM Server Public Key in Merchant Portal > Developer > Applications > Server Public Key.

important

All JSON keys — including keys inside nested objects — must be sorted alphabetically before encoding.


Verifying a Callback Signature

Step 1: Get the Callback Response Body

When RM calls your notifyUrl, the request body will be a JSON object. The following is an example for a Web/Mobile Payment callback:

itemOBJECT

Response payload

checkoutIdSTRING

Identifier for the checkout session

Example: "1617985392758071583"

urlSTRING

Checkout URL

Example: "https://sb-pg.revenuemonster.my/v2/checkout?checkoutId=1617985392758071583"

codeSTRING

"SUCCESS" if the payment succeeded. Otherwise an error code.

Example: "SUCCESS"

Callback Body
JSON
1{
2"code": "SUCCESS",
3"item": {
4 "checkoutId": "1617985392758071583",
5 "url": "https://sb-pg.revenuemonster.my/v2/checkout?checkoutId=1617985392758071583"
6}
7}

Step 2: Base64-encode the Response JSON

Sort the JSON keys alphabetically (including nested objects), make it compact, then Base64-encode it.

Sorted JSON (keys in alphabetical order):

Sorted JSON
JSON
1{
2"code": "SUCCESS",
3"item": {
4 "checkoutId": "1617985392758071583",
5 "url": "https://sb-pg.revenuemonster.my/v2/checkout?checkoutId=1617985392758071583"
6}
7}

Compact form (no whitespace) — this exact string is what gets Base64-encoded:

Sorted Compact JSON
JSON
{"code":"SUCCESS","item":{"checkoutId":"1617985392758071583","url":"https://sb-pg.revenuemonster.my/v2/checkout?checkoutId=1617985392758071583"}}

Base64 result:

Base64 Encoded
Text
eyJjb2RlIjoiU1VDQ0VTUyIsIml0ZW0iOnsiY2hlY2tvdXRJZCI6IjE2MTc5ODUzOTI3NTgwNzE1ODMiLCJ1cmwiOiJodHRwczovL3NiLXBnLnJldmVudWVtb25zdGVyLm15L3YyL2NoZWNrb3V0P2NoZWNrb3V0SWQ9MTYxNzk4NTM5Mjc1ODA3MTU4MyJ9fQ==

Step 3: Construct the Verification String

Build the same signing string format used for requests. The values of nonceStr and timestamp come from the RM callback request headers (X-Nonce-Str and X-Timestamp).

dataSTRINGrequired

Base64-encoded response body from Step 2. Omit if the body is empty.

Example: (See Step 2)

methodSTRINGrequired

HTTP method of the callback, lowercase

Example: "post"

nonceStrSTRINGrequired

Value of X-Nonce-Str from the RM callback request header.

Example: "VYNknZohxwicZMaWbNdBKUrnrxDtaRhN"

requestUrlSTRING

Omit this parameter when verifying a callback — it is not included in the callback signature.

Example: N/A

signTypeSTRINGrequired

Signing algorithm

Example: "sha256"

timestampSTRINGrequired

Value of X-Timestamp from the RM callback request header.

Example: "1527407052"

note

requestUrl is omitted when verifying callback signatures.

Example verification string:

Verification String
Text
data=eyJjb2Rl...&method=post&nonceStr=VYNknZohxwicZMaWbNdBKUrnrxDtaRhN&signType=sha256&timestamp=1527407052

Step 4: Verify Using the RM Server Public Key

Verify the X-Signature header from the RM callback against your constructed string using the RM Server Public Key.

important

Use the RM Server Public Key (not your own public key) to verify callbacks. Find it in Merchant Portal > Developer > Applications > Server Public Key.

Wrap it in standard PEM format before use:

PEM Format
Text
-----BEGIN PUBLIC KEY-----
<server_public_key_content>
-----END PUBLIC KEY-----

The verification process:

  1. Extract the signature value from the X-Signature header (strip the sha256 prefix).
  2. Verify the signature against your constructed string from Step 3 using the RM Server Public Key and sha256.
  3. If verification passes, the callback is authentic. If it fails, discard the request.