diff --git a/postman/collections/Fleetbase Storefront API/.resources/definition.yaml b/postman/collections/Fleetbase Storefront API/.resources/definition.yaml index 7f53c86..1459655 100644 --- a/postman/collections/Fleetbase Storefront API/.resources/definition.yaml +++ b/postman/collections/Fleetbase Storefront API/.resources/definition.yaml @@ -14,7 +14,15 @@ scripts: // Status is asserted explicitly against a list. The obvious-looking // `pm.expect(pm.response).to.be.ok` is chai's truthiness check on an object and // is therefore true for every response, including a 400 — it asserts nothing. - const expected = pm.request.method === 'POST' ? [200, 201, 202] : [200, 201, 202, 204]; + // + // A request whose CONTRACT is a refusal (e.g. capturing an unpaid Stripe checkout + // must answer 402) opts out of the 2xx expectation by setting `expected_status` + // in its beforeRequest script. The error-payload check is skipped for it too — + // the error body is exactly what such a request is asserting. + const expectedOverride = Number(pm.variables.get('expected_status')) || null; + const expected = expectedOverride + ? [expectedOverride] + : (pm.request.method === 'POST' ? [200, 201, 202] : [200, 201, 202, 204]); pm.test(`${pm.info.requestName} responds 2xx`, function () { pm.expect(pm.response.code, `got HTTP ${pm.response.code}`).to.be.oneOf(expected); @@ -38,6 +46,7 @@ scripts: (Array.isArray(value) && value.length === 0); pm.test(`${pm.info.requestName} returns no error payload`, function () { + if (expectedOverride) { return; } let body; try { body = pm.response.json(); } catch (e) { return; } if (body === null || typeof body !== 'object') { return; } diff --git a/postman/collections/Fleetbase Storefront API/Checkout/Before Cash Pickup Checkout.queryParams.yaml b/postman/collections/Fleetbase Storefront API/Checkout/Before Cash Pickup Checkout.queryParams.yaml new file mode 100644 index 0000000..39f7b42 --- /dev/null +++ b/postman/collections/Fleetbase Storefront API/Checkout/Before Cash Pickup Checkout.queryParams.yaml @@ -0,0 +1,14 @@ +$kind: params +fields: + - name: gateway + type: string + description: "Payment gateway code — `cash` for a cash-on-delivery checkout." + - name: customer + type: string + description: "Customer ID associated with the request." + - name: cart + type: string + description: "Cart value for this checkout request." + - name: pickup + type: boolean + description: "Set true for a pickup order; a cash pickup checkout needs no service quote." diff --git a/postman/collections/Fleetbase Storefront API/Checkout/Before Cash Pickup Checkout.request.yaml b/postman/collections/Fleetbase Storefront API/Checkout/Before Cash Pickup Checkout.request.yaml new file mode 100644 index 0000000..0de5735 --- /dev/null +++ b/postman/collections/Fleetbase Storefront API/Checkout/Before Cash Pickup Checkout.request.yaml @@ -0,0 +1,25 @@ +$kind: http-request +description: |- + Initializes a cash (cash-on-delivery) pickup checkout. A pickup checkout with the cash gateway needs no delivery service quote, so the `service_quote` parameter is omitted. The response returns the checkout id and token; no gateway client data is prepared for cash. +url: "{{base_url}}/{{api_prefix}}/{{namespace}}/checkouts/before" +method: GET +queryParams: + gateway: "cash" + customer: "{{customer_id}}" + cart: "{{cart_id}}" + pickup: "true" +scripts: + - type: afterResponse + code: |- + // Capture checkout as order captures THIS checkout: cash needs no provider + // payment, so it is the one checkout in the run that capture can actually turn + // into an order. Saved under its own name so the stripe checkout's + // {{checkout_token}}/{{checkout_id}} stay intact for Get Checkout Status and + // the QPay callbacks. + var json_response = pm.response.json(); + + if (json_response && json_response.token) { + pm.environment.set("cash_checkout_token", json_response.token); + } + language: text/javascript +order: 1100 diff --git a/postman/collections/Fleetbase Storefront API/Checkout/Capture Stripe checkout without payment.params.yaml b/postman/collections/Fleetbase Storefront API/Checkout/Capture Stripe checkout without payment.params.yaml new file mode 100644 index 0000000..88134d1 --- /dev/null +++ b/postman/collections/Fleetbase Storefront API/Checkout/Capture Stripe checkout without payment.params.yaml @@ -0,0 +1,6 @@ +$kind: params +fields: + - name: token + type: string + required: true + description: "Checkout token of a Stripe checkout whose PaymentIntent has not succeeded." diff --git a/postman/collections/Fleetbase Storefront API/Checkout/Capture Stripe checkout without payment.request.yaml b/postman/collections/Fleetbase Storefront API/Checkout/Capture Stripe checkout without payment.request.yaml new file mode 100644 index 0000000..b815cda --- /dev/null +++ b/postman/collections/Fleetbase Storefront API/Checkout/Capture Stripe checkout without payment.request.yaml @@ -0,0 +1,29 @@ +$kind: http-request +description: |- + Documents the refusal contract for capturing a Stripe checkout whose PaymentIntent has not succeeded: the API answers `402` with `"Stripe payment has not been completed."` and creates no order. Client-supplied transaction details can never substitute for the provider's verified payment state. +url: "{{base_url}}/{{api_prefix}}/{{namespace}}/checkouts/capture" +method: POST +headers: + - key: Content-Type + value: application/json +body: + type: json + content: |- + { + "token": "{{checkout_token}}" + } +scripts: + - type: beforeRequest + code: |- + // This request's contract IS the refusal — see the collection-level baseline + // script, which asserts this status instead of 2xx and skips the error-payload + // check when expected_status is set. + pm.variables.set('expected_status', 402); + language: text/javascript + - type: afterResponse + code: |- + pm.test('Capture without payment is refused with the Stripe contract error', function () { + pm.expect(pm.response.json().error).to.eql('Stripe payment has not been completed.'); + }); + language: text/javascript +order: 3100 diff --git a/postman/collections/Fleetbase Storefront API/Checkout/Capture checkout as order.request.yaml b/postman/collections/Fleetbase Storefront API/Checkout/Capture checkout as order.request.yaml index d8283a8..90da2ae 100644 --- a/postman/collections/Fleetbase Storefront API/Checkout/Capture checkout as order.request.yaml +++ b/postman/collections/Fleetbase Storefront API/Checkout/Capture checkout as order.request.yaml @@ -1,6 +1,6 @@ $kind: http-request description: |- - Captures a checkout token and creates the corresponding order. The response returns the completed order or the existing order when the checkout was already captured. + Captures a checkout token and creates the corresponding order. The response returns the completed order or the existing order when the checkout was already captured. Gateway checkouts must be paid before capture — a Stripe checkout whose PaymentIntent has not succeeded is refused with `402` — so this example captures the cash pickup checkout, which needs no provider payment. url: "{{base_url}}/{{api_prefix}}/{{namespace}}/checkouts/capture" method: POST headers: @@ -10,7 +10,7 @@ body: type: json content: |- { - "token": "{{checkout_token}}" + "token": "{{cash_checkout_token}}" } scripts: - type: afterResponse diff --git a/postman/collections/Fleetbase Storefront API/Customer/Update Contact Customer Alias.request.yaml b/postman/collections/Fleetbase Storefront API/Customer/Update Contact Customer Alias.request.yaml index 5242e3b..30f58b0 100644 --- a/postman/collections/Fleetbase Storefront API/Customer/Update Contact Customer Alias.request.yaml +++ b/postman/collections/Fleetbase Storefront API/Customer/Update Contact Customer Alias.request.yaml @@ -1,9 +1,11 @@ $kind: http-request description: |- - Updates a storefront customer through the legacy contact alias route. The request is handled by the same customer update controller as `/customers/{id}`. + Updates a storefront customer through the legacy contact alias route. The request is handled by the same customer update controller as `/customers/{id}` and carries the same authorization contract: it must be authenticated with the `Customer-Token` of the customer being updated. url: "{{base_url}}/{{api_prefix}}/{{namespace}}/contacts/{{customer_id}}" method: PUT headers: + - key: Customer-Token + value: "{{customer_token}}" - key: Content-Type value: application/json body: diff --git a/postman/collections/Fleetbase Storefront API/Customer/Update a Customer.request.yaml b/postman/collections/Fleetbase Storefront API/Customer/Update a Customer.request.yaml index 3580ac2..7283260 100644 --- a/postman/collections/Fleetbase Storefront API/Customer/Update a Customer.request.yaml +++ b/postman/collections/Fleetbase Storefront API/Customer/Update a Customer.request.yaml @@ -1,9 +1,11 @@ $kind: http-request description: |- - Updates a storefront customer profile. The response returns the customer with the new values applied. + Updates a storefront customer profile. The request must be authenticated as the customer being updated: the `Customer-Token` identity is authoritative and a token belonging to a different customer is rejected with `403`. The response returns the customer with the new values applied. url: "{{base_url}}/{{api_prefix}}/{{namespace}}/customers/{{customer_id}}" method: PUT headers: + - key: Customer-Token + value: "{{customer_token}}" - key: Content-Type value: application/json body: