Customer Acquisition — Dokumentasi Teknis
KYC Data Submission

Integrasi Pengiriman Data Nasabah ke Pihak Luar

Dokumen ini menjelaskan cara data KYC nasabah dikirimkan secara otomatis ke sistem eksternal (core banking, sistem penjamin, atau partner) setelah pengajuan disetujui oleh approver berwenang.

Trigger: Status APPROVED
Protocol: HTTP POST / JSON
Auth: Bearer Token + X-Api-Key
Retry: Manual via API
1

Mekanisme Pengiriman

Trigger
Status = APPROVED
Approver
BM / AM / RM / BOD
Protocol
HTTP POST (JSON)
Mode
Fire & Forget
Log
tabel kyc_submissions
Timeout Default
15 detik

Ketika approver menekan Setuju dan status pengajuan berubah menjadi APPROVED, sistem secara otomatis memanggil submitKycToExternal() sebagai fire-and-forget — artinya kegagalan pengiriman tidak membatalkan proses approval.

Request yang dikirim ke endpoint luar

HTTP Request
POST <kyc_endpoint>
Content-Type:  application/json
Authorization: Bearer <kyc_api_key>
X-Api-Key:     <kyc_api_key>
X-Source:      customer-acquisition
X-App-No:      CA-2026-00042

{ ...full KYC payload... }
2

Konfigurasi

Semua konfigurasi disimpan di tabel admin_settings dengan category = 'kyc_submission'. Ini memungkinkan perubahan endpoint/key tanpa deploy ulang.

setting_keyContoh NilaiKeterangan
kyc_enabledtrueAktifkan/matikan pengiriman KYC
kyc_endpointhttps://api.partner.id/kyc/receiveURL endpoint sistem penerima
kyc_api_keysk_live_xxxxxAPI Key / Bearer Token untuk autentikasi
kyc_timeout_ms15000Timeout HTTP request dalam milidetik
kyc_include_doc_urlstrueSertakan URL file dokumen dalam payload
ℹ️
Jika endpoint belum dikonfigurasi

Pengajuan tetap disetujui. KYC submission dicatat dengan status PENDING dan bisa dikirim ulang manual via POST /api/kyc/:id/retry setelah konfigurasi diisi.

3

Format Payload KYC

Berikut adalah struktur JSON lengkap yang dikirimkan ke sistem luar. Semua nilai numerik sudah dikonversi ke tipe number (bukan Decimal string).

Struktur Top-Level

KeyTipeKeterangan
metaObjectInformasi sumber, nomor pengajuan, cabang, produk
applicationObjectJumlah pinjaman, tenor, tujuan, metode pencairan, credit score
personalDataObjectData diri nasabah (nama, NIK, TTL, status pernikahan, dll)
contactDataArrayNomor telepon + kontak darurat
addressDataArrayAlamat tinggal, usaha, dan permanen + koordinat GPS
businessDataObjectSektor usaha, deskripsi, lama usaha, jumlah karyawan
spouseDataObject|nullData pasangan (jika menikah)
financialDataObjectRingkasan cashflow MFO + net income CA/TL
creditHistoryObject|nullHasil SLIK OJK (KOL 1–5, total outstanding)
riskProfileObject|nullAnalisis 5C oleh MFO (Watak, Kemampuan, Modal, Kondisi, Collateral)
collateralsArrayDaftar agunan beserta estimasi nilai
declarationObject|nullPersetujuan SLIK dan pihak ketiga
documentsArrayDaftar dokumen + URL akses file

Contoh Payload Lengkap

JSON
{
  "meta": {
    "sourceSystem": "customer-acquisition",
    "applicationNo": "CA-2026-00042",
    "trackingCode":  "TRK-ABCD1234",
    "submittedAt":   "2026-04-02T07:00:00.000Z",
    "branch":  { "id": 1, "name": "Cabang Jakarta Pusat", "code": "JKT-01" },
    "product": { "id": 2, "name": "Kredit Mikro",        "code": "KM-01"  }
  },
  "application": {
    "requestAmount":      5000000,
    "tenor":              52,
    "purpose":            "Modal usaha warung makan",
    "disbursementMethod": "bank_transfer",
    "weeklyInstallment":  120000,
    "creditScore":        78.5,
    "creditGrade":        "B"
  },
  "personalData": {
    "fullName":           "Budi Santoso",
    "nik":               "3271010101900001",
    "gender":            "L",
    "placeOfBirth":      "Jakarta",
    "dateOfBirth":       "1990-01-01T00:00:00.000Z",
    "mothersName":       "Siti Rahayu",
    "maritalStatus":     "married",
    "lastEducation":     "SMA",
    "numberOfDependents": 2
  },
  "contactData": [
    {
      "contactType":           "MN",
      "contactNumber":         "081234567890",
      "contactName":           "Budi Santoso",
      "isEmergency":           false,
      "emergencyRelationship": null
    },
    {
      "contactType":           "MN",
      "contactNumber":         "081298765432",
      "contactName":           "Siti Rahayu",
      "isEmergency":           true,
      "emergencyRelationship": "parent"
    }
  ],
  "addressData": [
    {
      "addressType":       "RESIDENTIAL",
      "address":           "Jl. Merdeka No. 10, RT 01/RW 02",
      "area":             "Gambir, Jakarta Pusat",
      "lengthOfStay":     60,
      "statusOfResidence": "own",
      "gps":             { "lat": -6.1754, "lng": 106.8272 }
    }
  ],
  "businessData": {
    "sector":         "Perdagangan",
    "subSector":      "Makanan & Minuman",
    "businessDesc":   "Warung makan nasi padang",
    "businessLength": 48,
    "totalManPower":  2
  },
  "financialData": {
    "cashflow": {
      "revenuePerMonth":   12000000,
      "grossOtherIncome": 12500000
    },
    "netIncome": {
      "netIncomePerMonth":     4500000,
      "maxMonthlyInstallment": 800000
    }
  },
  "creditHistory": {
    "slikStatus":      "CLEAN",
    "totalOutstanding": 0,
    "kol1Count": 0, "kol2Count": 0, "kol3Count": 0
  },
  "riskProfile": {
    "riskLevel":         "RENDAH",
    "mfoRecommendation":  "RECOMMENDED",
    "watakGrade":        "good",
    "kemampuanGrade":    "good",
    "hasCollateral":     false
  },
  "declaration": {
    "slikConsent":       "SETUJU",
    "thirdPartyConsent": true,
    "agreed":            true
  },
  "documents": [
    {
      "docType":    "CUSTOMER_KTP",
      "fileName":  "ktp_budi.jpg",
      "mimeType":  "image/jpeg",
      "url":       "https://yourdomain.com/uploads/documents/ktp_budi.jpg",
      "gps":       null,
      "uploadedAt": "2026-03-20T08:30:00.000Z"
    }
  ]
}
4

Tipe Dokumen — docType

NilaiKeterangan
CUSTOMER_KTPFoto KTP nasabah
CUSTOMER_PHOTOFoto selfie / pas foto nasabah
CUSTOMER_SIGNATURETanda tangan nasabah (digital)
SPOUSE_KTPFoto KTP pasangan
FAMILY_CARDKartu Keluarga (KK)
HOUSE_PHOTOFoto tempat tinggal
BUSINESS_PHOTOFoto lokasi usaha
COLLATERAL_PHOTOFoto agunan / jaminan
OTHERDokumen pendukung lainnya
5

API Internal — Manajemen KYC

Base URL: http://localhost:5000/api/kyc
Semua endpoint memerlukan header Authorization: Bearer <jwt_token>

GET /api/kyc List semua KYC submission

Roles Diizinkan

ADMIN AM RM BOD

Query Parameters

page integer Nomor halaman (default: 1)
limit integer Jumlah per halaman (default: 20)
status string Filter status: PENDING | SENT | ACKNOWLEDGED | FAILED | RETRYING

Response

200 OK
{
  "success": true,
  "data": [{
    "id": 1,
    "customerId": 42,
    "status": "SENT",
    "externalRefId": "EXT-KYC-20260402-042",
    "approvedBy": "BM",
    "approvedAt": "2026-04-02T07:00:00.000Z",
    "sentAt":    "2026-04-02T07:00:02.000Z",
    "ackAt":     null,
    "retryCount": 0,
    "lastError":  null,
    "customer": {
      "applicationNo": "CA-2026-00042",
      "personalDetails": { "fullName": "Budi Santoso", "nik": "32710..." },
      "branch": { "name": "Cabang Jakarta Pusat" }
    }
  }],
  "pagination": { "page": 1, "limit": 20, "total": 1 }
}
GET /api/kyc/:customerId/status Status submission per customer

Roles Diizinkan

ADMIN BM AM RM BOD

Path Parameter

customerId integer ID customer dari tabel customers
ℹ️

Mengembalikan 404 jika pengajuan belum pernah disetujui atau record submission belum ada.

GET /api/kyc/:customerId/payload Preview payload KYC (tanpa kirim)

Roles Diizinkan

ADMIN

Mengembalikan payload JSON lengkap persis seperti yang akan dikirim ke sistem luar. Berguna untuk debugging dan validasi data sebelum pengiriman.

POST /api/kyc/:customerId/retry Kirim ulang submission yang gagal

Roles Diizinkan

ADMIN
⚠️
Hanya untuk status FAILED atau PENDING

Jika status sudah SENT atau ACKNOWLEDGED, endpoint ini akan mengembalikan error 400.

Response Sukses

200 OK
{ "success": true, "message": "KYC retry berhasil dimulai" }
POST /api/kyc/:customerId/ack Catat acknowledgment dari sistem luar

Roles Diizinkan

ADMIN

Request Body

JSON
{ "externalRefId": "EXT-KYC-20260402-042" }

Status akan berubah SENTACKNOWLEDGED dan field ackAt diisi dengan timestamp saat ini.

6

Status KYC Submission

StatusKeteranganAksi Selanjutnya
PENDING Endpoint belum dikonfigurasi saat approval, atau baru di-trigger Konfigurasi endpoint, lalu retry manual
SENT HTTP POST berhasil (2xx), menunggu konfirmasi dari sistem luar Tunggu ACK, atau panggil /ack manual
ACKNOWLEDGED Sistem luar mengonfirmasi penerimaan data ✓ Selesai
FAILED HTTP error, timeout, atau network error Cek lastError, perbaiki, lalu retry
RETRYING Sedang dalam proses retry manual Tunggu hasil (akan berubah ke SENT atau FAILED)
7

Alur Lengkap

MFO mengisi data nasabah
Data pribadi, kontak, alamat, usaha, cashflow, dokumen
Proses Review Berjenjang
CSA Review → SLIK Check → CA/TL Review → BM Review
BM menekan Setuju
Sistem memeriksa: apakah requestAmount ≤ approvalLimit BM?
✅ Ya — dalam limit
Status → APPROVED
KYC dikirim otomatis
↑ Melebihi limit
Eskalasi ke AM → RM → BOD
KYC dikirim setelah approval final
submitKycToExternal() dipanggil
Fire-and-forget — kegagalan tidak membatalkan approval
HTTP POST ke endpoint eksternal
Payload JSON lengkap dikirim dengan Bearer Token + X-Api-Key
HTTP 2xx
Status → SENT
externalRefId disimpan
Error / Timeout
Status → FAILED
lastError dicatat
Acknowledged
Sistem luar konfirmasi via POST /api/kyc/:id/ack → status ACKNOWLEDGED
8

Setup Database

Jalankan SQL berikut untuk mengaktifkan pengiriman KYC ke endpoint tertentu:

SQL
INSERT INTO admin_settings
  (category, setting_key, setting_value, description)
VALUES
  ('kyc_submission', 'kyc_enabled',          'true',
   'Aktifkan pengiriman KYC'),

  ('kyc_submission', 'kyc_endpoint',         'https://api.partner.id/kyc/receive',
   'URL endpoint sistem luar'),

  ('kyc_submission', 'kyc_api_key',          'sk_live_XXXXXXXXXXXX',
   'API Key / Bearer Token'),

  ('kyc_submission', 'kyc_timeout_ms',       '15000',
   'Timeout request dalam ms'),

  ('kyc_submission', 'kyc_include_doc_urls', 'true',
   'Sertakan URL dokumen dalam payload');
9

Data Sensitif & Keamanan

ItemPerlindungan
NIK, foto KTP, tanda tangan Pastikan endpoint tujuan menggunakan HTTPS. Data hanya dikirim ke endpoint yang terdaftar.
API Key Disimpan di tabel admin_settings (database), tidak di-hardcode di source code atau environment file.
Log respons Disimpan di kyc_submissions.response_payload, dipotong maksimal 65KB untuk menghindari kebocoran data berlebih.
Kegagalan pengiriman Tidak membatalkan proses approval. Error dicatat dan dapat di-retry tanpa mempengaruhi alur bisnis.
Akses API Internal Endpoint /api/kyc/* memerlukan JWT yang valid + role check. Preview payload hanya ADMIN.
✓ Disalin!