Accept Payments
Learn how to accept payments with Chapa API v2 by initializing transactions and redirecting customers to hosted checkout.
This section explains how to accept payments with Chapa API v2 by initializing a transaction and redirecting your customer to a hosted checkout page.
You can integrate Chapa using:
- REST APIs
- JavaScript libraries (Inline / Popup)
- SDKs & plugins
Regardless of the method, the core concept is the same:
Create a payment session → receive a checkout_url → redirect the customer → verify payment
How the Payment Flow Works
- Collect customer and payment details in your application
- Initialize a payment using Chapa's API
- Redirect the customer to the returned
checkout_url - Receive post-payment signals (redirect / webhook)
- Verify the payment on your server
- Fulfill the order only after successful verification
Important: Redirects, callbacks, and webhooks are signals, not proof. Always verify the payment server-side before delivering value.
Collecting Customer Information
Before initializing a payment, your application should collect the required payment details.
Required Fields
| Parameter | Description |
|---|---|
amount | Amount to charge the customer |
currency | Transaction currency |
Supported Currencies
| Code | Currency |
|---|---|
ETB | Ethiopian Birr |
USD | US Dollar |
UGX | Ugandan Shilling |
DJF | Djiboutian Franc |
Currency availability may vary by payment method and region.
Conditionally Required
| Parameter | Description |
|---|---|
phone_number | Required for high-risk businesses and some payment methods |
Phone number rules:
- Must be in international format
- Example:
251722927727 - Invalid formats will cause validation errors
Optional (Recommended)
| Parameter | Description |
|---|---|
merchant_reference | Your unique internal reference for this payment |
customer | Customer information (name, email, phone) |
preferred_payment_methods | Control checkout payment methods and order |
subaccounts | Used for split payments |
meta | Internal metadata (order ID, notes, etc.) |
Initialize a Hosted Payment
Use this endpoint to create a hosted checkout session and receive a checkout_url.
Endpoint:
POST /v2/payments/hosted
Host: api.chapa.coHeaders:
Authorization: Bearer <YOUR_SECRET_KEY>
Content-Type: application/jsonExample Request:
{
"amount": 25000,
"currency": "ETB",
"merchant_reference": "Cv90J9DZ8r6zKW",
"preferred_payment_methods": ["telebirr", "cbebirr", "cbe"],
"subaccounts": [
{
"subaccount_reference": "SUB_REF_001",
"split_type": "percentage",
"split_value": 10
},
{
"subaccount_reference": "SUB_REF_002",
"split_type": "flat",
"split_value": 243
}
],
"customer": {
"first_name": "John",
"last_name": "Doe",
"email": "john.doe@example.com",
"phone_number": "251722927727"
},
"meta": {
"order_id": "ORD-99887",
"notes": "Hosted payment for premium subscription"
}
}Field Notes
| Field | Description |
|---|---|
merchant_reference | Your unique identifier for this payment. Must be unique per order/attempt. |
preferred_payment_methods | Optional. Controls which methods appear on checkout and in what order. |
customer | Strongly recommended for receipts, reconciliation, and support. |
subaccounts | Optional. Used for revenue split (percentage or flat). |
meta | Optional. Store internal identifiers for reporting and reconciliation. |
Successful Response
If initialization succeeds, Chapa returns a hosted checkout link.
{
"status": "success",
"message": "Payment initialized successfully",
"data": {
"checkout_url": "https://checkout.chapa.co/payment/CHAPA123456789",
"created_at": "2025-11-07T12:00:00Z",
"expires_at": "2025-11-07T13:00:00Z"
}
}What You Should Store:
merchant_referencecheckout_urlchapa_reference(via webhook or verification)- timestamps (optional)
Failed Response
Example error response:
{
"status": "error",
"message": "Failed to initialize direct charge. Try again later.",
"error": {
"code": "PROCESSING_FAILED",
"details": null
}
}Recommended Handling:
- Log the full error response (server-side)
- Show a friendly error message to the user
- Allow retry, but avoid duplicate orders
Redirect the Customer to Checkout
Once you receive data.checkout_url, redirect the customer:
- Web: Browser redirect
- Mobile: In-app browser or system browser
Chapa handles the checkout experience and payment method selection.
After Payment: What Happens Next
After payment completion (success, failure, cancellation), Chapa may notify you through:
- Webhook events (recommended, reliable)
- Redirect back to your app (UX signal)
- Dashboard updates
- Email notification (if enabled)
Do not rely on redirects alone.
Webhooks (Recommended)
Webhooks are the source of truth for payment status changes.
Typical payment events:
payment.successpayment.failedpayment.cancelledpayment.incompletepayment.auth_neededpayment.blocked
Best Practices:
- Validate webhook authenticity (if signature verification is enabled)
- Implement idempotency (events may be delivered more than once)
- Update internal payment state
- Optionally re-verify critical payments
See the Webhooks section for payload formats.
Verify the Transaction (Required)
Verification confirms:
- Payment actually succeeded
- Amount and currency match expectations
- Transaction belongs to your merchant account
Endpoint:
GET /v2/payments/{reference}/verifyOnly after verification returns a successful and valid result should you:
- Mark the order as paid
- Deliver goods or services
- Trigger fulfillment workflows
Redirection Behavior
Hosted payments are redirection-based:
- You initialize the payment
- Customer pays on Chapa checkout
- Chapa redirects back to your app (optional)
- Webhook confirms final status
This approach is reliable for both web and mobile integrations.
Retry Behavior
- Customers can retry failed payments up to 10 times
- Retry window is configurable in the dashboard (default: 60 minutes, range: 5–60 minutes)
Recommended Practices:
- Offer a "Try again" option
- Reuse the same logical order
- Ensure your system handles multiple attempts safely
Customer Profiles (Dashboard Feature)
Chapa supports customer profiles via the dashboard.
To use:
- Enable customer profiles: Settings → Account Settings
- Manage customers from the Customers section
Benefits:
- Easier support and reconciliation
- Better customer tracking
- Foundation for repeat payments (where applicable)
Key Takeaways
- Always verify payments server-side
- Use webhooks as your primary signal
- Keep
merchant_referenceunique - Handle retries safely
- Never deliver value before verification
Next Steps
- Quick Start - Simple end-to-end payment flow
- Dashboard Overview - Manage payments from the dashboard
- Migration Guide - Migrate from v1 to v2