Configurable action buttons
Three front-desk surfaces — POS, the visit checkout overlay, and check-in advance pay — let an Owner or Manager design the action buttons hosts see. Each button is a chain of small registered steps that run in order. If any step fails, the chain stops and the host sees the error.
Where they appear
POS — payment buttons under the cart total.
Visit checkout — settle/charge buttons on the visit overlay.
Check-in advance pay — quick-charge buttons during member check-in.
Step amount sources
Steps that move money take an amount from one of four sources:
Failure semantics
Steps run sequentially. The first failed step stops the chain and the host sees the structured error. Earlier steps are not rolled back — a successful card charge stays charged even if a later receipt-print step fails. This matches how front-desk staff already think about money: once it’s captured, it’s captured. Refunds are explicit, never automatic.
Who can configure
Owner and Manager roles can create, edit, reorder, duplicate, and delete buttons under Settings → Buttons. Individual steps can carry their own minimum-role gate so that, for example, a refund step only runs when a Manager is the active host.
Built-in actions
The current library covers payments (charge, refund), cart adjustments (discount, surcharge, tip, comp remainder, add item), hardware (print receipt, open cash drawer), and visit lifecycle (checkout, flag for review). Payment processors are pluggable — PayJunction ships first; NMI, cash, gift card, and BTCPay slots exist for future integrations.
Audit trail
Every press writes a BUTTON_PRESSED audit entry with the resolved actor, device, and surface context. Each step writes BUTTON_STEP_OK or BUTTON_STEP_FAIL. Edits to the configuration write BUTTON_CONFIG_CHANGED. Resolved parameters are redacted in logs so prompt-entered amounts and member identifiers don’t accumulate as searchable plaintext.
Visibility predicates
Buttons hide themselves automatically when their predicates aren’t met, so hosts only ever see actions that can actually run on the current surface state.
Seeder behavior
The seeder is idempotent — re-running it on a club skips any button whose label already exists on the same surface, so a manager’s edits and additions are never overwritten. PayJunction-dependent buttons (Card Token and Card Terminal flows) are skipped on clubs without an active PayJunction integration; cash, tip, surcharge, discount, comp, and hardware buttons still seed for everyone so non-PayJunction clubs aren’t shipped empty.
Configurator access control
Only Owners and Managers can read the configurator payload (which exposes every button’s steps, parameters, and minimum-role gate). The runtime listing on each surface is role-filtered server-side, so a host never receives a button they couldn’t press anyway. Each step also re-checks its own minimum role at run time, so a misconfigured button can’t escalate a host into a manager-only step.