Home/Docs

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

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/json

Request Body

{
  "type": "hosted",
  "amount": 100,
  "card_number": "7878064900",
  "merchant_reference": "ORDER-2026-001"
}
FieldRequiredDescription
typeYes"hosted"
amountYesAmount to add
card_numberYesCard to credit
merchant_referenceNoYour 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

StatusMessageWhen
400Validation errorMissing amount, card_number, or type
404Gift card not foundcard_number does not exist on your account
409Duplicate merchant referenceSame 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"
}
FieldRequiredDescription
typeYes"direct-charge"
phone_numberYesCustomer phone
payment_methodYesWallet 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

StatusMessageWhen
400Validation errorMissing phone_number or payment_method
404Gift card not foundcard_number does not exist on your account
404Account not foundNo linked wallet account for the card holder
400Account is not activeThe card holder's linked account is disabled
409Duplicate merchant referenceSame 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}}
QueryDefaultMaxDescription
page1Page number (1-based)
limit15100Number of records per page
offsetOptional 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

FieldDescription
link_referenceReference returned when you started the payment
merchant_referenceYour order ID, if you sent one
chapa_referenceChapa processor reference, when available
statuspending, success, or failed
currencyCard currency
amountAmount in minor units
service_feeFee charged on the transaction
payment_methodWallet slug, e.g. telebirr
card_numberGift card that was credited
modelive or test — matches your API key environment
created_atWhen the payment was created
updated_atWhen 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

StatusMessageWhen
400Invalid requestreference path parameter is missing
404Payment not foundReference 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