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://sandbox-payment.ipaymu.com/...",
#   "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}

Auth Endpoints

POST/auth/register

Buat akun + merchant baru. Return Sanctum token.

Body: name, email, phone, password, password_confirmation, business_name, business_email, business_phone, business_website

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.

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