Dokumentasi API
Instanpay menyediakan API pembayaran QRIS dan Crypto (USDT/USDC) untuk merchant Indonesia. Semua endpoint menggunakan format JSON.
| Base URL | https://instanpay.my.id |
|---|---|
| Format | JSON |
| Versi | v2.0 |
Autentikasi
Semua permintaan ke endpoint /api/v1/* memerlukan API Key di header.
X-API-Key: sk_live_xxxxxxxxxxxxxxxx Content-Type: application/json
Rate Limit
Tidak ada batasan rate limit saat ini. Gunakan dengan wajar untuk menjaga stabilitas layanan.
1. Buat Pembayaran QRIS
POST /api/v1/payments
Request
{
"amount": 10000,
"customer_name": "Budi Santoso", // opsional
"webhook_url": "https://tokomu.com/webhook" // opsional
}
Response (200)
{
"success": true,
"data": {
"transactionId": "TXN-1751411106-652",
"qrisString": "0002010102112657...",
"qrCodeSvg": "<svg>...</svg>",
"baseAmount": 10000,
"uniqueCode": 652,
"totalAmount": 10652,
"baseFormatted": "Rp 10.000",
"totalFormatted": "Rp 10.652",
"expiredAt": "2026-07-14 10:30:00",
"status": "PENDING"
}
}
totalAmount, bukan baseAmount. Pembayaran tidak sesuai tidak akan terdeteksi.2. Cek Status Pembayaran QRIS
GET /api/v1/status/:transactionId
GET /api/v1/status/TXN-1751411106-652
Response (200)
{
"success": true,
"data": {
"transactionId": "TXN-1751411106-652",
"baseAmount": 10000,
"uniqueCode": 652,
"totalAmount": 10652,
"status": "PAID",
"expiredAt": "2026-07-14 10:30:00",
"paidAt": "2026-07-14 10:15:22"
}
}
| Status | Keterangan |
|---|---|
PENDING | Menunggu pembayaran |
PAID | Pembayaran berhasil dikonfirmasi |
EXPIRED | Kadaluarsa (2 jam) |
Webhook QRIS
Ketika pembayaran QRIS berhasil, sistem mengirim POST ke webhook URL yang dikonfigurasi.
Payload Webhook QRIS
{
"transactionId": "TXN-1751411106-652",
"status": "PAID",
"baseAmount": 10000,
"uniqueCode": 652,
"totalAmount": 10652,
"paidAt": "2026-07-14 10:15:22"
}
type. Gunakan ini untuk membedakan dengan webhook Crypto.Server Anda harus merespons HTTP 200. Timeout: 10 detik.
Ketentuan QRIS
| Aturan | Nilai |
|---|---|
| Nominal minimum | Rp 100 |
| Nominal maksimum | Rp 10.000.000 |
| Format nominal | Bilangan bulat, tidak boleh desimal |
| Kode unik | 500 - 999 (otomatis ditambahkan) |
| Masa berlaku | 2 jam sejak dibuat |
| Saldo yang masuk | baseAmount saja (kode unik tidak termasuk) |
3. Buat Order Crypto
POST /api/v1/crypto-payments
| Chain | Token | Jaringan |
|---|---|---|
| BSC | USDT, USDC | BNB Smart Chain |
| BASE | USDT, USDC | Base (Coinbase L2) |
| ETH | USDT, USDC | Ethereum Mainnet |
| POLYGON | USDT, USDC | Polygon PoS |
| SOL | USDT, USDC | Solana |
Request
{
"amount_usd": 5.00,
"chain": "BSC",
"token": "USDT",
"customer_name": "Budi Santoso", // opsional
"customer_email": "budi@mail.com" // opsional
}
Response (200)
{
"success": true,
"data": {
"transactionId": "CRYPTO-1751500000-AB1CD",
"gatewayOrderId": "ORD_MRKxxxx_XXXXXX",
"amount_usd": 5.00,
"chain": "BSC",
"token": "USDT",
"deposit_address": "0xAbCd...1234",
"status": "PENDING",
"expires_at": "2026-07-14T10:30:00.000Z",
"payment_url": "https://instanpay.my.id/pay/crypto/ORD_MRKxxxx"
}
}
Arahkan customer ke payment_url untuk tampilan QR code dan deep link wallet, atau tampilkan deposit_address secara langsung.
4. Cek Status Order Crypto
GET /api/v1/crypto-status/:id
Parameter id bisa berupa transactionId lokal (CRYPTO-xxx) atau gatewayOrderId (ORD_xxx).
GET /api/v1/crypto-status/CRYPTO-1751500000-AB1CD
Response (200)
{
"success": true,
"data": {
"transactionId": "CRYPTO-1751500000-AB1CD",
"gatewayOrderId": "ORD_MRKxxxx_XXXXXX",
"amount_usd": 5.00,
"chain": "BSC",
"token": "USDT",
"deposit_address": "0xAbCd...1234",
"status": "PAID",
"tx_hash": "0xabc123...def456",
"amount_received": "5.00",
"asset_received": "USDT",
"created_at": "2026-07-14T10:00:00.000Z",
"expires_at": "2026-07-14T10:30:00.000Z",
"paid_at": "2026-07-14T10:15:30.000Z",
"payment_url": "https://instanpay.my.id/pay/crypto/ORD_MRKxxxx"
}
}
| Status | Keterangan |
|---|---|
PENDING | Menunggu transfer on-chain |
PAID | Pembayaran dikonfirmasi on-chain |
EXPIRED | Kadaluarsa (30 menit) |
Webhook Crypto
Webhook Crypto dikirim ke URL webhook yang sama dengan QRIS. Bedakan keduanya dengan field type.
| Tipe Transaksi | Penanda |
|---|---|
| QRIS | Tidak ada field type |
| Crypto | "type": "CRYPTO" |
Payload Webhook Crypto
{
"transactionId": "CRYPTO-1751500000-AB1CD",
"status": "PAID",
"paidAt": "2026-07-14T10:15:30.000Z",
"type": "CRYPTO",
"gatewayOrderId": "ORD_MRKxxxx_XXXXXX",
"amount_usd": 5.00,
"chain": "BSC",
"token": "USDT",
"tx_hash": "0xabc123...def456",
"amount_received": "5.00",
"asset_received": "USDT"
}
Contoh Handler (Node.js)
app.post('/webhook', (req, res) => {
const payload = req.body;
if (payload.type === 'CRYPTO') {
// Transaksi crypto
console.log('Crypto PAID:', payload.amount_usd, payload.token, 'on', payload.chain);
console.log('TX Hash:', payload.tx_hash);
} else {
// Transaksi QRIS (tidak ada field type)
console.log('QRIS PAID:', payload.totalAmount, '| ID:', payload.transactionId);
}
res.sendStatus(200);
});
Ketentuan Crypto
| Aturan | Nilai |
|---|---|
| Nominal minimum | $0.01 USD |
| Token yang diterima | USDT, USDC |
| Masa berlaku | 30 menit sejak dibuat |
| Toleransi pembayaran | +/- 1% (misal order $5.00, bayar $4.95 = PAID) |
| Saldo yang masuk | amount_usd x 100 (contoh: $5.00 = +500 unit) |
Kode Error
| HTTP | Keterangan |
|---|---|
| 200 | Berhasil |
| 400 | Parameter tidak valid |
| 401 | API Key tidak valid atau tidak ada |
| 404 | Transaksi tidak ditemukan |
| 500 | Internal server error |
| 503 | Server monitor atau crypto gateway offline |
Contoh Kode
QRIS - Node.js
const axios = require('axios');
const apiKey = 'sk_live_xxxx';
// Buat pembayaran QRIS
const res = await axios.post('https://instanpay.my.id/api/v1/payments',
{ amount: 10000, customer_name: 'Budi' },
{ headers: { 'X-API-Key': apiKey } }
);
const { transactionId, qrCodeSvg, totalFormatted } = res.data.data;
// Cek status
const status = await axios.get(
'https://instanpay.my.id/api/v1/status/' + transactionId,
{ headers: { 'X-API-Key': apiKey } }
);
console.log(status.data.data.status); // PENDING | PAID | EXPIRED
Crypto - Node.js
const axios = require('axios');
const apiKey = 'sk_live_xxxx';
// Buat order crypto
const res = await axios.post('https://instanpay.my.id/api/v1/crypto-payments',
{ amount_usd: 5.00, chain: 'BSC', token: 'USDT' },
{ headers: { 'X-API-Key': apiKey } }
);
const { transactionId, deposit_address, payment_url } = res.data.data;
console.log('Arahkan customer ke:', payment_url);
// Cek status
const status = await axios.get(
'https://instanpay.my.id/api/v1/crypto-status/' + transactionId,
{ headers: { 'X-API-Key': apiKey } }
);
console.log(status.data.data.status); // PENDING | PAID | EXPIRED
QRIS - PHP
$ch = curl_init('https://instanpay.my.id/api/v1/payments');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode(['amount' => 10000]),
CURLOPT_HTTPHEADER => ['Content-Type: application/json', 'X-API-Key: sk_live_xxxx'],
CURLOPT_RETURNTRANSFER => true,
]);
$data = json_decode(curl_exec($ch), true)['data'];
echo "Total bayar: " . $data['totalFormatted'];
Crypto - PHP
$ch = curl_init('https://instanpay.my.id/api/v1/crypto-payments');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode(['amount_usd' => 5.00, 'chain' => 'BSC', 'token' => 'USDT']),
CURLOPT_HTTPHEADER => ['Content-Type: application/json', 'X-API-Key: sk_live_xxxx'],
CURLOPT_RETURNTRANSFER => true,
]);
$data = json_decode(curl_exec($ch), true)['data'];
echo "Deposit: " . $data['deposit_address'];
echo "URL: " . $data['payment_url'];
QRIS - Python
import requests
headers = {'X-API-Key': 'sk_live_xxxx'}
r = requests.post('https://instanpay.my.id/api/v1/payments',
json={'amount': 10000}, headers=headers)
data = r.json()['data']
print(f"Bayar: {data['totalFormatted']}")
Crypto - Python
import requests
headers = {'X-API-Key': 'sk_live_xxxx'}
r = requests.post('https://instanpay.my.id/api/v1/crypto-payments',
json={'amount_usd': 5.00, 'chain': 'BSC', 'token': 'USDT'},
headers=headers)
data = r.json()['data']
print(f"Deposit: {data['deposit_address']}")
print(f"URL Bayar: {data['payment_url']}")
Unduh Dokumentasi (.txt)