Skip to main content

Pay-in (Mobile Money) API

This endpoint allows you to initiate mobile money payment requests from your customers. Mobile money is a dominant payment method across Central and West Africa, enabling payments via providers like MTN Mobile Money, Orange Money, and others.

Endpoint

POST /payments/payin/mobile-money

Headers

NameDescription
X-API-KeyYour Zikopay API Key
X-API-SecretYour Zikopay API Secret
AcceptMust be application/json
Content-TypeMust be application/json

Request Parameters

ParameterTypeRequiredDescription
amountnumberYesTransaction amount in the specified currency
currencystringYesCurrency code (e.g., XAF, NGN, GHS)
phoneNumberstringYesCustomer's mobile money phone number with country code
operatorstringYesMobile money operator (e.g., orange_cm, mtn_cm)
return_urlstringYesURL where customer will be redirected after payment
cancel_urlstringYesURL where customer will be redirected if they cancel
callback_urlstringYesURL where payment status updates will be sent
descriptionstringYesTransaction description
payment_detailsobjectNoAdditional payment metadata
customerobjectYesCustomer information
customer.namestringYesCustomer's full name
customer.phonestringYesCustomer's phone number
customer.emailstringYesCustomer's email address

Example Request

{
"amount": 200,
"currency": "XAF",
"phoneNumber": "237696447402",
"operator": "orange_cm",
"return_url": "https://yourwebsite.com/payment/success",
"cancel_url": "https://yourwebsite.com/payment/cancel",
"callback_url": "https://yourwebsite.com/api/webhook",
"description": "Payment for order #12345",
"payment_details": {
"order_id": "12345",
"items": "Premium subscription"
},
"customer": {
"name": "John Doe",
"phone": "696447002",
"email": "john.doe@example.com"
}
}

Success Response

{
"error": false,
"reference": "TXN17494045440D1288",
"status": "success",
"message": "Vous devez maintenant confirmer votre transaction"
}

Error Response

{
"error": true,
"reference": "TXN17494045440D1288",
"status": "failed",
"error_message": "Something went wrong"
}

Response Parameters

ParameterTypeDescription
referencestringUnique transaction reference ID
currencystringTransaction currency
statusstringCurrent transaction status: pending, completed, failed

Transaction Flow

  1. Your application initiates a mobile money payment request
  2. Zikopay sends a payment request to the mobile money provider
  3. The customer receives a prompt on their phone to authorize the payment
  4. After the customer approves or rejects, the mobile money provider sends a status update
  5. Zikopay sends a webhook notification to your callback_url with the payment status
  6. The customer is redirected to your return_url or cancel_url depending on the outcome

Supported Mobile Money Operators

OperatorCodePayment TypeCountriesCurrencies
MTN Cameroonmtn_cmMTN Mobile MoneyCameroonXAF
Orange Cameroonorange_cmOrange MoneyCameroonXAF
MTN Côte d'Ivoiremtn_ciMTN MoMoCôte d'IvoireXOF
Orange Côte d'Ivoireorange_ciOrange MoneyCôte d'IvoireXOF
Moov Côte d'Ivoiremoov_ciMoov MoneyCôte d'IvoireXOF
Wave Côte d'Ivoirewave_ciWave Mobile MoneyCôte d'IvoireXOF
Orange Senegalorange_snOrange MoneySenegalXOF
Free Money Senegalfree_money_snFree MoneySenegalXOF
Expresso Senegalexpresso_snExpresso MoneySenegalXOF
MTN Beninmtn_bjMTN Mobile MoneyBeninXOF
Moov Beninmoov_bjMoov MoneyBeninXOF
T Money Togot_money_tgT MoneyTogoXOF

Testing

In the test environment, you can simulate different payment outcomes:

Phone NumberResult
237600000001Successful payment
237600000002Failed payment (insufficient funds)
237600000003Timeout (no response)
237600000004User cancellation

Notes

  • Phone numbers should include the country code (e.g., 237 for Cameroon)
  • Mobile money payment requests expire after 15 minutes if not completed
  • The account holder name on the mobile money account may be verified against the customer name
  • Fees are applied according to your merchant agreement and may vary by operator

Code Examples

PHP

<?php
$curl = curl_init();

curl_setopt_array($curl, [
CURLOPT_URL => "https://api.payment.zikopay.com/v1/payments/payin/mobile-money",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'amount' => 200,
'currency' => 'XAF',
'phoneNumber' => '237696447402',
'operator' => 'orange_cm',
'return_url' => 'https://yourwebsite.com/payment/success',
'cancel_url' => 'https://yourwebsite.com/payment/cancel',
'callback_url' => 'https://yourwebsite.com/api/webhook',
'description' => 'Payment for order #12345',
'payment_details' => [
'order_id' => '12345'
],
'customer' => [
'name' => 'John Doe',
'phone' => '696447002',
'email' => 'john.doe@example.com'
]
]),
CURLOPT_HTTPHEADER => [
"Accept: application/json",
"Content-Type: application/json",
"X-API-Key: your_api_key",
"X-API-Secret: your_api_secret"
],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
echo "cURL Error #:" . $err;
} else {
$data = json_decode($response, true);
if ($data['success']) {
// Store the reference for tracking
$_SESSION['payment_reference'] = $data['data']['reference'];
echo "Please check your phone to approve the payment request";
} else {
echo "Error: " . $data['message'];
}
}
?>

JavaScript

const initiateMobileMoneyPayment = async () => {
try {
const response = await fetch('https://api.payment.zikopay.com/v1/payments/payin/mobile-money', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'X-API-Key': 'your_api_key',
'X-API-Secret': 'your_api_secret'
},
body: JSON.stringify({
amount: 200,
currency: 'XAF',
phoneNumber: '237696447402',
operator: 'orange_cm',
return_url: 'https://yourwebsite.com/payment/success',
cancel_url: 'https://yourwebsite.com/payment/cancel',
callback_url: 'https://yourwebsite.com/api/webhook',
description: 'Payment for order #12345',
payment_details: {
order_id: '12345'
},
customer: {
name: 'John Doe',
phone: '696447002',
email: 'john.doe@example.com'
}
})
});

const data = await response.json();

if (data.success) {
// Show instructions to the customer
console.log(data.data.instructions);

// You might want to redirect to a waiting page
window.location.href = '/payment/waiting?reference=' + data.data.reference;
} else {
console.error('Payment initiation failed:', data.message);
}
} catch (error) {
console.error('Error:', error);
}
};

Python

import requests
import json

url = "https://api.payment.zikopay.com/v1/payments/payin/mobile-money"

payload = json.dumps({
"amount": 200,
"currency": "XAF",
"phoneNumber": "237696447402",
"operator": "orange_cm",
"return_url": "https://yourwebsite.com/payment/success",
"cancel_url": "https://yourwebsite.com/payment/cancel",
"callback_url": "https://yourwebsite.com/api/webhook",
"description": "Payment for order #12345",
"payment_details": {
"order_id": "12345"
},
"customer": {
"name": "John Doe",
"phone": "696447002",
"email": "john.doe@example.com"
}
})

headers = {
'Accept': 'application/json',
'Content-Type': 'application/json',
'X-API-Key': 'your_api_key',
'X-API-Secret': 'your_api_secret'
}

response = requests.post(url, headers=headers, data=payload)

if response.status_code == 200:
data = response.json()
if data['success']:
print(f"Payment initiated. Reference: {data['data']['reference']}")
print(f"Instructions: {data['data']['instructions']}")
else:
print(f"Error: {data['message']}")
else:
print(f"HTTP Error: {response.status_code}")

Regional Considerations

Different mobile money operators have unique characteristics:

  • Orange Money: Typically requires a 4-digit PIN to confirm transactions
  • MTN Mobile Money: May use USSD prompts or app notifications
  • Ghana: Mobile money interoperability is more advanced
  • Nigeria: Often requires BVN (Bank Verification Number) for higher amounts

Always ensure your customer is informed about the payment process specific to their mobile money provider.