NEXUS
Product Overview

What is WAVit Dashboard?

WAVit Dashboard is the web portal for merchants who take payments with the WAVit app on Clover. It reads the payments every terminal reports to MiCamp's MiPoint database and turns them into a daily balance, a filterable transaction list with CSV export, and charts. Merchants also use it to change a few terminal settings, send pay-by-link invoices, invite their staff and send feedback. It is an ASP.NET Core 8 MVC app with server-rendered Razor views, hosted on Azure App Service. Production runs version 2.1.0, released on 2026-08-17.

Who uses it

Merchants, from one location to manyAn owner or manager signs in with the email tied to their WAVit account and sees every location ("unit") under it: today's takings, transactions, analytics, terminals and settings.
The people they inviteA merchant can invite colleagues and choose which MIDs each one sees. An invited user is an ordinary account with a narrower set of units. There are no roles.
Their customersThe public receipt page shows a payment's virtual receipt without signing in. If MiCamp has no record of the payment, it hands over to Clover's own receipt.
Anyone giving feedbackA public survey about the WAVit Payments app posts each response to the team's Slack. Signed-in users also have a feedback form inside the dashboard.

Where it sits

The dashboard owns very little data. It mostly reads what the WAVit app and MiCamp's back office have already written.

PieceWhat it does for the dashboard
WAVit Payments (Clover app)Writes every payment, refund and void to MiPoint, and reads the terminal settings the dashboard edits. See the WAVit project.
MiPoint databaseThe system of record. The dashboard queries it directly with EF Core (no API in between) for transactions, units, MIDs, devices, settings and invoices. It writes a few of these tables too.
Identity databaseASP.NET Core Identity's AspNet* tables: logins, passwords, 2FA. This is a separate SQL database from MiPoint.
MiPoint APIUsed for one thing only: creating and cancelling pay-by-link invoices. MiPoint sends the email or text.
ConfiguratorWhere MiCamp sets up merchants and most terminal settings. The dashboard edits only the tax rate, tips and unlock PIN.
CloverFallback receipts: when the receipt page has no record of a payment, it redirects to Clover's web receipt.
AzureApp Service hosting, Key Vault for secrets, Application Insights for telemetry.
OthersSMTP2GO for email, a Slack webhook for survey responses, and Microsoft Clarity session replay on signed-in pages.

Tech stack

AreaChoice
FrameworkASP.NET Core 8 MVC with Razor views, plus Razor Pages for Identity and the public pages. Project WAVitDashboard/WAvitDashboardWeb.csproj.
AuthASP.NET Core Identity 8.0.11 (default UI, mostly restyled), with confirmed email required
DataEF Core 9.0 on SQL Server, database-first with no migrations. Two class libraries: MiCamp.Models (scaffolded MiPoint entities) and MiCamp.DataAccess (unit of work and a generic repository).
Front endBootstrap 5.3.8, jQuery, Chart.js, and per-page scripts under wwwroot/js/pages. The tables are server-rendered partials driven by OData-style query strings.
SecretsAzure Key Vault through DefaultAzureCredential. The vault is chosen by KeyVault:Uri.
ObservabilityApplication Insights (server SDK and browser snippet, through ILogger<T>), Microsoft Clarity, an audit table, and GET /health
Other librariesMailKit (SMTP), CsvHelper,RestSharp, Newtonsoft.Json
TestsxUnit with EF Core InMemory and Moq. A Playwright end-to-end suite exists on a branch. See Resources.
HostingWindows Azure App Service, one site for DEV and one for PROD, deployed by Azure Pipelines

Accounts and access

Three MiPoint records sit between a login and the merchants it can see.

RecordWhat it is
Unit (OrganizationUnit)One merchant location. MiPoint's hierarchy has Enterprise, Organization, Merchant and Revenue Center levels. The dashboard works with the unit's GUID, which it calls the MerchantId. Transactions, devices, settings and invoices all hang off it.
MID (OrganizationUnitMID)A processor merchant id mapped to a unit
Master MID (OrganizationUnitMasterMID)A dashboard-only record keyed by email. It stores the account's MIDs as a JSON list and a Hidden flag. A hidden record cannot sign in ("User temporarily disabled").
Preferences (DashboardPreferences)Per-user JSON: MerchantToShow (the units shown on Home), InvitationsLeft (50 to start), and the unused EnableDailyEmails and Emails
  1. 1
    RegisterAnyone with the email tied to their WAVit account can register from the login page. An invitation link fills the email in for them.
  2. 2
    Link the merchantsRegistration builds a master MID record from the units that list the email as their contact, unless an invitation already created one. It then creates the user's preferences with every linked unit shown.
  3. 3
    Confirm the emailSign-in waits for the confirmation link. The login page offers to resend it.
  4. 4
    Sign inEvery successful sign-in lands on Home, /Dashboard/Portal/Home.
  • Units shown are units allowed. MerchantToShow decides both what Home shows and which merchants the merchant-scoped pages accept. Unticking a unit under Preferences hides it everywhere.
  • Account settings has Profile (phone number), Preferences (pick units, with Select all / Clear all), Invite Users, Password and Personal Data (download or delete).
  • Invite Users: pick one or more of your MIDs and enter an email. The invitee gets a "You're Invited!" email with a registration link and sees only those MIDs.
  • Two-factor authentication pages (authenticator app and recovery codes) are present and work, but nothing in the settings menu links to them.
  • There are no roles or policies: every signed-in user has the same features, scoped to their own units.

Screens

ScreenWhat it is forShown when
HomeToday's balance across all units, a 10-day chart, unit cards, the latest transactions and shortcutsAlways; where sign-in lands
TransactionsSummary totals, a filterable table with a Quick View panel, and CSV exportAlways
Transaction detailEvery field of one payment, the card, the receipt, and Resend ReceiptFrom Transactions
Report (legacy)The older transactions page built on DataTables. It is still linked from Home's "View all transactions" button and the mobile shortcut.Home
AnalyticsVolume, amount, average and frequency, with two daily chartsAlways
InvoicesPay-by-link ("Text to Pay") invoices: totals, list, CSV export, a New Invoice wizard and cancelAny of the user's units has an invoice tender
DevicesTerminals per unit, with Settings and Change PIN for each unitAlways
FeedbackSubject and comments, stored for the teamHeader icon; mobile menu
Account settingsProfile, Preferences, Invite Users, Password, Personal DataHeader icon

Signed-in users can switch between light and dark themes from the header. The choice is kept per browser in localStorage under the key wavit-theme, and light is the default. The landing page, sign-in pages and public receipt are always light.

Home

The page itself is empty when it arrives. Two requests fill it: GetUnitsSummary and GetLastTenDaysChartData.

PartWhat it shows
Today's Total BalanceThe total of today's sales across every unit shown: TotalAmount of transactions that are not refunds, voids or pre-transactions. It is gross, not net of refunds. Volume is the number of those transactions.
Chart"Transactions amount per day (last 10 days)": the same sales total for each of the last ten days
Unit cardsName, address and today's balance for each unit. "View All Transactions" opens Transactions filtered to that unit. A search box filters the cards by name.
Most Recent TransactionsThe five newest payments from the last 30 days, with card brand (or cash), amount and date. Refunds are shown in red.
ShortcutsTransactions, Analytics, Devices, Preferences

Transactions

The filter bar, shared with Analytics and Invoices
FilterOptions
DateToday, Yesterday, Last 7 Days, This Month, or Custom (from/to date and time). The presets use the browser's clock. From must not be after To, and the latest allowed date is tomorrow.
MerchantAll Merchants, or one unit
TerminalAll Terminals, or one device by serial number
Card typeAll, Card, Cash, EBT/SNAP
  • Summary strip: Total, Card and Cash (only when the merchant has cash discounts on), Refunds, Voids, and EBT (only when an EBT tender exists). Expand it for Amount, Tip, WAVit (service) and Cash Savings. On a phone it becomes a swipeable carousel.
  • Table: Created (with payment id and invoice number), Tender, Amount (refunds in red), Terminal, and Details. The page sizes are 10, 25, 50 and 100.
  • Search matches the amount, invoice number and the five custom fields.
  • Quick View opens a side panel with the payment, device, custom fields (labelled with the merchant's own captions), card and receipt.
  • Transaction detail shows payment details, totals, other information (employee, auth code, MID), card art and the receipt. Resend Receipt emails an HTML receipt to any address.
  • Export CSV downloads WAVit Report - {merchant} - {from} to {to}.csv: a SUMMARY block (totals, card, cash, refunds, voids), then one row per transaction. The columns include date, time, unit, payment id, tenders, invoice, amounts, card type and number, auth code, terminal, service advisor, employee and the enabled custom fields. Refund rows carry a minus sign.
  • Which rows appear (tips, card/cash, EBT) depends on the selected merchant's WAVit settings: IsTipAllowed, EnableCashDiscounts and its tender types.

How totals are counted

These rules live in Helpers/Reporting.cs and TransactionService. They are the reason two screens can disagree.

Transaction codes
Field and valueTreated as
TransactionStatus = "9"A pre-transaction: the record the app writes before Clover is called. Always hidden.
TransactionTypeId = 4Failed. Excluded.
TransactionTypeId = 13A void. The voided sale is removed from the table and the totals. The void is counted under Voids.
IsRefundA refund. Counted under Refunds.
IsCashPaymentCash rather than card
CardTypeId = 10EBT/SNAP. The card brand also shows EBT for 11.
Several rows with one PaymentIdDuplicates written by webhooks. All but one are dropped.
Money fields and their labels
FieldShown as
AmountSub Total / Payment Amount
TaxAmountTax
TipAmountTip
ServiceAmountWAVit / Service Amount. On the public receipt it is "Technology Fee", hidden for dual-price merchants. It is the surcharge or non-cash adjustment.
DiscountAmountCash Savings
TotalAmountTotal. Every balance and chart sums this field.

Time zones: transaction times are stored in UTC. Each unit's state maps to one Windows time zone (Helpers/States.cs), and lists and totals are shown in that local time. When several units are selected, the first unit's zone is used for all of them. "Today" on Home is the server's date.

Analytics

  • Cards: Transaction Volume (count), Transaction Amount (sum of TotalAmount), Average Value, and Transaction Frequency (count per day of the range).
  • Charts: transactions per day (bar) and amount per day (line). Days are counted in the merchant's local time.
  • Refunds and pre-transactions are left out. On first load a range shorter than five days is widened to five days.
  • Everything is computed in memory from the rows in range. There are no stored aggregates.

Devices, settings and PIN

Devices lists every terminal under each unit: model image, brand and model, serial number, alternate merchant id and last update. Each unit has a Settings page and a Change PIN page.

Merchant settings the dashboard can change
FieldSettings keyRule
Tax Rate %TaxRateRequired, 0–100
Allow Gratuity (Tips)?IsTipAllowed
Gratuity calculated post tax?IsTipPostTaxSaved only when tips are allowed
Gratuity calculated post surcharge?IsTipPostSurchargeSaved only when tips are allowed
Gratuity Percent Option 1–3GratuityPercent1–3Not negative
  • Transaction type, integration type, cash discount and the tender types (with discount %) are shown read-only. Everything else is set in the Configurator.
  • Settings are one JSON document per unit in OrganizationUnitProduct.Settings. They apply to every terminal of the unit. The dashboard parses it and changes only the keys above, so keys it does not know about are left alone.
  • Change PIN sets the WAVit app's unlock PIN (UnlockPIN): 4 to 6 digits. It can change the PIN (the current one is required), set one when none exists, or remove it (stored as ----, meaning disabled).
  • Terminals pick up changes the next time the WAVit app restarts.
  • Every save is written to the audit log with the old and new values. A PIN change records only that the PIN changed, never the PIN.

Invoices (Text to Pay)

Pay-by-link invoices for merchants with an invoice tender. The list reads MiPoint's Invoice table; creating and cancelling go through the MiPoint API, which sends the link and hosts the payment page.

  1. 1
    MerchantOnly units with Text to Pay enabled are offered (TextToPayMerchants). The merchant's invoice-number settings (IncludeInvoice, InvoiceRequired, InvoiceCaption) come with it.
  2. 2
    DetailsInvoice number (a GUID is used when it is left blank), send method (email or SMS text, with a US phone mask), recipient, amount, and custom fields 1–5.
  3. 3
    BreakdownTax, service fee and total come from the merchant's settings (CalculateBreakdown). The server works them out again when the invoice is created, and the browser only sends the amount.
  4. 4
    SendThe dashboard authenticates to the MiPoint API as one of the merchant's terminals, then posts the invoice with status Outstanding.
InvoiceService.CalculateBreakdown(settings, amount)
amount  = round2(amount)
tax     = round2(amount × TaxRate / 100)
base    = SurchargePostTax ? amount + tax : amount
service = round2(base × SurchargePercent / 100)
tip     = 0                    // the customer tips on the payment page
total   = amount + tax + service
// rounding is AwayFromZero; missing or unreadable settings mean 0 tax and 0 service
  • Totals: Total, Paid, Outstanding and Cancelled, each with a count and an amount, for the filtered range.
  • Statuses: Outstanding (or Pending) until paid, then Paid (set upstream), or Cancelled.
  • Cancel is offered when an invoice is neither paid nor cancelled.
  • There is no resend.
  • Export downloads WAVit Invoices - {from} to {to}.csv.

Public pages

PageWhat it is
/The WAVit marketing page: no-fee pitch, savings calculator, clients, contact details, and links to "Become a Client" and the dashboard sign-in
/Invoice?id={paymentId}The virtual receipt for a payment: merchant, amounts, card brand and masked number, auth and payment ids, and a Refunded / Partially Refunded / Voided badge with the refunds. If MiPoint has no such payment, it redirects to Clover's receipt (the payment URL, then the credit URL), or to /ReceiptNotFound.
/ReceiptNotFoundApology and support contact
/Survey"WAVit Payments Feedback", an eight-step wizard: business name, star rating, impact of recent updates, biggest frustration, wished-for feature, NPS 0–10, what would help most, and an optional email. Responses are saved to MiPoint and posted to Slack.
/healthLiveness for monitoring.

The in-dashboard Feedback form is a separate thing. It offers eight subjects (WAVit App: features, reporting, other; WAVit Dashboard: data accuracy, features, other issue, other feedback; Other), needs at least 20 characters, and is stored in DashboardFeedback with no notification.