# KS Pay — Merchant API Documentation

Version 1 · Updated 2026-09-23 · Production base URL: `https://api.kspyment.com` · Sandbox base URL: `https://sandbox-api.kspyment.com` · Backup base URL: `https://api.kspaypg.vip` (sandbox: `https://sandbox-api.kspaypg.vip`) — see §11

KS Pay is a payment gateway for accepting payments (**payin**) through QRIS and Virtual Accounts, and for sending funds (**payout**) to bank accounts and e-wallets in Indonesia. This document explains how to connect your system to the KS Pay API.

Besides the API, every merchant has a **dashboard** at `https://merchant.kspyment.com` (sandbox: `https://sandbox-merchant.kspyment.com`) to view transactions and balance, manage credentials and the webhook URL, create payment links, request withdrawals, and download reports. Sign in with the username/password given at registration; enable Google Authenticator on the Account page — it is required to request withdrawals from the dashboard.

In short:

1. You create a payin order → KS Pay returns **how to pay**: the payment page URL, plus the raw payment data (`payData`) when it is available.
2. The customer pays.
3. KS Pay sends a **webhook** to your server and the order status becomes `SUCCESS`; your balance increases.
4. You move funds out whenever you like with a **payout** to a bank account / e-wallet.

## 1. Credentials

Every merchant receives the following credentials from KS Pay:

| Credential            | Purpose                                                        |
| --------------------- | -------------------------------------------------------------- |
| **API Key** (`ksp_…`) | Identifies the merchant; sent in the header of every request   |
| **Secret Key**        | Signs requests. **Never send it** in a request                 |
| **Webhook Secret**    | Verifies the signature of webhooks KS Pay sends to your server |
| **Whitelisted IP**    | Your server IPs allowed to call the payout API                 |

Keep the Secret Key and Webhook Secret in an environment/secret manager, not in source code. Every request must go over HTTPS.

## 2. Required headers

| Header         | Value                                                                                                 |
| -------------- | ----------------------------------------------------------------------------------------------------- |
| `Content-Type` | `application/json`                                                                                    |
| `Accept`       | `application/json`                                                                                    |
| `X-API-Key`    | Merchant API Key                                                                                      |
| `X-Timestamp`  | Unix timestamp in **seconds** (e.g. `1758268800`). Tolerance ±5 minutes from the KS Pay server clock. |
| `X-Signature`  | See §3                                                                                                |

## 3. Signature

```text
X-Signature = hex( HMAC-SHA256( secretKey, timestamp + "." + rawBody ) )
```

- `timestamp` — exactly the value of the `X-Timestamp` header.
- `rawBody` — the JSON string **exactly** as sent. Sign the same string you send; do not re-encode it.
- For **GET** requests (no body), `rawBody` is the empty string, so the signed input is `"1758268800."`.

### PHP example

```php
$apiKey    = 'ksp_xxxxxxxx';
$secretKey = 'xxxxxxxxxxxxxxxx';
$baseUrl   = 'https://api.kspyment.com';

function kspayRequest(string $method, string $path, ?array $data = null): array
{
    global $apiKey, $secretKey, $baseUrl;

    $body      = $data === null ? '' : json_encode($data, JSON_UNESCAPED_SLASHES);
    $timestamp = (string) time();
    $signature = hash_hmac('sha256', $timestamp.'.'.$body, $secretKey);

    $ch = curl_init($baseUrl.$path);
    curl_setopt_array($ch, [
        CURLOPT_CUSTOMREQUEST  => $method,
        CURLOPT_POSTFIELDS     => $body === '' ? null : $body,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER     => [
            'Content-Type: application/json',
            'Accept: application/json',
            'X-API-Key: '.$apiKey,
            'X-Timestamp: '.$timestamp,
            'X-Signature: '.$signature,
        ],
    ]);
    $response = curl_exec($ch);
    $status   = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    return ['status' => $status, 'body' => json_decode($response, true)];
}

$result = kspayRequest('POST', '/api/v1/payin', [
    'merchantOrderNo' => 'INV-2026-0001',
    'amount'          => 150000,
    'channel'         => 'QRIS',
    'customerName'    => 'Budi Santoso',
    'customerEmail'   => 'budi@example.com',
    'customerPhone'   => '081234567890',
    'returnUrl'       => 'https://shop.example/order/INV-2026-0001',
]);

// Redirect the customer to $result['body']['payment']['url'] (see §5)
```

### Node.js example

```js
import crypto from 'node:crypto';

const API_KEY = 'ksp_xxxxxxxx';
const SECRET_KEY = 'xxxxxxxxxxxxxxxx';
const BASE_URL = 'https://api.kspyment.com';

async function kspayRequest(method, path, data) {
  const body = data === undefined ? '' : JSON.stringify(data);
  const timestamp = Math.floor(Date.now() / 1000).toString();
  const signature = crypto
    .createHmac('sha256', SECRET_KEY)
    .update(`${timestamp}.${body}`)
    .digest('hex');

  const response = await fetch(BASE_URL + path, {
    method,
    headers: {
      'Content-Type': 'application/json',
      Accept: 'application/json',
      'X-API-Key': API_KEY,
      'X-Timestamp': timestamp,
      'X-Signature': signature,
    },
    body: body || undefined,
  });
  return { status: response.status, body: await response.json() };
}
```

### curl example

```bash
BODY='{"merchantOrderNo":"INV-2026-0001","amount":150000,"channel":"QRIS","customerName":"Budi Santoso","customerEmail":"budi@example.com","customerPhone":"081234567890"}'
TS=$(date +%s)
# awk '{print $NF}' takes the last column — OpenSSL on Linux prints "(stdin)= <hex>", LibreSSL on macOS just "<hex>"
SIG=$(printf '%s.%s' "$TS" "$BODY" | openssl dgst -sha256 -hmac "$SECRET_KEY" | awk '{print $NF}')

curl -X POST https://api.kspyment.com/api/v1/payin \
  -H "Content-Type: application/json" -H "Accept: application/json" \
  -H "X-API-Key: $API_KEY" -H "X-Timestamp: $TS" -H "X-Signature: $SIG" \
  --data-raw "$BODY"
```

## 4. Endpoints

Base path: `https://api.kspyment.com/api/v1`. Rate limit: 120 requests/minute per merchant. All amounts are **whole rupiah** (integer, no decimals).

### 4.1 Check balance

`GET /api/v1/balance`

```json
{ "totalBalance": 9496500, "frozenAmount": 0, "availableBalance": 9496500 }
```

- `availableBalance` — funds you can pay out.
- `frozenAmount` — funds held for payouts still in progress.
- `totalBalance` = `availableBalance` + `frozenAmount`.

### 4.2 Bank & e-wallet codes for payout

Every payout needs a `bankCode`: KS Pay's own destination code, **not** the clearing/BI code (`014`, `008`, …) and not the bank name. Codes are uppercase exactly as listed (`BCA`, not `bca` or `Bank BCA`).

Most common codes:

| `bankCode`  | Destination            | `accountNumber` to send           |
| ----------- | ---------------------- | --------------------------------- |
| `BCA`       | Bank Central Asia      | account number                    |
| `BRI`       | Bank Rakyat Indonesia  | account number                    |
| `BNI`       | Bank Negara Indonesia  | account number                    |
| `MANDIRI`   | Bank Mandiri           | account number                    |
| `BSI`       | Bank Syariah Indonesia | account number                    |
| `CIMB`      | Bank CIMB Niaga        | account number                    |
| `PERMATA`   | Bank Permata           | account number                    |
| `DANAMON`   | Bank Danamon           | account number                    |
| `BTN`       | Bank Tabungan Negara   | account number                    |
| `JAGO`      | Bank Jago              | account number                    |
| `GOPAY`     | GoPay (e-wallet)       | phone number, e.g. `081234567890` |
| `DANA`      | DANA (e-wallet)        | phone number                      |
| `OVO`       | OVO (e-wallet)         | phone number                      |
| `SHOPEEPAY` | ShopeePay (e-wallet)   | phone number                      |
| `LINKAJA`   | LinkAja (e-wallet)     | phone number                      |

The full list (170+ banks and e-wallets) is in **Appendix A** at the end of this document. The list that is **currently active** for your account is always available from the API:

`GET /api/v1/banks`

```json
[
  { "code": "BCA", "name": "Bank Central Asia", "type": "BANK" },
  { "code": "MANDIRI", "name": "Bank Mandiri", "type": "BANK" },
  { "code": "DANA", "name": "DANA", "type": "EWALLET" }
]
```

Recommended approach: fetch `GET /api/v1/banks` when your application loads (or cache it for a few hours), show `name` to the user as the destination choice, and send the chosen `code` as `bankCode`. A code can be disabled temporarily; when that happens the payout is refused with 422 and `message` `This destination bank is currently unavailable.` — offer the user another destination.

### 4.3 Create payin

`POST /api/v1/payin`

| Field             | Type             | Notes                                                                                                                                |
| ----------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `merchantOrderNo` | string ≤100      | Your order number, characters `A-Z a-z 0-9 _ . -`. **Unique per merchant.**                                                          |
| `amount`          | integer          | Amount in rupiah                                                                                                                     |
| `channel`         | string           | `QRIS`, `VA BCA`, `VA BRI`, `VA MANDIRI`, `VA BNI`                                                                                   |
| `customerName`    | string 2–64      | Customer name                                                                                                                        |
| `customerEmail`   | string ≤64       | Customer email (valid)                                                                                                               |
| `customerPhone`   | string           | Customer phone, 8–20 digits, may start with `+`                                                                                      |
| `returnUrl`       | string, optional | Where the customer lands after finishing on the payment page. KS Pay appends the query `systemOrderNo`, `merchantOrderNo`, `status`. |

Response: the transaction shape (§4.6) with a `payment` object (§5) and `expiresAt`.

### 4.4 Create payout

`POST /api/v1/payout` — accepted only from whitelisted IPs.

| Field             | Type         | Notes                                                                                                  |
| ----------------- | ------------ | ------------------------------------------------------------------------------------------------------ |
| `merchantOrderNo` | string ≤100  | Same as payin, unique per merchant                                                                     |
| `amount`          | integer      | Amount the recipient receives (the fee is charged separately from your balance)                        |
| `bankCode`        | string       | Destination code from §4.2 / `GET /api/v1/banks` (e.g. `BCA`, `GOPAY`). Uppercase, no spaces           |
| `accountNumber`   | digit string | **Digits only** (`0-9`), no spaces, dashes, or `+`. Bank: account number. E-wallet: phone number `08…` |
| `accountName`     | string       | Account holder / e-wallet account name, as registered                                                  |

Payout to a bank account:

```json
{
  "merchantOrderNo": "WD-2026-0001",
  "amount": 250000,
  "bankCode": "BCA",
  "accountNumber": "1234567890",
  "accountName": "Budi Santoso"
}
```

Payout to an e-wallet (phone number as `accountNumber`):

```json
{
  "merchantOrderNo": "WD-2026-0002",
  "amount": 100000,
  "bankCode": "GOPAY",
  "accountNumber": "081234567890",
  "accountName": "Budi Santoso"
}
```

Response: the payout transaction shape (§4.6) with `status` `PROCESSING`. The final status (`SUCCESS` / `FAILED`) arrives through the webhook (§8) or `GET /api/v1/payout/{systemOrderNo}`.

When a payout is created, `amount + fee` moves immediately from `availableBalance` to `frozenAmount` until the payout is final. If it is `FAILED`, the funds return to `availableBalance`.

**Per-transaction limits** (set by KS Pay; currently minimum Rp100,000, maximum Rp10,000,000 to a bank and Rp1,000,000 to an e-wallet). Outside the limits the request is refused with 422 and a `message` naming the limit, e.g. `Payout amount to e-wallet must not exceed Rp1.000.000 per transaction.` Split large amounts into several payouts.

Destination-related refusals (all HTTP 422, see `message`):

| `message`                                             | Cause & fix                                                                                       |
| ----------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
| `Unknown bank code; use code from GET /api/v1/banks.` | `bankCode` is not in the list (typo, lowercase, clearing code, or bank name). Check §4.2          |
| `This destination bank is currently unavailable.`     | Correct code but currently disabled. Offer another destination; active list = `GET /api/v1/banks` |
| `Insufficient merchant balance.`                      | `availableBalance` < `amount + fee`                                                               |
| `errors.accountNumber`                                | Contains non-digit characters — remove spaces, `-`, `+`                                           |

### 4.5 Check status

`GET /api/v1/payin/{systemOrderNo}`
`GET /api/v1/payout/{systemOrderNo}`

`systemOrderNo` is the number KS Pay returned when the transaction was created (`ZPL-PI-…` for payin, `ZPL-PO-…` for payout).

### 4.6 Transaction response shape

Payin:

```json
{
  "systemOrderNo": "ZPL-PI-01K5…",
  "merchantOrderNo": "INV-2026-0001",
  "status": "PENDING",
  "amount": 150000,
  "fee": 1050,
  "channel": "QRIS",
  "createdAt": "2026-09-19T08:00:00.000000Z",
  "expiresAt": "2026-09-19T09:00:00.000000Z",
  "payment": {
    "type": "CASHIER_URL",
    "url": "https://…/pay/c/…",
    "payData": "00020101021226…"
  }
}
```

Payout: the same fields without `expiresAt` and `payment`.

| Field       | Notes                                                                                                                                                |
| ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `status`    | Payin: `PENDING → SUCCESS \| FAILED`. Payout: `PROCESSING → SUCCESS \| FAILED`.                                                                      |
| `fee`       | KS Pay's fee for this transaction. Payin: funds credited to your balance = `amount - fee`. Payout: funds debited from your balance = `amount + fee`. |
| `expiresAt` | Payment deadline of a payin. After it passes the status becomes `FAILED` and the customer must create a new order.                                   |
| `payment`   | How the customer pays (§5). Present only while the payin is `PENDING`.                                                                               |

## 5. How the customer pays (`payment`)

Every payin is answered the same way, whatever the channel and whatever your account looks like:

```json
"payment": {
  "type": "CASHIER_URL",
  "url": "https://…/pay/c/…",
  "payData": "00020101021226…"
}
```

| Field     | Meaning                                                                                                                                                              |
| --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `url`     | The KS Pay payment page. Send the customer here and everything is handled for you: the QR / VA number, the countdown, the automatic update when the payment arrives, then the return to your `returnUrl`. |
| `payData` | The raw payment data of this order, for merchants who build their own payment page. **May be `null`** — see below.                                                    |
| `type`    | Always `CASHIER_URL` today. Treat an unfamiliar value as "use `url`": KS Pay may add types later.                                                                    |

The simplest integration uses `url` alone and ignores `payData`.

### 5.1 Building your own payment page (`payData`)

`payData` carries exactly what your page has to show, and what it contains follows the `channel` you asked for:

| `channel`                            | `payData`                                                              | What you do                                                              |
| ------------------------------------ | ---------------------------------------------------------------------- | ------------------------------------------------------------------------ |
| `QRIS`                               | QRIS payload string, e.g. `00020101021226…`                            | Render it as a QR code on your page                                      |
| `VA BCA`, `VA BRI`, `VA MANDIRI`, `VA BNI` | Virtual account number, e.g. `8812345678901234`                  | Show the number, the bank you chose, and the exact amount to pay         |

The customer must pay **exactly** `amount`, and only until `expiresAt`. Confirm the result through the webhook (§8) or `GET /api/v1/payin/{systemOrderNo}` — never from what your own page saw.

### 5.2 `payData` is not always available

**`payData` can be `null`, and your integration must handle it.** It is decided when the order is created and never filled in later, so there is nothing to wait for and nothing to poll:

- `payData` is a string → render your own page, or still send the customer to `url`. Both are valid.
- `payData` is `null` → **send the customer to `url`.** The KS Pay payment page always works for that order.

Treat it as a normal case, not an error: an order with `payData: null` is a perfectly good order, and the payment, the webhook, and your balance behave exactly the same.

`payment` itself is `null` only once the payin is no longer open (`SUCCESS` / `FAILED`) — there is nothing left to pay then. If a freshly created payin already comes back `FAILED`, it was refused; create a new order with a new `merchantOrderNo`.

## 6. Idempotency

`merchantOrderNo` is idempotent per merchant and transaction type:

- Resend a request with the **same payload** → KS Pay returns the existing transaction (HTTP 200) and does not create a new one. Safe for retries after a timeout.
- Resend with a **different payload** → HTTP 409.

Recommended practice: on a timeout, repeat the request with the same `merchantOrderNo`; do not generate a new number.

## 7. Error codes

| HTTP | Meaning                                                                                                 |
| ---- | ------------------------------------------------------------------------------------------------------- |
| 401  | Wrong API key, inactive account, expired timestamp, or signature mismatch                               |
| 403  | IP not whitelisted (payout)                                                                             |
| 404  | Transaction not found / not owned by the merchant                                                       |
| 409  | `merchantOrderNo` already used with a different payload                                                 |
| 422  | Validation failed, insufficient balance, unknown or unavailable channel/bank code (see `message`, §4.4) |
| 429  | Rate limit                                                                                              |
| 503  | Payment service temporarily unavailable; retry shortly with the same `merchantOrderNo`                  |

Error body: `{ "message": "…", "errors": { "field": ["…"] } }` (`errors` only for 422 validation). All API `message` values are in English.

## 8. Webhook (KS Pay → merchant)

When a transaction reaches a final status (`SUCCESS` / `FAILED`), KS Pay sends a `POST` to the **Webhook URL** registered for your account.

URL requirements: `https://`, port 443, resolving to a public IPv4 address.

### Headers

| Header              | Value                                                                                     |
| ------------------- | ----------------------------------------------------------------------------------------- |
| `X-KSPay-Event-ID`  | UUID unique per event — use it to ignore duplicate events                                 |
| `X-KSPay-Timestamp` | Unix seconds                                                                              |
| `X-KSPay-Signature` | `hex( HMAC-SHA256( webhookSecret, timestamp + "." + rawBody ) )` — the same formula as §3 |

### Body

```json
{
  "eventId": "6f1c…",
  "systemOrderNo": "ZPL-PI-01K5…",
  "merchantOrderNo": "INV-2026-0001",
  "kind": "PAYIN",
  "status": "SUCCESS",
  "amount": 150000,
  "fee": 1050
}
```

`kind` is `PAYIN` or `PAYOUT`.

### Verification (PHP)

```php
$rawBody   = file_get_contents('php://input');
$timestamp = $_SERVER['HTTP_X_KSPAY_TIMESTAMP'] ?? '';
$expected  = hash_hmac('sha256', $timestamp.'.'.$rawBody, $webhookSecret);

if (! hash_equals($expected, $_SERVER['HTTP_X_KSPAY_SIGNATURE'] ?? '')) {
    http_response_code(401);
    exit;
}
if (abs(time() - (int) $timestamp) > 300) {
    http_response_code(401);
    exit;
}
// handle the event; store eventId so duplicates are ignored
http_response_code(200);
```

### Retries

- Reply **HTTP 2xx** within 10 seconds to count as delivered.
- On failure KS Pay retries with increasing delays (exponential backoff) up to the attempt limit.
- Because retries happen, **your webhook endpoint must be idempotent** (check `eventId`).
- Do not rely on the webhook alone — for certainty, call `GET /api/v1/payin/{systemOrderNo}` before fulfilling the order.

## 9. Sandbox environment

KS Pay provides a sandbox environment, fully separate from production, for building and testing your integration.

|                 | Sandbox                                                                 | Production                                    |
| --------------- | ----------------------------------------------------------------------- | --------------------------------------------- |
| **Base URL**    | `https://sandbox-api.kspyment.com`                                                       | `https://api.kspyment.com`                                |
| **Credentials** | **Sandbox** API Key, Secret Key, Webhook Secret — given at registration | **Production** credentials — given at go-live |
| **Funds**       | No real money moves                                                     | Real                                          |

- Flow, endpoints, headers, signature, and response format are **identical** to production. Going live means swapping the base URL and credentials in your configuration.
- Sandbox credentials do not work in production and vice versa. Balances, orders, and webhook logs of the two environments are separate.
- A sandbox payin returns a mock `payData` (QR string / VA number) that cannot be paid. Its status **does not change by itself**: settle it as `SUCCESS` or `FAILED` from the sandbox merchant dashboard (payin detail → Simulate), or ask the KS Pay team and mention the `systemOrderNo`. Once settled, the webhook is sent and your sandbox balance changes exactly as in production.
- Sandbox payouts are simulated the same way. The sandbox balance must be sufficient — fund it first with a sandbox payin settled as `SUCCESS`. Use `GET /api/v1/banks` for valid bank codes.
- The payout IP whitelist, time tolerance, and webhook retries apply in the sandbox too; test payouts from a server whose IP is registered.

## 10. Go-live checklist

- [ ] Secret Key & Webhook Secret stored in env/secret manager, not in code.
- [ ] Server clock synchronised (NTP) — a difference > 5 minutes gets every request refused with 401.
- [ ] The IP of the server calling payout is registered with KS Pay.
- [ ] Webhook endpoint on HTTPS with a valid certificate, replies 2xx quickly, idempotent.
- [ ] Request retries reuse the same `merchantOrderNo` (never a new number).
- [ ] Order status confirmed through `GET /api/v1/payin/{systemOrderNo}` before goods/services are delivered.
- [ ] `payData: null` handled by sending the customer to `payment.url` (§5.2).
- [ ] Unknown `payment.type` handled safely.

## 11. Backup host

KS Pay serves the same API on two domains at once:

| | Primary | Backup |
| --- | --- | --- |
| Production | `https://api.kspyment.com` | `https://api.kspaypg.vip` |
| Sandbox | `https://sandbox-api.kspyment.com` | `https://sandbox-api.kspaypg.vip` |

Credentials, signature, and webhooks **do not change** — only the host. Keep both base URLs in your configuration and, when the primary host is unreachable (timeout / DNS failure), repeat the same request against the backup host. We announce through the Telegram group if a permanent move is needed.


## Appendix A — Bank & e-wallet code list

Master list of payout destinations. Send the `code` column **exactly** as `bankCode`. The list active for your account right now = `GET /api/v1/banks` (§4.2); a code listed here but missing from the API is currently disabled.

| `code` (send as `bankCode`) | Name | Type |
| --- | --- | --- |
| `HARDA_INTERNASIONAL` | Allo Bank/Bank Harda Internasional | Bank |
| `ANGLOMAS` | Anglomas International Bank | Bank |
| `ARTAJASA` | ARTAJASA PEMBAYARAN ELEKTRONIK | Bank |
| `BANGKOK` | Bangkok Bank | Bank |
| `ACEH` | Bank Aceh Syariah | Bank |
| `ACEH_UUS` | Bank Agris UUS | Bank |
| `AGRONIAGA` | Bank Agroniaga | Bank |
| `AMAR` | BANK AMAR INDONESIA | Bank |
| `ANDARA` | Bank Andara | Bank |
| `ANTAR_DAERAH` | BANK ANTAR DAERAH | Bank |
| `ANZ` | Bank ANZ Indonesia | Bank |
| `ANZ_PANIN` | Bank ANZ PANIN | Bank |
| `ARTA_NIAGA_KENCANA` | Bank Arta Niaga Kencana | Bank |
| `ARTHA` | Bank Artha Graha Internasional | Bank |
| `ARTOS` | Bank ARTOS/ Bank Jago | Bank |
| `BARCLAYS` | BANK BARCLAYS INDONESIA | Bank |
| `BENGKULU` | Bank Bengkulu | Bank |
| `BISNIS_INTERNASIONAL` | Bank Bisnis Internasional | Bank |
| `BJB_SYR` | Bank BJB Syariah | Bank |
| `BNI_SYR` | Bank BNI Syariah | Bank |
| `BNP_PARIBAS` | Bank BNP Paribas | Bank |
| `BRI_SYR` | Bank BRI Syariah | Bank |
| `BTPN` | Bank BTPN | Bank |
| `BTPN_SYR` | Bank BTPN Syariah | Bank |
| `BUKOPIN_SYR` | Bank Bukopin Syariah | Bank |
| `BUMI_ARTA` | Bank Bumi Arta | Bank |
| `BUMIPUTERA` | BANK BUMIPUTERA | Bank |
| `CAPITAL` | Bank Capital Indonesia | Bank |
| `BCA` | Bank Central Asia | Bank |
| `BCA_SYR` | Bank Central Asia (BCA) Syariah | Bank |
| `CENTRATAMA` | BANK CENTRATAMA | Bank |
| `CHINACONS` | BANK CHINA CONSTRUCTION | Bank |
| `CIMB` | Bank CIMB Niaga | Bank |
| `CIMB_REKENING_PONSEL` | Bank CIMB Niaga REKENING PONSEL | Bank |
| `CIMB_UUS` | Bank CIMB Niaga UUS | Bank |
| `COMMONWEALTH` | Bank Commonwealth | Bank |
| `DANAMON` | Bank Danamon | Bank |
| `DANAMON_UUS` | Bank Danamon UUS | Bank |
| `DBS` | Bank DBS Indonesia | Bank |
| `DINAR_INDONESIA` | Bank Dinar Indonesia | Bank |
| `DIPO` | BANK DIPO INTERNATIONAL | Bank |
| `DKI` | Bank DKI | Bank |
| `DKI_UUS` | Bank DKI UUS | Bank |
| `EKA` | Bank EKA | Bank |
| `EKONOMI_RAHARJA` | BANK EKONOMI RAHARJA | Bank |
| `FAMA` | Bank Fama International | Bank |
| `GANESHA` | Bank Ganesha | Bank |
| `HIMPUNAN_SAUDARA` | Bank Himpunan Saudara 1906 | Bank |
| `AGRIS` | Bank IBK Indonesia | Bank |
| `ICBC` | Bank ICBC Indonesia | Bank |
| `INA_PERDANA` | Bank Ina Perdana | Bank |
| `INDEX_SELINDO` | Bank Index Selindo | Bank |
| `JAGO` | BANK JAGO TBK | Bank |
| `JAMBI` | Bank Jambi | Bank |
| `JASA_JAKARTA` | Bank Jasa Jakarta | Bank |
| `JAWA_TENGAH` | Bank Jateng | Bank |
| `JATIM` | Bank Jatim | Bank |
| `JATIM_UUS` | Bank Jatim UUS | Bank |
| `BJB` | Bank Jawa Barat(BJB) | Bank |
| `JTRUST` | Bank JTrust Indonesia | Bank |
| `MALUKU` | Bank Maluku | Bank |
| `MANDIRI` | Bank Mandiri | Bank |
| `MANDIRI_TASPEN` | Bank Mandiri Taspen Pos | Bank |
| `MANTAP` | Bank MANTAP | Bank |
| `MASPION` | Bank Maspion Indonesia | Bank |
| `MAYAPADA` | Bank Mayapada | Bank |
| `MAYBANK` | Bank Maybank | Bank |
| `MAYBANK_SYR` | Bank Maybank Syariah Indonesia | Bank |
| `MAYBANK_UUS` | Bank Maybank Syariah Indonesia UUS | Bank |
| `MAYORA` | Bank Mayora Indonesia | Bank |
| `MEGA` | Bank Mega | Bank |
| `MEGA_SYR` | Bank Mega Syariah | Bank |
| `MESTIKA_DHARMA` | Bank Mestika Dharma | Bank |
| `METRO_EXPRESS` | BANK METRO EXPRESS | Bank |
| `MITRA_NIAGA` | Bank Mitra Niaga | Bank |
| `MIZUHO` | Bank Mizuho Indonesia | Bank |
| `MUAMALAT` | Bank Muamalat Indonesia | Bank |
| `MULTI_ARTA_SENTOSA` | Bank Multi Arta Sentosa(MAS) | Bank |
| `MULTICOR` | Bank MULTICOR | Bank |
| `MUTIARA` | Bank MUTIARA | Bank |
| `NAGARI` | BANK NAGARI | Bank |
| `NATIONALNOBU` | Bank National Nobu | Bank |
| `BNI` | Bank Negara Indonesia(BNI) | Bank |
| `NIAGA_SYR` | BANK NIAGA TBK. SYARIAH | Bank |
| `NUSANTARA_PARAHYANGAN` | Bank Nusantara Parahyangan | Bank |
| `OCBC` | Bank OCBC NISP | Bank |
| `OCBC_UUS` | Bank OCBC NISP UUS | Bank |
| `BOA` | BANK OF AMERICA NA | Bank |
| `BOC` | BANK OF CHINA LIMITED | Bank |
| `INDIA` | Bank of India Indonesia | Bank |
| `TOKYO` | Bank of Tokyo | Bank |
| `OKE` | Bank Oke Indonesia | Bank |
| `PANIN` | Bank Panin | Bank |
| `PAPUA` | Bank Papua | Bank |
| `BPD_DIY_SYR` | BANK PEMBANGUNAN DAERAH DIY UNIT USAHA SYARIAH | Bank |
| `PERMATA` | Bank Permata | Bank |
| `PERMATA_UUS` | Bank Permata UUS | Bank |
| `PRIMA_MASTER` | Bank Prima Master | Bank |
| `PUNDI` | BANK PUNDI INDONESIA | Bank |
| `SAHABAT_PURBA_DANARTA` | BANK PURBA DANARTA | Bank |
| `BRI` | Bank Rakyat Indonesia(BRI) | Bank |
| `RESONA` | Bank Resona Perdania | Bank |
| `SAHABAT_SAMPOERNA` | Bank Sahabat Sampoerna | Bank |
| `SBI_INDONESIA` | Bank SBI Indonesia | Bank |
| `SHINHAN` | Bank Shinhan Indonesia | Bank |
| `SINARMAS` | Bank Sinarmas | Bank |
| `SINARMAS_UUS` | Bank Sinarmas UUS | Bank |
| `SULSELBAR` | Bank Sulselbar | Bank |
| `SULSELBAR_UUS` | Bank Sulselbar UUS | Bank |
| `SULAWESI` | Bank Sulteng | Bank |
| `SULAWESI_TENGGARA` | Bank Sultra | Bank |
| `MITSUI` | Bank Sumitomo Mitsui Indonesia | Bank |
| `SUMSEL_DAN_BABEL` | Bank Sumsel Babel | Bank |
| `SUMSEL_DAN_BABEL_UUS` | Bank Sumsel Dan Babel UUS | Bank |
| `SUMUT` | Bank Sumut | Bank |
| `SUMUT_UUS` | Bank Sumut UUS | Bank |
| `BSI` | Bank Syariah Indonesia(BSI) | Bank |
| `MANDIRI_SYR` | Bank Syariah Mandiri | Bank |
| `BTN` | Bank Tabungan Negara (BTN) | Bank |
| `BTN_UUS` | Bank Tabungan Negara (BTN) UUS | Bank |
| `VICTORIA_INTERNASIONAL` | Bank Victoria International | Bank |
| `VICTORIA_SYR` | Bank Victoria Syariah | Bank |
| `WOORI` | Bank Woori Saudara | Bank |
| `ROYAL` | Blu/BCA Digital | Bank |
| `BALI` | BPD Bali | Bank |
| `BANTEN` | BPD Banten | Bank |
| `BPD_DIY` | BPD DIY | Bank |
| `ACEH_SYR` | BPD ISTIMEWA ACEH SYARIAH | Bank |
| `JAWA_TENGAH_UUS` | BPD JAWA TENGAH UNIT USAHA SYARIAH | Bank |
| `JAWA_TIMUR` | BPD Jawa Timur | Bank |
| `KALIMANTAN_BARAT_UUS` | BPD Kalimantan Barat UUS | Bank |
| `KALIMANTAN_BARAT` | BPD Kalimantan Barat/Kalbar | Bank |
| `KALIMANTAN_SELATAN_UUS` | BPD Kalimantan Selatan UUS | Bank |
| `KALIMANTAN_SELATAN` | BPD Kalimantan Selatan/Kalsel | Bank |
| `KALIMANTAN_TENGAH` | BPD Kalimantan Tengah (Kalteng) | Bank |
| `KALIMANTAN_TIMUR` | BPD Kalimantan Timur | Bank |
| `KALIMANTAN_TIMUR_UUS` | BPD Kalimantan Timur UUS | Bank |
| `LAMPUNG` | BPD Lampung | Bank |
| `NUSA_TENGGARA_BARAT_UUS` | BPD Nusa Tenggara Barat (NTB) UUS | Bank |
| `NUSA_TENGGARA_BARAT` | BPD Nusa Tenggara Barat(NTB) | Bank |
| `NUSA_TENGGARA_TIMUR` | BPD Nusa Tenggara Timur(NTT) | Bank |
| `RIAU_DAN_KEPRI` | BPD Riau Dan Kepri | Bank |
| `RIAU_DAN_KEPRI_UUS` | BPD Riau Dan Kepri UUS | Bank |
| `SULUT` | BPD Sulawesi Utara(SulutGo) | Bank |
| `SUMATERA_BARAT` | BPD Sumatera Barat | Bank |
| `SUMATERA_BARAT_UUS` | BPD Sumatera Barat UUS | Bank |
| `SUMSEL_BABEL` | BPD Sumsel Babel | Bank |
| `DAERAH_ISTIMEWA_UUS` | BPD_Daerah_Istimewa_Yogyakarta_(DIY) | Bank |
| `BPRKS` | BPR KS | Bank |
| `BTPN_SYARIAH` | BTPN Syariah | Bank |
| `CCB` | CCB Indonesia | Bank |
| `CNB` | Centratama Nasional Bank(CNB) | Bank |
| `CITIBANK` | Citibank | Bank |
| `CHINATRUST` | CTBC Indonesia | Bank |
| `DEUTSCHE` | Deutsche Bank | Bank |
| `HSBC` | HSBC | Bank |
| `JPMORGAN` | JPMORGAN CHASE BANK | Bank |
| `HANA` | LINE Bank/KEB Hana | Bank |
| `MNC_INTERNASIONAL` | Motion/Bank MNC Internasional | Bank |
| `YUDHA_BHAKTI` | Neo Commerce/Bank Yudha Bhakti(BNC) | Bank |
| `PANIN_SYR` | Panin Dubai Syariah | Bank |
| `QNB_INDONESIA` | QNB Indonesia | Bank |
| `QNB_KESAWAN` | QNB KESAWAN | Bank |
| `RABOBANK` | Rabobank International Indonesia | Bank |
| `RBS` | Royal Bank of Scotland (RBS) | Bank |
| `KESEJAHTERAAN_EKONOMI` | Seabank/Bank Kesejahteraan Ekonomi(BKE) | Bank |
| `STANDARD_CHARTERED` | Standard Chartered Bank | Bank |
| `UOB` | TMRW/Bank UOB Indonesia | Bank |
| `BUKOPIN` | Wokee/Bukopin | Bank |
| `DANA` | DANA | E-wallet |
| `GOPAY` | GOPAY | E-wallet |
| `LINKAJA` | LINKAJA | E-wallet |
| `OVO` | OVO | E-wallet |
| `SHOPEEPAY` | SHOPEEPAY | E-wallet |
