8.1 KiB
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:
# 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:
migrate -path db/migrations -database "postgres://..." up
Or manually run:
-- 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:
{
"plan_id": 1,
"phone": "0912345678",
"email": "user@example.com"
}
Response:
{
"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:
{
"plan_id": 1,
"phone": "0912345678",
"email": "user@example.com"
}
Response:
{
"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:
{
"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:
{
"plan_id": 1,
"phone": "0912345678",
"email": "user@example.com",
"payment_method": "AMOLE"
}
Supported Payment Methods:
TELEBIRR- Telebirr (push notification)TELEBIRR_USSD- Telebirr USSDCBE- Commercial Bank of EthiopiaAMOLE- Amole (requires OTP)HELLOCASH- HelloCash (requires OTP)AWASH- Awash Bank (requires OTP)MPESA- M-Pesa
Response:
{
"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:
{
"session_id": "ABC123DEF456",
"otp": "123456"
}
Response (Success):
{
"message": "Payment completed successfully",
"data": {
"success": true,
"transaction_id": "TXN123456",
"payment_id": 123
}
}
Response (Failed):
{
"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)
- User selects a subscription plan and initiates payment via
/payments/subscribe - Backend creates a payment record with status
PENDING - Backend calls ArifPay to create a checkout session
- User is redirected to ArifPay payment page (using
payment_url) - User completes payment on ArifPay
- ArifPay sends webhook to notify payment status
- Backend processes webhook:
- Updates payment status
- If successful, creates subscription
- Links payment to subscription
- User can verify payment status via
/payments/verify/:session_id
Flow 2: Direct Payment (OTP-based)
- User selects plan and payment method via
/payments/direct - Backend creates payment record and checkout session
- Backend initiates direct transfer with selected payment method
- 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
- 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 actionPROCESSING- Payment is being processedSUCCESS- Payment completed successfullyFAILED- Payment failedCANCELLED- Payment cancelled by userEXPIRED- Payment session expired
Subscription Statuses
PENDING- Subscription pending paymentACTIVE- Subscription is activeEXPIRED- Subscription has expiredCANCELLED- 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
- Webhook endpoint validates requests from ArifPay
- Payment verification double-checks with ArifPay API
- User can only access their own payment records
- 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