Appearance
Merchant Dashboard
Who: the Vecnet client / merchant (the government entity or operator). Read-mostly, hard-scoped by RLS to their own entity_id.
Live mockup
See the working dashboard at vecnet-dashboard.vercel.app — specifically /finances, /transactions, and /terminales. Per-module deep-dives: Finances surface, Terminales. Recent changes: Changelog.
Capabilities
| Capability | Backed by | Notes |
|---|---|---|
| Balance overview (per account/currency) | accounts (RLS) | Realtime subscription for live balance |
| Transaction history | journals + ledger_entries (RLS) | filter by category/date/rail/correlation_id |
| Disputas submodule | journals (dispute states) | Inside /transactions — KPI strip, status tabs, evidence-upload form. New in v0.2 (see changelog). |
| Terminales | sucursales + terminales (operator tier) | Sub-MID hierarchy + per-device payment history. Dedicated surface: Terminales. New in v0.2. |
| Daily ledger statements | balance_snapshots + Storage | download XLSX (CSV in v0.2 dashboard mock) |
| Settlement statements | journals where settlement_id set | read-only, with date + amount filter UI; see Finances surface |
| Rolling reserve view | journals (rr_amount, expected_reserve_release_date) | upcoming releases |
| Payment status (live) | Webhook Manager → Realtime | the citizen-facing notification loop |
The merchant cannot create fee rules, run settlements, post transfers, or see other entities.
Metric catalog
The Dashboard organizes into four pages. Two data sources, never confused (§7.9):
- Money metrics (settled volume, refunds, disputes, deposits, fees, net) →
journals/ledger_entries. - Acceptance / conversion / risk metrics (acceptance rate, decline reasons, status mix, 3DS, BIN/issuer, Guardian) →
transactions(the only place declines/failures/pending/expired live).
Global metric rules
Get these exactly right — they're the usual source of wrong dashboards
- Acceptance rate =
successful ÷ (success + declined + failed) × 100. Excludeexpired,pending, and duplicates from the denominator. - APM conversion rate =
successful APM ÷ all APM intents × 100. Includeexpiredandpending(it measures conversion, not authorization). - Card acceptance rate and APM conversion rate are never blended into one number — they measure different things.
- Dedup everywhere: each
payment_intent_idis counted once; retries behind one intent collapse. - FTD = first-ever successful payment for a
customer_ref, confirmed by looking back across all history (not just the selected range). - Every metric respects the global date-range filter (Today / 7D / 30D / 90D / custom).
Home — Primary KPIs
| Metric | Formula |
|---|---|
| Gross volume | Σ all transaction amounts, any outcome |
| Success volume | Σ amounts where status = success |
| Successful payments | count of unique successful payments |
| Acceptance rate (count & volume) | rule #1, computed by count and by amount |
Secondary KPIs: Refunds (count + Σ; cards only), Disputes (count + Σ chargebacks), FTDs (rule #5), Avg ticket (success volume ÷ successful payments).
Charts: Payment volume over time (toggle $ / count / acceptance); Payment-method donut; Status distribution; Top issuing banks by acceptance; Daily-health 30-day heatmap (green ≥80%, amber 50–79%, red <50%); Top decline reasons (code + count + severity).
Analytics — Acceptance & Conversion
| KPI | Formula |
|---|---|
| Overall acceptance rate | rule #1 |
| FTD acceptance rate | successful ÷ total payments, restricted to first-time customers (rule #1 denominator) |
| Trusted acceptance rate | same, restricted to returning customers |
| APM conversion rate | rule #2 |
Charts: acceptance over time (Overall / FTD / Trusted lines); acceptance by method (APM bars show conversion); card-network performance table (Visa/MC/Amex); top & worst issuing banks (with auth rate); FTD-vs-Trusted comparison.
Analytics — Deposit Analytics
(operator/iGaming framing; relabel "deposit/depositor" → "payment/payer" for GovTech)
| KPI | Formula |
|---|---|
| Total deposits | Σ successful payment amounts |
| FTDs | count of new first-time customers (rule #5) |
| Active depositors | count of distinct customer_ref with ≥1 success in range |
| Avg deposit amount | total deposits ÷ successful deposits |
Charts: deposit volume + count; FTD funnel (initiated → authorized → FTD completed, incl. pending/expired since it's conversion); deposit-amount distribution; deposits vs withdrawals (net-flow); top depositors; payment-method mix over time.
Fraud & Risk
(Tonder marks these formulas "pending to confirm" — treat as provisional.)
| KPI | Formula |
|---|---|
| Guardian block rate | blocked ÷ total card transactions screened × 100 (healthy <5%) |
| 3DS abandonment rate | 3DS challenges abandoned ÷ total 3DS transactions × 100 |
| Intl card acceptance | successful international card payments ÷ total international card payments × 100 |
3D Secure sub-metrics: success rate (successful 3DS ÷ total 3DS); challenge rate (challenged ÷ total 3DS); frictionless = 100% − challenge rate; abandonments (count). Charts: block decisions over time (allowed / issuer declines / Guardian blocks); suspicious BINs; geographic risk; suspicious email velocity.
Rail note
The tonder rail is card/CNP-rich (full card_brand/BIN/3DS/Guardian); the menta POS rail is card-present and won't populate every fraud field. Status/acceptance/volume span both. The Vecnet admin sees these same metrics across all entities.
The live mockup is at vecnet-dashboard.vercel.app/finances; the
vecnet-dashboardrepo is private, so this page/metric structure is the working model until the repo is shared (open items). The metric formulas are already captured from Tonder's metric-definitions page.