Bagaimana membuat pembayaran pertama lewat API?
Enam langkah: ambil kunci, pilih mode akses, atur URL webhook, aktifkan metode, buat tagihan di sandbox, lalu verifikasi webhook dan pindah ke produksi. Kunci dan URL yang sama dipakai di sandbox dan produksi, jadi tidak ada yang perlu diganti saat go-live selain mode akun.
Isi halaman ini dicocokkan dengan kode API per 16 Oktober 2026.
Apa yang perlu disiapkan sebelum menulis kode?#
- Akun merchant yang sudah lolos verifikasi (KYC). Sebelum itu,
POST /paymentdibalas403 MERCHANT_KYC_INCOMPLETE. - Server yang bisa dijangkau dari internet untuk menerima webhook. Alamat internal seperti
localhostatau IP privat ditolak sebagaicallback_url. - Akses ke dasbor merchant untuk mengambil kunci dan mengatur URL.
Bagaimana urutan integrasinya?#
Ambil API key dan secret key
Dasbor, menu Pengaturan API, lalu API Keys. Secret key tampil setelah verifikasi PIN. Simpan di variabel lingkungan server, jangan di kode klien atau repositori.
Pilih mode akses
Pengaturan API, Mode & akses. Server ber-IP tetap: daftarkan IP-nya (IP Whitelist). Serverless: matikan whitelist untuk memakai Enhanced HMAC. Bedanya ada di Autentikasi.
Atur URL webhook dan return URL
Pengaturan API, Webhook & Return URL. Keduanya bisa diganti per transaksi lewat field
callback_urldanreturn_url.Aktifkan metode pembayaran
Menu Metode pembayaran di dasbor. Hanya metode yang aktif di akun Anda yang bisa dipakai, dan
GET /payment-methodsmengembalikan daftar itu besertapayment_code-nya.Nyalakan sandbox dan buat tagihan
Mode sandbox ada di Mode & akses. Kirim permintaan di bawah, buka
payment_linkdari respons, lalu klik simulasi sukses.Verifikasi webhook, lalu matikan sandbox
Pastikan endpoint Anda memverifikasi
X-Signaturedan membalas 2xx. Setelah itu matikan sandbox; kunci dan URL tetap sama.
Seperti apa permintaan pertamanya?#
Contoh berikut untuk mode IP Whitelist: hanya permintaan POST yang ditandatangani, dengan HMAC-SHA256 atas body JSON persis seperti yang dikirim. Untuk Enhanced HMAC, lihat contohnya.
BODY='{"merchant_ref_id":"ORDER-2026-00184","amount":150000,"payment_code":"QRIS","customer_name":"Budi Santoso","customer_email":"[email protected]","customer_phone":"081234567890","callback_url":"https://toko-anda.id/webhook/sekalipay","return_url":"https://toko-anda.id/checkout/selesai"}'
SIGNATURE=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$SEKALIPAY_SECRET_KEY" | sed 's/^.* //')
curl -X POST https://sekalipay.com/api/v1/gateway/payment \
-H "X-API-Key: $SEKALIPAY_API_KEY" \
-H "X-Signature: $SIGNATURE" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
--data-raw "$BODY"$body = json_encode([
'merchant_ref_id' => 'ORDER-2026-00184',
'amount' => 150000,
'payment_code' => 'QRIS',
'customer_name' => 'Budi Santoso',
'customer_email' => '[email protected]',
'customer_phone' => '081234567890',
'callback_url' => 'https://toko-anda.id/webhook/sekalipay',
'return_url' => 'https://toko-anda.id/checkout/selesai',
]);
$signature = hash_hmac('sha256', $body, getenv('SEKALIPAY_SECRET_KEY'));
$ch = curl_init('https://sekalipay.com/api/v1/gateway/payment');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $body,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'Accept: application/json',
'X-API-Key: ' . getenv('SEKALIPAY_API_KEY'),
'X-Signature: ' . $signature,
],
]);
$response = json_decode(curl_exec($ch), true);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);import { createHmac } from "node:crypto";
const body = JSON.stringify({
"merchant_ref_id": "ORDER-2026-00184",
"amount": 150000,
"payment_code": "QRIS",
"customer_name": "Budi Santoso",
"customer_email": "[email protected]",
"customer_phone": "081234567890",
"callback_url": "https://toko-anda.id/webhook/sekalipay",
"return_url": "https://toko-anda.id/checkout/selesai"
});
const signature = createHmac("sha256", process.env.SEKALIPAY_SECRET_KEY)
.update(body)
.digest("hex");
const res = await fetch("https://sekalipay.com/api/v1/gateway/payment", {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
"X-API-Key": process.env.SEKALIPAY_API_KEY,
"X-Signature": signature,
},
body,
});
const result = await res.json();{
"status": true,
"message": "OK",
"data": {
"merchant_ref_id": "ORDER-2026-00184",
"invoice": "SPY1791446400K3QZ",
"amount": 150000,
"fee": 1500,
"total": 151500,
"payment_code": "QRIS",
"payment_link": "https://sekalipay.com/payment/SPY1791446400K3QZ",
"qr_link": "https://sekalipay.com/payment/SPY1791446400K3QZ/qris",
"virtual_account": null,
"checkout_url": null,
"payment_guide": null,
"expired_at": "2026-10-08T08:30:00.000000Z",
"status": "pending",
"is_sandbox": false
}
}Apa yang wajib dicek sebelum go-live?#
- Webhook diverifikasi dengan HMAC atas body mentah dan dibandingkan waktu-konstan (caranya).
- Pesanan ditandai lunas hanya dari webhook atau cek status, tidak pernah dari parameter di
return_url. - Pemrosesan webhook idempoten, karena webhook yang sama bisa datang lebih dari sekali.
amountdi webhook dicocokkan dengan pesanan sebelum barang dikirim.- Setiap pesanan punya
merchant_ref_idunik, dan percobaan ulang setelah timeout memakai ref yang sama (idempotensi). - Status
paiddancompletedsama-sama diperlakukan lunas (kenapa). - Respons
429ditangani dengan menunggu sesuai headerRetry-After. - Mode sandbox sudah dimatikan.
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
