Skip to main content

Pay-In · Vietnam

TOPPAY TeamAbout 4 min

Overview

The Pay-In API initiates collection transactions from customers. This page covers Vietnam (country code vn) with two ordering modes:

ModePathDescription
Cashier mode/pay/prePayDefault. Returns cashierUrl for the platform H5 cashier
API mode/pay/transOrderRequires 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:

FieldRequiredTypeDescription
Content-TypeMStringFixed 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.

EnvironmentURL
Sandboxhttps://openapi.toppayment.com/sandbox/vn/pay/prePay
Productionhttps://openapi.toppayment.com/vn/pay/prePay

Request Body

FieldRequiredTypeDescription
mchNoMString(32)Merchant number
orderNumMString(64)Merchant order number
amountMNumber(32,8)Transaction amount
No decimals allowed for Vietnam, pass an integer
e.g. 100000
productDetailOString(100)Product detail
methodOString(16)Vietnam method
Optional; if omitted, the customer chooses on the cashier page. Supported: BANK_QR, MOMO, ZALO, VTPAY — see Regional Payment Guide — Vietnam
timestampMString(13)Timestamp in milliseconds
customerNameOString(64)Customer name
customerEmailOString(64)Customer email
customerPhoneOString(32)Customer phone
expiryPeriodONumber(1-9999)Expiry in minutes
downNotifyUrlMString(255)Async callback URL
redirectUrlOString(512)Redirect URL
signMStringSignature, 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

FieldRequiredTypeDescription
successMBooleanRequest success status
codeMString9999: success; other values: failure
msgOStringMessage
timeStampMNumberServer response time in milliseconds
dataMObjectTransaction data
orderNumMStringMerchant order number
platOrderNumMStringPlatform order number
amountMNumberAmount
feeMNumberFee
methodMStringPayment method (Vietnam) — see Regional Payment Guide — Vietnam
productDetailOStringProduct detail
customerNameOStringCustomer name
customerEmailOStringCustomer email
customerPhoneOStringCustomer phone
validTimeMNumberExpiry timestamp (ms)
cashierUrlMStringCashier 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

EnvironmentURL
Sandboxhttps://openapi.toppayment.com/sandbox/vn/pay/transOrder
Productionhttps://openapi.toppayment.com/vn/pay/transOrder

Request Body

Differences from Cashier mode:

FieldRequiredTypeDescription
methodMString(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:

FieldRequiredTypeDescription
payDataMStringPayment data
A JSON string (same structure for all payDataType values) that must be parsed (see "payData structure" below)
payDataTypeMStringData type of the inner payData.payData field
Values: 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:

payDataTypeMeaning of inner payData
QR_CODEQR text content — render as a QR code on your side (currently the common return type)
QR_URLQR code image URL — display the image directly via this URL
CASHIER_URLHTTPS 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:

FieldDescription
payDataPayment credential content; meaning is determined by the outer payDataType (see table above)
accNoReceiving bank account number
accNameReceiving account holder name
accBankNameReceiving bank name
paymentCodeTransfer memo / payment code
The customer must include this when transferring, used by the upstream to match the order
payAmountActual 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)

FieldRequiredTypeDescription
Content-TypeMStringapplication/json

Notification Body

FieldRequiredTypeDescription
platOrderNumMStringPlatform order number
versionMStringAPI version, e.g. v1
orderNumMStringMerchant order number
amountMNumberAmount
feeMNumberFee
customerNameOStringCustomer name
customerEmailOStringCustomer email
customerPhoneOStringCustomer phone
statusMStringStatus — see Transaction Status Codes
signMStringCallback 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"
}