Direct Disbursements API
This page documents the live public direct-disbursement surface served under
https://api.gopiaxis.com/api.
Overview
Public direct-disbursement routes:
POST /api/disbursements/quotePOST /api/disbursementsGET /api/disbursementsGET /api/disbursements/{disbursement_id}POST /api/disbursements/{disbursement_id}/cancel
Public Contract Notes
The guaranteed create-disbursement request schema is:
recipientscurrencypayment_methoddescription
Each recipient guarantees:
recipient_idemailphone_numberamountreference
If you see longer examples elsewhere with keys such as callback_url,
notify_recipients, metadata, or bulk-upload helpers, treat those as
deployment-specific extensions and not part of the guaranteed public contract.
How recipient resolution works
Each recipient item follows one of two paths:
recipient_idpresent: internal Piaxis transfer to that Piaxis accountrecipient_idomitted: external payout through the batchpayment_method
When present, recipient_id must be a Piaxis Account.id. Do not send a
MerchantProfile.id or UserProfile.id there.
For external mobile-money payouts:
phone_numberis the routing field that matters for MTN and Airtelemailis optional metadata, not the mobile-money routing keythe beneficiary does not need to be a Piaxis user
When recipient_id is needed
Use recipient_id only when the beneficiary should receive funds into a Piaxis wallet.
Typical cases:
a merchant wants to pay another business that already uses Piaxis
a platform wants to pay a service provider into that provider’s Piaxis wallet
you have already connected the beneficiary through the public OAuth flow and persisted the returned
user_id
How to obtain a Piaxis recipient_id safely:
send the beneficiary through
GET /api/authorizeexchange the authorization code through
POST /api/tokenpersist the returned
user_idfrom the token responselater use that stored
user_idasrecipients[].recipient_id
If the beneficiary should receive on external mobile money instead, do not use
recipient_id. Omit it and send the payout phone number with the batch
payment_method.
Payment-method scope
payment_method is a top-level batch field.
That means:
all external recipients in one batch use the same payout rail
if you need some recipients paid by MTN and others by Airtel, create separate batches
internal recipients identified by
recipient_idare processed as internal wallet transfers and do not depend on the external payout rail
For the currently documented public mobile-money payout rail, use mtn or airtel.
Authentication
Use merchant API key authentication:
api-key: YOUR_MERCHANT_API_KEY
Content-Type: application/json
X-piaxis-Client-ID: YOUR_MERCHANT_CLIENT_ID
Create Disbursement
Quote Disbursement
- POST /api/disbursements/quote
Preview recipient-level fees and the total merchant wallet debit before submitting a payout batch.
Guaranteed quote response fields
currencypayment_methodrecipient_countinternal_recipient_countexternal_recipient_counttotal_amountinternal_total_amountexternal_total_amounttotal_fee_amounttotal_debit_amountitems
Representative response shape
{
"currency": "UGX",
"payment_method": "mtn",
"recipient_count": 2,
"internal_recipient_count": 0,
"external_recipient_count": 2,
"total_amount": "2750000.00",
"internal_total_amount": "0.00",
"external_total_amount": "2750000.00",
"total_fee_amount": "2500.00",
"total_debit_amount": "2752500.00",
"items": [
{
"recipient_id": null,
"email": null,
"phone_number": "+256700123456",
"amount": "1500000.00",
"payout_type": "external",
"fee_amount": "1500.00",
"total_debit_amount": "1501500.00",
"reference": "SALARY-JUNE-001",
"fee_breakdown": [
{
"fee_id": "00000000-0000-0000-0000-000000000001",
"fee_name": "Default disbursement fee",
"fee_type": "tiered",
"amount": "1500.00",
"description": "Default UGX disbursement fee tier"
}
]
}
]
}
- POST /api/disbursements
Create a direct disbursement batch.
Canonical example
POST /api/disbursements HTTP/1.1
Host: api.gopiaxis.com
api-key: YOUR_API_KEY
Content-Type: application/json
X-piaxis-Client-ID: YOUR_MERCHANT_CLIENT_ID
{
"recipients": [
{
"recipient_id": "096b723a-45c5-4957-94d7-747835136265",
"email": "[email protected]",
"phone_number": "+256700123456",
"amount": "1500000.00",
"reference": "SALARY-JUNE-001"
},
{
"email": "[email protected]",
"phone_number": "+256700654321",
"amount": "1250000.00",
"reference": "SALARY-JUNE-002"
}
],
"currency": "UGX",
"payment_method": "mtn",
"description": "June contractor payouts"
}
External mobile-money rules
For an external mobile-money recipient in this route:
include
phone_numberchoose the batch
payment_methodasmtnorairteldo not assume
recipient_idis requireddo not assume the beneficiary needs a Piaxis account
If you only send email and omit both recipient_id and phone_number,
the request may pass schema validation but it is not a valid MTN or Airtel payout target.
Guaranteed create response
{
"disbursement_id": "b6b93a8b-2c81-44bf-9d98-9a43f725b90f",
"status": "processing",
"total_amount": "2750000.00",
"total_fee_amount": "2500.00",
"total_debit_amount": "2752500.00",
"internal_total_amount": "0.00",
"external_total_amount": "2750000.00",
"currency": "UGX",
"recipient_count": 2,
"successful_count": 0,
"failed_count": 0,
"pending_count": 2
}
Get Disbursement
- GET /api/disbursements/{disbursement_id}
Guaranteed response fields:
disbursement_idstatustotal_amounttotal_fee_amounttotal_debit_amountinternal_total_amountexternal_total_amountcurrencypayment_methoddescriptioncreated_atcompleted_atcancelled_atcancellation_reasonitems
List Disbursements
- GET /api/disbursements
Supported query parameters:
statusfrom_dateto_dateoffsetlimit
Representative response shape
{
"total": 1,
"offset": 0,
"limit": 50,
"results": [
{
"disbursement_id": "b6b93a8b-2c81-44bf-9d98-9a43f725b90f",
"status": "processing",
"total_amount": "2750000.00",
"total_fee_amount": "2500.00",
"total_debit_amount": "2752500.00",
"internal_total_amount": "0.00",
"external_total_amount": "2750000.00",
"currency": "UGX",
"recipient_count": 2,
"successful_count": 0,
"failed_count": 0,
"pending_count": 2
}
]
}
Cancel Disbursement
- POST /api/disbursements/{disbursement_id}/cancel
Guaranteed request field:
reason
Example
{
"reason": "Incorrect recipient information"
}
Marketplace Mapping
For platform payouts, keep two beneficiary concepts clearly separated:
internal Piaxis beneficiary: map your beneficiary id to a trusted Piaxis
recipient_idexternal mobile-money beneficiary: store the beneficiary phone number and intended payout method in your own beneficiary directory
For the internal-wallet path, that mapped recipient_id is always the
beneficiary’s Piaxis Account.id.
Never let raw recipient ids come directly from end-user form input.
Marketplace collect -> release -> payout example
For a platform or merchant-funded marketplace:
collect from the customer with direct payment or escrow
the merchant or platform wallet receives the collected funds
if you used escrow, release the escrow to the merchant or platform account named in
receiver_idcall
POST /api/disbursements/quotecreate a disbursement batch to the final beneficiary phone number
Example external payout item:
Collect to merchant:
{
"amount": "50000.00",
"currency": "UGX",
"payment_method": "mtn",
"user_info": {
"email": "[email protected]",
"phone_number": "+256700000000"
}
}
Release or settle to the merchant/platform wallet, then disburse:
{
"recipients": [
{
"phone_number": "+256700123456",
"amount": "45000.00",
"reference": "ORDER-1001-NET-PAYOUT"
}
],
"currency": "UGX",
"payment_method": "airtel",
"description": "Net payout after platform fee"
}
This flow does not require the final beneficiary to have a Piaxis account.
Fee Behaviour
Disbursement fees are configurable through the Piaxis fee policy system and can be targeted by merchant, company, role, account type, and channel. When no merchant-specific rule is configured, the public UGX direct-disbursement surface uses this default tier for external mobile-money style payouts:
up to
100000 UGX:500 UGXabove
100000 UGXup to1000000 UGX:1000 UGXabove
1000000 UGX:1500 UGX
Internal recipient transfers do not apply this external payout fee tier.