Wallet
Panel Guide
Overview & Permissions

Panel — Overview & Permissions

Who calls these endpoints?Merchant panel
Base path
/api/panel/v1/wallet
Identity
Panel session (JWT) — Authorization: Bearer <panel access token>. The token comes from panel login; an s2s signing key does NOT open these endpoints.
Authorization
Every endpoint is bound to an RBAC permission code; codes are given per endpoint below.Four-eyes: the requester and the approver cannot be the same person — this is enforced by identity comparison, not by a role gate.
Cross-surface
The endpoints on this page have NO equivalent in the s2s API; you cannot call them from your own panel. These capabilities exist only in the merchant panel, behind a panel session.

The merchant panel is where you operate your wallet program: program settings, customer management, operational intervention, limit and fee schemes, campaigns, bulk payouts, terminals and reports.

The panel surface lives under /api/panel/v1/wallet/* and runs on your panel session (JWT). For server-to-server integration use the external API; for the end-user app use the portal. 132 panel endpoints have no s2s counterpart — see the surface comparison matrix.

Permission codes

Every panel action is bound to an RBAC permission code. You delegate authority by granting codes to team roles. The wallet surface currently defines 30 permission codes:

Program & policy

Permission codeWhat it opens
wallet:program:readProgram list and detail, the live program, the wallet-provider catalogue
wallet:program:manageCreating and editing programs — branding, currencies, onboarding mode, status
wallet:sponsor-policy:manageSponsor-policy drafts, bank integrations, provider switches, integration catalogue, merchant wallet providers
wallet:sponsor-policy:approveSponsor-policy version approve/reject, completing a provider switch, QR producer-code approve/retire — four eyes
wallet:config:manageAgent (dealer) definitions

End user & corporate account

Permission codeWhat it opens
wallet:enduser:readReading customers, corporate accounts, wallets, balances, limits, KYC level, deposit instructions and crypto balances
wallet:enduser:manageCreating customers, freeze/unfreeze/close, corporate account and employee management, assigning a merchant category
wallet:enduser:kyc-overrideRequesting a KYC level change — the change is applied once another person approves it
wallet:enduser:kyc-approveApproving a KYC level change request — a separate permission; enduser:manage is not enough; four eyes
wallet:legal-hold:manageAdding legal holds, viewing holds and the retention status, requesting the release of a hold — see Data Retention and Legal Holds
wallet:legal-hold:approveApproving a hold release request — a different person than the requester; four eyes

Operations & intervention

Permission codeWhat it opens
wallet:operation:readOperation list/detail, receipts, suspense funds, invoice and bill-payment monitoring, ops-health
wallet:operation:interveneManual operation intervention, suspense match/return, top-up refund, stuck withdrawals, cash-out holds — opening intervention requests and approving other people's requests; four eyes

Limits, fees & commission

Permission codeWhat it opens
wallet:limit:manageLimit schemes, assigning a scheme to a program, shared caps, OTP policy, spend-policy rules
wallet:fee:manageFee and commission schedules, the version submit/approve chain (four eyes), branch fees, the fee report

Campaigns & loyalty

Permission codeWhat it opens
wallet:campaign:manageCampaign and segment management, version submit and approve — approval is not a separate permission; four eyes is enforced by principal comparison
wallet:loyalty:readReading the loyalty program, earn rules, tier scheme, badges, point balance and history
wallet:loyalty:manageWriting the loyalty program, earn rules, tier scheme, badges and badge rules

Bulk payouts

Permission codeWhat it opens
wallet:bulk:createCreating, listing, items, preview, statement, counters, submit
wallet:bulk:approveApprove, reject, process, cancel, retry failed — a different person from create, four eyes

QR & terminals

Permission codeWhat it opens
wallet:qr:readListing and reading QR codes
wallet:qr:manageIssuing and revoking QR codes
wallet:terminal:readTerminal list, detail, event history and the terminal report
wallet:terminal:manageCreating terminals, issuing activation codes, issue/rotate/revoke credentials, suspend/resume/retire, bulk actions

Cards

Permission codeWhat it opens
wallet:card:readCard list, detail and authorization history
wallet:card:operateIssuing, freezing, unfreezing and cancelling cards
wallet:card:authorizeIssuer event endpoints: authorization, clearing, reversal (/card-events)

Cash-out

Cash-out endpoints live under /api/panel/v1/wallet/cash-out.

Permission codeWhat it opens
wallet:cashout:readCash-out request detail
wallet:cashout:operateGenerating and cancelling a cash-out code
wallet:cashout:dispenseConfirming that the cash was dispensed

Invoices & reports

Permission codeWhat it opens
wallet:invoice:manageIssuing and cancelling invoices
wallet:report:readOverview, operations, campaign and custody reports, the campaign report, operations export
⚠️

There are NO permission codes called wallet:campaign:approve or wallet:card:manage. Both were listed on this page before, but neither ever existed in the code; granting them to a role opens nothing. Campaign approval runs on wallet:campaign:manage (four eyes still applies) and card actions on wallet:card:operate.

The four-eyes rule

⚠️

On money-critical actions, the requester and the approver cannot be the same person. This is enforced not by a role gate but by principal comparison in the service layer: even when OWNER or ADMIN holds both permissions, the same user cannot approve their own request.

Four eyes is enforced in eleven places in the service layer:

ActionRelated permission
Manual operation intervention (stuck operation, withdrawal)wallet:operation:intervene
Suspense fund matchwallet:operation:intervene
Top-up refundwallet:operation:intervene
Releasing a cash-out holdwallet:operation:intervene
Bulk payout approvalwallet:bulk:approve
Fee schedule version approvalwallet:fee:manage
Commission schedule version approvalwallet:fee:manage
Campaign version approvalwallet:campaign:manage
Sponsor policy version approvalwallet:sponsor-policy:approve
QR producer-code approvalwallet:sponsor-policy:approve
KYC level changerequest wallet:enduser:kyc-override, approval wallet:enduser:kyc-approve
Legal hold releaserequest wallet:legal-hold:manage, approval wallet:legal-hold:approve

The first four rows, the KYC change and the legal hold release run as stored intervention requests: one operator opens a request and another person approves it on the Four-Eyes Approvals screen; the requester and the approver are taken from their panel sessions. Details: Four-eyes requests.

Note that four eyes does not always pair with a separate "approve" permission. For campaigns and fee schedules the preparer and the approver hold the same permission code; what keeps the rule standing is not the permission but the principal comparison in the service layer. You are still expected to hand those roles to different people operationally.

Step-up verification

Some actions require step-up verification on top of the panel session. This stops a hijacked operator session from moving money on its own.

Versioning and the approval chain

Configuration that changes money behaviour — fees, commission, campaigns — is never edited in place; it is versioned:

Four-eyes approval chainState machine: a draft is submitted, waits for approval, becomes active once approved and is retired at the end of its life. A rejected draft ends on its own branch.SUBMITAPPROVERETIREREJECTDRAFTPENDING_APPROVALACTIVERETIREDREJECTEDLEGENDWAITINGIN FORCEEND
The same chain governs fee schedules, limit schemes and sponsor policy. The approver must differ from the submitter — four-eyes is enforced in the service layer, not in the UI.

Past operations remain traceable to their own version. When a report shows an unexpected fee, the operation's scheduleVersionId tells you which version was in force at the time.

Sections

When delegating permissions

  1. Give maker and checker to different people. bulk:create and bulk:approve are separate codes — put them in separate roles. Campaigns and fee schedules have no separate code; there you draw the line by giving the same code to two different people.
  2. Keep operation:intervene narrow. It is the authority to touch funds in suspense — and it is also the second eye of the four-eyes check.
  3. Separate sponsor-policy:manage from sponsor-policy:approve. Bank integration and provider policy changes affect every money flow; config:manage only opens agent definitions.
  4. Keep terminal:manage away from field staff. It is the authority to issue and rotate credentials; terminal:read is enough in the field.
  5. Give enduser:kyc-override and enduser:kyc-approve to different people. One requests the change, the other approves it; enduser:manage carries neither. The same applies to legal-hold:manage and legal-hold:approve.
  6. Define read-only roles. Most support work is served by the *:read codes (program, enduser, operation, loyalty, qr, terminal, card, cashout, report).