Merchant Developer Portal
Integration guide for the Airpero multi-tenant fintech ecosystem. Build scaleable payment applications on top of the 9PSB infrastructure.
The Airpero SaaS API implements a robust, secure, and multi-tenant resilient architecture. Whether you are using our Dashboard or integrating via API, we provide the tools to manage customers and track financial flows with ease.
Authentication
We use a dual-auth system depending on your integration type. Never share your private keys.
Dashboard (JWT)
Used for UI-based management. Authenticate once and use the Bearer token.
Authorization: Bearer
Server-to-Server (Keys)
Used for backend automation. Required for customer creation.
x-public-key: pk_...
x-private-key: sk_...
Self-onboard your business to the Airpero ecosystem. Returns your unique API keys and 9PSB funding account.
{
"businessName": "My Fintech",
"email": "dev@myfintech.com",
"password": "secure_password"
}
Success Response:
{
"success": true,
"message": "Merchant registered successfully",
"data": {
"businessName": "My Fintech",
"email": "dev@myfintech.com",
"publicKey": "pk_live_...",
"privateKey": "sk_live_...",
"merchantAccountNumber": "99XXXXXXXX",
"bankName": "9PSB"
}
}
Authenticate to your merchant dashboard. Returns a JWT Bearer token.
{
"email": "dev@myfintech.com",
"password": "secure_password"
}
Success Response:
{
"success": true,
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"merchant": {
"id": "uuid",
"businessName": "My Fintech",
"email": "dev@myfintech.com"
}
}
Reporting Dashboards
Real-time financial metrics for your business overview.
Fetches cumulative inflow, outflow, and total funds held by your customers.
{
"success": true,
"data": {
"merchantBalance": "50000.00",
"totalCustomerFunds": 2500.00,
"totalInflow": 12000.00,
"customerCount": 42
}
}
Detailed log of all customer financial flows. Support for filtering.
Query Params:
?period=daily|monthly|yearly&status=success
Success Response:
{
"success": true,
"count": 2,
"data": [
{
"transaction_id": "MCH-PAY-abc123",
"type": "debit",
"class": "payout",
"amount": "1000.00",
"status": "success",
"createdAt": "2026-04-01T12:00:00.000Z"
}
]
}
Customer Creation
For security, customer creation is restricted to **API Key Auth** only. This prevents unauthorized sessions from minting virtual accounts.
Register a new customer and assign a 9PSB virtual account. The account name will be prefixed with your preview name (or business name by default).
{
"fullName": "Jane Doe",
"email": "jane@example.com",
"phoneNumber": "08100000000"
}
Success Response:
{
"success": true,
"message": "Customer created successfully",
"data": {
"id": "customer-uuid",
"fullName": "Jane Doe",
"accountNumber": "99XXXXXXXX",
"bankName": "9PSB"
}
}
Retrieve full details for a specific customer, including their balance and virtual account information.
Success Response:
{
"success": true,
"data": {
"id": "customer-uuid",
"merchantId": "merchant-uuid",
"fullName": "Jane Doe",
"email": "jane@example.com",
"phoneNumber": "08100000000",
"accountNumber": "99XXXXXXXX",
"balance": "5000.00",
"createdAt": "2026-04-01T12:00:00.000Z"
}
}
Send money out of a specific customer's balance. Requires Private Key auth.
{
"amount": 2000,
"accountNumber": "0123456789",
"bankCode": "90052",
"accountName": "John Doe"
}
This call returns exactly two possible responses —
no others. A payout is never returned as "failed" immediately. If it can't be confirmed as
successful right away, it comes back as PENDING instead, with the customer's balance staying
debited while confirmation completes. You'll receive a PAYOUT_SUCCESS or
PAYOUT_FAILED webhook automatically once it's resolved — see the Webhooks section.
Response 1 — Success (200):
{
"status": "SUCCESS",
"responseCode": "00",
"message": "Transaction Successful",
"data": {
"success": true,
"reference": "PAYOUT-abc123",
"transaction_id": "PAYOUT-abc123",
"fee": 20.00
}
}
Response 2 — Pending (202):
{
"status": "PENDING",
"message": "Transaction pending",
"data": {
"success": true,
"reference": "PAYOUT-abc123",
"fee": 20.00,
"transaction_id": "PAYOUT-abc123"
}
}
You can also check a
transaction's current status anytime via /transactions/requery or your transaction
history.
Directly debit a customer's balance (moves funds to your merchant wallet).
{
"amount": 1500,
"reason": "Service Charge"
}
Success Response:
{
"success": true,
"message": "Successfully debited customer Jane Doe",
"data": {
"transaction_id": "MCH-DR-xyz789",
"amount": 1500.00,
"fee": 0,
"status": "success"
}
}
Directly credit a customer's balance from your merchant wallet.
{
"amount": 2500,
"narration": "Customer Reward"
}
Success Response:
{
"success": true,
"message": "Successfully credited customer Jane Doe",
"data": {
"transaction_id": "MCH-CR-abc123",
"amount": 2500.00,
"fee": 0,
"status": "success"
}
}
Bank Utilities
Helper tools for bank identification and account validation.
Fetch summarized inflow/outflow report for a customer.
Success Response:
{
"success": true,
"data": {
"totalVolume": 5000.00,
"totalCredit": 3500.00,
"totalDebit": 1500.00,
"transactionCount": 12
}
}
Get the full granular list of transactions for a customer.
Success Response:
{
"success": true,
"count": 1,
"data": [
{
"transaction_id": "DEP-123",
"type": "credit",
"amount": 500.00,
"status": "success"
}
]
}
Get a list of all Nigerian banks and their codes.
Success Response:
{
"success": true,
"data": [
{ "name": "Access Bank", "code": "044" },
{ "name": "Guaranty Trust Bank", "code": "058" }
]
}
Verify the account name for a given number and bank.
{
"accountNumber": "0123456789",
"bankCode": "058"
}
Success Response:
{
"success": true,
"data": {
"accountName": "JOHN DOE",
"accountNumber": "0123456789",
"bankCode": "058"
}
}
Verify the status of a specific transaction ID. Optional `accountNo` improves accuracy.
{
"transactionId": "PAYOUT-12345",
"accountNo": "0123456789"
}
Success Response:
{
"success": true,
"data": {
"status": "SUCCESS",
"amount": 2000,
"transactionId": "PAYOUT-12345",
"updatedAt": "2026-04-01T15:00:00Z"
}
}
Webhooks & Hooks
Airpero delivers instant POST notifications. We recommend logging all inbound payloads for audit purposes.
Update your destination URL for notifications.
{ "webhookUrl": "https://api.yourdomain.com/hooks" }
Success Response:
{
"success": true,
"message": "Webhook URL updated successfully",
"data": {
"businessName": "My Fintech",
"webhookUrl": "https://api.yourdomain.com/hooks"
}
}
Update your business name or current 'preview' prefix for virtual accounts.
{ "preview": "AIRPERO", "businessName": "Airpero Global" }
Success Response:
{
"success": true,
"message": "Profile updated successfully",
"data": {
"preview": "AIRPERO",
"businessName": "Airpero Global"
}
}
Detailed Webhook Payload (PAYIN_SUCCESS):
Sent to your callback URL when a customer successfully deposits funds via their virtual account.
{
"event": "PAYIN_SUCCESS",
"merchantId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"timestamp": "2026-04-06T10:45:10.000Z",
"data": {
"transactionId": "100004260402085201156174739776",
"customerId": "88776655-4433-2211-0099-aabbccddeeff",
"customerName": "DESTINY MOMODU",
"senderName": "DANIEL OSAGIE ABIEVBODE",
"senderAccountNumber": "8032184432",
"senderBankName": "Palmpay",
"senderBankCode": "100033",
"amount": 10000.00,
"fee": 50.00,
"total_amount": 10000.00,
"currency": "NGN",
"reference": "CUST-VA-17be8eaf",
"transactionDate": "2026-04-02T17:09:05"
}
}
Detailed Webhook Payload (WALLET_FUNDED):
Sent to your callback URL when you fund your own merchant wallet directly.
{
"event": "WALLET_FUNDED",
"merchantId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"timestamp": "2026-04-06T10:45:10.000Z",
"data": {
"transactionId": "100004260402085201156174739776",
"amount": 50000.00,
"currency": "NGN",
"reference": "MCH-VA-ref123",
"senderName": "DANIEL OSAGIE ABIEVBODE",
"senderAccountNumber": "8032184432",
"senderBankName": "Palmpay",
"transactionDate": "2026-04-02T17:09:05"
}
}
Detailed Webhook Payload (PAYOUT_SUCCESS):
Sent when a payout that came
back PENDING from /merchants/payout or
/customers/{id}/payout is confirmed successful. A payout that returns an immediate
200 SUCCESS does not trigger this webhook — it's only sent for the delayed-confirmation case.
customerId is null for a merchant's own payout.
{
"event": "PAYOUT_SUCCESS",
"merchantId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"timestamp": "2026-04-06T10:45:10.000Z",
"data": {
"transaction_id": "PAYOUT-abc123",
"reference": "PAYOUT-abc123",
"customerId": "88776655-4433-2211-0099-aabbccddeeff",
"amount": 5000.00,
"fee": 20.00,
"currency": "NGN",
"status": "success"
}
}
Detailed Webhook Payload (PAYOUT_FAILED):
Sent when a payout that came
back PENDING is confirmed to have truly failed. By the time this fires, the debited
balance has already been refunded — refunded is always true.
customerId is null for a merchant's own payout.
{
"event": "PAYOUT_FAILED",
"merchantId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"timestamp": "2026-04-06T10:45:10.000Z",
"data": {
"transaction_id": "PAYOUT-abc123",
"reference": "PAYOUT-abc123",
"customerId": "88776655-4433-2211-0099-aabbccddeeff",
"amount": 5000.00,
"fee": 20.00,
"currency": "NGN",
"status": "failed",
"reason": "Confirmed failed by the provider after repeated verification.",
"refunded": true
}
}
Payout Operations
Initiate transfers out of your merchant wallet to any destination bank.
Real-time transfer via 9PSB infrastructure.
{
"amount": 1000,
"accountNumber": "0123456789",
"bankCode": "90052",
"accountName": "John Doe",
"narration": "Monthly Settlement"
}
This call returns exactly two possible responses —
no others. A payout is never returned as "failed" immediately. If it can't be confirmed as
successful right away, it comes back as PENDING instead, with your wallet staying debited while
confirmation completes. You'll receive a PAYOUT_SUCCESS or PAYOUT_FAILED
webhook automatically once it's resolved — see the Webhooks section.
Response 1 — Success (200):
Note: this endpoint's success shape differs from
/customers/{id}/payout's — success is a top-level field here, and
data is whatever the provider itself returned plus fee, rather than an
explicit reference/transaction_id pair.
{
"success": true,
"message": "Payout initiated successfully",
"status": "SUCCESS",
"responseCode": "00",
"data": {
"fee": 20.00
}
}
Response 2 — Pending (202):
{
"status": "PENDING",
"message": "Transaction pending",
"data": {
"success": true,
"reference": "MCH-PAY-xyz789",
"status": "SUCCESS",
"fee": "20.00",
"transaction_id": "MCH-PAY-xyz789"
}
}
You can also check a
transaction's current status anytime via /transactions/requery or your transaction
history.
© 2026 Airpero SaaS. Branded documentation for authorized merchants.