# Use Chiwa Pay with AI agents
> Give your coding agent the documentation and API contract it needs to build a Chiwa Pay integration.
Canonical: https://docs.chiwapay.com/agents
Chiwa Pay documentation is available as focused Markdown, a complete documentation bundle, and an OpenAPI contract. Your agent can find the right guide without scraping the website or guessing how an endpoint works.
## Start here
### Point your agent to the index
Give the agent [`/llms.txt`](https://docs.chiwapay.com/llms.txt). It lists the available guides and their machine-readable versions.
### Read only the relevant guide
For a payment integration, for example, the agent can open [`/llms.mdx/payments`](https://docs.chiwapay.com/llms.mdx/payments) instead of loading the entire documentation set.
### Check the API contract
Before it writes code, have the agent validate methods, paths, authentication, and schemas against [`/openapi/core-api.yaml`](https://docs.chiwapay.com/openapi/core-api.yaml).
## Give this to your agent
Tell the agent what you want to build, then copy this instruction with it. The documentation origin is filled from the current environment.
```text
Read https://docs.chiwapay.com/llms.txt and use it to find only the Chiwa Pay guides relevant to this task.
Before writing code, validate every endpoint, HTTP method, authentication requirement, and schema against https://docs.chiwapay.com/openapi/core-api.yaml.
Do not invent endpoints, fields, status values, fees, or webhook events. Keep secret keys on the server and ask for explicit approval before any live payment, refund, cancellation, or configuration change.
```
## Machine-readable resources
- [`/llms.txt`](https://docs.chiwapay.com/llms.txt) — Find the right guide.
- [`/llms.mdx/{document}`](https://docs.chiwapay.com/llms.mdx/payments) — Read one guide as Markdown.
- [`/llms-full.txt`](https://docs.chiwapay.com/llms-full.txt) — Load the complete documentation set.
- [`/openapi/core-api.yaml`](https://docs.chiwapay.com/openapi/core-api.yaml) — Generate or validate API code.
- [`/.well-known/chiwa-docs.json`](https://docs.chiwapay.com/.well-known/chiwa-docs.json) — Discover the machine-readable files.
- [`/agent-instructions.md`](https://docs.chiwapay.com/agent-instructions.md) — Read agent-specific rules.
> **Keep credentials out of the conversation**
> Never paste API keys, OTPs, cookies, authorization headers, webhook secrets, or customer data into an agent prompt. Keep secrets on your server and load them through your deployment environment.
## Before an agent performs an action
Reading documentation and generating code do not require Chiwa Pay credentials. Creating a live payment, issuing a refund, cancelling a transaction, or changing merchant configuration still requires the normal authentication flow and your explicit approval.
Chiwa Pay currently publishes documentation for coding agents; it does not expose an MCP or A2A server for performing merchant actions.
---
# Authentication
> Authenticate API requests with a Chiwa Pay secret key.
Canonical: https://docs.chiwapay.com/authentication
Use a secret key on every API request.
## Header
```http
Authorization: Bearer sk_xxx
```
> **Keep your API key secret**
> Do not send a secret key from a browser or mobile app.
## Requirements
| Requirement | Status |
| --- | --- |
| Merchant | `approved` |
| Payment method | `active` |
| Secret key | Not revoked |
## Security
| Area | Description |
| --- | --- |
| Storage | Store it on your server. |
| Logging | Mask secret key values. |
| Rotation | Revoke the old key after the new key is active. |
| IP allowlist | Restrict a key to server IPs or CIDR ranges such as `203.0.113.10` or `203.0.113.0/24`. |
## Example
```tsx
```
---
# Error Codes
> Understand Chiwa Pay API error responses and codes.
Canonical: https://docs.chiwapay.com/errors
When a request fails, the API returns an `error` object.
```json
{
"error": {
"code": "invalid_api_key",
"message": "secret key is invalid or revoked"
}
}
```
## Public API
| HTTP | Code | Description |
| --- | --- | --- |
| `400` | `invalid_json` | Body is not valid JSON. |
| `400` | `invalid_amount` | Amount is invalid. |
| `400` | `invalid_bulk_size` | Bulk item count is invalid. |
| `400` | `unsupported_payment_method` | Payment method is not supported. |
| `400` | `payment_create_failed` | Transaction could not be created. |
| `400` | `payment_cancel_failed` | Transaction could not be cancelled. |
| `400` | `payment_refund_failed` | Transaction could not be refunded. |
| `401` | `invalid_api_key` | Secret key is missing, invalid, or revoked. |
| `403` | `merchant_not_approved` | Merchant is not active. |
| `403` | `api_key_ip_not_allowed` | Request IP is not in the API key allowlist. |
| `404` | `not_found` | Resource was not found. |
| `429` | `rate_limited` | Rate limit exceeded. |
| `500` | `server_error` | Request could not be processed. |
## Rate Limit
The API applies rate limits to keep the service stable.
If you receive `429`, wait briefly before sending the next request.
## Retry
| Condition | Retry |
| --- | --- |
| Timeout | Yes, use the same request. |
| `500` | Yes, after a delay. |
| `400`, `401`, `403`, `404` | No. Fix the request or merchant status. |
| `429` | Yes, after waiting for the next rate-limit window. |
---
# Fees and Disbursement
> Understand transaction amounts, fees, refunds, and disbursement.
Canonical: https://docs.chiwapay.com/fees-disbursement
## Amount Fields
| Field | Description |
| --- | --- |
| `amount` | Order amount from the merchant. |
| `fee_amount` | Payment fee. |
| `total_amount` | Amount the customer must pay. |
| `net_amount` | Amount recorded for the merchant. |
## Fee Example
| Fee payer | `amount` | `fee_amount` | `total_amount` | `net_amount` |
| --- | ---: | ---: | ---: | ---: |
| `buyer` | 100000 | 700 | 100700 | 100000 |
| `merchant` | 100000 | 700 | 100000 | 99300 |
## Refund Calculation
Provider refunds currently apply to GoPay transactions. The ShopeePay Partner SDK has no refund operation.
Refunds are sent to the provider for the customer-paid amount (`total_amount`).
The customer receives the full refund, while the merchant settlement balance is still reduced by `fee_amount` as the transaction service fee.
| Fee payer | Customer pays | Main refund amount | Notes |
| --- | --- | --- | --- |
| `buyer` | `amount + fee_amount` | `amount + fee_amount` | The customer-paid amount is refunded through the provider; `fee_amount` still reduces merchant settlement. |
| `merchant` | `amount` | `amount` | `fee_amount` remains the merchant's cost and reduces settlement. |
Possible refund statuses are `refund_processing`, `refund_failed`, and `refunded`.
Refunds with status `refund_processing` can be cancelled, returning the transaction to `paid`.
Refunds with status `refund_failed` or `refunded` cannot be cancelled.
## Disbursement
Fees and settlement policy are configured for each provider and channel pair in the admin catalog. A transaction captures its policy when created; settlement becomes available after the configured delay. The worker processes `automatic` policies, while `manual` policies require an admin action.
Disbursement is handled from the merchant dashboard after the settlement account is approved.
---
# Chiwa Pay API Overview
> Chiwa Pay integration overview for creating transactions, accepting payments, and tracking payment status.
Canonical: https://docs.chiwapay.com/
Chiwa Pay helps merchants create payment transactions, show payment instructions to customers, and track status changes through webhooks or the API.
Use this page as a quick map before opening the endpoint-level guides.
## What You Can Build
- [Accept QRIS payments](https://docs.chiwapay.com/payments): Create transactions, show QRIS, and guide customers to complete payment.
- [Track transaction status](https://docs.chiwapay.com/payment-detail): Fetch the latest status by transaction UUID or reference ID.
- [Refund transactions](https://docs.chiwapay.com/payment-refund): Start a refund for paid transactions and follow the refund status.
- [Automate notifications](https://docs.chiwapay.com/webhooks): Receive events for paid, expired, failed, refund, and settled transactions.
- [Manage fees and disbursement](https://docs.chiwapay.com/fees-disbursement): Understand customer total, merchant net amount, refunds, and disbursement.
- [Handle API errors](https://docs.chiwapay.com/errors): Recognize error response formats and codes your app should handle.
## Before You Start
| Requirement | Description |
| --- | --- |
| Active merchant | The merchant application must be approved before its API key can create transactions. |
| API key | The secret key is available in the merchant dashboard and sent with the `Authorization` header. |
| Payment method | Make sure the payment method you want to use is enabled for the merchant. |
| Webhook URL | Recommended for automatic payment status updates from Chiwa Pay. |
## API URL
Every endpoint example uses the following base URL.
`https://api.chiwapay.com`
## Quick Start
The shortest path to create a QRIS transaction:
```tsx
```
The create payment response includes `payment.id`, `reference_id`, `status`, `qris_payload`, `qris_image_url`, and `expires_at`.
Show the QRIS to the customer, then fulfill the order after the status changes to `paid`.
## Integration Flow
| Step | Description |
| --- | --- |
| 1 | Store the API key on your server and never expose the secret key to the frontend. |
| 2 | Merchant creates a transaction with `POST /payments`. |
| 3 | Chiwa Pay returns payment instructions such as a QRIS payload or QR image URL. |
| 4 | Customer pays using the payment instruction before `expires_at`. |
| 5 | Chiwa Pay sends a webhook when status changes, for example `payment.paid` or `payment.expired`. |
| 6 | Merchant verifies the webhook, updates the order, and reconciles with the dashboard or transaction detail API. |
## Transaction Status
| Status | Description |
| --- | --- |
| `created` | Transaction was created. |
| `pending` | Waiting for payment. |
| `paid` | Customer has paid. |
| `expired` | Payment deadline has passed. |
| `settled` | Funds are in settlement and the transaction cannot be cancelled. |
| `failed` | Payment failed. |
| `cancelled` | Transaction was cancelled. |
| `refund_processing` | Refund is being processed. |
| `refund_failed` | Refund failed and needs retry or manual handling. |
| `refunded` | Refund succeeded. |
## Webhook or Polling
| Mechanism | Use When | Notes |
| --- | --- | --- |
| Webhook | Your system can receive requests from Chiwa Pay. | This is the primary way to process status changes in real time. |
| Transaction detail polling | Your system cannot receive webhooks yet or needs a fallback check. | Use as a fallback and add delay between requests to avoid rate limits. |
| Dashboard | Operations teams need to inspect transactions manually. | Useful for investigation, support, and reconciliation. |
## Key Concepts
| Concept | Summary |
| --- | --- |
| `merchant_reference_id` | The order ID from the merchant system. Use a value that is easy to reconcile. |
| `reference_id` | Chiwa Pay transaction ID that can be used to look up a payment. |
| `Idempotency-Key` | Prevents duplicate transaction creation when a create payment request is retried. |
| `total_amount` | The amount the customer must pay. It can differ from `amount` when the buyer pays the fee. |
| `net_amount` | The amount recorded for the merchant after fee rules are applied. |
## Continue From Here
- [Authentication](https://docs.chiwapay.com/authentication): Send the API key and keep access secure.
- [API Reference](https://docs.chiwapay.com/): Payment, transaction detail, refund, and transaction list endpoints.
- [Webhooks](https://docs.chiwapay.com/webhooks): Transaction status events and signature headers.
- [Errors](https://docs.chiwapay.com/errors): Error response format and codes your app should handle.
---
# Cancel Payment
> Cancel a payment transaction that is still pending.
Canonical: https://docs.chiwapay.com/payment-cancel
`POST /payments/:id/cancel`
Cancel a transaction that is still `pending`.
The ShopeePay Partner SDK does not support cancellation.
When the request succeeds, the transaction status changes to `cancelled` and a `payment.cancelled` event is sent to webhooks.
The `POST /transactions/:id/cancel` alias is available with the same behavior.
## Status Rules
| Initial status | Result |
| --- | --- |
| `pending` | `cancelled` |
| `refund_processing` | `paid`, the refund process is cancelled. |
| `created`, `paid`, `expired`, `failed`, `cancelled`, `settled`, `refund_failed`, `refunded` | Cannot be cancelled. |
## Path Params
| Param | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes | Transaction UUID or `reference_id`. |
## Request Example
```tsx
```
## Response
```json
{
"payment": {
"id": "f2b1d5b0-7b1f-4c5d-9c37-93f0c8f6a001",
"reference_id": "PAY-LXAMPLE",
"merchant_reference_id": "ORDER-1024",
"payment_method_code": "qris",
"currency": "IDR",
"amount": 150000,
"fee_amount": 1050,
"net_amount": 150000,
"total_amount": 151050,
"status": "cancelled",
"cancelled_at": "2026-05-19T10:05:00Z"
}
}
```
## HTTP Error Codes
| HTTP | Code | Description |
| --- | --- | --- |
| `400` | `payment_cancel_failed` | Transaction cannot be cancelled from its current status. |
| `401` | `invalid_api_key` | Secret key is invalid. |
| `403` | `merchant_not_approved` | Merchant is not active yet. |
| `403` | `api_key_ip_not_allowed` | Request IP is not in the API key allowlist. |
| `404` | `not_found` | Transaction was not found. |
---
# Payment Detail
> Retrieve payment details and the latest transaction status.
Canonical: https://docs.chiwapay.com/payment-detail
`GET /payments/:id`
Returns transaction detail.
## Path Params
| Param | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes | Transaction UUID or `reference_id`. |
## Request Example
```tsx
```
## Response
```json
{
"payment": {
"id": "f2b1d5b0-7b1f-4c5d-9c37-93f0c8f6a001",
"reference_id": "PAY-LXAMPLE",
"merchant_reference_id": "ORDER-1024",
"payment_method_code": "qris",
"provider": "gopay",
"currency": "IDR",
"amount": 150000,
"fee_amount": 1050,
"net_amount": 150000,
"total_amount": 151050,
"status": "paid",
"paid_at": "2026-05-19T10:01:00Z",
"created_at": "2026-05-19T10:00:00Z",
"updated_at": "2026-05-19T10:01:00Z"
}
}
```
## Response Fields
| Field | Description |
| --- | --- |
| `payment.id` | Transaction UUID. |
| `payment.reference_id` | Chiwa Pay transaction ID. |
| `payment.merchant_reference_id` | Merchant order ID. |
| `payment.status` | Transaction status. |
| `payment.total_amount` | Amount the customer must pay. |
| `payment.net_amount` | Amount after fee. |
| `payment.paid_at` | Time payment was received. |
## HTTP Error Code
| HTTP | Code | Description |
| --- | --- | --- |
| `401` | `invalid_api_key` | Secret key is invalid. |
| `403` | `merchant_not_approved` | Merchant is not active. |
| `404` | `not_found` | Transaction was not found. |
---
# Refund Payment
> Start a refund and track its status.
Canonical: https://docs.chiwapay.com/payment-refund
`POST /payments/:id/refund`
Starts a refund for a transaction that is already `paid` and has not entered settlement.
The ShopeePay Partner SDK does not support refunds; this endpoint applies to GoPay transactions only.
When the request succeeds, the transaction status changes to `refund_processing`.
## Status Rules
| Initial status | Result |
| --- | --- |
| `paid` | `refund_processing` |
| `created`, `pending`, `expired`, `failed`, `cancelled`, `settled`, `refund_processing`, `refund_failed`, `refunded` | Cannot be refunded. |
## Refund Calculation
The main refund amount is the customer-paid amount (`total_amount`).
The customer receives that amount in full. The merchant settlement balance is still reduced by `fee_amount` as the transaction service fee.
| Fee payer | Customer pays | Main refund amount | Notes |
| --- | --- | --- | --- |
| `buyer` | `amount + fee_amount` | `amount + fee_amount` | The customer-paid amount is refunded through the provider; `fee_amount` still reduces merchant settlement. |
| `merchant` | `amount` | `amount` | `fee_amount` remains the merchant fee and reduces settlement. |
## Path Params
| Param | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes | Transaction UUID or `reference_id`. |
## Request Example
```tsx
```
## Response
```json
{
"payment": {
"id": "f2b1d5b0-7b1f-4c5d-9c37-93f0c8f6a001",
"reference_id": "PAY-LXAMPLE",
"merchant_reference_id": "ORDER-1024",
"payment_method_code": "qris",
"currency": "IDR",
"amount": 150000,
"fee_amount": 1050,
"net_amount": 150000,
"total_amount": 151050,
"status": "refund_processing"
}
}
```
## HTTP Error Code
| HTTP | Code | Description |
| --- | --- | --- |
| `400` | `payment_refund_failed` | Transaction cannot be refunded from its current status. |
| `401` | `invalid_api_key` | Secret key is invalid. |
| `403` | `merchant_not_approved` | Merchant is not active. |
| `404` | `not_found` | Transaction was not found. |
---
# Create Payment
> Create single or bulk payment transactions.
Canonical: https://docs.chiwapay.com/payments
`POST /payments`
Creates payment transactions. The request can contain a single transaction or a bulk payload through the `payments` field.
## Headers
| Header | Required | Description |
| --- | --- | --- |
| `Authorization` | Yes | `Bearer sk_xxx` |
| `Content-Type` | Yes | `application/json` |
| `Idempotency-Key` | No | Unique ID for a single request. For bulk, use `payments[].idempotency_key`. |
## Body Fields
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `amount` | integer | Yes for single request | Order amount. |
| `currency` | string | No | Default `IDR`. |
| `payment_method` | string | No | Default `qris`. Currently only `qris` is supported. |
| `provider` | string | No | `gopay` or `shopeepay`. Defaults to `gopay` for compatibility. Also applies to each `payments[]` item. The provider must be enabled for the merchant. |
| `merchant_reference_id` | string | No | Order ID from the merchant system. |
| `customer` | object | No | Customer data. |
| `metadata` | object | No | Extra merchant data. |
| `payments` | array | No | Transaction list for bulk create. Maximum `50` items per request. |
| `payments[].idempotency_key` | string | Recommended | Unique ID per bulk item. |
## Payment Method Fields
| Field | Description |
| --- | --- |
| `payment_method` | Payment method code. If empty, the API uses `qris`. |
| `provider` | QRIS provider. Internal provider accounts are selected automatically and omitted from responses. |
| `qris_payload` | Payment payload in QRIS responses. |
| `qris_image_url` | QR image URL in QRIS responses. |
## Single Request Example
```tsx
```
## Bulk Request Example
```tsx
```
## Single Response
```json
{
"payment": {
"id": "f2b1d5b0-7b1f-4c5d-9c37-93f0c8f6a001",
"reference_id": "PAY-LXAMPLE",
"merchant_reference_id": "ORDER-1024",
"payment_method_code": "qris",
"provider": "gopay",
"currency": "IDR",
"amount": 150000,
"fee_amount": 1050,
"net_amount": 150000,
"total_amount": 151050,
"status": "pending",
"qris_payload": "000201010212...",
"qris_image_url": "",
"expires_at": "2026-05-19T10:30:00Z",
"created_at": "2026-05-19T10:00:00Z",
"updated_at": "2026-05-19T10:00:00Z"
}
}
```
## Bulk Response
```json
{
"payments": [
{
"id": "f2b1d5b0-7b1f-4c5d-9c37-93f0c8f6a001",
"reference_id": "PAY-LXAMPLE",
"merchant_reference_id": "ORDER-1024",
"payment_method_code": "qris",
"amount": 150000,
"fee_amount": 1050,
"net_amount": 150000,
"total_amount": 151050,
"status": "pending",
"expires_at": "2026-05-19T10:30:00Z"
}
]
}
```
## Response Fields
| Field | Description |
| --- | --- |
| `payment.id` / `payments[].id` | Transaction UUID. |
| `payment.reference_id` / `payments[].reference_id` | Chiwa Pay transaction ID. |
| `payment.merchant_reference_id` | Merchant order ID. |
| `payment.payment_method_code` | Payment method. |
| `payment.amount` | Order amount. |
| `payment.fee_amount` | Payment fee. |
| `payment.net_amount` | Amount recorded for the merchant. |
| `payment.total_amount` | Amount the customer must pay. |
| `payment.status` | Transaction status. |
| `payment.expires_at` | Payment deadline; after it passes, pending transactions become `expired`. |
## Fee Payer
| Value | Customer pays | Merchant receives |
| --- | --- | --- |
| `buyer` | `amount + fee_amount` | `amount` |
| `merchant` | `amount` | `amount - fee_amount` |
QRIS is created dynamically by the provider and validated with provider transaction IDs, not amount matching.
## HTTP Error Code
| HTTP | Code | Description |
| --- | --- | --- |
| `400` | `invalid_json` | Body is not valid JSON. |
| `400` | `invalid_amount` | `amount` must be greater than 0. |
| `400` | `invalid_bulk_size` | `payments` must contain 1 to 50 items. |
| `400` | `unsupported_payment_method` | Payment method is not supported. |
| `400` | `payment_create_failed` | Transaction could not be created. |
| `401` | `invalid_api_key` | Secret key is invalid. |
| `403` | `merchant_not_approved` | Merchant is not active. |
| `429` | `rate_limited` | Rate limit exceeded. |
---
# Transactions
> List and filter merchant transactions.
Canonical: https://docs.chiwapay.com/transactions
`GET /transactions`
Returns merchant transactions.
## Query Params
| Param | Type | Required | Description |
| --- | --- | --- | --- |
| `limit` | integer | No | Number of transactions. Default `50`. |
## Request Example
```tsx
```
## Response
```json
{
"transactions": [
{
"id": "f2b1d5b0-7b1f-4c5d-9c37-93f0c8f6a001",
"reference_id": "PAY-LXAMPLE",
"merchant_reference_id": "ORDER-1024",
"payment_method_code": "qris",
"currency": "IDR",
"amount": 150000,
"fee_amount": 1050,
"net_amount": 150000,
"total_amount": 151050,
"status": "paid",
"paid_at": "2026-05-19T10:01:00Z",
"created_at": "2026-05-19T10:00:00Z",
"updated_at": "2026-05-19T10:01:00Z"
}
]
}
```
## Response Fields
| Field | Description |
| --- | --- |
| `transactions` | Transaction list. |
| `transactions[].id` | Transaction UUID. |
| `transactions[].reference_id` | Chiwa Pay transaction ID. |
| `transactions[].merchant_reference_id` | Merchant order ID. |
| `transactions[].status` | Transaction status. |
| `transactions[].total_amount` | Amount the customer must pay. |
## HTTP Error Code
| HTTP | Code | Description |
| --- | --- | --- |
| `401` | `invalid_api_key` | Secret key is invalid. |
| `403` | `merchant_not_approved` | Merchant is not active. |
| `500` | `server_error` | Transactions could not be loaded. |
---
# Webhooks
> Receive and verify transaction status events.
Canonical: https://docs.chiwapay.com/webhooks
Webhooks are sent to the URL registered in the merchant dashboard.
## Events
```txt
payment.created
payment.pending
payment.paid
payment.expired
payment.cancelled
payment.failed
payment.refund_processing
payment.refund_failed
payment.refunded
payment.settled
```
| Event | Description |
| --- | --- |
| `payment.created` | Transaction was created. |
| `payment.pending` | Waiting for payment. |
| `payment.paid` | Payment was received. |
| `payment.expired` | Payment deadline has passed. |
| `payment.cancelled` | Transaction was cancelled. |
| `payment.failed` | Payment failed. |
| `payment.refund_processing` | Refund is being processed. |
| `payment.refund_failed` | Refund failed. |
| `payment.refunded` | Refund succeeded. |
| `payment.settled` | Transaction has entered settlement. |
## Payload
```json
{
"id": "f2b1d5b0-7b1f-4c5d-9c37-93f0c8f6a001",
"event": "payment.paid",
"reference_id": "PAY-LXAMPLE",
"merchant_reference_id": "ORDER-1024",
"status": "paid",
"environment": "live",
"amount": 150000,
"fee_amount": 1050,
"net_amount": 150000,
"total_amount": 151050,
"currency": "IDR",
"payment_method": "qris",
"provider": "gopay",
"created_at": "2026-05-19T10:00:00Z",
"updated_at": "2026-05-19T10:01:00Z"
}
```
## Headers
```http
Content-Type: application/json
User-Agent: ChiwaPay-Webhooks/0.1
X-Chiwa-Event: payment.paid
X-Chiwa-Delivery: 1d4c...
X-Chiwa-Signature: t=1779184860,v1=
```
Verify `X-Chiwa-Signature` before processing the payload.