Models - Afriex Business API

Customer

Field Type Description
customerId string Unique identifier for the customer
name string Full name of the customer
email string (email) Email address
phone string Phone number in E.164 format (e.g. +2348192837465)
countryCode string ISO 3166-1 alpha-2 country code (e.g. NG)
meta object Optional metadata you attach to the customer
createdAt string (ISO 8601) Timestamp when the customer was created
updatedAt string (ISO 8601) Timestamp of the last update

On create and update requests, supply the customer’s full name as fullName; responses return it as name. KYC details are submitted separately through the Update KYC endpoint.

Transaction

Field Type Description
transactionId string Unique identifier for the transaction
customerId string ID of the customer who owns this transaction
sourceId string ID of the source payment method
destinationId string ID of the destination payment method
sourceAmount string Amount debited from the source wallet
sourceCurrency string ISO 4217 currency code of the source wallet (e.g. USD)
destinationAmount string Amount credited to the destination
destinationCurrency string ISO 4217 currency code of the destination (e.g. NGN)
fee string Fee charged for this transaction, denominated in sourceCurrency. Reported separately from sourceAmount. Omitted when no fee applied.
type string Transaction type. See Transaction Types
channel string Payment channel of the transaction. See Transaction Channels.
status string Current status. See Transaction Statuses
merchantReference string Merchant-supplied reference (mirrors meta.reference from the create request)
meta object Metadata attached to the transaction. See TransactionMeta
createdAt string (ISO 8601) Timestamp when the transaction was created
updatedAt string (ISO 8601) Timestamp of the last update

Transaction Types

Value Description
WITHDRAW Send funds from the Afriex wallet to a recipient’s payment method
DEPOSIT Receive funds into the Afriex wallet
SWAP Convert funds between currencies within the Afriex wallet

Transaction Channels

Channel Description
BANK_ACCOUNT Local bank account transfer
SWIFT International SWIFT wire transfer
MOBILE_MONEY Mobile money wallet (e.g. M-Pesa, MTN MoMo)
UPI Unified Payments Interface (India)
INTERAC Interac e-Transfer (Canada)
WE_CHAT WeChat Pay
CARD Card payment
CRYPTO Crypto rail
VIRTUAL_BANK_ACCOUNT Hosted virtual bank account
POOL_ACCOUNT Shared pool account for incoming deposits
ACH_BANK_ACCOUNT US ACH bank transfer
PAYBILL_TILL Paybill / Till (M-Pesa business numbers)
RFP Request for Payment
VIRTUAL_CARD Virtual card
ALIPAY Alipay
WALLET Afriex wallet (internal leg)

Transaction Statuses

Status Description
PENDING Transaction has been received and is awaiting processing
PROCESSING Transaction is actively being processed
SUCCESS Transaction settled successfully
FAILED Transaction failed. Check meta.failureReason for the reason code. See Failure reasons.
CANCELLED Transaction was cancelled before processing
REFUNDED Funds were returned to the sender
RETRY Transaction is being automatically retried
UNKNOWN Status could not be determined. Contact support.
SCHEDULED Transaction is scheduled to be processed later
CUSTOMER_ACTION_REQUIRED Transaction is paused pending an action from the customer
REJECTED Transaction was rejected after review
IN_REVIEW Transaction is under manual review
DISPUTED A dispute has been raised against the transaction
DISPUTE_RESOLVED The dispute has been resolved
DISPUTE_WON The dispute was resolved in your favour
DISPUTE_LOST The dispute was resolved against you
DISPUTE_EVIDENCE_SUBMITTED Evidence has been submitted for the dispute

TransactionMeta

The meta object passed when creating a transaction. idempotencyKey and reference are required.

Field Type Required Description
idempotencyKey string Yes Unique key to prevent duplicate transactions. Use a UUID or your own unique identifier.
reference string Yes Your internal reference for the transaction (e.g. order ID). Returned on the transaction as merchantReference.
narration string No Human-readable reason or description for the transaction
invoice string No Base64-encoded invoice document to attach to the transaction.
settlement string No Settlement handling. One of spot (default, processes immediately) or request (WITHDRAW only, queues the payout for the next business day in the destination payment method’s country). scheduled is derived server-side and should not be sent.
{
  "meta": {
    "idempotencyKey": "550e8400-e29b-41d4-a716-446655440000",
    "reference": "ORDER-12345",
    "narration": "Payment for invoice #12345",
    "invoice": "base64EncodedStringHere"
  }
}

Always provide a unique idempotencyKey per transaction attempt. If you retry a failed request with the same key, Afriex will return the original transaction instead of creating a duplicate.

Server-set meta fields

Afriex also sets fields on meta after the transaction is created. These echo alongside any fields you passed on create.

Field Type Description
otpRequired boolean true when the customer must complete an OTP challenge before the transaction can settle. See Simulating OTP-required deposits.
failureReason object Present only when status is FAILED or REJECTED. Carries a stable code, a customer-safe message, and a retryable flag. See Failure reasons.

Failure reasons

When a transaction reaches FAILED or REJECTED, meta.failureReason explains why using a stable AFX_* code and a customer-safe message. Branch on code rather than the underlying rail so your integration stays stable across routing changes.

Field Type Description
code string Stable AFX_* failure code. Safe to switch on; the set grows over time but existing values do not change meaning.
message string Customer-safe short description of the failure. Suitable for display; do not parse. Branch on code instead.
retryable boolean true when re-submitting the same request (or, for AFX_PROPOSAL_EXPIRED, starting a fresh proposal) may succeed. false when the caller must change the request before retrying.
{
  "meta": {
    "failureReason": {
      "code": "AFX_VELOCITY_LIMIT_EXCEEDED",
      "message": "This transaction exceeds the allowed velocity limit. Try again later.",
      "retryable": true
    }
  }
}
Code Meaning
AFX_REQUEST_FAILED Generic failure while processing the request. Usually retryable.
AFX_SYSTEM_ERROR Internal Afriex error. Retry with backoff.
AFX_SERVICE_UNAVAILABLE A downstream service was unavailable. Retry with backoff.
AFX_INVALID_CURRENCY The requested currency is not supported for this route.
AFX_INVALID_AMOUNT The requested amount is invalid or outside allowed limits.
AFX_INVALID_RECIPIENT The recipient payment method is invalid or incomplete.
AFX_RECIPIENT_NOT_FOUND The recipient account could not be located at the destination institution.
AFX_BENEFICIARY_RESTRICTED The beneficiary is restricted and cannot receive funds.
AFX_INVALID_SENDER The sender’s payment method is invalid or ineligible.
AFX_INVALID_REQUEST The request payload is malformed or inconsistent.
AFX_VELOCITY_LIMIT_EXCEEDED The customer has exceeded a velocity limit. Retry after the window resets.
AFX_AMOUNT_LIMIT_EXCEEDED The request exceeds a per-transaction, daily, or account limit.
AFX_PAYMENT_FAILED The payment leg failed at the payment rail.
AFX_COMPLIANCE_REJECTED The transaction was rejected during compliance review.
AFX_PROPOSAL_EXPIRED The rate proposal expired before the transaction was committed. Start a fresh proposal.

The AFX_* set may grow over time as new failure modes are surfaced. Existing values will not change meaning. Handle unknown codes by falling back to message.

PaymentMethod

Empty fields are omitted from responses. Account-shaped channels (BANK_ACCOUNT, MOBILE_MONEY, SWIFT, etc.) populate accountName, accountNumber, and institution; the CARD channel instead populates last4, brand, expiration, and cardName.

Field Type Description
paymentMethodId string Unique identifier for the payment method
customerId string ID of the customer who owns this payment method
channel string Payment channel. See Payment Channels
countryCode string ISO 3166-1 alpha-2 country code
currency string ISO 4217 currency code. Use this instead of inferring from countryCode, which is ambiguous (e.g. a USD account in a non-US country)
capabilities string[] Operations this method is enabled for (e.g. DEPOSIT, WITHDRAW). Filterable via the capabilities query parameter on List Payment Methods
reference string Identifier used to reconcile incoming deposits against
accountName string Account holder name. Present for account-shaped channels
accountNumber string Account number. Present for account-shaped channels
institution object Bank or provider details. See PaymentMethodInstitution
recipient object Recipient contact details. See PaymentMethodRecipient
transaction object Per-transaction overrides. See PaymentMethodTransaction
status string Lifecycle status. See Payment Method Statuses
last4 string Last 4 digits of the card. CARD channel only
brand string Card brand (e.g. Visa, MasterCard). CARD channel only
expiration object Card expiry with month and year. CARD channel only
cardName string Name on the card. CARD channel only
expiresInMinutes integer Minutes until a dynamic virtual account expires, when applicable
amount number Requested amount for a dynamic virtual account, when applicable
extra object Additional channel-specific properties
meta object Optional metadata attached to the payment method

Payment Channels

Channel Description
BANK_ACCOUNT Local bank account transfer
MOBILE_MONEY Mobile money wallet (e.g. M-Pesa, MTN MoMo)
SWIFT International SWIFT wire transfer
INTERAC Interac e-Transfer (Canada)
UPI Unified Payments Interface (India)
WE_CHAT WeChat Pay
ALIPAY Alipay
CARD Card payment
CRYPTO Crypto rail
VIRTUAL_BANK_ACCOUNT Hosted virtual bank account
POOL_ACCOUNT Shared pool account for incoming deposits
ACH_BANK_ACCOUNT US ACH bank transfer
PAYBILL_TILL Paybill / Till (M-Pesa business numbers)
RFP Request for Payment
VIRTUAL_CARD Virtual card

Not every channel is valid when creating a payment method. The Create Payment Method endpoint accepts a narrower set of channels; the list above covers all channels that can appear on a returned payment method.

Payment Method Statuses

Status Description
active Payment method is active and usable
pending Payment method is awaiting activation or verification
deleted Payment method has been deleted
expired Payment method has expired (e.g. an expired card)
blocked Payment method has been blocked

PaymentMethodRecipient

Recipient contact details attached to a payment method, when supplied.

Field Type Description
recipientName string Name of the recipient
recipientEmail string (email) Email address of the recipient
recipientPhone string Phone number of the recipient in E.164 format
recipientAddress string Address of the recipient

PaymentMethodTransaction

Optional per-transaction details attached to a payment method.

Field Type Description
transactionNarration string Optional reason or description for the transaction
transactionInvoice string Base64-encoded invoice for the transaction

PaymentMethodInstitution

Field Type Description
institutionId string Unique ID of the bank or mobile money provider
institutionName string Display name of the institution
institutionCode string Institution code (e.g. bank code)
institutionAddress string Physical address of the institution, if required

Use the List Institutions endpoint to retrieve valid institutions for a given country and channel.

Error Response

All API errors return a consistent JSON body:

Field Type Description
code string Machine-readable error code (e.g. AUTHENTICATION_ERROR)
error string Short error category (e.g. Bad Request)
details.errorMessage string Specific error reason (e.g. PHONE_COUNTRY_MISMATCH)
details.friendlyMessage string User-friendly message you can display to end users
details.data object Optional caller-safe context. On a customer-create uniqueness conflict (EMAIL_ALREADY_EXISTS, PHONE_NUMBER_ALREADY_EXISTS) contains { customerId } for the existing customer so you can adopt it without a follow-up lookup
{
  "code": "INVALID_BUSINESS_CUSTOMER_REQUEST",
  "error": "Bad Request",
  "details": {
    "errorMessage": "PHONE_COUNTRY_MISMATCH",
    "friendlyMessage": "The phone number does not match the customer's country."
  }
}

Common error codes

Code HTTP Status Description
AUTHENTICATION_ERROR 401 API key is missing or invalid
INVALID_BUSINESS_CUSTOMER_REQUEST 400 Customer request validation failed
PHONE_COUNTRY_MISMATCH 400 Phone number country does not match countryCode
EMAIL_ALREADY_EXISTS 409 A customer with this email already exists. details.data.customerId returns the existing customer’s id.
PHONE_NUMBER_ALREADY_EXISTS 409 A customer with this phone number already exists. details.data.customerId returns the existing customer’s id.
NOT_FOUND 404 The requested resource does not exist
RATE_LIMIT_EXCEEDED 429 Too many requests. Slow down and retry with backoff.