OnlinePay API
V2
V1
V2
V1
  1. Introduction
  • Introduction
    • Introduction
    • How to Start
    • Country Code
    • Country Info
    • Currency Code
    • Error Code
    • Transfer Order Info Type
    • Transfer Order File Type
    • Per Bank
    • Spei Bank
    • Vietnam Bank
    • V2 Signature Specification
  • Payin
    • Credit Card API
      POST
    • Alipay API
      POST
    • GCash API
      POST
    • WeChat API
      POST
    • PIX API
      POST
    • Crypto API
      POST
    • Union Pay API
      POST
    • SPEI API
      POST
    • SEPA API
      POST
    • Per Transfer API
      POST
    • Cash App API
      POST
    • Google Pay API
      POST
    • Apple Pay API
      POST
    • MONO API
      POST
    • Vietnam Bank API
      POST
    • CheckOut API
      POST
    • CheckOut Payment API
      POST
    • OnRamps API
      GET
  • Payout
    • PER Transfer Payout API
    • Checkout Payout API
    • Card Payout API
    • Bank Account Payout API
    • PIX Payout API
    • PER Transfer Payout API
    • SPEI Payout API
    • CashApp Payout API
    • Checkout Payout API
    • Query Payout Order API
    • Upload SEPA File API
  • Refund
    • Refund API
  • Card
    • Create Cardholder API
    • Create Card API
    • Active Card API
    • Freeze Card API
    • UnFreeze Card API
    • Cancel Card API
    • TopUp Card API
    • Card Withdraw API
    • Query Card Balance API
    • Query Card Info API
    • Query Card Transaction API
    • Add VPA Scene API
    • UploadFile API
  • Query
    • Query Payout Order API
    • Query Order API
    • QueryOrderList API
    • QueryBalance API
    • QueryOrderAmount API
  • Notify
    • Pay Notify WebHook API
    • Card Notify WebHook API
    • Refund Notify WebHook API
    • Chargeback Notify WebHook API
  • Schemas
    • UserArray
    • CheckStandV2Request
    • ApiResponse
    • PayoutCheckStandV2Request
    • QueryPayOutV2Request
    • V2EncryptedEnvelope
    • V2EncryptedNotification
    • PaymentNotificationPayload
    • ProductParams
    • Category
    • PayoutCheckStandV2Response
    • PaymentNotification
    • QueryPayOutV2Response
    • PayoutQueryResult
    • Pet
    • OrderQueryV2Data
    • PayoutCheckStandV2Data
    • CheckStandV2Response
    • RefundNotificationPayload
    • CheckStandV2Data
    • ChargebackNotificationPayload
    • Tag
    • OrderQueryV2Request
    • OrderQueryV2Response
    • Order
    • User
  1. Introduction

V2 Signature Specification

This document describes the signature mechanism used by all V2 APIs. V2 uses RSA-SHA256 exclusively for both request signing and response verification. MD5 signing is not supported in V2.

1. Key Preparation#

Generate Your RSA Key Pair#

1.
Generate a 2048-bit RSA key pair (use the KeyPairExample utility provided by OnlinePay).
2.
Your Private Key — Keep this secret in your backend. You will use it to sign requests.
3.
Your Public Key — Upload to OnlinePay Developer Center > User PublicKey.

Obtain the OnlinePay Public Key#

1.
In Developer Center, locate the field OnlinePay PublicKey.
2.
Click View to obtain the OnlinePay public key.
3.
You will use this key to:
Verify response signatures
Verify and decrypt webhook notifications

2. Request Signing#

Every V2 API request must include a sign field in the request body. The sign value is generated as follows:

Step 1 — Build the Sign String#

1.
Take all request body parameters.
2.
Exclude the following fields (they do not participate in signing):
Excluded FieldReason
signThe signature itself
authorizationHTTP header value
refererHTTP header value
paymentTypeHTTP header value
serverNameServer-side value
userAgentHTTP header value
protocolIdInternal field
isfunctionInternal field
3.
Skip any field with a null or empty value.
4.
Sort the remaining fields alphabetically by key (ascending, case-sensitive).
5.
For nested objects and arrays: serialize to JSON with all keys sorted alphabetically at every level.
6.
Concatenate as key1=value1&key2=value2.
Example:
Request body:
{
    "merNo": 104001001,
    "merOrderNo": "ORD20260527001",
    "currencyCode": "USD",
    "sourceAmount": "100.00",
    "notifyUrl": "https://merchant.com/notify",
    "returnUrl": "https://merchant.com/return",
    "sign": "..."
}

Fields after exclusion & sorting:
currencyCode=USD&merNo=104001001&merOrderNo=ORD20260527001&notifyUrl=https://merchant.com/notify&returnUrl=https://merchant.com/return&sourceAmount=100.00
Nested object example:
Request body contains:
{
    "productInfoList": [
        {"sku": "SKU001", "price": "50.00", "productName": "Product A"}
    ],
    "merNo": 104001001
}

Sign string (productInfoList serialized with sorted keys):
merNo=104001001&productInfoList=[{"price":"50.00","productName":"Product A","sku":"SKU001"}]

Step 2 — Generate the RSA-SHA256 Signature#

sign = Base64(SHA256WithRSA(signString, yourPrivateKey))
Algorithm: SHA256WithRSA (RSASSA-PKCS1-v1_5 with SHA-256)
Input: The sign string from Step 1
Key: Your RSA private key (PKCS#8 format, Base64 encoded)
Output: Base64-encoded signature string

Step 3 — Include in Request#

Add the generated sign value to the request body:
{
    "merNo": 104001001,
    "merOrderNo": "ORD20260527001",
    "currencyCode": "USD",
    "sourceAmount": "100.00",
    "sign": "Base64EncodedSignatureString..."
}

3. Response Verification#

V2 API responses include a sign field at the top level:
{
    "code": "00000",
    "message": "SUCCESS",
    "data": { ... },
    "sign": "Base64EncodedSignatureString..."
}

Verification Steps#

1.
Build the sign string from the response fields using the same rules as request signing (exclude sign, skip null/empty, sort alphabetically, concatenate as key=value pairs).
2.
Verify the signature using the OnlinePay RSA Public Key:
boolean valid = SHA256WithRSA.verify(responseSignString, response.sign, onlinePayPublicKey)
3.
If verification fails, do not trust the response — contact OnlinePay support.

4. Webhook Notification Verification#

V2 webhook notifications (payment result, refund result, chargeback, etc.) use RSA+AES hybrid encryption. You will receive an encrypted payload instead of plaintext JSON.

Notification Payload Structure#

{
    "encryptedData": "AES-encrypted payment result (Base64)",
    "encryptedKey": "RSA-encrypted AES key (Base64)",
    "signType": "RSA256"
}

Step 1 — Decrypt the AES Key#

Use the OnlinePay RSA Public Key to decrypt the encryptedKey:
aesKey = RSA_Decrypt(Base64Decode(encryptedKey), onlinePayPublicKey)
Note: OnlinePay encrypts the AES key with its private key. You decrypt with the OnlinePay public key.

Step 2 — Decrypt the Data#

Use the AES key from Step 1 to decrypt encryptedData:
plaintext = AES_Decrypt(Base64Decode(encryptedData), aesKey)
The decrypted result is a JSON string containing the notification data.

Step 3 — Verify the Signature#

The decrypted JSON contains a sign field:
{
    "tradeNo": "T20260527001",
    "merOrderNo": "ORD20260527001",
    "code": "00000",
    "message": "SUCCESS",
    "sign": "Base64EncodedSignature..."
}
Verify the signature using the same method as response verification (Section 3):
1.
Build the sign string from all fields in the decrypted JSON, excluding sign and other excluded fields listed in Section 2.
2.
Verify with the OnlinePay RSA Public Key:
boolean valid = SHA256WithRSA.verify(signString, notification.sign, onlinePayPublicKey)

Step 4 — Acknowledge the Notification#

After successful verification, respond with HTTP 200. Any other status code will trigger OnlinePay to retry the notification.
Retry Policy: If OnlinePay does not receive HTTP 200, it will retry at increasing intervals. Ensure your endpoint is idempotent.

5. Quick Reference#

OperationKey UsedAlgorithm
Sign requestYour RSA private keySHA256WithRSA
Verify responseOnlinePay RSA public keySHA256WithRSA
Decrypt notification AES keyOnlinePay RSA public keyRSA decrypt
Decrypt notification dataRandom AES key (from above)AES decrypt
Verify notification signatureOnlinePay RSA public keySHA256WithRSA

6. Error Codes#

CodeMessageDescription
40002SIGN_ERRORSignature verification failed. Check your private key and sign string construction.
Modified at 2026-05-27 08:59:15
Previous
Vietnam Bank
Next
Credit Card API
Built with