IX Infinexpay
Try it live
API v2 · M-Pesa, Cards & Crypto

One API to collect, hold, and pay out money across Kenya.

Infinexpay wraps STK Push, card checkout, wallet payouts and stablecoin deposits in a single JSON API — built for developers who'd rather ship than integrate five different gateways.

SAMPLE SETTLEMENT · KES 100.00 STK PUSH api/v2/stkpush.php
Gross amount
100.00 KES
Processing fee
1.50 KES
Net settled
98.50 KES
Status
completed
01 · Overview

Introduction

The Infinexpay Payment Gateway API lets you collect M-Pesa STK Push payments, run card and crypto checkouts, and send payouts, all from a consistent JSON interface. This page covers configuration, request/response shapes, and a live sandbox for each endpoint.

Base URL

Every endpoint below is relative to:

https://www.infinexpay.co.ke.gazelleusacompany.com/api/v2/

Response format

Every response is JSON with a consistent top-level shape:

JSON
{
  "success": true|false,
  "message": "Descriptive message"
  // additional fields depend on the endpoint
}
02 · Security

Authentication

Every request is authenticated with an API key/secret pair, sent as headers. Generate and rotate these from your merchant dashboard — never expose the secret in client-side code.

Required headers
X-API-Key: your_api_key
X-API-Secret: your_api_secret
Content-Type: application/json
Keep secrets server-side

Route all API calls through your backend. If a key is ever exposed publicly, rotate it immediately from the dashboard.

03 · Quickstart

Initiate your first payment

  1. Create an account on the Infinexpay dashboard.
  2. Generate an API key and secret.
  3. Set up at least one payment account.
PHP
function initiatePayment($apiKey, $apiSecret, $paymentAccountId, $phone, $amount, $reference, $description) {
    $url = "https://www.infinexpay.co.ke.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);
    curl_close($ch);

    return json_decode($response, true);
}

$result = initiatePayment("your_api_key", "your_api_secret", 14, "254712345678", 100, "ORDER123", "Test payment");

if ($result['success']) {
    echo "Checkout Request ID: " . $result['checkout_request_id'];
} else {
    echo "Error: " . $result['message'];
}

04 · Reference

Endpoints

Six endpoints cover the full money-movement lifecycle: collect via STK Push, check status, list history, top up your wallet, pay customers out, and accept stablecoin deposits.

Prompts a customer's phone with an M-Pesa STK Push dialog for the given amount.

POST/stkpush.php
ParameterTypeRequiredDescription
payment_account_idIntegerYesYour payment account ID
phoneStringYesCustomer number, e.g. 254712345678
amountFloatYesPayment amount, minimum 1 KES
referenceStringNoYour internal reference for the transaction
descriptionStringNoDescription shown in your records
Success · 200 OK
{
  "success": true,
  "message": "STK push sent successfully",
  "checkout_request_id": "ws_CO_20260101120000_abc123",
  "merchant_request_id": "ws_MR_20260101120000_xyz789"
}

Checks the status of a payment using the checkout_request_id returned from STK Push.

POST/status.php
ParameterTypeRequiredDescription
checkout_request_idStringYesID returned by the STK Push response
Success · 200 OK
{
  "success": true,
  "status": "completed",
  "amount": 100,
  "phone": "254712345678",
  "transaction_code": "ABC123DEF456",
  "created_at": "2026-01-01 12:00:00"
}

Status values

pending  initiated, awaiting PIN entry  ·  completed  funds received  ·  failed  cancelled or timed out

Returns a paginated list of your transactions.

GET/transactions.php?page=1&limit=10
ParameterTypeRequiredDescription
pageIntegerNoPage number · default 1
limitIntegerNoItems per page · max 100, default 10
Success · 200 OK
{
  "success": true,
  "data": [
    {
      "id": 123,
      "amount": 100,
      "status": "completed",
      "phone": "254712345678",
      "transaction_code": "ABC123DEF456",
      "fee_amount": 1.5,
      "type": "API",
      "created_at": "2026-01-01 12:00:00",
      "completed_at": "2026-01-01 12:02:30"
    }
  ],
  "pagination": {
    "current_page": 1,
    "per_page": 10,
    "total_items": 150,
    "total_pages": 15
  }
}

Deposits funds into your Infinexpay service wallet via STK Push. A processing fee is deducted from your service balance for each transaction.

POST/topup.php
ParameterTypeRequiredDescription
phoneStringYesNumber to receive the STK Push prompt
amountFloatYesDeposit amount in KES, must be > 0

Response modes

If the customer enters their PIN within a few seconds the response resolves synchronously; otherwise it falls back to pending until the carrier callback arrives.

Synchronous success
{
  "success": true,
  "status": "completed",
  "transaction_id": "QGR45TX79K",
  "amount_added": 100.00,
  "fee_deducted": 6.00
}
Pending · awaiting PIN
{
  "success": true,
  "status": "pending",
  "checkout_request_id": "ws_CO_18052026023512345678"
}
Insufficient service balance

If your service balance can't cover the processing fee, the request fails with success: false and a message telling you the top-up amount needed.

Sends a Business-to-Customer (B2C) disbursement from your service wallet to any M-Pesa number.

POST/payout.php
ParameterTypeRequiredDescription
phoneStringYesRecipient number, e.g. 254712345678
amountFloatYesAmount to disburse · minimum 25.00 KES
referenceStringNoYour unique ID for tracking the payout
Python
import requests

url = "https://www.infinexpay.co.ke.gazelleusacompany.com/api/v2/payout.php"
headers = {
    "X-API-Key": "your_api_key",
    "X-API-Secret": "your_api_secret",
    "Content-Type": "application/json"
}
data = {
    "phone": "254712345678",
    "amount": 150.0,
    "reference": "PY_REF_101"
}

response = requests.post(url, json=data, headers=headers)
print(response.json())
Success · 200 OK
{
  "success": true,
  "message": "Payout successful",
  "transaction_id": "OP_PAY_881272",
  "amount_sent": 142.50,
  "fee_deducted": 7.50
}

Accepts USDT deposits and settles the KES-equivalent value into your service wallet automatically.

POST/crypto_deposit.php
ParameterTypeRequiredDescription
amountFloatYesDeposit amount in USD
order_idStringYesUnique identifier for this deposit
Success · 200 OK
{
  "success": true,
  "checkout_url": "https://infinexpay.co.ke/checkout/crypto/secure_frame"
}
Network restriction

This endpoint only supports USDT on the TRON network (TRC20). Deposits sent via Ethereum (ERC20) or BSC (BEP20) cannot be recovered.


05 · Async

Webhooks

Once a payout or deposit settles, Infinexpay posts the result to the webhook URL configured in your dashboard.

Webhook payload
{
  "status": "success",
  "transaction_id": "OP_PAY_881272",
  "mpesa_receipt": "RBC9982XX",
  "amount": 150.00,
  "phone": "254712345678",
  "reference": "ORDER_9921",
  "timestamp": "2026-03-20 10:15:00"
}
Handling it · PHP
$input = file_get_contents('php://input');
$data = json_decode($input, true);

if (isset($data['status']) && $data['status'] === 'success') {
    // mark the matching $data['reference'] as paid in your database
    http_response_code(200);
    echo json_encode(["message" => "Acknowledged"]);
}

06 · Reference

Error handling

Standard HTTP status codes indicate success or failure.

CodeMeaning
200Success
400Bad request · invalid parameters
401Unauthorized · invalid API credentials
404Not found · resource doesn't exist
405Method not allowed
500Internal server error

Common error messages

  • Insufficient service balance — top up your account to cover transaction fees
  • Invalid payment account ID — check the ID you passed
  • Transaction not found — the checkout_request_id doesn't exist
  • Missing required parameter — a required field wasn't sent

07 · Try it

Live sandbox

Test STK Push, status checks, and transaction listing against your own credentials, right from this page.

Results will appear here once you run a test.
08 · Help

Support

Need a hand integrating? Reach out and we'll help you get unstuck.