Skip to content

Payment / Alternative payment methods / Africa / Bank Account

H2H#

POST https://payments.apipro.io/v2/payment

Introduction#

Bank account payment method allows you to charge money from a customer's bank account. For confirm charging founds using challenges: otp, pin, redirect and other.

Utilizing the REST setup, your website or application can quickly initiate requests to the API, enabling your customers to conveniently make purchases using bank_account_africa method.

How to start?#

  1. Prepare a Create Payment request (see the Request Body example on this page).

  2. Sign the request according to the Authentication & Signature rules.

  3. Send the request to: POST payments.apipro.io/v2/payment

  4. Parse the response:

    • check error_code

    • check status.name

    • follow the challenge instructions (see below)

  5. Wait for the callback with the final status (recommended) or use Check status endpoints.

Create a Bank Account payment#

There is you can find instructions how to make payment with bank account method.

Example Create Payment request#

POST payments.apipro.io/v2/payment

{
  "method": "bank_account_africa", // required
  "mode": "initial", // required, always "initial" for this method
  "reference": "order-00001", // required
  "currency": "NGN", // required
  "amount": 25.01, // required
  "description": "My order", // optional
  "bank_account_africa": { // required
    "account_number": "2215381176", // required
    "bank_code": "033", // required
    "bank_verification_number": "01234567899", // required
    "account_dob_day": "12", // required
    "account_dob_month": "12", // required
    "account_dob_year": "2012" // required
  },
  "customer": { // optional
    "identifier": "12345", // required, may be used any unique value from system of merchant
    "email": "user@example.com", // optional
    "first_name": "Darth", // optional
    "last_name": "Vader", // optional
    "middle_name": "Skywalker", // optional
    "phone": "2348035776359", // optional
    "itn": "X1234567890", // optional
    "country": "NG", // optional, ISO 3166-1
    "state_code": "LA", // optional, ISO 3166-2
    "city": "Lagos", // optional
    "address": "Thomas Animashaun Street, 2", // optional
    "zip_code": "100213", // optional
    "birthday": "2006-01-02", // optional
    "ip": "192.168.0.1", // optional
    "gender": "male" // optional
  },
  "redirect_url": "https://merchant.domain/customer_pending_page", // conditional
  "callback_url": "https://merchant.domain/callback", // conditional
  "extra": { // optional
    "meta": { // any field which may be needed for transaction routing and integration. Below is an example of parameters with available data types
      "meta_data1[min0, max255]": "text", // type: string
      "meta_data2[min1, max64]": 50, // type: int
      "meta_data3[min1, max64]": true, // type: boolean
      "meta_data4": "2024-02-20T14:00:00+02" // attention to datetime format: YYYY-MM-DDThh:mm:ss±hh. ISO 8601
    }
  }
}

Response handling (200 OK)#

  1. Check error_code

    • if error_code != 0 — the request failed (see error examples below)
  2. Check status.name

    • a non-final status (for example created / pending) means you must follow the challenge flow and then wait for the callback.

Challenge Types#

This is an action, which the user must complete to confirm chargins money from his bank account.

Redirect#

If you get challenge.challenge_type with value redirect then you should redirect your Customer to the URL in the field challenge.challenge_redirect.url.

After the Customer passes actions from specified page, they will be automatically redirected to the URL specified in the redirect_url field of your request.

OTP#

If you get challenge.challenge_type with value otp then you should ask the user to enter a code that will be sent to the specified email or phone number. If the user has not received the otp code, you can request re-sending the otp code, only one attempt available (attention, not available for all providers).

After the Customer passes otp challenge you need to create request to method which described below and handle the response of this method:

  • If status of transaction move to success or declined, this means that work with this transaction is completed and no further actions are not needed.

  • If status of transaction still in pending you need complete the following challenge, which described from this page (if challenge_type without changed, this means that the user entered incorrect data).

Complete otp challenge#

Request

Use the URL: https://payments.apipro.io/v2/payment/challenge/otp

{
  "reference": "order1111", // string, required
  "otp": "625424" // required
}

Response

{
  "error_code": 0,
  "error_reason": "",
  "identifier": "PM00000000FONI1",
  "request_id": "8f0b50db-7ede-4edb-b36c-8b5cffdf9310",
  "reference": "order-00001",
  "method": "bank_account_africa",
  "type": "payment",
  "mode": "initial",
  "currency": "NGN",
  "amount": "25.01",
  "status": "success",
  "bank_account": {
    "account_number": "2215381176",
    "bank_code": "033",
    "bank_verification_number": "01234567899",
    "account_dob_day": "12",
    "account_dob_month": "12",
    "account_dob_year": "2012"
  },
  "timestamp": "2024-04-01T18:08:24Z",
  "status_date": "2024-04-01T18:07:03Z"
}

Resend otp#

Request

Use the URL: https://payments.apipro.io/v2/payment/challenge/otp/resend

{  
   "reference": "order1111" // string, required
}

Response

{
  "error_code": 0,
  "error_reason": "",
  "identifier": "PM00000000FONI1",
  "request_id": "8f0b50db-7ede-4edb-b36c-8b5cffdf9310",
  "reference": "order-00001",
  "method": "bank_account_africa",
  "type": "payment",
  "mode": "initial",
  "currency": "NGN",
  "amount": "25.01",
  "status": "success",
  "bank_account": {
    "account_number": "2215381176",
    "bank_code": "033",
    "bank_verification_number": "01234567899",
    "account_dob_day": "12",
    "account_dob_month": "12",
    "account_dob_year": "2012"
  },
  "timestamp": "2024-04-01T18:08:24Z",
  "status_date": "2024-04-01T18:07:03Z"
}

PIN#

If you get challenge.challenge_type with value pin then you should ask the user to enter a pin code of his bank account.

After the Customer passes pin challenge you need to create request to method which described below and handle the response of this method:

  • If status of transaction move to success or declined, this means that work with this transaction is completed and no further actions are not needed.

  • If status of transaction still in pending you need complete the following challenge, which described from this page (if challenge_type without changed, this means that the user entered incorrect data).

Complete pin challenge#

Request

{
  "reference": "order1111", // string, required
  "pin": "4214" // string, required
}

Request

{
  "error_code": 0,
  "error_reason": "",
  "identifier": "PM00000000FONI1",
  "request_id": "8f0b50db-7ede-4edb-b36c-8b5cffdf9310",
  "reference": "order-00001",
  "method": "bank_account_africa",
  "type": "payment",
  "mode": "initial",
  "currency": "NGN",
  "amount": "25.01",
  "status": "success",
  "bank_account": {
    "account_number": "2215381176",
    "bank_code": "033",
    "bank_verification_number": "01234567899",
    "account_dob_day": "12",
    "account_dob_month": "12",
    "account_dob_year": "2012"
  },
  "timestamp": "2024-04-01T18:08:24Z",
  "status_date": "2024-04-01T18:07:03Z"
}

Headers#

Header Value
Content-Type application/json
Authorization {{authorization}}
Digest {{digest}}
Host {{host}}
Date {{date}}

See Authentication & Signature for how to build the signed headers.

Request body#

Annotations in the example are the field requirements: required, optional or conditional. Comments are stripped automatically by the Postman collection before signing; remove them in your own requests.

{
    "reference": "AfricaBankTransferH2H#1", // required, unique
    "currency": "NGN", // required
    "amount": 876, // required
    "description": "My order h2h", // optional
    "customer": // required
    {
        "identifier": "1111-1111-2211-2211", // required, any unique value from the merchant's system may be used.
        "email": "juancarloos@hotmail.com", // required
        "phone": "+2348031234567", // optional, Nigerian format number 
        "first_name": "Juan", // required
        "last_name": "Garcisa Rodriiguez", // required
        "middle_name": "Carlos", // optional
        "country": "NG", // optional, Nigeria (ISO 3166-1 country code for Nigeria)
        "state_code": "B", // optional
        "city": "Buenos Aires", // optional
        "address": "Calle Emilio Mitre 3256", // optional
        "zip_code": "C1407", // optional
        "itn": "2526232527", // conditional
        "birthday": "2006-01-02", // optional
        "ip": "192.168.0.1", // optional
        "gender": "male" // optional
    },
    "method": "bank_transfer_africa", // required, snake_case / lower case only: "bank_transfer_africa" (not "BANK_TRANSFER_AFRICA" or "BankTransferAfrica")
    "redirect_url": "redirect-url", // optional
    "cancel_url": "cancel_url", // optional
    "callback_url": "callback_url", // conditional
    "extra": { // conditional, any field which may be needed for transaction routing and integration
        "meta": {
            "key": "value"
        }
    }
}

Fields#

Field Type Requirement / note
reference string required, unique
currency string required
amount integer required
description string optional
customer object required
customer.identifier string required, any unique value from the merchant's system may be used.
customer.email string required
customer.phone string optional, Nigerian format number
customer.first_name string required
customer.last_name string required
customer.middle_name string optional
customer.country string optional, Nigeria (ISO 3166-1 country code for Nigeria)
customer.state_code string optional
customer.city string optional
customer.address string optional
customer.zip_code string optional
customer.itn string conditional
customer.birthday string optional
customer.ip string optional
customer.gender string optional
method string required, snake_case / lower case only: "bank_transfer_africa" (not "BANK_TRANSFER_AFRICA" or "BankTransferAfrica")
redirect_url string optional
cancel_url string optional
callback_url string conditional
extra object conditional, any field which may be needed for transaction routing and integration
extra.meta object
extra.meta.key string

Responses#

Response Examples

Merchant not found
{
  "error_code": 35,
  "error_reason": "Merchant not found",
  "description": "The requested resource is undefined",
  "request_id": "YOUR_REFERENCE",
  "status": "error",
  "timestamp": "2025-10-26T14:01:00.00Z"
}
Required fields are missing: method or widget.method, reference
{
  "error_code": 31,
  "error_reason": "Required fields are missing: method or widget.method, reference",
  "timestamp": "2025-10-26T14:03:00.00Z"
}
Using 'method' and 'widget.method' at the same time.
{
  "error_code": 30,
  "error_reason": "Invalid params",
  "description": "Widget and method cannot be used together",
  "request_id": "YOUR_REFERENCE",
  "status": "error",
  "timestamp": "2025-10-26T14:04:00.00Z"
}
Card can only be used with specific methods. Check documentation
{
  "error_code": 30,
  "error_reason": "Invalid params",
  "description": "Card can only be used with specific methods. Check documentation",
  "request_id": "YOUR_REFERENCE",
  "status": "error",
  "timestamp": "2025-10-26T14:05:00.00Z"
}
Customer is blocked
{
  "error_code": 451,
  "error_reason": "General risk decline",
  "description": "Customer is blocked",
  "request_id": "YOUR_REFERENCE",
  "status": "error",
  "timestamp": "2025-10-26T14:06:00.00Z"
}
Customer is blocked for all merchant projects
{
  "error_code": 451,
  "error_reason": "General risk decline",
  "description": "Customer is blocked for all merchant projects",
  "request_id": "YOUR_REFERENCE",
  "status": "error",
  "timestamp": "2025-10-26T14:08:02.00Z"
}
Customer is blocked for the specified project
{
  "error_code": 451,
  "error_reason": "General risk decline",
  "description": "Customer is blocked for the specified project",
  "request_id": "YOUR_REFERENCE",
  "status": "error",
  "timestamp": "2025-10-26T14:08:04.00Z"
}
Customer is blocked system-wide
{
  "error_code": 451,
  "error_reason": "General risk decline",
  "description": "Customer is blocked system-wide",
  "request_id": "YOUR_REFERENCE",
  "status": "error",
  "timestamp": "2025-10-26T14:08:06.00Z"
}
Customer is globally locked
{
  "error_code": 451,
  "error_reason": "General risk decline",
  "description": "Customer is globally locked",
  "request_id": "YOUR_REFERENCE",
  "status": "error",
  "timestamp": "2025-10-26T14:08:08.00Z"
}
Timeout while requesting routing
{
  "error_code": 121,
  "error_reason": "An issue has been detected in the routing settings. For instance, it could be due to a disabled project or bank",
  "description": "Routing request timeout",
  "request_id": "YOUR_REFERENCE",
  "status": "error",
  "timestamp": "2025-10-26T14:08:01.00Z"
}
Payment transaction timeout after some time
{
  "error_code": 121,
  "error_reason": "An issue has been detected in the routing settings. For instance, it could be due to a disabled project or bank",
  "description": "Payment transaction timeout after 30 seconds",
  "request_id": "YOUR_REFERENCE",
  "status": "error",
  "timestamp": "2025-10-26T14:08:03.00Z"
}
Unknown routing error
{
  "error_code": 121,
  "error_reason": "An issue has been detected in the routing settings. For instance, it could be due to a disabled project or bank",
  "description": "Unknown routing error",
  "request_id": "YOUR_REFERENCE",
  "status": "error",
  "timestamp": "2025-10-26T14:08:02.00Z"
}
Payment transaction was cancelled
{
  "error_code": 121,
  "error_reason": "An issue has been detected in the routing settings. For instance, it could be due to a disabled project or bank",
  "description": "Payment transaction was cancelled",
  "request_id": "YOUR_REFERENCE",
  "status": "error",
  "timestamp": "2025-10-26T14:08:04.00Z"
}
Internal error: Data is empty
{
  "error_code": 121,
  "error_reason": "An issue has been detected in the routing settings. For instance, it could be due to a disabled project or bank",
  "description": "Internal error: Value cannot be null. (Parameter 'data')",
  "request_id": "YOUR_REFERENCE",
  "status": "error",
  "timestamp": "2025-10-26T14:08:05.00Z"
}
Endpoint type wasn't found
{
  "error_code": 121,
  "error_reason": "An issue has been detected in the routing settings. For instance, it could be due to a disabled project or bank",
  "description": "Internal error: Endpoint type cannot be null or empty (Parameter 'endpointType')",
  "request_id": "YOUR_REFERENCE",
  "status": "error",
  "timestamp": "2025-10-26T14:08:06.00Z"
}
Mid configuration error
{
  "error_code": 121,
  "error_reason": "An issue has been detected in the routing settings. For instance, it could be due to a disabled project or bank",
  "description": "Internal error: Mid [Mid ID] no longer exists in configuration",
  "request_id": "YOUR_REFERENCE",
  "status": "error",
  "timestamp": "2025-10-26T14:08:07.00Z"
}
Routing service error: Converting data error
{
  "error_code": 121,
  "error_reason": "An issue has been detected in the routing settings. For instance, it could be due to a disabled project or bank",
  "description": "Routing service error: The JSON value could not be converted to System.Guid.",
  "request_id": "YOUR_REFERENCE",
  "status": "error",
  "timestamp": "2025-10-26T14:08:08.00Z"
}
Routing service error
{
  "error_code": 121,
  "error_reason": "An issue has been detected in the routing settings. For instance, it could be due to a disabled project or bank",
  "description": "Routing service error",
  "request_id": "YOUR_REFERENCE",
  "status": "error",
  "timestamp": "2025-10-26T14:08:08.00Z"
}
Broker transport failure
{
  "error_code": 121,
  "error_reason": "An issue has been detected in the routing settings. For instance, it could be due to a disabled project or bank",
  "description": "Internal error: Broker transport failure",
  "request_id": "YOUR_REFERENCE",
  "status": "error",
  "timestamp": "2025-10-26T14:08:09.00Z"
}
Internal error
{
  "error_code": 121,
  "error_reason": "An issue has been detected in the routing settings. For instance, it could be due to a disabled project or bank",
  "description": "Internal error",
  "request_id": "YOUR_REFERENCE",
  "status": "error",
  "timestamp": "2025-10-26T14:08:09.00Z"
}
An issue has been detected in the routing settings. For instance, it could be due to a disabled project or bank
{
  "error_code": 121,
  "error_reason": "An issue has been detected in the routing settings. For instance, it could be due to a disabled project or bank",
  "description": "An issue has been detected in the routing settings. For instance, it could be due to a disabled project or bank",
  "request_id": "YOUR_REFERENCE",
  "status": "error",
  "timestamp": "2025-10-26T14:08:10.00Z"
}
An unexpected error occurred while processing the request
{
  "error_code": 200,
  "error_reason": "Transaction processing error",
  "description": "An unexpected error occurred while processing the request",
  "request_id": "YOUR_REFERENCE",
  "status": "error",
  "timestamp": "2025-10-26T14:09:00.00Z"
}
Invalid method challenge configuration. Settings not found.
{
  "error_code": 121,
  "error_reason": "Invalid method challenge configuration. Please reconfigure method challenge type settings",
  "description": "Invalid method challenge configuration. Settings not found.",
  "request_id": "YOUR_REFERENCE",
  "status": "error",
  "timestamp": "2025-10-26T14:10:00.00Z"
}
Route is invalid (Incorrect method, mid settings)
{
  "error_code": 121,
  "error_reason": "Route is invalid",
  "description": "There is more than one challenge setting for a method. Please reconfigure method challenge type settings.",
  "request_id": "YOUR_REFERENCE",
  "status": "error",
  "timestamp": "2025-10-26T14:11:00.00Z"
}
Getting currency rate info error.
{
  "error_code": 200,
  "error_reason": "While getting currency rate, error happend",
  "description": "An internal error occurred while processing currency information",
  "request_id": "YOUR_REFERENCE",
  "status": "error",
  "timestamp": "2025-10-26T14:12:00.00Z"
}
Error processing currency information.
{
  "error_code": 200,
  "error_reason": "Error with payment configurations",
  "description": "An internal error occurred while processing currency information",
  "request_id": "YOUR_REFERENCE",
  "status": "error",
  "timestamp": "2025-10-26T14:13:00.00Z"
}
Error with wallet
{
  "error_code": 200,
  "error_reason": "Error with wallet",
  "description": "An internal error occurred while processing currency information",
  "request_id": "YOUR_REFERENCE",
  "status": "error",
  "timestamp": "2025-10-26T14:14:00.00Z"
}
Failed to register transaction
{
  "error_code": 200,
  "error_reason": "Failed to register transaction",
  "description": "An internal error occurred while processing currency information",
  "request_id": "YOUR_REFERENCE",
  "status": "error",
  "timestamp": "2025-10-26T14:15:00.00Z"
}
Failed saving card info
{
  "error_code": 200,
  "error_reason": "Transaction processing error",
  "description": "Failed to save card information",
  "request_id": "YOUR_REFERENCE",
  "status": "error",
  "timestamp": "2025-10-26T14:16:00.00Z"
}
Transaction processing error
{
  "error_code": 200,
  "error_reason": "Transaction processing error",
  "description": "Failed to register the transaction",
  "request_id": "YOUR_REFERENCE",
  "status": "error",
  "timestamp": "2025-10-26T14:17:00.00Z"
}
Mid doesn't support challenge type for method (mid or method settings problem)
{
  "error_code": 121,
  "error_reason": "Route is invalid",
  "description": "Mid does not support challenge type [challengeType] for method [method]",
  "request_id": "YOUR_REFERENCE",
  "status": "error",
  "timestamp": "2025-10-26T14:18:00.00Z"
}
Mid is disabled
{
  "error_code": 121,
  "error_reason": "Route is invalid",
  "description": "Mid is disabled",
  "request_id": "YOUR_REFERENCE",
  "status": "error",
  "timestamp": "2025-10-26T14:19:00.00Z"
}
Bank doesn't support currency
{
  "error_code": 1051,
  "error_reason": "Bank doesn't support currency",
  "description": "Blocked routing for transaction: Invalid currency",
  "request_id": "YOUR_REFERENCE",
  "status": "error",
  "timestamp": "2025-10-26T14:20:00.00Z"
}
Bank doesn't support payment method
{
  "error_code": 1054,
  "error_reason": "Bank doesn't support payment method",
  "description": "Blocked routing for transaction: Invalid method: [method]",
  "request_id": "YOUR_REFERENCE",
  "status": "error",
  "timestamp": "2025-10-26T14:21:00.00Z"
}
Bank does not support transaction: Invalid payment type
{
  "error_code": 1050,
  "error_reason": "Bank does not support transaction",
  "description": "Blocked routing for transaction: Invalid payment type",
  "request_id": "YOUR_REFERENCE",
  "status": "error",
  "timestamp": "2025-10-26T14:22:00.00Z"
}
Mid request timeout
{
  "error_code": 200,
  "error_reason": "Mid request timeout",
  "request_id": null,
  "reference": "YOUR_REFERENCE",
  "timestamp": "2025-10-26T14:24:00.00Z"
}
Communication error
{
  "error_code": 200,
  "error_reason": "Communication error",
  "request_id": "[UUID_ТРАНЗАКЦІЇ]",
  "reference": "YOUR_REFERENCE",
  "timestamp": "2025-10-26T14:25:00.00Z"
}
Forbidden
{
  "error_code": 5,
  "error_reason": "Forbidden",
  "timestamp": "2025-10-26T14:33:00.00Z"
}
Some unexpected message
{
  "error_code": 5,
  "error_reason": "[Some unexpected message]",
  "timestamp": "2025-10-26T14:33:00.00Z"
}
Failed to register card transaction
{
  "error_code": 200,
  "error_reason": "Failed to register card transaction",
  "request_id": null,
  "reference": "YOUR_REFERENCE",
  "timestamp": "2025-10-26T14:34:00.00Z"
}
Failed to register cascade transaction
{
  "error_code": 200,
  "error_reason": "Failed to register cascade transaction",
  "request_id": null,
  "reference": "YOUR_REFERENCE",
  "timestamp": "2025-10-26T14:35:00.00Z"
}
Endpoint type cannot be null or empty
{
  "error_code": 200,
  "error_reason": "Endpoint type cannot be null or empty",
  "request_id": null,
  "reference": "YOUR_REFERENCE",
  "timestamp": "2025-10-26T14:36:00.00Z"
}
Data is empty
{
  "error_code": 200,
  "error_reason": "Value cannot be null. (Parameter 'data')",
  "request_id": null,
  "reference": "YOUR_REFERENCE",
  "timestamp": "2025-10-26T14:36:00.00Z"
}
An unexpected internal error occured
{
  "error_code": 200,
  "error_reason": "Transaction processing error",
  "description": "An unexpected internal error occurred",
  "request_id": "YOUR_REFERENCE",
  "status": "error",
  "timestamp": "2025-10-26T14:38:00.00Z"
}
Handler returned null response
{
  "error_code": 210,
  "error_reason": "Handler returned null response",
  "description": "Handler returned null response",
  "request_id": "your_transaction_reference",
  "status": "error",
  "timestamp": "2025-10-26T12:02:00.000Z"
}
Rate limit exceeded
{
  "error_code": 210,
  "error_reason": "Rate limit exceeded",
  "description": "Rate limit exceeded",
  "request_id": "your_transaction_reference",
  "status": "error",
  "timestamp": "2025-10-26T12:01:00.000Z"
}
Access denied: Invalid or missing access token
{
  "error_code": 210,
  "error_reason": "Access denied: Invalid or missing access token",
  "description": "Access denied: Invalid or missing access token",
  "request_id": "your_transaction_reference",
  "status": "error",
  "timestamp": "2025-10-26T12:00:00.000Z"
}
Request cannot be null
{
  "code": 0,
  "reason": "",
  "error_code": 1,
  "error_reason": "Request cannot be null",
  "request_id": "",
  "reference": "",
  "status": "error",
  "timestamp": "2025-09-29T11:52:39.25Z",
  "description": ""
}
Flow cache limit exceeded
{
  "code": 0,
  "reason": "",
  "error_code": 1,
  "error_reason": "Flow cache limit exceeded",
  "request_id": "",
  "reference": "",
  "status": "error",
  "timestamp": "2025-09-29T11:52:39.25Z",
  "description": ""
}
Flow configuration not found for project: {projectId}
{
  "code": 0,
  "reason": "",
  "error_code": 1,
  "error_reason": "Flow configuration not found for project: {projectId}",
  "request_id": "",
  "reference": "",
  "status": "error",
  "timestamp": "2025-09-29T11:52:39.25Z",
  "description": ""
}
Invalid flow configuration
{
  "code": 0,
  "reason": "",
  "error_code": 1,
  "error_reason": "Invalid flow configuration",
  "request_id": "",
  "reference": "",
  "status": "error",
  "timestamp": "2025-09-29T11:52:39.25Z",
  "description": ""
}
Flow execution failed
{
  "code": 0,
  "reason": "",
  "error_code": 1,
  "error_reason": "Flow execution failed:",
  "request_id": "",
  "reference": "",
  "status": "error",
  "timestamp": "2025-09-29T11:52:39.25Z",
  "description": ""
}
Circular reference detected at node: {NodeIdentifier}
{
  "code": 0,
  "reason": "",
  "error_code": 1,
  "error_reason": "Circular reference detected at node: {NodeIdentifier}",
  "request_id": "",
  "reference": "",
  "status": "error",
  "timestamp": "2025-09-29T11:52:39.25Z",
  "description": ""
}
Node not found: {NodeIdentifier}
{
  "code": 0,
  "reason": "",
  "error_code": 1,
  "error_reason": "Node not found: {NodeIdentifier}",
  "request_id": "",
  "reference": "",
  "status": "error",
  "timestamp": "2025-09-29T11:52:39.25Z",
  "description": ""
}
Flow execution limit exceeded
{
  "code": 0,
  "reason": "",
  "error_code": 1,
  "error_reason": "Flow execution limit exceeded",
  "request_id": "",
  "reference": "",
  "status": "error",
  "timestamp": "2025-09-29T11:52:39.25Z",
  "description": ""
}
Flow ended without result
{
  "code": 0,
  "reason": "",
  "error_code": 1,
  "error_reason": "Flow ended without result",
  "request_id": "",
  "reference": "",
  "status": "error",
  "timestamp": "2025-09-29T11:52:39.25Z",
  "description": ""
}
Duplicated reference
{
  "error_code": 108,
  "error_reason": "Duplicated reference",
  "request_id": "3829f5bd-6dcb-41f9-a4ba-3ff8b65a3cfc",
  "reference": "",
  "timestamp": "2025-11-10T08:47:22.81Z"
}
Successful transaction
{
  "identifier": "BAN000442136",
  "request_id": "e5a1f870-c248-4d5b-a673-37a784dcecab",
  "reference": "AfricaBankTransferH2H#1",
  "description": "My order h2h",
  "status": {
    "name": "created",
    "date": "2025-10-13T08:48:13.4928684Z"
  },
  "created_date": "2025-10-13T08:46:32.096",
  "amount": 876,
  "billing_amount": 876,
  "currency": "NGN",
  "challenge": {
    "challenge_type": "bank_transfer_africa",
    "challenge_bank_transfer_africa": {
      "account_name": "54Pay Bank PLC",
      "account_number": "8725720385",
      "bank_name": "54Pay Bank PLC",
      "bank_code": "999999",
      "expiration_date": "2025-10-13 10:18:10"
    }
  },
  "timestamp": "2025-10-13T08:48:13.8622162Z",
  "error_code": 0,
  "error_message": ""
}
Missing Authorization header
{
  "error_code": 31,
  "error_reason": "Missing Authorization header",
  "timestamp": "2025-10-26T16:01:00.00Z"
}
Invalid Authorization header format
{
  "error_code": 31,
  "error_reason": "Invalid authorization header format",
  "timestamp": "2025-10-26T16:03:00.00Z"
}
Invalid signature format
{
  "error_code": 31,
  "error_reason": "Invalid signature format",
  "timestamp": "2025-10-26T16:03:00.00Z"
}
Unsupported algorithm
{
  "error_code": 31,
  "error_reason": "Unsupported algorithm",
  "timestamp": "2025-10-26T16:04:00.00Z"
}
Invalid API key
{
  "error_code": 31,
  "error_reason": "Invalid API key",
  "timestamp": "2025-10-26T16:05:00.00Z"
}
Missing Date header
{
  "error_code": 31,
  "error_reason": "Missing Date header",
  "timestamp": "2025-10-26T16:06:00.00Z"
}
Invalid date format
{
  "error_code": 31,
  "error_reason": "Invalid date format",
  "timestamp": "2025-10-26T16:07:00.00Z"
}
Date is outdated or invalid
{
  "error_code": 31,
  "error_reason": "Date is outdated or invalid",
  "timestamp": "2025-10-26T16:08:00.00Z"
}
Missing Digest header
{
  "error_code": 31,
  "error_reason": "Missing Digest header",
  "timestamp": "2025-10-26T16:09:00.00Z"
}
Invalid digest
{
  "error_code": 31,
  "error_reason": "Invalid digest",
  "timestamp": "2025-10-26T16:10:00.00Z"
}
Request timestamp has already been used
{
  "error_code": 31,
  "error_reason": "Request timestamp has already been used",
  "timestamp": "2025-10-26T16:11:00.00Z"
}
Invalid headers specification
{
  "error_code": 31,
  "error_reason": "Invalid headers specification",
  "timestamp": "2025-10-26T16:12:00.00Z"
}
Invalid signature
{
  "error_code": 31,
  "error_reason": "Invalid signature",
  "timestamp": "2025-10-26T16:13:00.00Z"
}
Processing error:
{
  "error_code": 210,
  "error_reason": "Processing error:",
  "description": "Processing error:",
  "request_id": "your_transaction_reference",
  "status": "error",
  "timestamp": "2025-10-26T12:03:00.000Z"
}
Missing required authentication headers
{
  "error_code": 31,
  "error_reason": "Missing required authentication headers",
  "timestamp": "2025-10-26T14:04:00.00Z"
}

Callback Notifications

The system sends an HTTP callback to the callback_url of your request when a transaction reaches a final state. Always verify the callback signature; see Callback Verification.

Callback Payload

Callback request
{
  "identifier": "PM0000000BTRNGN1",
  "creation_date": "2025-11-16T11:30:40.150Z",
  "request_id": "d4e5f6a7-b8c9-d0e1-f2a3-b4c5d6e7f8a9",
  "reference": "ref-btr-ng-h2h-6400334455",
  "method": "bank_transfer_africa",
  "type": "payment",
  "mode": "initial",
  "status": "success",
  "status_date": "2025-11-16T11:32:50.820Z",
  "amount": "50000.00",
  "currency": "NGN",
  "billing_amount": "50000.00",
  "billing_currency": "NGN",
  "fee_amount": "100.00",
  "fee_currency": "NGN",
  "customer": {
    "identifier": "cust_ng_686868",
    "email": "chioma.okonkwo@example.com",
    "phone": "+2348012345678",
    "first_name": "Chioma",
    "last_name": "Okonkwo",
    "country": "NG"
  },
  "error_code": 0,
  "error_reason": null,
  "timestamp": "2025-11-16T11:32:51.000Z",
  "meta": {
    "key": "value"
  }
}