# 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