Terima hasil pembayaran melalui webhook
Webhook adalah request HTTP POST dari Valcentra ke backend Anda. Request membawa event, misalnya payment.paid, sehingga backend dapat memperbarui pesanan tanpa bergantung pada pelanggan kembali dari checkout.
Sebelum mulai
- Anda sudah membuat payment TEST melalui Quickstart.
- Anda memiliki endpoint backend untuk menerima
POSTJSON. - Endpoint dapat diakses dari layanan Valcentra, bukan hanya dari laptop Anda.
- Anda memiliki penyimpanan persisten untuk event yang sudah diterima dan data pesanan.
1. Daftarkan endpoint pada project TEST
Buka Webhooks di project yang sama dengan API key Anda, lalu daftarkan URL receiver untuk environment TEST. Pastikan endpoint aktif dan simpan webhook secret ketika ditampilkan.
Gunakan URL HTTPS publik tanpa credential di URL. Alamat localhost, jaringan privat, dan tujuan yang tidak lolos kebijakan keamanan URL ditolak. Untuk receiver lokal, gunakan alamat publik pengujian yang disetujui dan melindungi data; jangan membuka backend pengembangan sembarangan. Endpoint tidak boleh mengandalkan redirect ke alamat lain.
Jika environment atau project endpoint berbeda dari payment, event tidak akan masuk ke receiver yang Anda harapkan.
2. Pahami bentuk request
Request memiliki header x-valcentra-timestamp dan x-valcentra-signature. Secret tidak dikirim bersama request.
{
"id": "evt_example_paid_1001",
"type": "payment.paid",
"created_at": "2026-10-01T09:05:00.000Z",
"livemode": false,
"data": {
"object": {
"id": "pay_example_1001",
"amount": "125000",
"currency": "IDR",
"merchant_reference": "order-book-1001",
"status": "paid",
"livemode": false,
"channel": "qris",
"created_at": "2026-10-01T09:00:00.000Z",
"updated_at": "2026-10-01T09:05:00.000Z",
"expires_at": "2026-10-01T09:30:00.000Z",
"paid_at": "2026-10-01T09:05:00.000Z"
}
}
}event.id mengidentifikasi event; data.object.id mengidentifikasi payment. Satu payment dapat memiliki beberapa event berbeda. Gunakan event ID, bukan payment ID, untuk deduplikasi penerimaan. Lihat daftar event untuk field dan tipe lain.
3. Verifikasi sebelum menggunakan body
Ambil raw body bytes sebelum JSON parsing. Verifikasi timestamp dan HMAC dengan secret endpoint, lalu parse JSON dan validasi schema event. Panduan signature HMAC menyediakan contoh TypeScript backend.
Jangan memperbarui pesanan berdasarkan body yang belum diverifikasi, meskipun bentuknya terlihat benar. Event TEST juga tidak boleh mengubah pesanan produksi.
4. Simpan event dan proses secara aman
Diagram ini memakai pola inbox: receiver menyimpan event di database, lalu worker Anda memprosesnya. Anda juga boleh memproses langsung, asalkan perubahan pesanan dan pencatatan event selesai secara atomik sebelum membalas sukses.
Urutan yang disarankan:
- Verifikasi signature, parse JSON, dan validasi bentuk event.
- Cocokkan environment receiver dengan
livemode; pilih penyimpanan sesuai konteks endpoint. - Simpan event yang diperlukan ke inbox persisten dengan constraint unik pada
event.iddalam konteks integrasi Anda. Gunakan transaksi/insert atomik, bukan sekadar pengecekan lalu insert yang dapat berlomba. - Balas HTTP 2xx hanya setelah event tersimpan aman. Jika penyimpanan gagal, balas kegagalan agar pengiriman dapat dicoba lagi.
- Worker mencocokkan payment ID, referensi pesanan, jumlah, mata uang, dan environment, lalu memperbarui pesanan secara atomik.
- Cegah pemenuhan pesanan dua kali, termasuk jika worker mencoba ulang setelah crash. Gunakan transaksi dan outbox/job yang memiliki pengenal unik sesuai pesanan.
Simpan hanya data event yang diperlukan sesuai kebijakan retensi Anda. Jangan menyimpan header signature, webhook secret, atau payload provider sebagai bagian dari inbox.
5. Balas cepat, tetapi jangan mengakui terlalu awal
Valcentra menganggap HTTP 200–299 sebagai penerimaan sukses. Batas waktu pengiriman saat ini 5 detik. Gunakan respons kecil, misalnya HTTP 204 tanpa body.
Jangan membalas 2xx lalu menyimpan event hanya di memori atau menjalankan proses yang hilang jika server berhenti. Sebaliknya, jangan menunggu email atau pekerjaan lambat selesai jika event sudah masuk antrean persisten.
DELIVERED di dashboard hanya berarti endpoint membalas sukses. Status itu tidak membuktikan worker merchant selesai atau pesanan sudah dipenuhi.
Hadapi event berulang dan tidak berurutan
Pengiriman webhook bersifat at-least-once: event yang sama bisa diterima lebih dari sekali. Urutannya juga tidak dijamin. Event payment.pending dapat datang setelah event payment.paid diterima.
- Jika event sudah tersimpan aman, balas 2xx tanpa mengulangi efek bisnis.
- Jangan menurunkan status akhir karena snapshot lama datang belakangan.
- Jika snapshot bertentangan dengan kondisi pesanan, ambil payment terbaru melalui API dari backend sebelum mengambil keputusan.
- Abaikan tipe yang tidak Anda tangani tanpa menjalankan efek bisnis, setelah signature dan schema diperiksa. Jangan membuat setiap event yang tidak dipakai menjadi kegagalan pengiriman.
Periksa integrasi Anda
Daftarkan receiver sebelum membuat payment uji, lalu simulasikan pembayaran baru. Periksa bahwa event masuk, signature valid, delivery sukses, dan pesanan uji diperbarui tepat sekali. Jika belum masuk, cocokkan endpoint aktif, project, environment, jaringan, dan secret.
Lanjutkan ke: verifikasi HMAC, retry webhook, dan checklist sandbox.
