Configuration
Create a Read & Write API key at web.mayar.id/api-keys and set:
MAYAR_API_KEY=your-api-key
MAYAR_WEBHOOK_TOKEN=your-webhook-token # optional
MAYAR_SANDBOX=false # true to use the sandbox host
MAYAR_API_BASE= # optional override
| Environment | Base URL |
|---|---|
| Production | https://api.mayar.id/hl/v2 |
| Sandbox | https://api.mayar.io/hl/v2 |
The environment belongs to your API key, not to your app, so it is not derived fromNODE_ENV. PGLink uses the production host by default and the sandbox host only whenMAYAR_SANDBOX=true. A production key sent to the sandbox host (or the other way around) is rejected with401 Unauthorized. SetMAYAR_API_BASEto override the host entirely.
Creating a payment
PGLink maps POST /payments (and /payments/payment-link) to
Mayar's POST /invoices/create. Mayar requires a customer name, email and
mobile number.
curl -X POST http://localhost:3000/payments \
-H "X-API-Key: your-app-api-key" \
-H "Content-Type: application/json" \
-d '{
"amount": 50000,
"provider": "MAYAR",
"applicationOrderId": "ORDER-12345",
"customerName": "Budi Santoso",
"customerEmail": "budi@example.com",
"customerPhone": "081234567890",
"mayarPaymentMethod": "qris",
"mayarExpiredAt": "2026-12-31T23:59:59.000Z",
"description": "Order #12345"
}'
Response (abridged):
{
"data": {
"externalId": "a1b2c3d4-...",
"checkoutUrl": "https://testingmayar.myr.id/invoices/ycfyxbj2h3",
"status": "PENDING",
"provider": "MAYAR"
},
"checkoutUrl": "https://testingmayar.myr.id/invoices/ycfyxbj2h3"
}
Redirect the customer to checkoutUrl to complete payment.
Payment channels
Set mayarPaymentMethod to restrict the invoice to one channel (it must be enabled in your Mayar settings):
| Category | Values |
|---|---|
| QRIS | qris |
| Virtual account | va/bni, va/bri, va/mandiri, va/cimb, va/permata, va/bjb, va/bsi |
| E-wallet | ewallet/dana, ewallet/gopay, ewallet/linkaja, ewallet/shopeepay, ewallet/jenius |
| Retail outlet | outlet/alfamart |
When omitted, Mayar shows its configured checkout page with all enabled channels.
Webhooks
Register your callback URL in the Mayar dashboard (Integration โ Webhook). Mayar posts events such as:
| Event | Mapped status | Meaning |
|---|---|---|
payment.received | SUCCESS | The customer paid |
payment.reminder | PENDING | Informational: the invoice is unpaid after 29 minutes. The payment is not changed. |
payment.failed | FAILED | The payment failed |
payment.expired | EXPIRED | The invoice expired |
Mayar sends the event to POST /payments/mayar-callback:
{
"event": "payment.received",
"data": {
"id": "6f8c19ff-...",
"transactionId": "a1b2c3d4-...",
"status": "SUCCESS",
"transactionStatus": "paid"
}
}
PGLink matches the payment by data.transactionId (falling back to
data.id) and forwards a normalized webhook to your application's
webhookUrl.
data.statusis the status of the webhook delivery โ Mayar reportsSUCCESSthere even for an invoice that has not been paid. PGLink therefore derives the payment status from the event name and fromdata.transactionStatus, never fromdata.status. An unknown event (for examplemembership.*orshipper.status) never marks a payment as paid.
If MAYAR_WEBHOOK_TOKEN is set it must be presented. Mayar sends
no signature and no custom header, so register the webhook URL as
https://your-host/payments/mayar-callback?token=YOUR_TOKEN โ the
token is read from the token query parameter (the
x-mayar-token header is also accepted).
Limitations
save-payment-methodis not available for Mayar (returns400).- Subscriptions are not exposed through this API for Mayar.
- Mayar requires
customerName,customerEmailandcustomerPhone. -
successRedirectUrlandfailureRedirectUrlare accepted but ignored: Mayar'sPOST /invoices/createhas no redirect parameter, so the customer completes payment on the Mayar checkout page. Only Xendit and Midtrans redirect the customer.