Strategi percobaan ulang webhook pada sistem pembayaran
Bagaimana Qvard mengulang webhook pembayaran, apa yang dianggap pengiriman gagal, dan cara membangun handler yang tahan terhadap pengulangan, duplikat, dan downtime tanpa memenuhi pesanan dua kali.

Webhook pembayaran adalah pesan yang tidak boleh hilang dan tidak boleh diproses dua kali. Jaringan gagal dan server restart, jadi pengirim mengulang; itulah sebabnya handler Anda harus ditulis dengan memperhitungkan pengulangan. Panduan ini menjelaskan bagaimana Qvard mengulang, apa yang dianggapnya sebagai kegagalan, dan cara membangun handler serta rutinitas pemulihan di sekitar perilaku itu.
Kapan webhook dikirim
Qvard mengirim webhook saat pembayaran selesai. Itu adalah POST ke callback URL yang tersimpan di proyek Anda, dengan JSON kecil berisi id Anda (pengenal yang Anda berikan saat membuat pembayaran) dan status, ditandatangani di header X-Qvard-Signature.
Pembayaran yang kurang, ditolak, atau masih menunggu tidak menghasilkan webhook penyelesaian. Jika Anda perlu mengetahui pembayaran semacam itu, lihat di panel; jangan menunggu pesan yang tidak dikirim.
Apa yang dianggap terkirim
Qvard menganggap pengiriman berhasil hanya ketika endpoint Anda menjawab tepat HTTP 200. Semua yang lain adalah kegagalan:
- kode status lain, termasuk
201,202,204, dan semua4xxserta5xx; - timeout, karena server Anda lambat atau tidak terjangkau;
- pengalihan: Qvard tidak mengikuti
301atau302, jadi aturan yang mengalihkanhttpkehttpsatau menambahkan garis miring di akhir membuat pengiriman gagal.
Ketelitian ini disengaja. 204 No Content tampak seperti jawaban yang baik dan tetap merupakan pengiriman gagal. Kembalikan 200, dengan isi kosong bila mau.
Cara kerja percobaan ulang
Setelah pengiriman gagal, Qvard mencoba lagi. Totalnya lima percobaan dalam sekitar enam menit. Dua konsekuensi:
- Downtime singkat tercakup. Jika server Anda restart atau deploy memakan satu-dua menit, percobaan berikutnya berhasil dan Anda tidak kehilangan apa pun.
- Downtime yang lebih lama tidak. Setelah percobaan terakhir Qvard berhenti. Jika server Anda mati lebih dari enam menit itu, notifikasi tidak tiba dengan sendirinya; kirim ulang untuk pembayaran itu dari panel.
Karena percobaan ulang, handler Anda kadang akan melihat peristiwa yang sama lebih dari sekali, misalnya saat server Anda sudah mengerjakan tugasnya tetapi jawabannya hilang di jalan pulang. Contoh di bawah dibuat untuk itu: pembaruan hanya mengubah pesanan yang belum dibayar, pemenuhan diantrekan hanya ketika satu baris berubah, dan jawabannya 200 dalam kedua kasus.
import os
from fastapi import FastAPI, Request, Response
from qvard import Qvard
app = FastAPI()
SECRET = os.environ["QVARD_SECRET_KEY"]
qvard = Qvard(SECRET)
@app.post("/webhooks/qvard")
async def qvard_webhook(request: Request):
try:
body = qvard.webhooks.construct_event(await request.body(), request.headers.get("X-Qvard-Signature", ""), SECRET)
except ValueError:
return Response(status_code=400)
order_id, status = body.get("id"), body.get("status")
# Idempotent: the UPDATE changes a row only for an order that is not paid yet.
if status == "completed":
changed = await db.execute(
"UPDATE orders SET state = 'paid' WHERE id = :id AND state <> 'paid'", {"id": order_id}
)
if changed:
await queue.enqueue("fulfil", order_id) # slow work after the answer
return Response(status_code=200) # exactly 200, also for repeats and unknown ordersApa yang harus dilakukan handler Anda
Empat aturan mencakup hampir semua masalah:
- Verifikasi tanda tangan. Periksa header
X-Qvard-Signature(HMAC-SHA256 dengan kunci rahasia Anda atas timestamp dan body mentah) dalam waktu konstan dan jawab400jika tidak cocok. Lakukan ini sebelum bertindak atas pembayaran. Lihat cara mengamankan webhook pembayaran kripto. - Idempoten. Jadikan perubahan status bersyarat, «tandai dibayar jika belum dibayar», idealnya dalam satu pernyataan database, agar dua pengiriman paralel tidak menang keduanya.
- Jawab cepat. Periksa, perbarui, antrekan, jawab tepat 200. Kerjakan email, pembuatan file, dan panggilan ke sistem lain dari antrean, agar layanan hilir yang lambat tidak berubah menjadi timeout pada webhook.
- Jawab 200 untuk yang tidak akan pernah Anda tangani. Pesanan tak dikenal atau pengulangan juga harus mengembalikan 200; jika tidak, Qvard terus mengulang pesan yang sudah Anda tangani atau tak akan pernah Anda tangani.
Kegagalan yang tampak seperti bug Qvard
Sebagian besar laporan «webhook tidak tiba» punya penyebab di sisi penerima:
- Firewall atau WAF yang memblokir permintaan dari alamat tak dikenal, atau halaman «segera hadir» atau pemeliharaan.
- Pengalihan dari
httpkehttps, dariwwwke domain tanpa awalan, atau ke garis miring di akhir. - Error framework setelah respons sudah diputuskan, misalnya pengecualian di middleware yang mengubah 200 Anda menjadi 500.
- Handler lambat yang mengerjakan tugas sebelum menjawab dan terbentur timeout.
- Cache atau CDN di depan rute.
- URL yang salah tersimpan di proyek, atau salah ketik pada rute.
Uji endpoint dari luar jaringan Anda dengan permintaan yang membawa header X-Qvard-Signature yang valid, dan periksa log akses server untuk kode jawabannya, bukan hanya apakah permintaan tiba.
Rutinitas pemulihan untuk notifikasi yang terlewat
Percobaan ulang mencakup downtime singkat; untuk sisanya, tambahkan jaring pengaman.
- Catat setiap pengiriman dengan
id,status, keputusan Anda (diterapkan, pengulangan, pesanan tak dikenal, kunci ditolak), dan waktu. Baris log yang hilang adalah cara Anda menyadari adanya celah. - Rekonsiliasi terjadwal. Sehari sekali, bandingkan pesanan yang masih Anda anggap belum dibayar dengan pembayaran dan saldo di panel Qvard. Apa pun yang di panel tampak selesai dan di sistem Anda belum dibayar adalah notifikasi yang terlewat.
- Kirim ulang dari panel untuk pembayaran itu dan biarkan handler idempoten menerapkannya.
- Beri peringatan saat serangkaian permintaan dijawab dengan error, agar Anda tahu endpoint rusak dalam hitungan menit, bukan di akhir hari.
Sisa integrasi, termasuk pembuatan pembayaran, ada di cara menerima pembayaran kripto di situs web dan API pembayaran kripto untuk developer.
FAQ
Berapa kali Qvard mengulang webhook?
Total lima percobaan dalam sekitar enam menit. Setelah itu Qvard berhenti, dan Anda dapat mengirim ulang notifikasi pembayaran dari panel.
Kode status apa yang harus dikembalikan endpoint saya?
Tepat 200. Status lain, termasuk 204, timeout, atau pengalihan dianggap pengiriman gagal dan diulang.
Bisakah webhook yang sama tiba dua kali?
Bisa, misalnya saat server Anda memproses pengiriman pertama tetapi jawabannya hilang. Buat handler idempoten dan tetap jawab 200 untuk pengulangan.
Apakah saya mendapat webhook untuk pembayaran yang kurang atau ditolak?
Tidak. Webhook dikirim saat pembayaran selesai. Periksa pembayaran lain di panel.
