ZenoPay API Guzzle Documentation v1.0

Welcome to ZenoPay PHP Guzzle Documentation

This documentation provides all the information you need to integrate with the ZenoPay API using PHP and the Guzzle HTTP client. This guide was originally constructed by Isaiah Nyalali.

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 Guzzle

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. Composer: Composer is a dependency manager for PHP. If you don't have it, download and install it from getcomposer.org.
  3. Guzzle HTTP Client: Once Composer is installed, navigate to your project directory in your terminal and run the following command to install Guzzle:
    composer require guzzlehttp/guzzle
  4. Include Composer's autoloader in your PHP scripts:
    <?php
    require 'vendor/autoload.php';
    // Guzzle client code will go here
    ?>
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.

URL: https://zenoapi.com/api/payments/mobile_money_tanzania

Method: POST

Authentication

Include your API key in the header:

x-api-key: YOUR_API_KEY

Request Body Parameters

ParameterTypeRequiredDescriptionExample Value
order_idstringYesUnique transaction ID (e.g., UUID) from your system."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 Guzzle Example

<?php
require 'vendor/autoload.php'; // Include Composer's autoloader

use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;

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

$client = new Client();

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

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

try {
    $response = $client->request('POST', $apiEndpoint, [
        'headers' => [
            'x-api-key'     => $apiKey,
            'Content-Type'  => 'application/json',
            'Accept'        => 'application/json', // Good practice to include
        ],
        'json'    => $payload,
        'timeout' => 15, // Timeout in seconds
    ]);

    $statusCode = $response->getStatusCode();
    $responseBody = $response->getBody()->getContents();

    echo "HTTP Status Code: " . $statusCode . "\n";
    echo "Response:\n" . $responseBody . "\n";
    
    $responseData = json_decode($responseBody, true);
    if ($responseData && isset($responseData['status']) && $responseData['status'] === 'success') {
        echo "Payment 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 "Payment initiation failed: " . $responseData['message'] . "\n";
    }

} catch (RequestException $e) {
    echo "Error: " . $e->getMessage() . "\n";
    if ($e->hasResponse()) {
        echo "Response Body: " . $e->getResponse()->getBody()->getContents() . "\n";
    }
}
?>

GET 2. Check Order Status

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

URL: https://zenoapi.com/api/payments/order-status

Method: GET

Authentication

Include your API key in the header:

x-api-key: YOUR_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, for reference from ZenoPay docs)

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 Guzzle Example

<?php
require 'vendor/autoload.php'; // Include Composer's autoloader

use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;

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

$client = new Client();

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

try {
    $response = $client->request('GET', $apiEndpoint, [
        'headers' => [
            'x-api-key' => $apiKey,
            'Accept'    => 'application/json',
        ],
        'query'   => [ // Query parameters are sent via 'query' option in Guzzle GET requests
            'order_id' => $orderIdToCheck,
        ],
        'timeout' => 10, // Timeout in seconds
    ]);

    $statusCode = $response->getStatusCode();
    $responseBody = $response->getBody()->getContents();

    echo "HTTP Status Code: " . $statusCode . "\n";
    echo "Response:\n" . $responseBody . "\n";

    $responseData = json_decode($responseBody, true);
    if ($responseData && isset($responseData['result']) && $responseData['result'] === 'SUCCESS' && !empty($responseData['data'])) {
        echo "Order 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 "Could not retrieve specific order details or order not found/completed, or an error occurred.\n";
    }

} catch (RequestException $e) {
    echo "Error: " . $e->getMessage() . "\n";
    if ($e->hasResponse()) {
        echo "Response Body: " . $e->getResponse()->getBody()->getContents() . "\n";
    }
}
?>

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!