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 own payment page, where they choose Mobile Money Push, Selcom Pesa, or Scan QR / TanQR themselves. This is the same underlying resource POST /v1/collections (the Collections API's "Infinity Payment Page" flow) creates — use whichever endpoint shape fits your integration.
Selcom Hosted Checkout is not used
/pay/… page, not a redirect to Selcom's hosted checkout — that product is currently inactive platform-wide (see the Go-Live Checklist). A payment link's public_url always points at Infinity's own page.Endpoints
/v1/payment-linksCreate a payment link.
Idempotency-Key required/v1/payment-links/{link_id}Get a payment link (reports EXPIRED once expires_at has passed).
dashboard/v1/payment-links/{link_id}/cancelCancel a link. Idempotent; rejects an already-PAID link.
dashboard/public/payment-links/{public_slug}Public checkout view — no auth. Always 200 for a slug that exists.
public/public/payment-links/{public_slug}/collectCustomer pays the link. 409 if not ACTIVE.
public, Idempotency-Key requiredCreate a link
{
"merchant_id": "5c1f0b2a-3e21-4b9a-9c33-2f6a1d0e8b71",
"amount": "25000.00",
"currency": "TZS",
"customer_name": "Grace Mwakalinga",
"customer_phone": "+255754221908",
"description": "Web design deposit",
"expires_at": "2026-08-24T00:00:00Z"
}{
"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",
"expires_at": "2026-08-24T00:00:00Z",
"status": "ACTIVE",
"public_slug": "PLK-7X29QK",
"public_url": "https://pay.infinityafrica.net/pay/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's own payment page, so nothing else on your side needs to render a payment form. You don't choose which methods are accepted — the customer picks Mobile Money Push, Selcom Pesa, or Scan QR / TanQR themselves on that page.
Status lifecycle
| Status | Meaning |
|---|---|
| ACTIVE | Payable — the default state on creation. |
| PAID | A collection against this link succeeded. Terminal. |
| EXPIRED | expires_at has passed. Computed lazily on read, not by a background job. |
| CANCELLED | Cancelled 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, then call POST /public/payment-links/{public_slug}/pay once the customer picks a method:
{
"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",
"status": "ACTIVE"
}
}{
"method": "WALLET_PUSH",
"customer_phone": "+255754221908"
}method is one of WALLET_PUSH, SELCOM_PESA, or TANQR — same three methods documented on the Collections API page. The response comes back pending, not successful — poll GET /public/payment-links/{public_slug}/collections/{collection_id}/status or listen for the webhook, exactly like every other collection method.