Payments
Add money to a gift card. Use hosted checkout when the customer pays on a checkout page. Use direct charge when you already have their phone number and wallet.
The currency comes from the card — you don't send it in the request.
Variables
{{API_KEY}}: your API key
Top Up - Hosted Checkout
Send the customer to a checkout page.
Endpoint
POST https://api.chapa.link/card/payments
Authorization: Bearer {{API_KEY}}
Content-Type: application/jsonRequest Body
{
"type": "hosted",
"amount": 100,
"card_number": "7878064900",
"merchant_reference": "ORDER-2026-001"
}| Field | Required | Description |
|---|---|---|
type | Yes | "hosted" |
amount | Yes | Amount to add |
card_number | Yes | Card to credit |
merchant_reference | No | Your order ID (must be unique if you use it) |
Success Response
{
"status": "success",
"message": "Card payment initiated successfully",
"data": {
"checkout_url": "https://checkout.chapa.co/payment/hosted/APR81525505F",
"created_at": "2026-06-15T12:11:45.169804804Z",
"expires_at": "2026-06-16T12:11:45.178018509Z",
"link_reference": "CARD-j81525500a",
"merchant_reference": "ORDER-2026-001"
}
}Redirect the customer to checkout_url. Save link_reference to check status later.
Error Responses
| Status | Message | When |
|---|---|---|
400 | Validation error | Missing amount, card_number, or type |
404 | Gift card not found | card_number does not exist on your account |
409 | Duplicate merchant reference | Same merchant_reference was used before |
{
"status": "error",
"message": "Validation error",
"error": {
"type": "Type is required"
}
}{
"status": "error",
"message": "Duplicate merchant reference. merchant_reference must be unique per merchant",
"error": "merchant_reference must be unique per merchant"
}Top Up — Direct Charge
Charge a wallet (e.g. Telebirr) directly.
Request Body
{
"type": "direct-charge",
"amount": 100,
"card_number": "5610764625",
"phone_number": "+251960724272",
"payment_method": "telebirr"
}| Field | Required | Description |
|---|---|---|
type | Yes | "direct-charge" |
phone_number | Yes | Customer phone |
payment_method | Yes | Wallet slug, e.g. telebirr |
Success Response
{
"status": "success",
"message": "Card payment initiated successfully",
"data": {
"auth_type": "ussd",
"created_at": "2026-06-15T12:13:42.325100518Z",
"expires_at": "2026-06-15T12:13:42.325100644Z",
"link_reference": "CARD-581525615z",
"payment_status": "Accepted",
"processor_reference": "CHzMxTthJUpD",
"request_id": "REQc81525616m"
}
}The customer may need to approve on their phone (USSD) before the payment completes.
Error Responses
| Status | Message | When |
|---|---|---|
400 | Validation error | Missing phone_number or payment_method |
404 | Gift card not found | card_number does not exist on your account |
404 | Account not found | No linked wallet account for the card holder |
400 | Account is not active | The card holder's linked account is disabled |
409 | Duplicate merchant reference | Same merchant_reference was used before |
{
"status": "error",
"message": "Validation error",
"error": {
"payment_method": "phone_number and payment_method are required for direct-charge"
}
}{
"status": "error",
"message": "Account is not active. The provided account is not active",
"error": "The provided account is not active"
}List Payments
Returns paginated payment records for your business. Use page and limit to page through results. Each item includes mode (live or test) matching your API key environment.
GET https://api.chapa.link/card/payments?page=1&limit=15
Authorization: Bearer {{API_KEY}}| Query | Default | Max | Description |
|---|---|---|---|
page | 1 | — | Page number (1-based) |
limit | 15 | 100 | Number of records per page |
offset | — | — | Optional alternative to page (0-based skip) |
Success Response
{
"status": "success",
"message": "Payments fetched successfully",
"data": {
"items": [
{
"link_reference": "CARD-j81525500a",
"merchant_reference": "ORDER-2026-001",
"chapa_reference": "CHzMxTthJUpD",
"status": "success",
"currency": "ETB",
"amount": 100,
"service_fee": 0,
"payment_method": "telebirr",
"card_number": "7878064900",
"mode": "live",
"created_at": "2026-06-15T12:11:45Z",
"updated_at": "2026-06-15T12:15:54Z"
}
],
"total": 24,
"page": 1,
"limit": 15,
"pages": 2
}
}Results are ordered by newest first. status is pending, success, or failed.
List item fields
| Field | Description |
|---|---|
link_reference | Reference returned when you started the payment |
merchant_reference | Your order ID, if you sent one |
chapa_reference | Chapa processor reference, when available |
status | pending, success, or failed |
currency | Card currency |
amount | Amount in minor units |
service_fee | Fee charged on the transaction |
payment_method | Wallet slug, e.g. telebirr |
card_number | Gift card that was credited |
mode | live or test — matches your API key environment |
created_at | When the payment was created |
updated_at | When the payment was last updated |
Check Payment Status
GET https://api.chapa.link/card/payment/CARD-R79130925F/status
Authorization: Bearer {{API_KEY}}Success Response
{
"status": "success",
"message": "Payment status fetched successfully",
"data": {
"reference": "CARD-p81525749O",
"chapa_ref": "CHFghskey123",
"amount": 100,
"service_fee": 0,
"currency": "ETB",
"status": "success",
"created_at": "2026-06-15T12:15:54Z",
"completed_at": "2026-06-15T12:15:54Z"
}
}data.status is pending, success, or failed.
Error Responses
| Status | Message | When |
|---|---|---|
400 | Invalid request | reference path parameter is missing |
404 | Payment not found | Reference does not exist or does not belong to your business |
{
"status": "error",
"message": "Payment not found",
"error": "Payment not found"
}For production, use webhooks instead of polling. Polling is fine for testing.
Tips
- Call this API from your server only
- Save
link_referencefrom every payment you start - Use
merchant_referenceto tie payments to your own order IDs - Use
GET /card/paymentsto page through payment history for your business