Verify Payments
Confirm the final status of a transaction before fulfilling orders or delivering goods.
Payment verification is how you confirm the final status of a transaction after a customer attempts to pay.
You should verify a payment when:
- The customer returns from checkout (redirect or inline completion)
- You receive a webhook event and want to double-check (optional)
- You must confirm payment status before delivering goods/services
Best practice: Always verify payments server-side before fulfilling an order. Redirects and frontend callbacks are not a reliable source of truth.
Endpoint
GET /v2/payments/{reference}/verify
Host: api.chapa.coAuthentication
Headers
| Name | Required | Description |
|---|---|---|
Authorization | Yes | Bearer token containing your private API key (Bearer <PRIVATE_API_KEY>) |
Content-Type | Yes | Must be application/json |
Example:
Authorization: Bearer CHAPA_TEST_xxxxxxxxxxxxx
Content-Type: application/jsonPath Parameter
| Name | Type | Required | Description |
|---|---|---|---|
reference | string | Yes | Unique payment reference returned during initialization (Chapa reference) |
Example Request
GET https://api.chapa.co/v2/payments/CHAPA123456789/verify
Authorization: Bearer CHAPA_TEST_xxxxxxxxxxxxx
Content-Type: application/jsonExample Response
{
"status": "success",
"message": "Payment retrieved successful",
"data": {
"chapa_reference": "CHAPA123456789",
"merchant_reference": "Cv90J9DZ8r6zKW",
"amount": 25000,
"currency": "ETB",
"status": "success",
"payment_method": "card",
"service_fee": 350,
"customer": {
"first_name": "John",
"last_name": "Doe",
"email": "john.doe@example.com",
"phone_number": "251722927727"
},
"created_at": "2025-11-07T11:06:00Z",
"updated_at": "2025-11-08T11:08:00Z"
}
}In some older examples, merchant_referece appears misspelled. Your integration should expect and store merchant_reference consistently.
Response Fields
Top-Level Fields
| Field | Type | Description |
|---|---|---|
status | string | Operation result: success or error |
message | string | Human-readable summary |
data | object | Payment details |
Payment Object (data)
| Field | Type | Description |
|---|---|---|
chapa_reference | string | Chapa payment reference |
merchant_reference | string | Your merchant-generated reference (if provided) |
amount | number | Payment amount |
currency | string | ISO currency code (ETB, USD, UGX, DJF) |
status | string | Payment status (e.g., success, pending, failed, cancelled, incomplete) |
payment_method | string | Payment method used (e.g., telebirr, card) |
service_fee | number | Fee charged by Chapa (if applicable) |
customer | object | Customer details |
created_at | string | ISO8601 creation time |
updated_at | string | ISO8601 last update time |
How to Use Verification in Your App
Typical Flow
- Initialize payment → get checkout URL
- Customer completes checkout
- Your backend calls
/verify - Handle the response:
- If
data.status == "success"→ fulfill order / grant access - If
data.status == "pending"→ wait for webhook or retry verification - If
data.status == "failed" | "cancelled" | "incomplete" | "blocked"→ show error, allow retry if applicable
- If
Recommended Verification Rules
Treat a payment as successful only when:
data.status == "success"- Amount and currency match what you expected
- The payment belongs to your merchant account
Store these for reconciliation:
chapa_referencemerchant_referenceamount,currencypayment_methodservice_feecreated_at,updated_atcustomer(if available)
If you receive a webhook event:
- Use it as a real-time signal to update state
- Optionally verify once more for confirmation (useful for high-value orders)
Common Errors
| HTTP | Error Code | Meaning |
|---|---|---|
| 400 | MISSING_REQUIRED_FIELD | Reference is missing |
| 404 | NOT_FOUND | Payment not found |
| 500 | PROCESSING_FAILED | System issue fetching payment |
Failed Response
If the reference is invalid or the payment cannot be found:
{
"status": "error",
"message": "Payment not found",
"error": {
"code": "NOT_FOUND",
"details": null
}
}Recommended handling:
- Confirm you're verifying with the correct reference (Chapa reference, not your merchant reference)
- Ensure you're using the correct environment keys (test key for test payments, live key for live payments)
- If you just created the payment, retry verification after a short delay (your system should be resilient to temporary states)
Verification Checklist
Before you mark an order as paid, confirm all of the following on your server:
| Check | Description |
|---|---|
status === "success" | Payment completed successfully |
| Amount matches | Matches your expected order total |
| Currency matches | Matches what you initialized |
merchant_reference matches | Matches your order/payment attempt |
| Not already processed | Use idempotency on your side |
Never deliver goods or services until all verification checks pass on your server.
Next Steps
- Accept Payments - Full hosted payment integration
- Webhooks - Real-time payment notifications
- Quick Start - End-to-end payment flow