AustinPay API
REST API untuk integrasi deposit QRIS, withdraw e-wallet & bank, dan manajemen akun. Semua endpoint mengembalikan JSON dengan field success (boolean).
https://austinstore.id
Format: application/json
HTTPS only
Autentikasi
/api/account, /api/dashboard, dan /api/transactions murni Public API (wajib API Key + IP Whitelist). Endpoint /api/deposit/* dan /api/withdraw/* dipakai bersama oleh dashboard web (cookie/JWT dari login) dan Public API — server membedakan otomatis dari kredensial yang kamu kirim: sertakan API key (lihat langkah di bawah) untuk diperlakukan sebagai Public API, kalau tidak akan dianggap sesi web biasa.
Buat API Key
Masuk ke Profil → bagian API Key → klik Buat API Key. Key hanya ditampilkan satu kali — simpan baik-baik karena tidak bisa dilihat lagi setelah itu.
Daftarkan IP Whitelist
Di halaman Profil, bagian Whitelist IP, tambahkan IP server/aplikasi yang akan memanggil API. Mendukung IP tunggal (203.0.113.10) atau CIDR (203.0.113.0/24). Request dari IP tidak terdaftar akan ditolak meski API key valid.
Sertakan API Key di Setiap Request
Kirim API key via query parameter ?apikey= pada setiap request Public API. Header X-API-Key tetap didukung untuk integrasi backend lama.
?apikey=apg_live_xxx
X-API-Key: apg_live_xxx
Authorization: Bearer apg_live_xxx
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://austinstore.id/api/account?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxx",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$response = curl_exec($curl);
curl_close($curl);
$hasil = json_decode($response, true);
const res = await fetch("https://austinstore.id/api/account?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxx");
const data = await res.json();
console.log(data);
curl "https://austinstore.id/api/account?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxx"
(Opsional, direkomendasikan) HMAC Signature dengan API Secret
Selain API key, kamu bisa generate API Secret di halaman Profil → bagian API Secret (HMAC Signature). Begitu secret dibuat, setiap request Public API dari key ini wajib ditandatangani — request tanpa signature valid akan ditolak (401), walau API key & IP whitelist-nya benar. Secret hanya ditampilkan satu kali saat dibuat/diganti.
Gabungkan 4 bagian berikut dengan newline (\n), lalu HMAC-SHA256 memakai API secret sebagai key, hasilnya dalam bentuk hex:
METHOD (huruf besar, mis. POST)
PATH (pathname murni, TANPA query string, mis. /api/deposit/create)
BODY (raw JSON string persis seperti yang dikirim; string kosong "" kalau tidak ada body)
TIMESTAMP (Date.now() dalam milidetik, dalam bentuk string)
Kirim hasilnya lewat header X-Signature, dan timestamp yang dipakai lewat header X-Timestamp. Server menolak request kalau selisih X-Timestamp dengan waktu server lebih dari 5 menit (mencegah replay attack), atau kalau signature tidak cocok.
import crypto from "node:crypto";
function signRequest(method, path, body, secret) {
const timestamp = Date.now().toString();
const payload = `${method}\n${path}\n${body}\n${timestamp}`;
const signature = crypto.createHmac("sha256", secret).update(payload).digest("hex");
return { timestamp, signature };
}
const path = "/api/deposit/create";
const body = JSON.stringify({ amount: 50000, method: "qris" });
const { timestamp, signature } = signRequest("POST", path, body, process.env.AUSTIN_API_SECRET);
await fetch(`https://austinstore.id${path}`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": process.env.AUSTIN_API_KEY,
"X-Timestamp": timestamp,
"X-Signature": signature,
},
body,
});
X-API-Key — bukan ?apikey= di URL — supaya path yang kamu tanda-tangani sama persis dengan yang diverifikasi server.
Rate Limiting
Batasan request untuk menjaga kestabilan sistem dan mencegah penyalahgunaan.
| Endpoint | Limit | Window | Keterangan |
|---|---|---|---|
/api/deposit/create |
5 req | per menit | Per akun/API key. Throttle ketat untuk mencegah spam QRIS. |
| Endpoint Public API lainnya | 300 req | per menit | Default rate limit per API key. Lewat batas ini request ditolak 429 (key tetap aktif); key baru dinonaktifkan otomatis jika mencapai ~3x lipat batas (indikasi abuse). |
429 Too Many Requests. Implementasikan exponential backoff sebelum retry.
User
Informasi akun dan riwayat transaksi pemilik API key.
Info lengkap akun pemilik API key — username, email, role, status, dan saldo wallet.
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://austinstore.id/api/account?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$response = curl_exec($curl);
curl_close($curl);
$hasil = json_decode($response, true);
const res = await fetch("https://austinstore.id/api/account?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
const data = await res.json();
console.log(data);
curl "https://austinstore.id/api/account?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
{"success":true,"user":{"id":"uuid","username":"austi","email":"austi@example.com","role":"user","status":"active","wallet":{"balance":150000}}}
Riwayat semua transaksi dengan pagination dan filter.
| Parameter | Tipe | Status | Deskripsi |
|---|---|---|---|
page | integer | Opsional | Default: 1 |
limit | integer | Opsional | Default: 10, Maks: 50 |
type | string | Opsional | deposit / withdraw / adjustment |
status | string | Opsional | pending / success / failed |
date_from | date | Opsional | Format YYYY-MM-DD |
date_to | date | Opsional | Format YYYY-MM-DD |
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://austinstore.id/api/transactions?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&page=1&limit=10",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$response = curl_exec($curl);
curl_close($curl);
$hasil = json_decode($response, true);
const params = new URLSearchParams({
apikey: "apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
page: 1,
limit: 10
});
const res = await fetch(`https://austinstore.id/api/transactions?${params}`);
const data = await res.json();
console.log(data);
curl "https://austinstore.id/api/transactions?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&page=1&limit=10"
{"success":true,"data":[{"id":"uuid","type":"deposit","amount":50000,"status":"success","created_at":"2026-06-27T10:00:00Z"}],"meta":{"page":1,"limit":10,"total":42,"totalPages":5}}
Riwayat mutasi ShopeePay yang diterima akunmu, dengan pagination dan filter. Hanya mutasi dari akun ShopeePay milikmu yang bisa dibaca.
| Parameter | Tipe | Status | Deskripsi |
|---|---|---|---|
page | integer | Opsional | Default: 1 |
limit | integer | Opsional | Default: 20, Maks: 100 |
account_id | string | Opsional | Filter per akun ShopeePay (id dari /api/mutasi/accounts) |
type | string | Opsional | CREDIT (masuk) / DEBIT (keluar) |
from | date | Opsional | Format YYYY-MM-DD (WIB) |
to | date | Opsional | Format YYYY-MM-DD (WIB) |
q | string | Opsional | Cari di keterangan / nominal |
curl "https://austinstore.id/api/mutasi?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&type=CREDIT&page=1&limit=20"
{"success":true,"data":[{"id":"uuid","account_ref":"uuid","account_name":"Toko Saya","merchant_id":"123456","type":"CREDIT","amount":25000,"description":"Pembayaran QR","balance":null,"fee":125,"fee_status":"paid","mutasi_at":"2026-07-08T03:42:00.000Z","received_at":"2026-07-08T03:42:03.000Z"}],"total":42,"page":1,"limit":20,"pages":3,"summary":{"count":42,"credit":1250000,"debit":300000}}
Mutasi terbaru (maks 50), cocok untuk polling. Kirim since berisi server_time dari response sebelumnya supaya hanya mutasi baru yang dikembalikan.
| Parameter | Tipe | Status | Deskripsi |
|---|---|---|---|
limit | integer | Opsional | Default: 20, Maks: 50 |
account_id | string | Opsional | Filter per akun ShopeePay |
since | datetime | Opsional | ISO 8601, hanya mutasi yang diterima setelah waktu ini |
curl "https://austinstore.id/api/mutasi/latest?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&limit=10"
{"success":true,"data":[{"id":"uuid","account_ref":"uuid","account_name":"Toko Saya","merchant_id":"123456","type":"CREDIT","amount":25000,"description":"Pembayaran QR","balance":null,"fee":125,"fee_status":"paid","mutasi_at":"2026-07-08T03:42:00.000Z","received_at":"2026-07-08T03:42:03.000Z"}],"server_time":"2026-07-08T03:45:00.000Z"}
Daftar akun ShopeePay yang terhubung beserta ringkasan mutasi hari ini.
curl "https://austinstore.id/api/mutasi/accounts?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
{"success":true,"data":[{"id":"uuid","phone":"08123456789","account_name":"Toko Saya","merchant_id":"123456","merchant_label":"Toko Saya","store_label":"Outlet 1","status":"active","total_mutations":42,"total_credit":1250000,"last_mutation_at":"2026-07-08T03:42:03.000Z","today":{"count":3,"credit":75000,"debit":0}}]}
Deposit
expired_at yang kamu terima selalu akurat untuk QR yang baru dibuat.
Generate QRIS dinamis untuk deposit saldo. Dibatasi 5 request/menit. Setelah QRIS dibuat, polling GET /deposit/check/:id dengan interval minimal 5 detik.
| Field | Tipe | Status | Deskripsi |
|---|---|---|---|
amount wajib | integer | Required | Nominal sebelum fee. Batas minimal/maksimal mengikuti pengaturan admin. |
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://austinstore.id/api/deposit/create?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ["Content-Type: application/json"],
CURLOPT_POSTFIELDS => json_encode([
"amount" => 50000,
]),
]);
$response = curl_exec($curl);
curl_close($curl);
$hasil = json_decode($response, true);
const res = await fetch("https://austinstore.id/api/deposit/create?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ amount: 50000 })
});
const data = await res.json();
console.log(data);
curl -X POST "https://austinstore.id/api/deposit/create?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"amount": 50000}'
{"success":true,"deposit":{"id":"uuid","transaction_id":"APG-A1B2C3D4","amount":50200,"unique_code":0,"fee":200,"qr_string":"00020101021226610016ID.CO.SHOPEE.WWW...6304XXXX","qr_image":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...","expired_at":"2026-06-27T10:20:00.000Z","status":"pending"}}
amount pada response sudah termasuk fee (0,4%) dan unique_code (0 secara default; menjadi 1, 2, dst. hanya jika nominal total sama dengan deposit lain yang sedang pending). Pastikan user membayar tepat sejumlah amount ini via QRIS. qr_image selalu base64 data URL yang di-generate di server kami, bukan URL gambar hosted eksternal.
Polling status pembayaran QRIS secara real-time. Jika status paid, saldo wallet otomatis ditambahkan. Lakukan polling dengan interval minimal 5 detik.
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://austinstore.id/api/deposit/check/APG-1751000000?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$response = curl_exec($curl);
curl_close($curl);
$hasil = json_decode($response, true);
const res = await fetch("https://austinstore.id/api/deposit/check/APG-1751000000?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
const data = await res.json();
console.log(data);
curl "https://austinstore.id/api/deposit/check/APG-1751000000?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
{"success":true,"status":"paid","message":"Deposit berhasil! Saldo telah ditambahkan."}
{"success":true,"status":"pending","message":"Menunggu pembayaran..."}
{"success":true,"status":"expired","message":"QRIS telah kadaluarsa."}
Batalkan deposit QRIS yang masih berstatus pending. Deposit yang sudah paid, expired, atau sudah dibatalkan sebelumnya tidak bisa dibatalkan ulang.
| Parameter | Tipe | Status | Deskripsi |
|---|---|---|---|
transactionId wajib | string | Required | ID transaksi yang didapat dari response POST /deposit/create. |
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://austinstore.id/api/deposit/cancel/APG-1751000000?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_TIMEOUT => 30,
]);
$response = curl_exec($curl);
curl_close($curl);
$hasil = json_decode($response, true);
const res = await fetch("https://austinstore.id/api/deposit/cancel/APG-1751000000?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", {
method: "POST"
});
const data = await res.json();
console.log(data);
curl -X POST "https://austinstore.id/api/deposit/cancel/APG-1751000000?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
{"success":true,"status":"cancel","message":"Deposit berhasil dibatalkan"}
{"success":false,"message":"Deposit tidak bisa dibatalkan (status: paid)"}
| Parameter | Tipe | Status | Deskripsi |
|---|---|---|---|
page | integer | Opsional | Default: 1 |
limit | integer | Opsional | Default: 10, Maks: 50 |
status | string | Opsional | pending / paid / expired |
search | string | Opsional | Cari berdasar transaction_id |
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://austinstore.id/api/deposit/history?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&page=1",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$response = curl_exec($curl);
curl_close($curl);
$hasil = json_decode($response, true);
const params = new URLSearchParams({
apikey: "apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
page: 1
});
const res = await fetch(`https://austinstore.id/api/deposit/history?${params}`);
const data = await res.json();
console.log(data);
curl "https://austinstore.id/api/deposit/history?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&page=1"
{"success":true,"data":[{"id":"uuid","transaction_id":"APG-1751000000","amount":50001,"fee":1500,"status":"paid","expired_at":"2026-06-27T10:15:00.000Z","paid_at":"2026-06-27T10:03:12.000Z","createdAt":"2026-06-27T10:00:00.000Z","updatedAt":"2026-06-27T10:03:12.000Z"}],"total":5,"page":1,"limit":10,"pages":1}
Withdraw
Penarikan saldo ke e-wallet atau rekening bank. Saldo dipotong saat request dibuat dan dikembalikan jika ditolak admin.
Daftar semua metode withdraw yang tersedia beserta fee masing-masing.
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://austinstore.id/api/withdraw/methods?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$response = curl_exec($curl);
curl_close($curl);
$hasil = json_decode($response, true);
const res = await fetch("https://austinstore.id/api/withdraw/methods?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
const data = await res.json();
console.log(data);
curl "https://austinstore.id/api/withdraw/methods?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
{"success":true,"methods":["Dana","GoPay","OVO","ShopeePay","LinkAja","BRI","BCA","Mandiri","BNI","BSI","CIMB"]}
Buat request withdraw baru. Saldo langsung dipotong (amount + fee) saat request dibuat, status pending menunggu approval admin. Jika ditolak, saldo dikembalikan otomatis.
| Field | Tipe | Status | Deskripsi |
|---|---|---|---|
amount wajib | integer | Required | Tanpa nominal minimal, harus lebih dari 0 |
method wajib | string | Required | Salah satu dari daftar methods, contoh: Dana |
account_number wajib | string | Required | Nomor HP / nomor rekening tujuan |
account_name wajib | string | Required | Nama pemilik akun tujuan |
note | string | Opsional | Catatan tambahan untuk admin |
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://austinstore.id/api/withdraw/create?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ["Content-Type: application/json"],
CURLOPT_POSTFIELDS => json_encode([
"amount" => 100000,
"method" => "Dana",
"account_number" => "081234567890",
"account_name" => "Muhlis Akbar",
"note" => "Withdraw gaji",
]),
]);
$response = curl_exec($curl);
curl_close($curl);
$hasil = json_decode($response, true);
const res = await fetch("https://austinstore.id/api/withdraw/create?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
amount: 100000,
method: "Dana",
account_number: "081234567890",
account_name: "Muhlis Akbar",
note: "Withdraw gaji"
})
});
const data = await res.json();
console.log(data);
curl -X POST "https://austinstore.id/api/withdraw/create?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"amount": 100000, "method": "Dana", "account_number": "081234567890", "account_name": "Muhlis Akbar", "note": "Withdraw gaji"}'
{"success":true,"message":"Request withdraw berhasil dikirim. Menunggu persetujuan admin.","withdraw_id":"uuid"}
GET /withdraw/methods untuk mendapatkan daftar method yang valid sebelum membuat request withdraw. Request dengan method tidak valid akan ditolak dengan 400.
Riwayat semua request withdraw milik akun.
| Parameter | Tipe | Status | Deskripsi |
|---|---|---|---|
page | integer | Opsional | Default: 1 |
limit | integer | Opsional | Default: 10 |
status | string | Opsional | pending / success / rejected |
Withdraw Instant
Penarikan saldo langsung ke e-wallet atau Virtual Account bank tanpa menunggu approval admin — saldo dipotong dan dana dikirim otomatis lewat provider secara real-time. Ada 2 tipe produk per wallet, dibedakan lewat flag open_denom di Products: Nominal Tetap (pilih dari katalog harga siap pakai) dan Bebas Nominal (tentukan sendiri nominalnya, dalam batas min–max).
Daftar wallet yang tersedia untuk withdraw instant dari provider yang sedang aktif, lengkap dengan tipe nomor tujuan dan tipe nominal yang didukung tiap wallet.
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://austinstore.id/api/instant-withdraw/wallets?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$response = curl_exec($curl);
curl_close($curl);
$hasil = json_decode($response, true);
const res = await fetch("https://austinstore.id/api/instant-withdraw/wallets?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
const data = await res.json();
console.log(data);
curl "https://austinstore.id/api/instant-withdraw/wallets?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
{"success":true,"wallets":["DANA","GoPay","ShopeePay","LinkAja","iSaku","Doku","Kaspro","AstraPay","Mandiri","BNI","BRI","CIMB","Permata"],"wallet_types":{"DANA":"phone","GoPay":"phone","ShopeePay":"phone","Mandiri":"va","BNI":"va"},"wallet_has_fixed":{"DANA":true,"GoPay":true,"ShopeePay":false,"Mandiri":false},"wallet_has_open_denom":{"DANA":true,"GoPay":true,"ShopeePay":true,"Mandiri":true}}
wallet_types: phone = nomor tujuan berupa nomor HP e-wallet, va = nomor tujuan berupa Nomor Virtual Account bank (Mandiri/BNI/BRI/CIMB/Permata).wallet_has_fixed: wallet itu punya katalog nominal tetap (baru DANA & GoPay yang punya ini — wallet lain false).wallet_has_open_denom: wallet itu bisa dipakai untuk Bebas Nominal. Wallet e-wallet lain (ShopeePay/LinkAja/iSaku/Doku/Kaspro/AstraPay) dan semua Virtual Account bank hanya punya jalur Bebas Nominal — wallet_has_fixed-nya selalu false.
Daftar produk yang tersedia untuk sebuah wallet — gabungan katalog Nominal Tetap (kalau ada) dan 1 item Bebas Nominal (kalau wallet-nya mendukung). Cek field open_denom tiap item untuk tahu cara pakainya di Create.
| Parameter | Tipe | Status | Deskripsi |
|---|---|---|---|
wallet wajib | string | Required | Salah satu dari wallets, contoh: DANA |
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://austinstore.id/api/instant-withdraw/products?wallet=DANA&apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$response = curl_exec($curl);
curl_close($curl);
$hasil = json_decode($response, true);
const params = new URLSearchParams({
wallet: "DANA",
apikey: "apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
});
const res = await fetch(`https://austinstore.id/api/instant-withdraw/products?${params}`);
const data = await res.json();
console.log(data);
curl "https://austinstore.id/api/instant-withdraw/products?wallet=DANA&apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
{"success":true,"products":[
{"code":"D1","name":"DANA 1.000","open_denom":false,"destination_type":"phone","nominal":1000,"cost_price":1050,"sell_price":1550},
{"code":"D10","name":"DANA 10.000","open_denom":false,"destination_type":"phone","nominal":10000,"cost_price":10050,"sell_price":10550},
{"code":"BBSDN","name":"DANA (Bebas Nominal)","open_denom":true,"destination_type":"phone","min":100,"max":10000000,"fee":50,"nominal":null,"cost_price":null,"sell_price":null}
]}
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://austinstore.id/api/instant-withdraw/products?wallet=ShopeePay&apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$response = curl_exec($curl);
curl_close($curl);
$hasil = json_decode($response, true);
const params = new URLSearchParams({
wallet: "ShopeePay",
apikey: "apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
});
const res = await fetch(`https://austinstore.id/api/instant-withdraw/products?${params}`);
const data = await res.json();
console.log(data);
curl "https://austinstore.id/api/instant-withdraw/products?wallet=ShopeePay&apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
{"success":true,"products":[
{"code":"BBSSH","name":"ShopeePay (Bebas Nominal)","open_denom":true,"destination_type":"phone","min":100,"max":10000000,"fee":500,"nominal":null,"cost_price":null,"sell_price":null}
]}
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://austinstore.id/api/instant-withdraw/products?wallet=Mandiri&apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$response = curl_exec($curl);
curl_close($curl);
$hasil = json_decode($response, true);
const params = new URLSearchParams({
wallet: "Mandiri",
apikey: "apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
});
const res = await fetch(`https://austinstore.id/api/instant-withdraw/products?${params}`);
const data = await res.json();
console.log(data);
curl "https://austinstore.id/api/instant-withdraw/products?wallet=Mandiri&apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
{"success":true,"products":[
{"code":"BBSVAMDR","name":"Virtual Account Mandiri (Bebas Nominal)","open_denom":true,"destination_type":"va","min":100,"max":10000000,"fee":2001,"nominal":null,"cost_price":null,"sell_price":null}
]}
open_denom:false, sell_price di response inilah harga potong saldo final — langsung pakai code-nya di Create. Untuk item open_denom:true, sell_price masih null karena harganya baru dihitung server saat Create dipanggil (tergantung nominal yang kamu kirim) — min/max/fee di sini cuma referensi.
Buat request withdraw instant. Saldo dipotong sesuai sell_price produk (nominal tetap) atau hasil kalkulasi nominal + fee + margin (Bebas Nominal) begitu request dibuat, lalu dieksekusi langsung ke provider — tidak ada tahap approval admin. Status akhir bisa langsung success, atau processing menyusul untuk provider yang async (lihat History untuk update terbaru). Jika provider menolak, saldo dikembalikan otomatis.
| Field | Tipe | Status | Deskripsi |
|---|---|---|---|
wallet wajib | string | Required | Salah satu dari wallets, contoh: DANA |
product_code wajib | string | Required | Kode dari Products — nominal tetap (mis. D10) atau kode Bebas Nominal (mis. BBSDN) |
phone wajib | string | Required | Nomor HP e-wallet tujuan, atau Nomor Virtual Account kalau destination_type wallet-nya va |
nominal | integer | Wajib untuk Bebas Nominal | Hanya dipakai kalau product_code adalah produk open_denom:true. Harus di antara min–max produk tersebut (umumnya Rp100 – Rp10.000.000). Diabaikan untuk produk nominal tetap. |
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://austinstore.id/api/instant-withdraw/create?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ["Content-Type: application/json"],
CURLOPT_POSTFIELDS => json_encode([
"wallet" => "DANA",
"product_code" => "D10",
"phone" => "081234567890",
]),
]);
$response = curl_exec($curl);
curl_close($curl);
$hasil = json_decode($response, true);
const res = await fetch("https://austinstore.id/api/instant-withdraw/create?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
wallet: "DANA",
product_code: "D10",
phone: "081234567890"
})
});
const data = await res.json();
console.log(data);
curl -X POST "https://austinstore.id/api/instant-withdraw/create?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"wallet": "DANA", "product_code": "D10", "phone": "081234567890"}'
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://austinstore.id/api/instant-withdraw/create?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ["Content-Type: application/json"],
CURLOPT_POSTFIELDS => json_encode([
"wallet" => "DANA",
"product_code" => "BBSDN",
"phone" => "081234567890",
"nominal" => 75000,
]),
]);
$response = curl_exec($curl);
curl_close($curl);
$hasil = json_decode($response, true);
const res = await fetch("https://austinstore.id/api/instant-withdraw/create?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
wallet: "DANA",
product_code: "BBSDN",
phone: "081234567890",
nominal: 75000
})
});
const data = await res.json();
console.log(data);
curl -X POST "https://austinstore.id/api/instant-withdraw/create?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"wallet": "DANA", "product_code": "BBSDN", "phone": "081234567890", "nominal": 75000}'
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://austinstore.id/api/instant-withdraw/create?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ["Content-Type: application/json"],
CURLOPT_POSTFIELDS => json_encode([
"wallet" => "Mandiri",
"product_code" => "BBSVAMDR",
"phone" => "8887001234567890",
"nominal" => 250000,
]),
]);
$response = curl_exec($curl);
curl_close($curl);
$hasil = json_decode($response, true);
const res = await fetch("https://austinstore.id/api/instant-withdraw/create?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
wallet: "Mandiri",
product_code: "BBSVAMDR",
phone: "8887001234567890",
nominal: 250000
})
});
const data = await res.json();
console.log(data);
curl -X POST "https://austinstore.id/api/instant-withdraw/create?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"wallet": "Mandiri", "product_code": "BBSVAMDR", "phone": "8887001234567890", "nominal": 250000}'
{"success":true,"message":"Transfer berhasil dikirim ke e-wallet tujuan","status":"success","id":"uuid"}
{"success":false,"message":"Nominal harus antara Rp100 - Rp10.000.000"}
product_code yang dipilih itu open_denom:true (butuh field nominal) atau false (harga sudah tetap, nominal diabaikan kalau dikirim). Format phone divalidasi beda tergantung destination_type wallet: nomor HP diawali 0 untuk e-wallet, format bebas 5–20 digit untuk Virtual Account. Verifikasi PIN dilewati untuk request via API key (PIN hanya berlaku untuk sesi dashboard web).
Riwayat semua request withdraw instant milik akun. Transaksi berstatus processing otomatis di-sync ke provider dulu sebelum data dikembalikan.
| Parameter | Tipe | Status | Deskripsi |
|---|---|---|---|
page | integer | Opsional | Default: 1 |
limit | integer | Opsional | Default: 10 |
status | string | Opsional | processing / success / failed |
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://austinstore.id/api/instant-withdraw/history?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&page=1&status=success",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$response = curl_exec($curl);
curl_close($curl);
$hasil = json_decode($response, true);
const params = new URLSearchParams({
apikey: "apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
page: 1,
status: "success"
});
const res = await fetch(`https://austinstore.id/api/instant-withdraw/history?${params}`);
const data = await res.json();
console.log(data);
curl "https://austinstore.id/api/instant-withdraw/history?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&page=1&status=success"
{"success":true,"data":[{"id":"uuid","user_id":"uuid","provider":"okeconnect","wallet":"DANA","phone":"081234567890","product_code":"D10","product_name":"DANA 10.000","nominal":10000,"cost_price":10050,"sell_price":10550,"status":"success","provider_response":"Transaksi berhasil diproses","createdAt":"2026-07-08T03:38:35.000Z","updatedAt":"2026-07-08T03:38:41.000Z"},{"id":"uuid","user_id":"uuid","provider":"vip","wallet":"ShopeePay","phone":"081298765432","product_code":"BBSSH","product_name":"ShopeePay (Bebas Nominal)","nominal":75000,"cost_price":75500,"sell_price":75650,"status":"processing","provider_response":null,"createdAt":"2026-07-08T02:10:12.000Z","updatedAt":"2026-07-08T02:10:15.000Z"}],"total":14,"page":1,"limit":10,"pages":2}
status:"processing" otomatis di-sync ke provider setiap kali endpoint ini dipanggil, jadi status/provider_response-nya bisa saja sudah berubah jadi success/failed di response dibanding request sebelumnya — tidak perlu polling manual ke provider lain.
Webhook
Alih-alih terus-menerus polling GET /deposit/check/:id, kamu bisa mendaftarkan URL server sendiri lewat menu Webhook di dashboard. AustinPay akan mengirim POST ke URL itu secara real-time setiap kali salah satu event di bawah terjadi.
2xx dalam 10 detik. Kalau gagal atau timeout, AustinPay otomatis retry hingga 3 kali dengan jeda 1–3 detik antar percobaan.
| Event | Terpicu Saat |
|---|---|
deposit.paid | QRIS deposit berhasil lunas (baik terdeteksi lewat polling maupun webhook gateway) |
withdraw.approved | Request withdraw disetujui admin |
withdraw.rejected | Request withdraw ditolak admin (saldo otomatis dikembalikan) |
mutasi.shopee | Mutasi baru masuk/keluar di akun ShopeePay yang kamu hubungkan (payload: mutationId, type, amount, description, balance, fee, mutationAt, dst.) |
Format Payload
Setiap request dikirim sebagai Content-Type: application/json, dibungkus dalam amplop yang sama untuk semua event:
{"event":"deposit.paid","data":{"transactionId":"APG-1751000000","amount":55000,"status":"paid","paidAt":"2026-07-08T03:38:35.000Z"},"sentAt":"2026-07-08T03:38:35.512Z"}
| Header | Deskripsi |
|---|---|
X-AustinPay-Event | Nama event, sama dengan field event di body |
X-AustinPay-Signature | HMAC-SHA256 (hex) dari raw body, ditandatangani pakai webhook secret milikmu |
Verifikasi Signature
Selalu verifikasi signature sebelum memproses payload, supaya request palsu (bukan dari AustinPay) tidak bisa memicu logika bisnis di server kamu.
const crypto = require('crypto');
app.post('/webhook/austinpay', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.headers['x-austinpay-signature'];
const secret = process.env.AUSTINPAY_WEBHOOK_SECRET;
const expected = crypto
.createHmac('sha256', secret)
.update(req.body) // raw Buffer, bukan hasil JSON.parse
.digest('hex');
const isValid = crypto.timingSafeEqual(
Buffer.from(signature, 'hex'),
Buffer.from(expected, 'hex')
);
if (!isValid) return res.status(401).json({ error: 'Invalid signature' });
const payload = JSON.parse(req.body);
// payload.event, payload.data, payload.sentAt
res.status(200).json({ success: true });
});
austinpay-webhook-example (Express.js) di bawah ini.
austinpay-webhook-example Error Codes
Semua error mengembalikan JSON dengan field success: false dan message berisi pesan deskriptif.
{"success":false,"message":"API Key tidak valid atau tidak ditemukan"}
| Pesan Error | HTTP | Endpoint | Penanganan |
|---|---|---|---|
API Key diperlukan |
401 | Semua Public API | Sertakan header X-API-Key |
API Key tidak valid |
401 | Semua | Periksa kembali nilai API Key di halaman Profil |
IP tidak terdaftar di whitelist |
403 | Semua Public API | Tambahkan IP server ke whitelist di halaman Profil |
Akun dibekukan |
403 | Semua | Hubungi admin |
Saldo tidak mencukupi |
400 | POST /withdraw/create |
Deposit saldo terlebih dahulu |
amount tidak valid |
400 | POST /deposit/create |
Nominal harus bilangan bulat positif sesuai min_deposit |
Transaksi tidak ditemukan |
404 | GET /deposit/check/:id |
Periksa nilai transactionId |
Deposit tidak bisa dibatalkan |
400 | POST /deposit/cancel/:id |
Deposit sudah paid, expired, atau sudah dibatalkan sebelumnya |
Internal server error |
500 | Semua | Retry dengan exponential backoff |