Product Document & Integration Manual · v1.0

CironetPay

The unified payment layer for the Cironet ecosystem. One gateway, one merchant identity, powering every product and client platform.

Version 1.0
8 Providers Integrated
Production Ready
pay.cironetug.com

What is CironetPay?

CironetPay is a centrally hosted payment gateway developed and operated by Cironet Technologies. It sits between the applications that need to accept payments (Nodes) and the payment service providers (PSPs) that process them. It acts as the single, unified layer through which all payment activity in the Cironet ecosystem flows.

For Cironet Products

Powers payments inside CironetSmart ERP, Marketplace, and Messaging through a single internal API — no provider logic needed in each product.

For Client Platforms

A drop-in payment layer for platforms Cironet builds for clients. Clients accept payments via MoMo and Cards instantly without separate PSP onboarding.

In one sentence: CironetPay is the payment backbone of the Cironet ecosystem — one gateway, one merchant account per provider, powering every product Cironet builds and every client platform Cironet delivers.

The Problem

Accepting digital payments in Uganda and across Africa is complex. Every PSP has its own API, authentication mechanism, sandbox environment, and webhook format. For a technology company operating multiple products and building platforms for various clients, this creates significant overhead:

The Solution

The "Node" Principle

Any application connects to CironetPay as a node. Nodes send requests to CironetPay and receive notifications when payments complete. The node never interacts with a payment provider directly.

CironetPay centralizes infrastructure, maintenance, and compliance. A bug fixed or provider added in CironetPay is immediately reflected across all connected products and clients.

How It Works

1

Initiation

Node POSTs a request to /api/initiate.php with amount, currency, and provider.

2

Engine Processing

CironetPay records a Pending transaction and selects the specific Gateway class.

3

Provider Action

The PSP processes the payment (USSD push for MoMo or redirect for Cards).

4

Webhook/Callback

PSP notifies CironetPay of the outcome. CironetPay updates the status to Completed or Failed.

5

Node Notification

CironetPay sends a signed webhook to the Node's registered callback URL to finalize the order.

Merchant Identity Model

CironetPay operates on a single-merchant, multi-source model. Payment providers only ever see traffic from Cironet Technologies.

PerspectiveWhat they seeWhy
Payment Providers One merchant: Cironet Technologies. Simplifies compliance and onboarding. Providers only deal with one trusted entity.
Inside CironetPay Every transaction is tagged with its node_source. Allows for granular per-product and per-client reporting, billing, and reconciliation.

Who It Serves

🏢

Cironet Products

Internal platforms owned by Cironet Technologies.

  • CironetSmart ERP — Invoice & payroll
  • CironetMarketplace — Storefront payments
  • CironetMessaging — Top-ups & billing
  • cironetug.com — Domains & hosting
🔌

Client Platforms

Solutions Cironet develops for external businesses.

  • SACCO & Microfinance systems
  • School Fees platforms
  • NGO Donor management
  • E-commerce custom builds

Core Capabilities

🔀
Multi-Provider Routing

Route to any of 8 PSPs via a single field in the API request.

🔐
Node Isolation

Every node has its own API key and isolated transaction history.

🔏
Signed Callbacks

HMAC-SHA256 signatures ensure Node-side webhook integrity.

📊
System-Wide Audit

Central ledger for all payments across the entire ecosystem.

Technical Architecture

Built with PHP 8.1+ on a standard LAMP stack. Hosted at pay.cironetug.com.

Component Overview

ComponentResponsibility
CironetPay EngineCore logic, database orchestration, and gateway selection.
GatewaysOne class per PSP (e.g., MtnGateway) handling API specifics.
API LayerREST-like endpoints for Initiation and Verification.
Webhook LayerReceives and normalizes provider notifications.

Installation & Setup

Database Schema

CironetPay requires two primary tables: transactions and nodes.

-- Core Transactions Table
CREATE TABLE transactions (
    id INT AUTO_INCREMENT PRIMARY KEY,
    transaction_ref VARCHAR(100) UNIQUE,
    external_id VARCHAR(100),
    node_source VARCHAR(50),
    merchant_id INT,
    provider VARCHAR(50),
    amount DECIMAL(20,2),
    currency VARCHAR(10),
    status ENUM('Pending', 'Completed', 'Failed', 'Cancelled'),
    provider_reference VARCHAR(255),
    raw_log JSON,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Configuration

All sensitive credentials live in the .env file. Never commit this file.

VariableDescription
DB_HOST / NAME / USER / PASSMySQL connection details
CIRONET_API_KEY_{NODE}Keys for internal product nodes
WEBHOOK_OUTGOING_SECRETSecret used to sign callbacks sent to nodes
{PSP}_API_KEY / SECRETCredentials for individual payment providers

Security: If a node's API key is compromised, it must be rotated immediately in both the .env file and the nodes table.

Database Schema Details

The nodes table is the source of truth for all authorized applications.

ColumnPurpose
node_nameSlug identifier (e.g., smart_erp_node)
api_keySecret key used in the X-CironetPay-Key header
webhook_urlNode endpoint where CironetPay sends payment results
statusActive or Suspended

Authentication

Every API request must include a valid key in the header:

X-CironetPay-Key: cp_live_smart_8823x91

API — Initiate Payment

POST /api/initiate.php

JSON Body:
{
  "amount": 50000,
  "currency": "UGX",
  "provider": "mtn",
  "external_id": "INV-101",
  "payer_data": { "phone": "25677..." }
}

API — Verify Status

GET /api/verify.php?provider={slug}&ref={provider_ref}

Checks current transaction status directly with the provider.

API — Webhook Receiver

POST /api/webhook.php?provider={slug}

This is the URL registered with PSPs. It receives raw notifications and forwards them to the Node.

Signature Security

CironetPay signs all outgoing webhooks using the WEBHOOK_OUTGOING_SECRET. Nodes must verify this signature to prevent spoofing.

// Node-side Verification (PHP)
$received_sig = $_SERVER['HTTP_X_CIRONETPAY_SIGNATURE'];
$payload = file_get_contents('php://input');
$expected_sig = hash_hmac('sha256', $payload, $secret);

if (!hash_equals($expected_sig, $received_sig)) {
    die("Invalid Signature");
}

Supported Providers

SlugProviderType
mtnMTN MoMoMobile Money (UG)
airtelAirtel MoneyMobile Money (UG)
yoYo! PaymentsMulti-MoMo (UG)
paypalPayPalCards/Global
pesapalPesaPalCard/MoMo (EA)
dpoDPO GroupCard/Pan-Africa
interswitchInterswitchCards
networkNetwork Intl.Cards

Client Onboarding

1

Key Generation

Generate a secure key using bin2hex(random_bytes(16)).

2

Node Registration

Insert the node name, key, and client callback URL into the nodes table.

3

Environment Config

Update the Node's application to use the new API key.

Troubleshooting

SymptomFix
401 UnauthorizedVerify the X-CironetPay-Key header matches the nodes table.
Stuck in PendingUse /api/verify.php to poll status manually. Check log for PSP errors.
Signature MismatchConfirm WEBHOOK_OUTGOING_SECRET is identical in both systems.

Roadmap