Payment Gateway QRIS API

Dokumentasi resmi REST API VPay untuk integrasi pembayaran QRIS dinamis secara real-time ke sistem Anda.

Base URL: https://VPay.id/api

API Key Unik

Autentikasi aman per merchant dengan Bearer Token.

QRIS Dinamis

Generate QR code unik per transaksi instant.

Saldo Real-time

Dana masuk hitungan detik, cek saldo kapan saja.

Autentikasi

Setiap request ke API VPay memerlukan API Key yang dikirim melalui HTTP Header Authorization.

Peringatan Keamanan: Jangan pernah mengekspos API Key Anda di frontend (browser, aplikasi mobile client-side). Lakukan request API hanya dari server backend Anda.
Authorization: Bearer YOUR_API_KEY_HERE

Cara Mulai

  1. Daftar akun di Portal Merchant VPay.
  2. Dapatkan API Key di halaman Dashboard.
  3. Integrasikan endpoint /api/pg/create untuk membuat QRIS pembayaran.
  4. Tampilkan qr_image (URL gambar) ke user Anda.
  5. Cek status pembayaran berkala via /api/pg/check/:id (polling) atau gunakan Webhook (coming soon).
  6. Jika status paid, berikan layanan/produk ke user Anda.

Buat QRIS

POST /api/pg/create

Membuat tagihan baru dan menghasilkan QRIS statis berbentuk gambar.

Request Body (JSON)

FieldTypeWajibDeskripsi
amountintegerYaNominal pembayaran (min: 1000)
ref_idstringTidakID referensi sistem Anda (max 50 char)

Response Sukses (200 OK)

{
  "success": true,
  "data": {
    "id": "pg_abc123xyz",
    "amount": 50000,
    "unique_code": 45,
    "total": 50045,
    "qr_image": "https://VPay.id/qr/pg_abc123xyz.png",
    "status": "pending",
    "created_at": "2024-03-10T10:00:00Z"
  }
}

Cek Status

GET /api/pg/check/:id

Mengecek status pembayaran berdasarkan ID transaksi.

Response (Belum Bayar)

{
  "success": true,
  "data": {
    "id": "pg_abc123xyz",
    "status": "pending",
    "total": 50045
  }
}

Response (Sudah Bayar)

{
  "success": true,
  "data": {
    "id": "pg_abc123xyz",
    "status": "paid",
    "total": 50045,
    "paid_at": "2024-03-10T10:05:12Z",
    "available_at": "2024-03-10T10:05:12Z"
  }
}

Riwayat Transaksi

GET /api/pg/history

Mendapatkan daftar 50 transaksi terakhir.

{
  "success": true,
  "data": [
    {
      "id": "pg_abc123xyz",
      "amount": 50000,
      "status": "paid",
      "created_at": "..."
    },
    // ...
  ]
}

Tabel Status

StatusDeskripsi
pendingMenunggu pembayaran dari user. QRIS masih aktif.
paidPembayaran berhasil diterima. Dana sudah ditambahkan ke saldo.
expiredWaktu pembayaran habis (default 24 jam).

Perhitungan Fee

VPay menggunakan model pricing transparan:

Contoh Kalkulasi

Amount yang direquest: Rp 100.000
Kode unik (random)   : Rp 23
Total tagihan user   : Rp 100.023

Perhitungan Fee:
Flat fee       : Rp 100
MDR (0.3%)     : Rp 300 (dari 100.000)
Total Fee      : Rp 400

Saldo Masuk ke Merchant:
= Total Tagihan - Total Fee
= 100.023 - 400
= Rp 99.623

List Produk

GET /api/products

Mendapatkan daftar produk yang tersedia di Toko App, dikelompokkan berdasarkan kategori.

{
  "success": true,
  "data": [
    {
      "id": 1,
      "name": "Layanan Premium",
      "icon": "📦",
      "products": [
        {
          "id": 1,
          "name": "Netflix Premium 1 Bulan",
          "price": 35000,
          "stock": 10
        }
      ]
    }
  ]
}

Beli Produk

POST /api/products/buy

Membeli produk dari Toko App menggunakan saldo merchant.

FieldTypeWajibDeskripsi
product_idintegerYaID produk yang ingin dibeli
qtyintegerTidakJumlah produk (default 1)

Response Sukses

{
  "success": true,
  "data": {
    "order_id": 12,
    "product_name": "Netflix Premium 1 Bulan",
    "amount": 35000,
    "license_keys": ["VITO-XXXX-XXXX-XXXX"],
    "balance_remaining": 115000
  }
}

Info Akun

GET /api/merchant/me
{
  "success": true,
  "data": {
    "merchant_name": "Toko Online Budi",
    "balance": 1500000,
    "pending_balance": 0,
    "api_key": "vito_live_xxxxxxxx..."
  }
}

Statistik

GET /api/merchant/stats
{
  "success": true,
  "data": {
    "total_transactions": 145,
    "success_rate": "92.5%",
    "revenue_today": 450000
  }
}

Tarik Saldo

POST /api/merchant/withdraw
FieldTypeDeskripsi
amountintegerNominal penarikan (min 50.000)
methodstringKode bank (cth: BCA, MANDIRI, BRI, BNI, GOPAY, OVO, DANA)
account_namestringNama pemilik rekening
account_numberstringNomor rekening / e-wallet

Node.js Example

const fetch = require('node-fetch');

const API_KEY = 'vito_live_YOUR_KEY';
const BASE_URL = 'https://VPay.id/api';

async function createQRIS() {
    // 1. Create Transaction
    const response = await fetch(`${BASE_URL}/pg/create`, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'Authorization': `Bearer ${API_KEY}`
        },
        body: JSON.stringify({ amount: 50000, ref_id: 'ORDER-123' })
    });
    const result = await response.json();
    
    if(!result.success) return console.error(result.message);
    console.log('QRIS URL:', result.data.qr_image);

    // 2. Poll Status every 5 seconds
    const interval = setInterval(async () => {
        const checkRes = await fetch(`${BASE_URL}/pg/check/${result.data.id}`, {
            headers: { 'Authorization': `Bearer ${API_KEY}` }
        });
        const checkData = await checkRes.json();
        
        if(checkData.data.status === 'paid') {
            console.log('Payment Received!');
            clearInterval(interval);
        }
    }, 5000);
}

Python Example

import requests
import time

API_KEY = 'vito_live_YOUR_KEY'
BASE_URL = 'https://VPay.id/api'
headers = {'Authorization': f'Bearer {API_KEY}'}

# Create
res = requests.post(f'{BASE_URL}/pg/create', json={'amount': 50000}, headers=headers)
data = res.json()

if data.get('success'):
    txn_id = data['data']['id']
    print(f"QR Code URL: {data['data']['qr_image']}")
    
    # Check
    while True:
        check = requests.get(f'{BASE_URL}/pg/check/{txn_id}', headers=headers).json()
        if check['data']['status'] == 'paid':
            print("Paid successfully!")
            break
        time.sleep(5)

PHP Example

<?php
$api_key = 'vito_live_YOUR_KEY';

$ch = curl_init('https://VPay.id/api/pg/create');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => json_encode(['amount' => 50000]),
    CURLOPT_HTTPHEADER => [
        'Content-Type: application/json',
        'Authorization: Bearer ' . $api_key
    ]
]);

$response = json_decode(curl_exec($ch), true);
if($response['success']) {
    echo "Scan URL: " . $response['data']['qr_image'];
}
?>

cURL Examples

Create QRIS

curl -X POST https://VPay.id/api/pg/create \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"amount": 50000}'

Check Status

curl -X GET https://VPay.id/api/pg/check/pg_abc123xyz \
  -H "Authorization: Bearer YOUR_API_KEY"

History

curl -X GET https://VPay.id/api/pg/history \
  -H "Authorization: Bearer YOUR_API_KEY"

Withdraw

curl -X POST https://VPay.id/api/merchant/withdraw \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"amount":100000, "method":"BCA", "account_name":"BUDI", "account_number":"1234567890"}'

Error & HTTP Status

HTTP StatusDeskripsiPenyebab Umum
401 UnauthorizedAkses DitolakAPI Key salah, kosong, atau format Bearer tidak sesuai.
400 Bad RequestFormat SalahAmount kurang dari minimal, tipe data salah.
404 Not FoundData Tidak DitemukanID Transaksi tidak valid saat cek status.
402 Payment RequiredSaldo Tidak CukupSaat melakukan penarikan (withdraw).
500 Internal ErrorGangguan ServerKesalahan di sistem VPay. Silakan coba lagi.