# Dokumentasi Lengkap API Aulaa Payment Gateway > **Dokumen ini dirancang untuk integrasi sistem dan konsumsi oleh Developer & AI Coding Agent.** > Format: Markdown Murni > Versi API: `v1` > Terakhir diperbarui: 2026 --- ## 1. Ikhtisar & Arsitektur Aulaa adalah payment aggregator & gateway yang memungkinkan aplikasi web/mobile menerima berbagai metode pembayaran di Indonesia: - **QRIS Dinamis** (Semua e-wallet & mobile banking di Indonesia) - **Virtual Account (VA)**: BCA, Mandiri, BRI, BNI, Permata, CIMB Niaga, Danamon, BSI, dll. - **E-Wallet**: DANA, OVO, ShopeePay, GoPay - **Kartu Kredit/Debit**: Visa, Mastercard, JCB ### Dua Model Integrasi: 1. **Hosted Payment Page (Direkomendasikan)**: Backend memanggil `POST /v1/payments`, lalu mengarahkan browser pelanggan ke URL `https://payment.aulaa.co/pay/{payment_id}`. Aulaa menangani rendering QRIS/VA dan UI countdown timer. 2. **White-label / Direct API**: Backend memanggil `POST /v1/payments` dengan menentukan `payment_method` (misal: `qris` atau `bca_va`). Respons API langsung mengembalikan `payment_number` (string QRIS mentah atau nomor VA) untuk di-render sendiri di UI aplikasi Anda. --- ## 2. Lingkungan & Autentikasi ### Base URL - **Production & Sandbox**: `https://api.aulaa.co/v1` — host yang sama untuk keduanya. - **Halaman Pembayaran**: `https://payment.aulaa.co` Sandbox dan Production TIDAK dibedakan oleh host maupun API key, melainkan oleh **mode Project**. Project baru bermode test: transaksinya diproses konektor simulasi, tidak menyentuh uang sungguhan, dan bisa dipakai segera tanpa menunggu review. Setelah project di-review dan di-Go Live, project tersebut memproses transaksi produksi. Satu API key berlaku untuk kedua mode. ### Autentikasi API Key Semua panggilan API wajib menyertakan API Key pada HTTP Header: ```http Authorization: Bearer pgw_id_xxxxxxxxxxxxxxxx Content-Type: application/json ``` - Dapatkan API Key melalui **Dashboard Merchant -> Menu Project**. - Simpan API Key di environment variable server backend Anda (`AULAA_API_KEY`). **Jangan pernah menyertakan API Key di frontend / client-side code.** --- ## 3. REST API Endpoints ### 3.1 Ambil Metode Pembayaran Aktif Mengembalikan daftar metode pembayaran yang aktif untuk project Anda beserta batas nominal transaksi (`min_amount` dan `max_amount`). - **Method**: `GET` - **Path**: `/v1/payments/methods` - **Headers**: - `Authorization: Bearer ` #### Contoh Request: ```bash curl -X GET https://api.aulaa.co/v1/payments/methods \ -H "Authorization: Bearer pgw_id_xxxxxxxxxxxxxxxx" ``` #### Contoh Response (200 OK): ```json { "country": "ID", "currency": "IDR", "methods": [ { "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": "mandiri_va", "name": "Mandiri Virtual Account", "type": "virtual_account", "is_available": true, "min_amount": 10000, "max_amount": 100000000 }, { "code": "bni_va", "name": "BNI Virtual Account", "type": "virtual_account", "is_available": true, "min_amount": 10000, "max_amount": 100000000 }, { "code": "permata_va", "name": "Permata 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 }, { "code": "credit_card", "name": "Credit/Debit Card", "type": "card", "is_available": true, "min_amount": 10000, "max_amount": 10000000 } ] } ``` --- ### 3.2 Buat Pembayaran (Create Payment) Membuat transaksi baru. Endpoint ini **idempoten** terhadap kombinasi `order_id` per project. - **Method**: `POST` - **Path**: `/v1/payments` - **Headers**: - `Authorization: Bearer ` - `Content-Type: application/json` #### Request Body Parameters: | Parameter | Tipe | Wajib | Keterangan | | :--- | :--- | :--- | :--- | | `order_id` | `string` | **Ya** | ID pesanan unik dari sistem Anda (mis. `INV-20260627-001`). Idempoten. | | `amount` | `integer` | **Ya** | Nominal tagihan dalam Rupiah bulat (mis. `50000` untuk Rp50.000). | | `payment_method` | `string` | *Opsional* | Kode metode (mis. `qris`, `bca_va`). Kosongkan jika ingin pelanggan memilih sendiri di halaman pembayaran. | | `redirect_url` | `string` | *Opsional* | URL redirect browser setelah pembayaran berhasil. | | `customer_name` | `string` | *Opsional* | Nama pembeli. | | `customer_email` | `string` | *Opsional* | Email pembeli. | | `customer_phone` | `string` | *Opsional* | Nomor WhatsApp/telepon pembeli. | | `description` | `string` | *Opsional* | Catatan atau deskripsi transaksi. | #### Contoh Request Body (JSON): ```json { "order_id": "INV-20260627-001", "amount": 50000, "payment_method": "qris", "redirect_url": "https://toko-anda.com/checkout/sukses" } ``` #### Contoh Response (200 OK / 201 Created): ```json { "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" } ``` #### Cara Penggunaan Output: 1. **Model Hosted**: Arahkan browser pelanggan ke `https://payment.aulaa.co/pay/{id}`. 2. **Model White-label**: - Jika `payment_method = "qris"`, render string `payment_number` menjadi QR code menggunakan library seperti `qrcode.react` (React) atau `qrcode` (Node.js). - Jika `payment_method` adalah Virtual Account (misal: `bca_va`), tampilkan `payment_number` sebagai teks nomor rekening Virtual Account beserta tombol salin. --- ### 3.3 Cek Status Pembayaran (Get Payment Status) Memeriksa status pembayaran berdasarkan ID transaksi pembayaran. - **Method**: `GET` - **Path**: `/v1/payments/{payment_id}` - **Headers**: - `Authorization: Bearer ` #### Contoh Request: ```bash curl -X GET https://api.aulaa.co/v1/payments/f47ac10b-58cc-4372-a567-0e02b2c3d479 \ -H "Authorization: Bearer pgw_id_xxxxxxxxxxxxxxxx" ``` #### Contoh Response (200 OK): ```json { "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" } ``` --- ### 3.4 Batalkan Pembayaran (Cancel Payment) Membatalkan pembayaran yang belum dibayar (`pending`). - **Method**: `POST` - **Path**: `/v1/payments/{payment_id}/cancel` - **Headers**: - `Authorization: Bearer ` #### Contoh Response (200 OK): ```json { "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "order_id": "INV-20260627-001", "status": "cancelled", "amount": 50000, "cancelled_at": "2026-06-27T07:20:00Z" } ``` --- ## 4. Tautan Instan Bertanda Tangan (Signed Checkout URL) Jika Anda ingin membuat tautan pembayaran langsung tanpa memanggil REST API terlebih dahulu (misal untuk tombol checkout statis atau link promosi), gunakan skema **Signed Checkout URL**. ### Rumus Signature: ```text payload = "checkout:v1:{ProjectID}:{Amount}:{OrderID}" signature = HMAC_SHA256(payload, webhook_secret) ``` ### URL Format: ```text https://payment.aulaa.co/checkout/{ProjectID}/{Amount}?order_id={OrderID}&sig={signature}&redirect_url={RedirectURL} ``` ### Contoh Node.js: ```javascript 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'); 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); ``` --- ## 5. Webhook & Verifikasi Notifikasi Saat pelanggan menyelesaikan pembayaran, Aulaa mengirimkan HTTP POST event ke **Callback URL** yang Anda konfigurasikan di menu Project. ### 5.1 Webhook Payload Format: ```json { "event": "payment.paid", "data": { "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "order_id": "INV-20260627-001", "status": "paid", "amount": 50000, "fee_amount": 350, "charged_amount": 50000, "currency": "IDR", "payment_method": "qris", "payment_number": "00020101021226670016COM.NOBUBANK...", "paid_at": "2026-06-27T07:15:32Z", "created_at": "2026-06-27T07:00:00Z" } } ``` ### 5.2 Header Webhook: - `X-Webhook-Signature`: Signature HMAC-SHA256 dari raw body request, memakai `webhook_secret` milik project. - `Content-Type`: `application/json` ### 5.3 Verifikasi Signature Webhook (Node.js Express): ```javascript const crypto = require('crypto'); const express = require('express'); const app = express(); // Gunakan express.raw({ type: 'application/json' }) untuk mendapatkan buffer mentah app.post('/api/aulaa-webhook', express.raw({ type: 'application/json' }), (req, res) => { const signature = req.headers['x-webhook-signature']; const webhookSecret = process.env.AULAA_WEBHOOK_SECRET; const expectedSignature = crypto .createHmac('sha256', webhookSecret) .update(req.body) .digest('hex'); if (signature !== expectedSignature) { return res.status(401).send('Invalid signature'); } const event = JSON.parse(req.body.toString()); if (event.event === 'payment.paid' && event.data.status === 'paid') { const orderId = event.data.order_id; // 1. Periksa idempotensi (pastikan order belum ditandai lunas sebelumnya) // 2. Tandai pesanan sebagai LUNAS di database Anda // 3. Proses pesanan / kirim produk } // Wajib kembalikan status 200 OK segera res.status(200).json({ received: true }); }); ``` --- ## 6. Contoh Implementasi Lengkap (Multi-Language) ### JavaScript / Node.js (Fetch API): ```javascript const response = 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 invoice = await response.json(); console.log('Payment ID:', invoice.id); console.log('Payment Number (QRIS/VA):', invoice.payment_number); // Arahkan pelanggan ke invoice page Aulaa: // window.location.href = `https://payment.aulaa.co/pay/${invoice.id}`; ``` ### Python (Requests): ```python import requests url = "https://api.aulaa.co/v1/payments" headers = { "Authorization": "Bearer pgw_id_xxxxxxxxxxxxxxxx", "Content-Type": "application/json", } payload = { "order_id": "INV-20260627-001", "amount": 50000, "payment_method": "qris", "redirect_url": "https://toko-anda.com/checkout/sukses" } response = requests.post(url, json=payload, headers=headers) invoice = response.json() print("Invoice URL: https://payment.aulaa.co/pay/" + invoice["id"]) ``` ### PHP (cURL): ```php 'INV-20260627-001', 'amount' => 50000, 'payment_method' => 'qris', 'redirect_url' => 'https://toko-anda.com/checkout/sukses', ]); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_POSTFIELDS => $payload, CURLOPT_HTTPHEADER => [ 'Authorization: Bearer pgw_id_xxxxxxxxxxxxxxxx', 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $invoice = json_decode($response, true); echo "Payment ID: " . $invoice['id']; ?> ``` ### Go: ```go package main import ( "bytes" "encoding/json" "fmt" "io" "net/http" ) func main() { payload := map[string]interface{}{ "order_id": "INV-20260627-001", "amount": 50000, "payment_method": "qris", "redirect_url": "https://toko-anda.com/checkout/sukses", } body, _ := json.Marshal(payload) req, _ := http.NewRequest("POST", "https://api.aulaa.co/v1/payments", bytes.NewBuffer(body)) req.Header.Set("Authorization", "Bearer pgw_id_xxxxxxxxxxxxxxxx") req.Header.Set("Content-Type", "application/json") resp, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer resp.Body.Close() respBody, _ := io.ReadAll(resp.Body) var invoice map[string]interface{} json.Unmarshal(respBody, &invoice) fmt.Printf("Payment ID: %v\n", invoice["id"]) } ``` --- ## 7. Status Transaksi & Kode Error ### Status Transaksi: - `pending`: Menunggu pembayaran dari pelanggan. - `paid`: Pembayaran berhasil diterima dan lunas. - `expired`: Waktu pembayaran habis (melewati batas kedaluwarsa). - `cancelled`: Transaksi dibatalkan oleh merchant/sistem. - `failed`: Transaksi gagal diproses oleh bank/PSP. ### HTTP Error Codes: - `400 Bad Request`: Format JSON tidak valid atau parameter wajib (`order_id`, `amount`) tidak diisi. - `401 Unauthorized`: API Key tidak valid, tidak disertakan, atau project dinonaktifkan. - `404 Not Found`: Transaksi / Payment ID tidak ditemukan. - `422 Unprocessable Entity`: Nominal transaksi di bawah `min_amount` atau di atas `max_amount` untuk metode tersebut. - `500 Internal Server Error`: Kendala teknis pada sistem perbankan / PSP upstream.