Create Virtual Account
Endpoint: POST /v2/gc/virtual-accounts
Description: Apply for a new multi-currency collection (virtual) account for receiving cross-border funds. A virtual bank account opened by NeoPay for users.
Request
Request Body Field Descriptions (JSON)
requestId
string(32)
Yes
Merchant-generated unique request ID (UUID recommended). Used for idempotency.
vaRegCountry
string(32)
Yes
Country/region of registration for the virtual account in ISO 3166-1 alpha-3 format. See VA capabilities by country/region below for supported values and constraints.
string
Yes
Intended use of the virtual account. See applyUse enumeration and VA capabilities by country/region for country-specific availability.
currency
string(256)
Yes
Currency or comma-separated list of currencies in ISO 4217 format (e.g. "USD" or "USD,EUR,HKD").
subMerchantId
string(32)
Conditional
NeoX sub-merchant identifier if this virtual account belongs to a sub-merchant. Optional in general; required when the merchant operates in PSP mode.
webhookUrl
string
No
Merchant-hosted callback URL to receive asynchronous virtual account status notifications (VA_SUPPLEMENT_REQUIRED / VA_CREATION_RESULT / VA_MATERIAL_SUPPLEMENT — see Webhook).
remark
string
No
Free-text remark for the virtual account application.
expiredTime
string
No
Application expiry time. If not set, the platform default applies.
holderId
string(32)
No
Identifier of the account holder entity.
materialId
string(64)
No
Material submission ID referencing a prior material submission. Must be a value returned by the Supplement Virtual Account Material API.
string
No
Required when vaRegCountry is one of HKG/USA/LUX/DEU/DNK/GBR and applyUse=PLATFORM_INDEPENDENT_WEBSITE. See payType details below.
string
No
Required when applyUse is PLATFORM or PLATFORM_INDEPENDENT_WEBSITE. Value must match the supported shopType list for the selected vaRegCountry + applyUse combination. See shopType details below.
applyBankCode
string(32)
No
Preferred bank code for account opening. Leave empty to let the system assign automatically. When vaRegCountry=NGA, must be one of: Paga | Wema | FCMB | Fidelity Bank.
extraInfo
object
No
Additional information as key-value pairs. Contents vary by vaRegCountry and applyUse.
applyUse enumeration
Name: Intended use of the virtual account
Type:
stringRequired: Yes
Description: Indicates the business scenario used for virtual account application.
PLATFORM
Platform business scenario
PLATFORM_INDEPENDENT_WEBSITE
Platform independent website scenario
ADVERTISING
Advertising scenario
B2B
Business-to-business collection scenario
SERVICE_LOGISTICS
Service logistics scenario
SERVICE_AVIATION_TRAVEL
Service aviation and travel scenario
SERVICE_SOFTWARE
Software service scenario
Validate vaRegCountry, currency, applyUse, and shopType against the matrix below before submitting requests.
CHF/NZD are not part of the confirmed frontend constant (HKG_SINGLE_CURRENCIES) for this scenario, and JPY/SGD are multi-currency-only. If your integration relies on CHF/NZD/JPY/SGD for a single-currency HKG virtual account, confirm directly with the NeoX integration team before relying on this table.
shopType details
payType details
Additional constraints
For API-initiated virtual account applications,
IDR,PHP,VND, andMYRvirtual accounts only support merchants whose registered addresses are in Mainland China or Hong Kong, China.If multiple currencies are provided in
currency, preserve the platform-defined currency ordering and do not reorder manually.
Before submitting a request, confirm vaRegCountry, currency order, applyUse, shopType, and payType are all valid in the sections above.
Request sample
This is a real captured request (not a fabricated illustrative example):
Response
Response Field Descriptions
code
number
Response code.
data
object
Virtual account application result.
message
string
Response message.
neoResponseId
string
Unique NeoX response identifier.
There is no state field in the response envelope. The data object on create is also intentionally small — it does not return vaNumber, bank details, materialCode/materialInfoJson, etc. at creation time. Those only appear later, via Get Detail Virtual Account or the webhooks below.
data object fields:
id
string
NeoX identifier for this virtual account application. Use this value in all subsequent API calls (Get Detail, Supplement Material) that reference this application.
requestId
string
Echoes the merchant-supplied requestId.
status
string
Application status immediately after creation. Real captured observed value: INIT. See Get Detail Virtual Account for the fuller status lifecycle.
materialInfoJson is not returned by this endpoint — it is only present on Get Detail Virtual Account and in the VA_SUPPLEMENT_REQUIRED webhook. See materialInfoJson structure in the Webhook page for its field layout and an example value.
Response sample
Real captured response, corresponding to the request above:
To retrieve the assigned bank details, supplementary-material requirements, or final approval status, call Get Detail Virtual Account with this id, or listen for the VA_SUPPLEMENT_REQUIRED / VA_CREATION_RESULT webhooks (see Webhook).
Notes
Requires Bearer token in the Authorization header.
The Accept-Language header can be used to specify the response language (Support: "vi", "en").
Use a unique
requestIdfor each request to avoid duplicate submissions.The request body must be in JSON format.
When Get Detail Virtual Account shows a non-empty
materialCode, the application requires supplementary KYC material. Call Supplement Virtual Account Material (POST /v2/gc/virtual-accounts/supplement) with the details indicated bymaterialCode/materialInfoJson.This is an asynchronous operation. The final result (account opened with
vaNumberand bank info) is delivered via theVA_CREATION_RESULTwebhook (see Webhook) and can also be polled using Get Detail Virtual Account (GET /v2/gc/virtual-accounts).The
currencyfield accepts a single ISO 4217 code (e.g."USD") or a comma-separated list (e.g."USD,EUR,HKD") on the request. On the response (Get Detail),currencycomes back as an array, not a comma-joined string.
Last updated
Was this helpful?