Skip to content
PGSwift Docs
Documentation/Virtual Account

Virtual Account

Merchants can use this API to create a checkout interface for processing transactions

POST /api/create/va

Request

NameTypeRequiredValidationDescription
merchant_transaction_idstringtrueMerchant-provided unique transaction identifier.
amountstringtrueNumeric, 1-12 digitsTransaction amount expressed as a numeric value.
currencystringtrueAllowed value: "IDR"Transaction currency (only Indonesian Rupiah is supported).
bank_codestringtrueAllowed value: see the table belowBank code used for the transaction
customer_namestringtrueBetween 5 - 25 characters. Allowed chars: a-z, A-Z, 0-9, - (dash), (space)Customer name linked to the transaction.
product_namestringtrueBetween 5 - 25 characters. Allowed chars: a-z, A-Z, 0-9, - (dash), (space)Product name linked to the transaction.
descriptionstringfalseOptional transaction information.
success_redirect_urlstringfalseURL to redirect the customer upon successful payment. Also supports mobile deep link URLs.

Supported bank_code values

bank_code Numeric code Bank
BCA 014 Bank Central Asia
BRI 002 Bank Rakyat Indonesia
BNI 009 Bank Negara Indonesia
MDR 008 Bank Mandiri
PRMT 013 Bank Permata
CIMB 022 CIMB Niaga
BNC 490 Bank Neo Commerce
BDM 011 Bank Danamon
BSI 451 Bank Syariah Indonesia
MUA 147 Bank Muamalat
SNM 153 Bank Sinarmas
OCBC 028 Bank OCBC
FINPAY — Finpay
NOBU 503 Bank Nationalnobu
INA 513 Bank Ina Perdana
CIMBS — CIMB Niaga Syariah

Each bank can be sent as its letter code or its numeric code; both resolve to the same channel, and responses and webhooks always return the letter code. CIMBS and FINPAY accept the letter code only.

{
    "merchant_transaction_id": "ICZ10000001",
    "amount": "100000",
    "currency": "IDR",
    "bank_code": "BRI",
    "description": "Lorem Ipsum",
    "customer_name": "John Doe",
    "product_name": "Product Test",
    "success_redirect_url": "https://example.com/success"
}

Response

Name Description
status Request status indicator. true indicates success, false indicates failure.
message Result message for the request. Usually "success" when the request succeeds.
data.transaction_id System-generated unique transaction identifier.
data.va_number Generated Virtual Account (VA) number for customer payment. This field can be empty if no virtual account number is available.
data.channel Bank or payment channel used for the Virtual Account.
data.redirect_url Redirect URL for users (when applicable). This field can be null if no redirect URL is available.
data.expired_at Payment expiry datetime, server time (UTC+7), no offset, format YYYY-MM-DD HH:MM:SS (e.g. "2025-02-26 19:00:00"). null if not applicable.
data.expired_at_iso Same expiry as expired_at, as ISO 8601 with offset (e.g. "2025-02-26T19:00:00+07:00"). Same format on every channel. null when expired_at is null.
data.payment_channel Normalized payment channel, one format for every payment type and provider: a value such as QRIS, VA_BRI, BANK_BCA, or EWALLET_DANA (payment type prefix + code from the Appendix). null when the channel cannot be determined. Prefer this over channel.
data.success_redirect_url URL to redirect the customer upon successful payment. Also supports mobile deep link URLs.
{
    "status": true,
    "message": "success",
    "data": {
        "transaction_id": "9e536777-2bfa-4161-9931-35f5c4b23faf",
        "payment_channel": "VA_MDR",
        "va_number": "8999817535253527",
        "channel": "MDR",
        "redirect_url": "{host}/checkout/9e536777-2bfa-4161-9931-35f5c4b23faf/va/MDR",
        "success_redirect_url": "https://example.com/success",
        "expired_at": "2025-02-26 19:00:00",
        "expired_at_iso": "2025-02-26T19:00:00+07:00"
    }
}

Webhook

© 2026 PGSwift. All rights reserved.