diff --git a/postman/collections/Fleetbase Storefront API/Cart/.resources/definition.yaml b/postman/collections/Fleetbase Storefront API/Cart/.resources/definition.yaml index c7aea0f..3de170c 100644 --- a/postman/collections/Fleetbase Storefront API/Cart/.resources/definition.yaml +++ b/postman/collections/Fleetbase Storefront API/Cart/.resources/definition.yaml @@ -1,4 +1,4 @@ $kind: collection description: |- - Carts hold the products a storefront customer intends to purchase. Use cart endpoints to create or retrieve a cart, add or update line items, empty the cart, and prepare it for checkout. + Carts hold the products a storefront customer intends to purchase. Use cart endpoints to create or retrieve a cart, add or update line items, apply or preview promo codes and promotions, empty the cart, and prepare it for checkout. order: 1000 diff --git a/postman/collections/Fleetbase Storefront API/Cart/.resources/object.yaml b/postman/collections/Fleetbase Storefront API/Cart/.resources/object.yaml index f21ffdb..6120288 100644 --- a/postman/collections/Fleetbase Storefront API/Cart/.resources/object.yaml +++ b/postman/collections/Fleetbase Storefront API/Cart/.resources/object.yaml @@ -12,7 +12,8 @@ example: | "total_unique_items": 2, "items": [], "events": [], - "discount_code": null, + "discount_code": "SUMMER25", + "promo_codes": ["SUMMER25"], "expires_at": "2026-05-08T09:30:00Z", "created_at": "2026-05-07T09:30:00Z", "updated_at": "2026-05-07T09:30:00Z" @@ -44,7 +45,10 @@ fields: description: "Cart event history." - name: discount_code type: string - description: "Discount code applied to the cart." + description: "Promo codes applied to the cart, comma separated. Prefer `promo_codes`." + - name: promo_codes + type: array of strings + description: "Promo codes applied to the cart with Apply Promotion Code to Cart. They are used automatically at checkout." - name: expires_at type: timestamp description: "Time the cart expires." diff --git a/postman/collections/Fleetbase Storefront API/Cart/Apply Promotion Code to Cart.params.yaml b/postman/collections/Fleetbase Storefront API/Cart/Apply Promotion Code to Cart.params.yaml new file mode 100644 index 0000000..a2cf479 --- /dev/null +++ b/postman/collections/Fleetbase Storefront API/Cart/Apply Promotion Code to Cart.params.yaml @@ -0,0 +1,12 @@ +$kind: params +fields: + - name: code + type: string + required: true + description: "The promo code to apply." + - name: pickup + type: boolean + description: "Price the cart as a pickup order when validating the code." + - name: service_quote + type: string + description: "Delivery service quote public ID, for free delivery codes." diff --git a/postman/collections/Fleetbase Storefront API/Cart/Apply Promotion Code to Cart.request.yaml b/postman/collections/Fleetbase Storefront API/Cart/Apply Promotion Code to Cart.request.yaml new file mode 100644 index 0000000..a11c9d6 --- /dev/null +++ b/postman/collections/Fleetbase Storefront API/Cart/Apply Promotion Code to Cart.request.yaml @@ -0,0 +1,37 @@ +$kind: http-request +description: |- + Applies a promo code to the cart after checking that it can be used on it. Codes are case insensitive. On success it returns `{ "cart": Cart, "promotions": preview }` (see Preview Cart Promotions) and stores the code in the cart's `promo_codes`; codes applied to a cart are used automatically at checkout. + + A code that cannot be applied returns `400` with the reason, e.g. `Promotion code "SUMMER" cannot be applied (invalid_code).` and `"reason": "invalid_code"`. Reasons: `invalid_code`, `not_applicable`, `not_active`, `usage_limit_reached`, `customer_usage_limit_reached`, `budget_exhausted`, `currency_mismatch`, `first_order_only`, `min_subtotal`, `min_items`, `no_eligible_items`, `pickup_order`, `no_discount`. A code that is valid but loses to a better combination of promotions is kept on the cart and reported in `promotions.rejected` as `not_combinable`. +url: "{{base_url}}/{{api_prefix}}/{{namespace}}/carts/{{cart_id}}/promo-code" +method: POST +headers: + - key: Customer-Token + value: "{{customer_token}}" + - key: Content-Type + value: application/json +body: + type: json + content: |- + { + "code": "{{promo_code}}" + } +scripts: + - type: beforeRequest + code: |- + // Uses {{promo_code}} when the environment provides a real code. Without one it + // sends an unknown code, and the request documents the refusal contract. + if (!pm.environment.get('promo_code')) { + pm.variables.set('promo_code', 'NOT-A-REAL-CODE'); + pm.variables.set('expected_status', 400); + } + language: text/javascript + - type: afterResponse + code: |- + if (pm.response.code === 400) { + pm.test('An unusable code is refused with its reason', function () { + pm.expect(pm.response.json().error).to.include('cannot be applied'); + }); + } + language: text/javascript +order: 1200 diff --git a/postman/collections/Fleetbase Storefront API/Cart/Preview Cart Promotions.queryParams.yaml b/postman/collections/Fleetbase Storefront API/Cart/Preview Cart Promotions.queryParams.yaml new file mode 100644 index 0000000..a241d47 --- /dev/null +++ b/postman/collections/Fleetbase Storefront API/Cart/Preview Cart Promotions.queryParams.yaml @@ -0,0 +1,8 @@ +$kind: params +fields: + - name: pickup + type: boolean + description: "Price the cart as a pickup order (no delivery discounts)." + - name: service_quote + type: string + description: "Delivery service quote public ID, used to price free delivery promotions." diff --git a/postman/collections/Fleetbase Storefront API/Cart/Preview Cart Promotions.request.yaml b/postman/collections/Fleetbase Storefront API/Cart/Preview Cart Promotions.request.yaml new file mode 100644 index 0000000..43e43e0 --- /dev/null +++ b/postman/collections/Fleetbase Storefront API/Cart/Preview Cart Promotions.request.yaml @@ -0,0 +1,24 @@ +$kind: http-request +description: |- + Previews the discounts the cart currently qualifies for: the storefront's automatic promotions plus the promo codes applied to the cart. Pass `pickup` and `service_quote` so delivery discounts are priced. Customer rules (first order only, per-customer limits) are only checked when a `Customer-Token` is sent, and every rule is checked again at checkout. + + Returns `{ "discount", "discount_subtotal", "discount_delivery", "applied": [...], "rejected": [...] }`. Each applied entry has `promotion`, `name`, `type`, `code`, `amount` and `delivery_amount` (minor units). Each rejected entry is `{ "code", "reason" }`. +url: "{{base_url}}/{{api_prefix}}/{{namespace}}/carts/{{cart_id}}/promotions" +method: GET +headers: + - key: Customer-Token + value: "{{customer_token}}" +queryParams: + pickup: "false" + service_quote: "{{service_quote_id}}" +scripts: + - type: afterResponse + code: |- + pm.test('Promotion preview carries the discount totals', function () { + var body = pm.response.json(); + pm.expect(body.discount).to.be.a('number'); + pm.expect(body.applied).to.be.an('array'); + pm.expect(body.rejected).to.be.an('array'); + }); + language: text/javascript +order: 1100 diff --git a/postman/collections/Fleetbase Storefront API/Cart/Remove Promotion Code from Cart.request.yaml b/postman/collections/Fleetbase Storefront API/Cart/Remove Promotion Code from Cart.request.yaml new file mode 100644 index 0000000..b41bee0 --- /dev/null +++ b/postman/collections/Fleetbase Storefront API/Cart/Remove Promotion Code from Cart.request.yaml @@ -0,0 +1,16 @@ +$kind: http-request +description: |- + Removes a promo code from the cart and returns `{ "cart": Cart, "promotions": preview }`. Removing a code that is not on the cart is not an error. +url: "{{base_url}}/{{api_prefix}}/{{namespace}}/carts/{{cart_id}}/promo-code/{{promo_code}}" +method: DELETE +headers: + - key: Customer-Token + value: "{{customer_token}}" +scripts: + - type: beforeRequest + code: |- + if (!pm.environment.get('promo_code')) { + pm.variables.set('promo_code', 'NOT-A-REAL-CODE'); + } + language: text/javascript +order: 1300 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 index 39f7b42..7c19fd4 100644 --- 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 @@ -12,3 +12,6 @@ fields: - name: pickup type: boolean description: "Set true for a pickup order; a cash pickup checkout needs no service quote." + - name: promo_codes + type: array of strings + description: "Promo codes to apply, as an array or a comma separated string. `promo_code` and `discount_code` are accepted for a single code. Codes already applied to the cart are always included. The checkout is refused with `400` and `promotions.rejected[]` (`{ code, reason }`) when a code cannot be applied; the discount of the storefront's automatic promotions is applied without a code." diff --git "a/postman/collections/Fleetbase Storefront API/Checkout/Before \342\235\227.queryParams.yaml" "b/postman/collections/Fleetbase Storefront API/Checkout/Before \342\235\227.queryParams.yaml" index cb6adc1..c316ca9 100644 --- "a/postman/collections/Fleetbase Storefront API/Checkout/Before \342\235\227.queryParams.yaml" +++ "b/postman/collections/Fleetbase Storefront API/Checkout/Before \342\235\227.queryParams.yaml" @@ -24,3 +24,6 @@ fields: - name: delivery_tip type: number description: "Tip amount allocated to delivery." + - name: promo_codes + type: array of strings + description: "Promo codes to apply, as an array or a comma separated string. `promo_code` and `discount_code` are accepted for a single code. Codes already applied to the cart are always included. The checkout is refused with `400` and `promotions.rejected[]` (`{ code, reason }`) when a code cannot be applied; the discount of the storefront's automatic promotions is applied without a code." diff --git "a/postman/collections/Fleetbase Storefront API/Checkout/Before \342\235\227.request.yaml" "b/postman/collections/Fleetbase Storefront API/Checkout/Before \342\235\227.request.yaml" index 14c2f3c..35474e4 100644 --- "a/postman/collections/Fleetbase Storefront API/Checkout/Before \342\235\227.request.yaml" +++ "b/postman/collections/Fleetbase Storefront API/Checkout/Before \342\235\227.request.yaml" @@ -1,6 +1,8 @@ $kind: http-request description: |- Initializes a checkout preview for a cart, customer, gateway, and delivery or pickup option. The response prepares gateway-specific client data or a checkout token before the order is captured. + + Promotions are priced when the checkout is created: automatic promotions and any promo codes (from `promo_codes` or applied to the cart) are subtracted from the amount charged, and each use is reserved for the checkout. A code that cannot be applied refuses the checkout with `400`. url: "{{base_url}}/{{api_prefix}}/{{namespace}}/checkouts/before" method: GET queryParams: diff --git a/postman/collections/Fleetbase Storefront API/Checkout/Update Stripe Payment Intent.params.yaml b/postman/collections/Fleetbase Storefront API/Checkout/Update Stripe Payment Intent.params.yaml index ee36024..d5868d7 100644 --- a/postman/collections/Fleetbase Storefront API/Checkout/Update Stripe Payment Intent.params.yaml +++ b/postman/collections/Fleetbase Storefront API/Checkout/Update Stripe Payment Intent.params.yaml @@ -1,15 +1,29 @@ $kind: params fields: - - name: name + - name: customer type: string - description: "Display name for the resource." - - name: description + required: true + description: "Customer public ID. When Customer-Token is present it must identify the authenticated customer." + - name: cart type: string - description: "Human-readable description of the resource." - - name: status - type: enum - values: ["active", "inactive"] - description: "Lifecycle status to apply to the resource." - - name: meta + required: true + description: "Cart public ID or unique identifier." + - name: payment_intent_id type: string - description: "Arbitrary metadata stored with the resource." + required: true + description: "Stripe PaymentIntent to update. `paymentIntent` and `paymentIntentId` are accepted aliases." + - name: service_quote + type: string + description: "Delivery service quote public ID. `serviceQuote` is an accepted alias." + - name: pickup + type: boolean + description: "Whether the order is a pickup order." + - name: tip + type: number + description: "Tip, as an amount or a percentage string such as `10%`." + - name: delivery_tip + type: number + description: "Delivery tip, as an amount or a percentage string. `deliveryTip` is an accepted alias." + - name: promo_codes + type: array of strings + description: "Promo codes to apply, as an array or a comma separated string. `promo_code` and `discount_code` are accepted for a single code. Codes already applied to the cart are always included. The checkout is refused with `400` and `promotions.rejected[]` (`{ code, reason }`) when a code cannot be applied; the discount of the storefront's automatic promotions is applied without a code." diff --git a/postman/collections/Fleetbase Storefront API/Customer/Register customer device.params.yaml b/postman/collections/Fleetbase Storefront API/Customer/Register customer device.params.yaml index 79b92a1..4a1ccb0 100644 --- a/postman/collections/Fleetbase Storefront API/Customer/Register customer device.params.yaml +++ b/postman/collections/Fleetbase Storefront API/Customer/Register customer device.params.yaml @@ -3,10 +3,16 @@ fields: - name: token type: string required: true - description: "Push notification device token." + description: "Push notification device token: the APNs device token on iOS, the FCM registration token on Android." - name: platform - type: string - description: "Device platform. `os` is also accepted as an alias." + type: enum + values: ["ios", "android"] + required: true + description: "Device platform, case insensitive. `os` is also accepted as an alias." - name: os type: string description: "Device platform alias used when `platform` is not provided." + - name: environment + type: enum + values: ["production", "sandbox"] + description: "Optional APNs environment that issued an iOS token (sandbox for development builds). When omitted the server tries production and falls back to sandbox. Stored only on Fleetbase versions that record device push metadata." diff --git a/postman/collections/Fleetbase Storefront API/Customer/Register customer device.request.yaml b/postman/collections/Fleetbase Storefront API/Customer/Register customer device.request.yaml index 9bfcd25..3c3ccb6 100644 --- a/postman/collections/Fleetbase Storefront API/Customer/Register customer device.request.yaml +++ b/postman/collections/Fleetbase Storefront API/Customer/Register customer device.request.yaml @@ -1,6 +1,6 @@ $kind: http-request description: |- - Registers a device token for the authenticated storefront customer. Use this to enable push notifications for the customer device. + Registers a push notification device token for the authenticated storefront customer. Call it whenever the app receives a new token or a different customer signs in: a token identifies one app install, so it always moves to the customer who registered it most recently. `platform` must be `ios` or `android` (case insensitive); the token is an APNs device token on iOS and an FCM registration token on Android. Returns `{ "status": "OK", "device": "" }`, or `400` for a missing token or unsupported platform. url: "{{base_url}}/{{api_prefix}}/{{namespace}}/customers/register-device" method: POST headers: diff --git a/postman/collections/Fleetbase Storefront API/Customer/Unregister customer device.params.yaml b/postman/collections/Fleetbase Storefront API/Customer/Unregister customer device.params.yaml new file mode 100644 index 0000000..c69a9b1 --- /dev/null +++ b/postman/collections/Fleetbase Storefront API/Customer/Unregister customer device.params.yaml @@ -0,0 +1,6 @@ +$kind: params +fields: + - name: token + type: string + required: true + description: "The push notification device token to remove." diff --git a/postman/collections/Fleetbase Storefront API/Customer/Unregister customer device.request.yaml b/postman/collections/Fleetbase Storefront API/Customer/Unregister customer device.request.yaml new file mode 100644 index 0000000..62813c1 --- /dev/null +++ b/postman/collections/Fleetbase Storefront API/Customer/Unregister customer device.request.yaml @@ -0,0 +1,26 @@ +$kind: http-request +description: |- + Removes a push notification device token from the authenticated customer, typically on sign out, so the device stops receiving that customer's notifications. Returns `{ "status": "OK", "deleted": n }`; unregistering a token the customer does not have deletes nothing and is not an error. +url: "{{base_url}}/{{api_prefix}}/{{namespace}}/customers/unregister-device" +method: POST +headers: + - key: Customer-Token + value: "{{customer_token}}" + - key: Content-Type + value: application/json +body: + type: json + content: |- + { + "token": "{{device_token}}" + } +scripts: + - type: beforeRequest + code: |- + // Register customer device uses {{device_token}}; fall back to a placeholder so + // the request still exercises the endpoint when none is configured. + if (!pm.environment.get('device_token')) { + pm.variables.set('device_token', 'postman-placeholder-device-token'); + } + language: text/javascript +order: 5100 diff --git a/postman/collections/Fleetbase Storefront API/Notifications/.resources/definition.yaml b/postman/collections/Fleetbase Storefront API/Notifications/.resources/definition.yaml new file mode 100644 index 0000000..f48ab63 --- /dev/null +++ b/postman/collections/Fleetbase Storefront API/Notifications/.resources/definition.yaml @@ -0,0 +1,6 @@ +$kind: collection +description: |- + The authenticated customer's notification inbox. Order status updates, promotional messages and campaigns are stored here as well as sent by push, so the app can list them, show an unread badge and mark them as read. Every request needs the `Customer-Token` header. A customer only sees their own notifications, limited to the storefront app the request is made with: a store key sees that store's notifications, a network key sees the network's and its member stores'. Notifications that reference no storefront are shown in every app. + + New notifications are also broadcast in realtime on the SocketCluster channel `contact.{customer uuid}` with the same shape as an inbox item. +order: 4500 diff --git a/postman/collections/Fleetbase Storefront API/Notifications/.resources/object.yaml b/postman/collections/Fleetbase Storefront API/Notifications/.resources/object.yaml new file mode 100644 index 0000000..498e670 --- /dev/null +++ b/postman/collections/Fleetbase Storefront API/Notifications/.resources/object.yaml @@ -0,0 +1,48 @@ +$kind: object +name: Notification +description: |- + An inbox item. `type` identifies what the notification is about (for example `order_accepted`, `order_completed`, `promotional` or `campaign`), and `data` carries the identifiers the app needs to deep link. Recipient details are never included. +example: | + { + "id": "0f4c9a52-8d3f-4a6e-9f0e-2b1f7f2f8c11", + "type": "order_completed", + "title": "Your order from Acme Market has been delivered", + "body": "Your order from Acme Market has been delivered, enjoy!", + "image": null, + "data": { + "order_id": "order_9Kx2mQ1", + "storefront_id": "store_3Xb9kL2", + "store_id": "store_3Xb9kL2" + }, + "is_read": false, + "read_at": null, + "created_at": "2026-09-26T09:30:00Z" + } +fields: + - name: id + type: string + description: "Notification id (uuid)." + - name: type + type: string + description: "What the notification is about, e.g. `order_accepted`, `order_enroute`, `order_nearby`, `order_completed`, `order_canceled`, `order_ready`, `order_driver_assigned`, `promotional` or `campaign`." + - name: title + type: string + description: "Notification title." + - name: body + type: string + description: "Notification message." + - name: image + type: string + description: "Optional image URL." + - name: data + type: object + description: "Deep link data with null values removed, such as `order_id`, `store_id`, `network_id`, `promotion_id`, `campaign_id` and `action`/`action_id`/`action_url`." + - name: is_read + type: boolean + description: "Whether the customer has read the notification." + - name: read_at + type: timestamp + description: "When the notification was read." + - name: created_at + type: timestamp + description: "When the notification was created." diff --git a/postman/collections/Fleetbase Storefront API/Notifications/Count Unread Notifications.request.yaml b/postman/collections/Fleetbase Storefront API/Notifications/Count Unread Notifications.request.yaml new file mode 100644 index 0000000..b07dc82 --- /dev/null +++ b/postman/collections/Fleetbase Storefront API/Notifications/Count Unread Notifications.request.yaml @@ -0,0 +1,16 @@ +$kind: http-request +description: |- + Returns `{ "count": n }`, the number of unread notifications for the authenticated customer in the current storefront. Use it for badges. +url: "{{base_url}}/{{api_prefix}}/{{namespace}}/notifications/unread-count" +method: GET +headers: + - key: Customer-Token + value: "{{customer_token}}" +scripts: + - type: afterResponse + code: |- + pm.test('Unread count is a number', function () { + pm.expect(pm.response.json().count).to.be.a('number'); + }); + language: text/javascript +order: 2000 diff --git a/postman/collections/Fleetbase Storefront API/Notifications/Delete a Notification.request.yaml b/postman/collections/Fleetbase Storefront API/Notifications/Delete a Notification.request.yaml new file mode 100644 index 0000000..863b74d --- /dev/null +++ b/postman/collections/Fleetbase Storefront API/Notifications/Delete a Notification.request.yaml @@ -0,0 +1,19 @@ +$kind: http-request +description: |- + Deletes one of the authenticated customer's notifications. Returns `{ "status": "OK", "id": "...", "deleted": true }`. +url: "{{base_url}}/{{api_prefix}}/{{namespace}}/notifications/{{notification_id}}" +method: DELETE +headers: + - key: Customer-Token + value: "{{customer_token}}" +scripts: + - type: beforeRequest + code: |- + // Addresses the first notification returned by List Notifications. A fresh + // stack has none, so without one this documents the not-found contract. + if (!pm.environment.get('notification_id')) { + pm.variables.set('notification_id', 'missing-notification'); + pm.variables.set('expected_status', 404); + } + language: text/javascript +order: 6000 diff --git a/postman/collections/Fleetbase Storefront API/Notifications/Get Notification Preferences.request.yaml b/postman/collections/Fleetbase Storefront API/Notifications/Get Notification Preferences.request.yaml new file mode 100644 index 0000000..62131ec --- /dev/null +++ b/postman/collections/Fleetbase Storefront API/Notifications/Get Notification Preferences.request.yaml @@ -0,0 +1,9 @@ +$kind: http-request +description: |- + Returns the authenticated customer's notification preferences, `{ "order_updates": true, "promotions": true }` by default. `order_updates` controls push notifications about the customer's orders (the inbox copy is always kept); `promotions` controls promotional notifications and campaigns entirely. +url: "{{base_url}}/{{api_prefix}}/{{namespace}}/notifications/preferences" +method: GET +headers: + - key: Customer-Token + value: "{{customer_token}}" +order: 7000 diff --git a/postman/collections/Fleetbase Storefront API/Notifications/List Notifications.queryParams.yaml b/postman/collections/Fleetbase Storefront API/Notifications/List Notifications.queryParams.yaml new file mode 100644 index 0000000..13e3608 --- /dev/null +++ b/postman/collections/Fleetbase Storefront API/Notifications/List Notifications.queryParams.yaml @@ -0,0 +1,14 @@ +$kind: params +fields: + - name: unread + type: boolean + description: "Only return notifications that have not been read." + - name: type + type: string + description: "Only return notifications of this type, e.g. `order_completed` or `promotional`." + - name: limit + type: integer + description: "Maximum number of notifications to return. Defaults to 25, maximum 100." + - name: offset + type: integer + description: "Number of notifications to skip." diff --git a/postman/collections/Fleetbase Storefront API/Notifications/List Notifications.request.yaml b/postman/collections/Fleetbase Storefront API/Notifications/List Notifications.request.yaml new file mode 100644 index 0000000..7e109da --- /dev/null +++ b/postman/collections/Fleetbase Storefront API/Notifications/List Notifications.request.yaml @@ -0,0 +1,28 @@ +$kind: http-request +description: |- + Lists the authenticated customer's notifications for the current storefront, newest first. Filter with `unread` and `type`, and page with `limit` (default 25, maximum 100) and `offset`. +url: "{{base_url}}/{{api_prefix}}/{{namespace}}/notifications" +method: GET +headers: + - key: Customer-Token + value: "{{customer_token}}" +queryParams: + unread: "false" +scripts: + - type: afterResponse + code: |- + // Retrieve, Mark as Read and Delete address {{notification_id}}. + var json_response = pm.response.json(); + var items = Array.isArray(json_response) ? json_response : (json_response && json_response.data) || []; + + pm.test('List Notifications returns an array', function () { + pm.expect(items).to.be.an('array'); + }); + + if (items.length) { + pm.environment.set('notification_id', items[0].id); + } else { + pm.environment.unset('notification_id'); + } + language: text/javascript +order: 1000 diff --git a/postman/collections/Fleetbase Storefront API/Notifications/Mark All Notifications as Read.request.yaml b/postman/collections/Fleetbase Storefront API/Notifications/Mark All Notifications as Read.request.yaml new file mode 100644 index 0000000..61fa304 --- /dev/null +++ b/postman/collections/Fleetbase Storefront API/Notifications/Mark All Notifications as Read.request.yaml @@ -0,0 +1,9 @@ +$kind: http-request +description: |- + Marks every unread notification of the authenticated customer in the current storefront as read. Returns `{ "status": "OK", "updated": n }`. +url: "{{base_url}}/{{api_prefix}}/{{namespace}}/notifications/read-all" +method: PUT +headers: + - key: Customer-Token + value: "{{customer_token}}" +order: 5000 diff --git a/postman/collections/Fleetbase Storefront API/Notifications/Mark a Notification as Read.request.yaml b/postman/collections/Fleetbase Storefront API/Notifications/Mark a Notification as Read.request.yaml new file mode 100644 index 0000000..6cf291e --- /dev/null +++ b/postman/collections/Fleetbase Storefront API/Notifications/Mark a Notification as Read.request.yaml @@ -0,0 +1,19 @@ +$kind: http-request +description: |- + Marks one notification as read and returns it. Marking an already read notification keeps its original `read_at`. +url: "{{base_url}}/{{api_prefix}}/{{namespace}}/notifications/{{notification_id}}/read" +method: PUT +headers: + - key: Customer-Token + value: "{{customer_token}}" +scripts: + - type: beforeRequest + code: |- + // Addresses the first notification returned by List Notifications. A fresh + // stack has none, so without one this documents the not-found contract. + if (!pm.environment.get('notification_id')) { + pm.variables.set('notification_id', 'missing-notification'); + pm.variables.set('expected_status', 404); + } + language: text/javascript +order: 4000 diff --git a/postman/collections/Fleetbase Storefront API/Notifications/Retrieve a Notification.request.yaml b/postman/collections/Fleetbase Storefront API/Notifications/Retrieve a Notification.request.yaml new file mode 100644 index 0000000..2bf6415 --- /dev/null +++ b/postman/collections/Fleetbase Storefront API/Notifications/Retrieve a Notification.request.yaml @@ -0,0 +1,19 @@ +$kind: http-request +description: |- + Retrieves one of the authenticated customer's notifications. Returns `404` for a notification that does not exist or belongs to another customer or storefront. +url: "{{base_url}}/{{api_prefix}}/{{namespace}}/notifications/{{notification_id}}" +method: GET +headers: + - key: Customer-Token + value: "{{customer_token}}" +scripts: + - type: beforeRequest + code: |- + // Addresses the first notification returned by List Notifications. A fresh + // stack has none, so without one this documents the not-found contract. + if (!pm.environment.get('notification_id')) { + pm.variables.set('notification_id', 'missing-notification'); + pm.variables.set('expected_status', 404); + } + language: text/javascript +order: 3000 diff --git a/postman/collections/Fleetbase Storefront API/Notifications/Update Notification Preferences.params.yaml b/postman/collections/Fleetbase Storefront API/Notifications/Update Notification Preferences.params.yaml new file mode 100644 index 0000000..0da187a --- /dev/null +++ b/postman/collections/Fleetbase Storefront API/Notifications/Update Notification Preferences.params.yaml @@ -0,0 +1,8 @@ +$kind: params +fields: + - name: order_updates + type: boolean + description: "Receive push notifications about order status changes." + - name: promotions + type: boolean + description: "Receive promotional notifications and campaigns (push and inbox)." diff --git a/postman/collections/Fleetbase Storefront API/Notifications/Update Notification Preferences.request.yaml b/postman/collections/Fleetbase Storefront API/Notifications/Update Notification Preferences.request.yaml new file mode 100644 index 0000000..05da83b --- /dev/null +++ b/postman/collections/Fleetbase Storefront API/Notifications/Update Notification Preferences.request.yaml @@ -0,0 +1,18 @@ +$kind: http-request +description: |- + Updates the authenticated customer's notification preferences. Only the keys sent are changed; unknown keys are ignored. Returns the full preferences, or `400` when a value is not a boolean. +url: "{{base_url}}/{{api_prefix}}/{{namespace}}/notifications/preferences" +method: PUT +headers: + - key: Customer-Token + value: "{{customer_token}}" + - key: Content-Type + value: application/json +body: + type: json + content: |- + { + "order_updates": true, + "promotions": true + } +order: 8000 diff --git a/postman/collections/Fleetbase Storefront API/Orders/.resources/object.yaml b/postman/collections/Fleetbase Storefront API/Orders/.resources/object.yaml index b799cd8..be3f4ab 100644 --- a/postman/collections/Fleetbase Storefront API/Orders/.resources/object.yaml +++ b/postman/collections/Fleetbase Storefront API/Orders/.resources/object.yaml @@ -14,6 +14,10 @@ example: | "checkout_id": "checkout_123", "storefront": "Acme Market", "total": 5150, + "discount": 500, + "promotions": [ + { "promotion": "promotion_7Hq2xL9", "name": "Welcome $5 off", "type": "fixed_amount", "code": "WELCOME5", "amount": 500, "delivery_amount": 0 } + ], "currency": "USD" }, "notes": null, @@ -41,7 +45,7 @@ fields: description: "Customer associated with the order." - name: meta type: object - description: "Storefront checkout, payment, totals, and fulfillment metadata." + description: "Storefront checkout, payment, totals, and fulfillment metadata. `discount` is the total promotion discount (minor units) and `promotions` lists the applied promotions with their amounts; multi-store child orders carry their store's share of the item discount." - name: notes type: string description: "Order notes supplied during checkout capture." diff --git a/postman/collections/Fleetbase Storefront API/Promotions/.resources/definition.yaml b/postman/collections/Fleetbase Storefront API/Promotions/.resources/definition.yaml new file mode 100644 index 0000000..cbfada5 --- /dev/null +++ b/postman/collections/Fleetbase Storefront API/Promotions/.resources/definition.yaml @@ -0,0 +1,4 @@ +$kind: collection +description: |- + Promotions are discounts a store or network offers at checkout: percentage or amount off, free delivery, or buy X get Y. They apply automatically or with a promo code. These endpoints list the storefront's live, public promotions ("deals") for the app. Codes are applied to carts with the Cart endpoints, and discounts are priced into the checkout amount. +order: 5700 diff --git a/postman/collections/Fleetbase Storefront API/Promotions/.resources/object.yaml b/postman/collections/Fleetbase Storefront API/Promotions/.resources/object.yaml new file mode 100644 index 0000000..9e090fe --- /dev/null +++ b/postman/collections/Fleetbase Storefront API/Promotions/.resources/object.yaml @@ -0,0 +1,102 @@ +$kind: object +name: Promotion +description: |- + A live, public promotion of the store (or, with a network key, of the network or one of its member stores). Money values are integers in the currency's minor unit, like cart subtotals. Promo codes are never included. +example: | + { + "id": "promotion_7Hq2xL9", + "name": "Weekday lunch 20% off", + "description": "20% off mains, weekdays 11:00-14:00.", + "trigger": "automatic", + "type": "percentage", + "value": 20, + "max_discount_amount": 1000, + "currency": "USD", + "min_subtotal": 1500, + "min_items": null, + "applies_to": { "categories": ["category_uuid"] }, + "bogo_config": null, + "first_order_only": false, + "usage_limit_per_customer": 1, + "stackable": false, + "starts_at": "2026-10-01T00:00:00Z", + "ends_at": "2026-12-31T23:59:59Z", + "schedule": [{ "days": [1, 2, 3, 4, 5], "start": "11:00", "end": "14:00" }], + "timezone": "America/New_York", + "image_url": "https://files.example.com/lunch.png", + "translations": null, + "created_at": "2026-09-26T09:30:00Z", + "updated_at": "2026-09-26T09:30:00Z" + } +fields: + - name: id + type: string + description: "Public identifier of the promotion." + - name: name + type: string + description: "Promotion name, also shown on applied discounts." + - name: description + type: string + description: "Optional details for customers." + - name: trigger + type: enum + values: ["automatic", "code"] + description: "`automatic` promotions apply to every eligible cart; `code` promotions need a promo code." + - name: type + type: enum + values: ["percentage", "fixed_amount", "free_delivery", "bogo"] + description: "How the discount is calculated." + - name: value + type: number + description: "Percent off for `percentage`, amount off (minor units) for `fixed_amount`." + - name: max_discount_amount + type: integer + description: "Maximum discount per order, in minor units." + - name: currency + type: string + description: "Currency of `fixed_amount` promotions." + - name: min_subtotal + type: integer + description: "Minimum spend on the targeted items, in minor units." + - name: min_items + type: integer + description: "Minimum number of targeted items." + - name: applies_to + type: object + description: "Targeting: `products`, `categories`, `stores`, `exclude_products` and `exclude_categories` identifier lists. Empty means the whole cart (of the owning store, for store promotions)." + - name: bogo_config + type: object + description: "For `bogo`: `buy_quantity`, `get_quantity` and `discount_percent` (100 means free). The cheapest units of each group are discounted." + - name: first_order_only + type: boolean + description: "Only customers who have never placed a storefront order can use it." + - name: usage_limit_per_customer + type: integer + description: "How many times one customer can use it." + - name: stackable + type: boolean + description: "Whether it combines with other stackable promotions." + - name: starts_at + type: timestamp + description: "When the promotion starts." + - name: ends_at + type: timestamp + description: "When the promotion ends." + - name: schedule + type: array of objects + description: "Optional weekly windows (`days` as ISO weekdays, `start`/`end` as HH:MM) in `timezone` when it applies." + - name: timezone + type: string + description: "Timezone of the schedule windows." + - name: image_url + type: string + description: "Promotion image." + - name: translations + type: object + description: "Translated content." + - name: created_at + type: timestamp + description: "Time the promotion was created." + - name: updated_at + type: timestamp + description: "Time the promotion was last updated." diff --git a/postman/collections/Fleetbase Storefront API/Promotions/Query Promotions.queryParams.yaml b/postman/collections/Fleetbase Storefront API/Promotions/Query Promotions.queryParams.yaml new file mode 100644 index 0000000..b5b6240 --- /dev/null +++ b/postman/collections/Fleetbase Storefront API/Promotions/Query Promotions.queryParams.yaml @@ -0,0 +1,5 @@ +$kind: params +fields: + - name: store + type: string + description: "Network member store public ID, to only list that store's promotions. Ignored for store keys." diff --git a/postman/collections/Fleetbase Storefront API/Promotions/Query Promotions.request.yaml b/postman/collections/Fleetbase Storefront API/Promotions/Query Promotions.request.yaml new file mode 100644 index 0000000..5d95207 --- /dev/null +++ b/postman/collections/Fleetbase Storefront API/Promotions/Query Promotions.request.yaml @@ -0,0 +1,25 @@ +$kind: http-request +description: |- + Lists the storefront's live, public promotions: active, inside their date range and weekly schedule. With a network key the network's promotions and those of its member stores are returned; pass `store` to only list one member store's. +url: "{{base_url}}/{{api_prefix}}/{{namespace}}/promotions" +method: GET +queryParams: + store: "" +scripts: + - type: afterResponse + code: |- + // Retrieve a Promotion addresses {{promotion_id}}. + var json_response = pm.response.json(); + var items = Array.isArray(json_response) ? json_response : (json_response && json_response.data) || []; + + pm.test('Query Promotions returns an array', function () { + pm.expect(items).to.be.an('array'); + }); + + if (items.length) { + pm.environment.set('promotion_id', items[0].id); + } else { + pm.environment.unset('promotion_id'); + } + language: text/javascript +order: 1000 diff --git a/postman/collections/Fleetbase Storefront API/Promotions/Retrieve a Promotion.request.yaml b/postman/collections/Fleetbase Storefront API/Promotions/Retrieve a Promotion.request.yaml new file mode 100644 index 0000000..c950312 --- /dev/null +++ b/postman/collections/Fleetbase Storefront API/Promotions/Retrieve a Promotion.request.yaml @@ -0,0 +1,16 @@ +$kind: http-request +description: |- + Retrieves one live, public promotion of the storefront. Returns `404` for promotions that are not active, not public, outside their schedule, or owned by another storefront. +url: "{{base_url}}/{{api_prefix}}/{{namespace}}/promotions/{{promotion_id}}" +method: GET +scripts: + - type: beforeRequest + code: |- + // Addresses the first promotion returned by Query Promotions. A stack without + // promotions documents the not-found contract instead. + if (!pm.environment.get('promotion_id')) { + pm.variables.set('promotion_id', 'promotion_missing'); + pm.variables.set('expected_status', 404); + } + language: text/javascript +order: 2000