API Reference

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

Aulaa menyediakan REST API sederhana untuk memproses transaksi pembayaran (QRIS, Virtual Account, E-Wallet, dan Kartu Kredit). Panggilan API dilakukan langsung dari backend server Anda (Server-to-Server).

Base URL

https://api.aulaa.co/v1

Semua request wajib menggunakan HTTPS dengan header Content-Type: application/json. Mode Sandbox maupun Live menggunakan Base URL dan API Key yang sama (dikontrol via switch project di Dashboard).

Langkah Integrasi

  1. Daftar Akun: Buat akun di Dashboard Aulaa dan pilih negara operasional (Indonesia / IDR).
  2. Buat Project & Ambil API Key: Dapatkan API Key (pgw_id_...) dan Webhook Secret di menu Projects.
  3. Panggil API & Terima Webhook: Buat pembayaran via API lalu tangani notifikasi pelunasan di endpoint Webhook Anda.

Autentikasi

Aulaa menggunakan Bearer Token. Sertakan API Key project Anda di header Authorization pada setiap request. Format key: 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

  1. Login ke Dashboard Aulaa
  2. Buka menu Projects → pilih project Anda
  3. Pada bagian API Keys, klik Buat API Key
  4. Salin API Key yang muncul (hanya ditampilkan sekali)

Uji Coba (Sandbox)

Saat project dalam mode Sandbox, transaksi tidak diteruskan ke payment provider asli. Aulaa membuat kode pembayaran dummy yang bisa Anda "bayar" sendiri lewat halaman simulasi — cocok untuk menguji alur integrasi dan webhook sebelum Go Live. Transaksi sandbox tidak masuk ke saldo/pendapatan dan ditampilkan terpisah di dashboard.

  1. 1Pastikan switch project pada posisi Sandbox, lalu buat transaksi seperti biasa (Via Halaman atau Via API).
  2. 2Anda menerima kode pembayaran dummy pada field payment_number (mis. SBX1A2B3C4D). Untuk QRIS, kode inilah yang di-render menjadi QR.
  3. 3Buka halaman simulasi, masukkan kode tersebut (atau scan QR untuk QRIS).
  4. 4Klik Bayar (Sukses) atau Simulasikan Gagal. Status invoice berubah dan Webhook dikirim ke project Anda — persis seperti produksi.

Halaman simulasi: https://api.aulaa.co/payment-simulation

Buka Simulator

Simulator hanya bekerja untuk transaksi Sandbox. Saat siap produksi, aktifkan mode Live (perlu review project + KYC) — transaksi Live diproses payment provider asli dan masuk ke saldo Anda.

REST API Pembayaran

Metode Pembayaran

GET/v1/payments/methods

Mengembalikan metode pembayaran yang tersedia dan aktif untuk project Anda saat ini. Negara dideteksi otomatis dari API Key Anda — tidak perlu parameter tambahan. Metode yang sedang maintenance otomatis disaring dari respons. Gunakan field code sebagai nilai payment_method saat membuat transaksi.

Daftarnya berbeda per project: setiap project punya pengaturan sendiri tentang metode apa saja yang diterima, diatur di halaman detail project. Metode yang dimatikan di sana tidak muncul di sini, dan ditolak bila tetap dikirim sebagai payment_method saat membuat transaksi. Jadi panggil endpoint ini dengan API Key project yang bersangkutan — jangan menyalin daftarnya antar project.

Setiap metode menyertakan batas nominal transaksi: min_amount dan max_amount (dalam Rupiah). Nilai 0 berarti tidak ada batas khusus. Gunakan data ini untuk memvalidasi nominal di sisi frontend Anda sebelum memanggil Buat 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": "credit_card", "name": "Credit/Debit Card", "type": "card",       "is_available": true, "min_amount": 10000, "max_amount": 10000000 },
    { "code": "qris",   "name": "QRIS",                "type": "qr_code",         "is_available": true, "min_amount": 1,     "max_amount": 10000000 },
    { "code": "bca_va", "name": "BCA Virtual Account", "type": "virtual_account", "is_available": true, "min_amount": 10000, "max_amount": 100000000 },
    { "code": "bri_va", "name": "BRI Virtual Account", "type": "virtual_account", "is_available": true, "min_amount": 10000, "max_amount": 100000000 },
    { "code": "dana",   "name": "DANA",               "type": "ewallet",         "is_available": true, "min_amount": 1000,  "max_amount": 10000000 },
    { "code": "ovo",    "name": "OVO",                "type": "ewallet",         "is_available": true, "min_amount": 1000,  "max_amount": 10000000 }
    // ...
  ]
} 

Kode Metode (Indonesia)

CodeNamaTipe
credit_cardCredit/Debit CardCard
qrisQRISQR Code
bca_vaBCA Virtual AccountVirtual Account
bri_vaBRI Virtual AccountVirtual Account
bni_vaBNI Virtual AccountVirtual Account
mandiri_vaMandiri Virtual AccountVirtual Account
permata_vaPermata Virtual AccountVirtual Account
cimb_niaga_vaCIMB Niaga Virtual AccountVirtual Account
maybank_vaMaybank Virtual AccountVirtual Account
bnc_vaBank Neo Commerce Virtual AccountVirtual Account
sampoerna_vaBank Sahabat Sampoerna Virtual AccountVirtual Account
atm_bersama_vaATM Bersama Virtual AccountVirtual Account
artha_graha_vaArtha Graha Virtual AccountVirtual Account
gopayGoPayE-Wallet
shopee_payShopeePayE-Wallet
ovoOVOE-Wallet
danaDANAE-Wallet
linkajaLinkAjaE-Wallet
alfamartAlfamartConvenience Store
indomaretIndomaretConvenience Store

Buat Pembayaran

POST/v1/payments

Membuat transaksi pembayaran baru di Aulaa. order_id bersifat unik per project: mengirim ulang order_id yang sama akan ditolak dengan 409 Conflict — bukan membuat transaksi kedua, sehingga pelanggan tidak mungkin tertagih dua kali.

Request Body

ParameterTipeWajibDeskripsi
order_idstringRequiredID order unik dari sistem Anda (mis. INV-20260627-001). Dipakai untuk idempotensi.
amountintegerRequiredNominal tagihan dalam Rupiah penuh (IDR). Batas: Rp1.000–Rp500.000.000.
payment_methodstringOpsionalKode metode (mis. qris, bca_va) untuk mengunci metode. Boleh dikosongkan jika Anda ingin pelanggan memilih metode sendiri di halaman /pay/{ID}.
redirect_urlstringOpsionalURL website Anda tempat browser pelanggan dialihkan secara otomatis setelah pembayaran terkonfirmasi lunas.

2 Cara Menyajikan Pembayaran ke Pelanggan

Setelah memanggil POST /v1/payments, Anda dapat memilih salah satu cara penyajian berikut:

Pilihan 1 (Direkomendasikan)
Arahkan ke Halaman Pembayaran Aulaa

Anda tidak perlu membuat form / halaman pembayaran sendiri. Cukup buat pembayaran via API dari backend Anda, lalu arahkan pelanggan ke URL 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 memanggil API. Pelanggan langsung melihat QR/VA metode itu di halaman invoice.

Pelanggan Pilih Metode (Flexible)

Kosongkan payment_method. Halaman /pay/{ID} akan menampilkan daftar seluruh metode yang aktif agar 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 Integrasi Buat & Redirect (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',
    redirect_url: 'https://toko-anda.com/checkout/sukses',
  }),
});
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 pelanggan
Pilihan 2
White-label (Render Mandiri di Website/Aplikasi Anda)

Jika Anda ingin tampilan pembayaran menyatu 100% dengan desain dan brand Anda: isi payment_method, lalu ambil nilai payment_number dari response JSON untuk di-render sendiri.

QRIS

payment_number = string QRIS mentah. Ubah jadi gambar QR dengan library QR.

Virtual Account & Retail

payment_number = nomor VA / kode bayar. Tampilkan sebagai teks tebal + tombol Salin.

E-Wallet

payment_number = link/deeplink pembayaran. Tampilkan sebagai tombol Bayar.

Kartu Kredit/Debit

payment_number = link form kartu Aulaa (terisolasi PCI DSS demi keamanan data kartu).

Contoh Render QRIS (React / Node.js):
// 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).

Kapan payment_method boleh dikosongkan?

  • Render sendiri (White-label) → wajib isi payment_method agar response berisi payment_number (nomor VA / string QRIS).
  • Redirect ke halaman Aulaa (/pay/{ID}) → boleh dikosongkan agar pelanggan memilih metode sendiri di halaman pembayaran.

Jika payment_method dikosongkan, payment_number akan kosong dan fee_amount bernilai 0 sampai pelanggan selesai memilih metode di halaman /pay/{ID}.

Contoh Request (Semua Bahasa)

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,
  "charged_amount": 50000,
  "currency": "IDR",
  "country_code": "ID",
  "payment_method": "qris",
  "payment_number": "00020101021226670016COM.NOBUBANK...",
  "redirect_url": "https://toko-anda.com/checkout/sukses",
  "is_test": false,
  "expired_at": "2026-06-27T08:00:00Z",
  "paid_at": null,
  "created_at": "2026-06-27T07:00:00Z"
}

Field penting: id = ID invoice Aulaa · payment_number = nomor VA / string QRIS · amount = nominal order · fee_amount = biaya layanan Aulaa · charged_amount = total yang dibayar pelanggan · status = status awal (pending).

Respons 409 — order_id sudah pernah dipakai

{
  "error": "Pesanan dengan order_id INV-20260627-001 sudah pernah dibuat",
  "payment_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479"
}

payment_id berisi id transaksi yang sudah ada. Ini jalan pulang bila panggilan pertama Anda putus sebelum responsnya sampai: kirim ulang order_id yang sama, ambil payment_id dari respons 409, lalu lanjutkan dengan Cek Status. Jangan pernah menerbitkan order_id baru untuk order yang sama.

Cek Status Pembayaran

GET/v1/payments/{id}

Mengecek status pembayaran terkini berdasarkan id invoice Aulaa — yaitu field id yang Anda terima saat membuat transaksi, bukan order_id Anda sendiri. Simpan id itu bersama order Anda. Webhook tetap merupakan sumber kebenaran utama; gunakan endpoint ini untuk rekonsiliasi atau verifikasi berkala. Satu pembayaran boleh dicek paling banyak 30 kali per menit (rata-rata sekali per 2 detik); lebih dari itu dijawab 429 dengan header Retry-After.

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,
  "charged_amount": 50000,
  "currency": "IDR",
  "country_code": "ID",
  "payment_method": "qris",
  "payment_number": "00020101021226670016COM.NOBUBANK...",
  "redirect_url": "https://toko-anda.com/checkout/sukses",
  "is_test": false,
  "expired_at": "2026-06-27T08:00:00Z",
  "paid_at": "2026-06-27T07:15:32Z",
  "created_at": "2026-06-27T07:00:00Z"
}

Nilai Status Transaksi

StatusDeskripsi
pendingMenunggu pembayaran dari pelanggan.
paidPembayaran berhasil diterima.
expiredSudah melewati batas waktu pembayaran.
cancelledDibatalkan oleh merchant via endpoint cancel.
failedPembayaran gagal diproses oleh penyedia pembayaran.
refundedDana dikembalikan ke pelanggan oleh penyedia pembayaran.

Batalkan Pembayaran

POST/v1/payments/{id}/cancel

Membatalkan pembayaran yang masih berstatus pending. Pembayaran yang sudah paid, expired, atau cancelled akan menghasilkan 409 Conflict.

Contoh Request

curl -X POST \
  https://api.aulaa.co/v1/payments/f47ac10b-58cc-4372-a567-0e02b2c3d479/cancel \
  -H "Authorization: Bearer pgw_id_xxxxxxxxxxxxxxxx"
Tautan Instan

Signed Checkout URL

Alternatif bagi Anda yang ingin membuat link pembayaran instan tanpa memanggil REST API pembayaran dari backend server. Tautan ini ditandatangani secara offline (*cryptographic HMAC-SHA256 signature*) menggunakan Webhook Secret project Anda agar parameter nominal tidak bisa dimanipulasi oleh pembeli.

https://payment.aulaa.co/checkout/{ProjectID}/{Amount}?order_id={OrderID}&sig={Signature}&redirect_url={RedirectURL}
  • ProjectID — ID project Anda (lihat di Dashboard → Projects).
  • Amount — Nominal tagihan dalam angka bulat tanpa titik/koma (mis. 50000).
  • order_id — Wajib. ID invoice unik di sistem Anda. Transaksi dengan order_id yang sama akan melanjutkan sesi pembayaran yang sama.
  • sig — Wajib. Signature HMAC-SHA256 (hex) dari data checkout:v1:ProjectID:Amount:OrderID ditandatangani dengan Webhook Secret project Anda.
  • redirect_url — Opsional. URL website Anda untuk redirect otomatis setelah pembayaran berhasil.

Contoh Pembuatan Signed URL (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
const redirectURL = encodeURIComponent('https://toko-anda.com/checkout/sukses');

// 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}&redirect_url=${redirectURL}`;
console.log(checkoutURL);

Saat pelanggan menyelesaikan pembayaran lewat Signed Checkout URL, webhook notifikasi tetap dikirimkan ke callback_url project Anda seperti biasa.

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 CodeStatusDeskripsi
400Bad RequestField 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}.)
401UnauthorizedAPI key tidak valid, tidak aktif, kedaluwarsa, atau tidak disertakan di header Authorization.
403ForbiddenProject belum Live atau disuspend (mis. mencoba transaksi produksi sebelum Go Live).
404Not FoundPayment dengan ID tersebut tidak ditemukan untuk project Anda.
409Conflictorder_id sudah pernah dipakai di project ini — responsnya memuat payment_id transaksi yang sudah ada. Juga dipakai saat aksi tidak bisa dijalankan pada status saat ini (mis. cancel payment yang sudah paid).
429Too Many RequestsTerlalu banyak permintaan dalam waktu singkat (mis. cek status satu pembayaran lebih dari 30 kali per menit). Tunggu sesuai header Retry-After, lalu coba lagi.
500Server ErrorKesalahan internal server. Hubungi support jika berlanjut.

Siap untuk integrasi?

Daftar sekarang dan dapatkan API Key untuk mulai menerima pembayaran di aplikasi Anda.