Auto-pay at exit — how plates-on-file are charged
When a session closes with the lot's auto-pay toggles enabled, the pipeline tries each path in order and stops at the first success.
**Path A — Off-session charge against the plate-on-file**
The driver registered their plate on `/me/parking` and put a default card on it. When a camera at your lot reads that plate, the entry-side trigger stamps `linkedUserId` on the new session. At close, the auto-pay function:
1. Loads the driver's plate-on-file via cross-org `collectionGroup('parkingPlatesOnFile')`.
2. Clones their platform-account payment method onto your Stripe Connect account (cached per (driver, your-account) so it's one Stripe API call, ever).
3. Creates an off-session `PaymentIntent` for the full `totalFee` against that PM.
4. On success, stamps `paymentStatus: 'auto-charged'`. The driver sees the receipt on /me/parking. You see the JE post.
**Path B — QR-pay fallback**
If the plate isn't on file OR auto-charge fails (insufficient funds, card declined), the function mints a Stripe Checkout session, stamps `qrPaymentUrl` on the parking session, and sets `paymentStatus: 'qr-pending'`. Your gate kiosk (or a printed QR sticker) renders that URL — driver pays on their phone, Checkout webhooks back, status flips to `paid`.
**Path C — Manual close**
Sessions on lots with **no** auto-pay or QR toggles still close cleanly — they just sit at `paymentStatus: 'pending'` until a human closes them via the Sessions tab.
**Watching for failures**
The Sessions list badges `auto-charged`, `paid`, `qr-pending`, `failed`. A `failed` badge means the off-session charge errored AND no QR-pay path was available (lot has `qrFallbackEnabled` off). The session writes `autoChargeError` with the Stripe message — the typical fix is enabling QR fallback so failed-card cases route to the driver.
**Receipts**
`receiptUrl` is populated by the Stripe latest-charge object once the PaymentIntent or Checkout settles. It surfaces on both the operator Sessions tab and the driver's /me/parking → Receipts tab.
**Validations + passes**
Pass-covered sessions skip auto-pay entirely (`paymentStatus: 'comped'`). Validation credits reduce `totalFee` before the charge fires — a $14 session with a $10 dinner validation auto-charges $4.
**Cross-org expense routing**
If the driver tagged a work trip and named your employer as the expense-target org, the auto-pay function also writes a line on that org's `expenseReports` (see "Auto-emit work-trip parking to your employer's expense report").