BankiPay API

Currency quotes, supplier payments, balances and transactions — over a simple REST API.

Base URL: https://bankipay.io/api/v1

Introduction

The BankiPay API lets you request exchange-rate quotes, create supplier payments, check wallet balances and read transaction history. All requests and responses use JSON. Every response includes a success boolean and, for authenticated calls, the mode that served the request.

Authentication

Authenticate by sending your API key as a Bearer token. The X-API-Key header is also accepted.

Authorization: Bearer bankipay_live_xxxxxxxxxxxxxxxx
Keep your keys secret. Never expose a live key in client-side code. If a key is compromised, regenerate it — the old key stops working immediately.

Test & live mode

Each account has two keys. Test keys (bankipay_test_…) run in sandbox mode and never move real money. Live keys (bankipay_live_…) execute real operations. The mode field in each response tells you which environment answered.

Errors

Errors return a non-2xx status and a consistent shape:

{
  "success": false,
  "error": { "type": "authentication_error", "message": "Invalid API key." }
}
StatusTypeMeaning
401authentication_errorMissing or invalid API key
404not_foundResource does not exist
422validation_errorInvalid request parameters
422insufficient_fundsWallet balance too low for the payment

Create a quote

POST/quotes

Returns the exchange rate and the amount the beneficiary will receive.

FieldTypeDescription
from_currencystringrequired3-letter ISO code, e.g. EUR
to_currencystringrequired3-letter ISO code, e.g. NGN
amountnumberrequiredAmount to send (min 0.01)
curl -X POST https://bankipay.io/api/v1/quotes \
  -H "Authorization: Bearer bankipay_test_xxx" \
  -H "Content-Type: application/json" \
  -d '{"from_currency":"EUR","to_currency":"NGN","amount":1000}'
{
  "success": true, "mode": "test",
  "data": { "from_currency":"EUR","to_currency":"NGN","send_amount":1000,"fee":0,"rate":1593.247873,"receive_amount":1593247.87 }
}

Create a payment

POST/payments

Creates a supplier payment request. Returns the payment with a unique reference you can use to track it.

FieldTypeDescription
from_currencystringrequiredSource currency
to_currencystringrequiredDestination currency
amountnumberrequiredAmount to send
beneficiary_namestringrequiredBeneficiary full name
beneficiary_bankstringoptionalBank name
beneficiary_accountstringoptionalAccount number / IBAN
beneficiary_countrystringoptionalBeneficiary country
purposestringoptionalPayment purpose / reference
{
  "success": true, "mode": "test",
  "data": {
    "id": "pay_test_xxx", "status": "pending",
    "from_currency": "EUR", "to_currency": "NGN",
    "send_amount": 1000, "rate": 1593.247873, "receive_amount": 1593247.87,
    "beneficiary": { "name":"Supplier Ltd","bank":"GTBank","account":"0123456789","country":"Nigeria" },
    "purpose": "Invoice 2026-001", "created_at": "2026-06-14T16:33:40+02:00"
  }
}

Payment status is one of pending, processing, completed, failed.

Retrieve a payment

GET/payments/{reference}

Returns the current status and details of a payment. You can only access your own payments.

curl https://bankipay.io/api/v1/payments/pay_test_xxx \
  -H "Authorization: Bearer bankipay_test_xxx"

Wallet balance

GET/balance

Returns all wallet balances for your account.

{
  "success": true, "mode": "test",
  "data": { "balances": [ { "currency":"EUR","balance":5000 } ] }
}

Transactions

GET/transactions

Paginated transaction history.

FieldTypeDescription
per_pageintegeroptional1–100, default 20
statusstringoptionalFilter by status
typestringoptionalFilter by type

Webhooks

BankiPay can notify your server when a payment changes status. Each notification is a POST request to your endpoint URL with this body:

{
  "event": "payment.completed",
  "created_at": "2026-06-14T16:33:40+02:00",
  "data": {
    "id":"pay_live_xxx","status":"completed",
    "from_currency":"EUR","to_currency":"NGN",
    "send_amount":1000,"receive_amount":1593247.87,"mode":"live"
  }
}

The event name follows the pattern payment.{status}, e.g. payment.completed or payment.failed. Respond with HTTP 200 to acknowledge receipt.

Verifying signatures

Every webhook body is signed with HMAC-SHA256 using your webhook signing secret. The signature is sent in the X-BankiPay-Signature header. Recompute it over the raw request body and compare before trusting the payload.

// PHP
$payload   = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_BANKIPAY_SIGNATURE'] ?? '';
$expected  = hash_hmac('sha256', $payload, 'whsec_your_secret');

if (hash_equals($expected, $signature)) {
    http_response_code(200); // trusted
} else {
    http_response_code(401);
}