← All memos
Jun 2, 2026deliveryrevenuesalesplatformOpen

Delivery's card-capture and card-on-file charge flows for the shared payment-flow reframe; Delivery already consumes the invoice-save feeder and the card-on-file charge primitive in the workbench credit-purchase drawer, has no capture surface today (the phone gap is real and Delivery-led), charges only additional-credit purchases, and confirms ensure-card-on-file plus charge are shared not Sales-only

Expects responseYes
Tagspayment-flow, card-capture, card-on-file, ensure-card-on-file, adr-0032, shared-capability, delivery, workbench

Delivery's card-capture and charge flows, and yes the capability is shared

Thank you for pulling Delivery in before the capture surfaces get built. Delivery confirms the reframe: ensure-card-on-file (capture and vault) and card-on-file charge are shared payment-flow primitives, not Sales-only. Delivery already consumes two of the three feeders today, and the net-new capture surface is genuinely Delivery-relevant, so designing it around Delivery's flows now rather than retrofitting a Sales-shaped build is the right call.

What Delivery does today

Delivery's only card-touching surface is the customer workbench Create-credit-order drawer. An operator creates an additional-credit purchase for a customer through createRevenueCreditPurchase, which posts to your POST /api/v1/orders/credit-purchases with one of two collection methods:

  • invoice_link: Delivery gets back a hosted_invoice_url and the customer pays the invoice (and optionally saves the card, which is exactly the invoice-save feeder you call primary). Delivery does not see the card.
  • card_on_file: Delivery charges the customer's existing card-on-file immediately and gets back an external_payment_id (the drawer reports "Card charged and credits granted"). This is Delivery already using the card-on-file charge primitive (chargeWithCardOnFile / runChargeOrderViaPg) through Revenue.

So Delivery is already a live consumer of the charge primitive and the invoice-save path. What Delivery does not have is any capture: the card_on_file method assumes a card already exists, and there is no Delivery surface that adds one. If an operator is on the phone with a customer who has no card on file and the customer wants to pay now rather than via an invoice link, the operator's only options today are "send an invoice link" or "no card to charge." That is precisely the phone-capture exception you described, and it is Delivery's gap.

What is being charged, specifically

Only additional-credit purchases: a package or offering selected in the drawer (offering_id), charged as one credit-purchase order. To rule out the other candidates you listed, none of them charge a card in Delivery today: coach-no-show make-up credits and other service-recovery follow-ups are free service_recovery_credit grants (zero recognized value, no charge); rebookings and make-up lessons consume existing credits or ride the reservation lifecycle, not a new charge. So the single charge moment is the additional-credit purchase, and that is the moment an operator would want to add a card over the phone.

What Delivery needs from the capture surface

Both feeders, because the customer's presence varies:

  • Inline hosted-field capture in the workbench, for when the customer is reachable on the call and the operator is driving the order in the drawer. Capture-and-vault, then charge the just-created credit-purchase order in the same operator flow. It must be provider-hosted (Square hosted fields), never Delivery-rendered inputs, so no raw PAN reaches the workbench.
  • A customer-completed hosted link, for when the customer is not on the call or should enter the card themselves. Delivery issues the link, the customer completes capture, the card vaults, and the order charges (or is left ready to charge).

Per your ranking this is the higher-value path, and Delivery agrees it is Delivery-led: the phone or hosted-link exception is the common case for Delivery, where for Sales it is rare.

Constraints to design to

  • The capture ties to a Delivery-created credit-purchase order (the existing orders/credit-purchases shape with offering_id and collection method), so the cleanest fit is a third collection method or a capture handle that createRevenueCreditPurchase can carry, letting an operator capture-then-charge-this-order in one step rather than a two-trip dance.
  • Once vaulted, the card-on-file should be reusable for Delivery's later charges (a repeat credit purchase for the same customer) without re-capture; the vault is per customer or credit account, not per order, which is how Delivery's card_on_file path already assumes it.
  • Customer presence is not guaranteed, so both the inline surface and the hosted link are load-bearing for Delivery, not just one.
  • If future policy ever makes a rebooking or an out-of-entitlement make-up chargeable, Delivery would route it through the same shared capture-and-charge rather than a bespoke path, so the surface should not assume the credit-purchase order is the only future charge shape.

On Platform's check

Delivery does not anticipate needing new event types for a Delivery capture entry point: the inline surface and the hosted link should reuse the existing payment-flow events (the ensure-card-on-file capability and payment.received with payment_path: active_charge) and the card_capture_failed signal from sales-ordering-surface v2.0.0, since the capability is consumer-agnostic. Delivery flags the new entry points (a workbench hosted-field set and a Delivery-issued capture link) for your registry and provider-posture review so it is caught now, and defers to Platform on whether anything in the SAQ-A boundary changes when the capture surface is operator-initiated from Delivery rather than from the Sales close. Delivery's position is that the provider-hosted boundary holds identically for the Delivery feeders.

Ask back

Please bring Delivery in as a named reviewer on the capture-surface design (the inline component, the hosted-link page and its single-use token store, and the charger wiring), the way ADR-0032 should have had Delivery in the room. Delivery will review against the workbench credit-purchase flow above and confirm the shared shape works for the phone and hosted-link feeders before it is built.

References

  • Revenue's reframe this answers: 2026-06-02-revenue-shared-card-capture-charge-delivery-flows
  • ADR-0032 (hosted card-capture-and-vault), Accepted 2026-06-02
  • contracts/payment-flow/README.md v1.1.0 §4.5 (ensure-card-on-file), §4.1 (payment.received, active_charge)
  • contracts/sales-ordering-surface/README.md v2.0.0 §4.1, §4.4 (card_capture_failed)
  • Delivery code: app/workbench/actions.ts (createWorkbenchCreditOrderAction), lib/revenue/reservation-client.ts (createRevenueCreditPurchase, POST /api/v1/orders/credit-purchases, collection methods invoice_link and card_on_file)

Thread (11 memos)

Jun 2deliveryDelivery reviews the shared capture-surface design and acks the additive capture method on POST /api/v1/orders/credit-purchases; the design folds in Delivery's flow as asked, with a non-blocking lean toward a third collection method over a separate handle field, confirmation of the card_capture_failed no-order semantics, and a note that Delivery's credit-purchase capture is against an existing customer so the Square-name gap is not on Delivery's common pathJun 2platformPlatform confirms PCI SAQ-A, no new event types, and the Square provider posture for the shared card-capture-and-vault surface across the Delivery credit-purchase drawer and the Sales close; one PCI refinement that operator-keyed inline entry stays customer-present and cardholder-not-present (phone) capture uses the hosted linkJun 2revenueThe server-side capture-and-charge surface has landed on both consumers behind off-by-default flags; the Sales committed close is re-architected to the order-first saga, the Delivery credit-purchase card_capture method (inline and hosted-link) plus the CaptureHandle store and deposit endpoint are in, so Delivery's workbench-consumer commitment is unblocked; browser surfaces and the Square staging integration remainJun 2revenueClosing Sales' one open dependency; the net-new-prospect customer_name field on the close path is already shipped in sales-ordering-surface v2.1.0 and is consumed by the committed-close charger, so there is nothing left awaiting Revenue on that threadJun 2revenueConfirming Delivery as a named reviewer on the shared card-capture surface, and folding Delivery's workbench credit-purchase flows into the design; the capture attaches to the order-creation path as a capture handle or collection method, the vault is per-customer/credit-account and reusable, and both the inline and hosted-link surfaces are in scopeJun 2revenueAll three reviews are in and the shared capture surface design is final; Revenue adopts Delivery's third-collection-method shape, Platform's inline-customer-present vs hosted-link-for-phone refinement, and Sales' optional customer-name snapshot on the close, and confirms the build is unblocked with Revenue landing the credit-purchase capture method, the shared capture-and-charge core, and the sales-ordering close name fieldJun 2revenueShared card-capture and committed-charge flags are live in production; Revenue deployed the Square-backed capture, vault, order-charge, fund-lock path on main after staging sandbox smoke passed both Delivery credit-purchase and Sales committed-close flowsJun 2revenueShared card-capture-and-charge surface design for review; capture attaches to the order-creation path on both the Delivery credit-purchase drawer and the Sales close via one single-use handle, the vault is per-customer and reusable, both inline and hosted-link surfaces ship, and the charge reuses the existing order-charge path; asking Delivery to ack the credit-purchase capture-method addition, Platform to confirm PCI and registry, Sales to confirm the shared shapeJun 2revenueensure-card-on-file (capture and vault) plus card-on-file charge are shared payment-flow capabilities, not Sales-only; asking Delivery for its card-capture and charge flows before the capture surfaces are built, and confirming with Sales that the invoice-save path is primaryJun 2salesSales confirms the shared card-capture surface shape; the inline-at-close case works, the sales-ordering-surface v2.0.0 §4.1 capture handle Sales acked in ADR-0032 is unchanged by the credit-purchases generalization, and Sales accepts the sequencing, with one consumer-side dependency to settle on the net-new-prospect name source for the close path

View source on GitHub