Dokumentasi API

Panduan teknis integrasi — create transaksi (QRIS & VA) dan callback. Mudah dibaca dan dipahami.

1. Get payment method
Endpoint

Method & URL

POST http://qrin.web.id/api/get-payment-method
Request Body

Kirim JSON dengan Content-Type: application/json

{
    "token_qrin": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
Parameter
ParameterTypeRequiredKeterangan
token_qrinStringYaToken QRIN dari Setting Merchant
Response
{
    "success": true,
    "message": "OK",
    "data": [
        {
            "payment_method": "qris",
            "payment_name": "QRIS",
            "merchant_cost": "0",
            "customer_cost": "750 + 0,7 %",
            "logo_url": "http://qrin.web.id/payment_metode/qr.png"
        },
        {
            "payment_method": "vabca",
            "payment_name": "Virtual Account BCA",
            "merchant_cost": "0",
            "customer_cost": "5000",
            "logo_url": "http://qrin.web.id/payment_metode/vabca.png"
        }
    ]
}

Gagal (422): validasi token_qrin

{
    "success": false,
    "message": "The token_qrin field is required.",
    "data": null
}

Gagal (401): token_qrin

{
    "success": false,
    "message": "The provided token_qrin is invalid or the merchant could not be found.",
    "data": null
}
2. Create Transaksi

Membuat transaksi pembayaran: set payment_method ke qris_nobu (QRIS Nobu), qris (QRIS Pronpay), atau salah satu VA Pronpay: vabri, vapermata, vamandiri, vabni, vabca, vabtn, vabjb, vamega, vabsi, vadki, vabankneo, vamaybank, vacimb, vadanamon. Minimum nominal request_payload.amount_value: qris_nobu, qris Rp 1.000, VA Rp 10.000. Isi amount_value sebagai bilangan bulat (tipe Number), mis. 1000 atau 10000, maks. 15 digit.

Endpoint

Method & URL

POST http://qrin.web.id/api/create-transaksi
Request Body

Kirim JSON dengan Content-Type: application/json

{
    "token_qrin": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "payment_method": "qris_nobu",
    "request_payload": {
        "no_ref_merchant": "TRX-123456789",
        "amount_value": 10000,
        "amount_currency": "IDR",
        "product_details": "[{\"name\":\"Nama Produk 1\",\"price\":10000}]",
        "validity": "60",
        "additional_info": {
            "customer_name": "Nama Pelanggan",
            "customer_email": "emailpelanggan@domain.com",
            "customer_phone": "081234567890"
        }
    }
}
Parameter
ParameterTypeRequiredKeterangan
token_qrinStringYaToken QRIN dari Setting Merchant
payment_methodStringYaqris_nobu (QRIS Nobu), qris (QRIS Pronpay), atau salah satu VA Pronpay: vabri, vapermata, vamandiri, vabni, vabca, vabtn, vabjb, vamega, vabsi, vadki, vabankneo, vamaybank, vacimb, vadanamon
request_payload.no_ref_merchantStringYaNomor referensi unik transaksi
request_payload.amount_valueNumberYaNominal IDR bilangan bulat (mis. 1000, 10000); maks. 15 digit. Minimum: qris_nobu, qris Rp 1.000, VA Rp 10.000.
request_payload.amount_currencyStringYaMata uang (wajib "IDR")
request_payload.product_detailsStringYaString berisi JSON array detail barang. Minimal tiap item: name dan price (lihat contoh request)
request_payload.validityStringYaDurasi kedaluwarsa transaksi dalam menit. Contoh: "10" = 10 menit, "60" = 1 jam, "1440" = 24 jam.
request_payload.additional_info.customer_nameStringOpsionalNama pelanggan. Jika diisi, panjang 5–100 karakter.
request_payload.additional_info.customer_emailStringOpsionalEmail pelanggan. Jika diisi, harus format email yang valid.
request_payload.additional_info.customer_phoneStringOpsionalNomor telepon pelanggan. Jika diisi, 8–13 karakter, diawali 08 atau 62.
Response

Saat success: true, message selalu "SUCCESS". data selalu flat: amount_value (nominal ke provider), merchant_cost / customer_cost (sesuai beban_biaya merchant), amount_currency, transaction_status, va_bank, va_number, qris_data, validity.

Berhasil — payment_method: "qris_nobu" (200 OK)

QRIS: isi gambar QR di data.qris_data; field VA akan null. Semua field ada langsung di level data.

{
    "success": true,
    "message": "SUCCESS",
    "data": {
        "no_ref_merchant": "TRX-123456789",
        "amount_value": 10000,
        "merchant_cost": 70,
        "customer_cost": 0,
        "amount_received": 9930,
        "amount_currency": "IDR",
        "transaction_status": "pending",
        "va_bank": null,
        "va_number": null,
        "qris_data": "00020101021226670016COM.NOBUBANK.WWW01189360050300000783000214260209000000050303UME51440014ID.CO.QRIS.WWW0303UME0215ID2026020900005520450395303360540810000.005802ID5921teca nusa UAT TESTING6006BEKASI61051773062750108MB1339LJ0622TRX-1234567890703A010804POSP99180002000108202602236304B480",
        "validity": "2026-03-01 15:30:00"
    }
}

Contoh request — payment_method: "vabni" (VA + validity, tanpa additional_info)

{
    "token_qrin": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "payment_method": "vabni",
    "request_payload": {
        "no_ref_merchant": "TRX-1775708041500-njdjyq1x",
        "amount_value": 10000,
        "amount_currency": "IDR",
        "product_details": "[{\"name\":\"Nama Produk 1\",\"price\":10000}]",
        "validity": "2026-04-10 11:14:09.056 +0700"
    }
}

Berhasil — VA Pronpay (contoh vabni)

VA: va_bank / va_number terisi dari provider Pronpay; qris_data null. Angka biaya mengikuti skema beban merchant.

{
    "success": true,
    "message": "SUCCESS",
    "data": {
        "no_ref_merchant": "TRX-1775708041500-njdjyq1x",
        "amount_value": 12125,
        "merchant_cost": 2125,
        "customer_cost": 2125,
        "amount_received": 7875,
        "amount_currency": "IDR",
        "transaction_status": "pending",
        "va_bank": "Virtual Account BNI",
        "va_number": "8919101279938347",
        "qris_data": null,
        "validity": "2026-04-10 11:14:09.056 +0700"
    }
}

Gagal (401): token_qrin

{
    "success": false,
    "message": "The provided token_qrin is invalid or the merchant could not be found.",
    "data": null
}

Contoh QR

Scan dengan aplikasi e-wallet / QRIS

3. Callback / Webhook

Setelah ada pembayaran atau perubahan status, QRIN mengirim data transaksi ke URL Callback yang Anda daftarkan di Setting Merchant. Body memuat status (sama dengan transaksis.status). Payload tidak menyertakan provider, payment_method, created_at, atau updated_at. Biaya admin: biaya_merchant, biaya_pelanggan, dan biaya (total). Untuk QRIS Nobu, jumlah_diterima mengikuti ketentuan admin (mis. nominal ≤ Rp 20.000: 0,7% dari jumlah_dibayar, dibulatkan ke atas ke rupiah penuh).

Cara kerja
  • QRIN mengirim POST ke URL callback merchant.
  • Body berisi JSON data transaksi (status, nominal, dll).
  • Header X-Callback-Signature = HMAC-SHA256(raw body, token_qrin) untuk validasi.
Status transaksi

Nilai field status:

  • pending — Menunggu
  • success — Berhasil
  • failed — Gagal
  • expired — Kadaluarsa
Header yang dikirim QRIN

Contoh header

Content-Type: application/json
X-Callback-Signature: <hmac_sha256>

X-Callback-Signature = HMAC-SHA256(raw body JSON, token_qrin).

Contoh payload (body) QRIN → Merchant

Contoh payload (selaras create transaksi QRIS, amount.value 10.000 — sukses bayar). tanggal_transaksi format YYYY-MM-DD HH:MM:SS (sama dengan database).

{
    "id": "ae0e42e0-b759-4cac-98da-9c0752152853",
    "tanggal_transaksi": "2026-03-28 11:47:15",
    "merchant_id": "04c9e242-3639-46bf-952a-e8221ef0cb5c",
    "no_referensi": "BILLHUB-260328-18018663",
    "no_ref_merchant": "TRX-123456789",
    "nama_pelanggan": "Nama Pelanggan",
    "email_pelanggan": "emailpelanggan@domain.com",
    "no_telpon_pelanggan": "081234567890",
    "biaya_merchant": 70,
    "biaya_pelanggan": 0,
    "biaya": 70,
    "jumlah_dibayar": 10000,
    "jumlah_diterima": 9930,
    "status": "success"
}
Contoh penanganan callback (PHP)

Gunakan token_qrin dari Setting Merchant untuk validasi signature.

<?php
$json = file_get_contents('php://input');
$callbackSignature = $_SERVER['HTTP_X_CALLBACK_SIGNATURE'] ?? '';
$tokenQrin = 'token_qrin_anda_dari_setting_merchant';
$signature = hash_hmac('sha256', $json, $tokenQrin);

if (!hash_equals($signature, $callbackSignature)) {
    header('Content-Type: application/json');
    echo json_encode(['success' => false, 'message' => 'Invalid signature']);
    exit;
}

$data = json_decode($json);
if (json_last_error() !== JSON_ERROR_NONE) {
    header('Content-Type: application/json');
    echo json_encode(['success' => false, 'message' => 'Invalid JSON']);
    exit;
}

$noRefMerchant = $data->no_ref_merchant;
$status       = $data->status;
// Update transaksi Anda berdasarkan no_ref_merchant

header('Content-Type: application/json');
echo json_encode(['success' => true]);