Transaction Reconciliation Guide
Platform Disbursements - Reconciliation Guide
For Cadana platform partner's, you manage multiple businesses (sub-clients) and their payroll, payouts, and other financial operations. The Platform Disbursements endpoint gives you a single, unified view of all transactions across every business under your platform -- the data you need to reconcile your books.
Endpoint
GET /v1/platform/disbursements
This endpoint automatically aggregates transactions from all businesses under your platform. You do not need to query each business individually.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
startDate | string | No | Start of date range (ISO 8601, e.g. 2026-01-01). Defaults to 7 days ago. |
endDate | string | No | End of date range (ISO 8601, e.g. 2026-02-01). Defaults to now. |
type | string | No | Comma-separated transaction types to include (see Transaction Types). |
status | string | No | Filter by status: SUCCESS, FAILED, INITIATED, PROCESSING. |
Example request:
GET /v1/platform/disbursements?startDate=2025-12-01&endDate=2026-02-10&type=PAYROLL,PAYOUT,CARD_MAINTENANCE_FEE,CARD_CREATION_FEE,STOCK_BUY,STOCK_SELL,INTEREST&status=SUCCESS
Response Structure
The response contains an array of transaction objects and a cursor for pagination:
{
"data": [ ... ],
"cursor": {
"previous": null,
"next": null
}
}Transaction Object Fields
| Field | Type | Description |
|---|---|---|
id | string | Unique transaction identifier. |
tenantKey | string | Identifies which business this transaction belongs to. Use this to group transactions per business. |
status | string | Transaction status (SUCCESS, FAILED, INITIATED, etc.). |
referenceId | string | External reference ID. Payroll transactions from the same run share the same referenceId. |
description | string | Human-readable description (e.g. "January 2026 Payment Dundies", "Virtual Card Maintenance Fee"). |
type | string | Transaction type (see Transaction Types). |
fxRate | number | Foreign exchange rate applied. Present only for cross-currency transactions. |
paymentMethod | string | Delivery method: bank, momo, wallet, ach, card, proxy. |
paymentDetails | object | Full payment method details (bank account, mobile money, wallet, ACH, card info). |
userId | string | The wallet/user account ID. Present on wallet-based transactions. For payroll, only present when the payment is delivered to a wallet. |
personId | string | The employee or contractor ID. Present only on payroll transactions. Use this as the primary identifier for payroll recipients. |
userName | string | Recipient name. |
amount | object | Amount the recipient receives, in the destination currency. |
sourceAmount | object | Cost in the source currency, before fees. |
feeAmount | object | Fees charged, in the source currency. |
totalAmount | object | Total debited from the sender (sourceAmount + feeAmount). |
fxRevenueShare | object | Revenue earned from the FX spread (see Revenue Share). |
feeRevenueShare | object | Revenue earned from fees (see Revenue Share). |
totalRevenueShare | object | Combined total revenue share. |
createdTimestamp | string | When the transaction was created. |
lastUpdatedTimestamp | string | When the transaction was last updated. |
All amount fields follow this structure:
{
"value": "100.00",
"currency": "USD"
}Identifying Businesses with tenantKey
tenantKeyEvery transaction includes a tenantKey that identifies which business it belongs to. When you have multiple businesses under your platform, use tenantKey to group and reconcile transactions per business.
For example, a single API call might return transactions from three different businesses:
[
{ "id": "...", "tenantKey": "tbl28153208", "type": "PAYROLL", ... },
{ "id": "...", "tenantKey": "tbl89195039", "type": "PAYROLL", ... },
{ "id": "...", "tenantKey": "cad35916961", "type": "PAYOUT", ... }
]Group by tenantKey to produce per-business reconciliation reports.
Transaction Types
| Type | Description |
|---|---|
PAYOUT | An outbound transfer from a user's wallet to an external bank account, mobile money, card, or other destination. |
PAYROLL | A payment from a business to an employee or contractor as part of a payroll run. |
CARD_MAINTENANCE_FEE | A recurring maintenance fee for a virtual card. |
CARD_CREATION_FEE | A one-time fee for creating a virtual card. |
STOCK_BUY | A stock purchase transaction. |
STOCK_SELL | A stock sale transaction. |
INTEREST | Interest earned or charged. |
PAYROLL_FEE | The processing fee for a payroll run (see Payroll Fee & Invoice Details). |
Wallet Transactions
Transactions of type PAYOUT, CARD_MAINTENANCE_FEE, CARD_CREATION_FEE, STOCK_BUY, STOCK_SELL, and INTEREST are wallet-level operations. They are associated with a user via the userId field, which identifies the wallet account.
These transactions may include revenue share fields depending on your platform agreement.
Example -- a cross-currency payout to a bank account in Brazil:
{
"id": "c5bcdbba-52a2-44a4-8dda-2b03d47a1af1",
"tenantKey": "tbl28153208",
"status": "SUCCESS",
"type": "PAYOUT",
"fxRate": 5.7896,
"paymentMethod": "bank",
"userId": "8cb1d569-5dfd-4b33-b25e-4fab0ee14251",
"userName": "Paula Torres",
"amount": { "value": "578.96", "currency": "BRL" },
"sourceAmount": { "value": "100.00", "currency": "USD" },
"feeAmount": { "value": "13.50", "currency": "USD" },
"totalAmount": { "value": "113.50", "currency": "USD" },
"fxRevenueShare": { "amount": { "value": "1.00", "currency": "USD" }, "rate": 1 },
"feeRevenueShare": { "amount": { "value": "10.00", "currency": "USD" } },
"totalRevenueShare": { "value": "11.00", "currency": "USD" }
}Payroll Transactions
Payroll transactions (type: "PAYROLL") represent individual payments to employees or contractors as part of a payroll run. The key identifier is:
personId-- the specific employee or contractor being paid. This is always present on payroll transactions and is the primary identifier you should use for reconciliation.userId-- only present when the payroll payment is delivered to a wallet. Not present for external payroll payments (bank, mobile money, etc.).
The description field contains the name of the payroll run (e.g. "January 2026 Payment Dundies"). Multiple transactions from the same payroll run share the same referenceId, which lets you group all payments within a single run.
Example -- a cross-currency payroll payment to a bank account:
{
"id": "a2f47c91-3b8e-4d12-9c6a-7e5d1f8b2a40",
"tenantKey": "tbl89195039",
"status": "SUCCESS",
"referenceId": "9c4829a8-0177-4dad-a0d8-e4f8fc42276a",
"description": "January 2026 Payment Dundies",
"type": "PAYROLL",
"fxRate": 5.812,
"paymentMethod": "bank",
"personId": "0a938505-ae3f-44a2-9793-196a4a11e6f2",
"userName": "Maria Santos",
"amount": { "value": "5812.00", "currency": "BRL" },
"sourceAmount": { "value": "1000.00", "currency": "USD" },
"totalAmount": { "value": "1000.00", "currency": "USD" },
"fxRevenueShare": { "amount": { "value": "10.00", "currency": "USD" }, "rate": 1 },
"totalRevenueShare": { "value": "10.00", "currency": "USD" }
}Note that userId is absent here because the payment was delivered to an external bank account, not a wallet.
Example -- a same-currency payroll payment via wallet:
{
"id": "c6250a16-eb63-41de-a952-8122d305ebbf",
"tenantKey": "tbl12101631",
"status": "SUCCESS",
"referenceId": "7b82d74e-4ad5-4fbf-af9c-a0f11b224c7a",
"description": "January 2026 Payment PS",
"type": "PAYROLL",
"paymentMethod": "wallet",
"userId": "060e3aeb-4a9d-4a90-aff5-17f8d69635ce",
"personId": "8ab2ba37-3c37-485d-9af9-122d11c96bf9",
"userName": "Reed Maygone",
"amount": { "value": "1000.00", "currency": "USD" },
"sourceAmount": { "value": "1000.00", "currency": "USD" },
"totalAmount": { "value": "1000.00", "currency": "USD" }
}Here userId is present because the payment went to the employee's wallet. Same-currency payroll has no fxRate or FX revenue share, and may not have fee fields since fees are captured in the payroll fee transaction instead.
Understanding Amounts
Each transaction has four amount fields that tell you the full financial picture:
| Field | Description |
|---|---|
amount | What the recipient receives, in the destination currency. |
sourceAmount | The cost in the sender's currency, before fees. |
feeAmount | Fees charged, in the sender's currency. |
totalAmount | Total debited from the sender: sourceAmount + feeAmount. |
Cross-Currency Example
When a user sends USD and the recipient receives BRL:
sourceAmount: 100.00 USD (cost before fees)
feeAmount: 13.50 USD (fees)
totalAmount: 113.50 USD (total debited = 100.00 + 13.50)
fxRate: 5.7896 (USD -> BRL conversion rate)
amount: 578.96 BRL (what the recipient gets: 100.00 * 5.7896)
Same-Currency Example
When both sides are in the same currency, no FX conversion applies:
sourceAmount: 1000.00 USD
feeAmount: 0.00 USD
totalAmount: 1000.00 USD
amount: 1000.00 USD (same as source, no conversion)
Revenue Share
If your platform has a revenue share agreement with Cadana, eligible transactions will include revenue share fields showing your earnings. These fields are only present when applicable -- they are omitted when no revenue share applies to a given transaction.
| Field | Description |
|---|---|
fxRevenueShare | Revenue earned from the FX spread. Contains amount (value + currency) and rate (the share percentage). |
feeRevenueShare | Revenue earned from transaction fees. Contains amount (value + currency). |
totalRevenueShare | The combined total of FX and fee revenue share. Contains value and currency. |
Example -- transaction with both FX and fee revenue share:
{
"fxRevenueShare": {
"amount": { "value": "0.41", "currency": "USD" },
"rate": 1
},
"feeRevenueShare": {
"amount": { "value": "10.07", "currency": "USD" }
},
"totalRevenueShare": { "value": "10.48", "currency": "USD" }
}In this case, the platform earned $0.41 from the FX spread and $10.07 from fees, totaling $10.48 in revenue share.
Example -- transaction with only FX revenue share:
{
"fxRevenueShare": {
"amount": { "value": "0.10", "currency": "USD" },
"rate": 1
},
"totalRevenueShare": { "value": "0.10", "currency": "USD" }
}No revenue share: If a transaction has no revenue share agreement applicable, these fields will be absent from the response entirely.
Payroll Fee & Invoice Details
When a business runs payroll, a separate PAYROLL_FEE transaction may appear in the response. This represents the processing fee charged for the entire payroll run.
To see the detailed breakdown of how the payroll fee was calculated (line-item details for each employee payment within the run), use the Get Invoice endpoint:
The invoice provides a full breakdown of the charges associated with a payroll run, including per-employee costs, FX markups, and fees.
Pagination
Results are paginated. The cursor object in the response tells you whether more pages are available:
{
"cursor": {
"previous": null,
"next": "eyJsYXN0S2V5Ijp7InBrIjoiLi4uIn19"
}
}cursor.next-- pass this value as thecursorquery parameter to fetch the next page.cursor.previous-- pass this to go back to the previous page.nullmeans there are no more pages in that direction.
Example -- fetching the next page:
GET /v1/platform/disbursements?startDate=2025-12-01&endDate=2026-02-10&status=SUCCESS&cursor=eyJsYXN0S2V5Ijp7InBrIjoiLi4uIn19
Reconciliation Walkthrough
Here is a step-by-step approach to reconciling your books using this endpoint.
Step 1: Fetch all successful transactions for the period
GET /v1/platform/disbursements?startDate=2026-01-01&endDate=2026-02-01&status=SUCCESS&type=PAYROLL,PAYOUT,CARD_MAINTENANCE_FEE,CARD_CREATION_FEE,STOCK_BUY,STOCK_SELL,INTEREST
Paginate through all results using the cursor.next value until cursor.next is null.
Step 2: Group by business
Group transactions by tenantKey to build per-business ledgers:
| tenantKey | Transaction Count | Total Debited |
|---|---|---|
tbl28153208 | 15 | $627.47 USD |
tbl89195039 | 2 | $385.00 USD |
tbl12101631 | 2 | $3,000.00 USD |
cad35916961 | 6 | $103.55 USD |
Step 3: For payroll, identify employees by personId
personIdFilter for type: "PAYROLL" and group by personId to see how much each employee was paid:
| personId | Employee Name | Total Paid (destination) | tenantKey |
|---|---|---|---|
0a938505-ae3f-44a2-9793-196a4a11e6f2 | Elizabeth Wilson | 151.39 GHS | tbl89195039 |
00b39f7a-e914-4cf7-aca3-3ae35e5ade47 | Dwight Schrute | 5,677.18 GHS | tbl89195039 |
8ab2ba37-3c37-485d-9af9-122d11c96bf9 | Reed Maygone | 1,000.00 USD | tbl12101631 |
ca49c55b-12c7-4085-8a0d-ebd006ed8002 | Mahatra Ghandi | 2,000.00 USD | tbl12101631 |
Step 4: Calculate revenue share
Sum totalRevenueShare across all transactions to determine your platform's total earnings for the period. You can break this down further using fxRevenueShare and feeRevenueShare to understand the source of revenue.
Step 5: Get payroll fee details
For any PAYROLL_FEE transactions, use the Get Invoice endpoint to retrieve the detailed breakdown of how the fee was calculated, including per-employee line items.
Updated 2 days ago
