Skip to content
PayDirect Docs

Docs › Core concepts

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 PAYOUT under a SENDER charge: your ledger funds the payout, so the commission would be debited from you and credited straight back;
  • an unsplit COLLECTION under a RECIPIENT charge: 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.

text
POST /integrators/{integratorId}/commissions/configs
json
{
  "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:

text
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:
text
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:

text
POST /integrators/{integratorId}/commissions/quote
json
{
  "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.

text
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

text
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

text
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:

json
{
  "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:

text
GET /integrators/{integratorId}/ledger/entries?type=COMMISSION_CREDIT&from=2026-09-01T00:00:00.000Z