BayarOn BayarOn API

BayarOn API Documentation

REST API untuk terima pembayaran via QRIS, Virtual Account 8 bank, dan Indomaret. Pakai Bearer token authentication. Response JSON.

Base URL

api.bayaron.com

Auth

Bearer Token

Format

JSON

Authentication

Semua endpoint kecuali public payment + auth public-flow butuh header Authorization: Bearer {token}.

Token didapat dari POST /auth/login atau POST /auth/register.

Authorization: Bearer 5|abc123xyz...
Accept: application/json
Content-Type: application/json

Quick Start โ€” Buat Payment Link

3 langkah dari nol ke first transaction:

Step 1 ยท Login dapet token

curl -X POST https://api.bayaron.com/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"[email protected]","password":"password123"}'

# Response: { "token": "5|abc...", "user": {...}, "merchant": {...} }

Step 2 ยท Bikin payment

curl -X POST https://api.bayaron.com/payments \
  -H "Authorization: Bearer 5|abc..." \
  -H "Content-Type: application/json" \
  -d '{
    "items": [{"name":"Premium Plan","qty":1,"price":99000}],
    "buyer_name": "Budi",
    "buyer_email": "[email protected]",
    "buyer_phone": "081234567890"
  }'

# Response: {
#   "transaction": { "reference_id": "BYRN-01K...", "amount_total":99000, ... },
#   "payment_url": "https://bayaron.com/p/BYRN-01K...",
#   "session_id": "..."
# }

๐Ÿ’ก Pakai https://bayaron.com/p/{reference_id} sebagai shareable link โ€” buyer dapat splash branded BayarOn lalu auto-checkout di domain kamu.

Step 3 ยท Receive webhook saat paid

Set webhook URL kamu di POST /merchant/webhook, BayarOn auto-forward callback iPaymu ke endpoint kamu dengan signature HMAC verifiable.

# Body BayarOn kirim ke webhook URL kamu:
{
  "event": "payment.paid",
  "merchant_id": "...",
  "occurred_at": "2026-05-12T14:30:00+07:00",
  "transaction": {
    "reference_id": "BYRN-...",
    "amount_total": 99000,
    "amount_merchant": 96525,
    "fee_amount": 2475,
    "status": "paid",
    "payment_channel": "qris",
    ...
  }
}

# Headers:
# X-BayarOn-Event: payment.paid
# X-BayarOn-Signature: a1b2c3...  (HMAC SHA256 of body, signed with webhook_secret)
# X-BayarOn-Delivery: {uuid}

Mode Uji (Sandbox)

Uji seluruh alur integrasi โ€” buat transaksi, picu status, terima webhook โ€” tanpa uang bergerak dan tanpa memanggil gateway asli. Mode ditentukan oleh token, bukan oleh isi request: token uji tidak bisa membuat tagihan sungguhan, dan token produksi tidak bisa membuat transaksi uji. Jadi kredensial yang tertukar gagal seketika, bukan diam-diam berhasil.

Transaksi uji tidak masuk saldo, omzet, maupun statistik. Kamu bisa menguji seharian tanpa mengotori angka dashboard.

Step 1 ยท Ambil token uji

Lewat dashboard: API & Integrasi โ†’ Generate Token โ†’ pilih mode Uji (sandbox). Atau lewat API pakai token live kamu:

curl -X POST https://api.bayaron.com/merchant/api-tokens \
  -H "Authorization: Bearer 5|token-live-kamu..." \
  -H "Content-Type: application/json" \
  -d '{"name":"Integrasi Dev","mode":"sandbox"}'

# Response: { "mode": "sandbox", "token": "9|uji-xxx...", ... }
# โš ๏ธ token ditampilkan SEKALI โ€” simpan sekarang.

๐Ÿ’ก Token dari /auth/login selalu live. Mode uji hanya dari token yang dibuat dengan "mode":"sandbox". Lencana mode di daftar token dibaca dari kemampuan token, bukan dari namanya โ€” token bernama "Sandbox Test" bisa saja token live.

Step 2 ยท Buat transaksi uji

Sama persis dengan POST /payments biasa โ€” cukup pakai token uji. Gateway asli (QRIS/VA) tidak dipanggil, jadi tidak ada sesi bayar sungguhan yang bisa terlanjur dibayar orang.

curl -X POST https://api.bayaron.com/payments \
  -H "Authorization: Bearer 9|uji-xxx..." \
  -H "Content-Type: application/json" \
  -d '{
    "items": [{"name":"Uji Coba","qty":1,"price":10000}],
    "buyer_name": "Tester",
    "buyer_email": "[email protected]",
    "buyer_phone": "081200000000"
  }'

# Response: transaction.reference_id "BYRN-...", is_sandbox: true, status "pending"

Step 3 ยท Picu status & terima webhook

Ubah status transaksi uji secara manual untuk menguji handler webhook kamu. Webhook sungguhan langsung diantrekan ke URL kamu.

curl -X POST https://api.bayaron.com/payments/BYRN-.../simulasi \
  -H "Authorization: Bearer 9|uji-xxx..." \
  -H "Content-Type: application/json" \
  -d '{"status":"paid"}'

# status valid: "paid" | "expired" | "failed"
# โ†’ event webhook: payment.paid | payment.expired | payment.failed

Response menyertakan akan_dikirim โ€” false berarti kamu belum berlangganan peristiwa itu, jadi webhook memang tidak akan datang (bukan endpoint kamu yang rusak). Endpoint ini hanya untuk transaksi uji; dipanggil pada transaksi sungguhan โ†’ 422 bukan_transaksi_sandbox.

Signature webhook

Di sandbox, signature webhook bersifat warn-only โ€” test webhook yang belum ditandatangani tetap diproses. Di produksi signature wajib valid.

Batas token uji

Token uji diblokir dari /withdrawals dan seluruh grup /merchant (403 TOKEN_UJI_DITOLAK). Bikin/kelola token & webhook pakai token live.

Auth Endpoints

POST/auth/register

Buat akun + merchant baru. Return Sanctum token.

Body: name, email, phone, password, password_confirmation, business_category (wajib: toko_online | smm_panel | voucher_game), business_name, business_email, business_phone, business_website

BayarOn hanya menerima ketiga industri di atas, dan usahanya harus berbasis website โ€” tautan Telegram/WhatsApp ditolak.

Rate limit: 10/jam per IP

POST/auth/login

Get bearer token. Body: email, password, device_name (optional).

Rate limit: 20/15min

GET/auth/me

Current user + merchant info. Auth required.

POST/auth/logout

Revoke current token. Auth required.

POST/auth/forgot-password

Request password reset email. Body: email. Rate limit 5/10min.

POST/auth/reset-password

Reset password dgn token dari email. Body: email, token, password, password_confirmation.

Payment Endpoints

POST/payments

Buat payment session. Auto-split ke merchant + fee BayarOn.

Body: items[], buyer_name, buyer_email, buyer_phone, return_url, cancel_url. Returns payment_url + reference_id.

Dengan token uji โ†’ transaksi sandbox (gateway tidak dipanggil). Lihat Mode Uji.

POST/payments/{reference_id}/simulasi

Picu status transaksi uji secara manual + kirim webhook. Body: status (paid/expired/failed).

Transaksi non-sandbox ditolak 422. Lihat Mode Uji.

GET/payments?status=paid&q=BYRN-xxx&per_page=20

List transaksi merchant. Filter + pagination.

GET/payments/stats?days=30

Daily stats โ€” count + revenue per hari (untuk chart). Return: daily[], summary.

GET/payments/{reference_id}

Detail transaksi + splits + webhook logs.

Public Checkout (No Auth)

Buyer-facing endpoints โ€” pakai untuk build custom checkout. Tidak perlu auth, secured by reference_id ULID obscurity.

GET/p/{reference_id}

Lookup payment info: business_name, amount, status, selected method (kalau udah pick).

POST/p/{reference_id}/init-method

Pilih metode bayar. Body: method (qris/va/cstore), channel (bca/mandiri/qris/indomaret/...). Returns instruction (VA number, QR code, etc).

GET/p/{reference_id}/status

Lightweight status polling (frontend call tiap 3-5s). Rate limit 60/min.

Merchant Endpoints

PATCH/merchant

Update profile + bank info. Body: business_name, business_email, business_phone, business_website, bank_name, bank_account_number, bank_account_name.

POST/merchant/webhook

Set webhook URL untuk receive forward dari BayarOn. Returns webhook_secret (shown once!).

POST/merchant/webhook/test

Kirim test ping ke webhook URL kamu, verify endpoint respond OK.

GET/audit-logs

Audit trail aksi sensitif (login, perubahan bank, withdraw request, dll).

Withdrawal Endpoints

GET/withdrawals

Saldo available + 20 withdrawal terakhir + bank info.

POST/withdrawals

Request tarik saldo. Body: amount (min Rp 10.000). Bank info harus udah di-set di /merchant.

Webhook Forward (BayarOn โ†’ Merchant)

Saat transaksi paid, BayarOn forward ke webhook URL kamu (kalau di-set). Verify signature di sisi kamu:

// Node.js example
const crypto = require('crypto');

app.post('/webhook/bayaron', (req, res) => {
  const signature = req.headers['x-bayaron-signature'];
  const payload = JSON.stringify(req.body);
  const expected = crypto.createHmac('sha256', WEBHOOK_SECRET).update(payload).digest('hex');

  if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
    return res.status(401).send('Invalid signature');
  }

  const { event, transaction } = req.body;
  if (event === 'payment.paid') {
    // Update order status di DB kamu
    markOrderPaid(transaction.reference_id, transaction.amount_total);
  }
  res.send('OK');
});

Retry policy: BayarOn retry 3x dengan backoff 30s kalau endpoint kamu return non-2xx atau timeout (10s).

Error Handling

Semua error response format JSON dengan key message. Validation errors tambah errors.{field}[].

HTTP Meaning
200Success
201Created (register, payment)
401Token tidak valid / expired
404Resource not found
422Validation error (cek errors)
429Rate limited
502iPaymu upstream error

Rate Limiting

EndpointLimit
POST /auth/register10/jam per IP
POST /auth/login20/15min per IP
POST /auth/forgot-password5/10min per IP
/p/* (public)60/min per IP

SDK Examples โ€” Bikin Payment Link

Copy-paste snippet di bawah, ganti YOUR_TOKEN dengan Bearer token kamu (dari /auth/login).

PHP (cURL)

$ch = curl_init('https://api.bayaron.com/payments');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer YOUR_TOKEN',
        'Content-Type: application/json',
        'Accept: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'items' => [['name' => 'Premium Plan', 'qty' => 1, 'price' => 99000]],
        'buyer_name' => 'Budi Santoso',
        'buyer_email' => '[email protected]',
        'buyer_phone' => '081234567890',
    ]),
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);

// Share URL ke buyer:
echo 'https://bayaron.com/p/' . $response['transaction']['reference_id'];

Node.js (fetch)

const response = await fetch('https://api.bayaron.com/payments', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_TOKEN',
    'Content-Type': 'application/json',
    'Accept': 'application/json',
  },
  body: JSON.stringify({
    items: [{ name: 'Premium Plan', qty: 1, price: 99000 }],
    buyer_name: 'Budi Santoso',
    buyer_email: '[email protected]',
    buyer_phone: '081234567890',
  }),
});

const data = await response.json();
const shareUrl = `https://bayaron.com/p/${data.transaction.reference_id}`;
console.log('Bayar di:', shareUrl);

Python (requests)

import requests

response = requests.post(
    'https://api.bayaron.com/payments',
    headers={
        'Authorization': 'Bearer YOUR_TOKEN',
        'Content-Type': 'application/json',
    },
    json={
        'items': [{'name': 'Premium Plan', 'qty': 1, 'price': 99000}],
        'buyer_name': 'Budi Santoso',
        'buyer_email': '[email protected]',
        'buyer_phone': '081234567890',
    },
)

data = response.json()
share_url = f"https://bayaron.com/p/{data['transaction']['reference_id']}"
print(f'Bayar di: {share_url}')

Verify Webhook Signature (Python Flask)

import hmac, hashlib
from flask import Flask, request

app = Flask(__name__)
WEBHOOK_SECRET = 'whsec_xxx_dari_dashboard_BayarOn'

@app.route('/webhook/bayaron', methods=['POST'])
def webhook():
    signature = request.headers.get('X-BayarOn-Signature')
    raw_body = request.get_data()
    expected = hmac.new(WEBHOOK_SECRET.encode(), raw_body, hashlib.sha256).hexdigest()

    if not hmac.compare_digest(signature, expected):
        return 'Invalid signature', 401

    payload = request.get_json()
    if payload['event'] == 'payment.paid':
        tx = payload['transaction']
        # Update order kamu di DB
        mark_order_paid(tx['reference_id'], tx['amount_total'])
    return 'OK', 200

Siap Integrate?

Daftar gratis, dapet API key, mulai terima pembayaran dalam 5 menit.

Daftar Sekarang