Direct Payments
Overview
Section titled “Overview”A direct payment is a payment for one specific payment_method — QRIS or a
bank virtual account — with no hosted Baiyar page involved. Use this when
you want to render the QR code or virtual account number inside your own
app instead of sending the customer to a payment link.
Creating a direct payment
Section titled “Creating a direct payment”POST /v1/paymentsIdempotency-Key: order-2026-0002-attempt-1
{ "project_id": "018f1f29-7c00-73e4-a310-744d2167fc60", "reference": "ORDER-2026-0002", "amount": 15000, "payment_method": { "type": "qris" }}Idempotency-Key is required — a unique string you generate per payment
attempt (a UUID works well). Retrying the same key with an identical body
returns the original payment (200) instead of creating a duplicate
(201); retrying with a different body is rejected with 409. This makes
it safe to retry on a network timeout without risking a duplicate charge.
The response includes instructions, shaped differently per method:
- QRIS —
qr_string(the raw QRIS payload, if you want to render your own QR code) andqr_image_url(a ready-to-display QR code image as adata:URI). - Virtual account —
bank_name,virtual_account_number, andpayment_steps(human-readable instructions you can display as-is).
{ "id": "018f1f29-9b21-73e4-a310-744d2167fca1", "project_id": "018f1f29-7c00-73e4-a310-744d2167fc60", "reference": "ORDER-2026-0002", "amount": 15000, "currency": "IDR", "fee_bearer": "merchant", "fee_amount": 105, "merchant_net": 14895, "status": "pending", "checkout_url": "https://checkout.baiyar.id/sandbox/payments/sandbox_018f...", "payment_method": { "type": "qris" }, "instructions": { "qr_string": "BAIYAR-SANDBOX-QRIS|sandbox_018f...|15000|IDR", "qr_image_url": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..." }, "expires_at": "2026-09-02T09:15:00Z", "created_at": "2026-09-02T09:00:00Z"}{ "bank_name": "Bank BNI", "virtual_account_number": "8808123456789", "payment_steps": [ "Open mobile banking.", "Choose virtual account transfer.", "Enter the virtual account number." ]}Minimum amount
Section titled “Minimum amount”amount is in IDR (whole rupiah). The minimum depends on the method:
| Method | Minimum amount |
|---|---|
qris |
100 |
virtual_account |
10,000 |
Expiry
Section titled “Expiry”expires_in_minutes is optional. It defaults to 15 minutes for qris and
24 hours for virtual_account, and is capped at 60 minutes for qris and 7
days for virtual_account.
Checking payment status
Section titled “Checking payment status”Poll GET /v1/payments/{paymentID} for status (pending, processing,
succeeded, failed, expired), or — better — configure a project webhook
so Baiyar notifies you instead. See Payment Statuses
for what each value means and Webhooks for
push notifications.