Bank Integrator KBI
Cara memasang, mengatur, memakai, dan memantau service api-integrator — lapisan integrasi antara Aplikasi Kliring dan API bank.
- Versi
- 1.0
- Tanggal
- 7 Oktober 2026
- Service
- api-integrator · port 2034
- Bank
- Mandiri · BRI · BNI · BTN · BSI
Bab 1Pengenalan
Apa itu Bank Integrator, di mana letaknya, dan untuk siapa buku ini.
Bank Integrator adalah service yang berdiri di antara Aplikasi Kliring dan API setiap bank. Aplikasi Kliring mengirim permintaan dengan satu format standar; integrator yang menentukan bank tujuan, mengubah format sesuai spesifikasi bank itu, mengurus token dan tanda tangan digital, mengirim, lalu mengembalikan jawaban dalam satu format standar pula.
Apa yang dikerjakan integrator
| Fungsi | Artinya dalam praktik |
|---|---|
| Routing | Memilih bank yang melayani permintaan, dari field bank atau dari aturan routing. |
| Transformasi | Mengubah permintaan standar menjadi badan JSON yang diminta bank, termasuk kekhususan tiap bank. |
| Autentikasi & tanda tangan | Mengambil token bank, menyimpannya, memperbaruinya sebelum habis, dan menandatangani setiap permintaan. |
| Normalisasi jawaban | Kode dan bentuk jawaban bank yang berbeda-beda dipetakan menjadi empat status standar. |
| Idempotency | Satu transaction_id tidak pernah menjadi dua instruksi ke bank. |
| Retry & status | Mengulang hanya bila aman; hasil yang belum pasti dikonfirmasi ke bank, bukan dikirim ulang. |
| Log, audit, monitoring | Setiap panggilan ke bank tercatat; latensi, galat, dan timeout bisa dipantau. |
Untuk siapa buku ini
- Pengembang Aplikasi Kliring — Bab 4, 7, 8, dan 9: cara memanggil integrator dan membaca jawabannya.
- Operator / tim operasional — Bab 5, 6, 11, dan 14: mengatur bank, memantau transaksi, menangani masalah.
- Tim infrastruktur — Bab 3 dan 13: memasang dan menyiapkan UAT/produksi.
- Pengembang integrator — Bab 10, 12, dan 15: adaptor bank, pengujian, menambah bank.
Integrator hanya melayani arah KBI → Bank. Arah Bank → KBI (notifikasi, inquiry dan payment virtual account yang dipanggil bank) dilayani aplikasi bank2kbi. Integrator belum menerima callback dari bank dan belum mengirim pemberitahuan balik ke Aplikasi Kliring.
Bab 2Konsep dasar
Enam istilah yang dipakai di seluruh buku.
Layanan standar
Integrator menyediakan tujuh layanan, sama untuk semua bank. Tidak semua bank membuka semuanya (lihat Bab 10).
| Layanan | Rute | Kegunaan | Mengubah sesuatu di bank? |
|---|---|---|---|
BALANCE_INQUIRY | POST /trx/balance | Cek saldo rekening | Tidak |
ACCOUNT_INQUIRY | POST /trx/account-inquiry | Memastikan nama pemilik rekening tujuan | Tidak |
TRANSFER | POST /trx/transfer | Memindahkan dana | Ya |
TRANSFER_STATUS | POST /trx/status | Mengonfirmasi status transaksi | Tidak |
BANK_STATEMENT | POST /trx/statement | Mutasi rekening | Tidak |
VA_CREATE | POST /trx/va | Membuat virtual account | Ya |
VA_INQUIRY | POST /trx/va-inquiry | Melihat data dan status bayar VA | Tidak |
Dua layanan yang mengubah sesuatu di bank wajib membawa transaction_id dan dicatat di tabel transaksi.
Status standar
| Status | Arti |
|---|---|
| SUCCESS | Bank memproses dan berhasil. |
| PENDING | Bank menerima tetapi belum selesai, atau hasilnya belum pasti (timeout, galat bank). Belum boleh dianggap gagal. |
| FAILED | Tidak diproses karena gangguan teknis. Bank pasti belum menjalankan instruksinya. |
| REJECTED | Bank menolak secara final: data salah, rekening tidak ada, limit, saldo. |
Istilah lain
| Istilah | Penjelasan |
|---|---|
transaction_id | Pengenal unik transaksi yang dibuat Aplikasi Kliring. Menjadi kunci idempotency dan dikirim ke bank sebagai partnerReferenceNo. |
request_id | Pengenal yang dibuat integrator untuk setiap permintaan (ITG…). Dipakai untuk menelusuri log. |
| Adaptor | Bagian kode yang mengetahui spesifikasi satu bank. Ada lima: MDR, BRI, BNI, BTN, BSI. |
| Bank eksekutor | Bank yang menjalankan permintaan (field bank). Berbeda dengan beneficiary_bank, yaitu bank pemilik rekening tujuan. |
| Bank reference | Nomor referensi dari bank (bank_reference_no) untuk pelacakan dan rekonsiliasi. |
Bab 3Memasang dan menjalankan
Dari folder kosong sampai service menjawab di port 2034.
Prasyarat
- Go 1.25 atau lebih baru.
- MySQL dengan database CMC (
icomexdi lokal). Integrator membacar_userid,r_member,r_bank, dan menulist_log. - OpenSSL untuk membuat kunci RSA.
Langkah
- Buat tabel
Empat tabel baru; tidak ada tabel atau baris lama yang diubah.
mysql --default-character-set=utf8mb4 -u root icomex < sql/migration.sql - Isi data awal (hanya lokal)
Mendaftarkan lima bank yang diarahkan ke simulator, dan tiga contoh aturan routing.
mysql --default-character-set=utf8mb4 -u root icomex < sql/seed.sql - Buat kunci RSA
Private key dipakai menandatangani permintaan token. Public key-nya yang diserahkan ke bank.
openssl genrsa -out keys/kbi-private-dev.pem 2048 openssl rsa -in keys/kbi-private-dev.pem -pubout -out keys/kbi-public-dev.pem - Siapkan
.envSalin.env.examplemenjadi.env, lalu isi sekurangnyaDB_USER,DB_NAME,JWT_SECRET, dan rahasia tiap bank. Untuk lokal, hidupkan simulator denganSIM_ENABLED=1. - Jalankan
Untuk pengembangan dengan muat ulang otomatis, gunakan
go run .air(konfigurasinya di.air.toml). - Periksa
Jawaban yang benar:
curl http://localhost:2034/apiBANK INTEGRATOR OK.
Isi .env
| Variabel | Bawaan | Keterangan |
|---|---|---|
APP_ENV | local | local, uat, atau production. |
DB_HOST DB_PORT | localhost 3306 | Alamat MySQL. |
DB_USER DB_NAME | — | Wajib. DB_PASS boleh kosong. |
HOST | kosong | Alamat yang diikat. Kosong = semua antarmuka; di server isi 127.0.0.1 agar hanya dijangkau lewat nginx. |
PORT URL_API | 2034 /api | Port dan awalan rute. |
JWT_SECRET | — | Wajib, minimal 32 karakter. Bila disamakan dengan cmc-api2, token user Kliring langsung diterima. |
JWT_EXPIRES | 1d | Umur token: 1d, 12h, 30m. |
CORS_ORIGINS | http://localhost:5173 | Asal browser yang diizinkan, dipisah koma. |
IP_ALLOW | kosong | IP atau CIDR yang boleh memanggil integrator. Kosong = semua. |
RATE_WINDOW RATE_MAX | 15m 600 | Batas jumlah permintaan per IP. |
DEFAULT_BANK | kosong | Bank yang dipakai bila tidak ada aturan routing yang cocok. |
BANK_CONNECT_TIMEOUT | 5s | Batas waktu membuka koneksi ke bank. |
BANK_INQUIRY_TIMEOUT | 15s | Batas waktu layanan baca dan permintaan token. |
BANK_TRANSFER_TIMEOUT | 45s | Batas waktu transfer dan pembuatan VA. |
RETRY_MAX RETRY_BACKOFF | 2 500ms | Jumlah pengulangan otomatis dan jeda dasarnya (berlipat tiap pengulangan). |
BANK_TOKEN_REFRESH_BEFORE | 60s | Token bank diperbarui bila sisa umurnya kurang dari ini. |
PENDING_CHECK_INTERVAL | 15s | Seberapa sering antrean PENDING diperiksa. 0 = mati. |
PENDING_CHECK_SCHEDULE | 30s,1m,2m,5m,10m,30m,1h | Jeda konfirmasi ke-1, ke-2, dan seterusnya. |
PENDING_CHECK_MAX | 30 | Setelah sebanyak ini, konfirmasi otomatis berhenti. |
NOT_FOUND_GRACE | 5m | Masa tenggang sebelum jawaban "tidak ditemukan" dianggap final. |
LOG_BODY | 1 | 1 = badan permintaan/jawaban (tersamar) ikut disimpan di log. |
SIM_ENABLED SIM_PATH | 0 /sim | Simulator bank. Ditolak bila APP_ENV=production. |
SIM_TIMEOUT_DELAY SIM_PENDING_DELAY | 60s 20s | Pengatur waktu skenario simulator. |
Rahasia tiap bank
Rahasia tidak disimpan di database. Semuanya dibaca dari environment dengan pola BANK_<ID>_<NAMA>, di mana <ID> adalah kode bank di integrator.
| Nama | Isi | Dipakai |
|---|---|---|
CLIENT_SECRET | Client secret dari bank | Tanda tangan HMAC setiap layanan (semua bank kecuali BSI) |
PRIVATE_KEY_FILE | Path berkas private key RSA KBI | Tanda tangan token (semua bank) dan layanan BSI |
API_KEY | API key tambahan | BSI (API Key NCMS) |
TLS_CERT_FILE TLS_KEY_FILE | Sertifikat dan kunci klien | mTLS, bila bank memintanya |
TLS_CA_FILE | Sertifikat CA bank | Bila bank memakai CA khusus |
BANK_BTN_CLIENT_SECRET=…
BANK_BTN_PRIVATE_KEY_FILE=keys/kbi-private-btn.pem
BANK_BSI_PRIVATE_KEY_FILE=keys/kbi-private-bsi.pem
BANK_BSI_API_KEY=…Berkas .env dan isi folder keys/ sudah dikecualikan lewat .gitignore. Jangan menyalinnya ke tempat lain tanpa pengamanan.
Bab 4Login dan hak akses
Siapa yang boleh memanggil integrator, dan boleh melakukan apa.
Login
Integrator memakai user exchange yang sama dengan cmc-api2: baris r_userid yang aktif dengan tipe A (exchange admin) atau V (surveillance).
curl -X POST http://localhost:2034/api/login \
-H "Content-Type: application/json" \
-d '{"username":"<userid>","password":"<password>"}'{
"success": true,
"message": "Login successful",
"token": "eyJhbGciOiJIUzI1NiIs…",
"user": { "userid": "…", "name_userid": "…", "member_id": "IX", "tipe_userid": "A" }
}Setiap rute lain butuh header Authorization: Bearer <token>. Token berlaku selama JWT_EXPIRES.
Isi token integrator sama bentuknya dengan token cmc-api2. Bila JWT_SECRET kedua service disamakan, Aplikasi Kliring cukup meneruskan token user-nya — tidak perlu login kedua. Ini keputusan pemasangan: secret yang sama berarti kebocoran di satu service berlaku di keduanya.
Peran
| Tipe user | Boleh | Tidak boleh |
|---|---|---|
A — exchange admin | Semua: memanggil bank, mengubah konfigurasi bank dan routing, membaca log. | — |
V — surveillance | Membaca: daftar transaksi, log, monitoring, konfigurasi. | Semua POST, PUT, DELETE selain login. Dijawab 403. |
Lainnya (S, B) | — | Tidak bisa login. |
Pembatasan lain
- IP whitelist — bila
IP_ALLOWdiisi, hanya alamat itu yang dilayani; yang lain dijawab 403. - Rate limit — melebihi
RATE_MAXpermintaan perRATE_WINDOWdijawab 429. - Profil —
GET /memenampilkan user yang sedang login danboleh_transaksi.
Bab 5Mengatur koneksi bank
Mendaftarkan bank, mengisi identitasnya, dan menguji koneksinya.
Setiap bank yang dilayani punya satu baris di r_integrator_bank, dikelola lewat rute /intbank. Perubahan langsung berlaku tanpa restart.
Melihat adaptor yang tersedia
GET/adapter menampilkan adaptor yang ada di kode beserta endpoint bank untuk tiap layanan. Kolom confirmed menunjukkan apakah path itu sudah berasal dari dokumen bank.
Mendaftarkan bank
POST /api/intbank
{
"id": "BTN",
"bank_code": "200",
"nama": "Bank BTN",
"adapter": "BTN",
"env": "UAT",
"base_url": "https://devapi.btn.co.id",
"client_key": "<client id dari bank>",
"partner_id": "<partner id dari bank>",
"channel_id": "<channel id>",
"norek": "<rekening settlement KBI>",
"nama_rek": "KLIRING BERJANGKA INDONESIA",
"va_prefix": "6775",
"opsi": { "origin": "https://<domain KBI>" }
}| Field | Wajib | Keterangan |
|---|---|---|
id | Ya | Kode bank di integrator, 2–10 karakter. Menjadi <ID> pada nama variabel rahasia. Tidak bisa diubah. |
bank_code | Ya | Kode bank BI (002, 008, 009, 200, 451). Dipakai untuk mengenali transfer sesama bank. |
nama | Ya | Nama tampilan. |
adapter | Ya | Salah satu dari GET /adapter. |
env | SIM, UAT (bawaan), atau PRODUCTION. PRODUCTION mewajibkan base_url https. | |
base_url | Alamat dasar API bank, tanpa path layanan. | |
client_key | Dikirim sebagai X-CLIENT-KEY saat meminta token. | |
partner_id | Dikirim sebagai X-PARTNER-ID. | |
channel_id | Dikirim sebagai CHANNEL-ID. Untuk BSI isi API. | |
norek, nama_rek | Rekening sumber bawaan. Dipakai bila permintaan tidak mengirim source_account. | |
va_prefix | Prefix virtual account (partnerServiceId), maksimal 8 karakter. Wajib untuk layanan VA. | |
timeout_inquiry_ms, timeout_transfer_ms | 0 = pakai bawaan dari .env. | |
retry_max | -1 = pakai bawaan; 0–5 = khusus bank ini. | |
path_override | Objek {kunci endpoint: path} untuk menimpa path bawaan adaptor. | |
opsi | Isian khusus bank yang bukan rahasia (lihat di bawah). | |
aktif | 1 (bawaan) atau 0. |
Isian opsi per bank
| Bank | Kunci | Kegunaan |
|---|---|---|
| BRI | device_id, channel | Dikirim sebagai additionalInfo.deviceId dan .channel pada inquiry dan transfer. |
| BTN | origin | Header Origin: nama domain KBI yang didaftarkan ke BTN. |
| BSI | user_id, parent_account_no | User ID NCMS dan rekening induk VA. |
Memeriksa kesiapan
GET/intbank menampilkan tiap bank beserta keadaannya:
| Bagian | Isi |
|---|---|
rahasia | Apakah client secret, private key, API key, dan sertifikat mTLS sudah diisi — nilainya tidak pernah ditampilkan. |
keadaan.configured | true bila konfigurasi lengkap untuk memanggil bank. Bila false, config_error menyebut yang kurang. |
keadaan.token_valid | Apakah integrator sedang memegang token bank yang masih berlaku. |
masalah | Muncul bila ada kesalahan memuat, misalnya berkas kunci tidak terbaca. |
layanan, metode_transfer | Layanan yang dibuka adaptor bank ini. |
Menguji koneksi
POST /api/intbank/BTN/pingIntegrator meminta token baru ke bank. Jawaban "ok": true berarti alamat, client key, private key, dan bentuk waktu sudah diterima bank. Ini langkah pertama setiap kali menyambung ke lingkungan baru.
Mengubah, menonaktifkan, menghapus
- PUT
/intbank/:id— kirim seluruh field (bukan sebagian). Token lama dibuang; token baru diambil saat panggilan berikutnya. - Menonaktifkan:
"aktif": 0. Bank tidak lagi dipilih routing dan permintaan ke bank itu ditolak. - DELETE
/intbank/:id— hanya untuk bank yang belum punya transaksi. Bank yang sudah dipakai cukup dinonaktifkan. - POST
/intbank-reload— memuat ulang konfigurasi dan rahasia, misalnya setelah berkas kunci diganti di server.
Rahasia dibaca dari environment saat service dimulai. Mengubah isi .env butuh restart; mengganti isi berkas kunci cukup dengan POST /intbank-reload.
Bab 6Mengatur routing
Bagaimana integrator memilih bank untuk satu permintaan.
Urutan pemilihan
- Field
bankdi permintaan — kode integrator (BTN) atau kode bank BI (200). - Aturan routing di tabel
r_integrator_route: yang cocok layanan dan mata uangnya, prioritas terkecil lebih dulu, dan banknya mendukung layanan itu. DEFAULT_BANKdi.env.- Bila hanya ada satu bank aktif yang mendukung layanan itu, bank itu dipakai.
Bila tidak ada yang cocok, permintaan ditolak 400 dengan pesan "bank tujuan belum ditentukan". Jalur yang dipakai muncul di jawaban sebagai route: request, route, default, atau single.
Membuat aturan
POST /api/route
{ "layanan": "TRANSFER", "mata_uang": "IDR", "bank_id": "BTN", "prioritas": 10, "ket": "Transfer rupiah lewat BTN" }| Field | Keterangan |
|---|---|
layanan | Nama layanan standar, atau * untuk semua. Bawaan *. |
mata_uang | Kode 3 huruf, atau *. Bawaan *. |
bank_id | Kode bank yang sudah terdaftar di /intbank. |
prioritas | Angka kecil didahulukan. Bawaan 100. Pada prioritas sama, aturan yang lebih spesifik menang atas *. |
aktif, ket | Mengaktifkan/mematikan aturan; catatan bebas. |
Menguji tanpa memanggil bank
GET /api/route-uji?layanan=TRANSFER&mata_uang=IDR{ "Hasil": { "layanan": "TRANSFER", "bank": "BTN", "nama": "Bank BTN", "jalur": "route" } }Transaksi yang harus keluar dari rekening bank tertentu sebaiknya selalu mengirim bank. Routing cocok untuk layanan yang boleh dilayani bank mana saja, atau sebagai cadangan bila satu bank dinonaktifkan.
Bab 7Layanan transaksi
Tujuh layanan: apa yang dikirim dan apa yang diterima.
Semua rute di bawah /api, metode POST, badan JSON, dan hanya untuk user tipe A. Field berikut berlaku di semua layanan:
| Field | Keterangan |
|---|---|
bank | Bank eksekutor. Kosong = ditentukan routing. |
member_id | Anggota yang bertransaksi. Kosong = member user yang login. |
currency | Bawaan IDR. |
extra | Objek bebas yang diteruskan ke bank sebagai additionalInfo. |
Nominal dan nomor rekening boleh dikirim sebagai teks maupun angka; integrator menyimpannya sebagai teks agar digitnya tidak berubah. Nominal memakai titik sebagai desimal, paling banyak dua angka di belakang koma.
7.1 Cek saldo
POST/trx/balance
{ "bank": "MDR", "account_no": "1150006399259" }account_no boleh dikosongkan; integrator memakai rekening bawaan bank itu. Data yang dikembalikan: account_no, account_name, available_balance, ledger_balance, hold_amount, currency.
7.2 Inquiry rekening tujuan
POST/trx/account-inquiry
{ "bank": "MDR", "beneficiary_account": "1390094033549", "beneficiary_bank": "014" }Bila beneficiary_bank kosong atau sama dengan bank eksekutor, integrator memakai inquiry internal; selain itu inquiry antarbank. Data: account_no, account_name, bank_code, bank_name, account_status, currency.
Sebagian bank mencocokkan nama penerima pada transfer dengan hasil inquiry dan menolak bila berbeda. Gunakan account_name dari inquiry sebagai beneficiary_name.
7.3 Transfer
POST/trx/transfer
{
"transaction_id": "TRX-20261007-0001",
"bank": "BTN",
"member_id": "IX",
"beneficiary_account": "1150010883959",
"beneficiary_bank": "008",
"beneficiary_name": "PT ANGGOTA KLIRING",
"amount": "1250000.00",
"remark": "Pencairan dana"
}| Field | Wajib | Keterangan |
|---|---|---|
transaction_id | Ya | 6–40 karakter: huruf, angka, titik, garis bawah, tanda hubung; diawali huruf atau angka. Harus unik per transaksi. |
beneficiary_account | Ya | 5–34 digit. |
amount | Ya | Lebih dari nol. |
source_account | Kosong = rekening bawaan bank. | |
beneficiary_bank | Kode bank tujuan. Kosong atau sama dengan bank eksekutor = sesama bank. | |
beneficiary_name | Bersyarat | Wajib untuk transfer ke bank lain. |
beneficiary_bank_name | Kosong = diambil dari r_bank. | |
beneficiary_bank_bic | Kode BIC bank tujuan. Dibutuhkan BTN untuk SKN/RTGS. | |
beneficiary_type | PERSONAL atau CORPORATE (bawaan), untuk SKN/RTGS. | |
method | Lihat tabel di bawah. Bawaan AUTO. | |
remark | Berita transfer, maksimal 100 karakter. | |
transaction_date | Kosong = saat ini. |
| Metode | Dipakai untuk |
|---|---|
AUTO | Integrator memilih: INTRABANK bila bank tujuan sama dengan bank eksekutor, selain itu INTERBANK. |
INTRABANK | Sesama bank. Ditolak bila bank tujuan berbeda. |
INTERBANK | Antarbank online (switching, BI-FAST). |
SKN, RTGS | Antarbank lewat SKN atau RTGS. Hanya bank yang membukanya (Mandiri, BTN). |
Data yang dikembalikan: bank_reference_no, amount, currency, source_account, beneficiary_account, transaction_date.
7.4 Konfirmasi status
POST/trx/status
{ "transaction_id": "TRX-20261007-0001" }Berlaku untuk transfer maupun pembuatan VA. Bila transaksi masih PENDING, integrator menanyakan bank dan menerapkan hasilnya. Bila sudah berstatus akhir, jawaban diambil dari catatan tanpa memanggil bank. Untuk sekadar membaca tanpa menanyakan bank, gunakan GET /trx/:transaction_id.
7.5 Mutasi rekening
POST/trx/statement
{ "bank": "MDR", "from_date": "2026-10-01", "to_date": "2026-10-07" }Rentang paling lama 31 hari. Tanggal tanpa jam pada to_date berarti sampai akhir hari itu. Data: entries (tiap entri berisi date, amount, currency, type = DEBIT/CREDIT, remark, reference_no), total_debit, total_credit.
7.6 Membuat virtual account
POST/trx/va
{
"transaction_id": "VA-20261007-0001",
"bank": "BNI",
"customer_no": "0000001234",
"va_name": "Anggota Kliring 017",
"amount": "50000000",
"va_type": "CLOSED",
"expired_at": "2026-10-14"
}| Field | Wajib | Keterangan |
|---|---|---|
transaction_id | Ya | Aturan sama dengan transfer. |
customer_no atau va_no | Ya | Nomor VA lengkap = prefix bank + customer_no. Bila mengirim va_no, harus diawali prefix bank itu. |
va_name | Ya | Maksimal 100 karakter. |
va_type | CLOSED (nominal tetap, bawaan) atau OPEN. | |
amount | Bersyarat | Wajib lebih dari nol untuk CLOSED. |
expired_at | Harus tanggal yang akan datang. | |
va_email, va_phone, remark | Diteruskan bila bank menerimanya. |
Data: va_no, va_name, amount, currency, va_type, expired_at.
7.7 Inquiry virtual account
POST/trx/va-inquiry
{ "bank": "BNI", "va_no": "988291720000001234" }Data: isi VA ditambah found, paid (sudah dibayar atau belum), dan bila ada paid_amount serta payment_date. VA yang tidak ada dijawab REJECTED dengan found: false.
Bab 8Membaca jawaban
Satu bentuk jawaban untuk semua bank dan semua layanan.
{
"success": true,
"message": "Berhasil",
"Hasil": {
"request_id": "ITG26100716331629117164",
"transaction_id": "TRX-20261007-0001",
"service": "TRANSFER",
"bank": "BTN",
"route": "request",
"bank_service": "transfer-interbank",
"method": "INTERBANK",
"status": "SUCCESS",
"reason": "SUCCESS",
"retryable": false,
"bank_response_code": "2001800",
"bank_response_message": "Successful",
"bank_reference_no": "…",
"external_id": "202610071633167457838676493552",
"http_status": 200,
"attempts": 1,
"latency_ms": 184,
"duplicate": false,
"timestamp": "2026-10-07T16:33:16+07:00",
"data": { "amount": "1250000.00", "currency": "IDR", "beneficiary_account": "1150010883959" }
}
}| Field | Arti |
|---|---|
success | true untuk SUCCESS dan PENDING; false untuk FAILED dan REJECTED. Jangan dipakai sendirian — baca status. |
status | Salah satu dari empat status standar. Inilah penentu. |
reason | Kode alasan standar, sama artinya di semua bank. |
message | Penjelasan dalam bahasa Indonesia. |
retryable | true = aman dikirim ulang dengan transaction_id yang sama. |
bank_response_code, bank_response_message | Jawaban asli bank, untuk komunikasi dengan bank. |
bank_reference_no | Referensi dari bank, untuk pelacakan dan rekonsiliasi. |
external_id | X-EXTERNAL-ID yang dikirim ke bank. |
bank_service, method | Layanan bank yang dipanggil dan metode transfer efektif. |
route | Cara bank dipilih (Bab 6). |
attempts | Jumlah percobaan ke bank. |
duplicate | true = transaction_id ini sudah pernah dikirim; ini jawaban atas transaksi yang sama. |
transaction | (transfer, VA, status) Baris transaksi seperti tersimpan. |
data | Isi jawaban yang sudah dinormalkan; bentuknya per layanan (Bab 7). |
Kode HTTP
HTTP 200 berarti integrator berhasil memberi jawaban standar — bukan berarti transaksinya berhasil. Kode lain hanya untuk kesalahan di tingkat integrator, sebelum bank disentuh.
| HTTP | Arti | Tindakan |
|---|---|---|
| 200 | Jawaban standar tersedia | Baca Hasil.status |
| 400 | Bank tidak dikenal, routing tidak menemukan bank, badan bukan JSON | Perbaiki permintaan atau konfigurasi |
| 401 | Token tidak ada, salah, atau kedaluwarsa | Login ulang |
| 403 | Peran tidak diizinkan, atau IP tidak terdaftar | Gunakan user tipe A; periksa IP_ALLOW |
| 404 | Transaksi atau data tidak ditemukan | — |
| 409 | transaction_id dipakai untuk isi berbeda, atau transaksi sedang diproses | Lihat Bab 9 |
| 422 | Validasi gagal; daftar kesalahan ada di error | Perbaiki data |
| 429 | Terlalu banyak permintaan | Tunggu, kurangi laju |
Kode alasan yang sering muncul
| Status | reason | Arti |
|---|---|---|
| SUCCESS | SUCCESS | Berhasil. |
| PENDING | IN_PROGRESS | Bank menerima dan masih memproses (HTTP 202). |
TIMEOUT | Permintaan terkirim, bank tidak menjawab dalam batas waktu. | |
GENERAL_ERROR, INTERNAL_SERVER_ERROR, EXTERNAL_SERVER_ERROR | Galat di sisi bank atau switching (5xx). | |
DUPLICATE_REFERENCE, DUPLICATE_EXTERNAL_ID | Bank sudah pernah melihat referensi ini. | |
UNKNOWN_RESPONSE_CODE, HTTP_404, INTERRUPTED | Jawaban tak dikenal, path tidak ada di bank, atau proses terhenti di tengah panggilan. | |
| FAILED | CONNECTION_FAILED | Bank tidak terhubung; permintaan belum terkirim. Retryable. |
BANK_TOKEN_FAILED | Token bank tidak diperoleh. Retryable. | |
TOO_MANY_REQUESTS, NOT_ALLOWED_AT_THIS_TIME | Bank membatasi laju, atau di luar jam layanan. Retryable. | |
NOT_FOUND_AT_BANK | Setelah dikonfirmasi, bank tidak mengenal transaksi ini. Retryable. | |
UNAUTHORIZED | Bank menolak tanda tangan. Bukan retryable: perlu perbaikan konfigurasi. | |
BANK_NOT_CONFIGURED | Konfigurasi atau rahasia bank belum lengkap. | |
| REJECTED | ACCOUNT_NOT_FOUND, ACCOUNT_INACTIVE, ACCOUNT_DORMANT | Masalah pada rekening tujuan. |
INSUFFICIENT_FUNDS | Saldo rekening sumber tidak cukup. | |
LIMIT_EXCEEDED, SUSPECTED_FRAUD | Tertahan limit atau screening bank. | |
INVALID_FIELD_FORMAT, INVALID_MANDATORY_FIELD, BAD_REQUEST | Bank menolak isi permintaan. | |
SERVICE_NOT_SUPPORTED | Bank itu tidak membuka layanan atau metode yang diminta. | |
FAILED_AT_BANK, INVALID_BILL, BILL_PAID | Bank menyatakan transaksi gagal; VA tidak ada; tagihan sudah dibayar. |
Daftar lengkap pemetaan kode bank ke status tersedia di GET /ref/status.
Bab 9Idempotency, retry, dan PENDING
Aturan yang mencegah transaksi ganda. Bab terpenting bagi pengembang Aplikasi Kliring.
Transaksi yang timeout atau dijawab galat bank belum tentu gagal — bank mungkin sudah memprosesnya. Karena itu integrator menandainya PENDING, bukan gagal. Jangan membuat transaksi baru sebagai penggantinya.
Apa yang harus dilakukan Aplikasi Kliring
| Jawaban | Tindakan |
|---|---|
| SUCCESS | Catat berhasil. Simpan bank_reference_no. |
| PENDING | Tandai "menunggu konfirmasi bank". Jangan kirim transaksi baru. Integrator mengonfirmasi otomatis; baca hasilnya lewat GET /trx/:transaction_id, atau minta konfirmasi segera lewat POST /trx/status. |
FAILED + retryable: true | Boleh dikirim ulang dengan transaction_id yang sama. Integrator sudah mencoba ulang otomatis beberapa kali sebelum menjawab. |
FAILED + retryable: false | Ada masalah konfigurasi (tanda tangan ditolak, bank belum siap). Hubungi operator; jangan diulang. |
| REJECTED | Final. Perbaiki penyebabnya, lalu buat transaksi baru dengan transaction_id baru. |
| HTTP 409 | Jangan ganti id. Baca GET /trx/:transaction_id untuk melihat transaksi yang sudah ada. |
| Tidak ada jawaban dari integrator | Kirim ulang dengan transaction_id yang sama. Aman berapa kali pun. |
Bagaimana ulangan ditangani
Mengirim ulang transaction_id yang sama tidak pernah menghasilkan instruksi kedua ke bank, kecuali percobaan sebelumnya terbukti belum diproses.
| Keadaan transaksi tersimpan | Yang terjadi saat dikirim ulang |
|---|---|
| SUCCESS atau REJECTED | Hasil tersimpan dikembalikan, duplicate: true. Bank tidak dipanggil. |
| PENDING | Integrator melakukan cek status ke bank, bukan mengirim ulang. |
| FAILED dan boleh diulang | Dijalankan lagi dengan referensi yang sama. duplicate: false. |
| FAILED dan tidak boleh diulang | Hasil tersimpan dikembalikan. |
| Sedang diproses | HTTP 409. |
| Isi berbeda (rekening, nominal, bank) | HTTP 409: id sudah dipakai untuk transaksi lain. |
Retry otomatis
Integrator mengulang sendiri hingga RETRY_MAX kali, dengan jeda yang berlipat, hanya bila bank pasti belum menerima instruksi: koneksi gagal sebelum permintaan terkirim, token tidak diperoleh, atau bank menjawab 429. Timeout setelah permintaan terkirim tidak pernah diulang.
Konfirmasi otomatis
- Transaksi PENDING dijadwalkan untuk dikonfirmasi menurut
PENDING_CHECK_SCHEDULE(bawaan: 30 detik, 1 menit, 2, 5, 10, 30 menit, lalu tiap jam). - Transfer dikonfirmasi lewat cek status transfer; pembuatan VA lewat inquiry VA.
- Jawaban "tidak ditemukan" baru dianggap final setelah
NOT_FOUND_GRACE(5 menit) sejak pengiriman terakhir. Saat itu transaksi menjadi FAILEDNOT_FOUND_AT_BANKdan boleh dikirim ulang. - Setelah
PENDING_CHECK_MAXkali tanpa kepastian, konfirmasi otomatis berhenti. Transaksi tetap PENDING dan terhitung padaperlu_cek_manualdi monitoring — operator menanyakannya ke bank. - Bila service mati di tengah panggilan ke bank, transaksinya dipulihkan menjadi PENDING
INTERRUPTEDlalu dikonfirmasi seperti biasa.
Bab 10Adaptor tiap bank
Layanan yang dibuka dan kekhususan yang sudah ditangani.
Layanan per bank
| Layanan | MDR | BRI | BNI | BTN | BSI |
|---|---|---|---|---|---|
| Cek saldo | ✓ | ✓ | ○ | ✓ | ✓ (VA) |
| Inquiry rekening | ✓ | ✓ antarbank · ○ internal | ○ | ✓ | — |
| Transfer intrabank | ✓ | ○ | ○ | ✓ | — |
| Transfer antarbank | ✓ | ✓ | ○ | ✓ | — |
| SKN / RTGS | ✓ | — | — | ✓ | — |
| Cek status transfer | ✓ | ○ | ○ | ✓ | — |
| Mutasi rekening | ✓ | ✓ | ○ | ✓ | ✓ (VA) |
| Buat VA | — | ○ | ✓ | ✓ | ✓ (Billing) |
| Inquiry VA | — | ○ | ✓ | ✓ | ✓ |
✓ path dari dokumen bank · ○ tersedia tetapi path belum terkonfirmasi · — tidak dibuka
Tanda ○ berarti path ditulis mengikuti pola SNAP atau pola produk bank, bukan dari dokumen bank itu: seluruh layanan non-VA BNI; intrabank, cek status, dan BRIVA SNAP BRI. Path token BSI juga belum ada di dokumennya. Daftar persisnya ada di GET /adapter ("confirmed": false). Bila path sebenarnya berbeda, isi path_override — tanpa build ulang.
Kekhususan yang ditangani adaptor
| Bank | Kode | Yang berbeda dari SNAP baku |
|---|---|---|
| Mandiri | MDR · 008 | Path /openapi/… (Corpay SNAP 1.0.11). VA tidak dibuat dari sisi KBI: VA Mandiri berpola UBP, bank yang memanggil KBI. |
| BRI | BRI · 002 | X-TIMESTAMP bermilidetik; jawaban token tanpa responseCode; X-EXTERNAL-ID 9 digit; additionalInfo.deviceId dan .channel; cek status terpisah untuk intrabank dan antarbank. |
| BNI | BNI · 009 | partnerServiceId 8 karakter dengan spasi pengisi di kiri. |
| BTN | BTN · 200 | Header Origin wajib; saldo meminta balanceTypes; tipe VA nominal tetap ditulis F; status transaksi tiga digit; SKN/RTGS memakai kode BIC. |
| BSI | BSI · 451 | Layanan ditandatangani RSA, bukan HMAC; setiap badan memuat apiKey, userId, custId; CHANNEL-ID = API; VA Billing memakai billDetails; tanggal kedaluwarsa hanya tanggal. |
Menimpa path
PUT /api/intbank/BTN
{ …seluruh field…, "path_override": { "transfer-status": "/snap/v1/transfer/status" } }Kunci endpoint yang berlaku: balance-inquiry, account-inquiry-internal, account-inquiry-external, transfer-intrabank, transfer-interbank, transfer-skn, transfer-rtgs, transfer-status, bank-statement, va-create, va-inquiry.
Mengirim field khusus bank
Field yang hanya dikenal satu bank dikirim lewat extra; integrator meneruskannya sebagai additionalInfo. Contoh: BI-FAST di BRI memakai "extra": {"serviceCode": "80", …}; field VA Billing BSI seperti biaya, jadwal, dan KYC juga lewat extra. Isian dari Kliring menang atas bawaan adaptor.
Bab 11Log, audit, dan monitoring
Menelusuri satu transaksi dan memantau kesehatan integrasi.
Daftar transaksi
GET/trx — transfer dan pembuatan VA, terbaru di atas.
| Saringan | Contoh |
|---|---|
status | ?status=PENDING |
bank, layanan, member_id | ?bank=BTN&layanan=TRANSFER |
dari, sampai | ?dari=2026-10-01&sampai=2026-10-07 |
q | Mencari di transaction_id, referensi bank, rekening tujuan, nama tujuan. |
limit | Bawaan 100, maksimal 500. |
Rincian satu transaksi — audit trail
GET/trx/:transaction_id menampilkan transaksi beserta panggilan: seluruh panggilan ke bank yang pernah dilakukan untuknya, berurutan — token, transfer, dan setiap cek status. Kolom penting:
| Kolom | Arti |
|---|---|
status, alasan, pesan | Keadaan terakhir. |
boleh_ulang | Aman dikirim ulang dengan id yang sama. |
terkirim | Permintaan pernah tertulis utuh ke bank. |
percobaan | Jumlah pengiriman ke bank. |
cek_status, cek_berikut | Jumlah konfirmasi yang sudah dilakukan dan jadwal berikutnya. cek_berikut kosong pada transaksi PENDING = menunggu cek manual. |
tgl, tgl_kirim, tgl_selesai | Diterima pertama kali, pengiriman terakhir ke bank, dan saat mencapai status akhir. |
userid, ip | Siapa yang meminta. |
Log panggilan ke bank
GET/log — setiap panggilan HTTP ke bank, termasuk permintaan token. Saringan: bank, layanan (nama layanan bank, mis. transfer-intrabank), status, transaction_id, request_id, dari, sampai, gagal=1, limit.
GET/log/:id menampilkan header dan badan permintaan serta jawaban. http_status = 0 berarti bank tidak menjawab.
Nomor rekening hanya menyisakan empat digit terakhir, nama hanya dua huruf pertama tiap kata. Token dan tanda tangan hanya potongan awal; access token dan API key ditulis ***. Nilai utuh hanya ada di tabel transaksi, karena tanpa itu rekonsiliasi tidak mungkin.
Monitoring
GET/monitor?menit=60 — ringkasan dalam jendela waktu terakhir (1 sampai 1440 menit).
| Bagian | Isi |
|---|---|
bank | Tiap bank: keadaan koneksi dan token, waktu jawaban terakhir, waktu galat koneksi terakhir, ringkasan panggilan. |
layanan | Per bank dan layanan: total, sukses, galat, timeout, tidak_dijawab, tingkat_galat_persen, latensi_rata_ms, latensi_p95_ms, latensi_maks_ms. |
transaksi_hari_ini | Jumlah dan nominal per bank dan status. |
pending | jumlah, tertua, dan perlu_cek_manual. |
Yang perlu diperhatikan operator setiap hari
pending.perlu_cek_manuallebih dari nol — ada transaksi yang tidak bisa dipastikan otomatis. Tanyakan ke bank dengantransaction_iddanexternal_id-nya.pending.tertuasudah lama — periksa apakah bank itu sedang bermasalah.tingkat_galat_persenatautimeoutnaik pada satu bank — pertimbangkan mengalihkan routing sementara.keadaan.configured=false— bank itu tidak bisa dipanggil sampai konfigurasinya dilengkapi.
Jejak audit pengguna
Login, logout, dan setiap perubahan konfigurasi bank atau routing dicatat ke t_log, sama seperti cmc-api2. Jejak transaksi tidak ditulis ke sana; semuanya ada di t_integrator_trx dan t_integrator_log.
Bab 12Simulator dan pengujian
Mencoba semua layanan dan semua skenario tanpa koneksi ke bank.
Dengan SIM_ENABLED=1, service juga berperan sebagai kelima bank di /sim/<BANK>/…. Simulator memakai profil yang sama dengan adaptor (path, bentuk waktu, panjang X-EXTERNAL-ID, cara tanda tangan) dan memeriksa token serta tanda tangan sungguhan. Adaptor yang salah menandatangani langsung ditolak.
Transaksi yang "berhasil" di simulator tidak memindahkan dana. Service menolak dijalankan bila SIM_ENABLED=1 bersama APP_ENV=production.
Skenario
Dipilih dari empat digit terakhir rekening tujuan (transfer, inquiry) atau nomor pelanggan (VA).
| Akhiran | Perilaku simulator | Hasil di integrator |
|---|---|---|
0404 | Rekening atau VA tidak ditemukan | REJECTED |
0403 | Rekening tidak aktif | REJECTED |
0500 | Galat 500, transaksi tidak tercatat | PENDING → FAILED boleh diulang |
0504 | Diproses, tetapi tidak dijawab | PENDING → SUCCESS |
0202 | 202 diproses, lalu sukses | PENDING → SUCCESS |
0206 | 202 diproses, lalu gagal | PENDING → REJECTED |
0200 | (VA) sudah dibayar | paid: true |
| lainnya | Berhasil | SUCCESS |
Saldo awal tiap bank simulator Rp 10 miliar; nominal di atasnya dijawab saldo tidak cukup. GET /sim menampilkan keadaan simulator, DELETE /sim meresetnya.
Uji otomatis
go test ./internal/...Uji unit: tanda tangan dicocokkan dengan hasil hitung di luar Go (Python dan OpenSSL), transformasi tiap bank, dan pemetaan status.
python tools/e2e.pyUji ujung-ke-ujung, 94 pemeriksaan: keamanan, routing, ketujuh layanan di lima bank, idempotency (termasuk permintaan serentak), timeout, konfirmasi, retry, log, dan monitoring. Service harus hidup dengan batas waktu pendek supaya uji selesai dalam sekitar dua menit:
BANK_TRANSFER_TIMEOUT=4s SIM_TIMEOUT_DELAY=7s SIM_PENDING_DELAY=6s \
PENDING_CHECK_INTERVAL=2s PENDING_CHECK_SCHEDULE=3s,3s,4s NOT_FOUND_GRACE=10s \
./tmp/integrator.exeSkrip membuat token sendiri dari JWT_SECRET di .env, jadi tidak butuh password.
Bab 13Menuju UAT dan produksi
Urutan kerja dari lokal ke lingkungan bank.
- Siapkan database
Cadangkan database, lalu jalankan
sql/migration.sql. Isinya hanyaCREATE TABLE IF NOT EXISTS. Jangan memuatsql/seed.sql. - Siapkan environment
APP_ENV=production(atauuat),SIM_ENABLED=0,JWT_SECRETbaru,IP_ALLOWberisi IP server Aplikasi Kliring,CORS_ORIGINSsesuai kebutuhan. - Buat kunci per bank dan serahkan public key-nya Simpan private key di server dengan hak baca terbatas. Daftarkan public key ke bank lewat jalur resmi masing-masing.
- Daftarkan bank
POST /intbankdengan base URL, client key, partner id, channel id, rekening, prefix VA, dan opsi dari bank. Isi rahasianya di.env, lalu restart. - Pastikan koneksi jaringan
IP server integrator didaftarkan di whitelist bank; sertifikat mTLS dipasang bila diminta; jam server tersinkron (bank menolak
X-TIMESTAMPyang meleset). - Uji bertahap
POST /intbank/:id/ping→ cek saldo → inquiry rekening → transfer bernominal kecil → cek status transfer itu. PeriksaGET /logpada tiap langkah. - Atur routing
Buat aturan di
/routeatau wajibkan Aplikasi Kliring mengirimbank.
Yang perlu dikonfirmasi ke tiap bank
- Path setiap endpoint yang bertanda ○ di Bab 10.
- Bentuk dan panjang
X-EXTERNAL-ID, dan bentukX-TIMESTAMP. - Aturan idempotency bank: per
partnerReferenceNoatau perX-EXTERNAL-ID, dan berapa lama berlaku. - Karakter yang diterima pada
partnerReferenceNo— menentukan bentuktransaction_idyang aman dipakai Kliring. - Batas waktu jawaban transfer, untuk menyetel
timeout_transfer_msbank itu. - Kode jawaban yang tidak ada di daftar
GET /ref/status.
Service sudah diuji lengkap terhadap simulator di lokal. Belum pernah disambungkan ke bank sungguhan, belum di-deploy, dan foldernya belum dilacak git.
Bab 14Pemecahan masalah
Gejala, penyebab yang paling mungkin, dan tindakannya.
Service tidak mau jalan
| Pesan | Penyebab | Tindakan |
|---|---|---|
variabel wajib belum diisi | DB_USER, DB_NAME, atau JWT_SECRET kosong | Lengkapi .env |
JWT_SECRET terlalu pendek | Kurang dari 32 karakter | Perpanjang |
Konfigurasi bank gagal dimuat | Tabel integrator belum ada | Jalankan sql/migration.sql |
SIM_ENABLED=1 tidak boleh dipakai dengan APP_ENV=production | Simulator hidup di produksi | SIM_ENABLED=0 |
Server gagal berjalan … bind | Port sudah dipakai, biasanya oleh proses service yang sama | Hentikan proses lama, atau ganti PORT |
Permintaan ditolak integrator
| Gejala | Penyebab | Tindakan |
|---|---|---|
| 401 Invalid or expired token | Token habis, atau JWT_SECRET berbeda dengan penerbit token | Login ulang; samakan secret bila memakai token cmc-api2 |
| 403 peran user tidak diizinkan | User tipe V memanggil rute yang mengubah | Gunakan user tipe A |
| 403 alamat IP tidak terdaftar | IP pemanggil tidak ada di IP_ALLOW | Tambahkan IP; periksa proxy di depan service |
| 400 bank … tidak terdaftar atau tidak aktif | Kode bank salah, atau bank dinonaktifkan | Periksa GET /intbank |
| 400 bank tujuan belum ditentukan | Tanpa field bank dan tidak ada aturan routing yang cocok | Kirim bank, atau tambah aturan di /route |
| 409 pada transfer | transaction_id dipakai ulang dengan isi berbeda, atau transaksi masih berjalan | Baca GET /trx/:transaction_id |
| 422 | Validasi gagal | Baca daftar di error |
Masalah dengan bank
reason / gejala | Penyebab yang paling mungkin | Tindakan |
|---|---|---|
BANK_NOT_CONFIGURED | Base URL, client key, atau rahasia belum diisi; message menyebut yang kurang | Lengkapi, lalu restart atau POST /intbank-reload |
masalah berisi private key: … | Berkas kunci tidak ada, tidak terbaca, atau bukan PEM RSA | Periksa path dan hak baca berkas |
CONNECTION_FAILED | Alamat salah, firewall, IP belum di-whitelist bank, VPN mati | Uji jaringan dari server; POST /intbank/:id/ping |
BANK_TOKEN_FAILED | Client key salah, public key belum terdaftar di bank, bentuk waktu ditolak, jam server meleset | Lihat jawaban bank di GET /log?layanan=access-token-b2b |
UNAUTHORIZED (kode bank 401xx00) | Tanda tangan ditolak: client secret salah, atau path yang ditandatangani berbeda dari yang dihitung bank | Periksa client secret; periksa apakah base_url memuat awalan path |
PENDING dengan HTTP_404 | Path endpoint tidak ada di bank | Isi path_override dengan path dari dokumen bank |
| BTN menjawab 400 soal Origin | Opsi origin kosong atau belum didaftarkan | Isi opsi.origin |
| BSI menjawab 401 soal apiKey | BANK_BSI_API_KEY, opsi.user_id, atau partner_id salah | Cocokkan dengan data NCMS |
Banyak TIMEOUT | Bank lambat, atau batas waktu terlalu pendek | Naikkan timeout_transfer_ms bank itu; pantau /monitor |
| PENDING tidak pernah selesai | Konfirmasi otomatis sudah mencapai batas, atau bank tidak punya layanan cek status | POST /trx/status; bila tetap, tanyakan bank dengan transaction_id dan external_id |
SERVICE_NOT_SUPPORTED | Bank itu tidak membuka layanan atau metode yang diminta | Lihat Bab 10; pilih bank lain |
Menelusuri satu transaksi
GET /trx/<transaction_id>— lihat status, alasan, dan daftarpanggilan.- Ambil
idpanggilan yang bermasalah, bukaGET /log/<id>— lihat apa yang dikirim dan apa jawaban bank. - Saat menghubungi bank, sertakan
transaction_id(di bank:partnerReferenceNo),external_id, waktu, danbank_response_code.
Bab 15Menambah bank baru
Untuk pengembang integrator. Aplikasi Kliring tidak berubah.
Bank berskema SNAP
Buat satu berkas di internal/bank/ berisi profil bank itu:
package bank
func init() {
registerSNAP(&Profile{
Adapter: "XYZ",
BankCode: "999",
Name: "Bank XYZ",
TokenPath: "/snap/v1.0/access-token/b2b",
Endpoints: map[string]Endpoint{
EpBalanceInquiry: {"/snap/v1.0/balance-inquiry", "11", true, "Dokumen API XYZ v1.0"},
EpTransferIntrabank: {"/snap/v1.0/transfer-intrabank", "17", true, "Dokumen API XYZ v1.0"},
EpTransferStatus: {"/snap/v1.0/transfer/status", "36", true, "Dokumen API XYZ v1.0"},
},
})
}| Isian profil | Kapan diisi |
|---|---|
TimeLayout | Bank meminta milidetik pada X-TIMESTAMP (snap.LayoutMillis). |
SignService | Layanan ditandatangani RSA (SignRSA), bukan HMAC. |
TokenWithoutCode | Jawaban token tidak memuat responseCode. |
ExternalIDDigits | Bank membatasi panjang X-EXTERNAL-ID. |
VAPad | partnerServiceId ditulis 8 karakter berpengisi spasi. |
Headers | Bank meminta header tambahan. |
Transform | Badan permintaan bank berbeda dari SNAP baku. |
Normalize | Jawaban bank berbeda dari SNAP baku. |
Tanpa endpoint transfer-status, hasil yang belum pasti tidak akan pernah bisa diselesaikan otomatis. Uji unit menolak profil seperti itu; hal yang sama berlaku untuk pembuatan VA tanpa inquiry VA.
Bank bukan SNAP
Implementasikan interface bank.Adapter (ID, Info, Conn, Supports, Do, Ping, State) lalu daftarkan dengan bank.Register. Do menerima *bank.Request dan harus mengembalikan bank.Result dengan empat status standar. Aturan yang wajib dijaga: layanan yang mengubah sesuatu dan hasilnya tidak pasti harus menjadi PENDING, dan Sent harus jujur menyatakan apakah permintaan sempat terkirim.
Sesudah kode
- Tambahkan uji transformasi bank itu di
internal/bank/bank_test.go. - Build ulang dan deploy.
- Daftarkan koneksinya lewat
POST /intbank, isiBANK_<ID>_*, laluping.
LampiranAcuan cepat
Daftar rute, tabel, dan susunan folder.
A. Daftar rute
Semua di bawah /api. Kolom "Peran" menyebut tipe user yang boleh.
| Metode | Rute | Kegunaan | Peran |
|---|---|---|---|
| GET | / | Health check sederhana | terbuka |
| GET | /health | Health check beserta database (dipakai pipeline deploy) | terbuka |
| POST | /login | Login | terbuka |
| GET | /me | Profil user yang login | A, V |
| POST | /logout | Mencatat logout | A, V |
| GET | /adapter | Katalog adaptor dan endpoint bank | A, V |
| GET | /intbank, /intbank/:id | Konfigurasi dan keadaan bank | A, V |
| POST · PUT · DELETE | /intbank, /intbank/:id | Mengelola konfigurasi bank | A |
| POST | /intbank/:id/ping | Uji koneksi dan kredensial | A |
| POST | /intbank-reload | Muat ulang konfigurasi dan rahasia | A |
| GET | /route, /route/:id, /route-uji | Aturan routing dan uji routing | A, V |
| POST · PUT · DELETE | /route, /route/:id | Mengelola aturan routing | A |
| POST | /trx/balance | Cek saldo | A |
| POST | /trx/account-inquiry | Inquiry rekening tujuan | A |
| POST | /trx/transfer | Transfer | A |
| POST | /trx/status | Konfirmasi status | A |
| POST | /trx/statement | Mutasi rekening | A |
| POST | /trx/va | Buat virtual account | A |
| POST | /trx/va-inquiry | Inquiry virtual account | A |
| GET | /trx, /trx/:transaction_id | Daftar dan rincian transaksi | A, V |
| GET | /log, /log/:id | Log panggilan ke bank | A, V |
| GET | /monitor | Monitoring | A, V |
| GET | /ref/status | Acuan status dan kode respons | A, V |
Buku ini sendiri disajikan service di /panduan/ (di luar /api).
Simulator (di luar /api, hanya bila SIM_ENABLED=1): GET /sim, DELETE /sim, POST /sim/<BANK>/….
B. Tabel database
| Tabel | Isi |
|---|---|
r_integrator_bank | Konfigurasi koneksi tiap bank (tanpa rahasia). |
r_integrator_route | Aturan routing. |
t_integrator_trx | Transfer dan pembuatan VA. transaction_id unik. |
t_integrator_log | Setiap panggilan HTTP ke bank, tersamar. |
Tabel CMC yang dibaca: r_userid, r_member, r_bank. Yang ditulis: t_log (login dan perubahan konfigurasi saja).
C. Susunan folder
api-integrator/
main.go titik masuk
.env.example contoh konfigurasi
internal/
config/ pembacaan .env
db/ koneksi MySQL
middleware/ JWT, peran, IP whitelist, CORS, rate limit
response/ audit/ utils/
snap/ protokol SNAP: tanda tangan, kode respons, penyamaran log
bank/ antarmuka standar + adaptor bri, bni, btn, bsi, mandiri
integrator/ routing, idempotency, retry, konfirmasi status
routes/ rute HTTP dan simulator
sql/ migration.sql, seed.sql
tools/e2e.py uji ujung-ke-ujung
keys/ kunci (tidak masuk git)
doc/ dokumen arsitektur dan buku iniD. Port service di lingkungan KBI
| Port | Service |
|---|---|
| 2026 | cmc-api2 — Aplikasi Kliring |
| 2027 | api-pub — API publik |
| 2028 · 2029 | api-bank |
| 2034 | api-integrator — Bank Integrator |