Pay-In · Vietnam
Overview
The Pay-In API initiates collection transactions from customers. This page covers Vietnam (country code vn) with two ordering modes:
| Mode | Path | Description |
|---|---|---|
| Cashier mode | /pay/prePay | Default. Returns cashierUrl for the platform H5 cashier |
| API mode | /pay/transOrder | Requires method in the request; returns payData / payDataType |
method (Vietnam Pay-In codes) is listed in Regional Payment Guide — Vietnam.
Integration note
Cashier mode is enabled by default. Contact support to whitelist your merchant account before integrating API mode.
Request Header
Shared by both modes:
| Field | Required | Type | Description |
|---|---|---|---|
| Content-Type | M | String | Fixed value: application/json |
Cashier Mode (prePay)
The merchant pre-creates an order and receives a cashierUrl, redirecting the customer to the platform's hosted cashier to pick a payment method and complete payment.
Request URL
Domain: Prefer unified host
openapi.toppayment.com(path unchanged); legacy country domain (e.g.global-vn-openapi.toppayment.com) remains available.
| Environment | URL |
|---|---|
| Sandbox | https://openapi.toppayment.com/sandbox/vn/pay/prePay |
| Production | https://openapi.toppayment.com/vn/pay/prePay |
Request Body
| Field | Required | Type | Description |
|---|---|---|---|
| mchNo | M | String(32) | Merchant number |
| orderNum | M | String(64) | Merchant order number |
| amount | M | Number(32,8) | Transaction amount No decimals allowed for Vietnam, pass an integer e.g. 100000 |
| productDetail | O | String(100) | Product detail |
| method | O | String(16) | Vietnam method Optional; if omitted, the customer chooses on the cashier page. Supported: BANK_QR, MOMO, ZALO, VTPAY — see Regional Payment Guide — Vietnam |
| timestamp | M | String(13) | Timestamp in milliseconds |
| customerName | O | String(64) | Customer name |
| customerEmail | O | String(64) | Customer email |
| customerPhone | O | String(32) | Customer phone |
| expiryPeriod | O | Number(1-9999) | Expiry in minutes |
| downNotifyUrl | M | String(255) | Async callback URL |
| redirectUrl | O | String(512) | Redirect URL |
| sign | M | String | Signature, see Signature |
Request Example
{
"mchNo": "{{mchNo}}",
"orderNum": "VN1232451",
"amount": 100000,
"productDetail": "Test",
"method": "BANK_QR",
"timestamp": "1749451858772",
"customerName": "AMY",
"customerEmail": "[email protected]",
"customerPhone": "0817773255",
"expiryPeriod": 1440,
"downNotifyUrl": "https://123.com",
"redirectUrl": "http://hxxyhyo.mr/gchmnzv",
"sign": "Generate per signature rules and replace"
}
Response Body Parameters
| Field | Required | Type | Description |
|---|---|---|---|
| success | M | Boolean | Request success status |
| code | M | String | 9999: success; other values: failure |
| msg | O | String | Message |
| timeStamp | M | Number | Server response time in milliseconds |
| data | M | Object | Transaction data |
| orderNum | M | String | Merchant order number |
| platOrderNum | M | String | Platform order number |
| amount | M | Number | Amount |
| fee | M | Number | Fee |
| method | M | String | Payment method (Vietnam) — see Regional Payment Guide — Vietnam |
| productDetail | O | String | Product detail |
| customerName | O | String | Customer name |
| customerEmail | O | String | Customer email |
| customerPhone | O | String | Customer phone |
| validTime | M | Number | Expiry timestamp (ms) |
| cashierUrl | M | String | Cashier URL for redirecting the customer to complete payment |
Response Example
{
"success": true,
"code": "9999",
"msg": null,
"timeStamp": 1767840272829,
"data": {
"orderNum": "VN1232451",
"platOrderNum": "PRE2009093829059153920",
"amount": 100000,
"fee": 2000.00,
"method": "BANK_QR",
"productDetail": "Test",
"customerName": "AMY",
"customerEmail": "[email protected]",
"customerPhone": "0817773255",
"validTime": 1767926672819,
"cashierUrl": "https://example.cashier/pay"
}
}
API Mode (transOrder)
When the merchant specifies a payment method in the request, the order is sent directly to the upstream channel and the response returns payData / payDataType, without redirecting to the platform's hosted H5 cashier.
Request URL
| Environment | URL |
|---|---|
| Sandbox | https://openapi.toppayment.com/sandbox/vn/pay/transOrder |
| Production | https://openapi.toppayment.com/vn/pay/transOrder |
Request Body
Differences from Cashier mode:
| Field | Required | Type | Description |
|---|---|---|---|
| method | M | String(16) | Vietnam method Required for API mode. Supported: BANK_QR, MOMO, ZALO, VTPAY — see Regional Payment Guide — Vietnam |
All other fields are the same as Cashier mode.
Request Example
{
"mchNo": "{{mchNo}}",
"orderNum": "VNAPI1232451",
"amount": 100000,
"productDetail": "Test",
"method": "BANK_QR",
"timestamp": "1749451858772",
"customerName": "AMY",
"customerEmail": "[email protected]",
"customerPhone": "0817773255",
"expiryPeriod": 1440,
"downNotifyUrl": "https://123.com",
"sign": "Generate per signature rules and replace"
}
Response Body Parameters
Common response fields (success, code, msg, timeStamp, and orderNum, platOrderNum, amount, fee, method, productDetail, customerName, customerEmail, customerPhone, validTime under data) are the same as Cashier mode. API mode adds:
| Field | Required | Type | Description |
|---|---|---|---|
| payData | M | String | Payment data A JSON string (same structure for all payDataType values) that must be parsed (see "payData structure" below) |
| payDataType | M | String | Data type of the inner payData.payData fieldValues: QR_CODE, QR_URL, CASHIER_URL (see table below) |
payDataType Reference
payDataType declares the meaning of the inner payData field after parsing the JSON. Always handle by the actual returned value — do not hardcode a single type:
| payDataType | Meaning of inner payData |
|---|---|
QR_CODE | QR text content — render as a QR code on your side (currently the common return type) |
QR_URL | QR code image URL — display the image directly via this URL |
CASHIER_URL | HTTPS payment page URL — redirect the customer to this link to complete payment |
payData Structure
For Vietnam, payData is always a serialized JSON string regardless of payDataType. The merchant must parse it into a JSON object first, then use the following fields to render the cashier UI or guide the customer to transfer funds:
| Field | Description |
|---|---|
| payData | Payment credential content; meaning is determined by the outer payDataType (see table above) |
| accNo | Receiving bank account number |
| accName | Receiving account holder name |
| accBankName | Receiving bank name |
| paymentCode | Transfer memo / payment code The customer must include this when transferring, used by the upstream to match the order |
| payAmount | Actual amount payable May differ slightly from the requested amount; use this field as the source of truth |
Response Example
{
"success": true,
"code": "9999",
"msg": null,
"timeStamp": 1767840272829,
"data": {
"orderNum": "VNAPI1232451",
"platOrderNum": "PRE2009093829059153921",
"amount": 100000,
"fee": 2000.00,
"method": "BANK_QR",
"productDetail": "Test",
"customerName": "AMY",
"customerEmail": "[email protected]",
"customerPhone": "0817773255",
"validTime": 1767926672819,
"payData": "{\"payData\":\"00020101021226650016COM.EXAMPLE.QR...\",\"accNo\":\"1234567890\",\"accName\":\"NGUYEN VAN A\",\"accBankName\":\"ACB\",\"paymentCode\":\"ERD5HGFK\",\"payAmount\":\"100000\"}",
"payDataType": "QR_CODE"
}
}
payData is a string
In the example above, the payData field's value is itself an escaped JSON string, not a JSON object. Merchants must run JSON.parse on this string again to access accNo, accName, accBankName, paymentCode, and payAmount.
Notification
Both ordering modes share the same asynchronous notification.
HTTP Request (callback)
| Field | Required | Type | Description |
|---|---|---|---|
| Content-Type | M | String | application/json |
Notification Body
| Field | Required | Type | Description |
|---|---|---|---|
| platOrderNum | M | String | Platform order number |
| version | M | String | API version, e.g. v1 |
| orderNum | M | String | Merchant order number |
| amount | M | Number | Amount |
| fee | M | Number | Fee |
| customerName | O | String | Customer name |
| customerEmail | O | String | Customer email |
| customerPhone | O | String | Customer phone |
| status | M | String | Status — see Transaction Status Codes |
| sign | M | String | Callback signature |
Response
SUCCESS
Notification Example
{
"platOrderNum": "PRE2009165141186183168",
"version": "v1",
"orderNum": "VN12324521",
"amount": 100000,
"fee": 2000,
"customerName": "AMY",
"customerEmail": "[email protected]",
"customerPhone": "0817773255",
"status": "SUCCESS",
"sign": "sample-signature"
}
