Lewati ke konten utama

Bagaimana menerima notifikasi pembayaran (webhook)?

Begitu pembayaran terkonfirmasi lunas, SekaliPay mengirim POST JSON ke callback_url Anda dengan header X-Signature: HMAC-SHA256 atas body mentah dengan secret key Anda. Verifikasi tanda tangannya, proses pesanan, lalu balas 2xx.

Isi halaman ini dicocokkan dengan kode API per 16 Oktober 2026.

Kapan webhook dikirim?#

  • Produksi: sekali saat tagihan berubah menjadi paid, termasuk pembayaran yang terkonfirmasi sesaat setelah kedaluwarsa.
  • Tidak ada webhook untuk tagihan kedaluwarsa. Status canceled hanya terlihat lewat cek status.
  • Sandbox: saat Anda menekan simulasi, dengan status completed atau failed.
  • Tujuannya callback_url di permintaan, atau URL di Pengaturan API, Webhook & Return URL. Tanpa keduanya, webhook tidak dikirim.

Seperti apa permintaan webhook?#

HTTP
POST /webhook/sekalipay HTTP/1.1
Host: toko-anda.id
Content-Type: application/json
User-Agent: SekalipayGateway/1.0
X-Signature: 2101dd6c3812f2bcc9908337098fbded3c573aa3943d89abca71527840af0d76

{"merchant_ref_id":"ORDER-2026-00184","invoice":"SPY1791446400K3QZ","amount":150000,"fee":1500,"total":151500,"status":"paid","paid_at":"2026-10-08 15:05:12"}
merchant_ref_idstring
Ref pesanan Anda.
invoicestring
Nomor invoice SekaliPay.
amountinteger
Nominal yang Anda terima.
feeinteger
Biaya transaksi.
totalinteger
Yang dibayar pembeli.
statusstring
paid di produksi; completed atau failed di sandbox.
paid_atstring
Waktu lunas Y-m-d H:i:s dalam WIB (UTC+7) tanpa zona waktu. Berbeda dari format ISO di respons API.

Bagaimana memverifikasi tanda tangannya?#

Hitung HMAC-SHA256 atas body mentah yang diterima dengan secret key, lalu bandingkan dengan X-Signature memakai perbandingan waktu-konstan. Jangan parse lalu encode ulang body: body dibuat json_encode PHP yang meng-escape / menjadi \/, sehingga hasil encode ulang di bahasa lain berbeda byte dan tanda tangannya tidak pernah cocok.

$raw       = file_get_contents('php://input');
$expected  = hash_hmac('sha256', $raw, getenv('SEKALIPAY_SECRET_KEY'));
$signature = $_SERVER['HTTP_X_SIGNATURE'] ?? '';

if (! hash_equals($expected, $signature)) {
    http_response_code(401);
    exit;
}

$event = json_decode($raw, true);

http_response_code(200);
echo 'OK';
Vektor uji
secret_key  : sk_test_contoh_saja
body        : {"merchant_ref_id":"ORDER-2026-00184","invoice":"SPY1791446400K3QZ","amount":150000,"fee":1500,"total":151500,"status":"paid","paid_at":"2026-10-08 15:05:12"}
X-Signature : 2101dd6c3812f2bcc9908337098fbded3c573aa3943d89abca71527840af0d76

Bagaimana membalas webhook?#

  • Balas status 2xx secepatnya. Isi balasan tidak dibaca.
  • Batas waktu 120 detik per percobaan. Pekerjaan berat sebaiknya dijalankan di antrean setelah membalas.
  • Endpoint harus bisa dijangkau dari internet. Alamat internal ditolak dan tidak dicoba ulang.

Apa yang terjadi bila endpoint saya gagal?#

PercobaanWaktu
1Segera setelah lunas
2Sekitar 30 detik setelah percobaan pertama gagal
3Sekitar 5 menit setelah percobaan kedua gagal

Setelah 3 percobaan gagal, webhook ditandai gagal. Perbaiki endpoint Anda, lalu kirim ulang dari detail transaksi di dasbor.

Pengiriman bisa dijeda sementara

Bila endpoint Anda gagal berkali-kali berturut-turut, pengiriman ke akun Anda dijeda supaya tidak membanjiri server yang sedang bermasalah. Transaksi yang terlewat ditandai gagal dan bisa dikirim ulang dari dasbor. Pengiriman pulih sendiri setelah jeda, atau segera setelah satu kiriman berhasil.

Bagaimana menangani webhook ganda?#

Webhook yang sama bisa datang lebih dari sekali: kiriman ulang manual, atau percobaan ulang ketika server Anda sudah memproses tetapi membalas terlambat. Catat invoice yang sudah diproses dan abaikan kiriman berikutnya. Cocokkan juga amount dengan pesanan Anda.

Siap memakai kunci Anda sendiri?

Masuk ke dasbor merchant untuk mengambil API key dan secret key, mengatur mode akses dan URL webhook, serta mengunduh koleksi Postman berisi kunci akun Anda.

Masuk ke dasbor