API Documentation

Mopay Integration Guide

Integrate Mopay into your website to accept M-Pesa, EcoCash, and Card payments in Lesotho. Simple, secure, and developer-friendly.

Quick Overview

Integrate payments in three simple steps: create a session, redirect to Mopay, and handle the response.

Your App → Create Payment Session → Redirect to Mopay → User Pays → Redirect Back

API Service

https://pay.mopay.co.ls

Create payment sessions

Payment UI

https://mopay.co.ls

User payment interface

Getting Started

1

Get Your API Key

  1. Go to https://mopay.co.ls
  2. Create an account and log in
  3. Create a new Project
  4. Copy your API Key from the project settings

Security: Keep your API key secure. Store it in environment variables, never in client-side code.

Integration Steps

Step 1: Create a Payment Session

Make a POST request to create a payment session:

POST https://pay.mopay.co.ls/api/external/payment

Headers:
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json

Body:
{
  "amount": "100.00",
  "reference": "ORDER12345",
  "redirectUrl": "https://yourwebsite.com/payment-complete",
  "description": "Order #12345",
  "customerEmail": "customer@example.com",
  "customerName": "John Doe"
}

Required Fields

FieldTypeDescription
amountstringPayment amount (e.g., "100.00")
referencestringUnique order reference (alphanumeric only)
redirectUrlstringURL to redirect after payment

Reference Format: Must contain only alphanumeric characters. No spaces, hyphens, underscores, or special characters.

✅ Valid: ORDER12345❌ Invalid: ORDER-12345

Optional Fields

FieldTypeDescription
descriptionstringPayment description shown to user
customerEmailstringCustomer's email address
customerNamestringCustomer's name
paymentFrequencystringONCE, MONTHLY, or ANNUALLY
productNamestringProduct name (for product payments)
productDetailsstringProduct or payment description
productImagestringURL to product image
payWhatYouWantbooleanAllow custom amounts
minimumAmountstringMinimum amount if payWhatYouWant is true

Note on paymentFrequency:

  • ONCE - One-time payment only
  • MONTHLY - (Coming Soon) Monthly debit orders/subscriptions
  • ANNUALLY - (Coming Soon) Annual debit orders/subscriptions

⚠️ Debit order functionality for MONTHLY and ANNUALLY is not yet available. All payments currently process as one-time payments.

Success Response (200):

{
  "success": true,
  "sessionId": "MOP_abc123_ORDER12345",
  "paymentUrl": "https://mopay.co.ls/pay/MOP_abc123_ORDER12345",
  "reference": "ORDER12345",
  "amount": "100.00"
}

Step 2: Redirect User to Mopay

After receiving the response, redirect the user to the payment URL:

// JavaScript example
window.location.href = response.paymentUrl;

// Or use a link
<a href="https://mopay.co.ls/pay/MOP_abc123_ORDER12345">Complete Payment</a>

The user will be taken to Mopay's payment page where they can select a payment method (M-Pesa, EcoCash, or Card) and complete the transaction.

Step 3: Handle the Redirect Back

After payment completion, users are redirected to your URL with query parameters:

✅ Successful Payment:

https://yourwebsite.com/payment-complete?status=success&reference=ORDER12345&transactionId=TXN123&sessionId=MOP_abc123_ORDER12345&amount=100.00&paymentMethod=mpesa

❌ Failed Payment:

https://yourwebsite.com/payment-complete?status=failed&reference=ORDER12345&sessionId=MOP_abc123_ORDER12345&error=Payment+declined&paymentMethod=card

⚠️ Cancelled Payment:

https://yourwebsite.com/payment-complete?status=cancelled&reference=ORDER12345&amount=100.00&paymentMethod=none&sessionId=MOP_abc123_ORDER12345

When a user clicks "Cancel Payment" on the Mopay payment page, they are redirected with status=cancelled. The paymentMethod will be none if cancelled before selecting a payment method.

Query Parameters

ParameterDescription
statussuccess, failed, or cancelled
referenceYour original reference
transactionIdMopay transaction ID (on success only)
sessionIdThe payment session ID
amountPayment amount
paymentMethodmpesa, ecocash, card, or none (if cancelled before selection)
errorError message (on failure only)

Complete Code Examples

JavaScript
// Create payment session
async function createPaymentSession(orderData) {
  const response = await fetch("https://pay.mopay.co.ls/api/external/payment", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.MOPAY_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      amount: orderData.total.toFixed(2),
      reference: orderData.orderId,
      redirectUrl: "https://yoursite.com/payment-complete",
      description: `Order #${orderData.orderId}`,
      customerEmail: orderData.customerEmail,
      customerName: orderData.customerName,
    }),
  });

  const data = await response.json();

  if (!data.success) {
    throw new Error(data.error);
  }

  return data;
}

// Usage
const payment = await createPaymentSession({
  orderId: "ORD001",
  total: 150.0,
  customerEmail: "john@example.com",
  customerName: "John Doe",
});

// Redirect user to payment page
window.location.href = payment.paymentUrl;

Payment Methods

M-Pesa

Mobile money by Vodacom Lesotho. User receives USSD prompt and enters PIN to confirm.

EcoCash

Mobile money by Econet Telecom Lesotho. User receives USSD prompt and enters PIN to confirm.

Card

Visa and Mastercard supported. Processed through iVeri payment gateway with secure card entry.

Retrieving Session Details

You can retrieve payment session details using the session ID:

Recommended: Always verify the transaction status by retrieving the session details from the API. Do not rely solely on the redirect parameters as they can be tampered with.

GET https://pay.mopay.co.ls/api/external/session/v1/{sessionId}

curl -X GET "https://pay.mopay.co.ls/api/external/session/v1/MOP_abc123_ORDER12345" \
  -H "Accept: application/json"

Response:

{
  "success": true,
  "session": {
    "id": "...",
    "sessionId": "MOP_abc123_ORDER12345",
    "amount": "100.00",
    "reference": "ORDER12345",
    "transactionStatus": "success",
    "redirectUrl": "https://yoursite.com/payment-complete",
    "status": "COMPLETED",
    "selectedPaymentMethod": "mpesa",
    "transactionId": "TXN123",
    "createdAt": "2025-12-04T14:00:00Z",
    "completedAt": "2025-12-04T14:05:00Z"
  }
}

Session Status Values

StatusDescription
CREATEDSession created, awaiting payment
PROCESSINGPayment in progress
COMPLETEDPayment successful
FAILEDPayment failed
CANCELLEDPayment cancelled by user
EXPIREDSession expired

Transaction Status Values

StatusDescription
successPayment successful
failedPayment failed
cancelledPayment cancelled

Note: transactionStatus can be null

Error Handling

Always check the success field in responses:

const response = await fetch("https://pay.mopay.co.ls/api/external/payment", {
  // ...
});

const data = await response.json();

if (!data.success) {
  // Handle error
  console.error("Error:", data.error);
  throw new Error(data.error);
}

// Proceed with data.paymentUrl

Common Errors

ErrorCauseSolution
Invalid API keyWrong or missing API keyCheck your API key
Invalid request dataMissing required fieldsInclude amount, reference, redirectUrl
Valid redirect URL is requiredInvalid redirectUrlUse full URL with https://

Security Best Practices

Never expose your API key

  • • Store in environment variables
  • • Only make API calls from server-side code

Validate payments server-side

  • • Don't trust client-side redirect parameters alone
  • • Use the session retrieval API to verify payment status

Use unique references

  • • Generate unique order IDs
  • • Prevents duplicate payments

Use HTTPS

  • • Always use https:// for your redirectUrl
  • • Protects customer data

Testing

For testing, use the same endpoints. Create test orders with small amounts to verify your integration works correctly.

Ready to integrate?

Get started today and start accepting payments in minutes.

Create Account

Quick Summary

  1. 1Get API key from https://mopay.co.ls
  2. 2Create session via POST https://pay.mopay.co.ls/api/external/payment
  3. 3Redirect user to the returned paymentUrl
  4. 4Handle redirect back to your redirectUrl with payment status