Virtual Accounts Create API

The following endpoint creates a new virtual account


Request parameters

Following are the parameters to be sent in the request body:

Fieldis required?Description
bank_codemandatoryType: string

The bank code for the Virtual Account

Supported Bank Codes: "BRI", "BCA", "MANDIRI", "PERMATA", "CIMB"
namemandatoryType: string

The name of virtual account

Example: "John's Virtual Account"
is_closedoptionalType: boolean (default: false)

Whether account can accept open(any amount) or closed(specific amount)

Example: true or false
amountoptionalType: string

Specify amount to be paid to va when is_closed=true

Example: "12000.12"
customermandatoryType: object

Object containing fields (id, email, mobile, given_name). One of (id, mobile, email) is mandatory field and given_name is mandatory.

Example: { "given_name": "Ardi Hanan", "mobile": "+6288888888", "email": "" }
expiry_minutesoptionalType: integer (default for is_reusable=true:1440 and is_reusable=false:15768000)

Number of minutes left till expiry from now maximum(15768000)

Example: 10000
account_suffixoptionalType: string (default: random)

Account suffix for the VA, if not specified a random suffix will be used to generate account_number

Example: "1234"
is_reusableoptionalType: boolean (default: true)

Whether multiple payments can be used for a particular VA

Example: true or false
min_amountoptionalType: number (default: nil)

Minimum amount to be paid to a VA in the case of is_closed=false

Example: 10000
max_amountoptionalType: number (default: nil)

Maximum amount which can be paid to a VA in the case of is_closed=false

Example: 20000
va_ref_idoptionalType: string (default: "")

A reference ID which the merchant wants to use for a specific VA

Example: "VA_XYZ_1234"
auto_disable_after_paymentoptionalType: boolean (default: false)

Disable a reusable VA temporariliy after a payment. Patch API can be used to enable it again after changing some parameters

Example: true or false

The following table has the maximum account_suffix lengths for each bank:

Bank CodeMax Length

Error Codes

DPAY_STATIC_VA_NOT_SUPPORTEDstatic va not supported
DPAY_STATIC_CLOSED_VA_NOT_SUPPORTEDstatic va (closed) not supported
DPAY_DYNAMIC_OPEN_VA_NOT_SUPPORTEDdynamic va (open) not supported
DPAY_MIN_MAX_AMOUNT_NOT_SUPPORTEDsetting min_amount and max_amount not supported
DPAY_STATIC_VA_EXPIRY_MINUTES_NOT_SUPPORTEDstatic va (expiry_minutes) not supported
DPAY_STATIC_VA_AUTO_DISABLING_VA_NOT_SUPPORTEDstatic va: auto disabling va not supported
DPAY_INTERNAL_ERRORan unclassified error
DPAY_INVALID_REQUESTan error in form fields
DPAY_UNAUTHORIZED_ACCESSan unauthorized access error

Sample Request

curl --location --request POST '' \
--header 'Authorization: [Base64({Your_Server_Key}:)]' \
--header 'Content-Type: application/json' \
--data-raw '{
    "bank_code": "PERMATA",
    "name": "Ardi Hanan Durian",
    "is_closed": true,
    "amount": "12333",
    "customer": {
        "given_name": "Ardi Hanan",
        "mobile": "+6288888888",
        "email": ""
    "expiry_minutes": 14400,
    "account_suffix": "123456",
    "is_reusable": true,
    "va_ref_id": "1234",
    "min_amount": 10000,
    "max_amount": 15000,
    "auto_disable_after_payment": true

Sample Response

The status code returned would be 201.

    "data": {
        "customer_id": "cus_CtZ8r2GOvq7341",
        "virtual_account": {
            "id": "va_sample_pWM5k3BUI63935",
            "bank_code": "PERMATA",
            "account_number": "88565004123456",
            "name": "Ardi Hanan Durian",
            "is_closed": true,
            "amount": 12333,
            "currency": "IDR",
            "customer_id": "cus_CtZ8r2GOvq7341",
            "is_sandbox": true,
            "created_at": "2022-06-28T10:38:54.350418Z",
            "expiry_at": "2022-07-08T05:08:54.353053Z",
            "metadata": {},
            "is_disabled": false,
            "is_paid": false,
            "is_reusable": true,
            "min_amount": null,
            "max_amount": null,
            "va_ref_id": "1234",
            "auto_disable_after_payment": true

Sample Error

Form Errors

Form errors are those which occur during form validation & contain an errors array and are thrown with status code 400.

    "error_code": "DPAY_INVALID_REQUEST",
    "request_id": "dp_JSN8xJULZ39583",
    "errors": [
            "field": "bank_code",
            "message": "can't be blank"
            "field": "name",
            "message": "can't be blank"
            "field": "customer",
            "message": "can't be blank needs either ID, Email or Mobile"
            "field": "customer.given_name",
            "message": "given name cannot be empty"
            "field": "expiry_minutes",
            "message": "can't be less than equal to 0"

Authorization Errors

Authorization errors are errors that occur during authorization. The status code returned is usually 401

    "error": "invalid Authorization header in request",
    "error_code": "DPAY_UNAUTHORIZED_ACCESS"

Other Errors

Other errors are failures which occur after form validation. The status codes codes are usually 400 & 500

    "error": "pq: VA Already Created",
    "error_code": "DPAY_INTERNAL_ERROR",
    "request_id": "dp_QMPB7IO53p6517"