# 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.