Dokumentasi REST API
Panduan integrasi teknis REST API, spesifikasi endpoint, skema payload webhook, pengujian simulator, dan standar keamanan transaksi merchant.
Spesifikasi Mesin (OpenAPI 3.0 Standard)
Butuh spesifikasi dalam format terstruktur untuk generator SDK, AI coding assistant, atau import ke Postman? Unduh /openapi.json — berisi skema lengkap seluruh endpoint, autentikasi, model request, format respons, dan event webhook.
Arsitektur Terintegrasi & Lisensi Bank Indonesia
API ini adalah lapisan operasional pembayaran modern yang terhubung langsung ke jaringan payment gateway resmi berlisensi Bank Indonesia. Anda tidak perlu repot mengurus protokol gateway yang rumit — cukup integrasikan 1 API kami untuk mengelola seluruh kanal pembayaran (QRIS, VA, Transfer Bank, E-Wallet).
Quick Start & Kredensial
1 Dapatkan API Credentials
Daftarkan akun dan selesaikan verifikasi KYC. Selanjutnya buat API Client dari dashboard merchant pada menu
API Integration
untuk memperoleh client_id dan client_secret.
2 Base URL
https://merchant.jualpulsaaja.com/api/v1
Semua request wajib melalui protokol HTTPS yang aman.
3 Autentikasi Bearer Token
Gunakan skema Bearer token pada header request:
Authorization: Bearer {client_id}:{client_secret}
Format: string Bearer diikuti spasi dan kombinasi client_id:client_secret.
Karakter yang diizinkan hanya A-Z a-z 0-9 _ -. Format lain akan ditolak dengan error 401 invalid_authorization_header.
4 Content-Type
Content-Type: application/json
5 Idempotency Key (Wajib untuk Transaksi Mutasi) FITUR AMAN
Untuk endpoint yang membuat atau memicu mutasi transaksi (seperti QRIS, VA, Transfer, E-Wallet), kirim header X-Idempotency-Key dengan nilai unik per nomor order.
Jika terjadi koneksi putus atau retry, server menjamin tidak akan terjadi double transaksi.
X-Idempotency-Key: INV-2026-0908-0001
• Kunci maksimal 128 karakter, karakter valid: A-Z a-z 0-9 : _ - .
• Kunci sama dengan isi body request berbeda ditolak dengan status 409 idempotency_key_conflict.
• Dua request duplikat serentak (concurrent) ditolak 409 idempotency_key_in_progress.
• Respons replay otomatis menyertakan header X-Idempotency-Replay: true.
• Kunci berlaku selama 24 jam dan terisolasi per client merchant.
Inbound Payments (Menerima Pembayaran)
Kanal pembayaran masuk untuk menerima dana dari pelanggan Anda secara otomatis.
/api/v1/qris
Generate QRIS dinamis untuk invoice atau pesanan tertentu. Customer cukup memindai gambar QR code dari aplikasi mobile banking atau e-wallet apa pun di Indonesia. Rate limit: 60 request/menit per alamat IP.
{
"amount": 50000,
"customer_name": "Nama Customer",
"customer_email": "customer@email.com",
"customer_phone": "08123456789",
"description": "Pembayaran invoice #001"
}
amount— Wajib, integer positif, minimal Rp 10.000.customer_name— Opsional, nama pelanggan, max 100 karakter.customer_email— Opsional, alamat email valid pelanggan.customer_phone— Opsional, nomor telepon aktif (format 08xx / 628xx).description— Opsional, deskripsi atau catatan invoice, max 200 karakter.
{
"ok": true,
"transaction": {
"id": 42,
"partner_reff": "QR-17817279850470051400",
"amount": 50000,
"status": "waiting_payment",
"expires_at": "2026-09-08T06:00:00+07:00"
},
"qris": {
"qr_image_url": "https://api.qrserver.com/v1/create-qr-code/?...",
"qr_string": "00020101021126620014ID.LINKQU...",
"qris_id": "QRIS123456"
},
"fees": {
"linkqu_fee": 700,
"platform_fee": 300,
"total_fee": 1000,
"net_amount": 49000
}
}
Masa berlaku QRIS dinamis adalah 30 menit. Saat dana dibayarkan, webhook otomatis memicu event transaction.paid dan saldo merchant bertambah seketika.
/api/v1/virtual-accounts
Buat atau ambil Virtual Account permanen untuk merchant per kode bank. Jika VA untuk bank tersebut sudah ada, sistem mengembalikan data VA yang telah ada (status 200). Jika baru dibuat, berstatus 201.
Kode bank yang didukung untuk dedicated VA saat ini: 002 (BRI) dan 013 (Permata).
{
"bank_code": "002"
}
{
"ok": true,
"virtual_account": {
"id": 1,
"bank_code": "002",
"bank_name": "BRI",
"virtual_account_number": "1234567890123456",
"account_name": "Merchant Jual Pulsa Aja",
"status": "active",
"created_at": "2026-06-18T10:00:00+00:00"
}
}
/api/v1/payments/va
Buat Virtual Account sekali-pakai dengan jumlah nominal dan masa aktif khusus untuk setiap invoice belanja customer. Customer mentransfer nominal pas ke nomor VA tersebut sebelum masa aktif berakhir.
{
"amount": 100000,
"bank_code": "002",
"customer_name": "Budi Santoso",
"customer_email": "budi@example.com",
"customer_phone": "081234567890",
"expires_in_hours": 24,
"description": "Order #INV-2026-0001"
}
{
"ok": true,
"payment": {
"partner_reff": "VA-6A41CFBBA9E1A-49d6",
"amount": 100000,
"status": "waiting_payment",
"bank_code": "002",
"bank_name": "BANK BRI",
"virtual_account_number": "1456195200000009",
"account_name": "Budi Santoso",
"expires_at": "2026-09-09T08:53:31+07:00"
},
"fees": {
"linkqu_fee": 2000,
"platform_fee": 0,
"total_fee": 2000,
"net_amount": 98000
}
}
/api/v1/payments/va/banks
Dapatkan daftar bank yang telah diverifikasi aktif menerima One-Time VA di jaringan kami.
{
"ok": true,
"banks": [
{ "code": "002", "name": "BRI", "method": "va" },
{ "code": "022", "name": "CIMB Niaga", "method": "va" },
{ "code": "013", "name": "Permata", "method": "va" }
]
}
/api/v1/payments/va/{partner_reff}
Cek status pembayaran VA secara langsung menggunakan nomor referensi transaksi.
{
"ok": true,
"payment": {
"partner_reff": "VA-6A41CFBBA9E1A-49d6",
"amount": 100000,
"status": "paid",
"bank_code": "002",
"bank_name": "BANK BRI",
"virtual_account_number": "1456195200000009",
"account_name": "Budi Santoso",
"expires_at": "2026-09-09T08:53:31+07:00",
"paid_at": "2026-09-08T09:12:44+07:00"
},
"fees": {
"linkqu_fee": 2000,
"platform_fee": 0,
"total_fee": 2000,
"net_amount": 98000
}
}
E-Wallet Cash-In (Terima Dana dari DANA, OVO, ShopeePay)
Portal DashboardDisbursement / Payout (Pengiriman Dana)
Kirim dana ke rekening bank atau saldo e-wallet mitra/customer secara otomatis.
/api/v1/transfer/inquiry
Cek validitas nomor rekening tujuan dan dapatkan nama resmi pemilik rekening dari bank sebelum dana dikirim. Membutuhkan status merchant KYC terverifikasi.
{
"amount": 100000,
"bank_code": "014",
"account_number": "1234567890"
}
{
"ok": true,
"transaction": {
"id": 43,
"partner_reff": "TRF-ABC123",
"amount": 100000,
"status": "pending",
"bank_code": "014",
"bank_name": "BCA",
"account_number": "1234567890",
"account_name": "BUDI SANTOSO"
},
"fees": {
"linkqu_fee": 2000,
"platform_fee": 500,
"total_fee": 2500,
"net_amount": 97500,
"total_debit": 102500
}
}
/api/v1/transfer/confirm
Eksekusi transfer ke bank tujuan menggunakan PIN transaksi 6 digit. Saldo merchant di-hold (reservasi) secara aman sebelum request diteruskan ke provider.
{
"partner_reff": "TRF-ABC123",
"pin": "123456"
}
{
"ok": true,
"transaction": {
"partner_reff": "TRF-ABC123",
"status": "paid",
"amount": 100000
}
}
Catatan: Jika transfer membutuhkan verifikasi kliring, response dapat mengembalikan status pending. Notifikasi final akan diteruskan ke webhook callback Anda saat dana mendarat di rekening penerima.
/api/v1/transfer/banks
Daftar bank tujuan transfer yang didukung sistem (140+ bank komersial & BPD di Indonesia).
{
"ok": true,
"data": [
{"code": "008", "name": "BANK MANDIRI"},
{"code": "014", "name": "BANK BCA"},
{"code": "002", "name": "BANK BRI"},
{"code": "009", "name": "BANK BNI"}
]
}
/api/v1/ewallet/inquiry
Inquiry pengiriman saldo ke e-wallet (DANA, OVO, GoPay, ShopeePay, LinkAja). Memvalidasi nomor handphone penerima dan kalkulasi biaya transaksi.
{
"amount": 50000,
"product_code": "DANA",
"phone_number": "08123456789"
}
{
"ok": true,
"transaction": {
"id": 44,
"partner_reff": "EW-ABC123",
"amount": 50000,
"status": "pending",
"product_code": "DANA",
"phone_number": "08123456789"
},
"fees": {
"linkqu_fee": 700,
"platform_fee": 300,
"total_fee": 1000,
"net_amount": 49000
}
}
/api/v1/ewallet/confirm
Konfirmasi eksekusi isi saldo e-wallet dengan PIN keamanan transaksi merchant. Saldo merchant direservasi sebelum diproses ke provider gateway.
{
"partner_reff": "EW-ABC123",
"pin": "123456"
}
{
"ok": true,
"transaction": {
"partner_reff": "EW-ABC123",
"status": "paid",
"amount": 50000
}
}
/api/v1/ewallet/products
Daftar kanal e-wallet yang aktif menerima top-up.
{
"ok": true,
"data": [
{"code": "DANA", "name": "DANA", "category": "e-wallet"},
{"code": "OVO", "name": "OVO", "category": "e-wallet"},
{"code": "GOPAY", "name": "GoPay", "category": "e-wallet"},
{"code": "SHOPEEPAY", "name": "ShopeePay", "category": "e-wallet"},
{"code": "LINKAJA", "name": "LinkAja", "category": "e-wallet"}
]
}
Transaksi & Audit Log
Endpoint untuk pelaporan, rekonsiliasi data, dan audit trail pergerakan saldo.
/api/v1/transactions
Ambil daftar transaksi merchant dengan pagination.
per_page— Jumlah data per halaman (default 20, max 100).page— Nomor halaman pagination.
{
"ok": true,
"data": [
{
"partner_reff": "QR-17817279850470051400",
"type": "qris",
"status": "paid",
"amount": 50000,
"total_fee": 500,
"net_amount": 49500,
"created_at": "2026-09-08T10:00:00+07:00"
}
],
"meta": {
"current_page": 1,
"last_page": 5,
"total": 100
}
}
/api/v1/transactions/{partner_reff}
Ambil detail transaksi berdasarkan partner_reff lengkap dengan log riwayat event status.
{
"ok": true,
"transaction": {
"partner_reff": "QR-17817279850470051400",
"type": "qris",
"status": "paid",
"amount": 50000,
"paid_at": "2026-09-08T10:05:00+07:00",
"expires_at": "2026-09-08T10:30:00+07:00",
"created_at": "2026-09-08T10:00:00+07:00"
},
"fees": {
"linkqu_fee": 350,
"platform_fee": 150,
"total_fee": 500,
"net_amount": 49500
},
"events": [
{
"event_type": "created",
"from": null,
"to": "created",
"source": "api",
"description": "QRIS created via API",
"at": "2026-09-08T10:00:00+07:00"
},
{
"event_type": "callback_received",
"from": "waiting_payment",
"to": "paid",
"source": "linkqu_callback",
"description": "Payment received via LinkQu callback",
"at": "2026-09-08T10:05:00+07:00"
}
]
}
Webhook & Notifikasi Callback
Sistem kami mengirim POST HTTP JSON real-time ke URL endpoint server Anda saat terjadi perubahan status transaksi.
Konsep & Delivery Webhook
Setiap kali transaksi Anda berubah status menjadi paid, expired, atau failed, engine webhook kami secara asinkron akan menembak URL callback yang Anda pasang di menu API Integration.
Content-Type: application/json Accept: application/json User-Agent: MerchantJualPulsaAja-Webhook/1.0 X-Webhook-Event: transaction.paid X-Webhook-Delivery: 1042 X-Webhook-Signature: <hmac-sha256-signature>
{
"event": "transaction.paid",
"partner_reff": "17828138963880051406",
"transaction": {
"partner_reff": "17828138963880051406",
"type": "qris",
"status": "paid",
"amount": 10000,
"fees": {
"linkqu_fee": 70,
"platform_fee": 30,
"total_fee": 100,
"net_amount": 9900
},
"paid_at": "2026-09-08T17:35:05+07:00",
"created_at": "2026-09-08T17:04:56+07:00"
}
}
- Response yang diharapkan: Server Anda wajib mengembalikan HTTP 2xx (200 / 201 / 204). HTTP 4xx, 5xx, timeout (>30 detik), atau redirect akan dianggap gagal.
- Redirect dilarang: URL callback harus merespons langsung tanpa 301/302.
- SSL Valid: Endpoint wajib menggunakan HTTPS dengan sertifikat SSL terpercaya.
Verifikasi & Signature Webhook
Header X-Webhook-Signature dikirimkan untuk validasi integritas payload. Untuk keamanan ekstra, server Anda juga disarankan melakukan verifikasi silang (cross-check) ke endpoint GET /api/v1/transactions/{partner_reff} sebelum meng-update status pesanan atau saldo pengguna akhir Anda.
Webhook Debugger & Ping Simulator
Anda dapat menguji endpoint callback server Anda secara langsung tanpa perlu menunggu pembayaran sungguhan. Buka menu API Integration → Detail Client di dashboard merchant untuk mengakses:
Kirimkan payload simulasi event webhook.ping untuk memastikan firewall & routing server Anda siap.
Lihat waktu respons HTTP secara presisi dalam milidetik dan respons body yang dikembalikan server Anda.
Jika server Anda sempat down saat transaksi terjadi, cukup klik Kirim Ulang pada tabel riwayat log webhook.
/api/v1/devices
Registrasikan token push notification perangkat (FCM / OneSignal) untuk menerima push notifikasi transaksi.
{
"token": "onesignal_player_id_atau_fcm_token",
"platform": "web",
"app_version": "1.0.0",
"device_name": "Chrome on Windows"
}
Produk Digital (Pulsa, Data, Game, Token, PPOB)
Beli produk digital memakai saldo akun Anda. Butuh izin digital:read (katalog), digital:create (order), digital:ppob (pascabayar). Harga yang tampil adalah harga jual khusus akun Anda.
Katalog Produk GET /api/v1/tv/products
Daftar produk aktif + harga jual Anda. Filter: category, operator, search, per_page, page. Detail produk + field dinamis: GET /api/v1/tv/products/{kode}.
curl -H "Authorization: Bearer CLIENT_ID:CLIENT_SECRET" \
"https://merchant.jualpulsaaja.com/api/v1/tv/products?search=TSEL&per_page=20"
{
"ok": true,
"data": [
{ "kode_produk": "TSEL10", "nama": "Tsel Reguler 10K", "kategori": "Pulsa",
"operator": "Telkomsel", "harga": 10350, "status": "normal", "butuh_server_id": false }
],
"meta": { "page": 1, "per_page": 20, "total": 312 }
}
Buat Order POST /api/v1/tv/orders
Asinkron (202). Wajib header X-Idempotency-Key - kirim ulang dengan key & body sama aman (tidak membuat order ganda). Saldo akun Anda dipotong sebesar harga order. Status dicek via webhook (order.pending/success/failed) atau GET /api/v1/tv/orders/{ref_id}.
curl -X POST https://merchant.jualpulsaaja.com/api/v1/tv/orders \
-H "Authorization: Bearer CLIENT_ID:CLIENT_SECRET" \
-H "Content-Type: application/json" \
-H "X-Idempotency-Key: inv-2026-0001" \
-d '{"ref_id":"INV-2026-0001","kode_produk":"TSEL10","tujuan":"081234567890"}'
{
"ok": true,
"data": { "ref_id": "INV-2026-0001", "tv_order_id": 9012, "status": "pending",
"kode_produk": "TSEL10", "tujuan": "081234567890", "harga": 10350,
"sn": null, "saldo_owner": 500000 }
}
Error penting: insufficient_balance (422), product_inactive (422), invalid_msisdn (422), duplicate_recent_order (409 - order identik dalam 60 detik), rate_limited (429).
PPOB Pascabayar POST /api/v1/tv/ppob/inquiries POST /api/v1/tv/ppob/orders
Cek tagihan dulu (read-only), tampilkan nama pelanggan & jumlahnya, lalu bayar dengan inquiry_id. Pembayaran = order asinkron seperti di atas; sukses dikirim via webhook ppob.paid.
curl -X POST .../api/v1/tv/ppob/inquiries \
-d '{"kode_produk":"PLNPASCH","tujuan":"123456789012"}'
{ "ok": true, "data": { "inquiry_id": 55, "customer_name": "BUDI SANTOSO",
"tagihan": 147500, "admin": 2500, "total": 152500, "due_date": "2026-10-02" } }
curl -X POST .../api/v1/tv/ppob/orders \
-H "X-Idempotency-Key: inv-2026-0002" \
-d '{"ref_id":"INV-2026-0002","inquiry_id":55}'
Saldo Akun GET /api/v1/tv/balance
Saldo akun Anda yang menjadi sumber dana order (satu saldo serbaguna: QRIS/VA/transfer/e-wallet juga memakai saldo yang sama).
{ "ok": true, "data": { "saldo": 500000, "currency": "IDR" } }
Standar, Kamus Status & Keamanan
Kamus kode status transaksi, format respons error, dan batasan rate limit.
Kamus Status Transaksi
created
Transaksi baru selesai dibuat di database sistem.
waiting_payment
Menunggu pembayaran (scan QRIS atau transfer VA) dari customer.
pending
Payout (Transfer Bank / E-Wallet) sedang diproses oleh jaringan perbankan.
paid
Pembayaran berhasil diterima / payout sukses dieksekusi.
settled
Dana telah di-settle ke saldo kas merchant yang dapat ditarik sewaktu-waktu.
failed
Transaksi gagal diproses oleh gateway atau rekening tujuan ditolak.
expired
Masa aktif transaksi telah habis (QRIS 30 menit, VA per waktu yang ditentukan).
Diagram Alur Eksekusi
Alur QRIS & Virtual Account
- Aplikasi merchant panggil API
POST /qrisatauPOST /payments/va. - Sistem membuat QRIS/VA dan mengembalikan URL image / nomor VA.
- Customer melakukan pembayaran sebelum masa kedaluwarsa.
- Gateway mitra memproses dana dan mengirim callback terenkripsi ke kami.
- Saldo kas merchant bertambah otomatis secara real-time.
- Engine kami mengirim webhook
transaction.paidke server merchant.
Alur Payout (Transfer & E-Wallet)
- Aplikasi merchant panggil endpoint
inquirydengan nomor rekening / HP. - Sistem memvalidasi nama pemilik rekening dan mengembalikan fee.
- Merchant panggil
confirmdengan menyertakan PIN transaksi. - Sistem me-reservasi (hold) saldo merchant sebelum eksekusi gateway.
- Jika sukses, status menjadi
paiddan webhook dikirimkan. - Jika gagal, saldo yang direservasi di-rollback seketika ke akun merchant.
Format Respons Error & Envelope
Seluruh respons error menggunakan struktur format envelope JSON seragam. Logika client wajib mengacu pada field mesin error:
{
"ok": false,
"error": "validation",
"message": "Parameter amount minimal 10000"
}
200 / 201 Permintaan berhasil diproses.401 Autentikasi gagal (invalid_authorization_header, invalid_client).403 Akses ditolak (client_not_active, ip_not_allowed, kyc_required).404 Resource transaksi tidak ditemukan (not_found).409 Konflik Idempotency Key (idempotency_key_conflict, idempotency_key_in_progress).422 Validasi data atau bisnis gagal (validation, insufficient_balance, invalid_pin).429 Rate limit terlampaui (maksimal 60 request / menit per IP).502 Kendala sementara dari payment gateway hulu (upstream_error).Keamanan, IP Whitelist & Rate Limiting
Merchant dapat membatasi akses API Client hanya dari alamat IP server backend tertentu. Request dari luar IP whitelist akan ditolak otomatis dengan kode 403.
Sistem memberlakukan kuota 60 request per menit per alamat IP untuk menjaga keandalan infrastruktur finansial dari lonjakan traffic tak wajar.
Matriks Hak Akses (Permissions)
qris:create
Izin untuk men-generate QRIS Dinamis (POST /qris).
qris:read
Izin untuk membaca riwayat dan detail semua transaksi.
va:create
Izin untuk membuat Dedicated VA dan One-Time VA per transaksi.
va:read
Izin untuk membaca data nomor Virtual Account dan status pembayaran VA.
transfer:create
Izin untuk inquiry dan konfirmasi Transfer Bank ke rekening pihak ketiga.
ewallet:create
Izin untuk inquiry dan eksekusi pengiriman saldo E-Wallet.
Arsitektur Tagihan Berulang (Recurring Subscriptions)
Bangun Model Bisnis Langganan Apapun Tanpa Batasan Kaku
Di Indonesia, lebih dari 90% pelanggan tidak memiliki kartu kredit dan lebih memilih membayar tagihan menggunakan Virtual Account (VA) atau QRIS Dinamis. Merchant Jual Pulsa Aja bertindak sebagai Otak Finansial & Infrastruktur Pembayaran Anda. Kami tidak membatasi logika paket langganan Anda dalam tabel database yang kaku — Anda memegang kendali penuh atas data member di server Anda sendiri, sementara API kami menangani pembuatan channel pembayaran, deteksi pelunasan real-time, dan webhook callback secara otonom.
- ✓ Software as a Service (SaaS)
- ✓ Tagihan ISP / RT-RW Net
- ✓ SPP Kursus / Sekolah
- ✓ Membership Komunitas
- ✓ Donasi & Infaq Rutin
Diagram Siklus Tagihan Berulang
Bagaimana cron job server Anda berkomunikasi secara harmonis dengan API kami dan pelanggan akhir.
Scheduler di server Anda mendeteksi pelanggan yang jatuh tempo hari ini (next_billing_date <= today).
Request QRIS dinamis (POST /qris) atau gunakan nomor VA Dedicated pelanggan yang sudah terdaftar.
Kirim tagihan via WhatsApp/Email. Pelanggan scan QRIS atau transfer via mobile banking ke nomor Virtual Account.
Kami kirim Webhook real-time. Server Anda memajukan masa aktif langganan (+1 bulan) secara otomatis.
1 Customer = 1 Nomor VA Tetap Selamanya
Saat customer pertama kali mendaftar di sistem Anda, panggil endpoint POST /api/v1/virtual-accounts untuk membuatkan nomor VA khusus (misal BRI atau Permata).
• Sangat Praktis: Pelanggan menyimpan nomor VA di daftar transfer favorit m-Banking mereka.
• Tanpa Generate Berulang: Server Anda tidak perlu menembak API tiap bulan untuk membuat invoice baru.
• Deteksi Instan: Tiap kali dana masuk ke nomor VA tersebut, webhook va.paid ditembakkan ke URL Anda.
Invoice Dinamis Tiap Siklus Tagihan
Scheduler server Anda berjalan tiap tanggal tagihan (misal H-3 sebelum jatuh tempo). Server Anda menembak POST /api/v1/qris atau POST /api/v1/payments/va dengan nominal tagihan siklus tersebut.
• Nominal Fleksibel: Cocok jika tagihan bulanan pelanggan bervariasi (misal tagihan pulsa pascabayar atau pemakaian kuota server).
• Multi-Channel: Pelanggan bisa memilih apakah ingin bayar via QRIS atau VA BCA/Mandiri/BNI.
• Auto-Expiry: Nomor tagihan otomatis hangus jika tidak dibayar melewati masa tenggang.
Contoh Implementasi (Code Recipes)
Skrip yang dapat langsung Anda implementasikan di aplikasi/server backend Anda.
<?php
// Contoh Artisan Command: app/Console/Commands/ProcessRecurringSubscriptions.php
use App\Models\Subscription;
use Illuminate\Support\Facades\Http;
public function handle()
{
// 1. Cari pelanggan yang jatuh tempo tagihan hari ini
$dueSubscriptions = Subscription::where('status', 'active')
->whereDate('next_billing_date', '<=', today())
->get();
foreach ($dueSubscriptions as $sub) {
$partnerReff = "REC-{$sub->id}-" . date('Ym'); // Unik per siklus bulan ini
// 2. Request QRIS Dinamis ke Merchant Jual Pulsa Aja API
$response = Http::withHeaders([
'Authorization' => 'Bearer ' . env('MJPA_CLIENT_ID') . ':' . env('MJPA_CLIENT_SECRET'),
'X-Idempotency-Key' => $partnerReff,
'Content-Type' => 'application/json',
])->post('https://merchant.jualpulsaaja.com/api/v1/qris', [
'amount' => (int) $sub->plan_price,
'partner_reff' => $partnerReff,
'customer_name' => $sub->customer_name,
'customer_email' => $sub->customer_email,
'customer_phone' => $sub->customer_phone,
'expires_in' => 86400 * 3, // Masa tenggang pembayaran 3 hari
]);
if ($response->successful()) {
$qrisData = $response->json('qris');
// 3. Kirimkan QRIS string atau Link Bayar ke WhatsApp / Email pelanggan Anda
$this->sendInvoiceNotification($sub, $qrisData['qr_string'], $partnerReff);
}
}
}
<?php
// Contoh Controller: app/Http/Controllers/PaymentWebhookController.php
use App\Models\Subscription;
use Illuminate\Http\Request;
use Carbon\Carbon;
public function handleWebhook(Request $request)
{
// 1. Verifikasi Signature HMAC-SHA256
$signature = $request->header('X-Webhook-Signature');
$calculated = hash_hmac('sha256', $request->getContent(), env('MJPA_CLIENT_SECRET'));
if (!hash_equals($signature, $calculated)) {
return response()->json(['error' => 'Invalid signature'], 401);
}
$event = $request->input('event');
$payload = $request->input('data');
// 2. Tangani pelunasan transaksi
if ($event === 'transaction.paid' || $event === 'va.paid') {
$partnerReff = $payload['partner_reff']; // Misal: REC-145-202609
if (preg_match('/REC-(\d+)-/', $partnerReff, $matches)) {
$subId = $matches[1];
$subscription = Subscription::find($subId);
if ($subscription) {
// 3. Majukan tanggal tagihan berikutnya ke 1 bulan ke depan
$subscription->update([
'status' => 'active',
'next_billing_date' => Carbon::parse($subscription->next_billing_date)->addMonth(),
'last_paid_at' => now(),
]);
// 4. Perpanjang akses layanan atau fitur member di sistem Anda!
$this->activateCustomerService($subscription);
}
}
}
return response()->json(['ok' => true]);
}
Checklist Praktik Terbaik (Best Practices)
SUB-{USER_ID}-{TAHUN_BULAN}. Ini memudahkan rekonsiliasi tanpa perlu query pencarian yang lambat.
X-Idempotency-Key yang sama dengan partner reff agar jika server Anda me-retry cron job, tidak akan terbit invoice ganda.
X-Webhook-Signature HMAC-SHA256 untuk memastikan bahwa notifikasi pembayaran benar-benar berasal dari sistem resmi kami.
Catatan Pembaruan (API Changelog)
- API Produk Digital (Isi Ulang) — endpoint baru:
GET /api/v1/tv/products(+detail per kode),POST /api/v1/tv/orders,GET /api/v1/tv/orders/{ref_id},POST /api/v1/tv/ppob/inquiries,POST /api/v1/tv/ppob/orders,GET /api/v1/tv/balance. - Izin per akun klien:
digital:read,digital:create,digital:ppob. - Harga jual khusus per akun — aturan harga berlingkup “Klien API” menentukan harga yang tampil di katalog dan yang ditagih ke akun Anda.
- Webhook status otomatis — peristiwa
order.pending,order.success,order.failed, danppob.paid. Kirim ulang order denganX-Idempotency-Keyyang sama tidak membuat order ganda. - Uji nyata lolos: pembelian produk digital pertama (token PLN) berhasil, nomor transaksi & SN diterima dari penyedia.
Arsitektur lengkap untuk 6 pilar inovasi platform telah disetujui (blueprint: doc/plans/2026-09-08-platform-expansion-and-security-roadmap.md) dan sedang disiapkan untuk implementasi bertahap:
Integrasi transaksi otonom AI (Hermes / Claude) berbasis Draft + Human 2FA Approval tanpa membocorkan PIN transaksi.
Mesin proteksi velocity threshold, blacklist rekening penipuan, dan deteksi lonjakan anomali otomatis.
Otomasi penagihan langganan (SaaS, pulsa rutin, wifi) dengan scheduler harian dan webhook siklus.
Dukungan multi-bahasa (ID/EN) di portal publik/docs serta portal artikel dan pengumuman resmi.
Dukungan Multi-Bahasa Publik (i18n): Halaman publik (Beranda, Tentang Kami, Kontak, Ketentuan Layanan, Kebijakan Privasi, dan Portal Blog) kini dilengkapi sistem dwibahasa (Bahasa Indonesia & English) dengan language switcher instan dan persistensi sesi.
Blueprint Tagihan Berulang (Recurring Billing): Panduan arsitektur penagihan langganan otomatis berbasis Virtual Account permanen dan scheduler faktur dinamis lengkap dengan resep kode Artisan Command dan webhook handler.
Anti-Pencucian Uang & Fraud Risk Engine: Mesin proteksi penarikan saldo, pencegahan velocity bot beruntun, serta blacklist rekening tujuan penipuan terintegrasi pada panel pengawasan internal.
Webhook Debugger & Ping Simulator: Merchant dapat melakukan simulasi pengiriman webhook live dari dashboard (/api-clients/{id}) dengan pengukuran latency HTTP (ms), pratinjau respons header/body, dan tombol Kirim Ulang (Resend) mandiri untuk webhook yang gagal.
Ekspor Transaksi CSV & Filter Waktu: Fitur ekspor mutasi transaksi merchant dalam format CSV berstandar UTF-8 BOM untuk rekonsiliasi Microsoft Excel dengan filter periode instan (Hari Ini, Kemarin, 7 Hari Terakhir, 30 Hari Terakhir).
E-Wallet Cash-In Numeric Reff: Standardisasi penomoran partner_reff khusus numerik untuk pemenuhan kepatuhan gateway core banking perbankan.
Navigasi Dokumentasi Sticky Sidebar: Pembaruan layout dokumentasi API dengan sidebar menu berstruktur, filter pencarian instan, deep-linking presisi, dan drawer cepat untuk pengguna mobile.
One-Time Virtual Account (VA per-transaksi): Peluncuran endpoint POST /api/v1/payments/va untuk menghasilkan nomor VA khusus sekali pakai dengan nominal pasti dan waktu kadaluarsa otomatis.
Diagnostic Bank One-Time VA: Endpoint GET /api/v1/payments/va/banks yang mencerminkan kapabilitas live real-time pada akun payment gateway Bank Indonesia.
Idempotency Key Protocol: Pengenalan header X-Idempotency-Key untuk mencegah double request pada endpoint pembuatan QRIS, VA, dan payout. Dilengkapi deteksi replay X-Idempotency-Replay: true.
Rilis OpenAPI 3.0 Machine-Readable Spec: Spesifikasi terstruktur publik tersedia di /openapi.json untuk integrasi cepat SDK, Postman, dan AI coding agents.
Disbursement Payout Engine: Penambahan endpoint Transfer Bank (140+ bank) dan E-Wallet Top-up (DANA, OVO, GoPay, ShopeePay, LinkAja) dengan mekanisme Inquiry & Confirm berbasis PIN otorisasi.
Balance Pre-Debit Reservation: Saldo merchant di-hold sebelum eksekusi ke pihak ketiga dan di-rollback instan jika payout gagal.
Peluncuran REST API Perdana: Pembuatan QRIS Dinamis (POST /api/v1/qris), Virtual Account tetap BRI & Permata, pengiriman Webhook Real-time, dan autentikasi Bearer berbasis client_id:client_secret.
Butuh Bantuan Integrasi Teknis?
Tim teknis dan support payment gateway kami siap membantu proses integrasi sistem Anda sampai live produksi tanpa kendala.