Untuk mencocokkan pembayaran kripto dengan pesanan yang benar, buat pesanan terlebih dahulu dan berikan local order ID yang stabil. Kirim ID itu sebagai konteks pada payment invoice terpisah dan simpan invoice ID provider pada order. Ketika API authenticated atau signed webhook melaporkan paid, cari order melalui reference, konfirmasi status invoice, simpan token, network, amount, dan tx hash, lalu jalankan fulfilment secara idempotent. Hubungan tepercaya adalah merchant order ID → payment invoice ID → confirmed blockchain transaction.
| Catatan | Yang dibuktikan | Yang tidak dibuktikan sendiri |
|---|---|---|
| Merchant order | Pelanggan, kewajiban, dan arti fulfilment | Dana telah tiba on-chain |
| Payment invoice | Token, jaringan, jumlah, dan waktu yang diharapkan | Merchant menyerahkan produk |
| Blockchain transaction | Transfer token publik | Pesanan komersial yang dimaksud |
| Signed event | Hubungan invoice, status, dan transaksi | Downstream effect terjadi sekali |
Blockchain tidak menyimpan pesanan Anda
Blockchain mencatat perpindahan aset. Event ERC-20 Transfer berisi sender, recipient, dan value; standar ERC-20 tidak membawa nomor order, pelanggan, SKU, atau aturan penyerahan. Masuknya 100 USDC membuktikan transfer, tetapi tidak menentukan apakah itu untuk ORDER-4821, invoice lama, atau operasi lain.
Bangun hubungan sebelum checkout dikirim. Menebak setelah dana tiba berdasarkan address, amount, atau time akan mengubah setiap kemiripan menjadi pekerjaan manual.
Jangan gunakan address, amount, atau screenshot sebagai key
Receiving address dapat digunakan oleh banyak pembayaran. Dua pelanggan bisa mengirim jumlah sama, seseorang bisa memakai instruksi lama, dan format 0x yang sama ada pada beberapa jaringan EVM. Amount juga tidak unik: harga sama, underpayment, overpayment, dan rounding terjadi. Jumlah decimal yang aneh mungkin mengurangi collision, tetapi tidak menggantikan foreign key.
Jika jumlah terverifikasi berbeda dari invoice, gunakan alur invoice kurang bayar dan lebih bayar dan jangan masukkan pesanan ke fulfilment otomatis normal.
Timestamp dan sender address hanyalah evidence tambahan. Exchange dapat menunda atau mengelompokkan withdrawal. Screenshot bukan bukti, dan tx hash nyata pun bisa berisi token, recipient, atau network salah, atau sudah dipakai untuk order lain. Gunakan panduan verifikasi manual.
Hubungkan tiga catatan dengan ID eksplisit
| Field | Tempat penyimpanan | Tujuan |
|---|---|---|
| Local order ID | Database merchant dan payment context | Lookup dan fulfilment stabil |
| Payment invoice ID | Order dan provider | Pencarian langsung dan support |
| Expected business amount | Order | Kewajiban komersial |
| Payable token amount | Invoice | Jumlah tepat pada checkout |
| Token dan network | Invoice dan payment record | Memisahkan rute berbeda |
| Status dan history | Payment record | Mengendalikan langkah berikutnya |
| Transaction hash | Final payment record | Menemukan bukti publik |
| Paid/expiry timestamps | Payment record | Menjelaskan late payment |
| Event/delivery key | Webhook inbox | Mencegah effect berulang |
Gunakan database ID immutable atau UUID, bukan nomor tampilan yang dapat diedit. Jangan masukkan secret, private key, atau data pribadi yang tidak perlu ke metadata. Segera simpan provider invoice ID pada order agar support dapat menelusuri kedua arah.
Buat invoice secara idempotent
Situs harus memvalidasi pembelian, membuat local order dalam payment_pending, menghasilkan idempotency key per order dan attempt, membuat payment invoice dengan order ID, menyimpan invoice ID serta checkout URL, lalu mengarahkan pelanggan.
Timeout bersifat ambigu: invoice mungkin sudah dibuat walau response tidak tiba. Retry dengan key baru dapat membuat dua checkout. Pada GramPayBot, reference dikirim dalam payload; Idempotency-Key dan parameter yang sama mengembalikan invoice awal, sedangkan key sama dengan parameter berbeda menghasilkan conflict. Lihat API quickstart dan API reference.
Satu order dapat memiliki beberapa attempt: order → attempt 1 expired → attempt 2 paid. Jangan menimpa attempt lama. Hanya satu yang boleh menutup order otomatis; sisanya disimpan untuk late-payment review.
Biarkan server mengubah status akhir
Browser return page bukan otoritas pembayaran. Gunakan authenticated API atau signed server-to-server webhook. Handler aman membaca raw body, memverifikasi HMAC dengan constant time, menyimpan delivery dan body, melakukan deduplication dengan stable key, merespons 2xx cepat, lalu memproses pada async worker.
GramPayBot dapat mencoba ulang event nyata hingga 17 kali selama sekitar empat hari. Duplicate delivery adalah mekanisme normal. Praktik webhook Stripe juga menyarankan penyimpanan event IDs yang telah diproses.
Deduplication delivery belum cukup: webhook dan polling worker dapat melihat invoice paid yang sama. Lindungi business effect dengan unique constraint atau conditional transition. Order hanya boleh berpindah dari payment_pending, dan hanya satu fulfilment job boleh ada per order ID. Tujuannya at-least-once delivery dengan exactly-once business effect.
Petakan status ke tindakan
| Status | Arti | Tindakan otomatis |
|---|---|---|
active | Permintaan valid tanpa pembayaran diterima | Order tetap pending |
paid | Invoice memenuhi confirmation rule | Izinkan fulfilment idempotent |
expired | Waktu berakhir tanpa match | Blokir penyerahan normal, review late payment |
cancelled | Permintaan ditutup | Jangan gunakan sebagai attempt saat ini |
Payment state dan order state dapat berbeda. Invoice paid bisa mengubah order menjadi ready_for_review jika diperlukan pemeriksaan stok atau compliance. Invoice expired dapat diganti attempt baru. Simpan status history, alasan, dan petugas untuk manual override.
Pertahankan exception secara terlihat
Wrong token contract, wrong network, underpayment, overpayment, late payment, duplicate tx hash, dan paid invoice tanpa local order harus masuk exception state. Simpan transaksi dan biarkan orang berwenang memilih menerima, meminta selisih, atau refund. Dalam direct-to-wallet, merchant menandatangani refund; monitoring service tidak dapat membalik blockchain.
Operational matching juga bukan keseluruhan accounting reconciliation. Finance mungkin memerlukan fiat value, fee, conversion, dokumen, dan riwayat refund. Bandingkan paid payment attempts dengan paid orders secara berkala serta cari orphan record dan duplicate hash. Transfer token tersedia melalui smart-contract event logs, tetapi log tersebut tidak mengetahui arti komersial.
Contoh GramPayBot
SaaS membuat ORDER-4821. Backend memanggil createInvoice dengan payload: "ORDER-4821" dan Idempotency-Key: ORDER-4821:crypto:1, lalu menyimpan public_id serta checkout URL. Pelanggan membayar USDC di Base. GramPayBot mengonfirmasi dan mengirim invoice_paid bertanda tangan dengan order reference, token, network, dan tx hash. Endpoint memverifikasi, menyimpan, dan menjawab 2xx; worker mengunci pending order dan membuat satu aktivasi. Retry tidak mengaktifkan paket lagi.
Panduan verifikasi otomatis membahas detection lebih luas, sedangkan use case situs menunjukkan penggunaan bisnisnya.
Sebelum peluncuran, ulangi invoice creation dengan key sama, kirim webhook yang sama dua kali, biarkan invoice expired, dan uji amount salah tanpa fulfilment. Integrasi siap bila setiap paid order dapat ditelusuri ke satu invoice dan transaksi diterima, sementara setiap retry menghasilkan safe no-op atau review item yang terlihat.
Langkah berikutnya
Otomatiskan verifikasi di website
Buat invoice untuk setiap pesanan, gunakan hosted checkout, dan terima hasil terkait pesanan.
Lihat pembayaran website →