API Tester Dashboard
BCA QRIS REST API v1

Panduan Integrasi BCA Payment Gateway

Dokumentasi lengkap dan praktis untuk menghubungkan toko online atau aplikasi Anda dengan sistem pembayaran BCA QRIS Dinamis otomatis.

1. Pengenalan & Alur Kerja

Gateway ini bekerja secara self-hosted tanpa potongan biaya transaksi pihak ketiga. Setiap pembayaran pembeli otomatis dideteksi dari mutasi KlikBCA Merchant dan diteruskan ke server toko Anda dalam hitungan detik.

Base URL Server Aktif Anda https://bca.5nod.com
1 Buat Invoice QRIS

Toko memanggil POST /api/v1/charge. Sistem menambah kode unik Rp 1–199 agar nominal tiap pembeli berbeda.

2 Pembeli Scan QRIS

Tampilkan qris_image. Dengan acquirer: "bca", pembayaran dari aplikasi apa pun wajib masuk ke KlikBCA.

3 Auto-Verifikasi & Webhook

Bot pemantau memeriksa mutasi KlikBCA tiap ±10 detik dan langsung mengirim HTTP POST ke webhook_url toko Anda.

Tips Pengaturan Kredensial (.env vs UI): Kredensial kasir KlikBCA (BCA_USER, BCA_PASS) serta template STATIC_QRIS dapat diisi di file .env server atau di menu Dashboard. Anda juga dapat menekan tombol Sync QRIS di Dashboard untuk menarik QRIS Statis otomatis dari portal KlikBCA.

2. Autentikasi (API Key)

Seluruh endpoint API publik (/api/v1/*) wajib menyertakan API Key Merchant pada header HTTP Authorization menggunakan format Bearer Token.

Cara Mendapatkan API Key: Masuk ke Dashboard Admin → pilih menu Akun BCA Merchant → klik tombol Salin pada kolom API Key merchant Anda (format: BCA-GW-...).
HTTP Authorization Header
Authorization: Bearer BCA-GW-YOUR_API_KEY
Content-Type: application/json

3. Charge API (Buat Invoice BCA QRIS)

Endpoint ini membuat transaksi QRIS Dinamis baru, menghitung kode unik otomatis (1–199) agar tidak bentrok dengan tagihan pending lain, dan mengembalikan gambar QR siap scan.

POST /api/v1/charge
Auth: Bearer API Key

Parameter Request Body (JSON)

Field Tipe Status Deskripsi
external_id String Wajib ID invoice unik dari sistem toko Anda (contoh: ORDER-100249).
amount Number Wajib Nominal dasar transaksi dalam Rupiah (IDR), bernilai positif. Sistem otomatis menambahkan kode unik 1–199.
webhook_url String Opsional URL endpoint server toko Anda untuk menerima notifikasi POST otomatis saat pembayaran sukses.
acquirer String Opsional Rute bank tujuan jika QRIS Anda memiliki multi-acquirer (misal DANA + BCA).
Nilai: bca (default, wajib agar auto-verifikasi KlikBCA jalan), dana, atau multi.
external_id String • Wajib

ID invoice unik dari sistem toko Anda (contoh: ORDER-100249).

amount Number • Wajib

Nominal dasar (IDR) bernilai positif. Sistem otomatis menambah kode unik 1–199.

webhook_url String • Opsional

URL callback server Anda untuk menerima notifikasi sukses otomatis.

acquirer String • Opsional

Rute bank QRIS: bca (default, direkomendasikan), dana, atau multi.

Contoh Request Body (JSON)

POST /api/v1/charge
{
  "external_id": "ORDER-100249",
  "amount": 10000,
  "acquirer": "bca",
  "webhook_url": "https://toko-anda.com/api/webhook-bca"
}

Respons Sukses (201 Created)

HTTP 201 Created 201
{
  "status": "pending",
  "transaction_id": 18,
  "external_id": "ORDER-100249",
  "amount": 10103,
  "base_amount": 10000,
  "fee": 103,
  "payment_method": "qris",
  "qris_acquirer": "bca",
  "active_acquirers": ["BCA"],
  "qris_string": "00020101021226650013ID.CO.BCA.WWW...",
  "qris_image": "data:image/png;base64,iVBORw0KGgo...",
  "created_at": "2026-11-11T05:50:00.000Z"
}
Penting Saat Menampilkan Tagihan ke Pembeli: Tampilkan nominal akhir data.amount (contoh: Rp 10.103) dan gambar data.qris_image. QRIS Dinamis sudah mengunci nominal tersebut otomatis saat di-scan pembeli sehingga pembayaran pasti cocok dengan mutasi KlikBCA.

4. Status API (Cek Status Pembayaran)

Gunakan endpoint ini untuk memeriksa status transaksi secara manual atau polling berkala dari backend toko Anda menggunakan external_id yang Anda kirim saat pembuatan invoice.

GET /api/v1/status/:external_id
Auth: Bearer API Key

Path Parameter

Parameter Tipe Status Deskripsi
:external_id String Wajib ID invoice milik toko Anda (contoh: /api/v1/status/ORDER-100249).
:external_id String • Wajib

Path parameter ID invoice toko Anda (contoh: /api/v1/status/ORDER-100249).

Respons Sukses (200 OK)

HTTP 200 OK 200
{
  "external_id": "ORDER-100249",
  "status": "success",
  "amount": 10103,
  "payment_method": "qris",
  "created_at": "2026-11-11T05:50:00.000Z",
  "updated_at": "2026-11-11T05:51:12.000Z"
}

5. Webhook Callback (Notifikasi Otomatis)

Begitu mutasi dana masuk terdeteksi di KlikBCA Merchant, server gateway akan otomatis mengirim request HTTP POST (dengan maksimal 3 kali percobaan ulang bila gagal) ke webhook_url yang Anda daftarkan.

Payload JSON yang Dikirim Gateway ke Server Anda

POST <webhook_url> (Content-Type: application/json)
{
  "transaction_id": 18,
  "external_id": "ORDER-100249",
  "amount": 10103,
  "status": "success",
  "updated_at": "2026-11-11T05:51:12.000Z"
}
Praktik Terbaik Menangani Webhook:
  • Selalu kembalikan response HTTP 200 OK secepat mungkin setelah menerima payload agar tidak dianggap gagal oleh sistem retry.
  • Terapkan pengecekan idempoten: cek apakah order external_id masih berstatus belum dibayar sebelum memproses pesanan agar tidak diproses dua kali.
  • Untuk keamanan ekstra, pastikan nominal amount & status dikonfirmasi ulang melalui GET /api/v1/status/:external_id sebelum mengirim barang digital/fisik.

6. Contoh Integrasi Kode (Siap Pakai)

Pilih tab di bawah untuk menyalin contoh kode lengkap pembuatan invoice, cek status, dan penerima webhook. URL server di bawah ini sudah menyesuaikan otomatis dengan domain aktif Anda.

# 1. Membuat invoice BCA QRIS Dinamis
curl -X POST https://bca.5nod.com/api/v1/charge \
  -H "Authorization: Bearer BCA-GW-YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "external_id": "ORDER-100249",
    "amount": 10000,
    "acquirer": "bca",
    "webhook_url": "https://toko-anda.com/api/webhook-bca"
  }'

# 2. Memeriksa status transaksi
curl -X GET https://bca.5nod.com/api/v1/status/ORDER-100249 \
  -H "Authorization: Bearer BCA-GW-YOUR_API_KEY"
<?php
// Membuat Invoice BCA QRIS Dinamis (PHP cURL)
$url = "https://bca.5nod.com/api/v1/charge";
$apiKey = "BCA-GW-YOUR_API_KEY";

$payload = [
    "external_id" => "ORDER-" . time(),
    "amount"      => 10000,
    "acquirer"    => "bca",
    "webhook_url" => "https://toko-anda.com/api/webhook-bca"
];

$ch = curl_init($url);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_POSTFIELDS     => json_encode($payload),
    CURLOPT_HTTPHEADER     => [
        "Authorization: Bearer " . $apiKey,
        "Content-Type: application/json"
    ],
    CURLOPT_TIMEOUT        => 20
]);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$data = json_decode($response, true);
if ($httpCode === 201 && isset($data['qris_image'])) {
    echo "<h3>Total Bayar: Rp " . number_format($data['amount'], 0, ',', '.') . "</h3>";
    echo '<img src="' . htmlspecialchars($data['qris_image']) . '" alt="QRIS BCA" width="240" />';
} else {
    echo "Gagal membuat invoice: " . ($data['message'] ?? 'Unknown error');
}
?>
// Membuat Invoice & Cek Status dengan Fetch bawaan Node.js 18+
const BASE_URL = 'https://bca.5nod.com';
const API_KEY = 'BCA-GW-YOUR_API_KEY';

async function createInvoice() {
  const res = await fetch(`${BASE_URL}/api/v1/charge`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      external_id: 'ORDER-' + Date.now(),
      amount: 10000,
      acquirer: 'bca',
      webhook_url: 'https://toko-anda.com/api/webhook-bca'
    })
  });

  const data = await res.json();
  if (!res.ok) throw new Error(data.message || 'Gagal membuat invoice');

  console.log('Nominal Unik (IDR):', data.amount);
  console.log('Routing Bank:', data.active_acquirers);
  console.log('QR String:', data.qris_string);
  return data;
}

createInvoice().catch(console.error);
<?php
// Contoh Endpoint Penerima Webhook di Server Toko (PHP)
// URL: https://toko-anda.com/api/webhook-bca

$rawBody = file_get_contents('php://input');
$payload = json_decode($rawBody, true);

if (!$payload || empty($payload['external_id']) || ($payload['status'] ?? '') !== 'success') {
    http_response_code(400);
    echo json_encode(['ok' => false, 'message' => 'Payload tidak valid']);
    exit;
}

$externalId = $payload['external_id'];
$amountPaid = (float) ($payload['amount'] ?? 0);

// 1. Verifikasi silang ke Gateway API agar 100% aman dari request palsu
$ch = curl_init("https://bca.5nod.com/api/v1/status/" . urlencode($externalId));
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ["Authorization: Bearer BCA-GW-YOUR_API_KEY"]
]);
$verifyJson = json_decode(curl_exec($ch), true);
curl_close($ch);

if (($verifyJson['status'] ?? '') === 'success' && (float)$verifyJson['amount'] === $amountPaid) {
    // 2. Tandai order sebagai LUNAS di database toko Anda (secara idempoten)
    // updateOrderPaid($externalId);
    http_response_code(200);
    echo json_encode(['ok' => true]);
} else {
    http_response_code(400);
    echo json_encode(['ok' => false, 'message' => 'Verifikasi status gagal']);
}
?>
// Contoh Endpoint Penerima Webhook di Server Toko (Node.js Express)
const express = require('express');
const app = express();
app.use(express.json());

const GATEWAY_URL = 'https://bca.5nod.com';
const API_KEY = 'BCA-GW-YOUR_API_KEY';

app.post('/api/webhook-bca', async (req, res) => {
  const { external_id, amount, status } = req.body || {};

  if (!external_id || status !== 'success') {
    return res.status(400).json({ ok: false, message: 'Payload tidak valid' });
  }

  try {
    // Verifikasi ulang ke Gateway API untuk memastikan pembayaran asli
    const verifyRes = await fetch(`${GATEWAY_URL}/api/v1/status/${encodeURIComponent(external_id)}`, {
      headers: { 'Authorization': `Bearer ${API_KEY}` }
    });
    const tx = await verifyRes.json();

    if (verifyRes.ok && tx.status === 'success' && Number(tx.amount) === Number(amount)) {
      // TODO: Update status order di database toko Anda menjadi PAID (idempoten)
      console.log(`Order ${external_id} lunas sebesar Rp ${amount}`);
      return res.status(200).json({ ok: true });
    }
    return res.status(400).json({ ok: false, message: 'Status transaksi belum lunas' });
  } catch (err) {
    return res.status(500).json({ ok: false, message: err.message });
  }
});

7. Kode Status HTTP & Troubleshooting

Referensi cepat arti kode respons HTTP yang dikembalikan oleh Gateway API beserta cara mengatasinya.

Kode Arti Penyebab Umum & Solusi
200 / 201 Sukses Request berhasil diproses (201 untuk pembuatan invoice baru, 200 untuk cek status).
400 Bad Request Parameter wajib kosong (external_id/amount), nominal ≤ 0, atau String QRIS Statis belum diset pada merchant/file .env (jalankan Sync QRIS di Dashboard).
401 Unauthorized Header Authorization: Bearer ... tidak ada, API Key salah, atau merchant sedang nonaktif.
404 Not Found Transaksi dengan external_id tersebut tidak ditemukan untuk merchant terkait.
500 Server Error Terjadi kesalahan internal saat membentuk QRIS. Periksa log aktivitas sistem pada Dashboard Admin.
200 / 201 Sukses

Request berhasil diproses (201 invoice baru, 200 cek status).

400 Bad Request

Field wajib kosong, nominal ≤ 0, atau QRIS Statis belum diset (klik Sync QRIS di Dashboard).

401 Unauthorized

Header Authorization: Bearer ... hilang atau API Key salah.

404 Not Found

ID transaksi external_id tidak ditemukan pada merchant Anda.

500 Server Error

Kesalahan internal server saat generate QRIS; cek Live Logs di Dashboard Admin.