From 2657f9c19640a7c5973697082bf6c8c8dbe3b913 Mon Sep 17 00:00:00 2001 From: Shahed Nasser Date: Mon, 15 Sep 2025 12:29:55 +0300 Subject: [PATCH] docs: add manage promotions in cart storefront guide (#13483) * docs: add manage promotions in cart storefront guide * fix incorrect cURL example --- .../store_carts_{id}_promotions/delete.sh | 6 +- .../specs/store/openapi.full.yaml | 12 +- .../paths/store_carts_{id}_promotions.yaml | 8 ++ www/apps/book/public/llms-full.txt | 10 +- .../cart/manage-promotions/page.mdx | 117 ++++++++++++++++++ www/apps/resources/generated/edit-dates.mjs | 1 + www/apps/resources/generated/files-map.mjs | 4 + .../generated-commerce-modules-sidebar.mjs | 28 +++++ ...nerated-storefront-development-sidebar.mjs | 8 ++ www/apps/resources/sidebars/storefront.mjs | 5 + www/packages/tags/src/tags/cart.ts | 4 + www/packages/tags/src/tags/promotion.ts | 4 + www/packages/tags/src/tags/storefront.ts | 4 + .../delete_store_carts_[id]_promotions.ts | 9 +- .../store/post_store_carts_[id]_promotions.ts | 3 + 15 files changed, 215 insertions(+), 8 deletions(-) create mode 100644 www/apps/resources/app/storefront-development/cart/manage-promotions/page.mdx diff --git a/www/apps/api-reference/specs/store/code_samples/Shell/store_carts_{id}_promotions/delete.sh b/www/apps/api-reference/specs/store/code_samples/Shell/store_carts_{id}_promotions/delete.sh index f9a9e22c36..c2105714a6 100644 --- a/www/apps/api-reference/specs/store/code_samples/Shell/store_carts_{id}_promotions/delete.sh +++ b/www/apps/api-reference/specs/store/code_samples/Shell/store_carts_{id}_promotions/delete.sh @@ -1,2 +1,6 @@ curl -X DELETE '{backend_url}/store/carts/{id}/promotions' \ --H 'x-publishable-api-key: {your_publishable_api_key}' \ No newline at end of file +-H 'x-publishable-api-key: {your_publishable_api_key}' \ +-H 'Content-Type: application/json' \ +--data-raw '{ + "promo_codes": ["{value}"] +}' \ No newline at end of file diff --git a/www/apps/api-reference/specs/store/openapi.full.yaml b/www/apps/api-reference/specs/store/openapi.full.yaml index f6131bafc3..44aa62e70f 100644 --- a/www/apps/api-reference/specs/store/openapi.full.yaml +++ b/www/apps/api-reference/specs/store/openapi.full.yaml @@ -1863,6 +1863,9 @@ paths: x-sidebar-summary: Add Promotions description: Add a list of promotions to a cart. x-authenticated: false + externalDocs: + url: https://docs.medusajs.com/v2/resources/storefront-development/cart/manage-promotions#add-promotion-to-cart + description: 'Storefront guide: How to add a promotion to cart.' parameters: - name: id in: path @@ -1933,6 +1936,9 @@ paths: summary: Remove Promotions from Cart description: Remove a list of promotions from a cart. x-authenticated: false + externalDocs: + url: https://docs.medusajs.com/v2/resources/storefront-development/cart/manage-promotions#remove-promotion-from-cart + description: 'Storefront guide: How to remove a promotion from cart.' parameters: - name: id in: path @@ -1963,7 +1969,11 @@ paths: label: cURL source: |- curl -X DELETE '{backend_url}/store/carts/{id}/promotions' \ - -H 'x-publishable-api-key: {your_publishable_api_key}' + -H 'x-publishable-api-key: {your_publishable_api_key}' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "promo_codes": ["{value}"] + }' tags: - Carts responses: diff --git a/www/apps/api-reference/specs/store/paths/store_carts_{id}_promotions.yaml b/www/apps/api-reference/specs/store/paths/store_carts_{id}_promotions.yaml index 450c4662ec..5c80da8da4 100644 --- a/www/apps/api-reference/specs/store/paths/store_carts_{id}_promotions.yaml +++ b/www/apps/api-reference/specs/store/paths/store_carts_{id}_promotions.yaml @@ -4,6 +4,10 @@ post: x-sidebar-summary: Add Promotions description: Add a list of promotions to a cart. x-authenticated: false + externalDocs: + url: >- + https://docs.medusajs.com/v2/resources/storefront-development/cart/manage-promotions#add-promotion-to-cart + description: 'Storefront guide: How to add a promotion to cart.' parameters: - name: id in: path @@ -75,6 +79,10 @@ delete: summary: Remove Promotions from Cart description: Remove a list of promotions from a cart. x-authenticated: false + externalDocs: + url: >- + https://docs.medusajs.com/v2/resources/storefront-development/cart/manage-promotions#remove-promotion-from-cart + description: 'Storefront guide: How to remove a promotion from cart.' parameters: - name: id in: path diff --git a/www/apps/book/public/llms-full.txt b/www/apps/book/public/llms-full.txt index ec6b7b23ff..034228c55d 100644 --- a/www/apps/book/public/llms-full.txt +++ b/www/apps/book/public/llms-full.txt @@ -74126,9 +74126,9 @@ const StripeSavedPaymentMethodsContainer = ({ SavedPaymentMethod[] >([]) const [selectedPaymentMethod, setSelectedPaymentMethod] = useState< - string | undefined + string | null >( - paymentSession?.data?.payment_method_id as string | undefined + paymentSession?.data?.payment_method as string | null ) useEffect(() => { @@ -74274,7 +74274,7 @@ Then, add a new state variable that keeps track of whether the customer is using ```ts title="src/modules/checkout/components/payment-container/index.tsx" badgeLabel="Storefront" badgeColor="blue" const [isUsingSavedPaymentMethod, setIsUsingSavedPaymentMethod] = useState( - paymentSession?.data?.payment_method_id !== undefined + paymentSession?.data?.payment_method !== null ) ``` @@ -74411,7 +74411,7 @@ So, you need to update the `confirmCardPayment` usage to support passing the ID In `src/modules/checkout/components/payment-button/index.tsx`, find the `handlePayment` method and update its first `if` condition: ```ts title="src/modules/checkout/components/payment-button/index.tsx" badgeLabel="Storefront" badgeColor="blue" -if (!stripe || !elements || (!card && !session?.data.payment_method_id) || !cart) { +if (!stripe || !elements || (!card && !session?.data.payment_method) || !cart) { setSubmitting(false) return } @@ -74424,7 +74424,7 @@ Then, find the usage of `confirmCardPayment` in the `handlePayment` function and ```ts title="src/modules/checkout/components/payment-button/index.tsx" badgeLabel="Storefront" badgeColor="blue" highlights={confirmPaymentHighlights} await stripe .confirmCardPayment(session?.data.client_secret as string, { - payment_method: session?.data.payment_method_id as string || { + payment_method: session?.data.payment_method as string || { card: card!, billing_details: { name: diff --git a/www/apps/resources/app/storefront-development/cart/manage-promotions/page.mdx b/www/apps/resources/app/storefront-development/cart/manage-promotions/page.mdx new file mode 100644 index 0000000000..757496303d --- /dev/null +++ b/www/apps/resources/app/storefront-development/cart/manage-promotions/page.mdx @@ -0,0 +1,117 @@ +--- +tags: + - cart + - promotion + - storefront +products: + - cart + - promotion +--- + +import { CodeTabs, CodeTab } from "docs-ui" + +export const metadata = { + title: `Manage Cart Promotions in Storefront`, +} + +# {metadata.title} + +In this guide, you'll learn how to manage cart promotions or discounts, including adding, listing, and removing them. + +## Add Promotion to Cart + +To add a promotion to a cart, use the [Add Promotion API route](!api!/store#carts_postcartsidpromotions). + +For example: + +```ts +fetch(`http://localhost:9000/store/carts/${cart.id}/promotions`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + "x-publishable-api-key": + process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY || "temp", + }, + body: JSON.stringify({ + promo_codes: [promoCode], + }), +}) +.then((res) => res.json()) +.then(({ cart }) => { + // use cart... + console.log(cart) +}) +``` + +The [Add Promotion API route](!api!/store#carts_postcartsidpromotions) accepts the cart ID as a path parameter, and a `promo_codes` request body parameter, which is an array of promotion codes to apply to the cart. + +The response includes the updated cart with the applied promotions. You can use this cart object to show the updated promotions to the customer. + +--- + +## List Cart Promotions + +The cart object you retrieve in the storefront has a `promotions` field, which is an array of the promotions applied to the cart. + +You can refer to the [API reference](!api!/store#carts_cart_schema) for the expected fields in a promotion object. + +A promotion mainly has a `code` field. You can use that code to display the applied promotions to the customer, and later to [remove a promotion](#remove-promotion-from-cart) from the cart. + +For example, if you have a cart object retrieved from Medusa's Store APIs, you can list its promotions as follows: + +```tsx +
+ {cart?.promotions?.length ? ( + + ) : ( +

No promotions applied

+ )} +
+``` + +In the above example, you show the list of applied promotions, and for each promotion, you provide a button to [remove it from the cart](#remove-promotion-from-cart). + + + +To show the total discount amount from the applied promotions, refer to the [Cart Totals guide](../totals/page.mdx). + + + +--- + +## Remove Promotion from Cart + +To remove a promotion from a cart, use the [Remove Promotion API route](!api!/store#carts_deletecartsidpromotions). + +For example: + +```ts +fetch(`http://localhost:9000/store/carts/${cart.id}/promotions`, { + credentials: "include", + method: "DELETE", + headers: { + "Content-Type": "application/json", + "x-publishable-api-key": + process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY || "temp", + }, + body: JSON.stringify({ + promo_codes: [code], + }), +}) +.then((res) => res.json()) +.then(({ cart }) => { + // use cart... + console.log(cart) +}) +``` + +The [Remove Promotion API route](!api!/store#carts_deletecartsidpromotions) accepts the cart ID as a path parameter, and a `promo_codes` request body parameter, which is an array of promotion codes to remove from the cart. + +The response includes the updated cart with the removed promotions. You can use this cart object to show the updated promotions to the customer. diff --git a/www/apps/resources/generated/edit-dates.mjs b/www/apps/resources/generated/edit-dates.mjs index 4e5b4c9c5d..96d172dad8 100644 --- a/www/apps/resources/generated/edit-dates.mjs +++ b/www/apps/resources/generated/edit-dates.mjs @@ -6573,6 +6573,7 @@ export const generatedEditDates = { "app/troubleshooting/scheduled-job-not-running/page.mdx": "2025-08-29T11:32:54.117Z", "app/troubleshooting/pnpm/page.mdx": "2025-08-29T12:21:24.692Z", "app/how-to-tutorials/tutorials/product-feed/page.mdx": "2025-09-01T13:19:59.335Z", + "app/storefront-development/cart/manage-promotions/page.mdx": "2025-09-11T14:11:40.904Z", "app/recipes/ticket-booking/examples/page.mdx": "2025-09-10T14:11:55.063Z", "app/recipes/ticket-booking/examples/storefront/page.mdx": "2025-09-10T14:14:44.005Z", "app/recipes/ticket-booking/example/page.mdx": "2025-09-10T15:13:15.604Z", diff --git a/www/apps/resources/generated/files-map.mjs b/www/apps/resources/generated/files-map.mjs index 7b8d9d5b6d..e5f3d0e207 100644 --- a/www/apps/resources/generated/files-map.mjs +++ b/www/apps/resources/generated/files-map.mjs @@ -1183,6 +1183,10 @@ export const filesMap = [ "filePath": "/www/apps/resources/app/storefront-development/cart/manage-items/page.mdx", "pathname": "/storefront-development/cart/manage-items" }, + { + "filePath": "/www/apps/resources/app/storefront-development/cart/manage-promotions/page.mdx", + "pathname": "/storefront-development/cart/manage-promotions" + }, { "filePath": "/www/apps/resources/app/storefront-development/cart/retrieve/page.mdx", "pathname": "/storefront-development/cart/retrieve" diff --git a/www/apps/resources/generated/generated-commerce-modules-sidebar.mjs b/www/apps/resources/generated/generated-commerce-modules-sidebar.mjs index 43718889e2..4de36a5a89 100644 --- a/www/apps/resources/generated/generated-commerce-modules-sidebar.mjs +++ b/www/apps/resources/generated/generated-commerce-modules-sidebar.mjs @@ -1227,6 +1227,14 @@ const generatedgeneratedCommerceModulesSidebarSidebar = { "path": "https://docs.medusajs.com/resources/storefront-development/guides/express-checkout", "children": [] }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Manage Cart Promotions in Storefront", + "path": "https://docs.medusajs.com/resources/storefront-development/cart/manage-promotions", + "children": [] + }, { "loaded": true, "isPathHref": true, @@ -13508,6 +13516,26 @@ const generatedgeneratedCommerceModulesSidebarSidebar = { } ] }, + { + "loaded": true, + "isPathHref": true, + "type": "category", + "title": "Storefront Guides", + "autogenerate_tags": "storefront+promotion,-jsSdk", + "autogenerate_as_ref": true, + "sort_sidebar": "alphabetize", + "description": "Learn how to integrate the Promotion Module's features into your storefront.", + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Manage Cart Promotions in Storefront", + "path": "https://docs.medusajs.com/resources/storefront-development/cart/manage-promotions", + "children": [] + } + ] + }, { "loaded": true, "isPathHref": true, diff --git a/www/apps/resources/generated/generated-storefront-development-sidebar.mjs b/www/apps/resources/generated/generated-storefront-development-sidebar.mjs index f0652a9570..16f0738dbf 100644 --- a/www/apps/resources/generated/generated-storefront-development-sidebar.mjs +++ b/www/apps/resources/generated/generated-storefront-development-sidebar.mjs @@ -294,6 +294,14 @@ const generatedgeneratedStorefrontDevelopmentSidebarSidebar = { "title": "Manage Line Items", "children": [] }, + { + "loaded": true, + "isPathHref": true, + "type": "link", + "path": "/storefront-development/cart/manage-promotions", + "title": "Manage Promotions", + "children": [] + }, { "loaded": true, "isPathHref": true, diff --git a/www/apps/resources/sidebars/storefront.mjs b/www/apps/resources/sidebars/storefront.mjs index aa2c2c800d..b223864de4 100644 --- a/www/apps/resources/sidebars/storefront.mjs +++ b/www/apps/resources/sidebars/storefront.mjs @@ -179,6 +179,11 @@ export const storefrontDevelopmentSidebar = [ path: "/storefront-development/cart/manage-items", title: "Manage Line Items", }, + { + type: "link", + path: "/storefront-development/cart/manage-promotions", + title: "Manage Promotions", + }, { type: "link", path: "/storefront-development/cart/totals", diff --git a/www/packages/tags/src/tags/cart.ts b/www/packages/tags/src/tags/cart.ts index e1003fe607..b834a2cba2 100644 --- a/www/packages/tags/src/tags/cart.ts +++ b/www/packages/tags/src/tags/cart.ts @@ -47,6 +47,10 @@ export const cart = [ "title": "Manage Cart's Items in Storefront", "path": "https://docs.medusajs.com/resources/storefront-development/cart/manage-items" }, + { + "title": "Manage Cart Promotions in Storefront", + "path": "https://docs.medusajs.com/resources/storefront-development/cart/manage-promotions" + }, { "title": "Retrieve Cart in Storefront", "path": "https://docs.medusajs.com/resources/storefront-development/cart/retrieve" diff --git a/www/packages/tags/src/tags/promotion.ts b/www/packages/tags/src/tags/promotion.ts index d3ec32f5dc..1c18034d2a 100644 --- a/www/packages/tags/src/tags/promotion.ts +++ b/www/packages/tags/src/tags/promotion.ts @@ -27,6 +27,10 @@ export const promotion = [ "title": "Implement Loyalty Points", "path": "https://docs.medusajs.com/resources/how-to-tutorials/tutorials/loyalty-points" }, + { + "title": "Manage Cart Promotions in Storefront", + "path": "https://docs.medusajs.com/resources/storefront-development/cart/manage-promotions" + }, { "title": "getActionsToComputeFromPromotionsStep", "path": "https://docs.medusajs.com/resources/references/medusa-workflows/steps/getActionsToComputeFromPromotionsStep" diff --git a/www/packages/tags/src/tags/storefront.ts b/www/packages/tags/src/tags/storefront.ts index 3ab6c34609..7429c181c4 100644 --- a/www/packages/tags/src/tags/storefront.ts +++ b/www/packages/tags/src/tags/storefront.ts @@ -15,6 +15,10 @@ export const storefront = [ "title": "Manage Cart's Items in Storefront", "path": "https://docs.medusajs.com/resources/storefront-development/cart/manage-items" }, + { + "title": "Manage Cart Promotions in Storefront", + "path": "https://docs.medusajs.com/resources/storefront-development/cart/manage-promotions" + }, { "title": "Retrieve Cart in Storefront", "path": "https://docs.medusajs.com/resources/storefront-development/cart/retrieve" diff --git a/www/utils/generated/oas-output/operations/store/delete_store_carts_[id]_promotions.ts b/www/utils/generated/oas-output/operations/store/delete_store_carts_[id]_promotions.ts index a903890be3..d0cb841ef3 100644 --- a/www/utils/generated/oas-output/operations/store/delete_store_carts_[id]_promotions.ts +++ b/www/utils/generated/oas-output/operations/store/delete_store_carts_[id]_promotions.ts @@ -4,6 +4,9 @@ * summary: Remove Promotions from Cart * description: Remove a list of promotions from a cart. * x-authenticated: false + * externalDocs: + * url: https://docs.medusajs.com/v2/resources/storefront-development/cart/manage-promotions#remove-promotion-from-cart + * description: "Storefront guide: How to remove a promotion from cart." * parameters: * - name: id * in: path @@ -36,7 +39,11 @@ * label: cURL * source: |- * curl -X DELETE '{backend_url}/store/carts/{id}/promotions' \ - * -H 'x-publishable-api-key: {your_publishable_api_key}' + * -H 'x-publishable-api-key: {your_publishable_api_key}' \ + * -H 'Content-Type: application/json' \ + * --data-raw '{ + * "promo_codes": ["{value}"] + * }' * tags: * - Carts * responses: diff --git a/www/utils/generated/oas-output/operations/store/post_store_carts_[id]_promotions.ts b/www/utils/generated/oas-output/operations/store/post_store_carts_[id]_promotions.ts index f591993946..ee3c80948a 100644 --- a/www/utils/generated/oas-output/operations/store/post_store_carts_[id]_promotions.ts +++ b/www/utils/generated/oas-output/operations/store/post_store_carts_[id]_promotions.ts @@ -5,6 +5,9 @@ * x-sidebar-summary: Add Promotions * description: Add a list of promotions to a cart. * x-authenticated: false + * externalDocs: + * url: https://docs.medusajs.com/v2/resources/storefront-development/cart/manage-promotions#add-promotion-to-cart + * description: "Storefront guide: How to add a promotion to cart." * parameters: * - name: id * in: path