Skip to main content
Direct Charge allows your backend to initiate payment directly with a provider, without first creating a checkout URL.

When To Use Direct Charge

Backend-Driven Flows

Best for server-to-server payment initiation where you control the full transaction lifecycle.

Provider-Specific Inputs

Use when payment requires provider-specific fields like network or customer OTP codes.

Recurring / Embedded UX

Useful for tightly integrated experiences where redirect checkout is not preferred.

Endpoints

MethodEndpointPurpose
GET/payments/v1/payments/direct-charge/{provider}/propertiesFetch provider-specific properties (optional for some providers)
POST/payments/v1/payments/direct-chargeInitiate direct charge
GET/payments/v1/payments/verify/{reference}Verify final transaction status

Integration Steps

1

Pick provider slug

Select a valid provider from Supported Providers.
2

Fetch provider properties (optional)

For providers like Pawapay, fetch required properties (for example network values) before charging.
3

Send direct charge request

Call the direct-charge endpoint with provider, amount, and customerInput.
4

Handle action + confirm final status

Use response action (processing, redirect, bank-transfer) and finalize based on webhook/verification.

Fetch Provider Properties (Optional)

curl --location 'https://sandbox-api.payfonte.com/payments/v1/payments/direct-charge/{provider}/properties' \
  --header 'client-id: <client-id>' \
  --header 'client-secret: <client-secret>'
Example response:
{
  "data": {
    "networks": [
      { "name": "Airtel", "value": "airtel" },
      { "name": "MTN MoMo", "value": "mtn-momo" }
    ]
  }
}

Direct Charge Request

curl --location 'https://sandbox-api.payfonte.com/payments/v1/payments/direct-charge' \
  --header 'client-id: <client-id>' \
  --header 'client-secret: <client-secret>' \
  --header 'Content-Type: application/json' \
  --data '{
    "reference": "ORDER-1001",
    "amount": 10000,
    "provider": "mtn-momo-ivory-coast",
    "webhook": "https://yourapp.com/webhooks/payfonte",
    "narration": "Order payment",
    "customerInput": {
      "phoneNumber": "2250512345678"
    }
  }'
Sample response:
{
  "data": {
    "action": "processing",
    "sessionId": "1031-4120-a98f-9357692945",
    "provider": "mtn-momo-ivory-coast",
    "channel": "mobile-money",
    "reference": "ORDER-1001",
    "amount": 10000,
    "status": "pending",
    "statusDescription": "Awaiting Provider's Feedback"
  },
  "statusCode": 201
}

Request Fields

FieldTypeRequiredDescription
providerstringYesProvider slug (for example mtn-momo-ivory-coast)
amountintegerYesAmount in minor units (no decimals)
customerInputobjectYesProvider/customer fields (for example phoneNumber)
referencestringRecommendedUnique merchant reference
webhookstringNoOverride webhook for this transaction
narrationstringNoTransaction description
metadataobjectNoCustom metadata returned downstream

Action Types and Handling

processing

Customer/provider interaction is in progress (for example USSD/STK authorization pending). Keep payment state pending and wait for webhook/verification final status.
Redirect customer to provider URL (usually at data.data.link). Do not treat redirect completion alone as payment success.
Display returned bank transfer instructions (account name/number, amount, expiry). Wait for webhook/verification before marking success.

Amount Rule (Important)

Payfonte does not support decimal amounts in API requests. Send integer minor-unit values only.
  • 100.00 NGN -> 10000
  • 2500.75 NGN -> 250075
See Amount Specification.

Final Status Confirmation

For order fulfillment, rely on:
  1. Webhooks for async payment updates.
  2. GET /payments/v1/payments/verify/{reference} for backend verification.

Direct Charge Flows

Understand processing, redirect, and pre-OTP patterns.

Example Payloads

Copy provider-specific request examples.

Supported Providers

Provider slugs, limits, and country coverage.