Skip to content

fix(storefront): align contract collection with customer authorization and Stripe payment verification - #55

Merged
roncodes merged 1 commit into
mainfrom
fix/storefront-contract-authorized-flows
Aug 31, 2026
Merged

fix(storefront): align contract collection with customer authorization and Stripe payment verification#55
roncodes merged 1 commit into
mainfrom
fix/storefront-contract-authorized-flows

Conversation

@roncodes

Copy link
Copy Markdown
Member

Why

The storefront contract run (e.g. fleetbase/storefront#91's contract job) fails with 10 assertions since two intentional security fixes landed in dev-v0.4.20:

  • Authorize Storefront customer profile updates storefront#94 — customer updates now require the Customer-Token of the customer being updated. Update a Customer and Update Contact Customer Alias sent no Customer-Token at all (only the store key), so both answer 403 Not authorized to update customer.
  • Verify Stripe payment before Storefront order capture storefront#95 — capture now requires a succeeded Stripe PaymentIntent. The run cannot complete a card payment, so capturing the stripe checkout can only ever answer 402 Stripe payment has not been completed. — and with no order created, Complete Order Pickup and Get Order Receipt cascade into No order found.

What changed

  • Customer/Update a Customer, Customer/Update Contact Customer Alias: send Customer-Token: {{customer_token}} — the token Authenticate a Customer captures, which belongs to the same {{customer_id}} both requests target. Descriptions document the authorization contract.
  • New Checkout/Before Cash Pickup Checkout: initializes a cash pickup checkout — no provider payment and no service quote (documents the Fix cash pickup checkout without delivery quote storefront#93 behavior). Saves cash_checkout_token without touching the stripe checkout's variables, which Get Checkout Status and the QPay callbacks still use.
  • Checkout/Capture checkout as order: captures the cash checkout, so the run creates a real order again and {{order_id}} flows to the order requests.
  • New Checkout/Capture Stripe checkout without payment: explicit negative contract — asserts 402 and the exact Stripe payment has not been completed. error for the unpaid stripe checkout.
  • Collection baseline script: a request whose contract is a refusal can set expected_status in its beforeRequest script; the baseline then asserts that status instead of 2xx and skips the error-payload check for it.

Companion PR (merge order matters)

The CI orderer (scripts/ci/order-collection-requests.py in fleetbase/fleetbase) must add the two new requests to the storefront RUN_LATE sequence — companion PR in fleetbase/fleetbase. Merge this PR first: until the companion lands, the two new requests run in the ordinary phase before their variables are set (two transient failures). Merging the companion first would abort the whole run (unresolvable -i flags).

Validation

  • npm run postman:lint — Fleetbase Storefront API: 62 items scanned, 0 errors, 0 warnings (all collections clean).
  • Server-side behavior verified against the storefront dev-v0.4.20 code: cash pickup before returns {checkout, token} with no quote required; capture of a cash checkout creates the order; receipt for a cash order answers 200 with no error key; both update routes 200 when the token owner matches.

Docs impact

The collection doubles as published API reference: the two new requests document the fleetbase/storefront#93 (cash pickup without quote) and fleetbase/storefront#95 (402 refusal) behaviors, and the update-request descriptions now state the fleetbase/storefront#94 authorization contract. fleetbase/fleetbase.io regeneration may be needed after merge.

…n and stripe payment verification

The storefront API now enforces two security contracts the collection
predates:

- Customer updates require the Customer-Token of the customer being
  updated (fleetbase/storefront#94). Update a Customer and Update Contact
  Customer Alias sent no Customer-Token at all, so both now answer 403.
  Both requests now carry the token that Authenticate a Customer captures,
  which belongs to the same {{customer_id}} they target.

- Capturing a Stripe checkout requires a succeeded PaymentIntent
  (fleetbase/storefront#95). The run cannot complete a card payment, so
  capturing the stripe checkout can only ever answer 402 — and with no
  order created, Complete Order Pickup and Get Order Receipt cascaded
  into 'No order found.'

  The capture flow is restructured around that: a new Before Cash Pickup
  Checkout initializes a cash pickup checkout (no provider payment, no
  service quote — the fleetbase/storefront#93 behavior), Capture checkout
  as order captures it into a real order for the downstream order
  requests, and a new Capture Stripe checkout without payment documents
  the 402 refusal as an explicit negative contract. The collection
  baseline script gains an expected_status opt-out so a request whose
  contract is a refusal can assert it.

Requires the RUN_LATE sequence update in fleetbase/fleetbase's
scripts/ci/order-collection-requests.py (companion PR) — merge this one
first: until the companion lands, the two new requests run in the
ordinary phase before their variables are set.

Validation: npm run postman:lint — 62 storefront items scanned, 0 errors,
0 warnings.
@roncodes
roncodes merged commit 94e7e84 into main Aug 31, 2026
1 check passed
@roncodes
roncodes deleted the fix/storefront-contract-authorized-flows branch August 31, 2026 04:13
roncodes added a commit that referenced this pull request Aug 31, 2026
Both branches added the identical Customer-Token headers to the two
customer update requests, so only the descriptions conflicted — resolved
by combining this branch's exact 403 error contract with main's
authoritative-identity framing.

Capture checkout as order keeps main's functional change (it captures
the cash pickup checkout via {{cash_checkout_token}}, since a contract
run cannot complete a card payment) and this branch's documentation of
the idempotency and 402/409/422/502 verification contract, plus a note
pointing at the explicit 402 negative-contract request.

Validation: node scripts/validate-collections.js (5 collections, 3
environments) and postman collection lint on Fleetbase Storefront API —
62 items scanned, 0 errors, 0 warnings.
pull Bot pushed a commit to danielabelski/fleetbase that referenced this pull request Aug 31, 2026
…heckout

Storefront now refuses to capture a Stripe checkout whose PaymentIntent
has not succeeded (fleetbase/storefront#95), and a contract run can never
complete a card payment — so the stripe capture step could only ever
answer 402, and with no order created the pickup and receipt requests
cascaded into 'No order found.'

Resequence the storefront RUN_LATE chain around the collection's new
requests (fleetbase/postman#55): read the stripe checkout (status,
intent update) before anything consumes the cart, assert the 402 refusal
as an explicit negative contract, then initialize and capture a cash
pickup checkout — which needs no provider payment — so the run creates a
real order for Complete Order Pickup and Get Order Receipt. The QPay
callbacks keep addressing the stripe checkout's {{checkout_id}},
unchanged.

Merge AFTER fleetbase/postman#55: RUN_LATE entries are emitted as -i
flags without being matched against files first, so naming requests the
collection does not have yet would abort the whole run with 0 requests
executed.

Validated by running the orderer against the updated collection: the
chain emits in the intended sequence, both new requests resolve, and no
missing-entry warnings are produced.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant