Webhook listener
Setiap pergerakan barang di Accurate, penjualan maupun penerimaan, dikirim ke endpoint sistem klinik. Listener memproses event berurutan dan langsung memperbarui stok produk terkait.
Otomatis, tanpa sentuhan manusia
INCOVE KOSMESIA 2026Innovation Convention, kategori Suggestion System
Otomatisasi Sinkronisasi Stok Apotek Sistem Klinik dengan Accurate melalui Integrasi Webhook API
Tidak sinkron, FO tidak bisa transaksi
Klik langkah mana pun untuk langsung menuju ke sana.
Langkah 1 dari 12
Semua data stok farmasi dikelola di Accurate. Sistem klinik punya basis data stok sendiri yang tidak terhubung.
Penerimaan barang sudah dicatat lengkap di Accurate, tetapi apotek tetap harus memasukkannya lagi ke sistem klinik secara manual, dan nilainya hanya data sementara yang tidak mencerminkan penerimaan riil.
Masalah yang dihadapi Stok di sistem klinik tidak sinkron dengan Accurate dan tidak sesuai fisik: kadang 0 padahal barang ada, kadang tercatat ada padahal barang habis. Akibatnya transaksi Front Office terhambat, pasien yang sudah membayar bisa tidak mendapat produknya, dan apotek mengerjakan input ganda.
Selaras dengan prioritas perusahaan: kecepatan layanan pasien di FO dan akurasi persediaan sebagai dasar keputusan pengadaan.
Langkah 2 dari 12
tb_stock_produk sendiri tanpa kanal penghubung.Pembayaran_akun → update_keluar), naik saat apoteker mengisi form Terima Produk.CR031 (booster + tube) stoknya mengikuti bahan acuan atau kode varian berakhiran "A".Langkah 3 dari 12
Langkah 3 dari 12
Jam kerja yang hilang per cabang. Klinik buka setiap hari 08.00–20.00 (30 hari/bulan). Rumus: kali × menit × 30 hari (rekonsiliasi: sekali per bulan) ÷ 60. Frekuensi input penerimaan dari data sistem (slide berikutnya); angka lain rata-rata hasil pengamatan langsung di klinik. Waktu dihitung per proses.
| Komponen | Rata-rata | Jam / bulan | Dasar angka |
|---|---|---|---|
| Input penerimaan manualApoteker mengetik ulang barang yang sudah diterima di Accurate ke form Terima Produk. | 5× / hari × 3 menit |
7,5 | Data sistem & simulasiFrekuensi: rata-rata item yang diinput manual per hari ada input (form Terima Produk & Penyesuaian Stok), 1 Jan–31 Mei 2026 (database production, slide bukti data). Durasi 3 menit per item: pengamatan & simulasi input. |
| FO tertahan karena stok 0Pembayaran pasien terhenti karena stok di sistem 0. FO menelepon atau mendatangi apotek, apoteker cek fisik lalu input, kemudian konfirmasi ke FO dan transaksi diulang. | 3× / hari × 5 menit |
7,5 | Pengamatan langsungRata-rata hasil pengamatan di FO dan apotek. |
| Rekonsiliasi dua sistemSaat stock opname awal bulan, apoteker mencocokkan stok sistem klinik dengan Accurate dan fisik, lalu mengoreksi selisihnya. | 1× / bulan × 75 menit |
1,3 | Pengamatan langsungRata-rata lama rekonsiliasi saat stock opname awal bulan. |
| Total per cabang | 16,3 | × 7 cabang = 113,8 jam per bulan |
Langkah 3 dari 12
Database production clinic_prod, 1 Jan – 31 Mei 2026 (151 hari), diambil 15 Okt 2026. Input manual dihitung dari form Terima Produk dan menu Penyesuaian Stok (terakhir dipakai 24 Jun 2025). Lampung tidak dihitung karena baru buka Agustus 2026.
| Cabang | Item diinput per bulanJan–Mei 2026 | Item diinputbaris barang | Penyesuaian stokkali | Hari ada inputdari 151 hari | Item / hariper hari ada input |
|---|---|---|---|---|---|
| Malang | 782 | 0 | 137 | 6 | |
| Surabaya | 634 | 0 | 141 | 4 | |
| Bandung | 580 | 0 | 110 | 5 | |
| Sidoarjo | 432 | 0 | 94 | 5 | |
| Depok | 302 | 0 | 81 | 4 | |
| Bekasi | 169 | 0 | 40 | 4 | |
| Jakarta Selatan | 0 | 0 | 0 | – | |
| Rata-rata per cabang | 414 | 0 | 86 | 5 |
Dalam 5 bulan, apoteker 7 cabang memasukkan 2.899 item secara manual, padahal penerimaan barang sudah tercatat di Accurate. Angka 5 item per hari (4,8, dibulatkan) dipakai di rincian jam dan kalkulator NQI.
Langkah 4 dari 12
Ide ini berawal dari observasi langsung di Klinik Malang untuk melihat penggunaan sistem dalam pelayanan sehari-hari.
Mengamati alur pasien dari pendaftaran hingga pembayaran.
Mengamati penggunaan sistem di nurse station.
Mengamati tugas apoteker. Penerimaan barang yang sudah tercatat di Accurate diinput ulang, sementara FO datang langsung maupun menelepon untuk menanyakan stok yang di sistem tercatat 0. Agar tidak input berulang, stok kadang dicatat melebihi fisik, sehingga barang yang sudah dibayar pasien ternyata tidak ada saat diambil.
Ide perbaikan Cukup dicatat sekali di Accurate, stok di sistem klinik langsung ikut terbarui. Tanpa input ulang, tanpa FO harus bertanya ke apotek, tanpa stok yang dilebihkan.
Langkah 5 dari 12
Integrasi otomatis sistem klinik dengan Accurate API, sehingga stok klinik selalu mengikuti pergerakan terkini di Accurate tanpa input manual.
Setiap pergerakan barang di Accurate, penjualan maupun penerimaan, dikirim ke endpoint sistem klinik. Listener memproses event berurutan dan langsung memperbarui stok produk terkait.
Otomatis, tanpa sentuhan manusia
Menyamakan seluruh produk cabang sekaligus lewat antrian. Untuk awal hari atau rekonsiliasi menyeluruh.
Sinkronisasi satu item tanpa memuat ulang semua data.
Melihat stok real-time di Accurate, termasuk komponen produk grup, untuk validasi di tempat.
Ruang lingkup. Arah Accurate → sistem klinik berjalan real-time. Arah sistem klinik → Accurate tetap batch malam hari sesuai SOP accounting; itu ketentuan proses bisnis, bukan bagian masalah ini.
Langkah 6 dari 12
| Indikator | Sebelum | Target | Realisasi |
|---|---|---|---|
| Input ganda penerimaan barang | 5 item / hari / cabang | 0 | Penerimaan cukup dicatat di Accurate; stok klinik ter-update otomatis |
| Jeda stok klinik terhadap Accurate | Tidak pernah sama | Real-time | Mengikuti event webhook, diproses antrian tiap menit |
| FO menunggu update dari apotek | Setiap stok belum diinput | Tidak perlu menunggu | Stok sudah terisi saat barang diterima di Accurate |
| Barang sudah dibayar, tidak ada saat diambil | Terjadi saat stok dilebihkan | Tidak terjadi | Stok tidak lagi diisi manual; disamakan dengan Accurate |
| Waktu kerja terbuang | ±16 jam / bulan / cabang | Tereliminasi | Input & komunikasi stok tidak lagi diperlukan |
| Penilaian pengguna | - | Input ganda berkurang | 3 dari 3 apoteker: "Ya, signifikan" |
Single source of truth: angka stok yang dilihat apoteker, FO, dan accounting berasal dari satu sumber, yaitu Accurate.
Langkah 7 dari 12
item/detail.do, format event webhook ITEM_QUANTITY.Seluruhnya memakai server, lisensi Accurate, dan stack yang sudah ada. Tidak ada pembelian baru; dikerjakan in-house oleh tim IT.
Integrasi webhook, pemrosesan antrian asinkron, dan autentikasi API bertanda tangan, yang kini bisa dipakai ulang untuk integrasi Accurate berikutnya.
Langkah 8 dari 12
Dari observasi sampai perbaikan berkelanjutan, berdasarkan riwayat commit clinic-app dan clinic-api.
10–22 Juni 2026
Helper cek item Accurate lintas cabang & tombol "Cek Accurate".
Stok klinik 0 padahal barang ada; input ulang; FO tertahan.
API detail item, grup, sync stok. Perpanjang webhook setiap hari 00.01 WIB, perbarui host 00.10 WIB.
Antrian sync & auto-dispatch dari webhook, diuji ulang sebelum rilis.
23–29 Juni 2026
Sync semua, sync per produk, cek langsung API. Auto-sync aktif.
Status naik/turun, sebelum → sesudah, sumber Auto/Manual/Batch.
Surabaya, Sidoarjo, Bekasi memberi penilaian & masukan.
Dipakai harian oleh apotek dan FO.
Juli–Oktober 2026
Produk grup yang lolos sync kini tercakup lewat bahan acuan.
Samakan / kurangi keluar hari ini, Stok Accurate, label "Tidak ada di Accurate".
Simpan di Master Product langsung mengambil stok tiap cabang.
Titik penting: observasi, usulan, rilis production, laporan penerapan.
Langkah 8 dari 12
Konsol simulasi. Data contoh dari produk OTB1 di Lampiran 3.
Waktu webhook diukur dari Lampiran 1 (event Accurate 15:00:43, tersimpan 15:00:44). Waktu antrian dan respons API masih estimasi.
Sumber data stok utama. Setiap kali kuantitas barang berubah, Accurate mengirim event ITEM_QUANTITY berisi databaseId, timestamp, dan daftar itemNo + quantity.
Setiap hari pukul 00.01 WIB scheduler memperpanjang langganan webhook, dan pukul 00.10 WIB memperbarui host database, sehingga koneksi tidak putus diam-diam.
Endpoint ringan: memetakan databaseId ke cabang, menyimpan event, lalu menyerahkan pekerjaan berat ke antrian. Accurate langsung mendapat respons 200.
foreach ($webhookData as $entry) {
if ($entry['type'] == 'ITEM_QUANTITY') {
$toko_id = AkunAccurate::where('database_id', $databaseId)
->first()->id;
foreach ($entry['data'] as $data) {
AccurateItemQuantity::create([...]);
SyncProdukStokJob::dispatch($toko_id, $data['itemNo'], 'auto');
}
}
}
Setiap event tersimpan di accurate_item_quantity: cabang, kode item, kuantitas, dan waktu dari Accurate. Ini jejak audit sekaligus sumber kolom "Stok Accurate" di Produk Monitor.
Job berjalan di Laravel Queue (driver database). Worker dijalankan scheduler tiap menit. Gagal? Dicoba ulang sampai 3 kali dengan batas 30 detik per percobaan.
Jika item adalah bahan acuan sebuah produk grup, job untuk grup itu ikut dikirim, karena grup tidak pernah mendapat event sendiri.
public int $tries = 3;
public int $timeout = 30;
foreach (AccurateHelper::grupBahanAcuan() as $grup => $bahan) {
if ($bahan === $data['itemNo']) {
SyncProdukStokJob::dispatch($toko_id, $grup, 'auto');
}
}
Job tidak percaya begitu saja pada angka di event. Ia bertanya ulang ke item/detail.do dengan header bertanda tangan HMAC-SHA256, lalu memakai availableToSell.
if (!empty($d['detailGroup'])) {
$kodeStok = $bahanAcuan[$kode] ?? ($kode . 'A');
$d = itemDetailByBranch($tokoId, $kodeStok)['d'];
}
$stok = (int) ($d['availableToSell']
?? $d['balance'] ?? $d['quantity'] ?? 0);
Semua baris produk dengan kode Accurate yang sama diperbarui. Setiap perubahan menyimpan rincian di accurate_sync_info:
{
"stok_accurate": 18, "mode": "samakan",
"jumlah_sebelum": 19, "jumlah_sesudah": 18,
"selisih": -1, "update_from": "auto",
"synced_at": "2026-06-24 13:19:38"
}
Stok sistem dan stok Accurate berdampingan, ditambah barang keluar hari ini, tipe item, waktu sync, dan sumbernya (Auto, Manual, Batch). Tiga aksi per produk: sync, cek di Accurate, dan riwayat 30 hari. FO cukup bertransaksi: angkanya sudah benar.
| Kode | Nama produk | Stok sistem | Stok Accurate | Keluar hari ini | Tipe | Sync terakhir | Sumber | Aksi |
|---|---|---|---|---|---|---|---|---|
| CR031 | ACNE BLEMISH BOOSTER | 21 | 23 | 2 | Grup | 2026-10-14 13:05:40 | Manual | ⟳⌕⏱ |
| OTB1 | ACNE BREAKOUT CREAM 1 | 18 | 18 | 0 | Persediaan | 2026-10-14 11:42:05 | Auto | ⟳⌕⏱ |
| KLT002 | ACNE FC WASH | 44 | 44 | 0 | Persediaan | 2026-10-14 10:15:29 | Auto | ⟳⌕⏱ |
| PRAB5 | ACNE BREAKOUT 5 | 0 | — | 0 | — | Tidak ada di Accurate | — | ⟳⌕⏱ |
Langkah 8 dari 12
| Komponen | Sebelum | Sesudah |
|---|---|---|
| Stok bertambah | Apoteker mengisi form Terima Produk | Event webhook → SyncProdukStokJob menyamakan dengan Accurate |
| Stok berkurang | Saat pembayaran lunas (update_keluar) | Tetap dipertahankan, lalu dikoreksi oleh angka Accurate |
Tabel tb_stock_produk | Hanya jumlah | + accurate_sync_at, accurate_sync_info (JSON: sebelum, sesudah, selisih, mode, sumber) |
| Tabel baru | - | accurate_item_quantity (log event), jobs (antrian) |
| Produk grup / paket | Tidak dikenali | Deteksi detailGroup, stok dari kode + "A" atau peta 10 bahan acuan |
| Kode Accurate ganda | - | Semua baris dengan kode sama ikut diperbarui |
| Kode tidak terdaftar | Diam, tampak seperti gagal | Label "Tidak ada di Accurate", stok tidak disentuh |
| Produk baru di Master Product | Stok mulai dari 0 | Langsung ambil stok tiap cabang, paralel dengan curl_multi |
| Koneksi Accurate | - | Token + HMAC-SHA256; perpanjang webhook setiap hari 00.01 WIB, perbarui host 00.10 WIB |
Langkah 8 dari 12
Penjualan klinik baru dikirim ke Accurate malam hari. Sepanjang jam buka, stok Accurate belum dikurangi penjualan klinik hari itu.
Karena itu sync manual meminta apoteker memilih:
jumlah = stok Accurate. Tepat setelah closing dan batch terkirim.jumlah = stok Accurate − terjual hari ini. Terjual = baris penjualan dari pembayaran lunas bertanggal hari ini, titik yang sama tempat sistem lama mengurangi stok.Langkah 8 dari 12
Standar kerja baru: penerimaan barang cukup dicatat di Accurate. Produk Monitor dipakai untuk verifikasi dan rekonsiliasi, bukan untuk input.
Langkah 9 dari 12
Berjalan di production, dipakai harian oleh apotek dan FO di 8 cabang: MalangSurabayaBandungSidoarjoBekasiDepokJakarta SelatanLampung
| Kode | Nama produk | Stok sistem | Stok Accurate | Keluar hari ini | Tipe | Sync terakhir | Sumber | Aksi |
|---|---|---|---|---|---|---|---|---|
| CR031 | ACNE BLEMISH BOOSTER | 21 | 23 | 2 | Grup | 2026-10-14 13:05:40 | Manual | ⟳⌕⏱ |
| OTB1 | ACNE BREAKOUT CREAM 1 | 18 | 18 | 0 | Persediaan | 2026-10-14 11:42:05 | Auto | ⟳⌕⏱ |
| KLT002 | ACNE FC WASH | 44 | 44 | 0 | Persediaan | 2026-10-14 10:15:29 | Auto | ⟳⌕⏱ |
| PRAB5 | ACNE BREAKOUT 5 | 0 | — | 0 | — | Tidak ada di Accurate | — | ⟳⌕⏱ |
Screenshot rilis awal. Sejak Okt 2026 kedua dialog meminta memilih mode: samakan persis atau kurangi keluar hari ini.
Langkah 10 dari 12
5 input × 3 menit = 15 menit per hari per cabang hanya untuk input ulang. Bersama FO tertahan karena stok 0 dan rekonsiliasi: ±16 jam kerja per bulan per cabang (klinik buka 30 hari). Rinciannya ada di langkah 3.
Langkah 11 dari 12
Langkah 12 dari 12
INCOVE KOSMESIA 2026, Suggestion System
Terima kasih.
Muhammad Badruzzaman Ahdany
IT Head of Development, PT Kosmetika Klinik Indonesia