Setu
    • Setu API documentation
    • Introduction
    • Signature & Code samples
    • Webhook Verification
    • India
      • PayIn
        • Payment Webhook
        • Payment Redirect
        • Create Payment
        • Fetch Payment Status
        • Initiate Refund
      • PayOut
        • Payout Webhook
        • Initiate Payout
        • Fetch Payout Status
    • Egypt
      • PayIn
        • Payment Webhook
        • Initiate Refund
        • Create Payment
        • Fetch Payment Status
      • PayOut
        • Payout Webhook
        • Initiate Payout
        • Fetch Payout Status
    • Nigeria
      • PayIn
        • Payment Webhook
        • Initiate Refund
        • Create Payment
        • Fetch Payment Status
      • PayOut
        • Payout Webhook
        • Initiate Payout
        • Fetch Payout Status
        • Bank Code
    • Indonesia
      • PayIn
        • Payment Webhook
        • Initiate Refund
        • Create Payment
        • Fetch Payment Status
      • PayOut
        • Payout Webhook
        • Initiate Payout
        • Fetch Payout Status
        • Bank Code
    • Account Balance
      POST
    • USDT Exchange Rate
      POST

    Webhook Verification

    RSA-SHA512 Webhook signature verification#

    I. Purpose#

    To confirm a webhook came from Setu and that its body was not changed, verify the Signature header with Setu’s RSA public key and SHA-512 (algorithm name SHA512withRSA).

    II. When verification is required#

    After receiving a Setu callback, verify Signature before handling the payload. Discard the callback if verification fails.

    III. Structure and rules#

    Callbacks include Signature and Timestamp. Verify SHA512withRSA over the string below, using Setu’s public key. The request path is not part of that string.
    1
    Verification algorithms
    Digest: SHA-512 (512-bit Secure Hash Algorithm)
    Signature: RSA, PKCS#1 v1.5
    Algorithm name: SHA512withRSA
    Encoding: standard Base64
    2
    Build the string to verify
    String to verify:
    stringToVerify = sha512Hex(rawBody) + timestamp
    Notes:
    rawBody: the raw callback JSON bytes as received (UTF-8). Parsing and re-serializing changes field order, whitespace, or number types, and verification fails.
    sha512Hex: SHA-512 of rawBody, lowercase hex, 128 characters.
    timestamp: the Timestamp header value as received, in seconds. Do not replace it with the local current time.
    The path, host, and query string are not included.
    Example body (no trailing newline; hash demonstration only):
    {"transactionRef":"e50f5496-1316-4fa6-a206-98be03550c4d","merchantRef":"19e5b36d-c9d6-4cb4-8e4e-e6fe0e3a0cb5","currency":"INR","method":"NATIVE","amount":"100.01","paidAmount":"100.01","fee":"5.5","status":"Success"}
    Lowercase hex SHA-512 of that body:
    9e0fa54a47570bf67f9bff06fbabc2a1a220863dfa5f50514e220287ad5bcdeb46f07090e1bf2180cba4360a45a35cb0cf9dd705401bddfdaa18c275ecbb8688
    If Timestamp is:
    1699447297
    Then the string to verify is:
    9e0fa54a47570bf67f9bff06fbabc2a1a220863dfa5f50514e220287ad5bcdeb46f07090e1bf2180cba4360a45a35cb0cf9dd705401bddfdaa18c275ecbb86881699447297
    3
    Verify with the public key
    Verify the UTF-8 bytes of stringToVerify with Setu’s RSA public key using SHA512withRSA.
    Base64-decode Signature with the standard alphabet before verification. The alphabet is case-sensitive. Do not use URL-safe Base64.
    The public key is X.509 (-----BEGIN PUBLIC KEY-----).
    A successful verification means Setu’s private key signed this body and timestamp, and neither was changed afterward.
    Callback headers:
    HeaderValue
    TimestampUnix time in seconds, the same value concatenated above
    SignatureStandard Base64 of the signature produced with Setu’s private key
    Content-Typeapplication/json

    IV. Security notes#

    Setu signs callbacks with its private key. The merchant verifies them with Setu’s public key.
    The string to verify is sha512Hex + timestamp, with no path. The merchant request formula path + sha512Hex + timestamp does not apply to callbacks.
    The body hash and timestamp are both covered by the signature. After verification succeeds, keep using fields from the raw body. Do not switch to a re-serialized JSON object.

    V. Important notes#

    The string to verify is case-sensitive and must match byte for byte. The body hash must be lowercase hex.
    Hash the raw HTTP body bytes. Do not pretty-print, reorder keys, or add or remove whitespace.
    Read Timestamp from the header. It is in seconds and must be the value Setu used when signing.
    Signature is standard Base64 (alphabet includes +, /, and =). Decode it before verifying.
    The example body only demonstrates the hash. Live callback fields are defined by the API reference. Verification still hashes the raw body that was received.

    VI. Code samples#

    Java
    Python
    PHP
    C#(.NET Core)
    Go
    Modified at 2026-10-08 20:05:49
    Previous
    Signature & Code samples
    Next
    Payment Webhook
    Built with