Back to blog Tutorial

Integrate the ElyonPay API with JavaScript (Node.js)

ElyonPay Team ยท April 15, 2026 ยท 8 min read

This technical guide walks you through integrating the ElyonPay payment API with JavaScript (Node.js) step by step. From JWT authentication to transaction verification, learn how to create payment links and accept Mobile Money payments across 14 African countries.

1Why Use the ElyonPay API

The ElyonPay API allows developers to integrate Mobile Money and card payments into their web or mobile applications. The API uses a payment link model: you create a link server-side, then redirect the customer to that link so they can complete payment on a secure ElyonPay page.

This model offers several advantages: PCI DSS compliance is handled by ElyonPay, you don't need to handle sensitive customer data, and the payment experience is optimized for each Mobile Money operator (MTN MoMo, Orange Money, Wave, Moov Africa, Airtel Money) as well as Visa and Mastercard card payments with 3D Secure.

The API is RESTful and available in a sandbox environment for testing. It supports payments in 14 African countries and the currencies XAF, XOF, EUR, USD, GBP, NGN, KES, and CDF. If you're specifically targeting the Cameroonian market, check our complete guide to payment gateways in Cameroon to compare the different solutions available.

2Prerequisites and Environments

Before getting started, you'll need an ElyonPay merchant account with API login credentials (username and password provided during registration). The ElyonPay API uses two separate environments with different base URLs:

EnvironmentBase URLDescription
Sandboxhttps://api.elyonpay.net/apiTest transactions, no real debits
Productionhttps://api.elyonpay.org/apiLive transactions

All requests must use HTTPS โ€” unsecured HTTP requests are rejected. For this tutorial, we'll use Node.js with the native fetch module (Node.js 18+) or the axios library. No proprietary SDK is required to interact with the API.

bash
# Optional: install axios if you're not using native fetch
npm install axios

Create a .env file to store your credentials securely. Never commit this file to your code repository.

env
ELYONPAY_API_URL=https://api.elyonpay.net/api
ELYONPAY_USERNAME=your_username
ELYONPAY_PASSWORD=your_password

3JWT Authentication

The ElyonPay API uses JWT (JSON Web Token) authentication. You must first obtain a token by calling the login endpoint with your merchant credentials, then include that token in the Authorization header of all subsequent requests.

js
const API_URL = process.env.ELYONPAY_API_URL;

async function getToken() {
    const response = await fetch(`${API_URL}/login`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
            username: process.env.ELYONPAY_USERNAME,
            password: process.env.ELYONPAY_PASSWORD,
            role: 'ROLE_MERCHANT_ADMIN'
        })
    });

    if (!response.ok) {
        throw new Error(`Login failed: ${response.status}`);
    }

    const data = await response.json();
    return data.token;
}

The JWT token has a limited lifespan. In production, implement an automatic renewal mechanism: store the token in memory and regenerate it before it expires. The ROLE_MERCHANT_ADMIN role grants access to all payment operations.

Security: always store your credentials in environment variables. In production, use your hosting platform's secrets (AWS Secrets Manager, Vercel Environment Variables, etc.). Never log the JWT token in your application logs.

4Create a Payment Link

The core API operation is creating a payment link via the POST /api/request-to-pay/payment/link endpoint. You send the amount, customer phone number, language, and redirect URLs. The API returns a payment URL to which you redirect the customer.

js
async function createPaymentLink(token, orderData) {
    const response = await fetch(`${API_URL}/request-to-pay/payment/link`, {
        method: 'POST',
        headers: {
            'Authorization': `Bearer ${token}`,
            'Content-Type': 'application/json',
            'Idempotency-Key': orderData.orderId // prevents duplicates
        },
        body: JSON.stringify({
            amount: orderData.amount,
            user_lang: 'en',
            msisdn: orderData.phone,
            success_url: 'https://yoursite.com/payment-success',
            error_url: 'https://yoursite.com/payment-failed'
        })
    });

    if (!response.ok) {
        const error = await response.json();
        throw new Error(`Payment link creation failed: ${error.message}`);
    }

    const data = await response.json();
    return data.data.payment_url;
}

// Usage
const token = await getToken();
const paymentUrl = await createPaymentLink(token, {
    amount: 5000,
    phone: '+237691234567',
    orderId: 'ORD-2026-001'
});

console.log('Redirect customer to:', paymentUrl);

The Idempotency-Key header is strongly recommended: it ensures the same request won't be processed twice in case of a network issue. Use a unique identifier per order (your order reference, for example).

The user_lang parameter accepts fr or en and determines the language of the payment page shown to the customer. The msisdn field is the customer's phone number in international format. The success_url and error_url are the pages the customer will be redirected to after payment.

5Redirect the Customer and Verify the Transaction

Once you have the payment link, redirect the customer to that URL. They complete payment on the secure ElyonPay page, then get redirected to your success_url or error_url. The ElyonPay API uses a "pull" model: it's your responsibility to verify the transaction status server-side, rather than waiting for a webhook.

js
async function getTransaction(token, transactionId) {
    const response = await fetch(`${API_URL}/transactions/${transactionId}`, {
        method: 'GET',
        headers: {
            'Authorization': `Bearer ${token}`,
            'Accept': 'application/json'
        }
    });

    if (!response.ok) {
        throw new Error(`Transaction fetch failed: ${response.status}`);
    }

    return await response.json();
}

// Verify status after customer redirect
const transaction = await getTransaction(token, transactionId);
console.log('Status:', transaction.data.state);
// Possible statuses: CREATED, PENDING, WAITING_FOR_PAYMENT,
//                    ACCEPTED, DELIVERED, REJECTED, DECLINED, CANCELLED

Statuses follow a precise lifecycle: CREATED โ†’ PENDING โ†’ WAITING_FOR_PAYMENT โ†’ ACCEPTED โ†’ DELIVERED. Alternative statuses are REJECTED, DECLINED, and CANCELLED. Only consider a payment successful at the DELIVERED status.

Important: never rely solely on the redirect URL (success/error) to validate a payment. A customer could manually access your success_url. Always verify the transaction status server-side via the GET /api/transactions/{id} endpoint before fulfilling the order.

You can also list all your transactions with pagination via GET /api/transactions for accounting reconciliation or display in your dashboard.

6Handle Errors

The API returns errors in JSON format with machine-readable codes and standard HTTP status codes. Implement robust error handling to provide a good user experience.

js
async function safeApiCall(url, options) {
    try {
        const response = await fetch(url, options);

        if (!response.ok) {
            const error = await response.json();

            switch (error.code) {
                case 'INSUFFICIENT_FUNDS':
                    throw new Error('Insufficient balance on customer account');
                case 'PHONE_INVALID':
                    throw new Error('Invalid phone number');
                case 'AMOUNT_TOO_LOW':
                    throw new Error('Amount below the allowed minimum');
                case 'TOKEN_EXPIRED':
                    // Renew token and retry
                    return await retryWithNewToken(url, options);
                default:
                    throw new Error(`API error: ${error.message}`);
            }
        }

        return await response.json();
    } catch (err) {
        if (err.name === 'TypeError') {
            // Network error (no connection)
            throw new Error('Unable to reach ElyonPay server');
        }
        throw err;
    }
}

The most common errors are INSUFFICIENT_FUNDS (insufficient balance), PHONE_INVALID (incorrect or unregistered number), and TOKEN_EXPIRED (expired JWT token). For the latter, implement automatic token renewal and retry the request.

Always adapt error messages for the end user. A clear message โ€” "Your Mobile Money balance is insufficient, please top up your account" โ€” is more useful than a raw technical code.

7Go to Production

Once your integration is tested in sandbox, going to production means changing the API base URL from https://api.elyonpay.net/api (sandbox) to https://api.elyonpay.org/api (production) and using your production credentials.

js
// Production
const API_URL = 'https://api.elyonpay.org/api';

// Run a first test transaction with a small amount
const token = await getToken();
const testUrl = await createPaymentLink(token, {
    amount: 100,  // minimum amount for testing
    phone: '+237691234567',
    orderId: 'TEST-PROD-001'
});
console.log('Production test:', testUrl);

Production checklist: base URL changed to api.elyonpay.org, production credentials configured as environment variables, HTTPS on your server, server-side transaction status verification implemented, error handling in place, first test transaction successful with a small amount.

The ElyonPay sandbox provides test phone numbers with simulated behaviors (success, insufficient funds, timeout) and test card numbers for various scenarios. Use them to thoroughly test your integration before going live.

Conclusion

By following this guide, you have integrated the ElyonPay API in JavaScript from end to end: JWT authentication, payment link creation, customer redirect, and transaction status verification. Your application is now ready to accept Mobile Money and card payments across 14 African countries. Check the full ElyonPay API documentation for more details on available endpoints and advanced options.

Share this article

Get started with ElyonPay

Accept Mobile Money and card payments in minutes.

Create your free account
API