# 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.