Create Order VA API

Create a new VA order via SePay API for a BIDV, Sacombank, Vietcombank, VietinBank or Shinhan Bank account. Each order gets its own VA number to match payments.

||

Create a New Order

POST
https://userapi.sepay.vn/v2/bank-accounts/{ba_xid}/orders

Request Body (JSON or form-data)

ba_xidstringrequired

Bank account UUID

tidstringrequired (Vietcombank)

Vietcombank Terminal ID (required for Vietcombank accounts). Fetch via GET /bank-accounts/{ba_xid}/terminals. This is the raw Vietcombank-issued Terminal ID, not the SePay xid UUID.

va_prefixstringrequired (Sacombank)

VA prefix (required for Sacombank accounts). Example SEP200001WEB. Not used for BIDV, Vietcombank or VietinBank.

order_codestring

Order code (alphanumeric, 6-50 chars). SePay normalises it to upper case, so a lower-case code comes back upper-cased. Auto-generated if empty, as 10 upper-case characters. Vietcombank and Shinhan Bank limit to 15 characters max.

amountintegerrequired (Sacombank, Vietcombank, VietinBank, Shinhan Bank)

Amount (positive integer, max 12 digits). Required for Sacombank, Vietcombank and Shinhan Bank accounts (exact amount only), and for VietinBank accounts (underpayment accepted, overpayment rejected). Optional for BIDV.

va_holder_namestring

VA holder name, max 300 characters. BIDV enterprise accounts still require max 70 characters, uppercase A-Z, digits 0-9 and spaces only (contact SePay to enable custom VA name). Shinhan Bank accepts up to 300 characters with no uppercase constraint; when omitted it falls back to the name registered with the bank. Not supported by Sacombank, Vietcombank or VietinBank.

durationinteger

VA duration in seconds. Shinhan Bank defaults to 86400 seconds (1 day) and caps at 2592000 seconds (30 days). A larger value is silently lowered to 2592000, with no error. Read expired_at in the response for the real deadline.

with_qrcodeenum

Include QR code in response (0 or 1)

qrcode_templateenum

QR code template

Bank-specific differences

ParameterBIDVSacombankVietcombankVietinBankShinhan Bank
tidNot neededNot neededRequired. See List Terminals.Not neededNot needed
va_prefixNot neededRequired. See VA Prefixes.Not neededNot neededDo not send
amountOptionalRequired (exact amount only)Required (exact amount only)Required (underpayment accepted, overpayment rejected)Required (exact amount only)
order_code6-50 chars6-50 chars6-15 chars6-50 chars6-15 chars
va_holder_nameBIDV enterprise only (feature must be enabled, contact SePay)Not supportedNot supportedNot supportedUp to 300 chars; falls back to the name registered with the bank
durationNo default limitPer configurationDefaults to 900 secondsNo default limitDefaults to 86400 seconds, caps at 2592000 seconds. A larger value is silently lowered to 2592000, with no error. Read expired_at in the response for the real deadline
Sacombank, Vietcombank and Shinhan Bank accept the exact amount only

These three banks do not support partial payment. Orders only transition from Pending to Paid or Cancelled.

Shinhan Bank rejects a wrong amount, but an expired VA can still receive money

SePay registers Shinhan Bank VAs with an amount condition, so a payer sending the wrong amount over Napas is rejected the moment they confirm the transfer and the money never leaves their account.

A VA past its expired_at can still receive money at the bank for a short time before SePay cancels it. That payment is still recorded as a transaction and sent through the webhook, but it does not close the order. You need to reconcile these transactions manually.

VietinBank needs identified-account collection registered

A VietinBank enterprise account must be registered for identified-account collection with VietinBank before it can create orders. An unregistered account returns 422 vietinbank_va_order_not_enabled. If you hit this error, contact SePay for support.

A VietinBank order always requires an amount, but accepts underpayment: the order moves to Partially and the VA keeps accepting until the total is reached. A transfer above amount is not matched to that VA: the money still lands in the real account, but the order does not move to Paid.

Vietcombank tid parameter

tid must be the raw Vietcombank-issued Terminal ID (e.g. 20933557), not the SePay xid UUID. Fetch valid tid values via List Terminals before creating the order; if you don't have a terminal yet, see how to add a terminal for a Vietcombank enterprise/household business account. Sending a UUID returns 422 invalid_tid_format. If the tid does not belong to the bank account, SePay returns 422 invalid_tid.

Code Examples

>
>
>
>
>
curl --request POST \
--url https://userapi.sepay.vn/v2/bank-accounts/f9e8d7c6-b5a4-3210-fedc-ba0987654321/orders \
--header 'Authorization: Bearer REPLACE_BEARER_TOKEN' \
--header 'content-type: application/json' \
--data '{"tid":"string","va_prefix":"string","order_code":"string","amount":0,"va_holder_name":"string","duration":0,"with_qrcode":"0","qrcode_template":"compact"}'

Response (HTTP 201)

Response 201 - Order created successfully
{
  "status": "success",
  "message": "Order created successfully",
  "data": {
    "id": "b2c3d4e5-f6a7-8901-bcde-f12345678902",
    "order_code": "ORDER2026001",
    "va_number": "963NQDORD1234567890AB",
    "va_holder_name": "TRAN THI B",
    "amount": 1000000,
    "status": "Pending",
    "bank_name": "BIDV",
    "account_holder_name": "TRAN THI B",
    "account_number": "1234567890",
    "expired_at": null,
    "qr_code": "data:image/png;base64,...",
    "qr_code_url": "https://vietqr.app/img?acc=963NQDORD1234567890AB&bank=BIDV&amount=1000000&template=compact"
  }
}
statusstring
messagestring
dataobject

Errors

HTTPerror_codeDescription
400-BIDV: Bank account is not an enterprise account
400-Sacombank: Merchant not activated for this account
400-Sacombank: va_prefix is invalid or not activated
400-VietinBank: Bank account is not an enterprise account
400-Shinhan Bank: The selected bank account must be an Enterprise account. The Shinhan account has not been set up for the API connection by SePay
409duplicateDuplicate order_code
422validation_errorValidation error
422vietinbank_va_order_not_enabledVietinBank: account is not registered for identified-account collection, or SePay has not opened the feature yet
422invalid_tid_formatVietcombank: tid is the SePay xid UUID instead of the raw Terminal ID
422invalid_tidVietcombank: tid does not belong to this bank account
500vcb_errorVietcombank: unexpected error while creating the order. Contact SePay support.
503vcb_connection_errorVietcombank: service temporarily disrupted. Please try again in a few minutes.
500shinhan_errorShinhan Bank: unexpected error while registering the VA. Contact SePay support.
503shinhan_connection_errorShinhan Bank: service temporarily disrupted. Please try again in a few minutes.