API ReferencePayments

Payments

The Payments API lets you initiate, query, and refund payments across all supported providers. POPFAB handles routing, failover, and status normalization automatically.

Endpoints

POST/v1/payments
GET/v1/payments
GET/v1/payments/:id
POST/v1/payments/:id/sync
POST/v1/payments/:id/refund

Initiate a Payment

POST
/v1/payments

Creates a new payment and routes it to the best available provider.

Request headers

ParameterTypeRequiredDescription
AuthorizationstringRequiredBearer YOUR_API_KEY
Idempotency-KeystringRequiredA unique key per payment attempt (UUID or your order ID). Prevents duplicate charges if the request is retried.
Content-TypestringRequiredMust be application/json

Request body

ParameterTypeRequiredDescription
amountintegerRequiredAmount in the smallest currency unit (kobo for NGN, pesewas for GHS, etc.). Must be a positive integer.
currencystringRequiredISO 4217 currency code: NGN, GHS, KES, ZAR, UGX, XOF, USD.
payment_methodstringRequiredOne of: card, bank_transfer, ussd, mobile_money, qr.
referencestringRequiredYour unique payment reference. Alphanumeric, hyphens, and underscores only (a–z, A–Z, 0–9, -, _). Max 255 characters. Must be unique per merchant.
customerobjectRequiredCustomer object. Must include email. Optionally includes name and phone.
customer.emailstringRequiredCustomer's email address.
customer.namestringOptionalCustomer's full name.
customer.phonestringOptionalCustomer's phone number.
routing_overridestringOptionalForce a specific provider, bypassing routing rules: paystack, flutterwave, monnify, squad, interswitch, payaza.
callback_urlstringOptionalAbsolute URL to return the customer to after a redirect-based flow. Use HTTPS in production.
metadataobjectOptionalUp to 20 key-value pairs of string:string. Stored on the payment and returned in webhook events.
Example requestbash
curl -X POST https://api.popfab.io/v1/payments \
  -H "Authorization: Bearer sk_test_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order_abc123_v1" \
  -d '{
    "amount": 150000,
    "currency": "NGN",
    "payment_method": "card",
    "reference": "MYAPP-ORDER-7890",
    "customer": {
      "email": "ada@example.com",
      "name": "Ada Okafor",
      "phone": "+2348012345678"
    },
    "metadata": {
      "order_id": "7890",
      "plan": "premium"
    }
  }'
200 OK — Payment objectjson
{
  "id": "ppfb_pay_01HX9T2KBQM4Z3YWN5E6R7VP8S",
  "merchant_id": "ppfb_merch_01HX8W7K4YR6E9N2M3Q5T1ABCD",
  "idempotency_key": "order_abc123_v1",
  "reference": "MYAPP-ORDER-7890",
  "amount": 150000,
  "currency": "NGN",
  "payment_method": "card",
  "status": "pending",
  "provider": "paystack",
  "provider_reference": "psk_T8x29kLMqpn",
  "checkout_url": "https://checkout.paystack.com/abc123",
  "customer": {
    "email": "ada@example.com",
    "name": "Ada Okafor",
    "phone": "+2348012345678"
  },
  "metadata": { "order_id": "7890", "plan": "premium" },
  "fees": {
    "popfabFee": 225,
    "providerFee": 375,
    "totalFee": 600
  },
  "routing_context": {
    "strategy": "cost_optimizer",
    "providersConsidered": ["paystack", "flutterwave"],
    "selectedProvider": "paystack",
    "selectionReason": "lowest_cost",
    "attempts": [
      {
        "provider": "paystack",
        "attemptedAt": "2025-03-19T10:23:45.000Z",
        "outcome": "success",
        "latencyMs": 284
      }
    ]
  },
  "failure_reason": null,
  "created_at": "2025-03-19T10:23:45.000Z",
  "updated_at": "2025-03-19T10:23:45.000Z"
}

Payment response fields

ParameterTypeRequiredDescription
idstringRequiredThe POPFAB payment ID. Use this ID to retrieve, synchronize, or refund the payment.
merchant_idstringRequiredThe POPFAB merchant ID that owns the payment.
idempotency_keystringRequiredThe idempotency key supplied when the payment was initiated.
referencestringRequiredThe unique merchant reference supplied in the request.
amountintegerRequiredPayment amount in the currency's smallest unit.
currencystringRequiredISO 4217 currency code.
payment_methodstringRequiredPayment method selected for the transaction.
statusstringRequiredCurrent normalized payment status.
providerstring | nullOptionalProvider selected by POPFAB. It can be null before routing completes.
provider_referencestring | nullOptionalThe payment reference assigned by the selected provider.
checkout_urlstring | nullOptionalHosted authorization URL. When present, redirect the customer here to complete payment.
customerobjectRequiredCustomer details supplied when the payment was initiated.
metadataobject | nullOptionalMerchant metadata supplied in the request.
feesobject | nullOptionalFee breakdown when available.
routing_contextobject | nullOptionalProvider-routing and failover information when routing has completed.
failure_reasonstring | nullOptionalNormalized failure reason when the payment fails.
created_atstringRequiredISO 8601 creation timestamp.
updated_atstringRequiredISO 8601 timestamp of the latest update.
checkout_url is conditional. Hosted card and redirect flows normally return one, while methods such as bank transfer or USSD may instead rely on method-specific instructions. Redirect the customer only when the field is present. A browser redirect is not proof of payment; confirm the final status using a webhook or by retrieving the payment.

List Payments

GET
/v1/payments

Returns a cursor-paginated list of payments for your merchant account, newest first.

Query parameters

ParameterTypeRequiredDescription
statusstringOptionalFilter by status: pending, processing, success, failed, reversed, expired.
providerstringOptionalFilter by the selected provider, for example paystack or flutterwave.
limitintegerOptionalNumber of results per page. Default 25, max 100.
cursorstringOptionalPagination cursor from a previous response next_cursor field. Treat it as an opaque value.
List successful paymentsbash
curl "https://api.popfab.io/v1/payments?status=success&limit=50" \
  -H "Authorization: Bearer sk_test_YOUR_API_KEY"
Responsejson
{
  "data": [
    { "id": "ppfb_pay_...", "status": "success", ... },
    { "id": "ppfb_pay_...", "status": "success", ... }
  ],
  "next_cursor": "eyJpZCI6InBwZmJfcGF5XyJ9",
  "has_more": true
}

Get a Payment

GET
/v1/payments/:id

Retrieves the current state of a payment by its POPFAB ID or your merchant reference.

Get payment by IDbash
curl https://api.popfab.io/v1/payments/ppfb_pay_01HX9T2KBQM4Z3YWN5E6R7VP8S \
  -H "Authorization: Bearer sk_test_YOUR_API_KEY"

Synchronize Payment Status

POST
/v1/payments/:id/sync

Queries the selected provider and synchronizes the payment status.

ParameterTypeRequiredDescription
forcebooleanOptionalSet to true to recheck a failed or expired payment. Successful and reversed payments are never re-queried.
Synchronize a pending paymentbash
curl -X POST https://api.popfab.io/v1/payments/ppfb_pay_01HX9T2KBQM4Z3YWN5E6R7VP8S/sync \
  -H "Authorization: Bearer sk_test_YOUR_API_KEY"
Normal integrations should use webhooks and GET /v1/payments/:id. Use this endpoint for explicit reconciliation when you need an immediate provider check. The response includes asynced boolean and may include a reason when no update was made.

Refund a Payment

POST
/v1/payments/:id/refund

Initiates a full or partial refund for a payment with status success.

ParameterTypeRequiredDescription
amountintegerOptionalAmount to refund in the smallest currency unit. Omit for a full refund.
reasonstringOptionalReason for the refund. Max 500 characters. Stored for audit purposes.
Partial refund of ₦500 (50000 kobo)bash
curl -X POST https://api.popfab.io/v1/payments/ppfb_pay_01HX9T2K/refund \
  -H "Authorization: Bearer sk_test_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 50000,
    "reason": "Customer request — partial return"
  }'

Payment Statuses

StatusDescription
pendingRequest received. Awaiting routing and provider processing.
processingRouted to a provider. Awaiting confirmation from the provider.
successPayment confirmed by the provider. Value delivered.
failedPayment was declined or could not be completed by any provider.
reversedA refund or reversal has been successfully processed.
expiredThe provider authorization or payment window expired before completion.
payment.pending_confirmation is a webhook event emitted while a provider confirmation is outstanding. It is not a value returned in the payment object's status field.

Idempotency

The Idempotency-Key header is required on all POST /v1/payments requests. It ensures that retrying a failed network request does not result in a duplicate charge.

If you send a second request with the same Idempotency-Key, POPFAB returns the original payment object without creating a new one. Keys expire after 24 hours. If you receive a 409 IDEMPOTENCY_CONFLICT, the key was used with a different request body — generate a new key.