OptimaPay Payment Gateway API docs

Comprehensive documentation for integrating with our payment system

Introduction

OptimaPay Payment Gateway API allows you to integrate M-Pesa STK Push payments into your applications. This documentation provides details on how to configure your system, initiate payments, and track transactions in real-time.

Base URL

All API endpoints are relative to the base URL:

https://www.infinity.gazelleusacompany.com/api/v2/

Authentication

All API requests require authentication using API keys. Include these in the request headers:

Response Format

All API responses are returned in JSON format with a consistent structure:

{
    "success": true|false,
    "message": "Descriptive message",
    // Additional data fields depending on the endpoint
}

API Test Interface

Use this interface to test the OptimaPay Pay API endpoints with your credentials.

Test results will appear here...

Getting Started

1. Obtain API Credentials

To use the OptimaPay API, you need to:

  1. Create an account on the OptimaPay platform
  2. Generate your API Key and Secret from the dashboard
  3. Set up at least one payment account

2. PHP Integration Example

Here's a basic PHP implementation to get you started:

<?php
// Initialize payment
function initiatePayment($apiKey, $apiSecret, $paymentAccountId, $phone, $amount, $reference, $description) {
    $url = "https://www.infinity.gazelleusacompany.com/api/v2/stkpush.php";
    
    $data = [
        'payment_account_id' => $paymentAccountId,
        'phone' => $phone,
        'amount' => $amount,
        'reference' => $reference,
        'description' => $description
    ];
    
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'X-API-Key: ' . $apiKey,
        'X-API-Secret: ' . $apiSecret,
        'Content-Type: application/json'
    ]);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
    
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    
    return json_decode($response, true);
}

// Your API credentials
$apiKey = "your_api_key_here";
$apiSecret = "your_api_secret_here";
$paymentAccountId = 14; // Your payment account ID

// Example usage
$result = initiatePayment($apiKey, $apiSecret, $paymentAccountId, "254712345678", 100, "ORDER123", "Test payment");

if ($result['success']) {
    echo "STK push sent successfully. Checkout Request ID: " . $result['checkout_request_id'];
} else {
    echo "Error: " . $result['message'];
}
?>

API Endpoints

Initiate STK Push

This endpoint initiates an M-Pesa STK Push payment request.

POST /stkpush.php

Request Parameters

Parameter Type Required Description
payment_account_id Integer Yes Your payment account ID
phone String Yes Customer phone number (format: 254712345678)
amount Float Yes Payment amount (minimum 1 KES)
reference String No Your internal reference for the transaction
description String No Description of the payment

Example Request

{
    "payment_account_id": 17,
    "phone": "254712345678",
    "amount": 100,
    "reference": "ORDER_12345",
    "description": "Payment for order #12345"
}

Response

Success Response (200 OK)
{
    "success": true,
    "message": "STK push sent successfully",
    "checkout_request_id": "ws_CO_20230101120000_abc123def456",
    "merchant_request_id": "ws_MR_20230101120000_xyz789uvw012"
}
Error Response (4xx/5xx)
{
    "success": false,
    "message": "Error description"
}

Check Payment Status

This endpoint checks the status of a payment transaction.

POST /status.php

Request Parameters

Parameter Type Required Description
checkout_request_id String Yes The checkout request ID from the STK Push response

Example Request

{
    "checkout_request_id": "ws_CO_20230101120000_abc123def456"
}

Response

Success Response (200 OK)
{
    "success": true,
    "status": "completed",
    "amount": 100,
    "phone": "254712345678",
    "transaction_code": "ABC123DEF456",
    "created_at": "2023-01-01 12:00:00"
}

Status Values

  • pending - Payment initiated but not completed
  • completed - Payment successfully completed
  • failed - Payment failed or was cancelled

List Transactions

This endpoint retrieves a list of your transactions with pagination support.

GET /transactions.php?page=1&limit=10

Query Parameters

Parameter Type Required Description
page Integer No Page number (default: 1)
limit Integer No Number of items per page (max: 100, default: 10)

Example Request

GET /transactions.php?page=2&limit=20

Response

Success Response (200 OK)
{
    "success": true,
    "data": [
        {
            "id": 123,
            "amount": 100,
            "status": "completed",
            "phone": "254712345678",
            "transaction_code": "ABC123DEF456",
            "fee_amount": 1.5,
            "fee_deducted": true,
            "type": "API",
            "created_at": "2023-01-01 12:00:00",
            "completed_at": "2023-01-01 12:02:30"
        }
    ],
    "pagination": {
        "current_page": 2,
        "per_page": 20,
        "total_items": 150,
        "total_pages": 8
    }
}

Real-time Transaction Tracking

To track transactions in real-time, implement a polling mechanism that checks the status of a payment at regular intervals until it's completed or failed.

PHP Implementation Example

<?php
// Function to check payment status
function checkPaymentStatus($apiKey, $apiSecret, $checkoutRequestId) {
    $url = "https://www.infinity.gazelleusacompany.com/api/v2/status.php";
    
    $data = ['checkout_request_id' => $checkoutRequestId];
    
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'X-API-Key: ' . $apiKey,
        'X-API-Secret: . $apiSecret,
        'Content-Type: application/json'
    ]);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
    
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    
    return json_decode($response, true);
}

// Example usage after initiating payment
$checkoutRequestId = $result['checkout_request_id']; // From STK Push response

// Check status with polling (every 5 seconds for up to 2 minutes)
$maxAttempts = 24;
$attempt = 0;

while ($attempt < $maxAttempts) {
    $status = checkPaymentStatus($apiKey, $apiSecret, $checkoutRequestId);
    
    if ($status['success']) {
        if ($status['status'] === 'completed') {
            echo "Payment completed. Transaction Code: " . $status['transaction_code'];
            break;
        } elseif ($status['status'] === 'failed') {
            echo "Payment failed.";
            break;
        }
        // If still pending, continue polling
    }
    
    $attempt++;
    sleep(5); // Wait 5 seconds before next check
}

if ($attempt >= $maxAttempts) {
    echo "Payment status check timeout.";
}
?>

Error Handling

The API uses standard HTTP status codes to indicate success or failure:

Code Description
200 Success
400 Bad Request - Invalid parameters
401 Unauthorized - Invalid API credentials
404 Not Found - Resource not found
405 Method Not Allowed
500 Internal Server Error

Common Error Messages

Complete Test Code

Here's a complete PHP implementation that includes a user interface for testing the API:

<?php
// =========================
// OptimaPay STK Push Demo
// =========================
// - Users enter phone + amount in a form
// - System sends STK Push using OptimaPay API
// - Tracks payment automatically in real-time
// =========================

// ==== API CREDENTIALS ====
// (replace these with your real OptimaPay keys)
$apiKey    = "7390a54c44bcb9cb692f6c861562ff6f3b424094bef993d3434e692b17e02c46";
$apiSecret = "882e5a38596b0fd6cfd8f9631592e4290ca4f441a2be5990ec34d778974985c4";
$accountId = 17;

// ==== FUNCTIONS ====

// Function to send STK Push
function initiatePayment($apiKey, $apiSecret, $accountId, $phone, $amount, $reference, $description) {
    $url = "https://www.infinity.gazelleusacompany.com/api/v2/stkpush.php";

    $data = [
        'payment_account_id' => $accountId,
        'phone'              => $phone,
        'amount'             => $amount,
        'reference'          => $reference,
        'description'        => $description
    ];

    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'X-API-Key: '    . $apiKey,
        'X-API-Secret: ' . $apiSecret,
        'Content-Type: application/json'
    ]);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));

    $response = curl_exec($ch);
    curl_close($ch);

    return json_decode($response, true);
}

// Function to check payment status
function checkPaymentStatus($apiKey, $apiSecret, $checkoutRequestId) {
    $url = "https://www.infinity.gazelleusacompany.com/api/v2/status.php";

    $data = ['checkout_request_id' => $checkoutRequestId];

    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'X-API-Key: '    . $apiKey,
        'X-API-Secret: ' . $apiSecret,
        'Content-Type: application/json'
    ]);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));

    $response = curl_exec($ch);
    curl_close($ch);

    return json_decode($response, true);
}
?>
<!DOCTYPE html>
<html>
<head>
    <title>OptimaPay STK Push Demo</title>
    <style>
        body { font-family: Arial, sans-serif; background:#f4f4f4; }
        .container { max-width:500px; margin:50px auto; background:#fff; padding:20px; border-radius:10px; box-OptimaPay:0 0 10px rgba(0,0,0,0.1); }
        h2 { text-align:center; color:#333; }
        label { font-weight:bold; display:block; margin-top:10px; }
        input[type="text"], input[type="number"] { width:100%; padding:10px; margin-top:5px; border:1px solid #ccc; border-radius:5px; }
        button { margin-top:15px; padding:12px; background:#28a745; color:white; border:none; border-radius:5px; width:100%; font-size:16px; cursor:pointer; }
        button:hover { background:#218838; }
        .status-box { margin-top:20px; padding:15px; border-radius:8px; background:#f9f9f9; font-family:monospace; }
        .success { color:green; }
        .error { color:red; }
        .pending { color:orange; }
    </style>
</head>
<body>
<div class="container">
    <h2>💳 OptimaPay STK Push</h2>
    <form method="POST">
        <label>Phone Number (format: 2547XXXXXXXX)</label>
        <input type="text" name="phone" required placeholder="e.g. 254712345678">

        <label>Amount (KES)</label>
        <input type="number" name="amount" required placeholder="e.g. 100">

        <button type="submit" name="pay">Send STK Push</button>
    </form>

<?php
// ==== WHEN USER SUBMITS FORM ====
if (isset($_POST['pay'])) {
    $phone  = $_POST['phone'];
    $amount = $_POST['amount'];
    $reference   = "ORDER" . rand(1000,9999); // unique ref
    $description = "Payment via OptimaPay API";

    echo "<div class='status-box'>";
    echo "<p>📡 Sending STK Push to <b>$phone</b> for <b>KES $amount</b>...</p>";

    $result = initiatePayment($apiKey, $apiSecret, $accountId, $phone, $amount, $reference, $description);

    if (!$result['success']) {
        echo "<p class='error'>❌ Error: " . $result['message'] . "</p>";
        echo "</div>";
    } else {
        $checkoutRequestId = $result['checkout_request_id'];
        echo "<p class='success'>✅ STK Push sent successfully!</p>";
        echo "<p>Checkout Request ID: <b>$checkoutRequestId</b></p>";
        echo "<hr><p>🔍 Tracking payment status...</p>";

        // Auto-poll status
        $maxAttempts = 24; // 2 minutes
        $attempt = 0;

        while ($attempt < $maxAttempts) {
            $status = checkPaymentStatus($apiKey, $apiSecret, $checkoutRequestId);

            if ($status['success']) {
                $paymentStatus = $status['status'];

                echo "<p class='pending'>⏳ Attempt " . ($attempt + 1) . ": Status = <b>$paymentStatus</b></p>";
                flush();

                if ($paymentStatus === "completed") {
                    echo "<p class='success'>🎉 Payment Completed!</p>";
                    echo "<p>Transaction Code: <b>" . $status['transaction_code'] . "</b></p>";
                    break;
                } elseif ($paymentStatus === "failed") {
                    echo "<p class='error'>❌ Payment Failed.</p>";
                    break;
                }
            } else {
                echo "<p class='error'>⚠️ API Error: " . $status['message'] . "</p>";
                break;
            }

            $attempt++;
            sleep(5);
        }

        if ($attempt >= $maxAttempts) {
            echo "<p class='error'>⌛ Payment status check timed out.</p>";
        }

        echo "</div>";
    }
}
?>
</div>
</body>
</html>

The Bridge Protocol

OptimaPayBridge provides a high-performance unified payment middleware. We seamlessly bridge global clearing networks, Visa/Mastercard processing, and localized payment protocols into a single, cohesive API ecosystem, executing real-time account settlements automatically.

Commercial Fee Transparency

Our bridge leverages an optimized 8.0% aggregate commercial fee model. This breakdown accounts for underlying processing overheads combined with your dedicated service markup. Merchants securely clear and retain exactly 92.0% of gross processing volumes directly inside their operational ledger.

Payment Channel Total Aggregate Fee Settlement Target
Secure Card Checkout (Visa/Mastercard) 8.0% xdigitex_balance (KES)
Mobile Money Processing 8.0% xdigitex_balance (KES)
Crypto Assets (USDT/BTC) 8.0% xdigitex_balance (KES)

Secure Authentication

All inbound commercial API requests must pass signature security tokens within the HTTP headers. Live credentials can be rotated inside your merchant dashboard manager.

Required Protocol Headers
X-API-KEY: "OPT_LIVE_6366f1..."
X-API-SECRET: "SEC_LIVE_1e1b4b..."
Content-Type: "application/json"

Request Parameters (Payment Initiation)

Endpoint target for firing transactional requests into the gateway:

POST https://optimapaybridge.co.ke/api/v2/initiate.php
Field Property Data Type Description Summary
method string Conditional selector: 'card', 'mobile', or 'crypto'.
amount float Gross calculation base value in USD or KES depending on endpoint configuration.
phone string Customer recipient string tracking formats natively (e.g., 2547XXXXXXXX).
email string Target for dispatching automated receipt logs and status alerts.

Response Mapping Logic

Responses return clean structured JSON objects. Capture the checkout_url execution string to transfer user contexts safely to payment frames.

Application Success Payload
{ "success": true, "transaction_id": "OP-994821", "checkout_url": "https://optimapaybridge.co.ke/checkout/v2/secure_frame", "ledger": { "gross_computed": 100.00, "aggregate_fee_8pct": 8.00, "net_credit_target": 92.00 } }

Inbound Balance Sync Callback API

To explicitly check, process status variations, or safely force-reflect credit executions directly into your xdigitex_balance repository via backend mechanisms, transmit signed validations to our core commercial callback controller.

POST https://optimapaybridge.co.ke/api/v2/xdigitex_callback.php

Payload Requirements: Pass the transaction reference key inside a standard JSON string payload while serving operational authorization tokens across corresponding headers.

Callback Query Structure
{ "reference": "REF_TX_XYZ7890" }

Interactive API Playground

Verify network configurations and test connection instances against real-time data states instantly below.

Topup (STK Push) API for Wallet

The Topup API enables automated customer-initiated deposits (STK Push) straight to your OptimaPay Service Wallet. Note that a 6% processing fee is deducted from your Service Balance upfront for every transaction.

POST https://optimapaybridge.co.ke/api/v2/topup.php

Authentication

Include your API credentials in the request headers. Keep your Secret Key private.

X-API-KEY: YOUR_API_KEY
X-API-SECRET: YOUR_API_SECRET
Content-Type: application/json

Request Body Parameters

Parameter Type Required Description
phone String Yes The customer mobile number to receive the STK Push prompt (e.g., 0712345678 or 254712345678).
amount Float Yes The principal amount to deposit in KES. Must be greater than 0.

Sample Request Body

{
  "phone": "0712345678",
  "amount": 100.00
}

API Responses

This endpoint utilizes a hybrid synchronous loop. If the customer enters their PIN within 5 seconds, a completed response is delivered instantly. Otherwise, it falls back to a pending status awaiting callback execution.

1. Synchronous Success Response (PIN entered within 5s)

{
  "success": true,
  "status": "completed",
  "transaction_id": "QGR45TX79K",
  "amount_added": 100.00,
  "fee_deducted": 6.00,
  "message": "Deposit processed and credited successfully"
}

2. Asynchronous Pending Response (Awaiting PIN entry)

{
  "success": true,
  "status": "pending",
  "checkout_request_id": "ws_CO_18052026023512345678",
  "message": "STK Push popup sent successfully. Complete PIN entry on your handset."
}

3. Insufficient Service Balance (For 6% Fee)

{
  "success": false,
  "message": "Insufficient Service Balance for 6% processing fee (Need KES 6.00)"
}

Payout (B2C) API

The Payout API enables automated Business-to-Customer (B2C) disbursements from your OptimaPay Service Wallet to any M-Pesa registered number.

POST https://optimapaybridge.co.ke/api/v2/payout.php

Authentication

Include your API credentials in the request headers. Keep your Secret Key private.

X-API-KEY: YOUR_API_KEY
X-API-SECRET: YOUR_API_SECRET
Content-Type: application/json

Request Body Parameters

Parameter Type Required Description
phone String Yes Recipient number (e.g., 254712345678)
amount Float Yes Amount to disburse (Min: 25.00)
reference String No Your unique ID to track the payout

Frontend Example (HTML/Blade)

<!-- Basic Withdrawal Form -->
<form action="/payout-handler" method="POST" class="p-4 border rounded bg-white shadow-sm">
    <div class="mb-3">
        <label class="form-label fw-bold">Recipient Phone</label>
        <input type="text" name="phone" class="form-control" placeholder="2547XXXXXXXX" required>
    </div>
    <div class="mb-3">
        <label class="form-label fw-bold">Amount (KES)</label>
        <input type="number" name="amount" class="form-control" min="25" required>
    </div>
    <button type="submit" class="btn btn-dark w-100 fw-bold">Initialize Payout</button>
</form>

Backend Implementation (PHP)

<?php
$url = "https://optimapaybridge.co.ke/api/v2/payout.php";

$payload = [
    "phone" => "254712345678",
    "amount" => 150.00,
    "reference" => "ORDER_9921"
];

$headers = [
    "X-API-KEY: YOUR_API_KEY",
    "X-API-SECRET: YOUR_API_SECRET",
    "Content-Type: application/json"
];

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$response = curl_exec($ch);
curl_close($ch);

echo $response;
?>

Backend Implementation (Python)

import requests

url = "https://optimapaybridge.co.ke/api/v2/payout.php"
headers = {
    "X-API-KEY": "YOUR_API_KEY",
    "X-API-SECRET": "YOUR_API_SECRET",
    "Content-Type": "application/json"
}
data = {
    "phone": "2547XXXXXXXX",
    "amount": 150.0,
    "reference": "PY_REF_101"
}

response = requests.post(url, json=data, headers=headers)
print(response.json())

JSON Response (Success)

{
    "success": true,
    "message": "Payout successful",
    "transaction_id": "OP_PAY_881272",
    "amount_sent": 142.50,
    "fee_deducted": 7.50
}

Callback Webhooks

Once the transaction is finalized by the carrier, OptimaPay Bridge will POST the results to your configured Webhook URL.

Webhook Payload
{
    "status": "success",
    "transaction_id": "OP_PAY_881272",
    "mpesa_receipt": "RBC9982XX",
    "amount": 150.00,
    "phone": "254712345678",
    "reference": "ORDER_9921",
    "timestamp": "2024-03-20 10:15:00"
}
Handling Webhooks (PHP)
<?php
// Listener URL on your server
$input = file_get_contents('php://input');
$data = json_decode($input, true);

if (isset($data['status']) && $data['status'] === 'success') {
    $receipt = $data['mpesa_receipt'];
    $ref = $data['reference'];
    
    // Update your order status to 'Paid' in your database
    // notify_user($ref);
    
    http_response_code(200);
    echo json_encode(["message" => "Acknowledged"]);
}
?>

Merchant Gateway: Crypto Deposit API ⚡

Enable your users to pay via USDT (TRC20) with automatic conversion to KES.

8% Platform Fee Deducted from gross USD
128.00 KES Rate Fixed settlement value
Auto-Settlement Direct to service_wallet

1. The Request Endpoint

Trigger a new deposit by sending a POST request with your API credentials in the headers.

POST https://optimapaybridge.co.ke/api/v2/crypto_deposit.php

2. PHP Implementation Example 💻

Use the following snippet to generate a secure checkout URL for your customers.

PHP Integration
// 1. API Configuration
$endpoint = "https://optimapaybridge.co.ke/api/v2/crypto_deposit.php";
$api_key  = "YOUR_PUBLIC_KEY";
$secret   = "YOUR_PRIVATE_SECRET";

// 2. Order Details
$payload = [
    "amount"   => 50.00, // USD
    "order_id" => "TXN_" . time()
];

// 3. Request Execution
$ch = curl_init($endpoint);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    "X-API-KEY: $api_key",
    "X-API-SECRET: $secret",
    "Content-Type: application/json"
]);

$response = curl_exec($ch);
$result   = json_decode($response, true);

// 4. Handling Redirect
if (isset($result['success']) && $result['success'] === true) {
    header("Location: " . $result['checkout_url']);
    exit;
} else {
    echo "API Error: " . ($result['message'] ?? 'Unknown');
}
⚠️ Network Restriction: This service exclusively supports **USDT via TRON (TRC20)**. Sending funds via other networks like Ethereum (ERC20) or BSC (BEP20) will result in a permanent loss of funds.

Support

If you need help integrating with our API, please contact our support team.