Add Chapa checkout, verify, webhook, and callback flows so subscriptions activate only after confirmed payment. Route subscription checkout through Chapa while keeping ArifPay for direct payments. Include integration docs and a Postman collection. Co-authored-by: Cursor <cursoragent@cursor.com>
84 lines
3.0 KiB
Markdown
84 lines
3.0 KiB
Markdown
# Chapa Payment Gateway Integration
|
|
|
|
Subscription payments for learners use [Chapa](https://developer.chapa.co/docs) hosted checkout, following the same payment-first flow as the previous ArifPay integration.
|
|
|
|
## Overview
|
|
|
|
- Subscriptions are created only after Chapa confirms payment (webhook and/or verify).
|
|
- `tx_ref` is stored as the payment `nonce` and returned as `session_id` in API responses.
|
|
- ArifPay direct-payment routes remain available for legacy flows; subscription checkout uses Chapa.
|
|
|
|
## Environment Variables
|
|
|
|
```env
|
|
CHAPA_SECRET_KEY=CHASECK_TEST-xxxxxxxx
|
|
CHAPA_PUBLIC_KEY=CHAPUBK_TEST-xxxxxxxx
|
|
CHAPA_WEBHOOK_SECRET=your_webhook_secret_from_dashboard
|
|
CHAPA_BASE_URL=https://api.chapa.co/v1
|
|
CHAPA_CALLBACK_URL=https://your-api.example.com/api/v1/payments/chapa/callback
|
|
CHAPA_RETURN_URL=https://your-app.example.com/payment/success
|
|
CHAPA_RECEIPT_URL=
|
|
```
|
|
|
|
Configure the same webhook URL in the Chapa dashboard:
|
|
|
|
`https://your-api.example.com/api/v1/payments/webhook`
|
|
|
|
## Payment Flow
|
|
|
|
1. Learner calls `POST /api/v1/subscriptions/checkout` or `POST /api/v1/payments/subscribe`.
|
|
2. Backend creates a pending payment and calls Chapa `POST /transaction/initialize`.
|
|
3. Client redirects the user to `payment_url` (`checkout_url` from Chapa).
|
|
4. After payment, Chapa calls `callback_url` and sends a webhook.
|
|
5. Backend verifies via `GET /transaction/verify/{tx_ref}` and activates the subscription.
|
|
6. Client may poll `GET /api/v1/payments/verify/{tx_ref}` (`session_id` path param is the `tx_ref`).
|
|
|
|
## API Endpoints
|
|
|
|
| Method | Path | Auth | Description |
|
|
|--------|------|------|-------------|
|
|
| POST | `/api/v1/subscriptions/checkout` | Yes | Initiate subscription payment |
|
|
| POST | `/api/v1/payments/subscribe` | Yes | Same as checkout |
|
|
| GET | `/api/v1/payments/verify/:session_id` | Yes | Verify by `tx_ref` |
|
|
| POST | `/api/v1/payments/webhook` | No | Chapa webhook (HMAC signature required) |
|
|
| GET | `/api/v1/payments/chapa/callback` | No | Chapa redirect callback |
|
|
| GET | `/api/v1/payments/methods` | No | Supported Chapa methods |
|
|
|
|
### Initiate payment request
|
|
|
|
```json
|
|
{
|
|
"plan_id": 1,
|
|
"phone": "0912345678",
|
|
"email": "learner@example.com"
|
|
}
|
|
```
|
|
|
|
### Initiate payment response
|
|
|
|
```json
|
|
{
|
|
"message": "Payment initiated. Complete payment to activate subscription.",
|
|
"data": {
|
|
"payment_id": 42,
|
|
"session_id": "550e8400-e29b-41d4-a716-446655440000",
|
|
"payment_url": "https://checkout.chapa.co/checkout/payment/...",
|
|
"amount": 500,
|
|
"currency": "ETB",
|
|
"expires_at": "2026-05-21T18:00:00Z"
|
|
}
|
|
}
|
|
```
|
|
|
|
## Webhook Security
|
|
|
|
Chapa signs the raw JSON body with HMAC-SHA256 using your webhook secret. The handler checks `x-chapa-signature` or `chapa-signature` before processing.
|
|
|
|
## Testing
|
|
|
|
Use Chapa test keys and [test credentials](https://developer.chapa.co/test/testing-mobile). After checkout, confirm the subscription via verify endpoint or webhook logs.
|
|
|
|
### Postman
|
|
|
|
Import `postman/Chapa-Subscription-Payments.postman_collection.json`. Set collection variables (`base_url`, learner credentials, `chapa_webhook_secret`), then run folders **00 → 02** in order.
|