fix(storefront): align contract collection with customer authorization and Stripe payment verification - #55
Merged
Conversation
…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
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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:Customer-Tokenof the customer being updated.Update a CustomerandUpdate Contact Customer Aliassent no Customer-Token at all (only the store key), so both answer403 Not authorized to update customer.402 Stripe payment has not been completed.— and with no order created,Complete Order PickupandGet Order Receiptcascade intoNo order found.What changed
Customer/Update a Customer,Customer/Update Contact Customer Alias: sendCustomer-Token: {{customer_token}}— the tokenAuthenticate a Customercaptures, which belongs to the same{{customer_id}}both requests target. Descriptions document the authorization contract.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). Savescash_checkout_tokenwithout touching the stripe checkout's variables, whichGet Checkout Statusand 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.Checkout/Capture Stripe checkout without payment: explicit negative contract — asserts402and the exactStripe payment has not been completed.error for the unpaid stripe checkout.expected_statusin itsbeforeRequestscript; 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.pyin fleetbase/fleetbase) must add the two new requests to the storefrontRUN_LATEsequence — 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-iflags).Validation
npm run postman:lint— Fleetbase Storefront API: 62 items scanned, 0 errors, 0 warnings (all collections clean).dev-v0.4.20code: cash pickupbeforereturns{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.ioregeneration may be needed after merge.