Dokumentasi API Aulaa
Terima pembayaran QRIS, Virtual Account, dan E-Wallet. Pilih cara tercepat lewat Halaman Pembayaran terhosting, atau kontrol penuh lewat API.
Mulai Cepat
Ada dua cara mengintegrasikan Aulaa. Keduanya dimulai dari membuat pembayaran, lalu berbeda pada siapa yang menampilkan QR/VA ke pelanggan:
Via Halaman
Arahkan pelanggan ke halaman pembayaran terhosting Aulaa. Kami yang menampilkan QR/VA, hitung mundur, & status. Paling cepat.
Via API
Terima nomor VA / string QRIS dari response, lalu tampilkan sendiri di aplikasi Anda — white-label, desain & brand sepenuhnya milik Anda (QRIS dirender pakai library QR biasa).
Daftar & Pilih Negara
Buat akun di dashboard Aulaa, lalu pilih negara operasional (mis. Indonesia). Pilihan negara bersifat permanen.
Buat Project & API Key
Setiap project punya API Key sendiri. Key langsung bisa dipakai di mode Sandbox tanpa menunggu review. Untuk produksi, selesaikan review project + KYC lalu aktifkan mode Live.
Integrasikan
Pilih Via Halaman (redirect ke halaman Aulaa) atau Via API (render QR/VA sendiri). Lalu terima webhook saat pelanggan membayar.
Base URL: https://api.aulaa.co/v1
Semua request harus HTTPS. Mode Sandbox vs Live ditentukan oleh switch pada project — API Key Anda sama untuk keduanya.
Autentikasi
Aulaa menggunakan Bearer Token. Sertakan API Key project Anda di header Authorization pada setiap request. Format key: pgw_<negara>_<random> (mis. pgw_id_a1b2c3…).
Authorization: Bearer pgw_id_xxxxxxxxxxxxxxxx⚠️ Keamanan: Jangan pernah mengekspos API Key di client-side code (JavaScript browser, mobile app). Selalu panggil API dari backend/server Anda. API Key ditampilkan satu kali saja saat dibuat — simpan dengan aman.
Mendapatkan API Key
- Login ke Dashboard Aulaa
- Buka menu Projects → pilih project Anda
- Pada bagian API Keys, klik Buat API Key
- Salin API Key yang muncul (hanya ditampilkan sekali)
Halaman Pembayaran
Anda tidak perlu merender QR/VA sendiri — Aulaa menampilkan kode QR / nomor VA, hitung mundur kedaluwarsa, serta halaman sukses & kedaluwarsa. Ada dua cara.
Tautan bertanda tangan (Signed URL)
Arahkan pelanggan ke URL ini yang ditandatangani secara offline di backend Anda tanpa memanggil REST API pembayaran. URL harus menyertakan parameter sig untuk mencegah modifikasi nominal pembayaran oleh pelanggan.
https://payment.aulaa.co/checkout/{ProjectID}/{Amount}?order_id={OrderID}&sig={Signature}ProjectID— ID project Anda (lihat di Dashboard → Projects)Amount— nominal tanpa titik/koma, mis.50000order_id— ID order/invoice di sistem Andasig— signature HMAC-SHA256 (hex) dari datacheckout:v1:ProjectID:Amount:OrderIDmenggunakan Webhook Secret project Anda.
Contoh Pembuatan Link (Node.js)
const crypto = require('crypto');
const projectID = 'b2c3d4e5-f6a7-8901-bcde-f12345678901';
const amount = 50000;
const orderID = 'INV-20260627-001';
const secret = 'YOUR_WEBHOOK_SECRET'; // Diambil dari Dashboard -> Projects
// Format string: checkout:v1:{ProjectID}:{Amount}:{OrderID}
const payload = `checkout:v1:${projectID}:${amount}:${orderID}`;
const signature = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
const checkoutURL = `https://payment.aulaa.co/checkout/${projectID}/${amount}?order_id=${orderID}&sig=${signature}`;
console.log(checkoutURL);Metode yang sedang maintenance otomatis tidak muncul. Saat pelanggan lunas, Anda tetap menerima Webhook seperti biasa.
Buat via API lalu redirect
Buat pembayaran via API lalu arahkan pelanggan ke halaman invoice menggunakan id dari response. Halaman ini tidak menaruh nominal di URL, jadi tidak perlu tanda tangan.
https://payment.aulaa.co/pay/{ID}Metode terkunci (fixed)
Kirim payment_method (mis. qris) saat membuat pembayaran. Pelanggan langsung melihat QR/VA metode itu.
Pelanggan pilih metode (flexible)
Hilangkan payment_method. Halaman /pay/{ID} menampilkan daftar metode dan pelanggan memilih sendiri.
Karena invoice dibuat lebih dulu, transaksi langsung muncul di Dashboard berstatus pending — cocok untuk dibuat manual dari Dashboard lalu link-nya dikirim via WhatsApp/email.
Contoh (Node.js)
// 1. Buat pembayaran dari backend Anda
const res = await fetch('https://api.aulaa.co/v1/payments', {
method: 'POST',
headers: {
'Authorization': 'Bearer pgw_id_xxxxxxxxxxxxxxxx',
'Content-Type': 'application/json',
},
body: JSON.stringify({
order_id: 'INV-20260627-001',
amount: 50000,
payment_method: 'qris',
}),
});
const payment = await res.json();
// 2. Arahkan pelanggan ke halaman pembayaran Aulaa
const url = `https://payment.aulaa.co/pay/${payment.id}`;
window.location.href = url; // atau kirim 'url' ini ke pelangganDi kedua opsi, webhook tetap dikirim ke callback_url project Anda yang sudah direview, dan halaman pembayaran memperbarui statusnya sendiri secara realtime.
Metode Pembayaran
/v1/payments/methodsMengembalikan metode pembayaran yang tersedia untuk Anda saat ini. Negara dideteksi otomatis dari API Key Anda — tidak perlu parameter apa pun. Metode yang sedang maintenance otomatis tidak muncul di sini (dan akan ditolak jika tetap dipakai saat Buat Pembayaran). Gunakan field Code sebagai nilai payment_method saat membuat pembayaran.
Contoh Request
curl https://api.aulaa.co/v1/payments/methods \
-H "Authorization: Bearer pgw_id_xxxxxxxxxxxxxxxx"Response (200 OK)
{
"country": "ID",
"currency": "IDR",
"methods": [
{ "Code": "qris", "Name": "QRIS", "Type": "qr_code", "IsAvailable": true },
{ "Code": "bca_va", "Name": "BCA Virtual Account", "Type": "virtual_account", "IsAvailable": true },
{ "Code": "bri_va", "Name": "BRI Virtual Account", "Type": "virtual_account", "IsAvailable": true },
{ "Code": "gopay", "Name": "GoPay", "Type": "ewallet", "IsAvailable": true },
{ "Code": "ovo", "Name": "OVO", "Type": "ewallet", "IsAvailable": true }
// ...
]
}Kode Metode (Indonesia)
| Code | Nama | Tipe |
|---|---|---|
| qris | QRIS | QR Code |
| bca_va | BCA Virtual Account | Virtual Account |
| bri_va | BRI Virtual Account | Virtual Account |
| bni_va | BNI Virtual Account | Virtual Account |
| mandiri_va | Mandiri Virtual Account | Virtual Account |
| permata_va | Permata Virtual Account | Virtual Account |
| cimb_niaga_va | CIMB Niaga Virtual Account | Virtual Account |
| maybank_va | Maybank Virtual Account | Virtual Account |
| bnc_va | Bank Neo Commerce Virtual Account | Virtual Account |
| sampoerna_va | Bank Sahabat Sampoerna Virtual Account | Virtual Account |
| atm_bersama_va | ATM Bersama Virtual Account | Virtual Account |
| artha_graha_va | Artha Graha Virtual Account | Virtual Account |
| gopay | GoPay | E-Wallet |
| shopee_pay | ShopeePay | E-Wallet |
| ovo | OVO | E-Wallet |
| dana | DANA | E-Wallet |
| alfamart | Alfamart | Convenience Store |
| indomaret | Indomaret | Convenience Store |
Buat Pembayaran
/v1/paymentsMembuat transaksi pembayaran. Jika Anda mengisi payment_method, response berisi payment_number — nomor Virtual Account atau string QRIS — yang Anda tampilkan sendiri di aplikasi Anda (white-label). Endpoint ini idempoten terhadap order_id per project: mengirim ulang order_id yang sama mengembalikan transaksi yang sudah ada (tidak menagih dua kali).
Request Body
| Parameter | Tipe | Wajib | Deskripsi |
|---|---|---|---|
| order_id | string | Required | ID order unik dari sistem Anda. Dipakai untuk idempotensi. |
| amount | integer | Required | Nominal dalam satuan terkecil mata uang (Rupiah penuh untuk IDR). ID: Rp1.000–Rp500.000.000. |
| payment_method | string | Opsional | Satu kode metode (mis. qris, bca_va) untuk mengunci metode. Jika dikosongkan, pelanggan memilih metode sendiri di halaman /pay/{ID}. Lihat Metode Pembayaran. |
Kapan payment_method boleh dikosongkan?
Keberadaan payment_method menentukan siapa yang menampilkan VA/QRIS:
- Render sendiri (Anda tampilkan VA/QRIS di aplikasi Anda, mis. dengan library HTML QR) → wajib isi
payment_method. Response akan berisipayment_number(nomor VA / string QRIS) untuk Anda render. - Redirect ke halaman Aulaa (
/pay/{ID}) → boleh dikosongkan. Pelanggan memilih metode di halaman kami dan kami yang menampilkan VA/QRIS-nya.
Jika payment_method kosong, payment_number ikut kosong (belum ada metode yang diproses) — itu memang sengaja, dan berarti Anda harus mengarahkan pelanggan ke /pay/{ID}, bukan me-render sendiri.
Contoh Request
curl -X POST https://api.aulaa.co/v1/payments \
-H "Authorization: Bearer pgw_id_xxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"order_id": "INV-20260627-001",
"amount": 50000,
"payment_method": "qris"
}'Response (201 Created)
{
"id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"order_id": "INV-20260627-001",
"status": "pending",
"amount": 50000,
"fee_amount": 350,
"total_amount": 50350,
"charged_amount": 50000,
"processing_fee": 0,
"currency": "IDR",
"country_code": "ID",
"payment_method": "qris",
"payment_number": "00020101021226670016COM.NOBUBANK...",
"expired_at": "2026-06-27T08:00:00Z",
"paid_at": null,
"created_at": "2026-06-27T07:00:00Z"
}Field penting: payment_number = nomor VA / string QRIS untuk ditampilkan ke pelanggan · amount = nominal order · fee_amount = biaya platform · charged_amount = total yang dibayar pelanggan · status = status awal (pending).
Menampilkan ke Pelanggan (White-label)
Karena Anda menerima data mentahnya, halaman pembayaran sepenuhnya milik Anda — desain, logo, dan warna sesuai brand Anda. Cara menampilkan payment_number tergantung Type metode (lihat Metode Pembayaran):
Virtual Account & Retail
payment_number = nomor VA / kode bayar. Tampilkan sebagai teks besar + tombol Salin.
QRIS
payment_number = string QRIS. Ubah jadi gambar QR memakai library QR apa pun (lihat contoh).
E-Wallet
payment_number = link/deeplink. Tampilkan sebagai tombol Bayar.
Untuk QRIS, Anda tidak membuat QR sendiri dari nol — cukup masukkan string-nya ke library QR, dan QR siap dipindai:
// Library QR — pilih sesuai stack Anda:
// React : npm i qrcode.react Node : npm i qrcode
// Python : pip install qrcode PHP : composer require endroid/qr-code
// Go : go get github.com/skip2/go-qrcode
// --- Contoh React (qrcode.react) ---
import { QRCodeCanvas } from 'qrcode.react'
// payment.payment_number = string QRIS dari response POST /v1/payments
<QRCodeCanvas value={payment.payment_number} size={256} />
// --- Contoh Node.js (qrcode) → data URL untuk <img src=...> ---
import QRCode from 'qrcode'
const qrImg = await QRCode.toDataURL(payment.payment_number)
// <img src={qrImg} alt="QRIS" />
// Untuk Virtual Account, payment_number cukup ditampilkan apa adanya
// sebagai teks + tombol "Salin" (tidak perlu library QR).Setelah menampilkan QR/VA, pantau pelunasan lewat Webhook (utama) atau Cek Status — lalu tampilkan halaman sukses Anda sendiri.
Cek Status Pembayaran
/v1/payments/{id}Mengecek status pembayaran berdasarkan id yang dikembalikan saat create. Webhook tetap sumber kebenaran utama; gunakan endpoint ini untuk verifikasi/rekonsiliasi.
Contoh Request
curl https://api.aulaa.co/v1/payments/f47ac10b-58cc-4372-a567-0e02b2c3d479 \
-H "Authorization: Bearer pgw_id_xxxxxxxxxxxxxxxx"Response (200 OK)
{
"id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"order_id": "INV-20260627-001",
"status": "paid",
"amount": 50000,
"fee_amount": 350,
"total_amount": 50350,
"charged_amount": 50000,
"processing_fee": 0,
"currency": "IDR",
"country_code": "ID",
"payment_method": "qris",
"payment_number": "00020101021226670016COM.NOBUBANK...",
"expired_at": "2026-06-27T08:00:00Z",
"paid_at": "2026-06-27T07:15:32Z",
"created_at": "2026-06-27T07:00:00Z"
}Nilai Status
| Status | Deskripsi |
|---|---|
| pending | Menunggu pembayaran dari pelanggan. |
| paid | Pembayaran berhasil diterima. |
| expired | Sudah melewati batas waktu pembayaran. |
| cancelled | Dibatalkan oleh merchant via endpoint cancel. |
| failed | Pembayaran gagal diproses (mis. ditolak penyedia pembayaran). |
| refunded | Dana dikembalikan ke pelanggan oleh penyedia pembayaran. |
Batalkan Pembayaran
/v1/payments/{id}/cancelMembatalkan pembayaran yang masih pending. Pembayaran yang sudah paid, expired, atau cancelled akan menghasilkan 409 Conflict. Response mengembalikan invoice dengan status: "cancelled".
Contoh Request
curl -X POST \
https://api.aulaa.co/v1/payments/f47ac10b-58cc-4372-a567-0e02b2c3d479/cancel \
-H "Authorization: Bearer pgw_id_xxxxxxxxxxxxxxxx"Webhook
Saat status pembayaran berubah, Aulaa mengirim HTTP POST ke callback_url project Anda — diatur sekali di Dashboard → Projects dan berlaku untuk semua transaksi project itu (tidak bisa diganti per-transaksi, demi keamanan). Payload bersifat flat (tanpa pembungkus event); bedakan jenis notifikasi dari field status — biasanya paid atau expired.
Contoh Webhook Payload
{
"order_id": "INV-20260627-001",
"amount": 50000,
"currency": "IDR",
"country_code": "ID",
"status": "paid",
"payment_method": "qris",
"formatted_amount": "Rp 50.000",
"paid_at": "2026-06-27T07:15:32Z"
}Verifikasi Signature (Node.js)
Setiap request menyertakan header X-Webhook-Signature berisi HMAC-SHA256 (hex, tanpa prefix) dari raw body, ditandatangani dengan Webhook Secret project Anda. Selalu verifikasi sebelum memproses.
const crypto = require('crypto');
const express = require('express');
const app = express();
// PENTING: signature dihitung dari RAW body (byte mentah), jadi
// gunakan express.raw — bukan express.json — di endpoint webhook.
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.headers['x-webhook-signature'];
const expected = crypto
.createHmac('sha256', process.env.AULAA_WEBHOOK_SECRET)
.update(req.body) // req.body = Buffer (raw)
.digest('hex'); // hex, TANPA prefix "sha256="
const valid = signature && crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
if (!valid) {
return res.status(401).json({ error: 'Invalid signature' });
}
const event = JSON.parse(req.body.toString());
if (event.status === 'paid') {
// Verifikasi order_id & amount sesuai data Anda, lalu update order
console.log('Pembayaran lunas:', event.order_id);
}
res.status(200).json({ received: true });
});Webhook Secret: bersifat per-project. Temukan & rotasi di Dashboard → Projects → bagian Webhook. Merotasi secret tidak butuh review ulang. Namun mengganti callback URL pada project yang sudah approved akan memicu review ulang (project turun ke revision & Live dimatikan sementara), karena URL webhook termasuk yang ditinjau untuk anti-abuse.
⚠️ Retry: Endpoint Anda harus merespon 2xx. Jika gagal, Aulaa mencoba ulang hingga 4 kali total (percobaan awal + 3 retry) dengan jeda +1 menit, +5 menit, +30 menit. Pastikan handler Anda idempoten terhadap order_id.
Error Codes
Aulaa menggunakan HTTP status code standar. Body error berformat sederhana — satu field error berisi pesan:
{
"error": "amount must be between 1000 and 500000000 IDR"
}| HTTP Code | Status | Deskripsi |
|---|---|---|
| 400 | Bad Request | Field wajib (order_id / amount) kosong, nominal di luar batas (ID: Rp1.000–Rp500.000.000), atau metode pembayaran tidak tersedia / sedang maintenance. (payment_method opsional — kosongkan agar pelanggan memilih sendiri di /pay/{ID}.) |
| 401 | Unauthorized | API key tidak valid, tidak aktif, kedaluwarsa, atau tidak disertakan di header Authorization. |
| 403 | Forbidden | Project belum Live atau disuspend (mis. mencoba transaksi produksi sebelum Go Live). |
| 404 | Not Found | Payment dengan ID tersebut tidak ditemukan untuk project Anda. |
| 409 | Conflict | Aksi tidak bisa dijalankan pada status saat ini (mis. cancel payment yang sudah paid). |
| 429 | Too Many Requests | Terlalu banyak percobaan dalam waktu singkat (mis. login berulang). Coba lagi sebentar. |
| 500 | Server Error | Kesalahan internal server. Hubungi support jika berlanjut. |
Siap untuk integrasi?
Daftar sekarang dan dapatkan API Key untuk mulai menerima pembayaran di aplikasi Anda.