Yimaru-BackEnd/docs/ARIFPAY_INTEGRATION.md

347 lines
8.1 KiB
Markdown

# ArifPay Payment Gateway Integration
This document describes the ArifPay payment gateway integration for subscription payments in the Yimaru LMS application.
## Overview
The integration **coordinates payment with subscriptions** - users cannot create subscriptions without completing payment. Only admins can bypass this restriction for special cases (e.g., promotional subscriptions).
### Key Features:
- **Payment-first approach**: Subscriptions are only created after successful payment
- **Multiple payment flows**: Checkout redirect or direct OTP-based payment
- **Webhook handling**: Automatic subscription creation on payment success
- **Role-based access**: Regular users must pay; admins can grant free subscriptions
The integration supports multiple Ethiopian payment methods including:
- Telebirr
- CBE (Commercial Bank of Ethiopia)
- Awash Bank
- Amole
- HelloCash
- M-Pesa
- And more
## Environment Variables
Add the following environment variables to your `.env` file:
```env
# ArifPay Configuration
ARIFPAY_API_KEY=your_arifpay_api_key
ARIFPAY_BASE_URL=https://gateway.arifpay.net
ARIFPAY_CANCEL_URL=https://yourdomain.com/payment/cancelled
ARIFPAY_SUCCESS_URL=https://yourdomain.com/payment/success
ARIFPAY_ERROR_URL=https://yourdomain.com/payment/error
ARIFPAY_C2B_NOTIFY_URL=https://yourdomain.com/api/v1/payments/webhook
ARIFPAY_B2C_NOTIFY_URL=https://yourdomain.com/api/v1/payments/b2c-webhook
ARIFPAY_BANK=AWINETAA
ARIFPAY_BENEFICIARY_ACCOUNT_NUMBER=your_account_number
ARIFPAY_DESCRIPTION=Yimaru LMS Subscription
ARIFPAY_ITEM_NAME=Subscription
```
## Database Migration
Run the migration to create the payments table:
```bash
migrate -path db/migrations -database "postgres://..." up
```
Or manually run:
```sql
-- See db/migrations/000009_payments.up.sql
```
## API Endpoints
### Subscription Endpoints
#### Subscribe with Payment (Recommended)
**POST** `/api/v1/subscriptions/checkout`
The primary endpoint for users to subscribe. Initiates payment and returns checkout URL.
**Request Body:**
```json
{
"plan_id": 1,
"phone": "0912345678",
"email": "user@example.com"
}
```
**Response:**
```json
{
"message": "Payment initiated. Complete payment to activate subscription.",
"data": {
"payment_id": 123,
"session_id": "ABC123DEF456",
"payment_url": "https://checkout.arifpay.net/...",
"amount": 299.99,
"currency": "ETB",
"expires_at": "2024-01-15T18:30:00Z"
}
}
```
#### Direct Subscribe (Admin Only)
**POST** `/api/v1/subscriptions`
Creates subscription without payment. Only accessible by admin/super_admin roles.
---
### Payment Endpoints
#### Initiate Subscription Payment
**POST** `/api/v1/payments/subscribe`
Creates a payment session for a subscription plan.
**Request Body:**
```json
{
"plan_id": 1,
"phone": "0912345678",
"email": "user@example.com"
}
```
**Response:**
```json
{
"message": "Payment initiated successfully",
"data": {
"payment_id": 123,
"session_id": "ABC123DEF456",
"payment_url": "https://checkout.arifpay.net/...",
"amount": 299.99,
"currency": "ETB",
"expires_at": "2024-01-15T18:30:00Z"
}
}
```
### Verify Payment Status
**GET** `/api/v1/payments/verify/:session_id`
Checks the payment status with ArifPay and updates local records.
**Response:**
```json
{
"message": "Payment status retrieved",
"data": {
"id": 123,
"status": "SUCCESS",
"subscription_id": 456,
...
}
}
```
### Get Payment History
**GET** `/api/v1/payments`
Returns the authenticated user's payment history.
**Query Parameters:**
- `limit` (default: 20)
- `offset` (default: 0)
### Get Payment Details
**GET** `/api/v1/payments/:id`
Returns details of a specific payment.
### Cancel Payment
**POST** `/api/v1/payments/:id/cancel`
Cancels a pending payment.
### Payment Webhook
**POST** `/api/v1/payments/webhook`
Webhook endpoint called by ArifPay when payment status changes.
**Note:** This endpoint does not require authentication as it's called by ArifPay servers.
### Get Available Payment Methods
**GET** `/api/v1/payments/methods`
Returns list of supported payment methods.
---
## Direct Payment Endpoints (OTP-based)
Direct payments allow users to pay without being redirected to a payment page. Instead, the payment is processed via OTP verification.
### Initiate Direct Payment
**POST** `/api/v1/payments/direct`
Initiates a direct payment with a specific payment method.
**Request Body:**
```json
{
"plan_id": 1,
"phone": "0912345678",
"email": "user@example.com",
"payment_method": "AMOLE"
}
```
**Supported Payment Methods:**
- `TELEBIRR` - Telebirr (push notification)
- `TELEBIRR_USSD` - Telebirr USSD
- `CBE` - Commercial Bank of Ethiopia
- `AMOLE` - Amole (requires OTP)
- `HELLOCASH` - HelloCash (requires OTP)
- `AWASH` - Awash Bank (requires OTP)
- `MPESA` - M-Pesa
**Response:**
```json
{
"message": "OTP sent to your phone. Please verify to complete payment.",
"data": {
"payment_id": 123,
"session_id": "ABC123DEF456",
"requires_otp": true,
"amount": 299.99,
"currency": "ETB"
}
}
```
### Verify OTP
**POST** `/api/v1/payments/direct/verify-otp`
Verifies the OTP for direct payment methods (Amole, HelloCash, Awash).
**Request Body:**
```json
{
"session_id": "ABC123DEF456",
"otp": "123456"
}
```
**Response (Success):**
```json
{
"message": "Payment completed successfully",
"data": {
"success": true,
"transaction_id": "TXN123456",
"payment_id": 123
}
}
```
**Response (Failed):**
```json
{
"message": "Invalid OTP"
}
```
### Get Direct Payment Methods
**GET** `/api/v1/payments/direct/methods`
Returns list of payment methods that support direct payment.
---
## Payment Flows
### Flow 1: Checkout Session (Redirect-based)
1. **User selects a subscription plan** and initiates payment via `/payments/subscribe`
2. **Backend creates a payment record** with status `PENDING`
3. **Backend calls ArifPay** to create a checkout session
4. **User is redirected** to ArifPay payment page (using `payment_url`)
5. **User completes payment** on ArifPay
6. **ArifPay sends webhook** to notify payment status
7. **Backend processes webhook:**
- Updates payment status
- If successful, creates subscription
- Links payment to subscription
8. **User can verify** payment status via `/payments/verify/:session_id`
### Flow 2: Direct Payment (OTP-based)
1. **User selects plan and payment method** via `/payments/direct`
2. **Backend creates payment record** and checkout session
3. **Backend initiates direct transfer** with selected payment method
4. **For OTP-required methods (Amole, HelloCash, Awash):**
- User receives OTP via SMS
- User submits OTP via `/payments/direct/verify-otp`
- Backend verifies OTP with ArifPay
- On success, creates subscription
5. **For push-based methods (Telebirr, CBE):**
- User receives push notification on their app
- User approves payment in their app
- ArifPay sends webhook notification
- Backend creates subscription
## Statuses
### Payment Statuses
- `PENDING` - Payment initiated, waiting for user action
- `PROCESSING` - Payment is being processed
- `SUCCESS` - Payment completed successfully
- `FAILED` - Payment failed
- `CANCELLED` - Payment cancelled by user
- `EXPIRED` - Payment session expired
### Subscription Statuses
- `PENDING` - Subscription pending payment
- `ACTIVE` - Subscription is active
- `EXPIRED` - Subscription has expired
- `CANCELLED` - Subscription was cancelled
## Error Handling
The integration handles various error scenarios:
- User already has an active subscription
- Plan not found or inactive
- Payment verification failures
- Webhook processing errors
## Security Considerations
1. Webhook endpoint validates requests from ArifPay
2. Payment verification double-checks with ArifPay API
3. User can only access their own payment records
4. Sensitive data (API keys) stored in environment variables
## Testing
For sandbox testing, use:
- Base URL: `https://gateway.arifpay.net` (sandbox mode enabled via API key)
- Test phone numbers provided by ArifPay
- Sandbox credentials from ArifPay developer portal
## Support
For ArifPay-specific issues:
- Developer Portal: https://developer.arifpay.net
- Telegram: https://t.me/arifochet
- Support: info@arifpay.com