ZenoPay API cURL Documentation v1.0

Welcome to ZenoPay PHP cURL Documentation

This documentation provides all the information you need to integrate with the ZenoPay API using PHP and its native cURL extension.

ZenoPay specializes in secure and efficient Mobile Money Payments Integration within Tanzania. The API is designed to be straightforward for processing transactions.

Getting Started: Your Essential Credentials

Before you can start using the ZenoPay API, you'll need an API Key. This key is crucial for authenticating your requests to our API.

To obtain your API Key, you must first register for an account at https://zenoapi.com/. After successful registration, you can request your unique API Key from the ZenoPay dashboard. This key will be used for authentication.

Setting up PHP and cURL

To use the PHP examples in this documentation, you'll need:

  1. PHP: Ensure you have PHP installed on your system (version 7.4 or higher recommended). You can download it from php.net.
  2. PHP cURL Extension: The cURL extension is typically bundled and enabled by default in modern PHP installations. If not, you may need to enable it in your php.ini file (e.g., uncomment extension=curl or ;extension=php_curl.dll for Windows).
  3. No special Composer or external libraries are required for the basic cURL examples presented here, although using an HTTP client like Guzzle (as in your previous documentation) could simplify more complex interactions.
Important: Always refer to the official ZenoPay dashboard and your provided API Key for production use.

Authentication

ZenoPay API uses an API Key for authentication. You must include your API Key in the x-api-key header for every request made to secure endpoints.

Setting Up Your API Request Header

To communicate with the ZenoPay API, you need to include an authorization header in your requests. This tells our system that you are authenticated. The header should be formatted as follows:

x-api-key: YOUR_API_KEY
Content-Type: application/json
Accept: application/json

Replace YOUR_API_KEY with the actual API key you obtained from your ZenoPay dashboard. Ensure all requests are made over HTTPS.

Note: Some API endpoints, especially for initial data submission, utilize the POST method for sending data. Always check the specific endpoint details for the required HTTP method.

API Endpoints

The primary base URL for ZenoPay API is:

https://zenoapi.com

Specific paths for each API function (e.g., /api/payments/mobile_money_tanzania) will be appended to this base URL.

POST 1. Initiate Mobile Money Payment

This endpoint allows you to initiate a mobile money payment transaction for your customer, typically via a USSD push automated debit, followed by a callback to your system.

Endpoint: POST https://zenoapi.com/api/payments/mobile_money_tanzania

Headers

ParameterRequiredExample Value
x-api-keyYesYOUR_API_KEY
Content-TypeYesapplication/json

Request Body

ParameterTypeRequiredDescriptionExample Value
order_idstringYesA unique transaction ID (e.g., UUID) for your order."3rer407fe-3ee8-4525-456f-ccb95de38250"
buyer_emailstringYesPayer's valid email address."iam@gmail.com"
buyer_namestringYesPayer's full name."John Joh"
buyer_phonestringYesTanzanian mobile number (format: 07XXXXXXXX). This number will receive the payment push."0744963858"
amountnumberYesThe transaction amount in TZS.1000
webhook_urlstringNoYour webhook URL for receiving payment status updates when status changes to COMPLETED."https://your-domain.com/payment-webhook"

Example Request Body:

{
  "order_id": "3rer407fe-3ee8-4525-456f-ccb95de38250",
  "buyer_email": "iam@gmail.com",
  "buyer_name": "John Joh",
  "buyer_phone": "0744963858",
  "amount": 1000,
  "webhook_url": "https://your-domain.com/payment-webhook"
}

Processing the Response and Important Information

Upon successful submission of the payment request, ZenoPay will return a response indicating the request is in progress. The actual payment confirmation (e.g., "COMPLETED") will be sent via a webhook callback to your specified webhook_url (if provided), or you can check the status using the "Check Order Status" endpoint.

Example Successful Response:

{
  "status": "success",
  "resultcode": "000",
  "message": "Request in progress. You will receive a callback shortly",
  "order_id": "3rer407fe-3ee8-4525-456f-ccb95de38250"
}

Example Error Response:

{
  "status": "error",
  "message": "Invalid API Key or request payload"
}

PHP cURL Example

<?php

$apiEndpoint = 'https://zenoapi.com/api/payments/mobile_money_tanzania';
$apiKey = 'YOUR_API_KEY'; // Replace with your actual ZenoPay API Key

$orderId = 'MY-APP-ORDER-' . uniqid(); // Generate a unique order ID

$payload = [
    'order_id'      => $orderId,
    'buyer_email'   => 'customer@example.com',
    'buyer_name'    => 'Test Customer',
    'buyer_phone'   => '0744963858', // Tanzanian mobile number (e.g., 07XXXXXXXX)
    'amount'        => 1000,         // Amount in TZS
    'webhook_url'   => 'https://your-domain.com/api/zenopay_webhook.php', // Your webhook URL for callbacks
];

$jsonPayload = json_encode($payload);

$ch = curl_init($apiEndpoint);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonPayload);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'x-api-key: ' . $apiKey,
    'Content-Type: application/json',
    'Content-Length: ' . strlen($jsonPayload)
]);

$response = curl_exec($ch);
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

if (curl_errno($ch)) {
    echo 'cURL Error: ' . curl_error($ch);
} else {
    echo "HTTP Status Code: " . $httpcode . "\n";
    echo "Response:\n" . $response;
    
    $responseData = json_decode($response, true);
    if ($responseData && isset($responseData['status']) && $responseData['status'] === 'success') {
        echo "\nPayment request sent successfully. ZenoPay Order ID: " . $responseData['order_id'] . "\n";
        echo "A callback will be sent to your webhook_url or check status with the Order Status endpoint.\n";
    } elseif ($responseData && isset($responseData['status']) && $responseData['status'] === 'error') {
        echo "\nPayment initiation failed: " . $responseData['message'] . "\n";
    }
}

curl_close($ch);
?>

GET 2. Check Order Status

This endpoint allows you to check the current status of a specific payment order using its order_id.

Endpoint: GET https://zenoapi.com/api/payments/order-status

Headers

ParameterRequiredExample Value
x-api-keyYesYOUR_API_KEY

Query Parameter

ParameterTypeRequiredDescriptionExample Value
order_idstringYesThe unique identifier of the order whose status you want to check (e.g., from the payment initiation response)."3rer407fe-3ee8-4525-456f-ccb95de38250"

Sample Request (cURL)

curl -X GET "https://zenoapi.com/api/payments/order-status?order_id=3rer407fe-3ee8-4525-456f-ccb95de38250" \
-H "x-api-key: YOUR_API_KEY"

Successful Response

{
  "reference": "0936183435",
  "resultcode": "000",
  "result": "SUCCESS",
  "message": "Order fetch successful",
  "data": [
    {
      "order_id": "3rer407fe-3ee8-4525-456f-ccb95de38250",
      "creation_date": "2025-05-19 08:40:33",
      "amount": "1000",
      "payment_status": "COMPLETED",
      "transid": "CEJ3I3SETSN",
      "channel": "MPESA-TZ",
      "reference": "0936183435",
      "msisdn": "255744963858"
    }
  ]
}

PHP cURL Example

<?php

$apiEndpoint = 'https://zenoapi.com/api/payments/order-status';
$apiKey = 'YOUR_API_KEY'; // Replace with your actual ZenoPay API Key

$orderIdToCheck = '3rer407fe-3ee8-4525-456f-ccb95de38250'; // Replace with the actual order_id you want to check

$url = $apiEndpoint . '?order_id=' . urlencode($orderIdToCheck);

$ch = curl_init($url);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'x-api-key: ' . $apiKey,
    'Accept: application/json' // Although not specified as required in ZenoPay PDF, good practice.
]);

$response = curl_exec($ch);
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

if (curl_errno($ch)) {
    echo 'cURL Error: ' . curl_error($ch);
} else {
    echo "HTTP Status Code: " . $httpcode . "\n";
    echo "Response:\n" . $response;

    $responseData = json_decode($response, true);
    if ($responseData && isset($responseData['result']) && $responseData['result'] === 'SUCCESS' && !empty($responseData['data'])) {
        echo "\nOrder Status Details:\n";
        echo "  Order ID: " . $responseData['data'][0]['order_id'] . "\n";
        echo "  Amount: " . $responseData['data'][0]['amount'] . "\n";
        echo "  Payment Status: " . $responseData['data'][0]['payment_status'] . "\n";
        echo "  Channel: " . $responseData['data'][0]['channel'] . "\n";
    } else {
        echo "\nCould not retrieve specific order details or order not found/completed, or an error occurred.\n";
    }
}

curl_close($ch);
?>

Webhook Notifications

ZenoPay can send automatic notifications to your server when payment status changes to COMPLETED.

Webhook Setup

To receive status updates via webhooks, you need to include the webhook_url parameter in your initial payment request to the Initiate Mobile Money Payment endpoint.

Example Payment Request with Webhook URL:

{
  "order_id": "3rer407fe-3ee8-4525-456f-ccb95de38250",
  "buyer_email": "iam@gmail.com",
  "buyer_name": "John Joh",
  "buyer_phone": "0744963858",
  "amount": 1000,
  "webhook_url": "https://your-domain.com/payment-webhook"
}

Webhook Authentication

ZenoPay will send your `x-api-key` in the request header when calling your webhook_url. It is strongly recommended to verify this key in your webhook receiver to ensure the request is legitimate and originates from ZenoPay.

Webhook Payload Example

When a payment status changes to COMPLETED, ZenoPay will send a JSON payload similar to the following to your registered webhook_url:

{
  "order_id": "677e43274d7cb",
  "payment_status": "COMPLETED",
  "reference": "1003020496",
  "metadata": {}
}
Note: Webhooks are only triggered when payment status changes to COMPLETED.

Support & Resources

Get help with integration, troubleshooting, and account management through our comprehensive support channels.

Support Channels

Support Channel Contact Information Response Time
Email Support support@zenopay.net 24 hours
WhatsApp 0793166166 Business hours (8AM - 5PM EAT)
Documentation zenopay-docs.netlify.app 24/7

Common Integration Issues

Issue Solution
Invalid API Key Ensure your API key is correctly set in the request headers as x-api-key: YOUR_API_KEY
Phone Number Format Use Tanzanian format (0744001122) without country code or + sign
Webhook Not Receiving Check your webhook URL is publicly accessible and returns 200 OK. Test with webhook.site first.
SSL Certificate Ensure your webhook endpoint uses valid SSL certificate (Let's Encrypt offers free certificates)
Timeout Issues Set request timeout to at least 60 seconds for payment requests
Payment Status Not Updating Mobile money payments can take several minutes to complete. Use webhooks or poll the status endpoint periodically.

Implementation Guides

Additional Resources

Isaiah Nyalali
Isaiah's Integration Tip
API Developer & Documentation Author

When debugging API issues, I always recommend including these in your support requests:

  • Test API key (mask the first few characters for security)
  • Request samples (both successful and failing ones)
  • Timestamps in UTC format
  • Expected vs actual behavior

This helps me reproduce and resolve issues much faster. Feel free to follow me on LinkedIn!