Add WisePOS E in-person card payments (Stripe Terminal)
Server-driven Stripe Terminal integration for taking in-person card payments against an invoice, running on the same Stripe Connect connected account used for online payments. No native app or Terminal SDK — the WisePOS E is driven from the web backend via Stripe's REST API. - Domain: TerminalReader entity + status enum, PaymentMethod.CardReader, Company.StripeTerminalLocationId / TerminalSurchargeEnabled, DbSet + tenant filter + indexes, IUnitOfWork repo, migration AddTerminalReaders (additive). - StripeConnectService: location/reader registration, list, delete, process payment on reader, status poll, cancel, and a test-mode simulated tap. All routed to the connected account like the existing online-payment methods. - TerminalController: admin reader management + per-invoice ProcessPayment, PaymentStatus (poll), CancelPayment, SimulateTap (test mode only). Stores the PaymentIntent id on the invoice; the webhook remains the authoritative writer. - PaymentController webhook: HandlePaymentSucceededAsync records source=terminal payments as CardReader (online path unchanged — no source key means no change); new terminal.reader.action_failed handler for declines/timeouts (notification only, no ledger mutation). Refund path reused unchanged. - UI: Card Readers settings tab (register/list/deactivate + in-person surcharge toggle, default off with a compliance warning) and an invoice "Take Card Payment" modal with live status polling. External JS per project convention. - Feature bundled with the existing online-payments entitlement (no new plan flag); additionally requires StripeConnectStatus == Active. - Help: HelpKnowledgeBase + Invoices help article updated. - Tests: TerminalController validation + surcharge-routing tests (241 pass). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -360,6 +360,33 @@
|
||||
The link is unique to each invoice and does not expire as long as the invoice remains unpaid.
|
||||
Voided invoices do not generate payment links.
|
||||
</p>
|
||||
|
||||
<h3 id="card-readers" class="h6 fw-semibold mt-4 mb-2">In-Person Card Payments (WisePOS E)</h3>
|
||||
<p>
|
||||
Take a card payment in person against an invoice using a Stripe Terminal
|
||||
<strong>WisePOS E</strong> card reader. This is included with the same plan that allows
|
||||
online payments and runs on the same connected Stripe account — no separate merchant setup.
|
||||
</p>
|
||||
<ul class="mb-3">
|
||||
<li class="mb-2"><strong>One-time setup:</strong> go to <strong>Settings › Card Readers</strong>
|
||||
(the tab appears once Stripe is connected). On the reader, open
|
||||
<strong>Settings › Generate registration code</strong> to get a three-word code, enter it
|
||||
with a label such as “Front Counter,” and click <strong>Add Reader</strong>.</li>
|
||||
<li class="mb-2"><strong>Taking a payment:</strong> on an invoice with a balance due, click
|
||||
<strong>Take Card Payment</strong>, choose the reader, confirm the amount, and click
|
||||
<strong>Send to Reader</strong>. The reader prompts the customer to tap, insert, or swipe; the
|
||||
screen shows live progress and refreshes the invoice once the payment is approved.</li>
|
||||
<li class="mb-2">The payment is recorded automatically with the method <strong>Card Reader</strong>,
|
||||
posts to your books, and advances the invoice to Paid or Partially Paid. Partial payments are supported.</li>
|
||||
</ul>
|
||||
<div class="alert alert-permanent alert-warning d-flex gap-2 mb-0" role="alert">
|
||||
<i class="bi bi-exclamation-triangle flex-shrink-0 mt-1"></i>
|
||||
<div>
|
||||
<strong>In-person surcharging is off by default.</strong> It can be enabled on the Card Readers tab,
|
||||
but in-person card surcharging is regulated differently than online payments and is prohibited in some
|
||||
states — only turn it on after confirming the rules where you operate.
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="payment-reminders" class="mb-5">
|
||||
@@ -415,6 +442,7 @@
|
||||
<a class="nav-link py-1 px-3 small text-body" href="#deposits">Deposits</a>
|
||||
<a class="nav-link py-1 px-3 small text-body" href="#gift-certificates">Gift Certificates</a>
|
||||
<a class="nav-link py-1 px-3 small text-body" href="#online-payments">Online Payments</a>
|
||||
<a class="nav-link py-1 px-3 small text-body" href="#card-readers">In-Person Card Payments</a>
|
||||
<a class="nav-link py-1 px-3 small text-body" href="#payment-reminders">Payment Reminders</a>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user