X-Signature-Timestamp: 1713982800
Body: {"transaction_id":"20260424-2333-4543-bbc8-482d90a8a960","status":"Approved","merchant_id":"2f585060-092c-43af-9efe-2db5439c8448","transaction_type":"Payout","merchant_transaction_reference":"3342798"}
1.
Extract X-Signature-Timestamp, X-Signature, and X-Signed-By from the request headers
2.
Verify the timestamp is within your tolerance window (recommended: 300 seconds / 5 minutes)
3.
Fetch the public keys from Signing public keys and choose the correct one based on X-Signed-By header value (please refer Public Key Caching section). 4.
Reconstruct the signed payload: timestamp + "." + raw_body
5.
Compute SHA-256 hash of the signed payload
6.
Base64-decode the X-Signature header
7.
Verify the RSA signature using the public key
Always verify before parsing. Do not parse the JSON body until the signature has been verified.
Use raw bytes. Do not convert the body to string, format, or re-serialize the JSON before verification.
Timestamp tolerance. We recommend rejecting callbacks with timestamps older than 5 minutes (300 seconds) to prevent replay attacks.
Key rotation. When we rotate signing keys (every month), a new X-Signed-By identifier will be used.