1. VA Opening
BPN OpenAPI
  • Get started
    • Introduction to BPN
    • Introduction to API
    • Architecture Overview
    • Authentication
    • Environments
    • Response envelope
    • Idempotency
  • Guides
    • Virtual Account
      • Virtual Account Overview
      • VA · Payin
      • VA · Statuses
      • VA · Currencies & limits
      • VA · Payout
      • VA · RFI
      • VA Opening
        • VND VA Opening
        • BRL VA Opening
    • Wallet
      • Wallet · Transfer
      • Wallet · Assets & limits
      • Wallet · Deposit whitelist
      • Wallet · PaymentLink
      • Wallet Overview
      • Wallet · Deposit
      • Wallet · Statuses
      • Wallet · Withdraw
    • Convert
      • Convert Overview
      • Convert · Quote & submit
      • Convert · Business types
      • Convert · Pairs & limits
      • Convert · Statuses
  • API Reference
    • Virtual Account
      • Virtual Account field notes
      • Inquiry Master VA Balance
      • List Primary Virtual Accounts
      • Create Virtual Account
      • Get Virtual Account Detail
      • List Virtual Account
      • List Virtual Account Orders
      • Get Virtual Account Order Detail
      • Refund Virtual Account Order
      • List RFI Sub Virtual Account
      • Get Sub Virtual Account RFI Template Info
      • Sub Virtual Account Submit RFI
      • Add Bank Account
      • List Bank Account
      • List Banks
      • Payout via Virtual Account
      • Send Email Verify Code
    • Wallet
      • Wallet field notes
      • Deposit Whitelist
        • Get Deposit Whitelist Options
        • Register Deposit Source Address
        • List Deposit Source Addresses
        • Get Deposit Source Address
        • Disable Deposit Source Address
        • Submit Payer Details for a Received Deposit
        • Save Sub-wallet Payer Profile
        • Update Sub-wallet Payer Profile
        • Get Sub-wallet Payer Profile
      • Get Asset Balance
      • Get Deposit Address
      • Add Deposit Sender
      • Add Withdraw Whitelist
      • Delete Withdraw Whiltelist
      • Request Withdraw
      • Query Wallet Internal Transfer Detail
      • List Wallet Internal Transfer order
      • Wallet Internal Transfer
      • Create Sub Account
      • Query Transaction History
      • List Wallets
      • List Sub Account
      • Get Transaction Detail
      • List Wallet Transactions
      • Get Wallet Transaction Detail
    • Payment Link
      • Abnormal fund
        • Abnormal funds
        • Matchable Payment links
        • Link Order(Abnormal fund)
        • Submit to platform
      • Create Payment Link
      • List Payment links
      • Get Curreny Network Config
    • Convert
      • Convert field notes
      • Inquery FX Rate
      • Get Stablecoin Quote
      • Create Stable Order
      • Get Order (Single) Detail
      • List Orders(Batch)
    • KYB
      • Share KYB/KYC Info For Sub User
      • Get KYB Sub User Status
    • Reconciliation
      • Get Reconciliation Order List By Page
    • External Provider
      • FE: Create stablecoin collection sub-account link
      • FE: Deposit Travel Rule
      • External Provider · Deposit whitelist
      • Create stablecoin collection sub-account link
      • Get sub wallet account
      • List sub wallet accounts
      • Change sub wallet status
      • Query stablecoin collection order list
      • Query stablecoin collection order status
      • Get quote
      • Accept stablecoin collection order
      • Reject stablecoin collection order
      • Query USD balance
      • USD Payout (withdrawal)
      • Query USD Payout order status
      • Query USD Payout order list
      • Create deposit Travel Rule link
    • Mock
      • Mock Virtual account Payin Order
      • Mock wallet deposit transaction
      • Mock Payin Order Refund
      • Mock Payout Order Update Status
    • Pay Session
      • Request Pay Session
    • Files
      • Request File Upload URL
  • Webhooks
    • Webhooks Overview
    • KYB notifications
    • Event catalogue
    • Resend Fail Webhook
    • Open Virtual Account Status
    • Virtual Account Payment Status
    • Virtual Account Invoice update
    • Transaction Status Notification
    • KYB Status Notification
    • Deposit Sender Detail Required
    • Abnormal Fund Notification
    • WALLET_TRANSFER_ORDER_UPDATED
    • Sub Virtual Account RFI Required
    • Sub Wallet Update
    • wallet address whitelist Update
    • Crypto Deposit Order Notification
    • Collect Order Updated
    • Usd Payout Order Updated
    • onboard result
    • partner order status
    • PaymentLink Notification
    • Deposit Whitelist Notification
  • Partner Flow
    • inquiry supported currency
    • KYC/KYB Sharing
    • inquiry onboard status
    • get price
    • Create order
    • order list
    • inquiry single order
    • get user deposit address
    • get payment instruction
    • sync fund notification
    • daily settlement records
  • Appendix
    • Enums quick reference
    • Enum
    • Virtual Account(VA) Support List & KYB requirement
  • Release Notes & Changelog
  • Errors
    • Error codes catalogue
  • Change Log
    • 2026-09-21 Virtual Account independent refund orders
    • Wallet deposit source-address whitelist
  1. VA Opening

VND VA Opening

Audience: Merchant Open API integrators
Related APIs:
#DocumentMethodPath
1Request File Upload URLPOST/v1/files/upload-url
2Create Virtual AccountPOST/v1/virtual-account/sub/create
3Get VA DetailGET/v1/virtual-account/sub/get
4Open Virtual Account StatusWebhook—
Opening a VND (Vietnam Dong) VA requires the beneficiary to pass onboarding review before the account can receive funds. This guide covers the opening flow, every request field, the validation rules applied to the submission, and how to read the outcome.

1. Flow#

Opening a VND VA is a two-phase asynchronous process:
1.
Onboarding review — you submit the beneficiary profile (KYC for an individual, KYB for a company) together with supporting documents. The submission is validated, then goes to review.
2.
Account creation — the virtual account is created and the receiving details are returned only after the review passes.
Important — A 200 response from Create Virtual Account means the application was accepted, not that the account exists. No account number is returned at submit time. Do not present the account to your end user, and do not instruct anyone to remit funds, until the account reaches SUCCESS.

1.1 Individual (KYC)#

No files are required for an individual application.

1.2 Corporate (KYB)#


2. File upload#

Corporate applications carry supporting documents. File bytes never pass through the Open API: you request a short-lived pre-signed URL, upload the file directly to object storage, and reference it by fileId.
Full field reference: Request File Upload URL

2.1 Three steps per file#

Step 1 — request an upload URL
{
  "documentType": "VA_ONBOARDING",
  "fileType": "pdf",
  "fileSize": 284517,
  "currency": "VND"
}
{
  "status": 200,
  "msg": "OK",
  "code": null,
  "data": {
    "fileId": "0f1c9a2e-5b34-4f0e-9a7a-1c2d3e4f5a6b",
    "uploadUrl": "https://s3.ap-southeast-1.amazonaws.com/bpn-files/files/10023/20260915/0f1c9a2e-5b34-4f0e-9a7a-1c2d3e4f5a6b.pdf?X-Amz-Algorithm=...&X-Amz-Signature=...",
    "expiresAt": "2026-09-15T07:12:44Z"
  },
  "traceId": "8f0a5b8c4e1f4d0e8f0a5b8c4e1f4d0e"
}
Step 2 — upload the bytes
HTTP PUT the raw file body to uploadUrl. The signature is already embedded in the query string, so do not attach your Open API credentials or any Authorization header. A 200 from storage means the object is stored.
Step 3 — reference the file
Use the returned fileId inside companyInfo.documents[].files[] and companyInfo.persons[].documents[].files[]. The internal storage key is never exposed.

2.2 Rules#

RuleValueEnforced at
documentTypeVA_ONBOARDINGUpload URL request
currencyVNDUpload URL request
Accepted fileTypepdf, jpg, jpeg, png, heicUpload URL request
Declared fileSizeOptional. When supplied it must be between 10 KB and 10 MBUpload URL request
Upload URL validity10 minutes from issue (expiresAt)Object storage
Real file typeDetected from the file header, not from the extension; must match the fileType you declaredCreate Sub VA
Real single file size≤ 10 MB (10485760 bytes)Create Sub VA
Real total submission size≤ 40 MB (41943040 bytes) across all files in one applicationCreate Sub VA
The limits marked Upload URL request are a pre-check on the values you declare. The authoritative type and size are read from the stored object when you create the account — a mismatch fails the application, not the upload.
Warning — An expired uploadUrl cannot be renewed. If the PUT did not complete before expiresAt, request a new URL and use the new fileId. A fileId whose object was never uploaded fails the application.
Each fileId belongs to the merchant account that requested it. Referencing another merchant's fileId fails the application.

3. Create Virtual Account — common fields#

Full field reference: Create Virtual Account
FieldRequiredRule
currencyYesVND
accountSubTypeYesSTATIC
userTypeYesIndividual or Corporate
individualInfoWhen userType=IndividualObject, must be non-empty
companyInfoWhen userType=CorporateObject, must be non-empty
primaryAccountIdNoWhen omitted, routing is resolved from currency
Note — Field naming. VND structured fields use camelCase (legalName, dateOfBirth, fileId). snake_case keys (legal_name, date_of_birth, file_id) are still accepted as a legacy fallback, but camelCase wins when both are present. New integrations should use camelCase only.
Date fields are YYYY-MM-DD. dateOfBirth, incorporationDate, and any supplied document dateOfIssue / dateOfExpiry are parsed strictly, so 2026-02-30 is rejected.

4. Individual (KYC) — individualInfo#

Twelve fields, no file attachments.
FieldRequiredRule / values
firstNameYesCombined with lastName into the full name on the application
lastNameYes
dateOfBirthYesStrict YYYY-MM-DD
emailNo
phoneNo
addressYesFull residential address
idNumberYesCitizen ID number
idTypeYes1 = Citizen ID. The only value accepted on the individual path — a passport cannot be used to open an individual account
sexYes1 = Male, 2 = Female, 3 = Other
nationalityYesCountry code
dateOfIssueYesCitizen ID issue date
dateOfExpiryYesCitizen ID expiry date
Note — On the individual path, idType, sex, dateOfIssue and dateOfExpiry are only checked for presence and type before submission — idType and sex must parse as integers, and the two dates only need to be non-empty. A value outside the ranges above, including an idType other than 1, is therefore not rejected immediately; it surfaces later as a rejected application. Send the values in the formats above.

5. Corporate (KYB) — companyInfo#

Three parts: the company profile, documents[] (company evidence), and persons[] (legal representative and directors).

5.1 Company profile#

FieldRequiredRule / values
legalNameYesRegistered legal name
registrationNumberYesBusiness registration number
incorporationCountryYesISO 3166-1 alpha-2 (e.g. VN); alpha-3 also accepted
incorporationDateYesStrict YYYY-MM-DD
addressYesRegistered address
emailNo
phoneNo
websiteNo
natureOfBusinessYesBusiness description
geographicScopeYesArray of country codes, e.g. ["VN", "SG"]

5.2 documents[] — company evidence#

Each element:
FieldRequiredRule
typeYesSee the table below
filesYesArray of { "fileId": "..." } (a bare fileId string is also accepted). 1–10 entries
documentNumberConditionalMandatory for type=4
dateOfIssueNoStrict YYYY-MM-DD when supplied
dateOfExpiryNoStrict YYYY-MM-DD when supplied
typeDocumentMandatory
1Incorporation paperYes
2Business registration extractNo
3Nature and scope declarationYes
4Import / export licenceNo — but documentNumber is mandatory if present
5Product imagesNo
9OtherNo
Submitting two entries with the same type merges their files into one document.

5.3 persons[] — legal representative and directors#

At least one person; at most 20.
FieldRequiredRule / values
roleYes1 = Legal representative, 2 = Director
firstNameYesCombined with lastName into the full name on the application
lastNameYes
dateOfBirthYesStrict YYYY-MM-DD
emailNo
phoneNo
addressYes
idNumberYes
idTypeYes1 = Citizen ID, 2 = Passport
sexYes1 = Male, 2 = Female, 3 = Other
nationalityYesCountry code
documentsYesExactly one identity document — see below
Each person carries one identity document:
{
  "documents": [
    {
      "dateOfIssue": "2019-03-14",
      "dateOfExpiry": "2029-03-13",
      "files": [{ "fileId": "..." }, { "fileId": "..." }]
    }
  ]
}
The identity document type is derived from the person's idType (1 → Citizen ID, 2 → Passport); do not set it yourself. documentNumber is taken from the person's idNumber. If you send several document objects for one person, all their files are merged into that single identity document and the first non-empty dateOfIssue / dateOfExpiry wins — send one object to keep the result predictable.
Unlike the individual path, role, idType and sex inside persons[] are range-checked before submission and an out-of-range value fails the request immediately.

5.4 Cross-field rules#

These are checked before the submission is forwarded and fail the whole request:
Exactly one legal representative. persons[] must contain one and only one entry with role=1. Zero or two both fail.
Foreign persons must use a passport. A person whose nationality differs from companyInfo.incorporationCountry must have idType=2. Country codes are normalised to ISO alpha-3 before the comparison, so VN and VNM are treated as the same country.
Mandatory company documents. type=1 and type=3 must both be present with at least one file.
Import / export licence number. A type=4 document without documentNumber fails.

5.5 Submission limits#

LimitValue
Persons per application20
Documents per application (company + all person identity documents)30
Files per document10
Single file size10 MB
Total size of all files in one application40 MB

6. Track the result#

Two channels, use both:
Webhook. Subscribe to Open Virtual Account Status. It is delivered when the account reaches a terminal state. Deduplicate on eventId and treat the event as a prompt to query rather than as the source of truth.
Query. Call Get VA Detail (GET /v1/virtual-account/sub/get) with the virtualAccountId from the create response, and read status:
statusMeaningMerchant action
INITApplication accepted, not yet submitted for reviewWait
PROCESSINGAccount under reviewWait
SUCCESSAccount created and usableReceiving details are available; the account may now receive funds
FAILApplication rejected, or account creation failedRead failReason, correct, submit a new application
Review turnaround is measured in business days, not seconds. Keep a scheduled query as a fallback in case a webhook is delayed or missed, and do not block a user-facing request on the outcome.

7. Error reference#

7.1 Create Virtual Account — errors with a generic message#

Every other validation failure currently returns code: "10000046" with msg: "invalid parameter". The message does not say which field failed, so use the list below to diagnose. Each entry is a rule that, when broken, produces that generic error:
Mandatory fields and formats
A mandatory field in section 4 or section 5 is blank.
dateOfBirth or incorporationDate is not a valid YYYY-MM-DD date, or a supplied document dateOfIssue / dateOfExpiry is not.
role, idType or sex is not an integer.
Enum ranges inside persons[]
role is not 1 or 2.
idType is not 1 or 2.
sex is not 1, 2 or 3.
Cross-field rules
persons[] is empty, or has more than 20 entries.
persons[] does not contain exactly one role=1.
A person whose nationality differs from incorporationCountry does not use idType=2.
A type=1 or type=3 company document is missing or has no file.
A type=4 document has no documentNumber.
A person has no identity file, or more than one identity document.
A document has an empty files[], or more than 10 files.
The submission carries more than 30 documents in total.
File resolution
A fileId is unknown, or belongs to another merchant.
An upload URL was issued but the PUT never completed.
The stored file's real type differs from the fileType you declared, or cannot be detected.
The file service is unavailable — retry with the same fileIds.
Note — Include the response traceId when raising a support ticket; it identifies the exact request and the rule that failed.
Previous
VA · RFI
Next
BRL VA Opening
Built with