ElyonPay Logo

    ElyonPay API Documentation

    Welcome to the ElyonPay API technical documentation. This reference allows you to integrate Mobile Money payments, Visa, Mastercard and transfers into your application in just a few lines of code.

    Base URLs: https://api.elyonpay.net/api (Sandbox) / https://api.elyonpay.org/api (Production)
    All requests must be sent over HTTPS. Unsecured HTTP requests are rejected. See the Environments section for details.

    Key Features

    • Unified Mobile MoneyMTN MoMo, Orange Money, Wave, Moov, Airtel Money
    • Bank CardsVisa, Mastercard with 3D Secure, PCI DSS level 1 compliant
    • Simple IntegrationPayment link + iframe, active status verification
    • Full SandboxTest for free with simulated data
    • Multi-currencyXAF, XOF, EUR, USD, GBP, NGN, CDF, KES
    • Official SDKsJavaScript, PHP, Python, Java, React Native, Flutter

    Quick Start

    Follow these 3 steps to make your first payment:

    1. Contact us to get your API key
    2. Install the SDK for your language or use cURL directly
    3. Call POST /api/request-to-pay/payment/link with the amount and redirect URLs
    bash
    curl -X POST https://api.elyonpay.org/api/request-to-pay/payment/link \
      -H "Authorization: Bearer <your_jwt_token>" \
      -H "Content-Type: application/json" \
      -H "language: fr" \
      -d '{
        "amount": 15000,
        "user_lang": "fr",
        "msisdn": "+237600000000",
        "success": "https://yoursite.com/success",
        "error": "https://yoursite.com/error"
      }'

    Authentication

    The ElyonPay API uses JWT (JSON Web Token) authentication. Obtain your token via the login endpoint, then include it in every request.

    POST/api/login
    ParameterTypeRequiredDescription
    usernamestringRequiredMerchant account email
    passwordstringRequiredAccount password
    rolestringRequiredROLE_MERCHANT_ADMIN
    bash
    curl -X POST https://api.elyonpay.org/api/login \
      -H "Content-Type: application/json" \
      -d '{
        "username": "you@example.com",
        "password": "***",
        "role": "ROLE_MERCHANT_ADMIN"
      }'

    Response

    json
    {
      "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9...."
    }

    Usage in HTTP Header

    bash
    Authorization: Bearer <your_jwt_token>
    Security: Never expose your JWT token on the client side (browser JavaScript). Always make calls from your backend server. The token expires after a configurable delay — remember to renew it.

    Environments

    ElyonPay offers two distinct environments to allow you to develop and test safely before going to production.

    Base URLs

    EnvironmentBase URLDescription
    Sandboxhttps://api.elyonpay.net/apiNo real charges — simulated data
    Productionhttps://api.elyonpay.org/apiReal transactions
    Use the Sandbox environment for development and testing. Switch to the production URL only when you are ready to process real payments.

    Mobile Money Test Numbers

    NumberNetworkSimulated Behavior
    +237600000001MTN MoMoSuccessful payment
    +237600000002MTN MoMoInsufficient balance
    +237690000001Orange MoneySuccessful payment
    +237690000002Orange MoneySimulated timeout
    +221700000001WaveSuccessful payment

    Request Format

    All requests and responses use JSON format. The Content-Type: application/json header is required for requests with a body.

    Required Headers

    HeaderValueRequired
    AuthorizationBearer {votre_token_jwt}Required
    Content-Typeapplication/jsonRequired (POST)
    Acceptapplication/jsonOptional
    Idempotency-KeyUUID uniqueRecommended

    Standard Response Format

    json
    {
      "success": true,
      "data": {
        "id": "pay_1A2B3C4D5E6F",
        "status": "pending",
        "amount": 15000,
        "currency": "XAF"
      },
      "meta": {
        "request_id": "req_xxxxxxx",
        "timestamp": "2024-03-24T10:15:00Z"
      }
    }

    Create a Payment

    Generates a secure payment link. The customer is redirected to this link to choose their payment method (Mobile Money, bank card) and complete the transaction.

    POST/api/request-to-pay/payment/link

    Body Parameters

    ParameterTypeRequiredDescription
    amountnumberRequiredPayment amount
    user_langstringRequiredPayment interface language (fr, en)
    msisdnstringRequiredPhone number in international format: +237600000000
    successstringRequiredRedirect URL on success
    errorstringRequiredRedirect URL on error

    Response

    json
    {
      "url": "https://app.elyonpay.org/t/CI032667e43abf11?success=https://www.success.com&error=https://www.error.com"
    }

    Code Examples

    cURL

    bash
    curl -X POST https://api.elyonpay.org/api/request-to-pay/payment/link \
      -H "Authorization: Bearer <your_jwt_token>" \
      -H "Content-Type: application/json" \
      -H "language: fr" \
      -d '{
        "amount": 15000,
        "user_lang": "fr",
        "msisdn": "+237600000001",
        "success": "https://yoursite.com/success",
        "error": "https://yoursite.com/error"
      }'

    Node.js / JavaScript

    javascript
    const response = await fetch('https://api.elyonpay.org/api/request-to-pay/payment/link', {
      method: 'POST',
      headers: {
        'Authorization': 'Bearer ' + token,
        'Content-Type': 'application/json',
        'language': 'fr'
      },
      body: JSON.stringify({
        amount: 15000,
        user_lang: 'fr',
        msisdn: '+237600000001',
        success: 'https://yoursite.com/success',
        error: 'https://yoursite.com/error'
      })
    });
    
    const data = await response.json();
    console.log(data.url); // Payment link to redirect the customer

    PHP

    php
    $ch = curl_init('https://api.elyonpay.org/api/request-to-pay/payment/link');
    curl_setopt_array($ch, [
      CURLOPT_POST => true,
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . $token,
        'Content-Type: application/json',
        'language: fr'
      ],
      CURLOPT_POSTFIELDS => json_encode([
        'amount'    => 15000,
        'user_lang' => 'fr',
        'msisdn'    => '+237600000001',
        'success'   => 'https://yoursite.com/success',
        'error'     => 'https://yoursite.com/error'
      ])
    ]);
    
    $response = json_decode(curl_exec($ch), true);
    echo $response['url']; // Payment link

    Transactions

    Retrieve the complete history of your transactions: received payments, refunds, fees.

    GET/api/transactions

    Returns a paginated list of all your transactions. You can also retrieve details of a specific transaction via its identifier.

    Transaction Detail

    GET/api/transactions/{id}
    bash
    curl -X GET https://api.elyonpay.org/api/transactions/1553 \
      -H "Authorization: Bearer <your_jwt_token>" \
      -H "Accept: application/json"

    Response Example

    json
    {
      "id": 1553,
      "PSPid": "FR033169cbd9c1f1",
      "uuid": "FR033169cbd9c1f1",
      "creation_date": "2026-03-31T14:27:13+00:00",
      "validation_date": null,
      "delivery_date": null,
      "amount": 100,
      "totalCustomer": 100,
      "state": "CREATED",
      "ticket_type": "SMS_EMAIL",
      "operation_code": "03",
      "payer_phone_number": "+33782112127",
      "beneficiary_phone_number": "+33782112127",
      "payer_currency": "EUR",
      "beneficiary_currency": "EUR",
      "payer_country": "FR",
      "beneficiary_country": "FR",
      "payment": {
        "name": "MOLLIE"
      },
      "customer": {
        "phoneNumber": "+33782112127",
        "email": "client@example.com"
      },
      "merchant": {
        "id": 258,
        "name": "Ma Boutique",
        "city": "Paris",
        "address": "10 Rue de la Paix",
        "zipCode": "75002",
        "type": "individual",
        "country_code": "FR",
        "country": "France"
      },
      "transactionStates": [
        {
          "state": "CREATED",
          "date": "2026-03-31T14:27:14+00:00"
        }
      ],
      "commission_operateur": 0,
      "commission_marchand": 0,
      "commission_pays": 0,
      "commission_customer": 0,
      "deliveryPrice": 0
    }

    Response Fields

    FieldTypeDescription
    idintegerInternal transaction identifier
    PSPidstringUnique ElyonPay identifier (e.g. FR033169cbd9c1f1)
    uuidstringUnique identifier — same value as PSPid
    creation_datedatetimeCreation date (ISO 8601 with timezone)
    validation_datedatetime|nullPayment validation date — null if not yet validated
    delivery_datedatetime|nullDelivery date — null if not applicable
    amountnumberTransaction amount in the beneficiary's currency
    totalCustomernumberTotal amount charged to the customer (fees included)
    statestringCurrent status: CREATED, PENDING, WAITING_FOR_PAYMENT, ACCEPTED, DELIVERED, REJECTED, DECLINED, CANCELLED
    ticket_typestringNotification type: SMS_EMAIL, SMS, EMAIL
    operation_codestringInternal operation code
    payer_phone_numberstringPayer's phone number (international format)
    beneficiary_phone_numberstringBeneficiary's phone number
    payer_currencystringPayer's currency (ISO 4217 code: EUR, XAF, XOF...)
    beneficiary_currencystringBeneficiary's currency
    payer_countrystringPayer's country code (ISO 3166: FR, CM, CI...)
    beneficiary_countrystringBeneficiary's country code
    payment.namestringPayment provider used (MOLLIE, MTN, ORANGE...)

    customer Object

    FieldTypeDescription
    phoneNumberstringCustomer's phone number
    emailstringCustomer's email address

    merchant Object

    FieldTypeDescription
    idintegerMerchant identifier
    namestringMerchant or business name
    citystringMerchant's city
    addressstringPostal address
    zipCodestringZip code
    typestringAccount type: individual, company
    country_codestringISO 3166 country code (FR, CM, CI...)
    countrystringCountry name

    transactionStates Array

    History of transaction status changes, from oldest to newest.

    FieldTypeDescription
    statestringStatus at that point (CREATED, PENDING, WAITING_FOR_PAYMENT, ACCEPTED, DELIVERED...)
    datedatetimeStatus change date

    Fees

    FieldTypeDescription
    commission_operateurnumberTelecom operator commission
    commission_marchandnumberMerchant commission
    commission_paysnumberCountry commission
    commission_customernumberCommission applied to the customer
    deliveryPricenumberDelivery fees

    Custom Checkout

    Custom Checkout lets you build your own payment UI while using ElyonPay APIs directly. Unlike the simple payment link (redirect), you keep full control over the user experience.

    When to use Custom Checkout? Use this approach if you need a custom UI or full control over the payment flow. For a simple fixed-amount payment, the payment link (Create Payment section) is faster to integrate.

    4-Step Flow

    1

    Fetch payment methods

    Call GET /api/public/configuration/payments/{countryCode} to get available methods in the customer's country.

    2

    Display your checkout

    Show the order summary and payment methods in your own UI. The customer picks how to pay.

    3

    Initiate payment

    Send the direct payment request (Mobile Money, Stripe or bank card) with the chosen method.

    4

    Poll for status

    Query GET /api/transactions/{id} every 3–5 seconds until you get a terminal state (DELIVERED, FAILED, CANCELLED).

    Sequence Diagram

    sequenceDiagram
      participant Customer
      participant Merchant
      participant ElyonPay
    
      Customer->>Merchant: Browses products
      Merchant->>ElyonPay: GET /api/public/configuration/payments/{country}
      ElyonPay-->>Merchant: Available payment methods
      Customer->>Merchant: Selects payment method
      Merchant->>ElyonPay: POST /api/mobile-money/payment/request
      ElyonPay-->>Merchant: PaymentResult (transactionId, state)
      loop Poll every 3-5s (max 2 min)
        Merchant->>ElyonPay: GET /api/transactions/{id}
        ElyonPay-->>Merchant: Transaction state
      end
      Merchant->>Customer: Displays confirmation or error
          

    Payment Methods

    Dynamically retrieve the list of available payment methods in a given country. This endpoint is public — no authentication is required.

    GET/api/public/configuration/payments/{countryCode}

    Path Parameter

    ParameterTypeRequiredDescription
    countryCodestringRequiredISO 3166 country code (e.g. CM, CI, FR, SN)
    Public endpoint: This endpoint requires no authentication. You can call it directly from the frontend to dynamically adapt your payment UI.

    Response Example

    json
    {
      "payments": [
        {
          "name": "ORANGE_MONEY",
          "label": "Orange Money",
          "type": "MOBILE_MONEY",
          "available": true
        },
        {
          "name": "MTN_MONEY",
          "label": "MTN Mobile Money",
          "type": "MOBILE_MONEY",
          "available": true
        },
        {
          "name": "STRIPE",
          "label": "Carte bancaire (Visa / Mastercard)",
          "type": "CARD",
          "available": true
        }
      ]
    }
    bash
    curl https://api.elyonpay.org/api/public/configuration/payments/CM

    Direct Payment

    Initiate a payment directly from your server without redirecting to an ElyonPay page. The customer stays on your site throughout the transaction.

    Mobile Money

    POST/api/mobile-money/payment/request

    Body Parameters

    ParameterTypeRequiredDescription
    amountnumberRequiredPayment amount in local currency
    user_langstringRequiredUser language (fr, en)
    merchant_namestringRequiredMerchant name shown to the customer
    merchant_idintegerRequiredMerchant identifier
    operation_codestringRequiredOperation code — use "13" for a basket payment
    currencystringRequiredISO 4217 currency code (XAF, XOF, EUR...)
    country_namestringRequiredCustomer's country name
    basket_idintegerRequiredBasket ID (returned by the Basket API)
    beneficiariesarrayRequiredList of payment beneficiaries
    payment_methodstringRequiredChosen payment method (ORANGE_MONEY, MTN_MONEY...)
    customer_msisdnstringRequiredCustomer phone number (international format)
    transactionstringOptionalExternal transaction reference (optional)

    cURL

    bash
    curl -X POST https://api.elyonpay.org/api/mobile-money/payment/request \
      -H "Authorization: Bearer <your_jwt_token>" \
      -H "Content-Type: application/json" \
      -d '{
        "amount": 15000,
        "user_lang": "fr",
        "merchant_name": "Ma Boutique",
        "merchant_id": 258,
        "operation_code": "13",
        "currency": "XAF",
        "country_name": "Cameroon",
        "basket_id": 42,
        "beneficiaries": [{ "id": 258 }],
        "payment_method": "ORANGE_MONEY",
        "customer_msisdn": "+237690000001"
      }'

    Node.js / JavaScript

    javascript
    const response = await fetch('https://api.elyonpay.org/api/mobile-money/payment/request', {
      method: 'POST',
      headers: {
        'Authorization': 'Bearer ' + token,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        amount: 15000,
        user_lang: 'fr',
        merchant_name: 'Ma Boutique',
        merchant_id: 258,
        operation_code: '13',
        currency: 'XAF',
        country_name: 'Cameroon',
        basket_id: 42,
        beneficiaries: [{ id: 258 }],
        payment_method: 'ORANGE_MONEY',
        customer_msisdn: '+237690000001'
      })
    });
    
    const result = await response.json();
    // Start polling result.transactionId for status

    PHP

    php
    $ch = curl_init('https://api.elyonpay.org/api/mobile-money/payment/request');
    curl_setopt_array($ch, [
      CURLOPT_POST => true,
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . $token,
        'Content-Type: application/json'
      ],
      CURLOPT_POSTFIELDS => json_encode([
        'amount'          => 15000,
        'user_lang'       => 'fr',
        'merchant_name'   => 'Ma Boutique',
        'merchant_id'     => 258,
        'operation_code'  => '13',
        'currency'        => 'XAF',
        'country_name'    => 'Cameroon',
        'basket_id'       => 42,
        'beneficiaries'   => [['id' => 258]],
        'payment_method'  => 'ORANGE_MONEY',
        'customer_msisdn' => '+237690000001'
      ])
    ]);
    
    $response = json_decode(curl_exec($ch), true);
    // Start polling $response['transactionId'] for status

    Stripe

    POST/api/stripe/payment/request

    Same payload as the Mobile Money payment. Use payment_method: "STRIPE" and the corresponding currency (EUR, USD, GBP).

    Bank Card

    POST/api/bankcard/payment/request

    Same payload as the Mobile Money payment. Use payment_method: "BANK_CARD".

    Response — PaymentResult

    json
    {
      "transactionId": 1553,
      "PSPid": "CM133169cbd9c1f1",
      "state": "PENDING",
      "amount": 15000,
      "totalCustomer": 15150,
      "currency": "XAF",
      "payment_method": "ORANGE_MONEY",
      "created_at": "2026-06-10T14:27:13+00:00"
    }

    Response Fields

    FieldTypeDescription
    transactionIdintegerTransaction identifier — use this for polling
    PSPidstringUnique ElyonPay identifier
    statestringInitial status (usually PENDING)
    amountnumberTransaction amount
    totalCustomernumberTotal charged to the customer (fees included)
    currencystringISO 4217 currency code
    payment_methodstringPayment method used
    created_atdatetimeCreation date (ISO 8601)

    Status Polling

    After initiating a direct payment, periodically poll the API to get the transaction result. ElyonPay uses a pull model — no webhook is needed.

    Terminal States

    StateResultDescription
    DELIVEREDSuccessPayment confirmed, funds transferred
    FAILEDFailurePayment failed (insufficient balance, network error...)
    DECLINEDFailurePayment declined by the operator
    CANCELLEDFailureCancelled by the customer or system
    PENDINGProcessingTransaction in progress — keep polling
    Polling interval: Poll every 3–5 seconds. Set a maximum timeout of about 2 minutes — beyond that, consider the transaction expired and display an appropriate message to the customer.

    Complete Example — Node.js / Express

    This example covers all 4 Custom Checkout steps: payment methods, display, direct payment and status polling.

    javascript
    const express = require('express');
    const app = express();
    app.use(express.json());
    
    const API = 'https://api.elyonpay.org/api';
    let token = ''; // Obtained via POST /api/login
    
    // Helper: poll transaction status
    async function pollStatus(txId, maxMs = 120000, intervalMs = 4000) {
      const start = Date.now();
      while (Date.now() - start < maxMs) {
        const res = await fetch(`${API}/transactions/${txId}`, {
          headers: { 'Authorization': 'Bearer ' + token }
        });
        const tx = await res.json();
        const terminal = ['DELIVERED', 'FAILED', 'DECLINED', 'CANCELLED'];
        if (terminal.includes(tx.state)) return tx;
        await new Promise(r => setTimeout(r, intervalMs));
      }
      throw new Error('Polling timeout');
    }
    
    // Step 1 — Get payment methods for customer's country
    app.get('/payment-methods/:country', async (req, res) => {
      const methods = await fetch(
        `${API}/public/configuration/payments/${req.params.country}`
      ).then(r => r.json());
      res.json(methods);
    });
    
    // Steps 2-3-4 — Customer picks method, initiate payment, poll result
    app.post('/pay', async (req, res) => {
      const { payment_method, phone, merchant_id, amount } = req.body;
    
      // Step 3 — Initiate direct payment
      const payment = await fetch(`${API}/mobile-money/payment/request`, {
        method: 'POST',
        headers: {
          'Authorization': 'Bearer ' + token,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          amount,
          user_lang: 'fr',
          merchant_name: 'Ma Boutique',
          merchant_id,
          operation_code: '13',
          currency: 'XAF',
          country_name: 'Cameroon',
          beneficiaries: [{ id: merchant_id }],
          payment_method,
          customer_msisdn: phone
        })
      }).then(r => r.json());
    
      // Step 4 — Poll for terminal state
      try {
        const tx = await pollStatus(payment.transactionId);
        if (tx.state === 'DELIVERED') {
          res.json({ success: true, transaction: tx });
        } else {
          res.json({ success: false, state: tx.state, transaction: tx });
        }
      } catch (err) {
        res.status(408).json({ success: false, error: 'Payment timeout' });
      }
    });
    
    app.listen(3000);

    Official SDKs

    Official SDKs are available for major languages and frameworks. They automatically handle authentication and errors.

    JavaScript
    npm install elyonpay-sdk
    PHP
    composer require elyonpay/php-sdk
    Python
    pip install elyonpay
    Java
    Maven / Gradle
    React Native
    npm install @elyonpay/rn
    Flutter
    pub add elyonpay_flutter

    Integration Flow

    ElyonPay uses a 6-step model based on a payment link and active status verification (pull model). No webhook infrastructure is required.

    1

    Get a payment link

    Your backend calls POST /api/request-to-pay/payment/link with the amount and redirect URLs (success / error). The API returns a unique payment URL.

    2

    Display the payment iframe

    Redirect the customer to the returned URL, or embed it in an iframe. The customer chooses their payment method (Mobile Money, bank card) and enters their details.

    3

    Payment validation

    The customer confirms the payment on the operator side (USSD code for Mobile Money, 3D Secure for cards). ElyonPay processes the transaction.

    4

    Redirect to your backend

    Once the payment is processed, the customer is redirected to your success or error URL depending on the result. The transaction UUID is passed in the redirect URL.

    5

    Fetch the transaction status

    Your backend calls GET /api/transactions/{uuid} to retrieve the definitive transaction status. This server-side check is essential — never rely solely on the redirect URL.

    6

    Display confirmation to the customer

    Based on the returned status (DELIVERED, REJECTED, CANCELLED...), display the appropriate confirmation or error page to your customer.

    Pull model: No webhook to expose, no signature to verify, no retries to manage. Your backend controls the verification timing.

    Diagram — Payment Initiation

    sequenceDiagram
      participant Customer
      participant Merchant
      participant ElyonPay
    
      Customer->>Merchant: Finalizes cart
      Customer->>Merchant: Selects "Pay"
      Merchant->>ElyonPay: POST /api/login
      ElyonPay-->>Merchant: Returns JWT token
      Merchant->>ElyonPay: POST /api/request-to-pay/payment/link
      ElyonPay-->>Merchant: Returns payment URL
      Merchant->>Customer: Displays payment page (iframe or redirect)
      Customer->>ElyonPay: Selects payment method
      Customer->>ElyonPay: Completes transaction
      ElyonPay-->>Customer: Shows confirmation popup
          

    Diagram — Payment Result

    sequenceDiagram
      participant Customer
      participant Merchant
      participant ElyonPay
    
      Customer->>ElyonPay: Transaction completed
      alt Successful payment
          ElyonPay->>Merchant: Redirect to success URL
      else Failed payment
          ElyonPay->>Merchant: Redirect to error URL
      end
      Merchant->>ElyonPay: GET /api/transactions/[ID_TRANSACTION]
      ElyonPay-->>Merchant: Returns transaction status
      Merchant->>Merchant: Updates order status
      Merchant->>Customer: Shows order confirmation
          

    Implementation example (steps 1 → 5)

    Node.js / Express

    javascript
    // 1. Create payment link
    app.post('/checkout', async (req, res) => {
      const response = await fetch('https://api.elyonpay.org/api/request-to-pay/payment/link', {
        method: 'POST',
        headers: {
          'Authorization': 'Bearer ' + token,
          'Content-Type': 'application/json',
          'language': 'fr'
        },
        body: JSON.stringify({
          amount: req.body.amount,
          user_lang: 'fr',
          msisdn: req.body.phone,
          success: 'https://yoursite.com/payment/done',
          error: 'https://yoursite.com/payment/error'
        })
      });
      const { url } = await response.json();
      res.redirect(url); // 2. Redirect customer to payment page
    });
    
    // 4 → 5. Handle redirect & verify status
    app.get('/payment/done', async (req, res) => {
      // The transaction uuid is available from your order context
      const tx = await fetch(`https://api.elyonpay.org/api/transactions/${uuid}`, {
        headers: { 'Authorization': 'Bearer ' + token }
      }).then(r => r.json());
    
      if (tx.state === 'DELIVERED') {
        // 6. Show confirmation
        res.render('success', { transaction: tx });
      } else {
        res.render('pending', { transaction: tx });
      }
    });
    Never rely solely on the redirect URL (success/error) to confirm a payment. A user can manually modify the URL. Always verify the status server-side via GET /api/transactions/{uuid}.

    Mobile Money

    ElyonPay unifies 5 African Mobile Money networks under a single API. Each network has its own operator codes and country coverage.

    Supported Networks

    Method CodeNetworkCountriesCurrencies
    mtn_mobile_moneyMTN MoMoCM, NG, CI, GH, UGXAF, NGN, XOF
    orange_moneyOrange MoneyCM, CI, SN, MLXAF, XOF
    waveWaveSN, CI, BF, MLXOF
    moov_moneyMoov AfricaBJ, TG, BF, NEXOF
    airtel_moneyAirtel MoneyKE, TZ, UG, ZM, CDKES, TZS, UGX, CDF

    Coverage: Cameroon, Nigeria, Ivory Coast, Ghana, Uganda, Senegal, Mali, Burkina Faso, Benin, Togo, Niger, Kenya, Tanzania, Zambia, Democratic Republic of Congo.

    Bank Cards

    Accept Visa and Mastercard payments with 3D Secure, tokenization and PCI DSS level 1 compliance.

    Test Cards (Sandbox)

    Card NumberExpiryCVVBehavior
    4242 4242 4242 424212/28123Successful payment
    4000 0000 0000 000212/28123Card declined
    4000 0000 0000 322012/281233D Secure required
    5555 5555 5555 444412/28123Mastercard success

    Payment Statuses

    Each payment goes through several statuses during its lifecycle.

    CREATED
    Transaction created
    PENDING
    Payment initiated, pending
    WAITING_FOR_PAYMENT
    Awaiting customer payment
    ACCEPTED
    Payment confirmed
    DELIVERED
    Funds transferred to merchant
    REJECTED
    Validation failed
    DECLINED
    Payment declined
    CANCELLED
    Cancelled by user or admin

    State Transition Diagram

    stateDiagram-v2
      [*] --> CREATED
      CREATED --> PENDING: Payment initiated
      PENDING --> WAITING_FOR_PAYMENT: Awaiting customer
      WAITING_FOR_PAYMENT --> ACCEPTED: Payment confirmed
      PENDING --> ACCEPTED: Direct approval
      PENDING --> REJECTED: Validation failed
      PENDING --> DECLINED: Payment issue
      WAITING_FOR_PAYMENT --> DECLINED: Payment issue
      WAITING_FOR_PAYMENT --> CANCELLED: User cancellation
      ACCEPTED --> DELIVERED: Funds transferred
      ACCEPTED --> CANCELLED: Administrative action
      REJECTED --> [*]
      DECLINED --> [*]
      CANCELLED --> [*]
      DELIVERED --> [*]
          

    Error Codes

    In case of error, the API returns a JSON object with a machine error code and a readable message.

    json
    {
      "success": false,
      "error": {
        "code": "INSUFFICIENT_FUNDS",
        "message": "The customer's Mobile Money balance is insufficient.",
        "http_status": 402
      }
    }

    Error Table

    Error CodeHTTPDescription
    UNAUTHORIZED401Missing or invalid API key
    INVALID_AMOUNT400Invalid amount or below minimum allowed
    CURRENCY_NOT_SUPPORTED400Currency not supported for this network
    PHONE_INVALID400Invalid or unregistered phone number
    INSUFFICIENT_FUNDS402Insufficient balance on client side
    OPERATOR_TIMEOUT408Mobile Money operator did not respond in time
    DUPLICATE_REQUEST409Duplicate request — use Idempotency-Key
    PAYMENT_NOT_FOUND404Payment not found
    RATE_LIMIT_EXCEEDED429Too many requests — retry in a few seconds
    INTERNAL_ERROR500ElyonPay internal error — contact support

    Supported Currencies

    CodeCurrencyMinimum AmountMethods
    XAFFranc CFA BEAC100 XAFMTN MoMo, Orange Money, Carte
    XOFFranc CFA BCEAO100 XOFWave, Moov, Orange Money, MTN, Carte
    EUREuro0.50 EURCarte (Visa, Mastercard), PayPal
    USDUS Dollar0.50 USDCarte, PayPal
    GBPBritish Pound0.30 GBPCarte
    NGNNigerian Naira100 NGNMTN MoMo NG
    KESKenyan Shilling10 KESAirtel Money
    CDFCongolese Franc500 CDFAirtel Money

    Sandbox & Tests

    The sandbox environment lets you test the complete integration without making real payments. Connect to api.elyonpay.net — no real charges will be made.

    Access the dashboard at dashboard.elyonpay.org to view your transactions in real time.

    Test Accounts by Country

    Use these credentials to test the integration on the sandbox environment. Each account is associated with a specific country and currency.

    🇨🇲CameroonXAF
    PhoneEmailPassword
    +237683191284demo+23733@elyonpay.comCompteDemo1
    🇨🇮Ivory CoastXOF
    PhoneEmailPassword
    +2250758789285demo+225@elyonpay.comCompteDemo1
    🇫🇷FranceEUR
    PhoneEmailPassword
    +33895555555demo+33@elyonpay.comCompteDemo1

    Sandbox Limits

    • Sandbox transactions incur no fees
    • Data is reset every 30 days
    • Limit of 1,000 requests/hour per test key

    Go to Production

    1. Complete KYB (Know Your Business) verification in your dashboard
    2. Switch the base URL from api.elyonpay.net to api.elyonpay.org
    3. Verify that your redirect URLs (success / error) use HTTPS
    4. Configure your low balance alerts
    ElyonPay uses a pull model: after the customer is redirected, your server must call GET /api/transactions/{uuid} to get the definitive status. No webhook is needed.