Skip to content

Reports

Reports, under Overview, gives “figures for any date range up to 400 days, in one currency and environment, each exportable as CSV.” There are 25 reports, in five groups. Every report is read-only, and every one is served by a GET /v1/reports/* endpoint.

You see only the reports your role can open. A report is listed only if you hold every permission its endpoint needs. Those permissions are given in the tables below, and they are the same ones the server checks. A group with nothing you can open is left out. If you can open none at all, the page says “You cannot see any report.” A report shows nothing you could not already see record by record elsewhere in the console.

Control What it does
Date range Presets from Last 24 hours to Last 12 months, or a custom From and To. The default is the last 30 days and the maximum is 400 days. A wider window is refused, not cut short: “Narrow it rather than receiving a figure computed over a window you did not ask for.”
Environment Live by default. Test figures are developers testing, and a report that mixed the two would be wrong in the flattering direction.
Currency GHS by default, or NGN, XOF or USD. One currency at a time, because amounts in two currencies have no sum.
Group by Day, week or month, on reports with a chart. Weeks start on Monday.
Refresh Moves a rolling range forward to now, then reloads.
Export CSV See below.

Some reports ignore environment or currency, because what they count carries neither: risk alerts, KYC, onboarding, staff activity, sign-ins, data requests, and the count-only operations reports. Those controls are hidden there. Some reports add their own filters, such as partner, channel, direction or threshold.

Filters live in the address. A link opens the same report, and Back undoes a filter change. A rolling range is stored as “the last N days”, so a shared link to the last 30 days means the last 30 days whenever it is opened.

Days are UTC, which is Accra time all year. So a report’s day is the same day as the partners’ and the settlement statements’. A custom range runs from 00:00 on From to the end of To. In the API, to is exclusive.

Revenue fields are our fee, partner cost, net revenue, margin and MRR. Without ledger.read they are left out, not shown as zero. The column, figure or CSV column simply isn’t there. For example, the merchant volume ranking can’t rank by revenue without it. Money position, Revenue and margin, and Merchant balances need ledger.read to open at all.

Every report exports what it shows:

  • Amounts are in major units with no thousands separator (1250.00). The currency is in its own column. Dates are ISO 8601.
  • Formula injection is defused. A cell that starts with =, +, -, @, a tab or a carriage return gets an apostrophe in front of it. Negative amounts are numbers and are left alone.
  • Paged lists are fetched in full, up to 50,000 rows. Past that, the export stops and says so: “Export stopped at 50,000 rows. Narrow the range to export the rest.”
  • Files are UTF-8 with a BOM, so Excel reads names correctly. They are named paysigna-<report>[-test]-<CURRENCY>-<from>_to_<to>.csv.

A rate whose denominator is zero shows —, not 0%. A rate over nothing is unknown, not zero.

All 25 reports take the same query parameters:

  • from: inclusive.
  • to: exclusive.
  • environment: defaults to live.
  • currency: defaults to GHS.

from and to take RFC 3339 or a plain date. to defaults to now, and from to 30 days before it.

Every response echoes environment, currency, from, to and revenue_visible (whether you hold ledger.read). That way a short report can be told apart from a short window. The permissions each endpoint needs are in the tables below.

“Where the money is, what we earned, and whether it all adds up.”

Report Permissions What it shows
Partner statement transaction.read, partner.read What each partner carried: collected, failed, paid out, settled, refunded, reversed and in flight. Our fee, partner cost and net revenue are added with ledger.read. Click a partner for every transaction it carried, filterable by kind and outcome.
Daily money position ledger.read Each day’s money in and out, and what we owe merchants against what the ledger holds at the partners. Also shows the difference, and a “now” split of what is owed: available, pending, held, suspense, tax and commission payable.
Revenue and margin ledger.read Our fee, partner cost, referral share, net revenue, take rate and margin, broken down by merchant, partner or channel. Each breakdown adds up to the totals. Tax collected and merchant commission are shown but are not ours.
Settlements settlement.read Batches whose period ended in the range, by status and by merchant. Shows time to pay from the end of the period and from approval, and the failed and held batches.
Partner reconciliation settlement.read For each partner, by statement date: matched, unmatched, amount-mismatched, duplicate and resolved lines. Also the mismatch variance and how long the oldest open line has waited.
Merchant balances, aged ledger.read Each merchant’s balance, available, pending, reserve and on hold, with held funds aged into 0–7, 8–30, 31–90 and over 90 days.
Commissions settlement.read For each beneficiary: earned, due, in progress and paid, split into merchant-funded and referral share. Covers shares of transactions created in the range that landed.

Net revenue is our platform fee, less the partner’s whole charge, less referral shares paid out of our fee. The partner’s charge is the actual figure from their statement, or until then the expected fee plus its tax. Take rate is our fee over volume. Margin is net revenue over our fee. These are the same figures pricing’s margin check, the Overview and the Margin tab use.

What these reports can’t show:

  • Money position: flows are dated by when the transaction was created, and balances by when the ledger posted. So a payment created late one day and confirmed the next appears in one day’s flows and the next day’s balance. End-of-day balances are worked back from today’s. The pending and available split has no history, so it is for now only.
  • Merchant balances: balances, pending, reserve and holds are as of now, whatever the range. The range affects only the holds placed and released in it. If held funds don’t equal reserve plus on-hold, the page warns “Held funds do not match the open holds”. The ledger’s invariant check names the accounts.

“How the partners and the platform performed.”

Report Permissions What it shows
Partner performance transaction.read, partner.read Success rate, partner calls, failed calls, and response times (p50, p95, max) for each partner, per channel and per network. Can be grouped by hour for windows of 7 days or less.
Routing outcomes routing.read, transaction.read What each routing rule sent where: routed, landed, failed, retried, failed over and where the transactions ended up. The rule credited is the one on the first attempt.
Failure analysis transaction.read Why transactions failed: by side, class, the 50 commonest codes, partner, method, and the 50 merchants with the most failures.
Stuck transactions transaction.read Transactions still initiated, pending, processing or awaiting the customer for longer than their channel should take. Totals by partner, plus a list with oldest first.
Webhook delivery health merchant.read Delivery rate, retrying and exhausted deliveries, and the merchants and endpoints that are failing.

The definitions:

  • Success rate is landed ÷ (landed + failed). In flight counts against no one.
  • Response times are how long the partner took to answer us, not the customer. They include calls lost to a failover.
  • Failure sides:
    • Customer: no funds, declined, wrong details, or a prompt never approved.
    • Partner: no answer, unreachable or unavailable.
    • Platform: configuration, internal, risk, duplicate or limits.
    • Anything without a class, such as a cancellation, is counted as unclassified.
  • Stuck means past 15 minutes for mobile money and USSD, 30 minutes for card, 2 hours for bank and 5 minutes for wallet. Cash is recorded by hand and is never listed. Unlike the other operations reports, this one is filtered by currency.
  • Webhooks: retrying means the last attempt failed and another is scheduled. Exhausted means every attempt was used and the merchant never received the event. An endpoint failing now is listed even if it had no deliveries in the range.
  • Routing outcomes puts transactions with no rule recorded in a last row, and says so.

“Who is trading, growing, joining and paying.”

Report Permissions What it shows
Merchant volume ranking merchant.read, transaction.read Every merchant that transacted, ranked by value, count or (with ledger.read) revenue. Growth is compared with the window of the same length just before.
Merchant activity merchant.read How many merchants were new, activated, active, dormant (live with nothing landed in the 30 days to the range’s end) or churned (active the period before, not this one). Lists the merchants in each segment. The segments overlap.
Onboarding funnel merchant.read, kyc.read How far the merchants who signed up in the range have got: KYC submitted, approved, live, first live payment. Shows the median time at each step. Counted as of now, in the live environment, in any currency. A sub-account shares its organisation’s KYC.
Merchant billing activity merchant.read, transaction.read The subscriptions and invoices merchants run for their own customers, not PaySigna billing merchants. Shows subscriptions started, ended, active and past due, invoices issued, paid and written off, and MRR with ledger.read.

Subscription counts marked “now”, and MRR, are as of today whatever the range, because no subscription status history is kept.

“Disputes, alerts, unusual activity and KYC.”

Report Permissions What it shows
Disputes and chargebacks dispute.read Disputes opened in the range, by stage and outcome as they stand now. Also value lost, deadlines missed, and the dispute rate per merchant (disputes opened ÷ collections landed).
Risk alerts risk.read Alerts raised per rule, including in shadow mode. Shows true and false positives, precision (true ÷ judged), and median time to review.
Large and unusual transactions transaction.read, risk.read Transactions at or above a threshold (default 50,000, any direction and outcome). Also merchants whose landed volume jumped (default 3× the previous window and at least 100,000), and merchants live for 30 days or less already moving that much.
Refunds and reversals transaction.read Refunds and reversals per merchant and per partner. The refund rate is refunded ÷ collected; the reversal rate is reversed ÷ (collected + reversed).
KYC status kyc.read, merchant.read Submissions and review time, the review queue by age, and documents expiring within 90 days. Leads with the live merchants that traded in the range with KYC missing, unapproved or expired.
Regulatory summary transaction.read Number and value of transactions by channel and direction, per month, week or day. Also active merchants and unique customers.

What these reports can’t show:

  • Large transactions: the threshold is a working figure, not a statutory one. “Statutory reporting thresholds … must be confirmed with compliance before this list is used for a filing.”
  • Regulatory summary: not yet in the official return format. It is the content a Bank of Ghana return draws on, not the return itself. Once the official template is supplied, the report will be shaped to it line for line. Unique customers are counted once across merchants and periods. Landed transactions with no recorded counterparty can’t be counted as customers and are shown separately.
  • KYC status: approved documents with no expiry date are not listed.

“What staff did and who signed in.”

Report Permissions What it shows
Staff activity audit.read What each member of staff did, apart from signing in and out. It marks privileged actions (approvals, pricing, suspensions, holds and releases, credentials and access) and refused attempts at a dual-controlled permission. You can drill down to the audit entries.
Sign-ins audit.read Staff sign-ins, failures by reason, lockouts, and new addresses or devices. A new address or device is one that person hadn’t used in the year before. Also merchant sign-ins, with two-factor and lockouts.
Data requests gdpr.process Data-subject requests by type, status and merchant: time to close, those closed late, and those open past the legal deadline (extensions included).

What these reports can’t show:

  • Sign-ins: idle sign-outs are not recorded on the server yet. The consoles end an idle session themselves (see Signing in).
  • Sign-ins: the merchant API records no failed sign-in attempts. So failures and their reasons are for staff only, and a merchant’s two-factor figure is their setting now, not what it was at sign-in.
  • Data requests: requests about consumers or bare identifiers belong to no merchant, so they are counted but are not in the per-merchant table.