Merchant Jual Pulsa Aja
Jual Pulsa Aja Merchant
Payment Operations
Cara Kerja Fitur Simulasi Pembayaran (Demo) Kalkulator Biaya Biaya Transaksi API Developer Hub Dokumentasi API Blog & Pengumuman FAQ
REST API v1.4.0 — Production Ready & Sandbox

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).

API Status: Beroperasi Normal (SLA 99.9%)
Semua gateway pembayaran & antrean webhook aktif.
v1.4.0

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.

Bagian 1

Inbound Payments (Menerima Pembayaran)

Kanal pembayaran masuk untuk menerima dana dari pelanggan Anda secara otomatis.

POST /api/v1/qris
QRIS Dinamis

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.

Request Body (JSON):
{
  "amount": 50000,
  "customer_name": "Nama Customer",
  "customer_email": "customer@email.com",
  "customer_phone": "08123456789",
  "description": "Pembayaran invoice #001"
}
Ketentuan Parameter:
  • 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.
Response Sukses (HTTP 201 Created):
{
  "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.

POST /api/v1/virtual-accounts
Dedicated VA (Tetap)

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).

Request Body:
{
  "bank_code": "002"
}
Response (200 / 201):
{
  "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"
  }
}
POST /api/v1/payments/va
One-Time VA (Per-Transaksi)

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.

Request Body:
{
  "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"
}
Response Sukses (HTTP 201 Created):
{
  "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
  }
}
GET /api/v1/payments/va/banks
Bank VA Aktif

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" }
  ]
}
GET /api/v1/payments/va/{partner_reff}
Polling Status VA

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 Dashboard
Fitur E-Wallet Cash-In (menerima pembayaran langsung dari saldo e-wallet customer) saat ini dapat dibuat melalui dashboard merchant pada menu E-Wallet Cash-In. Integrasi direct API sedang dalam tahap sertifikasi Bank Indonesia.
Bagian 2

Disbursement / Payout (Pengiriman Dana)

Kirim dana ke rekening bank atau saldo e-wallet mitra/customer secara otomatis.

POST /api/v1/transfer/inquiry
Inquiry Rekening Bank

Cek validitas nomor rekening tujuan dan dapatkan nama resmi pemilik rekening dari bank sebelum dana dikirim. Membutuhkan status merchant KYC terverifikasi.

Request Body:
{
  "amount": 100000,
  "bank_code": "014",
  "account_number": "1234567890"
}
Response (HTTP 200):
{
  "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
  }
}
POST /api/v1/transfer/confirm
Konfirmasi Eksekusi Bank

Eksekusi transfer ke bank tujuan menggunakan PIN transaksi 6 digit. Saldo merchant di-hold (reservasi) secara aman sebelum request diteruskan ke provider.

Request Body:
{
  "partner_reff": "TRF-ABC123",
  "pin": "123456"
}
Response Sukses (HTTP 200):
{
  "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.

GET /api/v1/transfer/banks
Katalog Bank

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"}
  ]
}
POST /api/v1/ewallet/inquiry
Inquiry E-Wallet Top-up

Inquiry pengiriman saldo ke e-wallet (DANA, OVO, GoPay, ShopeePay, LinkAja). Memvalidasi nomor handphone penerima dan kalkulasi biaya transaksi.

Request Body:
{
  "amount": 50000,
  "product_code": "DANA",
  "phone_number": "08123456789"
}
Response (HTTP 200):
{
  "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
  }
}
POST /api/v1/ewallet/confirm
Konfirmasi E-Wallet

Konfirmasi eksekusi isi saldo e-wallet dengan PIN keamanan transaksi merchant. Saldo merchant direservasi sebelum diproses ke provider gateway.

Request Body:
{
  "partner_reff": "EW-ABC123",
  "pin": "123456"
}
Response Sukses (HTTP 200):
{
  "ok": true,
  "transaction": {
    "partner_reff": "EW-ABC123",
    "status": "paid",
    "amount": 50000
  }
}
GET /api/v1/ewallet/products
Produk E-Wallet

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"}
  ]
}
Bagian 3

Transaksi & Audit Log

Endpoint untuk pelaporan, rekonsiliasi data, dan audit trail pergerakan saldo.

GET /api/v1/transactions
Daftar Transaksi

Ambil daftar transaksi merchant dengan pagination.

Query Parameters:
  • 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
  }
}
GET /api/v1/transactions/{partner_reff}
Detail & Audit Trail

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"
    }
  ]
}
Bagian 4

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.

Headers yang Dikirim ke Server Anda:
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>
Contoh Payload Body (event: transaction.paid):
{
  "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"
  }
}
Spesifikasi Delivery Server:
  • 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.

Fitur Developer v1.4.0

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:

Uji Probe Ping Instan

Kirimkan payload simulasi event webhook.ping untuk memastikan firewall & routing server Anda siap.

Pengukuran Latency (ms)

Lihat waktu respons HTTP secara presisi dalam milidetik dan respons body yang dikembalikan server Anda.

Resend Webhook Mandiri

Jika server Anda sempat down saat transaksi terjadi, cukup klik Kirim Ulang pada tabel riwayat log webhook.

Tabel riwayat log webhook merekam 15 pengiriman terakhir lengkap dengan status HTTP, latency, dan timestamp pengiriman.
POST /api/v1/devices
Push Notification

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

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" } }
Bagian 5

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

  1. Aplikasi merchant panggil API POST /qris atau POST /payments/va.
  2. Sistem membuat QRIS/VA dan mengembalikan URL image / nomor VA.
  3. Customer melakukan pembayaran sebelum masa kedaluwarsa.
  4. Gateway mitra memproses dana dan mengirim callback terenkripsi ke kami.
  5. Saldo kas merchant bertambah otomatis secara real-time.
  6. Engine kami mengirim webhook transaction.paid ke server merchant.

Alur Payout (Transfer & E-Wallet)

  1. Aplikasi merchant panggil endpoint inquiry dengan nomor rekening / HP.
  2. Sistem memvalidasi nama pemilik rekening dan mengembalikan fee.
  3. Merchant panggil confirm dengan menyertakan PIN transaksi.
  4. Sistem me-reservasi (hold) saldo merchant sebelum eksekusi gateway.
  5. Jika sukses, status menjadi paid dan webhook dikirimkan.
  6. 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"
}
Daftar Kode HTTP Status:
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

IP Whitelist Proteksi

Merchant dapat membatasi akses API Client hanya dari alamat IP server backend tertentu. Request dari luar IP whitelist akan ditolak otomatis dengan kode 403.

Rate Limiting (60 req/min)

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.
Pola Integrasi Khusus

Arsitektur Tagihan Berulang (Recurring Subscriptions)

Developer Guide
FILOSOFI: PUSH-PAYMENT RECURRING INFRASTRUCTURE

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.

Cocok Untuk:
  • ✓ 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.

LANGKAH 1
Server Merchant (Cron Job)

Scheduler di server Anda mendeteksi pelanggan yang jatuh tempo hari ini (next_billing_date <= today).

LANGKAH 2
Panggil API Pembayaran

Request QRIS dinamis (POST /qris) atau gunakan nomor VA Dedicated pelanggan yang sudah terdaftar.

LANGKAH 3
Pelanggan Bayar

Kirim tagihan via WhatsApp/Email. Pelanggan scan QRIS atau transfer via mobile banking ke nomor Virtual Account.

LANGKAH 4
Webhook & Perpanjangan

Kami kirim Webhook real-time. Server Anda memajukan masa aktif langganan (+1 bulan) secara otomatis.

POLA A (PALING DIREKOMENDASIKAN) Dedicated Permanent VA

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).

Keunggulan Pola Ini:

• 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.

POLA B (TAGIHAN DINAMIS) QRIS / One-Time VA

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.

Keunggulan Pola Ini:

• 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.

Jalankan skrip ini setiap hari via Cron Job (misal jam 00:05 tengah malam) di server 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);
        }
    }
}
Controller di server Anda yang menerima webhook saat pelanggan berhasil melunasi tagihan:
<?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)

1. Format Partner Reff Terstruktur
Gunakan format yang mengkodekan ID langganan dan siklus bulan, misal SUB-{USER_ID}-{TAHUN_BULAN}. Ini memudahkan rekonsiliasi tanpa perlu query pencarian yang lambat.
2. Pasang Idempotency Key
Selalu sertakan header X-Idempotency-Key yang sama dengan partner reff agar jika server Anda me-retry cron job, tidak akan terbit invoice ganda.
3. Masa Tenggang (Grace Period)
Beri pelanggan toleransi waktu 3 s/d 5 hari setelah tanggal jatuh tempo sebelum menangguhkan (*suspend*) akun mereka secara otomatis.
4. Verifikasi Signature Webhook
Wajib lakukan validasi X-Webhook-Signature HMAC-SHA256 untuk memastikan bahwa notifikasi pembayaran benar-benar berasal dari sistem resmi kami.
Riwayat Rilis

Catatan Pembaruan (API Changelog)

Diperbarui: 27 September 2026
v1.5.0 Dirilis
• 27 September 2026
  • 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, dan ppob.paid. Kirim ulang order dengan X-Idempotency-Key yang sama tidak membuat order ganda.
  • Uji nyata lolos: pembelian produk digital pertama (token PLN) berhasil, nomor transaksi & SN diterima dari penyedia.
Roadmap v1.6.0 Dalam Perancangan
Target: Q4 2026

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:

AI Agentic Payments (Aman)

Integrasi transaksi otonom AI (Hermes / Claude) berbasis Draft + Human 2FA Approval tanpa membocorkan PIN transaksi.

Anti-Pencucian Uang (AML)

Mesin proteksi velocity threshold, blacklist rekening penipuan, dan deteksi lonjakan anomali otomatis.

Tagihan Berulang (Recurring)

Otomasi penagihan langganan (SaaS, pulsa rutin, wifi) dengan scheduler harian dan webhook siklus.

Bilingual & CMS Blog

Dukungan multi-bahasa (ID/EN) di portal publik/docs serta portal artikel dan pengumuman resmi.

Rilis Terkini
v1.4.0 • 8 September 2026
Fitur Baru

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.

Solusi Baru

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.

Keamanan

Anti-Pencucian Uang & Fraud Risk Engine: Mesin proteksi penarikan saldo, pencegahan velocity bot beruntun, serta blacklist rekening tujuan penipuan terintegrasi pada panel pengawasan internal.

Fitur Baru

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.

Fitur Baru

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).

Peningkatan

E-Wallet Cash-In Numeric Reff: Standardisasi penomoran partner_reff khusus numerik untuk pemenuhan kepatuhan gateway core banking perbankan.

Desain UI

Navigasi Dokumentasi Sticky Sidebar: Pembaruan layout dokumentasi API dengan sidebar menu berstruktur, filter pencarian instan, deep-linking presisi, dan drawer cepat untuk pengguna mobile.

v1.3.0 • 15 Juli 2026
Fitur Baru

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.

Peningkatan

Diagnostic Bank One-Time VA: Endpoint GET /api/v1/payments/va/banks yang mencerminkan kapabilitas live real-time pada akun payment gateway Bank Indonesia.

v1.2.0 • 18 Juni 2026
Keamanan

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.

Integrasi

Rilis OpenAPI 3.0 Machine-Readable Spec: Spesifikasi terstruktur publik tersedia di /openapi.json untuk integrasi cepat SDK, Postman, dan AI coding agents.

v1.1.0 • 20 Mei 2026
Fitur Baru

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.

Keamanan

Balance Pre-Debit Reservation: Saldo merchant di-hold sebelum eksekusi ke pihak ketiga dan di-rollback instan jika payout gagal.

v1.0.0 • 10 April 2026
Rilis Awal

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.

Butuh bantuan? Chat kami