Dokumentasi Integrasi

acuan integrasi API dan webhook

Referensi publik untuk akun, project, invoice QRIS, transaksi, webhook, laporan, dan penarikan.

1. Alur akun

  1. Daftar atau masuk melalui /login memakai Google atau email dengan kode sekali pakai. Email yang belum terdaftar langsung dibuatkan akun dengan peran USER.
  2. Lengkapi KYC sebelum membuat project produksi atau mengajukan penarikan.
  3. Buat project. Project baru berstatus menunggu persetujuan admin, tetapi token dan halaman bayarnya SUDAH aktif — pembayaran bisa masuk sejak awal.
  4. Gunakan slug, API key, webhook URL, dan webhook secret milik project tersebut. Yang belum bisa dilakukan selama pengajuan belum disetujui adalah menarik saldo project itu.

2. Penarikan saldo

  1. Pengajuan penarikan memakai rekening pencairan dari data KYC yang telah disetujui.
  2. Dana ditahan dari saldo saat pengajuan, sehingga saldo yang tampil selalu mencerminkan dana yang dapat ditarik.
  3. Admin menandai PAID setelah transfer, atau REJECTED sehingga dana kembali ke saldo.
  4. Penarikan otomatis tunduk pada batas minimum, saldo, status KYC, rekening, dan antrean penarikan yang masih menunggu.

3. Ikhtisar integrasi

Project
identitas aplikasi klien. Setiap aplikasi memakai project tersendiri.
Kredensial
slug dan api_key dipakai pada setiap permintaan API; webhook_secret dipakai untuk memverifikasi webhook.
Metode
pembayaran memakai QRIS. Nominal yang dibayar pelanggan adalah total_payment, bukan amount.
Pencocokan
pembayaran dicocokkan otomatis berdasarkan nominal total dan order_id.

4. URL halaman pembayaran

/pay/{slug}/{amount}?order_id={order_id}
slug
slug project yang sudah disetujui.
amount
nominal dasar invoice, tanpa kode unik.
order_id
ID order unik milik merchant; menjadi kunci idempotensi.
redirect
tujuan setelah pembayaran; hanya URL internal atau URL yang diizinkan.
qris_only
isi 1 untuk memaksa tampilan QRIS saja.

5. Membuat transaksi

POST /api/transactioncreate/{method} dengan method qris.

Permintaan

curl -L '/api/transactioncreate/qris' \ -H 'Content-Type: application/json' \ -d '{ "project": "<slug>", "order_id": "INV123123", "amount": 99000, "api_key": "<API_KEY>" }'

Jawaban

{ "payment": { "project": "<slug>", "order_id": "INV123123", "amount": 99000, "fee": 0, "total_payment": 99187, "payment_method": "qris", "payment_number": "00020101021226…6304ABCD", "expired_at": "2026-09-16T04:30:00.000Z", "qr_data_url": "data:image/png;base64,iVBORw0KGgo…", "payment_url": "/pay/<slug>/99000?order_id=INV123123&qris_only=1", "status": "pending" } }

Ketentuan

  • Arahkan pelanggan ke payment_url.
  • Pelanggan membayar total_payment, bukan amount.
  • Invoice memiliki masa berlaku expired_at.

6. Detail transaksi

GET /api/transactiondetail?project=…&amount=…&order_id=…&api_key=…

Permintaan

curl '/api/transactiondetail?project=<slug>&amount=99000&order_id=INV123123&api_key=<API_KEY>'

Jawaban

{ "transaction": { "amount": 99000, "order_id": "INV123123", "project": "<slug>", "status": "completed", "payment_method": "qris", "completed_at": "2026-09-16T03:07:02.819+07:00" } }

Ketentuan

status
pending · completed · expired · canceled
Kegunaan
polling status bila webhook belum diterima.

7. Membatalkan transaksi

POST /api/transactioncancel

curl -L '/api/transactioncancel' \ -H 'Content-Type: application/json' \ -d '{"project":"<slug>","order_id":"INV123123","amount":99000,"api_key":"<API_KEY>"}'

Ketentuan

  • Hanya invoice yang masih dapat dibatalkan yang diproses.
  • Invoice yang sudah dibayar tidak dapat dibatalkan.

8. Sandbox dan simulasi

POST /api/paymentsimulation hanya berlaku untuk project sandbox.

curl -L '/api/paymentsimulation' \ -H 'Content-Type: application/json' \ -d '{"project":"<slug-sandbox>","order_id":"INV123123","amount":99000,"api_key":"<API_KEY>"}'

Ketentuan

  • Jangan memakai simulasi pada project produksi.
  • Simulasi membukukan pembayaran seperti pembayaran sungguhan, termasuk webhook.

9. Webhook

HollaPay mengirim POST ke webhook URL project saat pembayaran terkonfirmasi.

Permintaan

{ "amount": 22000, "order_id": "INV123123", "project": "<slug>", "status": "completed", "payment_method": "qris", "completed_at": "2026-09-16T08:07:02.819+07:00", "event": "transaction.paid", "fee": 0, "unique_code": 187, "total_payment": 22187, "reference_label": "178950109669506557", "paid_at": "2026-09-16T01:07:02.819Z" }

Ketentuan

Tanda tangan
verifikasi header x-gateway-signature memakai webhook secret project sebelum memproses payload.
Header penelusuran
x-gateway-project · x-gateway-delivery
Deduplikasi
simpan x-gateway-delivery agar event kembar tidak diproses dua kali.
Pengiriman ulang
pengiriman yang gagal diulang otomatis; statusnya dapat dilihat dan dikirim ulang dari dashboard.

10. Laporan masalah

POST /api/problemreport

curl -L '/api/problemreport' \ -H 'Content-Type: application/json' \ -d '{ "project": "<slug>", "api_key": "<API_KEY>", "order_id": "INV123123", "amount": 99187, "category": "PAID_NOT_RECORDED", "note": "pelanggan mengirim bukti transfer pukul 10:12", "contact": "budi / 0812xxxxxxx" }'

Ketentuan

Kategori
PAID_NOT_RECORDED · AMOUNT_MISMATCH · STILL_PENDING · WRONG_ORDER · OTHER
Kolom wajib
order_id dan amount
Cek status
GET /api/problemreport?project=…&api_key=…[&status=NEW]

11. Multi-user dan kepemilikan

Kepemilikan
setiap project dimiliki satu akun; hanya pemilik dan admin yang dapat melihat detailnya.
Saldo
pembayaran yang tercocokkan menambah saldo pemilik project.
Pembatasan akses
user hanya melihat data miliknya; admin melihat seluruh gateway.

12. Ketentuan umum

Nominal
yang dibayar pelanggan adalah total_payment (nominal invoice ditambah kode unik).
Masa berlaku
invoice kedaluwarsa pada expired_at; status berubah menjadi expired.
Idempotensi
order_id yang sama tidak membuat invoice kedua.
Kode unik
ditambahkan otomatis untuk membedakan invoice bernominal sama.
Kontrak
nama field, status HTTP, dan bentuk error dipertahankan; perubahan diumumkan sebelum diberlakukan.

Endpoint ringkas

POST /api/transactioncreate/{method} GET /api/transactiondetail POST /api/transactioncancel POST /api/paymentsimulation POST /api/problemreport GET /api/problemreport GET /api/health GET /status