Buku Panduan

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.

UI Kliring Aplikasi Kliring cmc-api2 · business logic Bank Integrator routing · transformasi tanda tangan · status · log API Mandiri API BRI API BNI API BTN API BSI format standar adaptor
UI Kliring tidak pernah berbicara langsung dengan bank. Seluruh perbedaan teknis antarbank berhenti di integrator.

Apa yang dikerjakan integrator

FungsiArtinya dalam praktik
RoutingMemilih bank yang melayani permintaan, dari field bank atau dari aturan routing.
TransformasiMengubah permintaan standar menjadi badan JSON yang diminta bank, termasuk kekhususan tiap bank.
Autentikasi & tanda tanganMengambil token bank, menyimpannya, memperbaruinya sebelum habis, dan menandatangani setiap permintaan.
Normalisasi jawabanKode dan bentuk jawaban bank yang berbeda-beda dipetakan menjadi empat status standar.
IdempotencySatu transaction_id tidak pernah menjadi dua instruksi ke bank.
Retry & statusMengulang hanya bila aman; hasil yang belum pasti dikonfirmasi ke bank, bukan dikirim ulang.
Log, audit, monitoringSetiap 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.
Batas service ini

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).

LayananRuteKegunaanMengubah sesuatu di bank?
BALANCE_INQUIRYPOST /trx/balanceCek saldo rekeningTidak
ACCOUNT_INQUIRYPOST /trx/account-inquiryMemastikan nama pemilik rekening tujuanTidak
TRANSFERPOST /trx/transferMemindahkan danaYa
TRANSFER_STATUSPOST /trx/statusMengonfirmasi status transaksiTidak
BANK_STATEMENTPOST /trx/statementMutasi rekeningTidak
VA_CREATEPOST /trx/vaMembuat virtual accountYa
VA_INQUIRYPOST /trx/va-inquiryMelihat data dan status bayar VATidak

Dua layanan yang mengubah sesuatu di bank wajib membawa transaction_id dan dicatat di tabel transaksi.

Status standar

StatusArti
SUCCESSBank memproses dan berhasil.
PENDINGBank menerima tetapi belum selesai, atau hasilnya belum pasti (timeout, galat bank). Belum boleh dianggap gagal.
FAILEDTidak diproses karena gangguan teknis. Bank pasti belum menjalankan instruksinya.
REJECTEDBank menolak secara final: data salah, rekening tidak ada, limit, saldo.

Istilah lain

IstilahPenjelasan
transaction_idPengenal unik transaksi yang dibuat Aplikasi Kliring. Menjadi kunci idempotency dan dikirim ke bank sebagai partnerReferenceNo.
request_idPengenal yang dibuat integrator untuk setiap permintaan (ITG…). Dipakai untuk menelusuri log.
AdaptorBagian kode yang mengetahui spesifikasi satu bank. Ada lima: MDR, BRI, BNI, BTN, BSI.
Bank eksekutorBank yang menjalankan permintaan (field bank). Berbeda dengan beneficiary_bank, yaitu bank pemilik rekening tujuan.
Bank referenceNomor 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 (icomex di lokal). Integrator membaca r_userid, r_member, r_bank, dan menulis t_log.
  • OpenSSL untuk membuat kunci RSA.

Langkah

  1. Buat tabel Empat tabel baru; tidak ada tabel atau baris lama yang diubah.
    mysql --default-character-set=utf8mb4 -u root icomex < sql/migration.sql
  2. 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
  3. 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
  4. Siapkan .env Salin .env.example menjadi .env, lalu isi sekurangnya DB_USER, DB_NAME, JWT_SECRET, dan rahasia tiap bank. Untuk lokal, hidupkan simulator dengan SIM_ENABLED=1.
  5. Jalankan
    go run .
    Untuk pengembangan dengan muat ulang otomatis, gunakan air (konfigurasinya di .air.toml).
  6. Periksa
    curl http://localhost:2034/api
    Jawaban yang benar: BANK INTEGRATOR OK.

Isi .env

VariabelBawaanKeterangan
APP_ENVlocallocal, uat, atau production.
DB_HOST DB_PORTlocalhost 3306Alamat MySQL.
DB_USER DB_NAME—Wajib. DB_PASS boleh kosong.
HOSTkosongAlamat yang diikat. Kosong = semua antarmuka; di server isi 127.0.0.1 agar hanya dijangkau lewat nginx.
PORT URL_API2034 /apiPort dan awalan rute.
JWT_SECRET—Wajib, minimal 32 karakter. Bila disamakan dengan cmc-api2, token user Kliring langsung diterima.
JWT_EXPIRES1dUmur token: 1d, 12h, 30m.
CORS_ORIGINShttp://localhost:5173Asal browser yang diizinkan, dipisah koma.
IP_ALLOWkosongIP atau CIDR yang boleh memanggil integrator. Kosong = semua.
RATE_WINDOW RATE_MAX15m 600Batas jumlah permintaan per IP.
DEFAULT_BANKkosongBank yang dipakai bila tidak ada aturan routing yang cocok.
BANK_CONNECT_TIMEOUT5sBatas waktu membuka koneksi ke bank.
BANK_INQUIRY_TIMEOUT15sBatas waktu layanan baca dan permintaan token.
BANK_TRANSFER_TIMEOUT45sBatas waktu transfer dan pembuatan VA.
RETRY_MAX RETRY_BACKOFF2 500msJumlah pengulangan otomatis dan jeda dasarnya (berlipat tiap pengulangan).
BANK_TOKEN_REFRESH_BEFORE60sToken bank diperbarui bila sisa umurnya kurang dari ini.
PENDING_CHECK_INTERVAL15sSeberapa sering antrean PENDING diperiksa. 0 = mati.
PENDING_CHECK_SCHEDULE30s,1m,2m,5m,10m,30m,1hJeda konfirmasi ke-1, ke-2, dan seterusnya.
PENDING_CHECK_MAX30Setelah sebanyak ini, konfirmasi otomatis berhenti.
NOT_FOUND_GRACE5mMasa tenggang sebelum jawaban "tidak ditemukan" dianggap final.
LOG_BODY11 = badan permintaan/jawaban (tersamar) ikut disimpan di log.
SIM_ENABLED SIM_PATH0 /simSimulator bank. Ditolak bila APP_ENV=production.
SIM_TIMEOUT_DELAY SIM_PENDING_DELAY60s 20sPengatur 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.

NamaIsiDipakai
CLIENT_SECRETClient secret dari bankTanda tangan HMAC setiap layanan (semua bank kecuali BSI)
PRIVATE_KEY_FILEPath berkas private key RSA KBITanda tangan token (semua bank) dan layanan BSI
API_KEYAPI key tambahanBSI (API Key NCMS)
TLS_CERT_FILE TLS_KEY_FILESertifikat dan kunci klienmTLS, bila bank memintanya
TLS_CA_FILESertifikat CA bankBila 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=…
Jangan masuk git

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.

Memakai token Aplikasi Kliring

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 userBolehTidak boleh
A — exchange adminSemua: memanggil bank, mengubah konfigurasi bank dan routing, membaca log.—
V — surveillanceMembaca: 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_ALLOW diisi, hanya alamat itu yang dilayani; yang lain dijawab 403.
  • Rate limit — melebihi RATE_MAX permintaan per RATE_WINDOW dijawab 429.
  • Profil — GET /me menampilkan user yang sedang login dan boleh_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>" }
}
FieldWajibKeterangan
idYaKode bank di integrator, 2–10 karakter. Menjadi <ID> pada nama variabel rahasia. Tidak bisa diubah.
bank_codeYaKode bank BI (002, 008, 009, 200, 451). Dipakai untuk mengenali transfer sesama bank.
namaYaNama tampilan.
adapterYaSalah satu dari GET /adapter.
envSIM, UAT (bawaan), atau PRODUCTION. PRODUCTION mewajibkan base_url https.
base_urlAlamat dasar API bank, tanpa path layanan.
client_keyDikirim sebagai X-CLIENT-KEY saat meminta token.
partner_idDikirim sebagai X-PARTNER-ID.
channel_idDikirim sebagai CHANNEL-ID. Untuk BSI isi API.
norek, nama_rekRekening sumber bawaan. Dipakai bila permintaan tidak mengirim source_account.
va_prefixPrefix virtual account (partnerServiceId), maksimal 8 karakter. Wajib untuk layanan VA.
timeout_inquiry_ms, timeout_transfer_ms0 = pakai bawaan dari .env.
retry_max-1 = pakai bawaan; 0–5 = khusus bank ini.
path_overrideObjek {kunci endpoint: path} untuk menimpa path bawaan adaptor.
opsiIsian khusus bank yang bukan rahasia (lihat di bawah).
aktif1 (bawaan) atau 0.

Isian opsi per bank

BankKunciKegunaan
BRIdevice_id, channelDikirim sebagai additionalInfo.deviceId dan .channel pada inquiry dan transfer.
BTNoriginHeader Origin: nama domain KBI yang didaftarkan ke BTN.
BSIuser_id, parent_account_noUser ID NCMS dan rekening induk VA.

Memeriksa kesiapan

GET/intbank menampilkan tiap bank beserta keadaannya:

BagianIsi
rahasiaApakah client secret, private key, API key, dan sertifikat mTLS sudah diisi — nilainya tidak pernah ditampilkan.
keadaan.configuredtrue bila konfigurasi lengkap untuk memanggil bank. Bila false, config_error menyebut yang kurang.
keadaan.token_validApakah integrator sedang memegang token bank yang masih berlaku.
masalahMuncul bila ada kesalahan memuat, misalnya berkas kunci tidak terbaca.
layanan, metode_transferLayanan yang dibuka adaptor bank ini.

Menguji koneksi

POST /api/intbank/BTN/ping

Integrator 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.
Mengganti rahasia

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

  1. Field bank di permintaan — kode integrator (BTN) atau kode bank BI (200).
  2. Aturan routing di tabel r_integrator_route: yang cocok layanan dan mata uangnya, prioritas terkecil lebih dulu, dan banknya mendukung layanan itu.
  3. DEFAULT_BANK di .env.
  4. 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" }
FieldKeterangan
layananNama layanan standar, atau * untuk semua. Bawaan *.
mata_uangKode 3 huruf, atau *. Bawaan *.
bank_idKode bank yang sudah terdaftar di /intbank.
prioritasAngka kecil didahulukan. Bawaan 100. Pada prioritas sama, aturan yang lebih spesifik menang atas *.
aktif, ketMengaktifkan/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" } }
Kapan menyebut bank secara eksplisit

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:

FieldKeterangan
bankBank eksekutor. Kosong = ditentukan routing.
member_idAnggota yang bertransaksi. Kosong = member user yang login.
currencyBawaan IDR.
extraObjek 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.

Lakukan sebelum transfer antarbank

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"
}
FieldWajibKeterangan
transaction_idYa6–40 karakter: huruf, angka, titik, garis bawah, tanda hubung; diawali huruf atau angka. Harus unik per transaksi.
beneficiary_accountYa5–34 digit.
amountYaLebih dari nol.
source_accountKosong = rekening bawaan bank.
beneficiary_bankKode bank tujuan. Kosong atau sama dengan bank eksekutor = sesama bank.
beneficiary_nameBersyaratWajib untuk transfer ke bank lain.
beneficiary_bank_nameKosong = diambil dari r_bank.
beneficiary_bank_bicKode BIC bank tujuan. Dibutuhkan BTN untuk SKN/RTGS.
beneficiary_typePERSONAL atau CORPORATE (bawaan), untuk SKN/RTGS.
methodLihat tabel di bawah. Bawaan AUTO.
remarkBerita transfer, maksimal 100 karakter.
transaction_dateKosong = saat ini.
MetodeDipakai untuk
AUTOIntegrator memilih: INTRABANK bila bank tujuan sama dengan bank eksekutor, selain itu INTERBANK.
INTRABANKSesama bank. Ditolak bila bank tujuan berbeda.
INTERBANKAntarbank online (switching, BI-FAST).
SKN, RTGSAntarbank 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"
}
FieldWajibKeterangan
transaction_idYaAturan sama dengan transfer.
customer_no atau va_noYaNomor VA lengkap = prefix bank + customer_no. Bila mengirim va_no, harus diawali prefix bank itu.
va_nameYaMaksimal 100 karakter.
va_typeCLOSED (nominal tetap, bawaan) atau OPEN.
amountBersyaratWajib lebih dari nol untuk CLOSED.
expired_atHarus tanggal yang akan datang.
va_email, va_phone, remarkDiteruskan 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" }
  }
}
FieldArti
successtrue untuk SUCCESS dan PENDING; false untuk FAILED dan REJECTED. Jangan dipakai sendirian — baca status.
statusSalah satu dari empat status standar. Inilah penentu.
reasonKode alasan standar, sama artinya di semua bank.
messagePenjelasan dalam bahasa Indonesia.
retryabletrue = aman dikirim ulang dengan transaction_id yang sama.
bank_response_code, bank_response_messageJawaban asli bank, untuk komunikasi dengan bank.
bank_reference_noReferensi dari bank, untuk pelacakan dan rekonsiliasi.
external_idX-EXTERNAL-ID yang dikirim ke bank.
bank_service, methodLayanan bank yang dipanggil dan metode transfer efektif.
routeCara bank dipilih (Bab 6).
attemptsJumlah percobaan ke bank.
duplicatetrue = transaction_id ini sudah pernah dikirim; ini jawaban atas transaksi yang sama.
transaction(transfer, VA, status) Baris transaksi seperti tersimpan.
dataIsi 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.

HTTPArtiTindakan
200Jawaban standar tersediaBaca Hasil.status
400Bank tidak dikenal, routing tidak menemukan bank, badan bukan JSONPerbaiki permintaan atau konfigurasi
401Token tidak ada, salah, atau kedaluwarsaLogin ulang
403Peran tidak diizinkan, atau IP tidak terdaftarGunakan user tipe A; periksa IP_ALLOW
404Transaksi atau data tidak ditemukan—
409transaction_id dipakai untuk isi berbeda, atau transaksi sedang diprosesLihat Bab 9
422Validasi gagal; daftar kesalahan ada di errorPerbaiki data
429Terlalu banyak permintaanTunggu, kurangi laju

Kode alasan yang sering muncul

StatusreasonArti
SUCCESSSUCCESSBerhasil.
PENDINGIN_PROGRESSBank menerima dan masih memproses (HTTP 202).
TIMEOUTPermintaan terkirim, bank tidak menjawab dalam batas waktu.
GENERAL_ERROR, INTERNAL_SERVER_ERROR, EXTERNAL_SERVER_ERRORGalat di sisi bank atau switching (5xx).
DUPLICATE_REFERENCE, DUPLICATE_EXTERNAL_IDBank sudah pernah melihat referensi ini.
UNKNOWN_RESPONSE_CODE, HTTP_404, INTERRUPTEDJawaban tak dikenal, path tidak ada di bank, atau proses terhenti di tengah panggilan.
FAILEDCONNECTION_FAILEDBank tidak terhubung; permintaan belum terkirim. Retryable.
BANK_TOKEN_FAILEDToken bank tidak diperoleh. Retryable.
TOO_MANY_REQUESTS, NOT_ALLOWED_AT_THIS_TIMEBank membatasi laju, atau di luar jam layanan. Retryable.
NOT_FOUND_AT_BANKSetelah dikonfirmasi, bank tidak mengenal transaksi ini. Retryable.
UNAUTHORIZEDBank menolak tanda tangan. Bukan retryable: perlu perbaikan konfigurasi.
BANK_NOT_CONFIGUREDKonfigurasi atau rahasia bank belum lengkap.
REJECTEDACCOUNT_NOT_FOUND, ACCOUNT_INACTIVE, ACCOUNT_DORMANTMasalah pada rekening tujuan.
INSUFFICIENT_FUNDSSaldo rekening sumber tidak cukup.
LIMIT_EXCEEDED, SUSPECTED_FRAUDTertahan limit atau screening bank.
INVALID_FIELD_FORMAT, INVALID_MANDATORY_FIELD, BAD_REQUESTBank menolak isi permintaan.
SERVICE_NOT_SUPPORTEDBank itu tidak membuka layanan atau metode yang diminta.
FAILED_AT_BANK, INVALID_BILL, BILL_PAIDBank 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.

Aturan utama

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.

Transfer / buat VA transaction_id unik Bank dipanggil SUCCESS PENDING FAILED REJECTED Cek status ke bank otomatis / POST /trx/status sukses tak dikenal bank retryable: kirim ulang id sama gagal di bank
Hasil yang belum pasti selalu melewati cek status sebelum disimpulkan.

Apa yang harus dilakukan Aplikasi Kliring

JawabanTindakan
SUCCESSCatat berhasil. Simpan bank_reference_no.
PENDINGTandai "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: trueBoleh dikirim ulang dengan transaction_id yang sama. Integrator sudah mencoba ulang otomatis beberapa kali sebelum menjawab.
FAILED + retryable: falseAda masalah konfigurasi (tanda tangan ditolak, bank belum siap). Hubungi operator; jangan diulang.
REJECTEDFinal. Perbaiki penyebabnya, lalu buat transaksi baru dengan transaction_id baru.
HTTP 409Jangan ganti id. Baca GET /trx/:transaction_id untuk melihat transaksi yang sudah ada.
Tidak ada jawaban dari integratorKirim 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 tersimpanYang terjadi saat dikirim ulang
SUCCESS atau REJECTEDHasil tersimpan dikembalikan, duplicate: true. Bank tidak dipanggil.
PENDINGIntegrator melakukan cek status ke bank, bukan mengirim ulang.
FAILED dan boleh diulangDijalankan lagi dengan referensi yang sama. duplicate: false.
FAILED dan tidak boleh diulangHasil tersimpan dikembalikan.
Sedang diprosesHTTP 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 FAILED NOT_FOUND_AT_BANK dan boleh dikirim ulang.
  • Setelah PENDING_CHECK_MAX kali tanpa kepastian, konfirmasi otomatis berhenti. Transaksi tetap PENDING dan terhitung pada perlu_cek_manual di monitoring — operator menanyakannya ke bank.
  • Bila service mati di tengah panggilan ke bank, transaksinya dipulihkan menjadi PENDING INTERRUPTED lalu dikonfirmasi seperti biasa.

Bab 10Adaptor tiap bank

Layanan yang dibuka dan kekhususan yang sudah ditangani.

Layanan per bank

LayananMDRBRIBNIBTNBSI
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

Yang harus dipastikan ke bank sebelum UAT

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

BankKodeYang berbeda dari SNAP baku
MandiriMDR · 008Path /openapi/… (Corpay SNAP 1.0.11). VA tidak dibuat dari sisi KBI: VA Mandiri berpola UBP, bank yang memanggil KBI.
BRIBRI · 002X-TIMESTAMP bermilidetik; jawaban token tanpa responseCode; X-EXTERNAL-ID 9 digit; additionalInfo.deviceId dan .channel; cek status terpisah untuk intrabank dan antarbank.
BNIBNI · 009partnerServiceId 8 karakter dengan spasi pengisi di kiri.
BTNBTN · 200Header Origin wajib; saldo meminta balanceTypes; tipe VA nominal tetap ditulis F; status transaksi tiga digit; SKN/RTGS memakai kode BIC.
BSIBSI · 451Layanan 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.

SaringanContoh
status?status=PENDING
bank, layanan, member_id?bank=BTN&layanan=TRANSFER
dari, sampai?dari=2026-10-01&sampai=2026-10-07
qMencari di transaction_id, referensi bank, rekening tujuan, nama tujuan.
limitBawaan 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:

KolomArti
status, alasan, pesanKeadaan terakhir.
boleh_ulangAman dikirim ulang dengan id yang sama.
terkirimPermintaan pernah tertulis utuh ke bank.
percobaanJumlah pengiriman ke bank.
cek_status, cek_berikutJumlah konfirmasi yang sudah dilakukan dan jadwal berikutnya. cek_berikut kosong pada transaksi PENDING = menunggu cek manual.
tgl, tgl_kirim, tgl_selesaiDiterima pertama kali, pengiriman terakhir ke bank, dan saat mencapai status akhir.
userid, ipSiapa 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.

Data nasabah di log disamarkan

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).

BagianIsi
bankTiap bank: keadaan koneksi dan token, waktu jawaban terakhir, waktu galat koneksi terakhir, ringkasan panggilan.
layananPer bank dan layanan: total, sukses, galat, timeout, tidak_dijawab, tingkat_galat_persen, latensi_rata_ms, latensi_p95_ms, latensi_maks_ms.
transaksi_hari_iniJumlah dan nominal per bank dan status.
pendingjumlah, tertua, dan perlu_cek_manual.

Yang perlu diperhatikan operator setiap hari

  • pending.perlu_cek_manual lebih dari nol — ada transaksi yang tidak bisa dipastikan otomatis. Tanyakan ke bank dengan transaction_id dan external_id-nya.
  • pending.tertua sudah lama — periksa apakah bank itu sedang bermasalah.
  • tingkat_galat_persen atau timeout naik 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.

Hanya untuk lokal dan uji

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).

AkhiranPerilaku simulatorHasil di integrator
0404Rekening atau VA tidak ditemukanREJECTED
0403Rekening tidak aktifREJECTED
0500Galat 500, transaksi tidak tercatatPENDING → FAILED boleh diulang
0504Diproses, tetapi tidak dijawabPENDING → SUCCESS
0202202 diproses, lalu suksesPENDING → SUCCESS
0206202 diproses, lalu gagalPENDING → REJECTED
0200(VA) sudah dibayarpaid: true
lainnyaBerhasilSUCCESS

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.py

Uji 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.exe

Skrip membuat token sendiri dari JWT_SECRET di .env, jadi tidak butuh password.

Bab 13Menuju UAT dan produksi

Urutan kerja dari lokal ke lingkungan bank.

  1. Siapkan database Cadangkan database, lalu jalankan sql/migration.sql. Isinya hanya CREATE TABLE IF NOT EXISTS. Jangan memuat sql/seed.sql.
  2. Siapkan environment APP_ENV=production (atau uat), SIM_ENABLED=0, JWT_SECRET baru, IP_ALLOW berisi IP server Aplikasi Kliring, CORS_ORIGINS sesuai kebutuhan.
  3. 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.
  4. Daftarkan bank POST /intbank dengan base URL, client key, partner id, channel id, rekening, prefix VA, dan opsi dari bank. Isi rahasianya di .env, lalu restart.
  5. Pastikan koneksi jaringan IP server integrator didaftarkan di whitelist bank; sertifikat mTLS dipasang bila diminta; jam server tersinkron (bank menolak X-TIMESTAMP yang meleset).
  6. Uji bertahap POST /intbank/:id/ping → cek saldo → inquiry rekening → transfer bernominal kecil → cek status transfer itu. Periksa GET /log pada tiap langkah.
  7. Atur routing Buat aturan di /route atau wajibkan Aplikasi Kliring mengirim bank.

Yang perlu dikonfirmasi ke tiap bank

  • Path setiap endpoint yang bertanda ○ di Bab 10.
  • Bentuk dan panjang X-EXTERNAL-ID, dan bentuk X-TIMESTAMP.
  • Aturan idempotency bank: per partnerReferenceNo atau per X-EXTERNAL-ID, dan berapa lama berlaku.
  • Karakter yang diterima pada partnerReferenceNo — menentukan bentuk transaction_id yang aman dipakai Kliring.
  • Batas waktu jawaban transfer, untuk menyetel timeout_transfer_ms bank itu.
  • Kode jawaban yang tidak ada di daftar GET /ref/status.
Keadaan saat buku ini ditulis

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

PesanPenyebabTindakan
variabel wajib belum diisiDB_USER, DB_NAME, atau JWT_SECRET kosongLengkapi .env
JWT_SECRET terlalu pendekKurang dari 32 karakterPerpanjang
Konfigurasi bank gagal dimuatTabel integrator belum adaJalankan sql/migration.sql
SIM_ENABLED=1 tidak boleh dipakai dengan APP_ENV=productionSimulator hidup di produksiSIM_ENABLED=0
Server gagal berjalan … bindPort sudah dipakai, biasanya oleh proses service yang samaHentikan proses lama, atau ganti PORT

Permintaan ditolak integrator

GejalaPenyebabTindakan
401 Invalid or expired tokenToken habis, atau JWT_SECRET berbeda dengan penerbit tokenLogin ulang; samakan secret bila memakai token cmc-api2
403 peran user tidak diizinkanUser tipe V memanggil rute yang mengubahGunakan user tipe A
403 alamat IP tidak terdaftarIP pemanggil tidak ada di IP_ALLOWTambahkan IP; periksa proxy di depan service
400 bank … tidak terdaftar atau tidak aktifKode bank salah, atau bank dinonaktifkanPeriksa GET /intbank
400 bank tujuan belum ditentukanTanpa field bank dan tidak ada aturan routing yang cocokKirim bank, atau tambah aturan di /route
409 pada transfertransaction_id dipakai ulang dengan isi berbeda, atau transaksi masih berjalanBaca GET /trx/:transaction_id
422Validasi gagalBaca daftar di error

Masalah dengan bank

reason / gejalaPenyebab yang paling mungkinTindakan
BANK_NOT_CONFIGUREDBase URL, client key, atau rahasia belum diisi; message menyebut yang kurangLengkapi, lalu restart atau POST /intbank-reload
masalah berisi private key: …Berkas kunci tidak ada, tidak terbaca, atau bukan PEM RSAPeriksa path dan hak baca berkas
CONNECTION_FAILEDAlamat salah, firewall, IP belum di-whitelist bank, VPN matiUji jaringan dari server; POST /intbank/:id/ping
BANK_TOKEN_FAILEDClient key salah, public key belum terdaftar di bank, bentuk waktu ditolak, jam server melesetLihat 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 bankPeriksa client secret; periksa apakah base_url memuat awalan path
PENDING dengan HTTP_404Path endpoint tidak ada di bankIsi path_override dengan path dari dokumen bank
BTN menjawab 400 soal OriginOpsi origin kosong atau belum didaftarkanIsi opsi.origin
BSI menjawab 401 soal apiKeyBANK_BSI_API_KEY, opsi.user_id, atau partner_id salahCocokkan dengan data NCMS
Banyak TIMEOUTBank lambat, atau batas waktu terlalu pendekNaikkan timeout_transfer_ms bank itu; pantau /monitor
PENDING tidak pernah selesaiKonfirmasi otomatis sudah mencapai batas, atau bank tidak punya layanan cek statusPOST /trx/status; bila tetap, tanyakan bank dengan transaction_id dan external_id
SERVICE_NOT_SUPPORTEDBank itu tidak membuka layanan atau metode yang dimintaLihat Bab 10; pilih bank lain

Menelusuri satu transaksi

  1. GET /trx/<transaction_id> — lihat status, alasan, dan daftar panggilan.
  2. Ambil id panggilan yang bermasalah, buka GET /log/<id> — lihat apa yang dikirim dan apa jawaban bank.
  3. Saat menghubungi bank, sertakan transaction_id (di bank: partnerReferenceNo), external_id, waktu, dan bank_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 profilKapan diisi
TimeLayoutBank meminta milidetik pada X-TIMESTAMP (snap.LayoutMillis).
SignServiceLayanan ditandatangani RSA (SignRSA), bukan HMAC.
TokenWithoutCodeJawaban token tidak memuat responseCode.
ExternalIDDigitsBank membatasi panjang X-EXTERNAL-ID.
VAPadpartnerServiceId ditulis 8 karakter berpengisi spasi.
HeadersBank meminta header tambahan.
TransformBadan permintaan bank berbeda dari SNAP baku.
NormalizeJawaban bank berbeda dari SNAP baku.
Jangan membuka transfer tanpa cek status

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

  1. Tambahkan uji transformasi bank itu di internal/bank/bank_test.go.
  2. Build ulang dan deploy.
  3. Daftarkan koneksinya lewat POST /intbank, isi BANK_<ID>_*, lalu ping.

LampiranAcuan cepat

Daftar rute, tabel, dan susunan folder.

A. Daftar rute

Semua di bawah /api. Kolom "Peran" menyebut tipe user yang boleh.

MetodeRuteKegunaanPeran
GET/Health check sederhanaterbuka
GET/healthHealth check beserta database (dipakai pipeline deploy)terbuka
POST/loginLoginterbuka
GET/meProfil user yang loginA, V
POST/logoutMencatat logoutA, V
GET/adapterKatalog adaptor dan endpoint bankA, V
GET/intbank, /intbank/:idKonfigurasi dan keadaan bankA, V
POST · PUT · DELETE/intbank, /intbank/:idMengelola konfigurasi bankA
POST/intbank/:id/pingUji koneksi dan kredensialA
POST/intbank-reloadMuat ulang konfigurasi dan rahasiaA
GET/route, /route/:id, /route-ujiAturan routing dan uji routingA, V
POST · PUT · DELETE/route, /route/:idMengelola aturan routingA
POST/trx/balanceCek saldoA
POST/trx/account-inquiryInquiry rekening tujuanA
POST/trx/transferTransferA
POST/trx/statusKonfirmasi statusA
POST/trx/statementMutasi rekeningA
POST/trx/vaBuat virtual accountA
POST/trx/va-inquiryInquiry virtual accountA
GET/trx, /trx/:transaction_idDaftar dan rincian transaksiA, V
GET/log, /log/:idLog panggilan ke bankA, V
GET/monitorMonitoringA, V
GET/ref/statusAcuan status dan kode responsA, 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

TabelIsi
r_integrator_bankKonfigurasi koneksi tiap bank (tanpa rahasia).
r_integrator_routeAturan routing.
t_integrator_trxTransfer dan pembuatan VA. transaction_id unik.
t_integrator_logSetiap 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 ini

D. Port service di lingkungan KBI

PortService
2026cmc-api2 — Aplikasi Kliring
2027api-pub — API publik
2028 · 2029api-bank
2034api-integrator — Bank Integrator