Integrator commissions
Earn your own commission on the money that moves through your platform - set it per movement type, see it on every quote, have it credited to your ledger, and report on what you earned.
The platform charge pays PayDirect. If you want to earn on the money that moves through your platform as well, add an Integrator commission: your own fee, priced alongside the platform charge, and credited to your ledger balance each time a transaction succeeds. You withdraw it like any other balance.
A worked example
You send GHS 100 through PayDirect. The platform charge is 1%, paid by the sender, and you have set a 0.05% commission on sends.
| Without a commission | With a 0.05% commission | |
|---|---|---|
| Sender is debited | GHS 101.00 | GHS 101.05 |
| Recipient receives | GHS 100.00 | GHS 100.00 |
Platform charge (charges) |
GHS 1.00 | GHS 1.00 |
Your commission (commission) |
- | GHS 0.05, credited to your ledger |
The recipient is paid exactly what they would have been. The commission is added to what the
sender pays, and lands on your ledger as a COMMISSION_CREDIT entry once the send succeeds.
Who pays the commission
A commission always follows the platform charge's bearer for that movement (see who bears the charge):
chargeBearer |
Payer is debited | Beneficiary receives |
|---|---|---|
SENDER |
amount + charge + commission |
amount |
RECIPIENT |
amount |
amount - charge - commission |
Under RECIPIENT, the commission never takes more than is left of the amount after the platform
charge: on a small amount it is reduced (possibly to zero) rather than rejecting the payment. The
reduced figure is what is stored on the transaction and credited.
Where commissions apply
| Movement | Commission |
|---|---|
SEND_MONEY |
Yes |
PAY_BILL |
Yes |
PAYOUT (/transactions/disburse) |
Only under a RECIPIENT charge - the recipient receives less and you keep the difference |
COLLECTION (and hosted checkout, gateway pay-bill-ext) |
Under SENDER, always. Under RECIPIENT, only on a split collection |
WITHDRAWAL, subaccount settlements |
Never - these move your own balance |
Two combinations are skipped on purpose, because you would only be paying yourself:
- a
PAYOUTunder aSENDERcharge: your ledger funds the payout, so the commission would be debited from you and credited straight back; - an unsplit
COLLECTIONunder aRECIPIENTcharge: the collected money is credited to you anyway.
A skipped commission is 0, and the quote and the transaction say why
(commissionSkippedReason). Commissions only apply to transactions made with an API key - TEST
or LIVE - never to dashboard-session transactions.
Scopes
Reading your commissions needs COMMISSIONS_READ; setting them needs COMMISSIONS_WRITE.
Neither is in the default set a new key receives - ask PayDirect to add them. Your Integrator's
owner can also manage commissions from a dashboard session, and members with the
transaction-read permission can read them.
Setting a commission
A commission schedule covers one environment, movement type and currency, and optionally one
channel (MTN, BANK_ACCOUNT, ...). A channel-specific schedule wins over an any-channel one.
The rule shape is the same as a platform charge: FLAT, PERCENTAGE, FLAT_PLUS_PERCENTAGE
or TIERED, with optional minCommission / maxCommission.
POST /integrators/{integratorId}/commissions/configs
{
"movementType": "SEND_MONEY",
"currency": "GHS",
"commissionType": "PERCENTAGE",
"percentage": 0.05
}
An API key always acts in its own environment. From a dashboard session, also send
"environment": "TEST" or "LIVE". Try a schedule in TEST first - TEST and LIVE schedules,
earnings and balances are completely separate.
Changing a rate never edits a schedule in place - it opens a new revision, and every transaction keeps a snapshot of the exact revision it was priced with:
POST /integrators/{integratorId}/commissions/configs/{configId}/revisions
POST /integrators/{integratorId}/commissions/configs/{configId}/deactivate
POST /integrators/{integratorId}/commissions/configs/{configId}/activate
GET /integrators/{integratorId}/commissions/configs
GET /integrators/{integratorId}/commissions/configs/{configId}
effectiveFrom may be in the future, never in the past. Every change is recorded in the audit
trail with who made it.
How much you can charge
The commission is yours to set: PayDirect only prices its own charge and places no cap on what you charge. A percentage must be between 0 and 100, and a flat or tiered commission is charged exactly as configured. Three things still bound it:
- Under a
RECIPIENT-borne charge the recipient absorbs the charge and your commission, so your commission is trimmed to what is left after PayDirect's charge. It never fails the payment. - Until PayDirect verifies your Integrator, your commission on any one transaction is trimmed to
20% of its amount. The quote reports this with
commissionCapApplied: true. Verification lifts it. - PayDirect can suspend an Integrator's commissions. While suspended, no new commission is charged; what you already earned is untouched. See the status with:
GET /integrators/{integratorId}/commission-policy
maxPercentage in that response is a legacy field and is null. On a transaction's commission
snapshot, cap is null-valued too, except while the unverified-Integrator trim above applies.
Quoting
Always quote before you charge a customer. POST /transactions/quote-charge includes your
commission in totalDebit and netAmount automatically, and adds commission and
commissionSkippedReason. For a collection, pass "hasSplit": true when you will split it, and
for PAY_BILL pass "singleLeg": true when you will use pay-bill-ext.
To preview a schedule from your own side, including the rule that matched:
POST /integrators/{integratorId}/commissions/quote
{
"amount": 100,
"currency": "GHS",
"charge": 1,
"commission": 0.05,
"chargeBearer": "SENDER",
"totalDebit": 101.05,
"netAmount": 100,
"commissionSkippedReason": null
}
When it is credited
Your commission is credited only when the transaction succeeds, never while it is PENDING.
It lands as a COMMISSION_CREDIT entry on your ledger, in the
transaction's currency and environment. It is credited exactly once, however many times the transaction is
reconciled.
On a split collection the commission is not part of anyone's split share: your subaccounts are credited net of the charge and the commission, and the commission is credited to you separately.
If a transaction is later confirmed FAILED after it was reported successful, the commission is
taken back with a COMMISSION_REVERSAL entry. If you had already withdrawn it, your balance can go
below zero; payouts and withdrawals are then refused until it is covered.
Webhook payloads carry commission next to charges.
Reporting on what you earned
Every commission credit is an earning you can search, summarize and chart. All reporting
endpoints take from / to (ISO 8601, default the last 30 days, at most 366 days) and the same
filters: movementType, currency, channel, status (EARNED or REVERSED),
chargeBearer, minAmount / maxAmount, and q - a transaction id or the start of your own
reference.
GET /integrators/{integratorId}/commissions/earnings?from=2026-09-01T00:00:00.000Z&movementType=SEND_MONEY&pg=1&ipp=50
GET /integrators/{integratorId}/commissions/earnings/{earningId}
GET /integrators/{integratorId}/commissions/earnings/export
The search is paginated (ipp up to 100) and sortable (sortBy=earnedAt|amount,
sortOrder=asc|desc). An earning's detail includes the transaction and both pricing snapshots.
The export returns the same rows as CSV.
Summary
GET /integrators/{integratorId}/commissions/summary?compareToPrevious=true
Per currency - amounts in different currencies are never added together - you get earnedTotal,
reversedTotal, grossTotal, netTotal, counts, averageCommission and
effectiveRatePercent (commission as a share of the principal it was earned on), plus
breakdowns byMovementType and byChannel. compareToPrevious=true adds the same period just
before, and changePercent.
An API key always reports on its own environment. A dashboard session that sends no environment
gets LIVE for the summary, the time series and the staff overview, so TEST earnings are never
added to LIVE ones; send environment=TEST to see the sandbox.
Time series for charts
GET /integrators/{integratorId}/commissions/timeseries?grain=day&groupBy=movementType
grain is hour (ranges up to 7 days), day, week (weeks start on Monday) or month.
Buckets are UTC. The response lists every bucket in buckets, and each series has a point for
every bucket - zero where nothing was earned - so it can be plotted directly:
{
"grain": "day",
"groupBy": "movementType",
"buckets": ["2026-09-01T00:00:00.000Z", "2026-09-02T00:00:00.000Z"],
"series": [
{
"currency": "GHS",
"movementType": "SEND_MONEY",
"total": 12.4,
"count": 248,
"points": [
{ "bucket": "2026-09-01T00:00:00.000Z", "amount": 0, "count": 0 },
{ "bucket": "2026-09-02T00:00:00.000Z", "amount": 12.4, "count": 248 }
]
}
]
}
Without groupBy there is one series per currency. Only EARNED commissions are charted.
Getting paid
Commission is ledger balance. Withdraw it to your registered settlement account with
POST /transactions/withdraw - see the ledger and settlement.
LIVE commission is held for 24 hours (TEST is never held) before it can leave. It shows in currentBalance at once, but a payout or withdrawal
that would spend into still-held commission is refused. GET /integrators/{integratorId}/ledger
reports heldCommission and availableBalance per currency and environment, and each earning's
availableAt says when it is released. If the transaction later fails, the commission is reversed
while held, so nothing has left. To see
just your commission movements on the ledger, filter the entry log:
GET /integrators/{integratorId}/ledger/entries?type=COMMISSION_CREDIT&from=2026-09-01T00:00:00.000Z