Payment Receipt
Generate and display payment confirmations after successful transactions.
A Payment Receipt is the confirmation your system provides after a customer completes a payment. It typically includes:
- Payment reference(s)
- Amount and currency
- Payment method
- Customer details
- Date/time of payment
- Order/service details (from your system)
Chapa provides the data you need for a receipt through:
- Payment verification:
GET /v2/payments/{reference}/verify - Webhook events: e.g.,
payment.success
Best practice: Generate receipts from verified payment data (server-side) — not from redirect parameters or frontend callbacks.
When to Generate a Receipt
Generate a receipt only after you confirm the payment is successful.
Option A — Webhook-driven (Recommended)
- Receive
payment.successwebhook - Mark order as paid
- Generate and store receipt
- Show receipt page and/or send email/SMS
Option B — Verify after Redirect (Common)
- Customer returns from checkout
- Your backend calls
/verify - If
data.status == "success", generate receipt
In real systems, teams often do both: Webhook = source of truth (real-time), Verify = optional double-check / fallback.
Minimum Receipt Fields (Recommended)
Transaction Details
| Field | Description |
|---|---|
chapa_reference | Chapa's payment reference |
merchant_reference | Your order/payment reference |
status | Payment status (success) |
amount | Payment amount |
currency | Currency code (ETB, USD, UGX, DJF) |
payment_method | Method used (e.g., telebirr, card) |
service_fee | Fee charged by Chapa (if applicable) |
created_at, updated_at | Timestamps (and/or a derived paid_at) |
Customer Details (If Available)
| Field | Description |
|---|---|
customer.first_name | Customer's first name |
customer.last_name | Customer's last name |
customer.email | Customer's email address |
customer.phone_number | Customer's phone number |
Merchant / Order Details (From Your System)
| Field | Description |
|---|---|
| Order ID | Usually from meta.order_id |
| Item list | Products, plan name, ticket info |
| Merchant info | Merchant name & contact info |
Receipt Data Sources
1) From Payment Verification (Most Accurate)
Use:
GET /v2/payments/{reference}/verifyVerified data includes:
amount,currency,statuspayment_method,service_feecustomerdetails (when provided)- timestamps
Use verification when:
- You're fulfilling a high-value order
- You didn't receive webhooks (temporary downtime)
- You need absolute confirmation before issuing a receipt
2) From Webhook (payment.success)
A payment.success webhook typically includes:
merchant_referencechapa_referenceamount,currencypayment_methodcustomermetacreated_at,updated_at
Use webhooks to trigger receipt generation, and store the webhook payload (or normalized fields) for audit and troubleshooting.
Example Receipt Object (Suggested Schema)
This is a clean receipt object you can store in your database:
{
"receipt_id": "RCT_000123",
"order_id": "ORD-99887",
"merchant_reference": "ORDER_1001",
"chapa_reference": "CHAPA123456789",
"status": "success",
"amount": 25000,
"currency": "ETB",
"payment_method": "telebirr",
"service_fee": 350,
"customer": {
"first_name": "John",
"last_name": "Doe",
"email": "john.doe@example.com",
"phone_number": "251722927727"
},
"meta": {
"notes": "premium subscription"
},
"paid_at": "2025-11-07T13:00:00Z",
"created_at": "2025-11-07T13:00:00Z"
}Receipt UX Guidelines
A good receipt page should show:
| Element | Description |
|---|---|
| Payment status | Clear "Payment Confirmed" indicator |
| Amount + currency | Formatted payment amount |
| Date/time paid | When the payment was completed |
| Reference numbers | merchant_reference, chapa_reference |
| Customer info | Optional, based on your UX |
| Download/Email option | "Download receipt" or "Email receipt" button |
| Continue action | "Back to merchant" or "Continue" button |
Handling Refunds on Receipts
Refunds are communicated via webhook events:
payment.partially_refundedpayment.fully_refunded
Recommended approach:
- Store the receipt as the original payment record
- Store refund records separately (refund history table / collection)
- On receipt UI, display:
- Refunded amount
- Refund status
- Latest refund timestamp (if tracked)
This prevents confusing "receipt mutation" and keeps audit trails clean.
Best Practices
- Generate receipts only after
status == "success" - Store webhook payloads (or normalized fields) for audit
- Use
merchant_reference+meta.order_idfor reconciliation - Show
chapa_referenceon receipts (useful for support + disputes) - Process webhook retries idempotently (don't create duplicate receipts)
Next Steps
- Verify Payments - Confirm payment status server-side
- Webhooks - Handle payment events in real-time
- Accept Payments - Full payment integration guide