- Home
- Guides
- Quickstart
Quickstart
Create a test payment with the Baiyar API, pay it in the sandbox, and read the result, using curl or Node.js.
You need a test API key and a project that accepts the payment method you try. If you have neither, create a project in the sandbox (every method is available there) and get a test key. Keep the key in an environment variable:
export BAIYAR_KEY="bk_test_…"export BAIYAR_API="https://api.baiyar.com"1. Check the key
Section titled “1. Check the key”curl "$BAIYAR_API/v1/account" -H "Authorization: Bearer $BAIYAR_KEY"{ "data": { "livemode": false, "merchant": { "id": "mer_01k7…" }, "project": { "id": "prj_01k7…" }, "key": { "id": "apk_01k7…", "kind": "project", "scopes": ["payments:read", "payments:write"] } }, "meta": { "request_id": "req_…" }}Every answer has the same two parts: data is what you asked for, and meta is about the request (its request_id, and for a list its pagination). data.livemode: false confirms that this is a test key.
2. Create a payment
Section titled “2. Create a payment”A payment needs an Idempotency-Key. When retrying a timed-out request, send the same key and body so Baiyar returns the same payment. API amounts use the currency’s smallest unit: Rp10.000 is 1000000.
curl "$BAIYAR_API/v1/payments" \ -H "Authorization: Bearer $BAIYAR_KEY" \ -H "Idempotency-Key: order-1001-attempt-1" \ -H "Content-Type: application/json" \ -d '{ "amount": 1000000, "currency": "IDR", "payment_method": "payment.qris", "merchant_reference": "order-1001", "description": "Order 1001", "customer": { "name": "Sari Wijaya", "email": "sari@example.com" } }'The answer (201) has the payment in data. Its initial status is pending; instruction tells the payer how to complete it. For QRIS it is { "type": "qr", "qr_content": "…", "expires_at": "…" }: render qr_content as a QR code. Other methods answer with a virtual account (va), a wallet link (ewallet_link), a wallet push (ewallet_push) or a retail code (retail_code).
Fields used in the request:
| Field | Purpose |
|---|---|
amount, currency |
The base amount before fees and its currency code. Send IDR as an integer in the smallest unit, not as a rupiah amount. |
payment_method |
The requested method, such as payment.qris. The method must also be available to the project in that environment. |
project_id |
The project that owns the payment. Required for a merchant-wide key; a project key is already bound to its project. |
merchant_reference |
Your order ID, so you can find the payment and match it back to your order. |
description |
A short label to identify the payment in the dashboard. |
customer |
Optional payer details. Some payment methods require a phone number. |
metadata |
Your text key-value pairs, returned on the payment and webhook events. Do not put secrets or sensitive data here. |
expires_in |
How long the payment stays open before it expires, in seconds. It can be 300 seconds to 7 days; the default depends on the method. |
The response also includes fee, charged_amount (what the payer is charged, including the fee if they bear it) and net_amount (the merchant amount after Baiyar’s fee). After payment, net_amount enters the pending balance and moves to the available balance after provider settlement.
3. Pay it in the sandbox
Section titled “3. Pay it in the sandbox”Use a test key to set the outcome of a sandbox payment. This does not charge a payer:
curl "$BAIYAR_API/v1/sandbox/payments/pay_01k7…/simulate" \ -H "Authorization: Bearer $BAIYAR_KEY" \ -H "Content-Type: application/json" \ -d '{ "outcome": "paid" }'outcome is paid, failed or expired. This endpoint exists for test keys only.
4. Read the result
Section titled “4. Read the result”curl "$BAIYAR_API/v1/payments/pay_01k7…" -H "Authorization: Bearer $BAIYAR_KEY"data.status is now paid. In your own code, do not poll: register a webhook endpoint and handle payment.succeeded.
The same in Node.js
Section titled “The same in Node.js”const api = "https://api.baiyar.com";const headers = { Authorization: `Bearer ${process.env.BAIYAR_KEY}`, "Content-Type": "application/json" };
const created = await fetch(`${api}/v1/payments`, { method: "POST", headers: { ...headers, "Idempotency-Key": "order-1001-attempt-1" }, body: JSON.stringify({ amount: 1_000_000, currency: "IDR", payment_method: "payment.qris" }),});if (!created.ok) throw new Error((await created.json()).error.code);const { data: payment } = await created.json();console.log(payment.id, payment.status, payment.instruction);
await fetch(`${api}/v1/sandbox/payments/${payment.id}/simulate`, { method: "POST", headers, body: JSON.stringify({ outcome: "paid" }),});You can also run every one of these requests from the API reference: every operation has a Try it button that opens a request client in your browser, against the sandbox.
Going live
Section titled “Going live”Live needs a project that has been approved for live and a verified account. Make a live key and keep the code the same: only the key changes.