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 →