Pembayaran Digital
Integrasi Software Kasir dengan Pembayaran Digital

Ringkasan Cepat
Panduan teknis integrasi Software Kasir dan pembayaran digital agar status, retry, refund, settlement, serta rekonsiliasi dapat ditelusuri tanpa transaksi ganda.
- Integrasi Software Kasir dengan pembayaran digital harus menghubungkan order, payment attempt, status, provider reference, refund, settlement, serta accounting.
- Menampilkan tombol bayar atau QR belum cukup.
- Sistem perlu tetap benar ketika callback terlambat, jaringan putus, pengguna menekan ulang, status tidak pasti, dan settlement berbeda dari total order.
Ringkasan dibuat untuk membantu pembaca memahami poin utama. Gunakan isi artikel lengkap sebagai sumber penjelasan.
Integrasi Software Kasir dengan pembayaran digital harus menghubungkan order, payment attempt, status, provider reference, refund, settlement, serta accounting. Menampilkan tombol bayar atau QR belum cukup. Sistem perlu tetap benar ketika callback terlambat, jaringan putus, pengguna menekan ulang, status tidak pasti, dan settlement berbeda dari total order.
Artikel ini berfokus pada arsitektur integrasi serta operability. Optimasi waktu checkout dan desain antrean dibahas terpisah. Di sini, ukuran keberhasilan adalah integritas transaksi, kemampuan observasi, recovery, dan rekonsiliasi end-to-end.
Jawaban singkat
Tetapkan canonical order ID dan payment attempt ID. Bangun adapter per provider di belakang payment orchestration interface. Gunakan idempotency key, state machine, signature verification, webhook inbox, status inquiry, retry terkontrol, serta ledger event yang immutable.
Pisahkan payment success dari settlement. Rekonsiliasi POS, provider, payout, bank, refund, dan accounting setiap periode. Siapkan dashboard exception, alert, runbook, sandbox contract test, canary rollout, feature flag, serta rollback. Jangan menyimpan credential atau data instrumen di POS melebihi kebutuhan.
Petakan komponen
Arsitektur umum mencakup POS client, order service, payment orchestration, provider adapter, credential vault, webhook gateway, event store, reconciliation service, refund service, observability, dan accounting integration. Pada usaha kecil, sebagian komponen dapat disediakan vendor, tetapi tanggung jawab tetap perlu dipahami.
| Komponen | Fungsi | Data utama | Risiko |
|---|---|---|---|
| POS client | Memulai payment | Order/amount/method | Retry pengguna |
| Orchestrator | Atur lifecycle | Attempt/state | State salah |
| Adapter | Terjemahkan provider | Request/response | Contract drift |
| Webhook inbox | Terima event | Event/signature | Duplicate/spoof |
| Reconciliation | Cocokkan sumber | Settlement/bank | Selisih diam-diam |
| Refund | Balik dana | Original reference | Refund ganda |
| Ledger/audit | Jejak event | Immutable facts | Edit historis |
Source of truth untuk order, payment, settlement, serta accounting harus ditulis. Tidak satu database harus memiliki semuanya, tetapi hubungan ID wajib stabil.
Rancang contract internal
POS memanggil interface internal yang konsisten: create attempt, get status, cancel jika didukung, refund, serta list exception. Provider-specific field berada pada adapter, bukan menyebar ke seluruh aplikasi.
Request memuat order ID, attempt ID, amount, currency, method, merchant/outlet, device, expiry, return/callback context, dan metadata minimum. Response memuat accepted/rejected, provider reference, state, customer action, expiry, serta error terstruktur.
Version contract dengan backward compatibility. Jangan mengubah arti field tanpa migration. Consumer-driven contract test membantu menemukan breaking change sebelum produksi.
Gunakan identitas unik
Order ID merepresentasikan kewajiban bisnis. Payment attempt ID merepresentasikan satu percobaan metode. Provider reference mengidentifikasi transaksi pada provider. Settlement ID mengidentifikasi payout batch. Refund ID mengidentifikasi pengembalian.
Jangan memakai satu ID untuk semua lapisan atau nomor urut yang dapat bertabrakan antaroutlet. Correlation ID menghubungkan log serta event tanpa mengekspos data sensitif.
Idempotency key dikaitkan dengan operation dan payload. Jika key sama tetapi amount berbeda, sistem menolak serta membuat alertānot overwrite.
Bentuk state machine
Contoh state payment: created, requires_action, processing, pending, succeeded, failed, cancelled, reversed, partially_refunded, refunded, dan disputed sesuai kemampuan provider. Tidak semua provider memakai istilah sama; adapter memetakan ke canonical state.
Transition rule mencegah succeeded kembali menjadi pending. Event terlambat tetap disimpan tetapi tidak selalu mengubah current state. Unknown/unmapped state masuk quarantine agar tidak dianggap failed.
Order state terpisah: awaiting_payment, paid, fulfillment, cancelled. Satu order dapat memiliki beberapa attempts tetapi hanya hasil sah yang diterapkan. Compensation diperlukan jika dua attempts akhirnya success.
Terapkan idempotency end-to-end
Idempotency diperlukan pada create payment, capture, cancel, refund, webhook handling, ledger posting, dan notification. Database uniqueness serta transaction boundary melengkapi key; cache saja tidak cukup.
Client retry karena timeout menggunakan attempt/key yang sama sampai aturan menentukan attempt baru. Backend menyimpan request hash serta response. Jika provider tidak mendukung idempotency, adapter menerapkan lookup/inquiry serta locking yang dirancang hati-hati.
Uji double-click, network timeout setelah provider menerima request, process crash sebelum response disimpan, dan message replay. Hasil harus tetap satu transaksi ekonomi.
Amankan credential dan request
API key, secret, certificate, dan token disimpan dalam secret manager atau fasilitas yang sesuai, bukan source code, database POS biasa, atau chat. Terapkan rotation, least privilege, environment separation, access log, serta emergency revoke.
Gunakan TLS, certificate validation, official SDK bila dinilai, request signing sesuai provider, timestamp, nonce bila didukung, dan clock sync. Jangan mematikan certificate verification untuk menyelesaikan error.
Data instrumen pembayaran tidak perlu masuk log. Masking saja belum cukup jika raw payload tersimpan di tempat lain. Ikuti acquirer/provider serta standar industri yang berlaku.
Bangun webhook gateway
Endpoint webhook memverifikasi signature, timestamp, source context, content type, schema, dan size. Baca raw body sesuai metode signature provider. Tolak request yang tidak valid tanpa membocorkan detail.
Simpan event pada inbox dengan provider, event ID, received time, verified status, type, object reference, hash, dan processing result. Acknowledge cepat setelah durable write; proses bisnis dapat asynchronous.
Handler idempotent. Duplicate event menghasilkan hasil yang sama. Out-of-order event mengikuti state machine. Failed processing masuk retry dengan backoff dan dead-letter queue, bukan hilang.
Gunakan status inquiry
Webhook dapat terlambat atau tidak sampai. Inquiry mengambil status provider berdasarkan reference yang sah. Trigger dapat berasal dari timeout pelanggan, pending ageing, reconciliation mismatch, atau support case.
Jangan melakukan polling agresif. Ikuti rate limit serta backoff. Record setiap inquiry, response, dan state change. Jika provider tidak dapat memastikan, status tetap pending/unknown dengan owner.
UI kasir menampilkan elapsed time serta tindakan aman. Manual āmark paidā bukan pengganti inquiry; override material memerlukan approval dan reconciliation.
Kelola customer action
Beberapa metode memerlukan redirect, QR, OTP pada kanal provider, tap, atau instruction. Orchestrator menyimpan action type, payload aman, expiry, serta display rule. Jangan menyimpan credential pelanggan.
Ketika action expired, buat attempt baru hanya setelah status lama diperiksa. Browser return URL bukan bukti pembayaran karena dapat ditutup, dimodifikasi, atau datang sebelum callback. Server-to-server status menjadi basis sesuai integrasi.
Deep link serta QR memerlukan expiry dan binding ke amount/order bila didukung. Jangan memakai static code untuk alur yang memerlukan pencocokan otomatis tanpa kontrol tambahan.
Rancang refund
Refund mengacu pada successful payment, remaining refundable amount, reason, actor, approval, customer case, dan idempotency key. Partial refund menghitung cumulative total. Currency serta precision harus sama dengan original.
State refund: requested, approved, submitted, processing, succeeded, failed, reversed atau status provider relevan. Refund submitted belum sama dengan dana diterima pelanggan. Sediakan reference serta estimasi.
Retry refund menggunakan ID yang sama. Manual payout di luar provider dicatat sebagai jalur berbeda agar tidak terjadi pengembalian dua kali.
Pisahkan authorization, success, dan settlement
Metode dapat mempunyai lifecycle authorization, capture, reversal, settlement, chargeback, atau dispute. Definisikan istilah per provider. Jangan menyebut success sebagai settlement bila dana belum masuk payout.
Settlement record memuat provider, merchant/outlet, batch, period, gross, fee, tax, refund, adjustment, reserve, net, currency, payout date, dan bank reference. Breakdown perlu sampai transaction bila provider menyediakan.
Accounting mapping menentukan receivable provider, cash, fee, refund, chargeback, serta revenue/order secara terpisah.
Bangun rekonsiliasi
Three-way atau multi-way reconciliation membandingkan internal payment, provider transaction, settlement report, dan bank. Gunakan ID, amount, currency, status, serta dateānot description text.
Exception category:
- Internal success, provider missing.
- Provider success, internal pending.
- Amount/currency mismatch.
- Duplicate payment.
- Settlement missing atau terlambat.
- Fee/adjustment tidak dikenal.
- Refund status berbeda.
- Bank payout tidak cocok.
Setiap exception mempunyai value, ageing, severity, owner, root cause, action, dan closure evidence. Tolerance perlu approval serta review berkala.
Terapkan observability
Metric mencakup create latency, success, pending, failure by code, callback delay, signature failure, retry, duplicate prevented, inquiry, DLQ, refund, settlement lag, dan reconciliation break. Pecah per provider, method, outlet, app version, dan environment.
Structured log memakai correlation ID tanpa data sensitif. Trace mengikuti POSāorchestratorāadapterāprovider. Alert berdasarkan user/business impact, bukan setiap error teknis.
Dashboard memiliki data freshness. Absence of events dapat berarti pipeline mati, bukan kondisi sehat. Synthetic test dapat memeriksa endpoint yang aman sesuai provider.
Tulis runbook
Runbook per symptom: provider timeout, webhook gagal, signature error, pending spike, duplicate, settlement missing, refund stuck, credential expiry, dan provider outage. Ia memuat detection, scope, first action, stop condition, fallback, contact, evidence, customer communication, recovery, dan reconciliation.
Incident commander mengoordinasikan engineering, finance, operations, support, serta provider. Jangan meminta kasir mencoba berkali-kali. Setelah pulih, reprocess queue secara idempotent dan rekonsiliasi seluruh periode terdampak.
Post-incident review fokus pada sistem, bukan menyalahkan individu. Action memiliki owner serta deadline.
Lindungi data dan akses
Least privilege diterapkan pada credential, refund, manual adjustment, export, dashboard, dan log. Production access memakai MFA, approval, session logging, serta time-bound grant. Vendor support tidak mendapat akses permanen tanpa kebutuhan.
Pengolahan data pribadi perlu memperhatikan Undang-Undang Pelindungan Data Pribadi. Tentukan tujuan, processor/subprocessor, retensi, transfer, hak, serta incident notification.
Tinjau fitur Kasair, panduan Kasair, dan Kasair POS untuk memahami order serta payment flow yang tersedia. Integrasi aktual harus mengikuti dokumentasi serta kontrak vendor.
Uji integrasi
Contract test memeriksa schema serta mapping. Component test memakai simulator. Sandbox test memakai provider environment. End-to-end test mencakup order, customer action, callback, inquiry, refund, settlement fixture, dan accounting export.
Skenario wajib: timeout sebelum/selepas provider menerima, callback duplicate, event out-of-order, signature invalid, state baru, amount mismatch, process crash, queue retry, refund duplicate, credential rotation, rate limit, dan timezone cutoff.
Gunakan data sintetis. Test production kecil hanya melalui prosedur yang disetujui dan direkonsiliasi.
Rollout bertahap
Gunakan feature flag per outlet/method/provider, canary traffic, rate limit, kill switch, dan fallback. Tetapkan baseline, success gate, guardrail, serta rollback. Jangan rollout bersamaan dengan perubahan besar POS lain.
Monitor technical serta financial signals. Canary dapat terlihat sukses pada response API tetapi gagal settlement; evaluasi mengikuti satu siklus yang memadai. Finance serta operations ikut sign-off.
Version deprecation membutuhkan inventory client, communication, dual-run jika perlu, serta cutover. Simpan old adapter sampai transaksi in-flight selesai.
FAQ
Mengapa order ID dan payment ID harus berbeda?
Satu order dapat mempunyai beberapa percobaan pembayaran. ID terpisah menjaga retry, metode, dan status dapat ditelusuri.
Apakah browser redirect membuktikan pembayaran berhasil?
Tidak. Gunakan status server/provider yang dipercaya melalui webhook atau inquiry sesuai dokumentasi.
Bagaimana mencegah pembayaran ganda?
Gunakan idempotency, locking/uniqueness, state machine, status inquiry, UI terkontrol, deteksi duplikat, dan rekonsiliasi.
Mengapa payment success belum tentu settled?
Success menunjukkan transaksi diterima/diotorisasi sesuai metode; settlement adalah penyelesaian dana ke merchant setelah fee atau adjustment.
Kapan webhook perlu diulang?
Processing gagal dapat di-retry dengan backoff melalui inbox; handler harus idempotent dan event invalid tidak diproses.
Apa syarat rollout integrasi?
Contract test, end-to-end, security, observability, runbook, reconciliation, canary, fallback, dan rollback harus terbukti.
Integrasi Software Kasir dan pembayaran digital yang matang tidak hanya membuat transaksi āberhasilā. Identitas unik, state machine, idempotency, webhook aman, inquiry, observability, refund, serta rekonsiliasi memastikan setiap rupiah dapat ditelusuri ketika kondisi jaringan dan provider tidak sempurna.
BACA SELANJUTNYA