Payment Processing API

This page documents the live public direct-payment surface served under https://api.gopiaxis.com/api.

Overview

The public payment routes are:

  • POST /api/payments/create

  • GET /api/payments/{payment_id}

  • GET /api/merchant-payments

Supported public payment methods for this surface are documented as:

  • mtn

  • airtel

  • card

  • piaxis_external

Public Contract Notes

The guaranteed create-payment request schema is intentionally smaller than some older long-form examples. The public typed request model guarantees these fields:

  • amount

  • currency

  • payment_method

  • user_info

  • products

  • customer_pays_fees

The route still accepts legacy recipient_id for backward compatibility. On the live public merchant-collection route, that field does not choose who gets credited; if sent, it must match the authenticated merchant Account.id.

The public typed create-payment response guarantees these fields:

  • payment_id

  • status

  • amount

  • currency

If you see richer examples elsewhere with fields such as reference, description, metadata, callback_url, send_sms, send_email, card_info, recurring, or split_config, treat those as deployment-specific extensions, not part of the default guaranteed public contract.

Merchant Collection Semantics

The authenticated merchant on this route is the credited collector.

That means:

  • the merchant identified by api-key is the account whose wallet is credited

  • omitting recipient_id still creates a valid merchant collection

  • if recipient_id is supplied, it must match the authenticated merchant Account.id

  • this route does not use recipient_id to choose a different collector or beneficiary

Use this route when a customer is paying the merchant or platform. Use the disbursement routes later if you want to send part of those collected funds out to a business owner, driver, freelancer, or other beneficiary.

Authentication

Use merchant API key authentication for server-to-server direct payments:

api-key: YOUR_MERCHANT_API_KEY
Content-Type: application/json

Use OAuth bearer authentication in addition to the merchant API key when the payment method is piaxis_external.

GET /api/merchant-payments is stricter than POST /api/payments/create and also requires the merchant client identifier header:

X-piaxis-Client-ID: YOUR_MERCHANT_CLIENT_ID

Creating Payments

POST /api/payments/create

Create a direct payment.

JSON Parameters:
  • amount (number) – Payment amount

  • currency (string) – ISO currency code

  • payment_method (string) – Payment method identifier

  • recipient_id (string) – Legacy compatibility field

  • user_info (object) – Payer information for external-money flows (optional, but usually required for mtn, airtel, and card)

  • products (array) – Product payload used by some piaxis_external flows (optional)

  • customer_pays_fees (boolean) – Whether the payer absorbs transaction fees (optional)

New integrations should omit recipient_id. If supplied, it must equal the authenticated merchant Account.id and does not change who is credited on this route.

The route also accepts an optional mfa_code parameter for flows that require step-up verification.

Canonical mobile-money example

POST /api/payments/create HTTP/1.1
Host: api.gopiaxis.com
api-key: YOUR_API_KEY
Content-Type: application/json

{
  "amount": 50000,
  "currency": "UGX",
  "payment_method": "mtn",
  "customer_pays_fees": true,
  "user_info": {
    "phone_number": "+256700000000",
    "email": "[email protected]",
    "name": "Buyer Name"
  }
}

Legacy recipient_id compatibility

For the public merchant payment route:

  • the customer is charged through the requested payment method

  • the authenticated merchant is the credited receiver

  • new integrations should omit recipient_id entirely

  • if older integrations still send recipient_id, it must match the authenticated merchant Account.id

If your platform wants to hold the money first and pay the final beneficiary later, collect with this route or the escrow route, then call POST /api/disbursements after your own release or completion rules are satisfied.

Canonical piaxis_external example

POST /api/payments/create HTTP/1.1
Host: api.gopiaxis.com
api-key: YOUR_API_KEY
Authorization: Bearer YOUR_ACCESS_TOKEN
Content-Type: application/json

{
  "amount": 75000,
  "currency": "UGX",
  "payment_method": "piaxis_external",
  "products": [
    {
      "product_id": "7c8b7cbe-4d52-4097-9fb2-858be26f5338",
      "quantity": 1
    }
  ]
}

Guaranteed create response

{
  "payment_id": "f530533e-3761-4cde-9c9d-88c5be6493bb",
  "status": "pending",
  "amount": "50,000.00",
  "currency": "UGX"
}

Fee Handling

customer_pays_fees controls who absorbs transaction fees:

  • true: the payer is charged the purchase amount plus fees

  • false: the payer is charged the purchase amount and the merchant absorbs the fee

  • omitted: the merchant default configuration applies

Payment Details

GET /api/payments/{payment_id}

Fetch a single payment record.

Parameters:
  • payment_id – Payment UUID

Guaranteed response fields

Field

Meaning

id

Payment id

status

Current payment status

amount

Payment amount

currency

Currency code

payment_method

Payment method used

created_at

Creation timestamp

reference

Merchant reference if available

receipt

Receipt identifier if available

merchant_details

Merchant details object if available

recipient_details

Recipient details object if available

product_details

Product details object if available

chain_payment_details

Chain payment details object if available

transaction_details

Provider transaction details if available

Example

GET /api/payments/f530533e-3761-4cde-9c9d-88c5be6493bb HTTP/1.1
Host: api.gopiaxis.com
api-key: YOUR_API_KEY

Merchant Payment Listing

GET /api/merchant-payments

List payments for the authenticated merchant.

Query Parameters:
  • status (string) – Filter by payment status

  • payment_method (string) – Filter by payment method

  • from_date (string) – Lower date bound (ISO 8601)

  • to_date (string) – Upper date bound (ISO 8601)

  • limit (int) – Page size, maximum 100

  • offset (int) – Offset for pagination

Example

GET /api/merchant-payments?status=completed&payment_method=mtn&limit=50&offset=0 HTTP/1.1
Host: api.gopiaxis.com
api-key: YOUR_API_KEY

Representative response shape

{
  "total": 1,
  "offset": 0,
  "limit": 50,
  "results": [
    {
      "payment_id": "f530533e-3761-4cde-9c9d-88c5be6493bb",
      "status": "completed",
      "amount": "50,000.00",
      "currency": "UGX",
      "payment_method": "mtn",
      "date": "2026-01-15T10:30:00Z",
      "payer": {
        "id": "a6f63e42-9e7b-4f4d-a693-4c9fd8cf58e7",
        "email": "[email protected]",
        "type": "registered",
        "phone": "+256700000000"
      },
      "recipient": {
        "id": "096b723a-45c5-4957-94d7-747835136265",
        "email": "[email protected]"
      }
    }
  ]
}

Canonical Flows

Server-to-server mobile money

  1. Collect the payer phone number or email.

  2. Call POST /api/payments/create.

  3. Persist the returned payment_id.

  4. Poll GET /api/payments/{payment_id} or consume webhooks.

piaxis_external payment

  1. Redirect the user through GET /api/authorize.

  2. Exchange the returned code through POST /api/token.

  3. Call POST /api/payments/create with Authorization: Bearer ....

Marketplace mapping example

If you run a platform such as JetsLab and each business has its own Piaxis merchant account, authenticate collections as the merchant that should collect. Do not use recipient_id on this route to switch the collector.

Keep any trusted mapping for later payout use cases instead.

Your platform business id

Piaxis account id

Use in API

biz_jetslab_restaurant_001

096b723a-45c5-4957-94d7-747835136265

authenticated merchant account for collection

biz_jetslab_store_002

8d1d6c7e-6ad6-40a3-9714-d1e6ab63e3aa

recipients[].recipient_id on later internal disbursements

Do not let end-user input pick raw Piaxis recipient ids directly.

Refunds

The current public paymentAPI router does not expose a default refund endpoint under /api.

If your deployment exposes refund tooling elsewhere, treat that as deployment- specific and not part of the guaranteed public contract documented on this page.

Implementation Examples

Python

import os
import requests


class PiaxisPayments:
    def __init__(self, api_key: str) -> None:
        self.base_url = "https://api.gopiaxis.com"
        self.headers = {
            "api-key": api_key,
            "Content-Type": "application/json",
        }

    def create_payment(self, payload: dict) -> dict:
        response = requests.post(
            f"{self.base_url}/api/payments/create",
            json=payload,
            headers=self.headers,
            timeout=30,
        )
        response.raise_for_status()
        return response.json()

    def get_payment(self, payment_id: str) -> dict:
        response = requests.get(
            f"{self.base_url}/api/payments/{payment_id}",
            headers=self.headers,
            timeout=30,
        )
        response.raise_for_status()
        return response.json()

    def list_payments(self, **filters) -> dict:
        response = requests.get(
            f"{self.base_url}/api/merchant-payments",
            params=filters,
            headers=self.headers,
            timeout=30,
        )
        response.raise_for_status()
        return response.json()


piaxis = PiaxisPayments(api_key=os.environ["PIAXIS_API_KEY"])

Node.js

const axios = require("axios");

class PiaxisPayments {
  constructor(apiKey) {
    this.baseUrl = "https://api.gopiaxis.com";
    this.headers = {
      "api-key": apiKey,
      "Content-Type": "application/json",
    };
  }

  async createPayment(payload) {
    const response = await axios.post(
      `${this.baseUrl}/api/payments/create`,
      payload,
      { headers: this.headers }
    );
    return response.data;
  }

  async getPayment(paymentId) {
    const response = await axios.get(
      `${this.baseUrl}/api/payments/${paymentId}`,
      { headers: this.headers }
    );
    return response.data;
  }

  async listPayments(filters = {}) {
    const response = await axios.get(
      `${this.baseUrl}/api/merchant-payments`,
      { headers: this.headers, params: filters }
    );
    return response.data;
  }
}