SNAP API & QRIS 2.0 Indonesia: Panduan Developer untuk Integrasi Open Banking

Foto oleh Unsplash

Foto oleh Unsplash
Standar SNAP (Standar Nasional Open API Pembayaran) Bank Indonesia telah mengubah secara fundamental cara developer fintech mengintegrasikan diri dengan bank dan pemroses pembayaran Indonesia. Diperkenalkan melalui PBI No. 22/1/PBI/2022, SNAP mewajibkan skema request yang seragam, alur autentikasi, dan kode error di semua Penyelenggara Jasa Pembayaran (PJP) berlisensi, menggantikan puluhan API bank proprietary dengan satu standar tunggal. Dikombinasikan dengan kemampuan pembayaran lintas batas QRIS 2.0 dengan Thailand, Malaysia, dan Singapura, ekosistem open banking Indonesia kini menjadi salah satu yang paling komprehensif di Asia Tenggara.
SNAP disusun dalam dua fase implementasi. Fase 1, yang harus didukung penuh oleh semua PJP, mencakup transfer domestik (intra-bank dan antar-bank), pembuatan dan inquiry virtual account, pendaftaran merchant QRIS dan pemrosesan transaksi, debit langsung, dan inquiry saldo. Fase 2, yang sedang di-roll out, menambahkan kemampuan open finance termasuk API data pinjaman, verifikasi identitas digital (menggunakan data NIK Dukcapil), dan API akun investasi.
Endpoint SNAP Fase 1 yang paling umum diintegrasikan adalah: `/snap/v1.0/access-token/b2b` (token OAuth 2.0), `/snap/v1.0/transfer-interbank` (transfer kredit), `/snap/v1.0/create-va` (pembuatan virtual account), `/snap/v1.0/inquiry-va` (inquiry VA), dan `/snap/v1.0/debit` (debit langsung). Setiap bank yang mengimplementasikan SNAP harus mengekspos endpoint ini dengan skema request/response yang identik, hanya berbeda pada base URL dan kredensial partner yang diperlukan.
QRIS 2.0 memperluas standar QRIS domestik untuk memungkinkan pembayaran QR lintas batas. Konsumen Indonesia kini dapat membayar di terminal bertenaga QRIS di Thailand (PromptPay QR), Malaysia (DuitNow QR), Singapura (PayNow QR), dan sebaliknya. Untuk developer yang membangun POS merchant atau aplikasi e-wallet, alur QRIS lintas batas menambahkan langkah konversi mata uang — aplikasi Anda harus memanggil API kurs valuta asing QRIS untuk menampilkan setara IDR sebelum pengguna mengkonfirmasi pembayaran.
Selalu implementasikan idempotency key dalam panggilan SNAP API menggunakan header `X-EXTERNAL-ID`. Server SNAP menggunakan field ini untuk mendeteksi dan mendeduplikasi request yang diulang — mengirim external ID yang sama dua kali untuk transfer akan mengembalikan hasil transaksi asli, bukan membuat transfer duplikat.
Autentikasi SNAP menggunakan model keamanan dua lapis: alur OAuth 2.0 client credential untuk akuisisi access token, dan penandatanganan request HMAC-SHA512 untuk setiap panggilan API berikutnya. Langkah access token menggunakan tanda tangan asimetris (RSA-SHA256 dengan sertifikat klien P12 Anda) untuk membuktikan identitas, sementara tanda tangan HMAC-SHA512 per-request menggunakan access token dan hash body request untuk memastikan integritas pesan.
Algoritma tanda tangan SNAP memerlukan konstruksi `StringToSign` dari method HTTP, path endpoint, access token (huruf kecil), hash SHA-256 dari body request (huruf kecil), dan nilai header X-TIMESTAMP — digabung dengan titik dua. String ini kemudian ditandatangani dengan HMAC-SHA512 menggunakan client secret sebagai kunci. Tanda tangan berenkoding base64 yang dihasilkan dikirim dalam header `X-SIGNATURE`. Blok kode di bawah menampilkan implementasi lengkapnya.
// snap-api-client.js — Bank Indonesia SNAP API request with HMAC-SHA512
const crypto = require('crypto');
const axios = require('axios');
const CLIENT_ID = process.env.SNAP_CLIENT_ID;
const CLIENT_SECRET = process.env.SNAP_CLIENT_SECRET;
const BASE_URL = 'https://api.sandbox.bri.co.id'; // sandbox endpoint
/**
* Generate SNAP access token (OAuth 2.0 client credentials)
*/
async function getAccessToken() {
const timestamp = new Date().toISOString();
const stringToSign = `${CLIENT_ID}|${timestamp}`;
const signature = crypto
.createHmac('sha512', CLIENT_SECRET)
.update(stringToSign)
.digest('hex');
const resp = await axios.post(`${BASE_URL}/snap/v1.0/access-token/b2b`, {
grantType: 'client_credentials'
}, {
headers: {
'X-CLIENT-KEY': CLIENT_ID,
'X-TIMESTAMP': timestamp,
'X-SIGNATURE': signature,
'Content-Type': 'application/json'
}
});
return resp.data.accessToken;
}
/**
* Transfer credit (SNAP Phase 1 — inter-bank transfer)
*/
async function transferCredit(token, payload) {
const timestamp = new Date().toISOString();
const requestId = crypto.randomUUID();
const bodyHash = crypto.createHash('sha256').update(JSON.stringify(payload)).digest('hex');
const stringToSign = `POST:/snap/v1.0/transfer-interbank:${token}:${bodyHash.toLowerCase()}:${timestamp}`;
const signature = crypto.createHmac('sha512', CLIENT_SECRET).update(stringToSign).digest('base64');
return axios.post(`${BASE_URL}/snap/v1.0/transfer-interbank`, payload, {
headers: {
Authorization: `Bearer ${token}`,
'X-TIMESTAMP': timestamp,
'X-SIGNATURE': signature,
'X-PARTNER-ID': CLIENT_ID,
'X-EXTERNAL-ID': requestId,
'CHANNEL-ID': '95221',
'Content-Type': 'application/json'
}
});
}
// Usage
(async () => {
const token = await getAccessToken();
const result = await transferCredit(token, {
partnerReferenceNo: 'TXN-2026-001',
amount: { value: '100000.00', currency: 'IDR' },
beneficiaryBankCode: '014', // BCA
beneficiaryAccountNo: '1234567890',
sourceAccountNo: '9876543210',
transactionDate: new Date().toISOString()
});
console.log('Transfer status:', result.data.responseCode);
})();Partner SNAP menerima sertifikat klien P12 dari setiap bank yang diintegrasikan. Simpan sertifikat ini di secrets manager Anda (AWS Secrets Manager, HashiCorp Vault, atau Azure Key Vault) — jangan pernah commit ke source code. Sertifikat biasanya kadaluarsa setiap tahun; implementasikan monitoring kadaluarsa otomatis dengan alerting 60 dan 30 hari sebelum expiry. Saat merotasi kunci, uji sertifikat baru di environment sandbox bank minimal 2 minggu sebelum yang lama kadaluarsa.
Untuk aplikasi yang memerlukan pembuatan QRIS dinamis (jumlah sudah terisi dalam kode QR), gunakan endpoint SNAP `/snap/v1.0/generate-qr`. QR code dinamis kadaluarsa setelah TTL yang dapat dikonfigurasi (biasanya 5 menit untuk pembayaran konsumen, hingga 24 jam untuk tagihan). Selalu tampilkan nama merchant, jumlah, dan referensi transaksi unik di samping kode QR agar pengguna dapat memverifikasi transaksi sebelum melakukan scan.
SNAP mendefinisikan taksonomi kode error terstandarisasi: `4001XX` untuk error validasi input (jangan retry), `4091XX` untuk error konflik/duplikat (kembalikan hasil asli), `5001XX` untuk error sistem partner (retry dengan exponential backoff), dan `5041XX` untuk timeout pemrosesan bank (query status transaksi sebelum retry). Selalu implementasikan panggilan inquiry status transaksi sebelum memulai retry untuk menghindari transfer duplikat, yang sangat sulit dibalik dalam sistem antarbank Indonesia.
Environment sandbox dan produksi SNAP bukan sekadar base URL yang berbeda — keduanya juga memberlakukan aturan IP whitelisting yang berbeda. IP egress server produksi Anda harus didaftarkan ke tim API gateway setiap bank sebelum go-live. Sandbox sering menggunakan allowlist bersama, tetapi produksi secara ketat menolak IP yang tidak disetujui dengan respons 403. Kegagalan mendaftarkan IP adalah penyebab paling umum keterlambatan peluncuran produksi untuk integrasi SNAP.
Sebelum terhubung ke environment produksi SNAP sebuah bank, partner harus menyelesaikan proses sertifikasi di sandbox, membuktikan implementasi yang benar untuk semua endpoint wajib, penanganan error yang tepat, perilaku idempotency, dan kontrol keamanan. Proses sertifikasi biasanya memakan waktu 2–4 minggu per bank. Gunakan matriks test case SNAP resmi yang diterbitkan Bank Indonesia untuk mempersiapkan skrip test Anda.
Sebagian besar bank SNAP mendukung notifikasi webhook Host-to-Host (H2H) untuk event penyelesaian transaksi asinkron. Konfigurasi endpoint webhook Anda agar idempoten — notifikasi yang sama mungkin dikirimkan beberapa kali. Akui setiap notifikasi dengan respons HTTP 200 yang berisi payload acknowledgment SNAP dalam 30 detik, jika tidak sistem bank akan mencoba pengiriman ulang dengan interval yang meningkat hingga 24 jam.
Environment produksi SNAP memberlakukan rate limit per kredensial partner, biasanya berkisar dari 50 hingga 500 transaksi per detik tergantung tier PJP Anda. Implementasikan token bucket rate limiter di layer integrasi Anda untuk memperhalus lonjakan traffic. SLA SNAP Bank Indonesia mewajibkan PJP mempertahankan ketersediaan 99,5% untuk API pembayaran — bangun circuit breaker untuk secara otomatis fallback ke channel pembayaran alternatif saat provider SNAP mengalami degradasi.
Integrasikan metrik API SNAP — termasuk kegagalan verifikasi tanda tangan, tingkat timeout, dan distribusi kode error — ke platform observabilitas Anda. Lonjakan tiba-tiba `4011XX` (error autentikasi) sering mengindikasikan sertifikat yang hampir kadaluarsa, sementara tingkat `5041XX` (timeout) yang meningkat dari bank tertentu adalah peringatan dini masalah infrastruktur mereka sebelum pengumuman maintenance resmi.
Sebelum go-live dengan integrasi SNAP, verifikasi: alamat IP produksi sudah di-whitelist di semua bank yang diintegrasikan, sertifikat P12 disimpan di secrets manager dengan monitoring expiry, endpoint webhook sudah di-deploy dengan logika idempotency dan SLA respons 30 detik, rate limiter dan circuit breaker dikonfigurasi dan diuji, logika fallback inquiry status transaksi diimplementasikan untuk semua endpoint transfer, dan dashboard monitoring Anda sudah live dengan alert untuk ambang batas error rate dan latensi.
Test suite SNAP yang robust harus mencakup: (1) alur happy-path yang berhasil untuk setiap endpoint; (2) pencegahan replay attack (X-EXTERNAL-ID duplikat harus mengembalikan hasil idempoten); (3) penanganan access token yang kadaluarsa; (4) toleransi clock skew (X-TIMESTAMP dalam ±15 detik dari waktu server); (5) penolakan tanda tangan tidak valid; dan (6) semua kode error SNAP yang ditentukan untuk endpoint yang diintegrasikan. Mock endpoint bank SNAP secara lokal menggunakan tools seperti WireMock atau Mockoon untuk mengaktifkan eksekusi pipeline CI yang cepat tanpa rate limit sandbox.
Istilah kunci dalam artikel ini meliputi SNAP, QRIS, HMAC-SHA512, and PJP.