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
canceledhanya terlihat lewat cek status. - Sandbox: saat Anda menekan simulasi, dengan status
completedataufailed. - Tujuannya
callback_urldi permintaan, atau URL di Pengaturan API, Webhook & Return URL. Tanpa keduanya, webhook tidak dikirim.
Seperti apa permintaan webhook?#
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.
statusstringpaiddi produksi;completedataufaileddi sandbox.paid_atstring- Waktu lunas
Y-m-d H:i:sdalam 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';import express from "express";
import { createHmac, timingSafeEqual } from "node:crypto";
const app = express();
app.post("/webhook/sekalipay", express.raw({ type: "application/json" }), (req, res) => {
const expected = createHmac("sha256", process.env.SEKALIPAY_SECRET_KEY)
.update(req.body)
.digest("hex");
const given = req.get("X-Signature") ?? "";
const valid =
given.length === expected.length &&
timingSafeEqual(Buffer.from(given), Buffer.from(expected));
if (!valid) return res.sendStatus(401);
const event = JSON.parse(req.body.toString("utf8"));
res.sendStatus(200);
});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 : 2101dd6c3812f2bcc9908337098fbded3c573aa3943d89abca71527840af0d76Bagaimana 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?#
| Percobaan | Waktu |
|---|---|
| 1 | Segera setelah lunas |
| 2 | Sekitar 30 detik setelah percobaan pertama gagal |
| 3 | Sekitar 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
