Infinity Africa

API Reference

Payment Links API

Generate a secure, shareable checkout URL for a fixed amount — no website required on your end. Share it via SMS, WhatsApp, or email; the customer pays it on Infinity Africa's hosted checkout page.

Endpoints

POST/v1/payment-links

Create a payment link.

Idempotency-Key required
GET/v1/payment-links/{link_id}

Get a payment link (reports EXPIRED once expires_at has passed).

dashboard
PATCH/v1/payment-links/{link_id}/cancel

Cancel a link. Idempotent; rejects an already-PAID link.

dashboard
GET/public/payment-links/{public_slug}

Public checkout view — no auth. Always 200 for a slug that exists.

public
POST/public/payment-links/{public_slug}/collect

Customer pays the link. 409 if not ACTIVE.

public, Idempotency-Key required

Create a link

json — POST /v1/payment-links
{
  "merchant_id": "5c1f0b2a-3e21-4b9a-9c33-2f6a1d0e8b71",
  "amount": "25000.00",
  "currency": "TZS",
  "customer_name": "Grace Mwakalinga",
  "customer_phone": "+255754221908",
  "description": "Web design deposit",
  "allowed_payment_methods": ["USSD_PUSH", "STK_PUSH", "SELCOM_PESA_PUSH"],
  "expires_at": "2026-08-24T00:00:00Z"
}
json — 201 Created
{
  "success": true,
  "data": {
    "id": "a1b2c3d4-...",
    "merchant_id": "5c1f0b2a-3e21-4b9a-9c33-2f6a1d0e8b71",
    "amount": "25000.00",
    "currency": "TZS",
    "customer_name": "Grace Mwakalinga",
    "customer_phone": "+255754221908",
    "description": "Web design deposit",
    "allowed_payment_methods": ["USSD_PUSH", "STK_PUSH", "SELCOM_PESA_PUSH"],
    "expires_at": "2026-08-24T00:00:00Z",
    "status": "ACTIVE",
    "public_slug": "PLK-7X29QK",
    "public_url": "https://pay.infinityafrica.net/link/PLK-7X29QK",
    "created_at": "2026-08-14T09:00:00Z",
    "updated_at": "2026-08-14T09:00:00Z"
  }
}

Share public_url with your customer directly — it already points at Infinity Africa's hosted checkout page, so nothing else on your side needs to render a payment form.

Status lifecycle

StatusMeaning
ACTIVEPayable — the default state on creation.
PAIDA collection against this link succeeded. Terminal.
EXPIREDexpires_at has passed. Computed lazily on read, not by a background job.
CANCELLEDCancelled by the merchant before being paid.

Building your own checkout UI

If you'd rather render your own checkout page instead of redirecting to public_url, fetch the link's public details and let the customer choose a method and confirm from there:

json — GET /public/payment-links/PLK-7X29QK
{
  "success": true,
  "data": {
    "merchant_name": "Amani Store",
    "amount": "25000.00",
    "currency": "TZS",
    "description": "Web design deposit",
    "customer_name": "Grace Mwakalinga",
    "customer_phone": "+255754221908",
    "expires_at": "2026-08-24T00:00:00Z",
    "allowed_payment_methods": ["USSD_PUSH", "STK_PUSH", "SELCOM_PESA_PUSH"],
    "status": "ACTIVE"
  }
}
json — POST /public/payment-links/PLK-7X29QK/collect
{
  "method": "STK_PUSH",
  "customer_phone": "+255754221908"
}

This one resolves synchronously — the response comes back successful or failed in the same request, since the customer is watching the page.