Lewati ke konten utama

Integrasi Eksternal

Lima sistem luar yang terhubung ke CRM RSI.

IntegrasiArahAutentikasiKritis?
Jasnita ChatPaneldua arahOAuth2 password grant✅ Ya — tanpa ini tidak ada percakapan
Duitkudua arahSignature SHA-256 (keluar) + MD5 (masuk)✅ Ya — menyangkut uang
Penyedia LLMkeluarAPI key per AI Agent⚠️ Auto-reply mati kalau bermasalah
SIMRSmasuk (baca)Kredensial MySQL⚠️ Data klinis tidak diperbarui
API Inimediakeluarclient_id + client_secret❌ Pelengkap lookup pasien

1. Jasnita ChatPanel (Toschat)

Base URL: disimpan per akun di kolom gateway_base_url (produksi: https://cpapi.jasnita.co.id) Dokumentasi vendor: koleksi Postman Toschat

Autentikasi

Empat kredensial wajib — permintaan token melempar RuntimeException bernama kalau ada yang kosong: gateway_client_id, gateway_client_secret, gateway_username, gateway_password.

Konfigurasi per akun

KolomFungsi
gateway_providerHarus jasnita agar driver Toschat dipakai
gateway_base_urlBase URL API
gateway_client_id / gateway_client_secretKredensial OAuth (secret terenkripsi)
gateway_username / gateway_passwordKredensial OAuth (password terenkripsi)
gateway_channelChannel; default whatsapp_cloud
gateway_account_idID pengirim; hanya perlu bila satu channel punya >1 pengirim
webhook_verify_tokenToken yang ditempel di URL webhook

Pendaftaran webhook

Tombol "Daftarkan Webhook" di resource WhatsApp Business memanggil POST /api/v1/webhook/update dengan URL:

{APP_URL}/api/webhooks/whatsapp/{id_akun}?token={verify_token}
Dua jebakan pendaftaran webhook
  1. APP_URL dipakai eksplisit, bukan url(). Kalau admin dibuka lewat 127.0.0.1:8000, Laravel akan mengganti host jadi localhost dan mengabaikan tunnel di APP_URL — sehingga alamat yang didaftarkan tidak publik.
  2. channel ikut dikirim sesuai channel akun. Meng-hardcode 'whatsapp' membuat webhook terdaftar di channel lain dan pesan Cloud tidak pernah masuk CRM.

Batasan yang wajib diingat

BatasanKonsekuensi
Jendela 24 jam WhatsAppPesan bebas hanya boleh dikirim kalau pelanggan mengirim pesan dalam 24 jam terakhir. Di luar itu Meta membuang pesan sementara Toschat tetap menjawab "pending" — sistem tidak bisa mendeteksinya
Tidak ada API baca threadRiwayat percakapan internal (whatsapp_messages) adalah milik kami sendiri; thread lama tidak bisa di-backfill
Media butuh Bearer tokenKarena itu ada proksi /admin/chat/media
Endpoint ChatPanel tidak terdokumentasi publikchatpanel/* dan GET /api/v1/contact dipakai ChatPanel sendiri; bisa berubah sewaktu-waktu tanpa pemberitahuan

Daftar lengkap endpoint ada di Chat Rooms.


2. Duitku

Base URL: https://api-sandbox.duitku.com atau https://api-prod.duitku.com (dipilih DUITKU_ENV)

Payload createInvoice

FieldNilai
merchantOrderIdRESV-{payment_id}
paymentAmountTarif reservasi (integer)
productDetails"Reservasi Booking"
emailEmail pasien, fallback noreply@crmrsi.balascepat.com
phoneNumberNomor WhatsApp pasien
customerVaNameNama lengkap pasien
callbackUrl / returnUrlDari config
expiryPeriodDUITKU_EXPIRY_MINUTES (default 60)
customerDetail, itemDetailsTurunan dari nilai di atas

Invoice dianggap gagal kalau HTTP tidak sukses atau statusCode !== "00"DuitkuException.

Yang harus didaftarkan di dashboard Duitku

Callback URL: https://crmrsi.balascepat.com/webhook/duitku

Jangan pernah membalas non-200 ke Duitku

Duitku mengulang callback sampai menerima 200. Non-200 berarti callback diulang tanpa henti untuk pembayaran yang sebenarnya sudah selesai. Semua kegagalan di jalur ini ditelan dan dilog, bukan dilempar.

Detail lengkap di Booking & Pembayaran.


3. Penyedia LLM

API key disimpan per AI Agent (terenkripsi), bukan global. Artinya beberapa agent bisa memakai provider/model berbeda.

Kenapa Gemini default ke 2.5-flash-lite

Lebih ringan dan sering punya kuota berbeda dari gemini-2.0-flash — banyak akun kena HTTP 429 atau limit 0 di 2.0.

Yang dikirim ke penyedia LLM

DikirimTidak dikirim
Prompt sistem (identitas, gaya, panduan)Data pasien lain
Knowledge base (teks manual + ekstraksi berkas)Model WRITE (keluhan/survei orang lain)
Dump record Dokter/Poliklinik/PaketModel sensitif: User, Pasien, Kontak, Pengaturan, Follow-up
15 giliran percakapan terakhir nomor iniAPI key mana pun (llm_api_key dikecualikan)
Skema tool yang aktifpassword, remember_token

Fitur pendukung

FiturKeterangan
Uji koneksiLlmConnectionProbeService memeriksa kredensial; hasilnya disimpan di llm_last_probe_snapshot
Snapshot pemakaianllm_last_usage_snapshot diisi setiap balasan
Simulator chatMenguji agent tanpa WhatsApp — tool berjalan dalam mode dryRun (tidak menyentuh Duitku maupun database)
Pencatatan tokenSatu baris ai_token_usages per balasan
Token PricesTarif per model untuk menghitung biaya pemakaian

4. SIMRS (dev_simrs_b)

MySQL eksternal, hanya dibaca. Koneksi simrs dengan strict = false (karena data lama tidak selalu memenuhi mode ketat MySQL).

EnvDefault
SIMRS_DB_HOST127.0.0.1
SIMRS_DB_PORT3306
SIMRS_DB_DATABASEdev_simrs_b
SIMRS_DB_USERNAME / SIMRS_DB_PASSWORDkosong

Tabel yang dibaca: b_ms_unit, b_ms_pegawai, b_ms_pasien, b_kunjungan, b_pelayanan, b_tindakan.

Detail pemetaan di SIMRS Sync.


5. API Inimedia

Layanan pencarian pasien tambahan (PasienClient + PasienApiLookup). Dipakai untuk melengkapi lookup pasien di UI dengan daftar dari API eksternal (id, no_rm, nama), di-cache per request.

EnvDefault
INIMEDIA_API_BASE_URLhttp://139.255.23.90/api_inimedia
INIMEDIA_CLIENT_ID / INIMEDIA_CLIENT_SECRET

Kegagalan API disimpan sebagai lastFetchError dan ditampilkan di UI, tidak menjatuhkan halaman.


Ringkasan ketahanan tiap integrasi