Skip to content

Payout / Alternative payment methods / Africa

Wallet Palmpay#

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

The ApiPro Payout API allows you to send funds to your clients' PalmPay wallet accounts. This document provides instructions on how to create and manage these e-wallet payouts.

How PalmPay Wallet Payouts Work#

  1. Request: Your application makes a POST request to the ApiPro payout endpoint to create a transaction.
  2. Processing: ApiPro processes the payout, interacting with the PalmPay service.
  3. Notification: Once the transaction reaches a terminal state (e.g., success or error), ApiPro sends a callback (webhook) to your specified callback_url.

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.

{
  "method": "wallet_palmpay", // required, snake_case / lower case only: "wallet_palmpay" (not "WALLET_PALMPAY" or "WalletPalmpay")
  "mode": "initial", // required, always "initial"
  "reference": "PalmpayPayout#1", // required
  "currency": "NGN", // required
  "amount": 150, // required
  "description": "Payment for invoice #456", // optional
  "beneficiary": {
    "phone": "+2347011223344", // required
    "email": "beneficiary@example.com", // optional
    "first_name": "Han", // required
    "last_name": "Solo" // required
  },
  "customer": {
    "identifier": "cust_abc_987", // required, may be used any unique value from system of merchant
    "email": "han.solo@merchant.com", // conditional
    "first_name": "Chewbacca", // optional
    "last_name": "Wookiee", // optional
    "middle_name": "", // optional
    "phone": "2348099887766", // optional
    "itn": "Z9876543210", // optional
    "country": "GH", // optional, ISO 3166-1
    "state_code": "AA", // optional, ISO 3166-2
    "city": "Accra", // optional
    "address": "Osu Oxford Street, 10", // optional
    "zip_code": "GA-077-5310", // optional
    "birthday": "1985-05-25", // optional
    "ip": "10.0.0.5", // optional
    "gender": "male" // optional
  },
  "callback_url": "https://api.merchant.com/palmpay_hook", // conditional
   "extra": { // conditional, any field which may be needed for transaction routing and integration
        "meta": {
            "key": "value"
        }
    }
}

Fields#

Field Type Requirement / note
method string required, snake_case / lower case only: "wallet_palmpay" (not "WALLET_PALMPAY" or "WalletPalmpay")
mode string required, always "initial"
reference string required
currency string required
amount integer required
description string optional
beneficiary object
beneficiary.phone string required
beneficiary.email string optional
beneficiary.first_name string required
beneficiary.last_name string required
customer object
customer.identifier string required, may be used any unique value from system of merchant
customer.email string conditional
customer.first_name string optional
customer.last_name string optional
customer.middle_name string optional
customer.phone string optional
customer.itn string optional
customer.country string optional, ISO 3166-1
customer.state_code string optional, ISO 3166-2
customer.city string optional
customer.address string optional
customer.zip_code string optional
customer.birthday string optional
customer.ip string optional
customer.gender 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

Succesful transaction
{
  "identifier": "MOB000137185",
  "request_id": "6ae8671e-6b6f-4678-981a-36a783aa73ec",
  "reference": "AfricaPalmPayPayout#1",
  "description": "My order payout",
  "status": {
    "name": "pending",
    "date": "2025-08-27T08:27:49.014"
  },
  "created_date": "2025-08-27T08:27:45.764",
  "amount": 25.0,
  "billing_amount": 25.0,
  "currency": "NGN",
  "extra": [
    {
      "key": "key_2",
      "value": "value"
    },
    {
      "key": "key_3",
      "value": "value"
    },
    {
      "key": "key_4",
      "value": "value"
    },
    {
      "key": "key_1",
      "value": "value"
    }
  ],
  "timestamp": "2025-08-27T08:27:49.2818969Z",
  "error_code": 0,
  "error_message": ""
}
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"
}
Resource not found
{
  "error_code": 35,
  "error_reason": "Resource not found",
  "description": "The requested resource is undefined",
  "request_id": "value_from_data_reference",
  "status": "error",
  "timestamp": "2025-10-02T14:15:00.00Z"
}
Routing failed
{
  "error_code": 121,
  "error_reason": "Routing failed",
  "timestamp": "2025-10-02T14:17:00.00Z"
}
Unknown routing error
{
  "error_code": 1,
  "error_reason": "Unknown routing error",
  "timestamp": "2025-10-02T14:17:00.00Z"
}
Routing service error: Value cannot be null. (Parameter 'data')
{
  "error_code": 1,
  "error_reason": "Routing service error: Value cannot be null. (Parameter 'data')",
  "timestamp": "2025-10-02T14:17:00.00Z"
}
Routing request timeout
{
  "error_code": 2,
  "error_reason": "Routing request timeout",
  "timestamp": "2025-10-02T14:17:00.00Z"
}
Required fields are missing: method, reference, amount, currency
{
  "error_code": 31,
  "error_reason": "Required fields are missing: method, reference, amount, currency",
  "timestamp": "2025-10-02T14:16:00.00Z"
}
Routing service error: Endpoint type cannot be null or empty
{
  "error_code": 1,
  "error_reason": "Routing service error: Endpoint type cannot be null or empty",
  "timestamp": "2025-10-02T14:17:00.00Z"
}
Routing service error
{
  "error_code": 1,
  "error_reason": "Routing service error",
  "timestamp": "2025-10-02T14:17:00.00Z"
}
Payment transaction timeout after seconds
{
  "error_code": 1,
  "error_reason": "Payment transaction timeout after 30 seconds",
  "timestamp": "2025-10-02T14:17:00.00Z"
}
Internal error: Mid {MidId} no longer exists in configuration
{
  "error_code": 1,
  "error_reason": "Internal error: Mid {MidId} no longer exists in configuration",
  "timestamp": "2025-10-02T14:17:00.00Z"
}
Internal error: Value cannot be null. (Parameter 'tcs')
{
  "error_code": 1,
  "error_reason": "Internal error: Value cannot be null. (Parameter 'tcs')",
  "timestamp": "2025-10-02T14:17:00.00Z"
}
Payment transaction was cancelled
{
  "error_code": 1,
  "error_reason": "Payment transaction was cancelled",
  "timestamp": "2025-10-02T14:17:00.00Z"
}
Error while trying to process filling data
{
  "error_code": 200,
  "error_reason": "Error while trying to process filling data",
  "request_id": null,
  "reference": "value_from_data_reference",
  "timestamp": "2025-10-02T14:18:00.00Z"
}
Invalid method challenge configuration. Please reconfigure method challenge type settings
{
  "error_code": 121,
  "error_reason": "Invalid method challenge configuration. Please reconfigure method challenge type settings",
  "timestamp": "2025-10-02T14:19:00.00Z"
}
There is more than one challenge setting for a method. Please reconfigure method challenge type settings
{
  "error_code": 121,
  "error_reason": "There is more than one challenge setting for a method. Please reconfigure method challenge type settings",
  "timestamp": "2025-10-02T14:20:00.00Z"
}
MID not found in cache while getting currency rate
{
  "error_code": 35,
  "error_reason": "Resource not found",
  "description": "MID not found in cache while getting currency rate",
  "request_id": "value_from_data_reference",
  "status": "error",
  "timestamp": "2025-10-02T14:21:00.00Z"
}
Transaction processing error: error while getting currency rate
{
  "error_code": 200,
  "error_reason": "Transaction processing error",
  "description": "Unexpected error while getting currency rate",
  "request_id": "value_from_data_reference",
  "status": "error",
  "timestamp": "2025-10-02T14:22:00.00Z"
}
Transaction processing error: error with payment configurations during calculation
{
  "error_code": 200,
  "error_reason": "Transaction processing error",
  "description": "Error with payment configurations during calculation",
  "request_id": "value_from_data_reference",
  "status": "error",
  "timestamp": "2025-10-02T14:23:00.00Z"
}
Exceeded amount limits for project
{
  "error_code": 1132,
  "error_reason": "Limit exceeded",
  "description": "Amount is outside the allowed project limits",
  "request_id": "value_from_data_reference",
  "status": "error",
  "timestamp": "2025-10-02T14:24:00.00Z"
}
Exceeded amount limits for MID
{
  "error_code": 1132,
  "error_reason": "Limit exceeded",
  "description": "Amount is outside the allowed MID limits",
  "request_id": "value_from_data_reference",
  "status": "error",
  "timestamp": "2025-10-02T14:24:00.00Z"
}
Transaction processing error: error while getting withdrawal rates
{
  "error_code": 200,
  "error_reason": "Transaction processing error",
  "description": "Unexpected error while getting withdrawal rates",
  "request_id": "value_from_data_reference",
  "status": "error",
  "timestamp": "2025-10-02T14:24:00.00Z"
}
Invalid params: transactions constraints were violated
{
  "error_code": 30,
  "error_reason": "Invalid params",
  "description": "Transaction contraints were violated",
  "request_id": "value_from_data_reference",
  "status": "error",
  "timestamp": "2025-10-02T14:26:00.00Z"
}
Failed to create transaction for unfamiliar reason
{
  "error_code": 200,
  "error_reason": "Transaction processing error",
  "description": "Failed to create transaction",
  "request_id": "value_from_data_reference",
  "status": "error",
  "timestamp": "2025-10-02T14:27:00.00Z"
}
Account payout has negative balance after update
{
  "error_code": 1,
  "error_reason": "Insufficient funds on account",
  "description": "Account payout has negative balance after update",
  "request_id": "value_from_data_reference",
  "status": "error",
  "timestamp": "2025-10-02T14:28:00.00Z"
}
Error with wallet
{
  "error_code": 200,
  "error_reason": "Transaction processing error",
  "description": "Error with wallet",
  "request_id": "value_from_data_reference",
  "status": "error",
  "timestamp": "2025-10-02T14:29:00.00Z"
}
Mid is disabled
{
  "error_code": 32,
  "error_reason": "Invalid MID",
  "description": "Mid is disabled",
  "request_id": "value_from_data_reference",
  "status": "error",
  "timestamp": "2025-10-02T14:30:00.00Z"
}
Blocked routing for transaction: Invalid currency
{
  "error_code": 31,
  "error_reason": "Invalid currency",
  "description": "Blocked routing for transaction: Invalid currency",
  "request_id": "value_from_data_reference",
  "status": "error",
  "timestamp": "2025-10-02T14:31:00.00Z"
}
Blocked routing for transaction: Invalid method
{
  "error_code": 1054,
  "error_reason": "Invalid method",
  "description": "Blocked routing for transaction: Invalid method",
  "request_id": "value_from_data_reference",
  "status": "error",
  "timestamp": "2025-10-02T14:32:00.00Z"
}
Blocked routing for transaction: Invalid payment type
{
  "error_code": 1054,
  "error_reason": "Invalid type",
  "description": "Blocked routing for transaction: Invalid payment type",
  "request_id": "value_from_data_reference",
  "status": "error",
  "timestamp": "2025-10-02T14:33:00.00Z"
}
Requisites - Invalid JSON format
{
  "error_code": 31,
  "error_reason": "Required fields are missing: requisites - invalid JSON format",
  "timestamp": "2025-10-02T14:34:00.00Z"
}
Mid configuration error
{
  "error_code": 200,
  "error_reason": "Mid configuration error",
  "request_id": null,
  "reference": "value_from_data_reference",
  "timestamp": "2025-10-02T14:35:00.00Z"
}
Mid request timeout
{
  "error_code": 200,
  "error_reason": "Mid request timeout",
  "request_id": null,
  "reference": "value_from_data_reference",
  "timestamp": "2025-10-02T14:36:00.00Z"
}
Communication error
{
  "error_code": 200,
  "error_reason": "Communication error",
  "request_id": null,
  "reference": "value_from_data_reference",
  "timestamp": "2025-10-02T14:36:00.00Z"
}
Invalid adapter response format
{
  "error_code": 200,
  "error_reason": "Invalid adapter response format",
  "request_id": null,
  "reference": "value_from_data_reference",
  "timestamp": "2025-10-02T14:37:00.00Z"
}
Failed to register card transaction
{
  "error_code": 200,
  "error_reason": "Failed to register card transaction",
  "request_id": null,
  "reference": "value_from_data_reference",
  "timestamp": "2025-10-02T14:48:00.00Z"
}
Failed to register cascade transaction
{
  "error_code": 200,
  "error_reason": "Failed to register cascade transaction",
  "request_id": null,
  "reference": "value_from_data_reference",
  "timestamp": "2025-10-02T14:48:00.00Z"
}
Mid with ID '[MidId]' not found
{
  "error_code": 200,
  "error_reason": "Mid with ID '[MidId]' not found",
  "request_id": null,
  "reference": "value_from_data_reference",
  "timestamp": "2025-10-02T14:49:00.00Z"
}
Mid [MidName] ([MidId]) is not active
{
  "error_code": 200,
  "error_reason": "Mid [MidName] ([MidId]) is not active",
  "request_id": null,
  "reference": "value_from_data_reference",
  "timestamp": "2025-10-02T14:49:00.00Z"
}
Mid [MidId] no longer exists in configuration
{
  "error_code": 200,
  "error_reason": "Mid [MidId] no longer exists in configuration",
  "request_id": null,
  "reference": "value_from_data_reference",
  "timestamp": "2025-10-02T14:49:00.00Z"
}
Some unexpected error occured
{
  "error_code": 200,
  "error_reason": "<Some unexpected error message>",
  "request_id": null,
  "reference": "value_from_data_reference",
  "timestamp": "2025-10-02T14:49:00.00Z"
}
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: some unexpected error
{
  "code": 0,
  "reason": "",
  "error_code": 1,
  "error_reason": "Flow execution failed:",
  "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"
}
'beneficiary' missing field
{
  "error_code": 31,
  "error_reason": "Required fields are missing: beneficiary",
  "timestamp": "2025-10-02T14:25:00.00Z"
}
Invalid Authorization header format
{
  "error_code": 31,
  "error_reason": "Invalid Authorization header format",
  "timestamp": "2025-10-26T14:04:00.00Z"
}
Invalid Signature format
{
  "error_code": 31,
  "error_reason": "Invalid signature format",
  "timestamp": "2025-10-26T14:04:00.00Z"
}
Unsupported algorithm
{
  "error_code": 31,
  "error_reason": "Unsupported algorithm",
  "timestamp": "2025-10-26T14:04:00.00Z"
}
Invalid API key
{
  "error_code": 31,
  "error_reason": "Invalid API key",
  "timestamp": "2025-10-26T14:04:00.00Z"
}
Invalid date format
{
  "error_code": 31,
  "error_reason": "Invalid date format",
  "timestamp": "2025-10-26T14:04:00.00Z"
}
Date is outdated or invalid
{
  "error_code": 31,
  "error_reason": "Date is outdated or invalid",
  "timestamp": "2025-10-26T14:04:00.00Z"
}
Missing Digest header
{
  "error_code": 31,
  "error_reason": "Invalid digest",
  "timestamp": "2025-10-26T14:04:00.00Z"
}
Invalid digest
{
  "error_code": 31,
  "error_reason": "Missing Digest header",
  "timestamp": "2025-10-26T14:04:00.00Z"
}
Invalid signature
{
  "error_code": 31,
  "error_reason": "Invalid signature",
  "timestamp": "2025-10-26T14:04:00.00Z"
}
Invalid headers specification
{
  "error_code": 31,
  "error_reason": "Invalid headers specification",
  "timestamp": "2025-10-26T14:04:00.00Z"
}
Request timestamp has already been used
{
  "error_code": 31,
  "error_reason": "Request timestamp has already been used",
  "timestamp": "2025-10-26T14:04:00.00Z"
}
Missing required authentication headers
{
  "error_code": 31,
  "error_reason": "Missing required authentication headers",
  "timestamp": "2025-10-26T14:04:00.00Z"
}
Missing Authorization header
{
  "error_code": 31,
  "error_reason": "Missing Authorization header",
  "timestamp": "2025-10-26T16:01:00.00Z"
}
Missing Date header
{
  "error_code": 31,
  "error_reason": "Missing Date header",
  "timestamp": "2025-10-26T16:06: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"
}

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": "PT000000000000K",
  "creation_date": "2023-05-10T09:30:11.543210",
  "request_id": "66bde914-5b70-48aa-8f72-6ac76f050fe9",
  "reference": "PalmpayPayout#1",
  "method": "wallet_palmpay",
  "type": "payout",
  "mode": "initial",
  "status": "success",
  "status_date": "2023-05-10T09:30:13.112233",
  "wallet": {
    "number": "+2347011223344",
    "beneficiary_first_name": "Han",
    "beneficiary_last_name": "Solo",
    "beneficiary_phone": "+2347011223344",
    "beneficiary_email": "han.solo.beneficiary@example.com"
  },
  "customer": {
    "identifier": "cust_abc_987",
    "email": "han.solo@merchant.com",
    "first_name": "Chewbacca",
    "last_name": "Wookiee",
    "middle_name": "",
    "phone": "2348099887766",
    "itn": "Z9876543210",
    "country": "GH",
    "state_code": "AA",
    "city": "Accra",
    "address": "Osu Oxford Street, 10",
    "zip_code": "GA-077-5310",
    "birthday": "1985-05-25",
    "ip": "10.0.0.5",
    "gender": "male"
  },
  "amount": "150.00",
  "currency": "NGN",
  "billing_amount": "150.00",
  "billing_currency": "NGN",
  "fee_amount": "15.00",
  "fee_currency": "NGN",
  "error_code": 0,
  "error_reason": "",
  "timestamp": "2023-05-10T09:30:14.987654"
}