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​