InfinityPay

API Reference

Dynamic QR API

Generate a scannable QR code for a specific amount — no customer phone number required. Good for in-person checkouts, printed receipts, or a payment screen a customer scans with any mobile money app.

Endpoint

POST/v1/collections/qr

Generate a Dynamic QR collection.

API key or dashboard

Authentication

Call this endpoint from your own backend with an API key that has the collections:write scope, or from the dashboard (signed-in session). Generate a key on the dashboard — see API Key Authentication.

bash — cURL
curl -X POST https://api.infinitypay.me/v1/collections/qr \
  -H "Authorization: Bearer sk_live_xxxxxxxxxxxxx" \
  -H "Idempotency-Key: 6f1e2a3b-..." \
  -H "Content-Type: application/json" \
  -d '{
    "amount": "15000.00",
    "currency": "TZS",
    "reference": "ORDER-4821"
  }'

Response

Unlike a push collection, no customer_phone is required. You get back a payment_token and a qr_payload — render the payload as a QR code with any client-side QR library.

json — 202 Accepted
{
  "success": true,
  "data": {
    "collection_id": "2d4f8a91-6c7b-4e55-91a8-7d3f2b1c9e04",
    "reference": "ORDER-4821",
    "status": "processing",
    "payment_token": "9f2bc4d1e8a7b3c6",
    "qr_payload": "https://checkout.selcom.net/t/9f2bc4d1e8a7b3c6",
    "expires_at": null
  }
}

expires_at is always null. Selcom's own response carries no expiry for a QR or token, so InfinityPay does not invent one — do not assume the code is time-limited, and do not build a countdown on this field. No server-rendered QR image is produced either; render qr_payload yourself.

Resolving a scan

A QR collection starts as processing and resolves once the customer scans and confirms. Listen for collection.success / collection.failed, or poll Transaction Status by reference. Never mark an order paid from the 202 — it means the code was created, not that anyone has paid.

There is no expiry to code against

Selcom returns no expiry for a QR, so expires_at is always null. If you need a code to stop being payable, track that yourself and generate a fresh collection — do not rely on this API to expire one for you.