payment.failed
Sent when a payment (from a payment link
or a direct payment) reaches a final
state without succeeding — failed or expired. Both are delivered as this
same event type.
Headers
Section titled “Headers”| Header | Description |
|---|---|
X-Baiyar-Signature |
t=<unix timestamp>,v1=<hex HMAC-SHA256> — see Verifying Webhook Signatures |
Content-Type |
application/json |
Payload
Section titled “Payload”{ "id": "018f1f29-a1e0-73e4-a310-744d2167fcc2", "type": "payment.failed", "created_at": "2026-09-02T09:20:00Z", "data": { "id": "018f1f29-9b21-73e4-a310-744d2167fca1", "project_id": "018f1f29-7c00-73e4-a310-744d2167fc60", "reference": "ORDER-2026-0002", "amount": 15000, "currency": "IDR", "status": "failed" }}| Field | Type | Description |
|---|---|---|
id |
string | Unique event ID — use it to deduplicate retried deliveries, not data.id |
type |
string | Always payment.failed |
created_at |
date-time | When the event was generated |
data.status |
string | failed or expired |
data has no paid_at field — the payment never succeeded. Call
GET /v1/payments/{data.id}
with your API key for the rest of the payment’s detail.
A resubmitted attempt after payment.failed produces a new transaction
with its own event id — don’t assume a reference only ever fails once.
Testing
Section titled “Testing”curl -X POST https://api.baiyar.id/sandbox/payments/{providerPaymentID}/simulate \ -H "Content-Type: application/json" \ -d '{"outcome": "failed"}'outcome can also be expired, to test that path specifically. See
Sandbox Simulation and
Handling Webhook Deliveries.
Next steps
Section titled “Next steps”payment.paid — the other transaction event.