API Reference
https://austinstore.id
Documentation

AustinPay API

REST API untuk integrasi deposit QRIS, withdraw e-wallet & bank, dan manajemen akun. Semua endpoint mengembalikan JSON dengan field success (boolean).

Base URL: 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.

1

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.

2

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.

3

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.

Metode Pengiriman
Query Param (Direkomendasikan)
?apikey=apg_live_xxx
Header (Legacy)
X-API-Key: apg_live_xxx
Bearer Token
Authorization: Bearer apg_live_xxx
Contoh Request
php
$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);
javascript
const res = await fetch("https://austinstore.id/api/account?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxx");
const data = await res.json();
console.log(data);
curl
curl "https://austinstore.id/api/account?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxx"
Request Public API wajib memenuhi dua syarat sekaligus: API key valid & aktif, dan IP pengirim ada di whitelist. Jika salah satu tidak terpenuhi → 401/403.
4

(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.

Cara Menghitung Signature

Gabungkan 4 bagian berikut dengan newline (\n), lalu HMAC-SHA256 memakai API secret sebagai key, hasilnya dalam bentuk hex:

text
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.

Contoh (Node.js)
javascript
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,
});
Signature dihitung dari path murni (tanpa query string). Karena itu, kalau HMAC aktif, kirim API key lewat header X-API-Key — bukan ?apikey= di URL — supaya path yang kamu tanda-tangani sama persis dengan yang diverifikasi server.
API key tidak pernah disimpan dalam bentuk asli di server — hanya hash-nya. Jika key hilang atau bocor, nonaktifkan dari halaman Profil dan buat key baru.

Rate Limiting

Batasan request untuk menjaga kestabilan sistem dan mencegah penyalahgunaan.

EndpointLimitWindowKeterangan
/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).
Melampaui rate limit akan mengembalikan 429 Too Many Requests. Implementasikan exponential backoff sebelum retry.

User

Informasi akun dan riwayat transaksi pemilik API key.

GET
/api/account
API Key

Info lengkap akun pemilik API key — username, email, role, status, dan saldo wallet.

Contoh Request
php
$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);
javascript
const res = await fetch("https://austinstore.id/api/account?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
const data = await res.json();
console.log(data);
curl
curl "https://austinstore.id/api/account?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Response
json · 200 OK
{"success":true,"user":{"id":"uuid","username":"austi","email":"austi@example.com","role":"user","status":"active","wallet":{"balance":150000}}}
GET
/api/transactions
API Key

Riwayat semua transaksi dengan pagination dan filter.

Query Parameters
ParameterTipeStatusDeskripsi
pageintegerOpsionalDefault: 1
limitintegerOpsionalDefault: 10, Maks: 50
typestringOpsionaldeposit / withdraw / adjustment
statusstringOpsionalpending / success / failed
date_fromdateOpsionalFormat YYYY-MM-DD
date_todateOpsionalFormat YYYY-MM-DD
Contoh Request
php
$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);
javascript
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
curl "https://austinstore.id/api/transactions?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&page=1&limit=10"
Response
json · 200 OK
{"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}}
GET
/api/mutasi
API Key

Riwayat mutasi ShopeePay yang diterima akunmu, dengan pagination dan filter. Hanya mutasi dari akun ShopeePay milikmu yang bisa dibaca.

Query Parameters
ParameterTipeStatusDeskripsi
pageintegerOpsionalDefault: 1
limitintegerOpsionalDefault: 20, Maks: 100
account_idstringOpsionalFilter per akun ShopeePay (id dari /api/mutasi/accounts)
typestringOpsionalCREDIT (masuk) / DEBIT (keluar)
fromdateOpsionalFormat YYYY-MM-DD (WIB)
todateOpsionalFormat YYYY-MM-DD (WIB)
qstringOpsionalCari di keterangan / nominal
Contoh Request
curl
curl "https://austinstore.id/api/mutasi?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&type=CREDIT&page=1&limit=20"
Response
json · 200 OK
{"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}}
GET
/api/mutasi/latest
API Key

Mutasi terbaru (maks 50), cocok untuk polling. Kirim since berisi server_time dari response sebelumnya supaya hanya mutasi baru yang dikembalikan.

Query Parameters
ParameterTipeStatusDeskripsi
limitintegerOpsionalDefault: 20, Maks: 50
account_idstringOpsionalFilter per akun ShopeePay
sincedatetimeOpsionalISO 8601, hanya mutasi yang diterima setelah waktu ini
Contoh Request
curl
curl "https://austinstore.id/api/mutasi/latest?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&limit=10"
Response
json · 200 OK
{"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"}
GET
/api/mutasi/accounts
API Key

Daftar akun ShopeePay yang terhubung beserta ringkasan mutasi hari ini.

Contoh Request
curl
curl "https://austinstore.id/api/mutasi/accounts?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Response
json · 200 OK
{"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

Masa berlaku QR mengikuti pengaturan di sisi admin, tapi field expired_at yang kamu terima selalu akurat untuk QR yang baru dibuat.
POST
/api/deposit/create
API Key

Generate QRIS dinamis untuk deposit saldo. Dibatasi 5 request/menit. Setelah QRIS dibuat, polling GET /deposit/check/:id dengan interval minimal 5 detik.

Request Body
FieldTipeStatusDeskripsi
amount wajibintegerRequiredNominal sebelum fee. Batas minimal/maksimal mengikuti pengaturan admin.
Contoh Request
php
$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);
javascript
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
curl -X POST "https://austinstore.id/api/deposit/create?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"amount": 50000}'
Response
json · 200 OK
{"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.
GET
/api/deposit/check/:transactionId
API Key

Polling status pembayaran QRIS secara real-time. Jika status paid, saldo wallet otomatis ditambahkan. Lakukan polling dengan interval minimal 5 detik.

Contoh Request
php
$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);
javascript
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
curl "https://austinstore.id/api/deposit/check/APG-1751000000?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Response
json · 200 OK
{"success":true,"status":"paid","message":"Deposit berhasil! Saldo telah ditambahkan."}
json · 200 OK
{"success":true,"status":"pending","message":"Menunggu pembayaran..."}
json · 200 OK
{"success":true,"status":"expired","message":"QRIS telah kadaluarsa."}
paid pending expired
POST
/api/deposit/cancel/:transactionId
API Key

Batalkan deposit QRIS yang masih berstatus pending. Deposit yang sudah paid, expired, atau sudah dibatalkan sebelumnya tidak bisa dibatalkan ulang.

Path Parameters
ParameterTipeStatusDeskripsi
transactionId wajibstringRequiredID transaksi yang didapat dari response POST /deposit/create.
Contoh Request
php
$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);
javascript
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
curl -X POST "https://austinstore.id/api/deposit/cancel/APG-1751000000?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Response
json · 200 OK
{"success":true,"status":"cancel","message":"Deposit berhasil dibatalkan"}
json · 200 OK
{"success":false,"message":"Deposit tidak bisa dibatalkan (status: paid)"}
Bersifat atomik terhadap proses pembayaran — jika deposit kebetulan baru saja lunas (dibayar user / webhook masuk) tepat sebelum request cancel diproses, pembatalan akan ditolak dan saldo tetap dikreditkan.
Deposit QRIS memakai QRIS statis yang tidak punya endpoint pembatalan di sisi provider, jadi cancel di sini hanya menghentikan status di sistem kami — QR code fisiknya tetap bisa dipindai & dibayar sampai masa berlaku aslinya habis (maksimal 5 menit sejak dibuat). Kalau tetap dibayar setelah dibatalkan, dana tetap masuk ke rekening penerima tapi tidak otomatis dikreditkan ke wallet manapun — akan tercatat sebagai orphan mutasi untuk direkonsiliasi manual oleh admin, plus notifikasi Telegram otomatis.
GET
/api/deposit/history
API Key
Query Parameters
ParameterTipeStatusDeskripsi
pageintegerOpsionalDefault: 1
limitintegerOpsionalDefault: 10, Maks: 50
statusstringOpsionalpending / paid / expired
searchstringOpsionalCari berdasar transaction_id
Contoh Request
php
$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);
javascript
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
curl "https://austinstore.id/api/deposit/history?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&page=1"
Response
json · 200 OK
{"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.

GET
/api/withdraw/methods
API Key

Daftar semua metode withdraw yang tersedia beserta fee masing-masing.

Contoh Request
php
$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);
javascript
const res = await fetch("https://austinstore.id/api/withdraw/methods?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
const data = await res.json();
console.log(data);
curl
curl "https://austinstore.id/api/withdraw/methods?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Response
json · 200 OK
{"success":true,"methods":["Dana","GoPay","OVO","ShopeePay","LinkAja","BRI","BCA","Mandiri","BNI","BSI","CIMB"]}
POST
/api/withdraw/create
API Key

Buat request withdraw baru. Saldo langsung dipotong (amount + fee) saat request dibuat, status pending menunggu approval admin. Jika ditolak, saldo dikembalikan otomatis.

Request Body
FieldTipeStatusDeskripsi
amount wajibintegerRequiredTanpa nominal minimal, harus lebih dari 0
method wajibstringRequiredSalah satu dari daftar methods, contoh: Dana
account_number wajibstringRequiredNomor HP / nomor rekening tujuan
account_name wajibstringRequiredNama pemilik akun tujuan
notestringOpsionalCatatan tambahan untuk admin
Contoh Request
php
$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);
javascript
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
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"}'
Response
json · 200 OK
{"success":true,"message":"Request withdraw berhasil dikirim. Menunggu persetujuan admin.","withdraw_id":"uuid"}
Gunakan GET /withdraw/methods untuk mendapatkan daftar method yang valid sebelum membuat request withdraw. Request dengan method tidak valid akan ditolak dengan 400.
GET
/api/withdraw/history
API Key

Riwayat semua request withdraw milik akun.

Query Parameters
ParameterTipeStatusDeskripsi
pageintegerOpsionalDefault: 1
limitintegerOpsionalDefault: 10
statusstringOpsionalpending / success / rejected
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).

Karena tanpa approval manual dan tanpa verifikasi PIN untuk request via API key, jaga kerahasiaan API key kamu dan aktifkan IP Whitelist di menu Keamanan dashboard.
GET
/api/instant-withdraw/wallets
API Key

Daftar wallet yang tersedia untuk withdraw instant dari provider yang sedang aktif, lengkap dengan tipe nomor tujuan dan tipe nominal yang didukung tiap wallet.

Contoh Request
php
$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);
javascript
const res = await fetch("https://austinstore.id/api/instant-withdraw/wallets?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
const data = await res.json();
console.log(data);
curl
curl "https://austinstore.id/api/instant-withdraw/wallets?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Response
json · 200 OK
{"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.
GET
/api/instant-withdraw/products
API Key

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.

Query Parameters
ParameterTipeStatusDeskripsi
wallet wajibstringRequiredSalah satu dari wallets, contoh: DANA
Contoh Request — wallet dengan Nominal Tetap (DANA / GoPay)
php
$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);
javascript
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
curl "https://austinstore.id/api/instant-withdraw/products?wallet=DANA&apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Response
json · 200 OK
{"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}
]}
Contoh Request — wallet Bebas Nominal saja (ShopeePay, LinkAja, iSaku, Doku, Kaspro/KAI Pay, AstraPay)
php
$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);
javascript
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
curl "https://austinstore.id/api/instant-withdraw/products?wallet=ShopeePay&apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Response
json · 200 OK
{"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}
]}
Contoh Request — Virtual Account bank (Mandiri, BNI, BRI, CIMB, Permata)
php
$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);
javascript
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
curl "https://austinstore.id/api/instant-withdraw/products?wallet=Mandiri&apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Response
json · 200 OK
{"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}
]}
Untuk item 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.
POST
/api/instant-withdraw/create
API Key

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.

Request Body
FieldTipeStatusDeskripsi
wallet wajibstringRequiredSalah satu dari wallets, contoh: DANA
product_code wajibstringRequiredKode dari Products — nominal tetap (mis. D10) atau kode Bebas Nominal (mis. BBSDN)
phone wajibstringRequiredNomor HP e-wallet tujuan, atau Nomor Virtual Account kalau destination_type wallet-nya va
nominalintegerWajib untuk Bebas NominalHanya 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.
Contoh Request — Nominal Tetap (DANA/GoPay)
php
$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);
javascript
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
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"}'
Contoh Request — Bebas Nominal (e-wallet, mis. DANA/ShopeePay/dst)
php
$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);
javascript
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
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}'
Contoh Request — Bebas Nominal Virtual Account bank
php
$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);
javascript
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
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}'
Response
json · 200 OK
{"success":true,"message":"Transfer berhasil dikirim ke e-wallet tujuan","status":"success","id":"uuid"}
Response — Error Umum
json · 200 OK
{"success":false,"message":"Nominal harus antara Rp100 - Rp10.000.000"}
Selalu cek Products dulu untuk tahu apakah 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).
GET
/api/instant-withdraw/history
API Key

Riwayat semua request withdraw instant milik akun. Transaksi berstatus processing otomatis di-sync ke provider dulu sebelum data dikembalikan.

Query Parameters
ParameterTipeStatusDeskripsi
pageintegerOpsionalDefault: 1
limitintegerOpsionalDefault: 10
statusstringOpsionalprocessing / success / failed
processing success failed
Contoh Request
php
$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);
javascript
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
curl "https://austinstore.id/api/instant-withdraw/history?apikey=apg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&page=1&status=success"
Response
json · 200 OK
{"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}
Transaksi 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.

Server tujuan wajib membalas HTTP 2xx dalam 10 detik. Kalau gagal atau timeout, AustinPay otomatis retry hingga 3 kali dengan jeda 1–3 detik antar percobaan.
Daftar Event
EventTerpicu Saat
deposit.paidQRIS deposit berhasil lunas (baik terdeteksi lewat polling maupun webhook gateway)
withdraw.approvedRequest withdraw disetujui admin
withdraw.rejectedRequest withdraw ditolak admin (saldo otomatis dikembalikan)
mutasi.shopeeMutasi 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:

json · deposit.paid
{"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 yang Dikirim
HeaderDeskripsi
X-AustinPay-EventNama event, sama dengan field event di body
X-AustinPay-SignatureHMAC-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.

javascript
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 });
});
Butuh contoh server penerima yang sudah lengkap dan siap-pakai? Clone repo austinpay-webhook-example (Express.js) di bawah ini.
austinpay-webhook-example
Contoh server penerima webhook (Express.js) yang siap-pakai — clone langsung dari GitHub

Error Codes

Semua error mengembalikan JSON dengan field success: false dan message berisi pesan deskriptif.

Format Error
json
{"success":false,"message":"API Key tidak valid atau tidak ditemukan"}
Kode HTTP
200
OK
Request berhasil diproses.
400
Bad Request
Parameter tidak valid atau tidak lengkap.
401
Unauthorized
API Key tidak ada, tidak valid, atau tidak ditemukan.
403
Forbidden
Akun diblokir atau IP tidak ada di whitelist.
404
Not Found
Resource (user/transaksi) tidak ditemukan.
429
Too Many Requests
Rate limit terlampaui. Terapkan exponential backoff.
500
Server Error
Kesalahan internal server. Coba lagi dalam beberapa saat.
Pesan Error Umum
Pesan ErrorHTTPEndpointPenanganan
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

© 2026 AustinPay. Semua hak cipta dilindungi.

Butuh bantuan? Buka Profil atau hubungi admin.