Payment System Overview
This documents the xperise corporate payment architecture and how the two new methods (QR-code payment and the xperise card system) fit it. It is still a working draft; endpoint shapes are illustrative sketches, not a frozen API contract.
xperise is a corporate (B2B) payment system: a company funds spending, its employees spend at vendors, and every payment is governed by both a spending policy and a real balance. Understanding that split is the key to the whole design.
Actors
| Actor | Role |
|---|---|
| Company | Our customer. Holds the company wallet (real balance) and an assigned company credit line. Defines how employees spend. |
| Employee | Spends at vendors. Assigned a monthly limit or a cost center (per the company's operating model); may hold an xperise card. |
| Vendor (merchant) | Accepts payments; generates dynamic QR (via API or the merchant app); operates a card reader / scanner. |
| 2c2p | External payment gateway used when an employee pays by credit card. |
| xperise platform | Runs the ledger, enforces spending policy, authorizes/settles payments, issues xperise cards, and runs risk controls. |
The two-layer model (the core concept)
Every employee payment passes two independent checks, and on success xperise decrements one bucket from each layer:
-
Layer 1 — Spending authority (policy control): how much the employee is allowed to spend. It's a budget/limit, not real money. A company runs one operating model — either monthly limit or cost center, never both:
- Monthly limit — a per-employee allowance that resets every month.
- Cost center — a shared budget bucket that resets after a configured period, or is re-topped to a new limit, depending on the company's settings.
In addition, each xperise card carries a card balance — the spending-authority bucket for payments made with that card. Its reset is configurable: replenished on a day of the month, or no reset (the manager tops it up when it runs empty; top-up is always available). A card payment draws the card balance, plus the cost center only if the company's model is cost center.
The operating model is chosen per company (see the Corporate Portal).
-
Layer 2 — Funding (the real balance): where the money actually comes from. One of:
- Company wallet — the company's real internal balance, backed by company credit (a credit line assigned to the wallet that resets after a period, typically 1 month). Spendable from the wallet = wallet balance + remaining company credit.
- Credit card via 2c2p — an external credit card charged through the 2c2p payment gateway.
For xperise cards, the funding source is optional: the company wallet, or none — in which case the card balance is stored value (prepaid) and is itself the money, so no wallet is drawn.
If either layer is insufficient — allowance exhausted, or funds/credit unavailable — the payment is declined. Both are decremented together, atomically, only on a successful payment. (An unfunded stored-value card has only Layer 1: the card balance is the money.)
Payment methods
Four methods share the two-layer model. The difference is which control bucket and which funding source each one touches:
| Method | Layer 1 · control decremented | Layer 2 · funding | Rail / gateway | Status |
|---|---|---|---|---|
| Company wallet | monthly limit or cost center | company wallet | internal | existing |
| Credit card | monthly limit or cost center | credit card | 2c2p | existing |
| QR code | monthly limit or cost center | company wallet | internal, vendor-presented QR | new |
| xperise card | card balance (+ cost center under the cost-center model) | company wallet or none (stored value) | internal closed-group card | new |
- With credit card, the real money comes from the card (settled via 2c2p) — the company wallet is not drawn; the employee's monthly limit or cost center is still decremented as policy.
- QR is funded by the company wallet and draws against the operating-model bucket (monthly limit or cost center). The xperise card draws against its card balance (plus the cost center only under the cost-center model); its funding is optional — the company wallet, or none (the card balance is then stored value).
Confirmed rules:
- A company uses exactly one operating model — monthly limit or cost center, not both.
- The xperise card decrements its card balance (Layer 1); its funding (Layer 2) is optional — company wallet or none (stored value). Under the cost-center model it also draws the cost center.
- Transaction authentication for cards is the Cardholder Verification Method (CVM): a PIN or an OTP — one of the two, never both.
- A card is assigned to one employee or to no-one. Assigned, it inherits the employee's cost center(s) and stays in sync (the employee's default cost center is used for card payments); unassigned = a bearer card (usable by holder + PIN), optionally linked to one cost center.
Still to confirm:
- QR funding is the company wallet. If QR should also be payable by credit card (2c2p) or the xperise card, tell us and we'll add those combinations.
- Credit card payments do not draw the company wallet (2c2p is the funding source).
How a payment is processed
Every method runs the same authorize-both-layers → fund → commit sequence:
Two invariants keep this safe:
- Idempotency keys on every state-changing call, so a retried request never double-charges or double-decrements.
- Atomic dual decrement — the Layer 1 bucket and the Layer 2 balance are reserved together and committed together; a failure in either releases the other, so policy and money never drift apart.
Ledger & data model
The company wallet is a real, double-entry ledger account (the source of truth for money). The control buckets are budgets/counters enforced at authorization — they cap spending but are not themselves money.
A wallet-funded payment posts at least a two-legged entry, plus the policy decrement:
Layer 1 (policy): cost_center.used += 150,000 (or monthly_limit.used += 150,000)
Layer 2 (ledger): DEBIT company.wallet 150,000
CREDIT vendor.receivable 150,000
A credit-card payment records the policy decrement and books the vendor receivable, but the money leg is the 2c2p settlement, not the company wallet.
Services
Fits the existing api-gateway / microservice style:
| Service | Responsibility |
|---|---|
| Identity / Auth | Employee & admin sessions, MFA, device binding (reuses the existing session service). |
| Policy / Budget | Monthly limits, cost centers, card balances: reserve/commit/release, and resets. |
| Ledger / Wallet | Company wallet + company credit. Double-entry postings, balances, reconciliation. |
| Payment orchestrator | The authorize-both-layers → fund → commit state machine; refunds; reversals. |
| QR service | Creates and resolves payment intents and their signed, single-use QR tokens. |
| Card service | xperise card issuance & lifecycle, tokenization vault, PIN/cryptogram, card balance. |
| 2c2p connector | Credit-card authorization, capture, refund, and 3DS via the 2c2p gateway. |
| Merchant service | Vendor onboarding, API keys & secrets, webhooks, settlement/payout. |
| Risk / Fraud | Velocity & limit checks, step-up decisions, blocklists, freeze/lost-card. |
| Notification | Push/SMS confirmations & receipts (reuses the existing notification center). |
Transaction state machine
Every payment — wallet, credit card, QR, or xperise card — runs through the same states:
A refund credits both layers back — the vendor receivable/funding is reversed and the employee's allowance (monthly limit or cost center / card balance) is restored.
Where to go next
- QR-Code Payment — merchant-presented dynamic QR; deducts allowance + company wallet.
- Card Payment — the xperise card; deducts card balance + company wallet.
- Corporate Portal — where companies set the operating model, allowances, and funding.
- Security & Trade-offs — security layers, 2c2p/credit-card handling, and UX decisions.