Skip to content

Merchant dashboard

The Xaalis Merchant Dashboard (/dashboard/*) allows merchants and their teams to monitor balances, track payments and payouts, manage subscriptions and invoices, configure webhooks, rotate API keys, and manage team members.

Access to the merchant dashboard is passwordless and invitation-only:

  1. No Public Sign-Up: Dashboard users are provisioned by an operator (via POST /admin/merchants/{id}/dashboard-memberships) or invited by an existing account Owner.
  2. Magic Links: Sign in by entering your email at /dashboard/login. You will receive a secure magic link (POST /dashboard/auth/sign-in/magic-link).
  3. Session Cookie: Clicking the emailed link establishes a secure HttpOnly session cookie (credentials: "include"). No tokens or credentials are saved in client storage (localStorage or sessionStorage).

Every team member has an assigned role on each merchant account:

Feature / Action Owner Developer Viewer
View balances, transactions & invoices ✓ ✓ ✓
View webhook deliveries & payload logs ✓ ✓ ✓
Create test payments & simulate outcomes ✓ ✓ —
Create new subscriptions & advance cycles (test) ✓ ✓ —
Initiate real or test payouts ✓ — —
Cancel subscriptions (immediate or period-end) ✓ — —
Manage API keys (create, roll, revoke) ✓ — —
Update live webhook URL ✓ — —
Invite or remove team members ✓ — —

The top navigation bar features a clear toggle between Mode Test and Mode En direct (Live):

  • When in Test Mode, a distinctive 32px amber stripe is visible across the top of the interface. All displayed data, transactions, and balances belong strictly to the test: ledger.
  • Actions executed in Test Mode (e.g. creating test payments, simulating approvals/failures, rolling test keys) will never touch real money or provider rails.
  • You can switch seamlessly between modes at any time; your permissions remain identical across both modes.

The dashboard prominently displays two figures at the top:

  • Disponible (Available): Funds settled and cleared into your merchant account, ready for immediate payout.
  • Virements en cours (In transit): Funds reserved for payouts currently being processed by the provider connector.
  1. Click Virer les fonds from the balance strip or the Payouts page.
  2. Select your mobile provider (Wave or Orange Money).
  3. Enter the recipient mobile number (validated in the Senegalese standard format: +2217XXXXXXXX).
  4. Enter the amount in integer XOF (must be $\le$ Available balance minus the fixed payout fee payout_fee_fixed returned by /balance, capped at 100,000,000 XOF). Clicking Max automatically computes Math.max(0, available - payout_fee_fixed).
  5. Review the exact payout summary — recipient amount, fixed Xaalis payout fee (payout_fee_fixed), and total ledger debit (amount + payout_fee_fixed) — after the dashboard refreshes /balance before confirmation.
  6. The request is dispatched with an automatic, unique Idempotency-Key header to prevent duplicate transfers.
  • Overview: Real-time table displaying transaction date, customer details, client reference, provider receipt reference (provider_transaction_id), gross amount, and fee.
  • Status & Receipt Filters (WA-5): Filter payments by succeeded, processing, requires_payment_method, failed, or expired, or search directly by the provider receipt reference (provider_transaction_id, e.g., T_M6MTZ6GXKQ4YDFTP) to reconcile customer screenshot receipts.
  • Detail Drawer: Click any payment row to open a full slide-over panel displaying the exact Xaalis payment ID, customer info, fee breakdown, net payout amount, and direct link to the customer’s hosted checkout.
  • Simulation: In Test Mode, payments in processing or requires_payment_method can be simulated as succeeded or failed directly from the drawer to test your webhook integrations.

Subscriptions & Invoicing (Abonnements & Factures)

Section titled “Subscriptions & Invoicing (Abonnements & Factures)”

The Subscriptions section enables management of recurring customer billing:

  • Creating Subscriptions: Configure recurring plans with intervals (weekly, monthly, quarterly, semi_annually, yearly), billing cycles, customer details, and payment grace periods (days_until_due).
  • Invoices: Every cycle generates an invoice with a dedicated customer checkout URL (hosted_invoice_url). Invoices display clear statuses: draft, open, paid, overdue, or uncollectible.
  • Cancellation:
    • At period end (at_period_end: true): The current billing period remains active and payable; no subsequent renewals will be scheduled.
    • Immediate (at_period_end: false): Immediately cancels the subscription. If a payment is currently processing with a provider, it settles cleanly while future recurring billing ceases.
  • Testing Cycle Advances: In Test Mode, developers can trigger an immediate cycle advance to test recurring renewal notifications and invoice generation.

Located under /dashboard/developers, this section is tailored for engineering teams:

API Keys & Scopes (Clés d’API & Permissions)

Section titled “API Keys & Scopes (Clés d’API & Permissions)”
  • Lists all active and scheduled-for-revocation keys for the current mode.
  • Only safe identifiers (key_...), display prefixes (sk_test_..., sk_live_..., rk_test_..., or rk_live_...), and safe timestamps are shown.
  • Full vs. Restricted Keys:
    • Standard Keys (sk_...): Full administrative access across all merchant endpoints (*).
    • Restricted Keys (rk_...): Explicit, granular scopes (payments:read, payments:write, refunds:write, subscriptions:read, subscriptions:write, payouts:read, payouts:write, balance:read, webhooks:read, webhooks:write, agent_wallets:read, agent_wallets:write). Allows handing keys to microservices or AI agents with zero risk of unauthorized refunds or transfers.
  • One-Time Secret Display: Secret keys are displayed exactly once in a secure modal with a 1-click copy action. Secret keys are never persisted in browser storage, analytics, URLs, or client logs.
  • Zero-Downtime Rotation: Rolling a key configures a grace period between 1 and 72 hours (default 24h). The old key remains valid until scheduled_revoke_at, allowing updates to production servers without payment downtime.
  • Immediate Revocation: Compromised or decommissioned keys can be revoked instantly.

Webhooks & Multiple Destinations (WA-1, WA-1b)

Section titled “Webhooks & Multiple Destinations (WA-1, WA-1b)”

Located under /dashboard/developers?tab=webhooks, webhook management supports:

  • Default Endpoint & Multiple Destinations (WA-1): Every account maintains a default webhook endpoint and up to 9 custom destinations per environment (test or live).
  • Granular Event Filtering: Route specific event types to different internal services (payment.succeeded, payment.failed, payout.succeeded, invoice.paid, etc.).
  • Data Privacy Policies (Payload Policy):
    • full: Delivers the complete JSON resource object.
    • minimal: Sends only the event ID, merchant ID, and resource ID/type, requiring the receiver to re-fetch the resource over the authenticated API before processing sensitive consumer data.
  • Dedicated Signing Secrets: Each destination generates its own immutable signing secret (whsec_...) displayed once upon creation.
  • Service-Managed WhatsApp Endpoints (WA-1b): Endpoints managed by the internal WhatsApp service are marked Géré automatiquement (managed_by: "whatsapp") and cannot be modified or deleted manually.

WhatsApp Merchant Assistant & Payouts (WA-2, WA-3, WA-3b)

Section titled “WhatsApp Merchant Assistant & Payouts (WA-2, WA-3, WA-3b)”

Located under /dashboard/settings?tab=whatsapp, this feature allows merchants to monitor their business and issue secure payouts directly over WhatsApp:

  • Any team member can link their Senegalese WhatsApp number (+221...) by generating a unique 8-character code valid for 10 minutes.
  • Once the code is texted from WhatsApp, the user confirms the connection in the dashboard.
  • Toggle live payment notifications (notifications.payment_succeeded) on or off at will.
  • Owners can inspect all active connections across the business; team members manage their own.

Secure WhatsApp Payouts & PIN (WA-3, WA-3b)

Section titled “Secure WhatsApp Payouts & PIN (WA-3, WA-3b)”

Business owners can initiate quick payouts through WhatsApp while maintaining strict financial security:

  • 6-Digit PIN Validation: Confirmations occur strictly on a standalone secure Xaalis web page (/wa/pin/[token]), never inside the chat conversation.
  • Argon2id & Pepper: PINs are hashed using Argon2id with an isolated deployment pepper (WHATSAPP_PIN_PEPPER).
  • 3-Attempt Lockout: Three consecutive incorrect entries lock WhatsApp payouts for 24 hours.
  • 24-Hour Security Hold: All new links, PIN resets, account unlocks, and daily cap raises are subject to an irreversible 24-hour waiting period.
  • Configurable Daily Cap: Daily spending limit (in integer XOF) that automatically resets at midnight Dakar time.
  • Approved Settlement Only: WhatsApp payouts are restricted exclusively to the pre-approved Wave settlement wallet registered during onboarding.
  • 5-Minute Single-Use Links: Confirmation tokens expire in 5 minutes and become permanently invalid once used.

The dashboard is engineered for high-velocity operations with full keyboard control:

  • ⌘K / Ctrl+K: Open the universal Command Palette to search pages, resources, or trigger actions.
  • ?: Display the shortcuts cheat-sheet modal from anywhere.
  • m: Instant toggle between Test Mode and Live Mode.
  • Navigation Chords (g followed by…):
    • g then h: Overview (Home)
    • g then p: Payments & Transactions
    • g then s: Subscriptions & Invoices
    • g then o: Payouts (Withdrawals)
    • g then a: Autonomous AI Agent Wallets
    • g then d: Developers & API
    • g then t: Merchant Settings
  • j / ↓: Move focus to next row.
  • k / ↑: Move focus to previous row.
  • Enter: Open detail drawer or inspect the focused transaction.
  • c: Copy technical identifier (pay_..., po_..., sub_...) to clipboard.
  • r: Refresh current data live with a visual indicator.
  • e: Export currently filtered list to CSV.
  • /: Instantly jump cursor into the search filter input.
  • 1, 2, 3…: Switch sub-tabs in Developers, Subscriptions, and Settings.

Account Owners can refund settled transactions directly from /dashboard/payments:

  • Eligibility: Currently supported on completed Wave transactions.
  • Gross Deduction: Refunds deduct the full gross amount from your available balance. The standard Xaalis fee policy determines whether fees are absorbed or retained.
  • Insufficient Funds (422): If your available balance is insufficient to cover the gross refund amount, the dashboard clearly alerts you to receive further customer payments or deposit funds before retrying.
  • Scoped Idempotency Keys (R-2): Refund Idempotency-Key headers are scoped per (merchantId, mode, paymentId) and persisted across network retries so a retry resumes the same payment’s full refund; reusing a key across different payments is rejected with 409 idempotency_conflict.
  • Durable Refund States: Refund outcomes are tracked as pending, needs_review, or succeeded. A succeeded refund marks the payment as refunded in real-time.

Located at /dashboard/agent-wallets, this owner-only section empowers merchants to safely integrate autonomous AI agents:

  • Dedicated Sub-Wallets: Each agent receives an isolated ledger balance with explicit spending rules.
  • Daily Spending Limits: Configure a max_daily_amount enforced strictly in Africa/Dakar timezone. Admitted payouts reset at midnight Dakar time.
  • Owner Approval Above Soft Limits (AW-10, Test Mode): In Test Mode, owners can enable approval_above_limit with an approval_max_amount ($\ge$ max_payout_amount). Agent payouts that exceed max_payout_amount or max_daily_amount (up to approval_max_amount) return 202 Accepted (agent_payout_approval, status: "pending") without reserving ledger funds until the owner approves the request and confirms with their 6-digit owner PIN at /wa/pin/[token]?purpose=agent_approval. Owners can configure their shared 6-digit PIN directly from /dashboard/agent-wallets without needing a WhatsApp link (first setup is immediate; replacements wait 24 hours).
  • One-Time Agent Keys (ak_test_... / ak_live_...): Issue dedicated credentials for agents using @xaalis/sdk XaalisAgentClient.
  • Wallet Controls: Fund wallets from your merchant available balance, update spending policies (PATCH .../policy), or immediately disable a compromised agent to freeze its payout capability.

Located at /dashboard/settings, this area provides complete administrative control for account owners:

Merchants transitioning to live processing must complete business verification:

  1. Business Profile: Submit legal business name, NINEA, and RCCM registry numbers.
  2. Settlement Wallet: Specify your verified Wave mobile wallet (+2217XXXXXXXX) for automated funds settlement.
  3. Identity Verification: Upload a valid government-issued ID or business registration certificate (PDF, JPEG, or PNG up to 5 MiB). Uploads stream directly as raw bytes without persisting in browser memory, and are limited to 10 attempts per hour per IP address and per business (429 rate_limited with Retry-After beyond that).
  4. Review Status: Track status across draft, submitted, approved, or rejected. If rejected, detailed reviewer notes explain required corrections.

Automatic Settlement (Règlement Automatique)

Section titled “Automatic Settlement (Règlement Automatique)”
  • Configure automatic daily payouts of your cleared balance directly to your approved Wave wallet.
  • Schedule: Fixed daily sweep executed at 18:00 Africa/Dakar.
  • Threshold: Set a minimum payout threshold (min_amount) in net XOF. If available balance is below this threshold at 18:00, funds roll over to the following day.
  • Audit & History: Track last_run timestamp and payout delivery status.
  • Review and audit third-party AI connectors (e.g. ChatGPT, Claude.ai) connected via https://mcp.xaalis.org.
  • Displays client application names, assigned scopes, and grant dates.
  • Instant Revocation: Revoke consent at any time. Revocation immediately terminates active access tokens and blocks subsequent tool invocations.
  • View all active team members and their roles.
  • Invite new colleagues with Developer or Viewer access via secure email magic links.
  • Remove team members upon offboarding.
  • Located at /dashboard/settings?tab=notifications (or keyboard shortcut 7), account Owners can configure merchant-wide notification channels (Email and WhatsApp) shared across Test and Live modes (GET/PATCH /dashboard/v1/merchants/{merchantId}/{mode}/notification-preferences).
  • Categories:
    • kyc: Approval and rejection decisions (including the operator’s review reason and dashboard resubmission instructions), inactivity reminders (days 2, 7, and 14), and suspension notices.
    • payments: Customer payment confirmations.
    • payouts: Merchant payout status updates.
    • security: Mandatory security alerts (PIN changes, unlocks, daily cap updates) — locked to true across both channels.
  • KYC Inactivity Suspension & Recovery: Live pending merchants with unsubmitted or rejected KYC are reminded at days 2, 7, and 14 and suspended at day 30. While suspended, owners can still sign in to /dashboard/settings?tab=onboarding and /dashboard/settings?tab=notifications to update and resubmit their KYC dossier, which restores the account to pending_review.

For testing integrations, or registering a live business, without waiting for manual provisioning:

  • Instant Sandbox Signup (/sandbox/signup, SB-OWNER): Immediately generates a test merchant (mer_...), secret test API key (sk_test_...), and webhook signing secret (whsec_...) for https://sandbox-api.xaalis.org, and atomically provisions the signup email as Owner of that new test merchant. You can sign in immediately to the Sandbox dashboard (https://sandbox.xaalis.org/dashboard) via a magic link sent to that email without needing an operator invitation.
  • Live Registration (pending KYC, /live/signup): Creates a live merchant in pending_review status (no live keys, no money movement yet) and sends a magic link to sign in and complete KYC in the dashboard. An optional sandbox_merchant_id is recorded as a reference only: it does not link the accounts or copy settings.
  • Production Isolation & Host Capability Discovery (DX-1): GET /dashboard/v1/merchants exposes test_mode_enabled: boolean at startup (with a 403 forbidden fallback for older API responses). When TEST_KEYS_ENABLED=false on production (pay.xaalis.org), every dashboard page surfaces a clear notice in Test Mode with a one-click switch to Live, a link to the separate Sandbox Dashboard (https://sandbox.xaalis.org/dashboard), and a link to /sandbox/signup.