Fast Hosted Checkout
Create a payment session, redirect the customer, then verify or receive IPN updates when the transaction completes.
Accept wallet, gateway, and hosted checkout payments with environment-aware credentials, merchant-level currency control, and dashboard-managed payment gateway rules.
Create a payment session, redirect the customer, then verify or receive IPN updates when the transaction completes.
The requested currency must be enabled for the merchant and backed by an active merchant wallet.
Merchants can choose eligible payment gateways from API Config without regenerating API credentials.
EriPay API uses API keys to authenticate requests. You can obtain your credentials from your merchant dashboard.
EriPay API supports both sandbox (testing) and production environments. Always test in sandbox first before going live.
Use for: Development, testing, integration
X-Environment: sandbox
Credentials: Use test_* prefixed API keys
Use for: Live payments, real money
X-Environment: production
Credentials: Use production API keys (no prefix)
| Credential | Header | Description | Location |
|---|---|---|---|
Merchant ID |
X-Merchant-Key |
Your unique merchant identifier | Dashboard → Merchant → Config |
API Key |
X-API-Key |
API authentication key | Dashboard → Merchant → Config |
Request Timestamp |
X-Timestamp |
Unix timestamp in seconds used for replay protection | Generated by your server for each API request |
API Signature |
X-Signature |
HMAC-SHA256 signature for the request | Generated using your Client Secret |
Client Secret |
- | Used for API request signing and webhook signature verification | Dashboard → Merchant → CONFIG |
| Production API Key | X-API-Key |
Production API key (no prefix) | Merchant Dashboard > API Config > Production Mode |
| Production Merchant Key | X-Merchant-Key |
Production merchant identifier (no prefix) | Merchant Dashboard > API Config > Production Mode |
When API signatures are required, sign this exact payload with your Client Secret:
timestamp.HTTP_METHOD.path_with_query.raw_body
Use this flow for a production-safe integration. Credentials identify the merchant, while currency and gateway availability are controlled from the merchant dashboard.
Open Dashboard -> Merchant -> Config and copy the Merchant Key, API Key, and Client Secret for sandbox or production.
Make sure the merchant supports the checkout currency and the merchant owner has an active wallet for that currency.
From API Config, enable the payment gateways that should appear on hosted checkout for each eligible currency.
POST to /api/v1/initiate-payment with X-Timestamp and X-Signature, redirect the customer to payment_url, then verify or listen for IPN.
Use sandbox credentials first, then switch to production when your checkout and IPN are verified.
The merchant API is no longer a single-currency, fixed-gateway flow. A merchant can now support multiple currency rails, keep separate sandbox and production credentials, and choose eligible gateways from the API Config page without regenerating API keys.
Your code sends amount, currency, redirects, IPN URL, and optional gateway keywords. The dashboard decides which currency rails, wallets, and payment gateways are actually available for that merchant.
Pending merchants can test in sandbox. Production API access and live checkout are available only after admin approval.
Each request currency_code must exist in the merchant-supported currency list. Unsupported currencies are rejected before checkout opens.
The merchant owner must have an active wallet for the requested currency, otherwise the API returns a wallet availability error.
Only active automatic gateways that match the requested currency and merchant selection can appear on hosted checkout.
X-Environment decides which merchant key, API key, and API secret are used.
Rejected or disabled merchants are blocked. Production also requires approved merchant status.
currency_code must match a merchant-supported rail such as USD, EUR, or BDT.
The merchant owner needs an active wallet for that same currency.
Merchant API Config selections restrict checkout to the chosen eligible gateways. If none are selected, the safe fallback is all active automatic gateways for that currency.
allow_payment_methods can narrow the available gateway list, but it cannot expose an unconfigured or wrong-currency gateway.
| Case | API Result | Fix |
|---|---|---|
| Merchant supports USD and EUR, but only USD wallet exists. | 422 Receiver wallet for this currency is not available. |
Create/activate the EUR merchant wallet before accepting EUR checkout. |
| Stripe USD is selected, but the request sends currency_code EUR. | Stripe USD will not appear on checkout. | Select an active EUR gateway or send USD. |
| Merchant has not selected any gateway yet. | Checkout falls back to all active automatic gateways that match the requested currency. | Use API Config to lock checkout to preferred gateways. |
allow_payment_methods=["paypal"] but PayPal is not configured for the merchant. |
PayPal remains hidden. | Enable PayPal from Payment Gateway Controls if its currency matches. |
| Pending merchant calls production API. | 403 Merchant Pending Approval |
Use sandbox until admin approval is complete. |
A gateway configured for USD cannot process EUR checkout unless a separate EUR gateway exists.
API Secret is used only to sign server-to-server API requests and verify IPN signatures.
The returned payment_url is time-limited. Create a new payment session for expired checkout links.
A merchant can verify only its own transaction and only in the matching sandbox or production environment.
Merchant API checkout is controlled by three layers: merchant-supported currency, active receiver wallet, and configured payment gateways. This keeps checkout options accurate after API credentials are generated.
A gateway appears on hosted checkout only when every rule below is true. If the merchant has selected gateways, those selected gateways become the allowed set for checkout.
| Layer | Who controls it | Effect |
|---|---|---|
currency_code |
API request | Must match a merchant-supported currency with an active receiver wallet. |
Payment Gateway Controls |
Merchant dashboard | Defines the gateway set available to hosted checkout for each eligible currency. |
allow_payment_methods |
API request | Optional name/code keyword filter applied after merchant gateway rules. It cannot expose a gateway the merchant did not configure. |
Create a hosted checkout session for a merchant-supported currency. The returned payment_url should be opened by the customer.
https://eripays.com/api/v1/initiate-payment
| Header | Value | Required | Description |
|---|---|---|---|
Content-Type |
application/json |
Yes | Request content type |
Accept |
application/json |
Yes | Expected response type |
X-Environment |
sandbox | production |
Yes | Use sandbox for testing and production for live payments |
X-Merchant-Key |
{merchant_key} |
Yes | Merchant identifier from the API Config page |
X-API-Key |
{api_key} |
Yes | API key for the selected environment |
X-Timestamp |
{unix_timestamp} |
Yes | Current Unix timestamp in seconds. Requests outside the allowed tolerance are rejected. |
X-Signature |
sha256={hmac} |
Yes | HMAC-SHA256 of timestamp.METHOD.path_with_query.raw_body using the API Secret for the selected environment. |
| Parameter | Type | Required | Description |
|---|---|---|---|
payment_amount |
number | Yes | Payment amount. Minimum value is 1.00. |
currency_code |
string | Yes | 3-letter currency code. Must be enabled for the merchant and backed by an active merchant wallet. |
ref_trx |
string | Yes | Your unique order or transaction reference. Max 60 characters. |
success_redirect |
url | Yes | Customer is redirected here after a successful hosted checkout. |
cancel_redirect |
url | Yes | Customer is redirected here when checkout is canceled or cannot continue. |
ipn_url |
url | Yes | Server-to-server webhook URL for payment status updates. Must be a public HTTPS address (sandbox also accepts public HTTP); private and local addresses are refused. |
description |
string | No | Payment description visible in merchant transaction context. |
customer_name |
string | No | Customer name. Max 100 characters. |
customer_email |
No | Customer email address. Max 100 characters. | |
allow_payment_methods |
string | array | No | Optional keyword filter applied after merchant gateway rules. Example: "stripe,paypal" or ["stripe","paypal"]. |
| Field | Type | Meaning |
|---|---|---|
info.merchant_payment_methods_restricted |
boolean | true when the merchant has selected specific gateways in API Config. |
info.merchant_payment_method_ids |
array | Eligible deposit method IDs for the requested currency. |
info.merchant_payment_method_codes |
array | Eligible method codes that can appear on hosted checkout. |
curl -X POST "https://eripays.com/api/v1/initiate-payment" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "X-Environment: sandbox" \
-H "X-Merchant-Key: test_merchant_key" \
-H "X-API-Key: test_api_key" \
-H "X-Timestamp: 1778650000" \
-H "X-Signature: sha256=generated_hmac_signature" \
-d '{
"payment_amount": 250.00,
"currency_code": "USD",
"ref_trx": "ORDER_12345",
"description": "Premium Subscription",
"success_redirect": "https://merchant.example/payments/success",
"cancel_redirect": "https://merchant.example/payments/cancel",
"ipn_url": "https://merchant.example/webhooks/eripay",
"customer_name": "John Doe",
"customer_email": "john@example.com",
"allow_payment_methods": ["stripe", "paypal"]
}'
<?php
use Illuminate\Support\Facades\Http;
$payload = [
'payment_amount' => 250.00,
'currency_code' => 'USD',
'ref_trx' => 'ORDER_12345',
'description' => 'Premium Subscription',
'success_redirect' => route('payments.success'),
'cancel_redirect' => route('payments.cancel'),
'ipn_url' => route('webhooks.eripay'),
'customer_name' => 'John Doe',
'customer_email' => 'john@example.com',
'allow_payment_methods' => ['stripe', 'paypal'],
];
$body = json_encode($payload, JSON_THROW_ON_ERROR);
$timestamp = (string) time();
$path = '/api/v1/initiate-payment';
$signature = hash_hmac(
'sha256',
$timestamp.'.POST.'.$path.'.'.$body,
config('services.eripay.api_secret')
);
$response = Http::withHeaders([
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'X-Environment' => 'sandbox',
'X-Merchant-Key' => config('services.eripay.merchant_key'),
'X-API-Key' => config('services.eripay.api_key'),
'X-Timestamp' => $timestamp,
'X-Signature' => 'sha256='.$signature,
])->withBody($body, 'application/json')
->post('https://eripays.com/api/v1/initiate-payment')
->throw()
->json();
return redirect()->away($response['payment_url']);
const crypto = require('crypto');
const payload = {
payment_amount: 250.00,
currency_code: 'USD',
ref_trx: 'ORDER_12345',
description: 'Premium Subscription',
success_redirect: 'https://merchant.example/payments/success',
cancel_redirect: 'https://merchant.example/payments/cancel',
ipn_url: 'https://merchant.example/webhooks/eripay',
customer_name: 'John Doe',
customer_email: 'john@example.com',
allow_payment_methods: ['stripe', 'paypal']
};
const body = JSON.stringify(payload);
const timestamp = Math.floor(Date.now() / 1000).toString();
const path = '/api/v1/initiate-payment';
const signature = crypto
.createHmac('sha256', process.env.ERIPAY_API_SECRET)
.update(`${timestamp}.POST.${path}.${body}`)
.digest('hex');
const response = await fetch('https://eripays.com/api/v1/initiate-payment', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'X-Environment': 'sandbox',
'X-Merchant-Key': process.env.ERIPAY_MERCHANT_KEY,
'X-API-Key': process.env.ERIPAY_API_KEY,
'X-Timestamp': timestamp,
'X-Signature': `sha256=${signature}`
},
body
});
const data = await response.json();
if (!response.ok) {
throw new Error(data.error || 'Payment initiation failed');
}
window.location.href = data.payment_url;
{
"payment_url": "https://eripays.com/payment/checkout?expires=1791290858&token=encrypted&signature=signed",
"trx_id": "TXN7148PS8GPQKN",
"ref_trx": "ORDER_12345",
"expires_at": "2026-10-07T07:00:00+03:00",
"info": {
"ref_trx": "ORDER_12345",
"description": "Premium Subscription",
"ipn_url": "https://merchant.example/webhooks/eripay",
"cancel_redirect": "https://merchant.example/payments/cancel",
"success_redirect": "https://merchant.example/payments/success",
"customer_name": "John Doe",
"customer_email": "john@example.com",
"merchant_id": 1,
"merchant_name": "Demo Store",
"amount": 250,
"currency_code": "USD",
"environment": "sandbox",
"is_sandbox": true,
"allow_payment_methods": ["stripe", "paypal"],
"merchant_payment_methods_restricted": true,
"merchant_payment_method_ids": [7],
"merchant_payment_method_codes": ["stripe-usd"]
}
}
The requested currency_code is not in the merchant-supported currency list.
The merchant owner does not have an active wallet for the requested currency.
Check X-Environment, X-Merchant-Key, and X-API-Key for the same environment.
Creating a payment is idempotent on ref_trx: the same order returns the same pending checkout, a paid order returns 409 with its trx_id, and a different amount or currency for the same ref_trx returns 409.
Webhooks are only delivered to public addresses.
Over the per-minute rate limit, or more than 20 failed authentication attempts a minute from one address. Wait for Retry-After seconds.
Fetch the latest status for a hosted checkout transaction. Always verify server-side before fulfilling an order.
https://eripays.com/api/v1/verify-payment/{trxId}
| Header | Value | Required | Description |
|---|---|---|---|
Accept |
application/json |
Yes | Expected response type |
X-Environment |
sandbox | production |
Yes | Must match the environment used to initiate the payment |
X-Merchant-Key |
{merchant_key} |
Yes | Merchant identifier from API Config |
X-API-Key |
{api_key} |
Yes | API key for the selected environment |
X-Timestamp |
{unix_timestamp} |
Yes | Use the same timestamp format as payment initiation. |
X-Signature |
sha256={hmac} |
Yes | Sign timestamp.GET./api/v1/verify-payment/{trxId}. using the matching API Secret. The raw body is empty for GET requests. |
| Parameter | Type | Required | Description |
|---|---|---|---|
trxId |
string | Yes | The trx_id returned when you created the payment (or sent in the IPN), or your own ref_trx for that order. |
curl -X GET "https://eripays.com/api/v1/verify-payment/TXNQ5V8K2L9N3XM1" \
-H "Accept: application/json" \
-H "X-Environment: sandbox" \
-H "X-Merchant-Key: test_merchant_key" \
-H "X-API-Key: test_api_key" \
-H "X-Timestamp: 1778650000" \
-H "X-Signature: sha256=generated_hmac_signature"
{
"status": "success",
"trx_id": "TXNQ5V8K2L9N3XM1",
"amount": 237.5,
"fee": 12.5,
"currency": "USD",
"net_amount": 237.5,
"customer": {
"name": "John Doe",
"email": "john@example.com"
},
"description": "Premium Subscription",
"created_at": "2026-05-13T10:30:00.000000Z",
"updated_at": "2026-05-13T10:35:45.000000Z"
}
| Status | Description | Recommended Action |
|---|---|---|
pending |
Payment is still processing. | Wait for IPN or verify again later. |
success |
Payment completed successfully. | Fulfill the order after idempotency checks. |
failed |
Payment failed or was canceled. | Do not fulfill; show retry or cancel state. |
Fetch gateway branding, environment labels, and customer-facing checkout metadata for a merchant-authenticated integration.
https://eripays.com/api/v1/site-info
curl -X GET "https://eripays.com/api/v1/site-info" \
-H "Accept: application/json" \
-H "X-Environment: sandbox" \
-H "X-Merchant-Key: test_merchant_key" \
-H "X-API-Key: test_api_key" \
-H "X-Timestamp: 1778650000" \
-H "X-Signature: sha256=generated_hmac_signature"
{
"site_name": "EriPay",
"site_logo": "https://eripays.com/storage/images/2026/09/18/20260918_181848_ic_launcher_I86m.png",
"site_url": "https://eripays.com",
"gateway_name": "EriPay Payment Gateway",
"gateway_description": "Secure payment powered by EriPay",
"features": {
"ssl_secured": "SSL Secured",
"instant_processing": "Instant",
"global_support": "Global",
"mobile_ready": "Mobile Ready"
},
"environments": {
"production": "Production Mode - Live payment processing is active",
"sandbox": "Test Mode - This is a test transaction. No real money will be charged"
},
"api_version": "1.0",
"status": "active"
}
Refund all or part of a completed payment back to the customer. Partial refunds add up and can never exceed what the customer paid.
https://eripays.com/api/v1/refund-payment
| Customer paid with | Refund | refund_status |
|---|---|---|
| Wallet ID + PIN or logged-in wallet | Credited to the customer's wallet immediately. | completed |
| Mobile Money | Sent to the number that paid. Your wallet is debited the amount plus the mobile money payout fee; if the provider fails it, both return to your wallet. | processing → webhook |
| Sandbox payments | Recorded only; no money moves. | completed |
Your wallet must hold the refund amount. The original processing fee is not returned. Payments made through other gateways cannot be refunded through the API.
The same headers and HMAC signature as Initiate Payment: sign timestamp.POST./api/v1/refund-payment.{raw body} with the API Secret for the environment. Send an Idempotency-Key (a UUID) so a retried request replays the first answer, marked Idempotent-Replayed: true, instead of refunding twice. Reusing a key with different parameters returns 409.
| Parameter | Type | Required | Description |
|---|---|---|---|
trx_id | string | Yes | The trx_id of the completed payment |
amount | number | No | Amount to refund. Omit to refund everything not yet refunded. Mobile money refunds must be at least 500 UGX. |
reason | string | No | Stored with the refund (max 255 characters) |
ref_refund | string | No | Your own refund reference. The same reference never refunds twice for a payment. |
curl -X POST "https://eripays.com/api/v1/refund-payment" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "X-Environment: production" \
-H "X-Merchant-Key: your_merchant_key" \
-H "X-API-Key: your_api_key" \
-H "X-Timestamp: 1759650000" \
-H "X-Signature: sha256=generated_hmac_signature" \
-H "Idempotency-Key: 63632250-3170-421f-8021-9d0a730e90aa" \
-d '{"trx_id": "TXNQ5V8K2L9N3XM1", "amount": 10000, "reason": "Customer returned item", "ref_refund": "RFD-10231"}'
{
"status": "success",
"message": "Refund is being sent to the customer's mobile money number.",
"refund_trx_id": "TXNZ9YX87WV65AB",
"original_trx_id": "TXNQ5V8K2L9N3XM1",
"ref_refund": "RFD-10231",
"refund_status": "processing",
"method": "mobile_money",
"refunded_amount": 10000,
"total_refunded": 10000,
"remaining_refund": 40000,
"fully_refunded": false,
"currency": "UGX"
}
When a refund completes (or a mobile money refund fails), the payment's ipn_url receives a signed POST. Verify X-Signature (HMAC-SHA256 of the raw body with your API Secret). Refund webhooks are only sent to public HTTPS URLs.
{
"event": "payment.refunded",
"status": "refunded",
"data": {
"refund_trx_id": "TXNZ9YX87WV65AB",
"original_trx_id": "TXNQ5V8K2L9N3XM1",
"ref_trx": "ORDER-10231",
"ref_refund": "RFD-10231",
"refund_status": "completed",
"method": "mobile_money",
"refunded_amount": 10000,
"total_refunded": 10000,
"remaining_refund": 40000,
"fully_refunded": false,
"currency": "UGX"
},
"message": "Payment refunded.",
"timestamp": 1759650000
}
A failed mobile money refund sends event payment.refund_failed with status refund_failed; the amount is back in your wallet and can be refunded again.
404 Transaction not found (not yours, or a different environment).422 Only completed payments can be refunded · Refund amount exceeds the refundable balance · Insufficient merchant wallet balance · This payment method cannot be refunded through the API.409 Idempotency-Key reused with different parameters, or the first request is still running (honour Retry-After).Bill a customer daily, weekly, monthly, half-yearly or yearly. Each period is a hosted invoice the customer pays with their wallet or mobile money; the subscription becomes active, and moves to the next period, only when a payment completes.
https://eripays.com/api/v1/subscriptions
EriPay stores no card or mobile money mandate: nothing is ever charged without the customer approving it. When a period ends, EriPay creates the next invoice, marks the subscription past_due and sends you a webhook with the invoice payment_url to share with the customer (by SMS, email or in your app).
| Method | Endpoint | Purpose |
|---|---|---|
POST | /api/v1/subscriptions | Create a subscription and its first invoice (or schedule a future start). Returns 201. |
GET | /api/v1/subscriptions?status= | List your subscriptions (20 per page; filter by pending, active, past_due or canceled). |
GET | /api/v1/subscriptions/{id} | Current status and the latest 20 invoices. |
POST | /api/v1/subscriptions/{id}/cancel | Cancel at period end (default), or now with at_period_end=false. Canceling now voids the open invoice. |
POST | /api/v1/subscriptions/{id}/renew | Get a payable invoice for the unpaid period: the open one with a fresh link, or a new one if the last payment failed. Active subscriptions cannot renew early (409). |
All endpoints use the same headers and HMAC signature as Initiate Payment. Send an Idempotency-Key on every POST: retrying the identical request within 24 hours returns the original response with Idempotent-Replayed: true; reusing the key with different parameters returns 409.
| Field | Required | Rules |
|---|---|---|
external_reference | Yes | Your ID; unique per merchant and environment (max 100). Sent back as ref_trx on invoice payment IPNs. |
billing_cycle | Yes | daily, weekly, monthly, half_yearly, yearly |
payment_amount | Yes | Amount per period (mobile money payments start at 500 UGX) |
currency_code | Yes | A currency enabled for your merchant account |
customer_email | Yes | Valid email (max 150) |
success_redirect, cancel_redirect | Yes | Absolute URLs |
ipn_url | Yes | HTTPS URL on a public network; private and internal addresses are rejected |
customer_name, description | No | Shown on the hosted invoice |
starts_at | No | ISO 8601 date-time in the future; the first invoice is created then |
allow_payment_methods | No | Limit checkout methods, as with Initiate Payment |
metadata | No | JSON object (max 50 entries). Never store secrets. |
| Status | Meaning |
|---|---|
pending | First invoice unpaid, or starts_at not reached. |
active | Paid through current_period_end. The first period starts when the customer pays. |
past_due | The period ended and the renewal invoice is unpaid. Paying it restores active; periods stay back-to-back. |
canceled | No further invoices. |
curl -X POST "https://eripays.com/api/v1/subscriptions" \
-H "Content-Type: application/json" -H "Accept: application/json" \
-H "X-Environment: production" -H "X-Merchant-Key: your_merchant_key" -H "X-API-Key: your_api_key" \
-H "X-Timestamp: 1759650000" -H "X-Signature: sha256=generated_hmac_signature" \
-H "Idempotency-Key: 0b9c2f2e-7d1c-4b8e-9a41-5f3e2c1d0a77" \
-d '{"external_reference": "SCHOOL-FEES-42", "billing_cycle": "monthly", "payment_amount": 150000,
"currency_code": "UGX", "customer_email": "parent@example.com", "customer_name": "A Parent",
"success_redirect": "https://school.example/paid", "cancel_redirect": "https://school.example/cancel",
"ipn_url": "https://school.example/eripay/ipn"}'
{
"status": "success",
"data": {
"id": "sub_k2v9q4x7m1c8z5r3t6w0y2ab",
"external_reference": "SCHOOL-FEES-42",
"status": "pending",
"environment": "production",
"billing_cycle": "monthly",
"payment_amount": 150000,
"currency_code": "UGX",
"current_period_start": null,
"current_period_end": null,
"next_billing_at": null,
"cancel_at_period_end": false,
"latest_invoice": {
"trx_id": "TXNQ5V8K2L9N3XM1",
"sequence": 1,
"status": "pending",
"amount": 150000,
"payment_url": "https://eripays.com/payment/checkout?token=...&signature=..."
}
}
}
Signed like payment IPNs (verify X-Signature, HMAC-SHA256 of the raw body with your API Secret) and sent to the subscription ipn_url. data is the subscription object above.
| event | When |
|---|---|
subscription.activated | The first invoice was paid |
subscription.renewed | A renewal invoice was paid |
subscription.past_due | A period ended; data.latest_invoice.payment_url is the renewal checkout to send the customer |
subscription.canceled | Canceled now, or at the end of the period |
Each invoice payment also sends the normal payment IPN (data.ref_trx is your external_reference, plus data.subscription_id). Grant access only on a completed payment, and make fulfilment idempotent using the trx_id.
Authenticate using OAuth 2.0 client credentials flow to obtain a secure Bearer access token for Mobile Money API operations.
https://eripays.com/connect/token
| Header | Value | Required | Description |
|---|---|---|---|
Content-Type |
application/x-www-form-urlencoded | application/json |
Yes | Request body format |
Accept |
application/json |
Yes | Expected response format |
| Parameter | Type | Required | Description |
|---|---|---|---|
client_id |
string | Yes | Your unique Client ID or Merchant Key |
client_secret |
string | Yes | Your secret API Key / Secret |
grant_type |
string | Yes | Must be set to "client_credentials" |
curl --request POST \
--url "https://eripays.com/connect/token" \
--header "Content-Type: application/x-www-form-urlencoded" \
--header "Accept: application/json" \
--data "client_id=your_client_id" \
--data "client_secret=your_client_secret" \
--data "grant_type=client_credentials"
<?php
use Illuminate\Support\Facades\Http;
$response = Http::asForm()->post('https://eripays.com/connect/token', [
'client_id' => 'your_client_id',
'client_secret' => 'your_client_secret',
'grant_type' => 'client_credentials',
]);
$tokenData = $response->json();
$accessToken = $tokenData['access_token'];
const response = await fetch('https://eripays.com/connect/token', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'application/json'
},
body: new URLSearchParams({
client_id: 'your_client_id',
client_secret: 'your_client_secret',
grant_type: 'client_credentials'
})
});
const data = await response.json();
const accessToken = data.access_token;
{
"access_token": "a1b2c3d4e5f60718293a4b5c6d7e8f90...",
"expires_in": 3600,
"token_type": "Bearer",
"scope": "profile email"
}
Use the following designated phone numbers in Sandbox mode to simulate various network outcomes:
| Number Pattern | Outcome | Description | Example |
|---|---|---|---|
011177777(0-9) |
Success | Simulates immediate payment authorization and success | 0111777771 |
011177799(0-9) |
Failed | Simulates payer decline or insufficient funds | 0111777991 |
011177778(0-9) |
Pending | Simulates awaiting user PIN entry on mobile handset | 0111777781 |
011177779(0-9) |
SentToVendor | Simulates network provider queueing (e.g. MTN / Airtel) | 0111777791 |
Retrieve the current total and available balance of a specified payment gateway wallet.
https://eripays.com/api/wallet-balance/{walletId}
| Header | Value | Required | Description |
|---|---|---|---|
Authorization |
Bearer {access_token} |
Yes | OAuth 2.0 Bearer token from /connect/token |
Accept |
application/json |
Yes | Expected response format |
| Parameter | Type | Required | Description |
|---|---|---|---|
walletId |
string (UUID) | Yes | The unique UUID of the merchant wallet |
curl --request GET \
--url "https://eripays.com/api/wallet-balance/5e83b187-801e-410e-b76e-f491928547e0" \
--header "Authorization: Bearer your_access_token" \
--header "Accept: application/json"
{
"id": "5e83b187-801e-410e-b76e-f491928547e0",
"currency": "UGX",
"partnerId": "1",
"name": "UGX Wallet",
"actualBalance": 250000.00,
"availableBalance": 250000.00,
"collectionCallBackUrl": "https://yourdomain.com/webhooks/collection",
"disbursementCallBackUrl": "https://yourdomain.com/webhooks/disbursement"
}
Request a mobile money payment prompt on the payer’s mobile handset into your payment gateway wallet.
https://eripays.com/api/collections/collect
| Parameter | Type | Required | Description |
|---|---|---|---|
amount |
number | Yes | Amount to be collected from the payer |
payer |
string | Yes | Mobile money number of payer (e.g. 256770000001 or sandbox test number) |
currency |
string | No | Currency code (default: UGX) |
walletId |
string | No | Target wallet UUID. Defaults to active merchant wallet for the currency. |
externalId |
string | No | Your unique transaction tracking ID for reconciliation and duplicate prevention. |
payerNote |
string | No | Note shown to the payer on their device. |
payeeNote |
string | No | Note for internal merchant reference. |
curl --request POST \
--url "https://eripays.com/api/collections/collect" \
--header "Authorization: Bearer your_access_token" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data '{
"category": "MobileMoney",
"currency": "UGX",
"externalId": "ORDER-1002",
"payer": "0111777771",
"payerName": "Jane Doe",
"amount": 5000,
"payerNote": "Payment for Order #1002",
"payeeNote": "Invoice 1002"
}'
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"createdAt": "2026-09-19T17:30:00.000Z",
"category": "MobileMoney",
"status": "Success",
"paymentChannel": "MobileMoney",
"statusCode": "success",
"statusMessage": "The transaction is successful.",
"externalId": "ORDER-1002",
"walletId": "5e83b187-801e-410e-b76e-f491928547e0",
"partnerId": "1",
"amount": 5000,
"currency": "UGX",
"payer": "0111777771",
"payerName": "Jane Doe",
"payerNote": "Payment for Order #1002",
"payeeNote": "Invoice 1002",
"wallet": {
"id": "5e83b187-801e-410e-b76e-f491928547e0",
"text": "UGX Wallet"
},
"chargeModel": "Standard",
"transactionCharge": 0,
"vendorCharge": 0,
"totalTransactionCharge": 0,
"vendor": "MTN",
"vendorTransactionId": "TRX_ABC12345",
"lastUpdated": "2026-09-19T17:30:00.000Z",
"transactions": []
}
Check the real-time status of a mobile money collection using either the system request ID or your externalId.
https://eripays.com/api/collections/status/{requestId}
https://eripays.com/api/collections/external-id/{externalId}
# Check by Request ID
curl --request GET \
--url "https://eripays.com/api/collections/status/3fa85f64-5717-4562-b3fc-2c963f66afa6" \
--header "Authorization: Bearer your_access_token"
# Check by your External ID
curl --request GET \
--url "https://eripays.com/api/collections/external-id/ORDER-1002" \
--header "Authorization: Bearer your_access_token"
Withdraw funds from your wallet and disburse directly to a recipient’s mobile money phone number or bank account.
The recipient receives exactly the amount you send. Your wallet is debited that amount plus the EriPay payout fee, returned as fee in the response. Both are refunded if the payout fails.
https://eripays.com/api/disbursements/disburse
| Parameter | Type | Required | Description |
|---|---|---|---|
amount |
number | Yes | Amount to be disbursed to the recipient. Your wallet must also cover the payout fee. |
payee |
string | Yes | Recipient mobile money phone number |
currency |
string | No | Currency code (default: UGX) |
walletId |
string | No | Source wallet UUID |
externalId |
string | No | Your unique tracking reference. Prevents duplicate payouts if request is retried. |
payeeName |
string | No | Name of the recipient. |
curl --request POST \
--url "https://eripays.com/api/disbursements/disburse" \
--header "Authorization: Bearer your_access_token" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data '{
"category": "MobileMoney",
"currency": "UGX",
"externalId": "PAYOUT-5001",
"payee": "0111777771",
"payeeName": "Alex Vendor",
"amount": 2500,
"payerNote": "Commission Payout",
"payeeNote": "Payment for August sales"
}'
{
"id": "7ca85f64-5717-4562-b3fc-2c963f66afa7",
"createdAt": "2026-09-19T17:35:00.000Z",
"category": "MobileMoney",
"status": "Success",
"paymentChannel": "MobileMoney",
"statusCode": "success",
"statusMessage": "The transaction is successful.",
"externalId": "PAYOUT-5001",
"walletId": "5e83b187-801e-410e-b76e-f491928547e0",
"partnerId": "1",
"amount": 2500,
"fee": 500,
"currency": "UGX",
"payee": "0111777771",
"payeeName": "Alex Vendor",
"payeeUploadName": "Alex Vendor",
"payeeNameStatus": "Verified",
"approvalDecision": true,
"lastUpdated": "2026-09-19T17:35:00.000Z"
}
Check disbursement progress by transaction ID, externalId, or query paginated disbursement history.
https://eripays.com/api/disbursements/status/{transactionId}
https://eripays.com/api/disbursements/external-id/{externalId}
https://eripays.com/api/disbursements/paged-history?page=1&pageSize=20
https://eripays.com/api/disbursements/bank-list
EriPay sends real-time notifications to your specified IPN URL when payment status changes. This ensures you're immediately notified of payment completions, failures, and other status updates. Webhooks work identically in both sandbox and production environments.
Use the same webhook URL for both sandbox and production. EriPay will include environment context in webhook payloads to help you differentiate between test and live transactions.
| Header | Description | Example |
|---|---|---|
Content-Type |
Always application/json |
application/json |
X-Signature |
Raw HMAC-SHA256 signature for verification | a8b9c2d1e5f3... |
X-Environment |
Webhook environment context | sandbox | production |
All webhook payloads include environment information to help you differentiate between sandbox and production transactions:
sandbox for test transactions or production for live ones. Sandbox webhooks are signed with your sandbox API secret, live ones with your live API secret.
{
"event": "payment.completed",
"trx_id": "TXN7148PS8GPQKN",
"ref_trx": "ORDER_12345",
"amount": 200,
"fee": 5,
"net_amount": 195,
"currency": "USD",
"attempt": 1,
"data": {
"ref_trx": "ORDER_12345",
"description": "Order #1234",
"ipn_url": "https://webhook.site/5711b7d5-917a-4d94-bbb3-c28f4a37bea5",
"cancel_redirect": "https://merchant.com/cancel",
"success_redirect": "https://merchant.com/success",
"customer_name": "John Doe",
"customer_email": "john@example.com",
"merchant_name": "Xanthus Wiggins",
"amount": 200,
"currency_code": "USD",
"environment": "production",
"is_sandbox": false
},
"message": "Payment Completed",
"status": "completed",
"timestamp": 1705747245
}
Always verify webhook signatures to ensure authenticity and prevent unauthorized requests. Use your API secret (environment-specific) to verify signatures:
test_webhook_secret for sandbox and webhook_secret for production environments.
<?php
// Laravel Webhook Handler
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use App\Enums\EnvironmentMode;
class EriPayWebhookController extends Controller
{
public function handle(Request $request)
{
// Get webhook headers
$environment = $request->header('X-Environment', 'production');
$signature = $request->header('X-Signature');
// Get appropriate secret based on environment
$secret = $this->getSecretForEnvironment($environment);
// Verify signature
if (!$this->verifySignature($request->getContent(), $signature, $secret)) {
Log::warning('EriPay webhook signature verification failed', [
'environment' => $environment
]);
return response()->json(['error' => 'Invalid signature'], 401);
}
$payload = $request->json()->all();
// Handle based on environment
if ($environment === EnvironmentMode::SANDBOX->value) {
return $this->handleSandboxWebhook($payload);
} else {
return $this->handleProductionWebhook($payload);
}
}
private function getSecretForEnvironment(string $environment): string
{
// Return test secret for sandbox, live secret for production
return $environment === 'sandbox'
? config('eripay.test_webhook_secret')
: config('eripay.webhook_secret');
}
private function verifySignature(string $payload, string $signature, string $secret): bool
{
$expectedSignature = hash_hmac('sha256', $payload, $secret);
$providedSignature = str_starts_with($signature, 'sha256=') ? substr($signature, 7) : $signature;
return hash_equals($expectedSignature, $providedSignature);
}
private function handleSandboxWebhook(array $payload): JsonResponse
{
Log::info('Processing sandbox webhook', $payload);
// Your sandbox-specific logic here
// Don't fulfill orders, don't send emails to real customers, etc.
return response()->json(['status' => 'sandbox_processed']);
}
private function handleProductionWebhook(array $payload): JsonResponse
{
Log::info('Processing production webhook', $payload);
// Your production logic here
// Fulfill orders, send confirmation emails, etc.
return response()->json(['status' => 'processed']);
}
}
const crypto = require('crypto');
const express = require('express');
const EnvironmentMode = {
SANDBOX: 'sandbox',
PRODUCTION: 'production'
};
// Webhook handler
app.post('/api/webhooks/eripay', async (req, res) => {
const environment = req.headers['x-environment'] || 'production';
const signature = req.headers['x-signature'];
# Get appropriate secret based on environment
const secret = getSecretForEnvironment(environment);
# Verify signature
if (!verifySignature(JSON.stringify(req.body), signature, secret)) {
console.warn('EriPay webhook signature verification failed', {
environment: environment
});
return res.status(401).json({ error: 'Invalid signature' });
}
const payload = req.body;
try {
# Handle based on environment
if (environment === EnvironmentMode.SANDBOX) {
await handleSandboxWebhook(payload);
} else {
await handleProductionWebhook(payload);
}
res.json({ status: 'processed' });
} catch (error) {
console.error('Webhook processing error:', error);
res.status(500).json({ error: 'Processing failed' });
}
});
function getSecretForEnvironment(environment) {
# Return test secret for sandbox, live secret for production
return environment === 'sandbox'
? process.env.ERIPAY_TEST_WEBHOOK_SECRET
: process.env.ERIPAY_WEBHOOK_SECRET;
}
function verifySignature(payload, signature, secret) {
if (!signature) {
return false;
}
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
const providedSignature = signature.startsWith('sha256=') ? signature.slice(7) : signature;
return crypto.timingSafeEqual(
Buffer.from(expectedSignature),
Buffer.from(providedSignature)
);
}
async function handleSandboxWebhook(payload) {
console.log('Processing sandbox webhook:', payload);
# Your sandbox-specific logic here
# Don't fulfill orders, don't send emails to real customers, etc.
}
async function handleProductionWebhook(payload) {
console.log('Processing production webhook:', payload);
# Your production logic here
# Fulfill orders, send confirmation emails, etc.
}
import hmac
import hashlib
import json
import logging
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_http_methods
logger = logging.getLogger(__name__)
ENVIRONMENT_MODE = {
'SANDBOX': 'sandbox',
'PRODUCTION': 'production'
}
@csrf_exempt
@require_http_methods(["POST"])
def eripay_webhook(request):
environment = request.headers.get('X-Environment', 'production')
signature = request.headers.get('X-Signature', '')
# Get appropriate secret based on environment
secret = get_secret_for_environment(environment)
# Verify signature
if not verify_signature(request.body, signature, secret):
logger.warning('EriPay webhook signature verification failed', extra={
'environment': environment
})
return JsonResponse({'error': 'Invalid signature'}, status=401)
try:
payload = json.loads(request.body)
# Handle based on environment
if environment == ENVIRONMENT_MODE['SANDBOX']:
handle_sandbox_webhook(payload)
else:
handle_production_webhook(payload)
return JsonResponse({'status': 'processed'})
except Exception as e:
logger.error(f'Webhook processing error:{str(e)}')
return JsonResponse({'error': 'Processing failed'}, status=500)
def get_secret_for_environment(environment):
from django.conf import settings
# Return test secret for sandbox, live secret for production
return (settings.ERIPAY_TEST_WEBHOOK_SECRET
if environment == 'sandbox'
else settings.ERIPAY_WEBHOOK_SECRET)
def verify_signature(payload, signature, secret):
if not signature:
return False
expected_signature = hmac.new(
secret.encode('utf-8'),
payload,
hashlib.sha256
).hexdigest()
provided_signature = signature[7:] if signature.startswith('sha256=') else signature
return hmac.compare_digest(expected_signature, provided_signature)
def handle_sandbox_webhook(payload):
logger.info('Processing sandbox webhook', extra=payload)
# Your sandbox-specific logic here
# Don't fulfill orders, don't send emails to real customers, etc.
def handle_production_webhook(payload):
logger.info('Processing production webhook', extra=payload)
# Your production logic here
# Fulfill orders, send confirmation emails, etc.
Production-oriented integration examples for popular platforms and frameworks. Keep gateway selection in Merchant API Config, then sign each API request from your server.
<?php
// Laravel Integration Service
namespace App\Services;
use Illuminate\Support\Facades\Http;
use Exception;
class EriPayService
{
private string $baseUrl;
private string $merchantKey;
private string $apiKey;
private string $environment;
public function __construct()
{
$this->baseUrl = config('eripay.base_url');
$this->merchantKey = config('eripay.merchant_key');
$this->apiKey = config('eripay.api_key');
$this->environment = config('eripay.environment'); // 'sandbox' or 'production'
}
public function initiatePayment(array $paymentData): array
{
try {
$response = Http::withHeaders([
'Content-Type' => 'application/json',
'X-Environment' => $this->environment,
'X-Merchant-Key' => $this->merchantKey,
'X-API-Key' => $this->apiKey,
])->post("{$this->baseUrl}/api/v1/initiate-payment", $paymentData);
if ($response->successful()) {
return $response->json();
}
throw new Exception('EriPay API Error: Payment initiation failed');
} catch (Exception $e) {
throw new Exception('EriPay API Error: ' . $e->getMessage());
}
}
public function verifyPayment(string $transactionId): array
{
try {
$response = Http::withHeaders([
'Accept' => 'application/json',
'X-Environment' => $this->environment,
'X-Merchant-Key' => $this->merchantKey,
'X-API-Key' => $this->apiKey,
])->get("{$this->baseUrl}/api/v1/verify-payment/{$transactionId}");
if ($response->successful()) {
return $response->json();
}
throw new Exception('EriPay API Error: Payment verification failed');
} catch (Exception $e) {
throw new Exception('EriPay API Error: ' . $e->getMessage());
}
}
}
// Configuration (config/eripay.php)
return [
'base_url' => env('ERIPAY_BASE_URL', 'https://eripays.com'),
'environment' => env('ERIPAY_ENVIRONMENT', 'sandbox'), // sandbox or production
'merchant_key' => env('ERIPAY_MERCHANT_KEY'), // Use appropriate prefix
'api_key' => env('ERIPAY_API_KEY'), // Use appropriate prefix
];
// Usage in Controller
class PaymentController extends Controller
{
public function initiatePayment(Request $request, EriPayService $eripay)
{
$paymentData = [
'payment_amount' => $request->amount,
'currency_code' => 'USD',
'ref_trx' => 'ORDER_' . time(),
'description' => $request->description,
'success_redirect' => route('payment.success'),
'cancel_redirect' => route('payment.cancelled'),
'ipn_url' => route('webhooks.eripay'),
'allow_payment_methods' => ['stripe', 'paypal'],
];
try {
$result = $eripay->initiatePayment($paymentData);
return redirect($result['payment_url']);
} catch (Exception $e) {
return back()->withErrors(['error' => $e->getMessage()]);
}
}
}
// Node.js Integration Service
const axios = require('axios');
class EriPayService {
constructor() {
this.baseUrl = process.env.ERIPAY_BASE_URL || 'https://eripays.com';
this.environment = process.env.ERIPAY_ENVIRONMENT || 'sandbox'; // sandbox or production
this.merchantKey = process.env.ERIPAY_MERCHANT_KEY; // Use appropriate prefix
this.apiKey = process.env.ERIPAY_API_KEY; // Use appropriate prefix
}
async initiatePayment(paymentData) {
try {
const response = await axios.post(`${this.baseUrl}/api/v1/initiate-payment`, paymentData, {
headers: {
'Content-Type': 'application/json',
'X-Environment': this.environment,
'X-Merchant-Key': this.merchantKey,
'X-API-Key': this.apiKey
}
});
return response.data;
} catch (error) {
throw new Error(`EriPay API Error: ${error.message}`);
}
}
async verifyPayment(transactionId) {
try {
const response = await axios.get(`${this.baseUrl}/api/v1/verify-payment/${transactionId}`, {
headers: {
'Accept': 'application/json',
'X-Environment': this.environment,
'X-Merchant-Key': this.merchantKey,
'X-API-Key': this.apiKey
}
});
return response.data;
} catch (error) {
throw new Error(`EriPay API Error: ${error.message}`);
}
}
}
// Express.js Route Example
const express = require('express');
const app = express();
const eripay = new EriPayService();
app.post('/initiate-payment', async (req, res) => {
const paymentData = {
payment_amount: req.body.amount,
currency_code: 'USD',
ref_trx: `ORDER_${Date.now()}`,
description: req.body.description,
success_redirect: `${req.protocol}://${req.get('host')}/payment/success`,
cancel_redirect: `${req.protocol}://${req.get('host')}/payment/cancelled`,
ipn_url: `${req.protocol}://${req.get('host')}/webhooks/eripay`,
allow_payment_methods: ['stripe', 'paypal'],
};
try {
const result = await eripay.initiatePayment(paymentData);
res.redirect(result.payment_url);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
module.exports = EriPayService;
# Python/Django Integration Service
import os
import requests
from django.conf import settings
class EriPayService:
def __init__(self):
self.base_url = getattr(settings, 'ERIPAY_BASE_URL', 'https://eripays.com')
self.environment = getattr(settings, 'ERIPAY_ENVIRONMENT', 'sandbox') # sandbox or production
self.merchant_key = getattr(settings, 'ERIPAY_MERCHANT_KEY') # Use appropriate prefix
self.api_key = getattr(settings, 'ERIPAY_API_KEY') # Use appropriate prefix
def initiate_payment(self, payment_data):
try:
headers = {
'Content-Type': 'application/json',
'X-Environment': self.environment,
'X-Merchant-Key': self.merchant_key,
'X-API-Key': self.api_key
}
response = requests.post(
f"{self.base_url}/api/v1/initiate-payment",
headers=headers,
json=payment_data,
timeout=30
)
response.raise_for_status()
return response.json()
except requests.RequestException as e:
raise Exception(f'EriPay API Error: {str(e)}')
def verify_payment(self, transaction_id):
try:
headers = {
'Accept': 'application/json',
'X-Environment': self.environment,
'X-Merchant-Key': self.merchant_key,
'X-API-Key': self.api_key
}
response = requests.get(
f"{self.base_url}/api/v1/verify-payment/{transaction_id}",
headers=headers,
timeout=30
)
response.raise_for_status()
return response.json()
except requests.RequestException as e:
raise Exception(f'EriPay API Error: {str(e)}')
# Django Settings Configuration
ERIPAY_BASE_URL = 'https://eripays.com'
ERIPAY_ENVIRONMENT = 'sandbox' # Change to 'production' for live
ERIPAY_MERCHANT_KEY = os.environ.get('ERIPAY_MERCHANT_KEY') # Use appropriate prefix
ERIPAY_API_KEY = os.environ.get('ERIPAY_API_KEY') # Use appropriate prefix
# Django View Example
from django.shortcuts import redirect
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
import json
eripay = EriPayService()
@csrf_exempt
def initiate_payment(request):
if request.method == 'POST':
data = json.loads(request.body)
payment_data = {
'payment_amount': data['amount'],
'currency_code': 'USD',
'ref_trx': f'ORDER_{int(time.time())}',
'description': data['description'],
'success_redirect': request.build_absolute_uri('/payment/success/'),
'cancel_redirect': request.build_absolute_uri('/payment/cancelled/'),
'ipn_url': request.build_absolute_uri('/webhooks/eripay/'),
'allow_payment_methods': ['stripe', 'paypal'],
}
try:
result = eripay.initiate_payment(payment_data)
return redirect(result['payment_url'])
except Exception as e:
return JsonResponse({'error': str(e)}, status=500)
# Environment Variables Setup
export ERIPAY_ENVIRONMENT="sandbox" # or "production"
export ERIPAY_MERCHANT_KEY="test_merchant_your_key" # or "merchant_your_key" for production
export ERIPAY_API_KEY="test_your_api_key" # or "your_api_key" for production
# Initiate Payment
curl -X POST "https://eripays.com/api/v1/initiate-payment" \
-H "Content-Type: application/json" \
-H "X-Environment: $ERIPAY_ENVIRONMENT" \
-H "X-Merchant-Key: $ERIPAY_MERCHANT_KEY" \
-H "X-API-Key: $ERIPAY_API_KEY" \
-d '{
"payment_amount": 250.00,
"currency_code": "USD",
"ref_trx": "ORDER_12345",
"description": "Premium Subscription",
"success_redirect": "https://yoursite.com/payment/success",
"cancel_redirect": "https://yoursite.com/payment/cancelled",
"ipn_url": "https://yoursite.com/api/webhooks/eripay",
"allow_payment_methods": ["stripe", "paypal"]
}'
# Verify Payment
curl -X GET "https://eripays.com/api/v1/verify-payment/TXNQ5V8K2L9N3XM1" \
-H "Accept: application/json" \
-H "X-Environment: $ERIPAY_ENVIRONMENT" \
-H "X-Merchant-Key: $ERIPAY_MERCHANT_KEY" \
-H "X-API-Key: $ERIPAY_API_KEY"
# Environment-specific credential examples:
# Sandbox: test_merchant_xxxxx, test_api_key_xxxxx
# Production: merchant_xxxxx, api_key_xxxxx
Advanced EriPay payment gateway with modern WooCommerce Blocks support, dynamic branding, and enterprise-grade security features.
Production-ready payment gateway with WooCommerce Blocks (Gutenberg) support, dynamic branding, and secure webhook processing.
Enterprise-grade WooCommerce payment gateway with modern Blocks support and dynamic branding.
Enterprise-grade payment processing with modern architecture
Full Gutenberg checkout compatibility with React-based UI
Auto-fetch logo, colors, and branding from EriPay API
HMAC-SHA256 signature verification for payment callbacks
Space-efficient, responsive design for all devices
Multi-header authentication with environment isolation
Seamless sandbox testing with production deployment
Get started with EriPay WooCommerce integration in minutes
Download EriPay WooCommerce Gateway v2.8.0 from the download section above. This includes all latest features and security updates.
Navigate to Plugins → Add New → Upload Plugin and select the downloaded ZIP file. The plugin will auto-extract and install.
Activate the plugin and go to WooCommerce → Settings → Payments → EriPay. Enter your API credentials and webhook secret.
Enable Test Mode, process a sandbox transaction to verify Blocks checkout, webhook delivery, and order completion.
Disable test mode, ensure production API keys are configured, and start accepting real payments with full webhook processing.
Essential API settings for secure payment processing
https://eripays.com
Your unique merchant credentials from EriPay dashboard
RequiredHMAC-SHA256 signature verification for secure callbacks
RecommendedRequired headers for all EriPay API requests:
X-Environment: sandbox|production
X-Merchant-Key: your_merchant_id
X-API-Key: your_api_key
Content-Type: application/json
Real-time payment status updates and order processing
https://yoursite.com/wc-api/eripay_webhook
Configure this URL in your EriPay merchant dashboard for automatic order updates.
Modern Gutenberg checkout with React-based payment UI
Compact, mobile-optimized payment interface that adapts to any screen size.
Automatically fetches and displays your EriPay branding and logos.
Clear SSL and security badges to build customer trust during checkout.
Clear sandbox indicators for testing without affecting live transactions.
Ensure everything is configured correctly before going live
Common issues and solutions for EriPay WooCommerce integration
Solutions:
Solutions:
Solutions:
Use this checklist before moving from test payments to live checkout. The same API routes work in both modes; only the environment header and credential set change.
Use test credentials and X-Environment: sandbox. Transactions are marked as sandbox and do not represent real money movement.
Use live credentials and X-Environment: production only after admin approval, wallet readiness, and gateway configuration are complete.
Test EriPay API endpoints directly from this documentation. Use the demo credentials below for sandbox testing.
Use these demo credentials to test all payment methods in sandbox environment:
123456789
Wallet PIN:
123456
TESTVOUCHER
Auto Success
X-ENVIRONMENT: sandbox in your API requestssandbox for testing and production for live transactions. Only sandbox credentials use test_ prefix, production credentials have no prefix.
Base URL: https://eripays.com
Environment Header: X-Environment: sandbox
Credentials: Use test_ prefixed keys
Purpose: Safe testing without real money
Base URL: https://eripays.com
Environment Header: X-Environment: production
Credentials: No prefix for production keys
Purpose: Live transactions with real money
EriPay API uses conventional HTTP response codes to indicate the success or failure of API requests.
| Code | Status | Description |
|---|---|---|
| 200 | OK | Request succeeded |
| 400 | Bad Request | Invalid request parameters |
| 401 | Unauthorized | Invalid or missing API credentials |
| 403 | Forbidden | Insufficient permissions |
| 404 | Not Found | Resource not found |
| 429 | Too Many Requests | Rate limit exceeded |
| 500 | Internal Server Error | Server error occurred |
| Error Code | Description | Solution |
|---|---|---|
INVALID_CREDENTIALS |
Invalid API credentials provided | Check your Merchant ID and API Key |
INSUFFICIENT_FUNDS |
Customer has insufficient funds | Customer needs to add funds to their wallet |
PAYMENT_DECLINED |
Payment was declined by payment processor | Customer should try a different payment method |
INVALID_AMOUNT |
Payment amount is invalid | Check minimum and maximum amount limits |
INVALID_CURRENCY |
Unsupported currency code | Use a supported currency code (USD, EUR, etc.) |
DUPLICATE_REFERENCE |
Transaction reference already exists | Use a unique transaction reference |
EXPIRED_SESSION |
Payment session has expired | Create a new payment request |
MERCHANT_SUSPENDED |
Merchant account is suspended | Contact EriPay support |
{
"success": false,
"message": "Validation failed",
"error_code": "INVALID_AMOUNT",
"errors": {
"payment_amount": [
"The payment amount must be at least 1.00"
]
},
"timestamp": "2024-01-20T10:30:00Z"
}
Need assistance with EriPay API integration? Our technical team provides comprehensive support.