Cara Integrasi POS dengan E-commerce untuk Omnichannel yang Rapi
T
Kembali ke Blog

Cara Integrasi POS dengan E-commerce untuk Omnichannel yang Rapi

Tutorial
Tim Pilar Inovasi 07 Nov 2026 6 min baca 1,149 kata 0
Panduan praktis integrasi POS ke Shopee, Tokopedia, dan website: satu sumber stok, webhook idempotent, reservasi stok, dan pola retry yang aman untuk mencegah oversell.

Kalau Anda mengelola apotek, toko retail, atau restoran yang juga berjualan di Shopee, Tokopedia, dan website sendiri, kemungkinan besar Anda pernah mengalami ini: stok di kasir menunjukkan 3 unit, tetapi marketplace masih menerima pesanan ke-5 karena sinkronisasi terakhir berjalan 40 menit lalu. Pesanan dibatalkan, rating toko turun, dan tim gudang harus stock opname manual setiap malam. Omnichannel bukan sekadar punya banyak channel penjualan — intinya adalah satu data inventori, satu harga, dan satu riwayat pelanggan yang konsisten di semua titik sentuh. Artikel ini membahas cara membangun integrasi POS ke e-commerce secara konkret: arsitektur, mapping SKU, penanganan konflik stok, sampai pola retry yang aman, berdasarkan pengalaman implementasi POS retail, farmasi, dan restoran.

Arsitektur: Satu Sumber Kebenaran, Banyak Kanal

Langkah pertama bukan menulis kode, tapi memutuskan siapa pemilik data. Pilih satu sistem sebagai master untuk stok dan harga — umumnya POS atau ERP pusat, bukan marketplace. Marketplace hanya cermin. Skema paling aman: tabel product_variants di POS menyimpan stok on-hand, stok reserved (pesanan sudah diterima tapi belum dikirim), dan stok available = on-hand − reserved. Semua channel membaca angka available, bukan on-hand. Tanpa pemisahan ini, pesanan marketplace yang belum di-pick akan terus dihitung sebagai stok tersedia dan memicu oversell berulang di hari yang sama.

Kedua, jangan pernah memakai sinkronisasi sinkron. Panggilan API marketplace bisa memakan 800–2.000 ms; kalau kasir menunggu respons itu setiap kali transaksi, antrean di counter langsung menumpuk. Gunakan pola webhook masuk + message queue: webhook hanya memvalidasi tanda tangan dan melempar job ke Redis 7 + BullMQ 5 (atau RabbitMQ 3.13), lalu worker terpisah yang memproses tarik pesanan dan push stok. Efeknya, endpoint webhook bisa merespons di bawah 1 detik dan marketplace tidak menandai endpoint Anda sebagai lambat.

Ketiga, buat tabel mapping eksplisit: channel (shopee/tokopedia/woocommerce), channel_sku, variant_id, price_override, dan buffer_stock. Satu SKU POS sah dipetakan ke banyak channel sekaligus. Untuk produk fast-moving seperti obat bebas atau menu andalan, sisakan buffer 5–10% agar stok di channel online tidak pernah menyentuh nol bersamaan dengan transaksi walk-in. Mapping yang tidak lengkap adalah penyebab nomor satu stok tidak tersinkron, jadi validasi di awal: target 100% SKU aktif terpetakan sebelum go-live.

Langkah Implementasi dan Webhook yang Aman

Urutan implementasi yang terbukti: (1) mapping SKU dan validasi, (2) simpan kredensial per channel — Shopee Open Platform API v2 memakai partner_id, partner_key, dan shop_id; Tokopedia memakai Fulfillment API dengan client_id; WooCommerce memakai REST API v3 dengan consumer key/secret, (3) bangun endpoint webhook, (4) bangun worker, (5) jalankan reconciliation terjadwal. Jangan lompat ke langkah 3 sebelum mapping selesai — debugging data jauh lebih mahal daripada debugging kode.

Perhatikan batas laju. Shopee Open Platform membatasi jumlah request per shop per menit, sementara WooCommerce tidak punya rate limit bawaan tetapi akan tumbang di shared hosting kalau Anda mengirim 500 request paralel. Solusinya batching: kirim update stok 100 SKU per request, bukan satu request per item, dan batasi worker ke 5–10 konkurensi. Untuk katalog 3.000 SKU, batching memangkas waktu push dari sekitar 6 menit menjadi di bawah 30 detik.

app.post('/webhook/shopee/order', express.json(), async (req, res) => {
  const sig = crypto.createHmac('sha256', process.env.SHOPEE_SECRET)
    .update(JSON.stringify(req.body)).digest('hex');
  if (sig !== req.headers['x-shopee-signature']) return res.sendStatus(401);
  const key = 'order:' + req.body.order_sn;
  if (!(await redis.set(key, 1, 'NX', 'EX', 86400))) return res.sendStatus(200);
  await queue.add('pull-order', { orderSn: req.body.order_sn },
    { attempts: 5, backoff: { type: 'exponential', delay: 2000 } });
  res.sendStatus(200); // balas < 1 detik, proses async
});

Dua hal penting di kode di atas. Pertama, verifikasi HMAC SHA-256 memastikan payload benar dari marketplace, bukan dari pihak yang menebak URL webhook. Kedua, SET NX EX pada Redis berfungsi sebagai kunci idempotensi: marketplace kerap mengirim ulang webhook yang sama 2–4 kali saat jaringan goyang, dan tanpa kunci ini Anda berisiko membuat pesanan ganda di POS. Retry 5 kali dengan exponential backoff menangani kegagalan sementara, dan setelah itu job masuk dead letter queue untuk diperiksa manual.

Menangani Konflik Stok, Reservasi, dan Pesanan Gagal

Saat pesanan masuk, jangan hanya mengurangi stok di akhir. Lakukan reservasi atomik begitu order diterima, misalnya UPDATE stock SET reserved = reserved + :qty WHERE variant_id = :id AND (on_hand - reserved) >= :qty. Jika baris yang terpengaruh nol, artinya stok habis dan pesanan harus ditandai. Reservasi otomatis dilepas setelah 15 menit jika pembayaran tidak masuk, sehingga stok tidak terkunci oleh keranjang yang ditinggalkan pembeli.

Ketika reservasi gagal padahal marketplace sudah menerima order, jangan langsung auto-cancel. Pada implementasi retail farmasi kami, 2–4% pesanan harian masuk kategori ini dan mayoritas masih bisa diselamatkan lewat substitusi produk atau pengiriman bertahap. Buat antrean perlu keputusan yang muncul di dashboard operasional dengan batas waktu 2 jam sebelum eskalasi ke refund.

Terakhir, pasang pengawasan yang bisa dibaca tim non-teknis: lag sinkronisasi per channel (target di bawah 60 detik), jumlah job di dead letter queue, dan selisih hasil reconciliation harian. Reconciliation sebaiknya memakai tiga arah: stok POS, stok yang dilaporkan channel, dan jumlah yang benar-benar dikirim ekspedisi. Selisih lebih dari 2 unit per SKU otomatis memicu tiket untuk stock opname spot-check, bukan menunggu akhir bulan.

Best Practices

  1. Tetapkan satu master data. Stok dan harga hanya boleh diubah di POS/ERP; marketplace bersifat read-only untuk data tersebut.
  2. Selalu idempotent. Simpan order_sn atau event ID di Redis/DB dengan TTL minimal 24 jam sebelum memproses webhook.
  3. Pisahkan stok on-hand dan available. Tampilkan available ke channel, sisakan buffer 5–10% untuk produk fast-moving.
  4. Batch dan throttle. Kirim update stok per 100 SKU dengan konkurensi 5–10 worker agar tidak kena rate limit.
  5. Reconciliation otomatis harian. Bandingkan POS, channel, dan ekspedisi; selisih > 2 unit langsung jadi tiket, bukan temuan akhir bulan.

FAQ

Apakah integrasi harus benar-benar real-time?

Tidak. Yang dibutuhkan adalah near real-time: webhook masuk segera, push stok selesai di bawah 60 detik. Untuk katalog besar, sinkronisasi penuh cukup 2–4 kali sehari, sementara update stok per transaksi berjalan event-driven.

Bagaimana jika internet toko mati saat ada pesanan online?

POS tetap jalan dengan mode lokal (SQLite atau IndexedDB) dan webhook ditangkap oleh server cloud, bukan mesin kasir. Saat koneksi pulih, antrean job diproses dan reconciliation menutup selisihnya. Kuncinya: webhook endpoint tidak boleh bergantung pada jaringan toko.

Channel mana yang paling rumit diintegrasikan?

Umumnya marketplace dengan aturan fulfillment sendiri, karena status pesanan berubah beberapa kali (paid, ready to ship, shipped, delivered) dan setiap transisi memicu efek stok berbeda. Website sendiri via WooCommerce REST API v3 justru paling mudah dan cocok dijadikan baseline sebelum menambah channel lain.

Berapa lama implementasi yang realistis?

Untuk satu POS dengan 1–3 channel dan katalog di bawah 5.000 SKU, 4–6 minggu sudah cukup: 1 minggu mapping data, 2 minggu integrasi dan worker, 1 minggu uji paralel, sisanya stabilisasi dan reconciliation.

Integrasi POS dan e-commerce bukan proyek sekali jadi — ia sistem yang harus dipantau, direkonsiliasi, dan disempurnakan setiap minggu. Mulailah dari satu channel, pastikan mapping SKU bersih, lalu tambahkan channel berikutnya setelah lag sinkronisasi stabil di bawah satu menit. Jika Anda sedang menyiapkan omnichannel untuk apotek, klinik, retail, atau restoran dan butuh arsitektur yang aman sejak awal — termasuk reservasi stok, idempotensi webhook, dan dashboard reconciliation — silakan hubungi Nugroho Setiawan untuk sesi konsultasi teknis dan pemetaan kebutuhan sistem Anda.

Solusi terkait dari PT Pilar Inovasi Informatika (produk IT Pilar Inovasi): PilarPOS SIM Klinik Integrator Bridging BPJS & SatuSehat. Butuh konsultasi gratis?

Terakhir diperbarui 07 Nov 2026

Komentar

Komentar ditinjau sebelum tampil.

Belum ada komentar. Jadilah yang pertama!