> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aftersell.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 在 Upcart 中设置自定义模板

> 本文概述了可用于自定义 Upcart 模板的关键 props，帮助你在保持核心功能的同时个性化购物车体验。

<div id="important-notice">
  ## ⚠️ **重要通知**
</div>

自定义模板需要 HTML、CSS、JavaScript 和 React 方面的高级技术知识。在继续之前，请确保你具备足够的开发专业知识，或能够联系合格的 Shopify 开发者。\*\*我们的支持团队不会为自定义模板的开发、调试或故障排除提供协助。\*\*技术问题请咨询 Shopify 专家或合格的开发者。

***

<div id="code-editor-features">
  ## 代码编辑器功能
</div>

自定义模板代码编辑器包含内置工具，帮助你更轻松地编写有效的模板。

<div id="typescript-intellisense">
  ### TypeScript IntelliSense
</div>

编辑器支持 TypeScript，因此在你输入时可以获得所有可用 `props` 的自动补全建议、类型检查和内联文档。prop 类型提示只是编辑器内的 IntelliSense，用于帮助你编写模板——它们不是需要写入模板的内容，也永远不会在你的店面上运行。

<div id="editable-template-body">
  ### 可编辑的模板主体
</div>

编辑器只暴露模板的可编辑 JSX 主体——没有锁定的行。外围的函数包装器会在构建时自动添加，且永远不会显示在编辑器中。

如果你的编辑破坏了模板结构，可随时使用 **Reset to default** 恢复原始模板。

***

<div id="general-section">
  ## General 区域
</div>

<div id="header">
  ## Header
</div>

Header 模块允许你使用自己的设计自定义购物车页眉，同时保持基本的购物车功能，例如显示商品数量和提供关闭按钮。

<div id="available-props-full-template">
  ### **可用 Props - Full template**
</div>

<img src="https://mintcdn.com/aftersell/uxKAdY-e0h16xa48/images/upcart/custom-template-cart-drawer-header-title.png?fit=max&auto=format&n=uxKAdY-e0h16xa48&q=85&s=7c679bee70bf5ff8a61657d83158e986" alt="Cart drawer 页眉，显示 Cart 标题、商品数量和关闭按钮" width="400" data-path="images/upcart/custom-template-cart-drawer-header-title.png" />

`cartQuantity`

* **类型**：`string`

* **描述**：购物车中当前的商品数量，格式化为字符串

* **用法**：在你的自定义页眉设计中显示购物车商品数量

```
<h2>Shopping Cart ({props.cartQuantity})</h2>
```

`closeHandler`

* **类型**：`() => void`

* **描述**：触发时关闭购物车的回调函数

* **用法**：绑定到按钮、图标或其他交互元素上以关闭购物车

```
<button  
  onClick={props.closeHandler}  
  aria-label="Close cart"  
>×</button>
```

`titleComponent`

* **类型**：`React.ReactElement | null`

* **描述**：预渲染的购物车页眉标题组件，包含正确的样式和翻译

* **用法**：根据你的购物车设置配置显示购物车标题

```
<div>{props.titleComponent}</div>
```

***

<div id="body-section">
  ## Body 区域
</div>

<div id="announcements">
  ## Announcements
</div>

Announcements 模块允许你使用自己的设计自定义公告显示，同时保持基本的公告功能，例如计时器控制和条件可见性。

<div id="available-props-full-template-2">
  ### 可用 Props - **Full template**
</div>

<img src="https://mintcdn.com/aftersell/uxKAdY-e0h16xa48/images/upcart/custom-template-cart-announcement-bar-countdown.png?fit=max&auto=format&n=uxKAdY-e0h16xa48&q=85&s=2c7d03e71ebf5bec3b5d3bddff3447b3" alt="购物车公告栏，带有为客户保留商品的倒计时器" width="400" data-path="images/upcart/custom-template-cart-announcement-bar-countdown.png" />

`announcementTemplate`

* **类型**：`string`

* **描述**：公告消息的 HTML 内容

* **用法**：在你的自定义实现中显示公告消息

```
<div dangerouslySetInnerHTML={{ __html: props.announcementTemplate }} />
```

`timer`

* **类型**：`string`

* **描述**：当前计时器值，格式化为字符串

* **用法**：在自定义公告实现中显示倒计时器

```
<div>Time remaining: {props.timer}</div>
```

`shouldUseTimer`

* **类型**：`boolean`

* **描述**：指示此公告是否启用了计时器功能

* **用法**：有条件地渲染与计时器相关的内容和控件

```
<div>  
  {props.shouldUseTimer && (  
    <span>{props.timer}</span>   
  )}  
</div>
```

`isTimerExpiredAndShouldHide`

* **类型**：`boolean`

* **描述**：指示计时器是否已过期且公告应被隐藏

* **用法**：根据计时器状态控制整个公告的可见性

```
<div>  
  {!props.isTimerExpiredAndShouldHide && (  
    <div>{props.timer}</div>  
  )}  
</div>
```

<div id="tiered-rewards">
  ## Tiered Rewards
</div>

Rewards 模块允许你使用自己的设计自定义奖励进度显示，同时保持基本的奖励功能，例如里程碑跟踪、进度可视化和奖励消息。

<div id="available-props-full-template-3">
  ### 可用 Props - **Full template**
</div>

<img src="https://mintcdn.com/aftersell/uxKAdY-e0h16xa48/images/upcart/custom-template-tiered-rewards-progress-bar.png?fit=max&auto=format&n=uxKAdY-e0h16xa48&q=85&s=78f30082b982815d333f8de09225d884" alt="分级奖励进度条，带有免运费和商品里程碑图标" width="400" data-path="images/upcart/custom-template-tiered-rewards-progress-bar.png" />

`rewardsMessageHtml`

* **类型**：`string`

* **描述**：奖励消息的 HTML 内容

* **用法**：在自定义实现中以富文本格式显示奖励消息

```
<div dangerouslySetInnerHTML={{ __html: props.rewardsMessageHtml }} />
```

`milestonesCompleted`

* **类型**：`number`

* **描述**：已完成的里程碑数量

* **用法**：显示完成数量或计算完成百分比

```
<div>  
  {Math.round((props.milestonesCompleted / props.milestonesData.milestonesToRender.length) * 100)}% Complete  
</div>
```

`milestonesData`

* 类型：

  ```
  {  
    milestonesToRender: {  
      id: string;  
      label: string;  
      icon: React.ReactElement;  
      isCompleted: boolean;  
      positionPercent: number;  
    }[];  
    progressPercent: number;  
    showMilestones: boolean;  
    settings: {  
      iconContainerSize: string;  
      iconAlignment: string;  
      labelAlignment: string;  
      hideLabel: boolean;  
    };  
  }
  ```

* **描述**：奖励系统的完整里程碑配置和进度数据

* **用法**：访问里程碑信息、进度百分比和显示设置

* **属性**：

  * `milestonesToRender`：里程碑对象数组，包含完成状态和位置信息
  * `progressPercent`：当前进度百分比（0-100）
  * `showMilestones`：是否显示里程碑标记
  * `settings`：里程碑显示的视觉配置

<div id="discounts">
  ## Discounts
</div>

Discounts 模块支持自定义模板，你可以设计自己的显示方式，同时保留规则管理、区块可见性和奖励呈现等基本功能。为了与现有自定义模板代码向后兼容，自定义模板的内部模块类型标识符为 `TRIGGERED_REWARDS`。

<div id="available-props-full-template-4">
  ### **可用 Props - Full template**
</div>

`rules`

* **类型**：

  ```
  {  
    id: string;  
    title: string;  
    description: string;  
    conditionsMet: boolean;  
  }[]
  ```

* **描述**：当前已启用的折扣规则数组

* **用法**：显示可用奖励、其标题、描述以及每条规则的条件是否已满足

* **属性**：

  * `id`：奖励规则的唯一标识符
  * `title`：折扣规则的标题
  * `description`：奖励规则的描述
  * `conditionsMet`：购物车当前是否满足该规则的条件。使用它来构建"你已解锁 X"与"再消费 \$Y 即可解锁 X"的用户体验模式

```
<div>
  {props.rules.map((rule) => (
    <div key={rule.id}>
      <h3>{rule.title}</h3>
      <p>{rule.conditionsMet ? "Reward unlocked!" : rule.description}</p>
    </div>
  ))}
</div>
```

`showSection`

* **类型**：`boolean`

* **描述**：指示是否应显示 Discounts 区块

* **用法**：控制整个 Discounts 模块的可见性

```
<div>  
  {props.showSection && (  
    <div>  
      <h2>Available Rewards...</h2>  
    </div>  
  )}  
</div>
```

`onToggleSection`

* **类型**：`() => void`

* **描述**：切换 Discounts 区块可见性状态的回调函数

* **用法**：绑定到按钮或交互元素上，让用户显示/隐藏奖励区块

```
<button type="button" onClick={props.onToggleSection}>  
  {props.showSection ? "Hide Rewards" : "Show Available Rewards"}  
</button>
```

<div id="recommendations">
  ## Recommendations
</div>

Recommendation 模块允许你使用自己的设计自定义 upsell 商品显示，同时保持基本的电商功能，例如变体选择、加购操作和商品信息显示。

<div id="available-props-recommendation-tile-template">
  ### **可用 Props - Recommendation tile template**
</div>

<img src="https://mintcdn.com/aftersell/uxKAdY-e0h16xa48/images/upcart/custom-template-recommendation-tile-snowboard-product.png?fit=max&auto=format&n=uxKAdY-e0h16xa48&q=85&s=7db82e0496937fa8ee8eea180edb3530" alt="推荐磁贴，显示一个滑雪板商品及其价格和 Add 按钮" width="400" data-path="images/upcart/custom-template-recommendation-tile-snowboard-product.png" />

*推荐磁贴模板与 Upsells 模块中的 [upsell 磁贴模板具有相同的 prop 接口](#available-props-upsell-tile-template)。所有可用的 props、类型和用法示例都记录在下方的 Upsells 模块部分。*

<div id="cart-items">
  ## Cart Items
</div>

Cart Items 模块允许你使用自己的设计自定义购物车商品显示，同时保持基本的电商功能。此模块提供多种模板类型，每种模板都有自己特定的 props，用于购物车商品显示的不同方面。

<Note>
  \*\*在加购或购物车更新期间显示加载指示器：\*\*标准的 Cart Items 模块不提供内置的"正在添加到购物车"加载动画。如果你想在添加商品或购物车操作进行中显示加载状态，请使用 Product tile 模板并读取 `isLoading` 和 `loadingOperation` props（记录在下方），以有条件地渲染加载动画或遮罩层。自定义模板需要开发者经验——请参阅本页顶部的通知。
</Note>

<div id="available-props-product-tile-template">
  ### **可用 Props - Product tile template**
</div>

**注意：**启用 *Product Tile* 模板将覆盖此模块中的所有其他模板，包括 **Variant template**、**Properties template**、**Bundle template** 和 **Price template**。\
如果你想在这些模板中的任何一个中使用自定义代码，你***必须****关闭 Product Tile 模板。*

<img src="https://mintcdn.com/aftersell/uxKAdY-e0h16xa48/images/upcart/custom-template-cart-product-tile-variant.png?fit=max&auto=format&n=uxKAdY-e0h16xa48&q=85&s=3d2efc06b542f7c59cc86ad3fe611a0e" alt="购物车商品磁贴，带有图片、变体、促销价、数量选择器和订阅按钮" width="400" data-path="images/upcart/custom-template-cart-product-tile-variant.png" />

`title`

* **类型**：`string`

* **描述**：商品标题/名称

* **用法**：在购物车商品中显示主要商品名称

`variant`

* **类型**：`React.ReactNode`

* **描述**：预渲染的变体信息组件

* **用法**：以 React 组件形式显示变体详情

`properties`

* **类型**：`React.ReactNode`

* **描述**：预渲染的商品属性组件

* **用法**：以 React 组件形式显示商品属性和订阅信息

`bundle`

* **类型**：`React.ReactNode`

* **描述**：预渲染的套装详情组件

* **用法**：以 React 组件形式显示套装信息

`compareAtPrice`

* **类型**：`string | undefined`

* **描述**：格式化的原价（compare-at price）

* **用法**：为促销商品显示原价

`price`

* **类型**：`string`

* **描述**：格式化的当前价格

* **用法**：显示商品当前价格

`savings`

* **类型**：`string | undefined`

* **描述**：格式化的节省金额

* **用法**：显示客户节省了多少

`imageUrl`

* **类型**：`string | undefined`

* **描述**：商品图片 URL

* **用法**：显示商品图片

`productUrl`

* **类型**：`string | undefined`

* **描述**：商品页面 URL

* **用法**：链接到商品详情页

`quantity`

* **类型**：`number`

* **描述**：购物车中该商品的当前数量

* **用法**：显示和管理商品数量

`showQuantitySelector`

* **类型**：`boolean`

* **描述**：是否显示数量控件

* **用法**：有条件地显示数量选择器

`discountCodes`

* **类型**：`string[] | undefined`

* **描述**：应用于此商品的折扣码数组

* **用法**：显示商品特定的折扣

`subscription`

* **类型**：

  ```
  {  
    subscriptionUpgradeData: {  
      buttonText: string;  
      defaultSellingPlanId: number;  
    } | null;  
    sellingPlansData: {  
      sellingPlanGroups: {  
        name: string;  
        selling_plans: {  
          id: number;  
          name: string;  
        }[];  
      }[] | null;  
      activeSellingPlanId: string;  
      oneTimePurchaseText: string | null;  
    } | null;  
    upgradeSellingPlan: (item: CartItem, sellingPlanId: number) => void;  
    changeSellingPlan: (item: CartItem, value: string) => void;  
    getSellingPlanGroupText: (groupName: string, planName: string) => string;  
  }
  ```

* **描述**：完整的订阅管理对象，包含升级数据、销售方案和处理函数

* **用法**：管理订阅功能

* 该 subscription 对象包含：

  * **subscriptionUpgradeData**：升级信息（如果没有可用升级则为 null）

    * `buttonText`：升级按钮的文本
    * `defaultSellingPlanId`：用于升级的默认销售方案 ID
  * **sellingPlansData**：可用的销售方案选项（如果没有方案则为 null）

    * `sellingPlanGroups`：方案组数组，包含各自的销售方案
    * `activeSellingPlanId`：当前选中的销售方案 ID
    * `oneTimePurchaseText`：一次性购买选项的文本（如果不可用则为 null）
  * **upgradeSellingPlan**：升级到特定销售方案的函数
  * **changeSellingPlan**：更改当前销售方案的函数
  * **getSellingPlanGroupText**：格式化销售方案显示文本的工具函数

`onIncrease`

* **类型**：`() => void`

* **描述**：增加商品数量的函数

* **用法**：处理数量增加操作

`onDecrease`

* **类型**：`() => void`

* **描述**：减少商品数量的函数

* **用法**：处理数量减少操作

`onDeleteProduct`

* **类型**：`() => void`

* **描述**：从购物车中移除商品的函数

* **用法**：处理商品移除

`onQuantityChange`

* **类型**：`(quantity: string) => void`

* **描述**：处理数量直接输入的函数

* **用法**：处理手动数量更改

`handleInputChange`

* **类型**：`(e: React.ChangeEvent<HTMLInputElement>) => void`

* **描述**：数量字段的输入更改处理程序

* **用法**：处理数量输入字段的更改

`replaceItemWithVariant`

* **类型**：`(variantId: string) => Promise<{ success: boolean }>`

* **描述**：将商品替换为不同变体的函数

* **用法**：处理变体切换

`isLoading`

* **类型**：`boolean`

* **描述**：购物车操作的加载状态

* **用法**：显示加载指示器

`loadingOperation`

* **类型**：`'increase' | 'decrease' | 'inputChange' | 'remove' | 'subscription' | undefined`

* **描述**：当前正在加载的具体操作

* **用法**：显示特定操作的加载状态

`setLoadingOperation`

* **类型**：`(op: "increase" | "decrease" | "inputChange" | "remove" | "subscription" | undefined) => void`

* **描述**：设置加载操作状态的函数

* **用法**：管理不同操作的加载状态

`rawItem`

* **类型**：`CartItem`（参考[下方](#cartitem-object-properties)的 `CartItem` 类型）

* **描述**：包含所有信息的原始购物车商品数据

<div id="available-props-variant-template">
  ### **可用 Props - Variant template**
</div>

<img src="https://mintcdn.com/aftersell/uxKAdY-e0h16xa48/images/upcart/custom-template-cart-item-variant-line.png?fit=max&auto=format&n=uxKAdY-e0h16xa48&q=85&s=c1220e3bf77d9b091c82d0f0b7709034" alt="购物车商品变体行，显示所选尺寸 Medium" width="150" data-path="images/upcart/custom-template-cart-item-variant-line.png" />

`item`

* **类型**：`CartItem`（参考[下方](#cartitem-object-properties)的 `CartItem` 类型）

* **描述**：包含变体信息的原始购物车商品数据

* **用法**：从购物车商品中访问变体详情

<div id="available-props-properties-template">
  ### **可用 Props - Properties template**
</div>

<img src="https://mintcdn.com/aftersell/uxKAdY-e0h16xa48/images/upcart/custom-template-cart-item-property-line.png?fit=max&auto=format&n=uxKAdY-e0h16xa48&q=85&s=2ce7abe36cf542d62e9fc7e2092e7009" alt="购物车商品属性行，显示礼品留言备注" width="220" data-path="images/upcart/custom-template-cart-item-property-line.png" />

`productProperties`

* **类型**：`{ key: string; value: string; isUrl?: boolean; }[]`

* **描述**：商品属性数组（自定义字段、订单项属性）

`subscriptionLabel`

* **类型**：`string | undefined`

* **描述**：订阅信息的标签

<div id="available-props-bundle-template">
  ### **可用 Props - Bundle template**
</div>

<img src="https://mintcdn.com/aftersell/uxKAdY-e0h16xa48/images/upcart/custom-template-expanded-bundle-components.png?fit=max&auto=format&n=uxKAdY-e0h16xa48&q=85&s=9a04c17667ea4af9cef303b96c079f37" alt="展开的套装，列出三个包含的组件商品及其变体" width="200" data-path="images/upcart/custom-template-expanded-bundle-components.png" />

`getSizedImageUrl`

* **类型**：`getSizedImageUrl: ({ src, width, height }: SizedImageParams) => string`

* **描述**：获取正确尺寸图片 URL 的工具函数

`item`

* **类型**：

  ```
  {  
    itemComponents: {  
      quantity: number;  
      image: {  
        url: string;  
        height: number | null;  
        width: number | null;  
        alt: string;  
      };  
      product: {  
        title: string;  
        has_only_default_variant: boolean;  
      };  
      variantTitle: string;  
    }[];  
    variantTitle: string | undefined;  
    hasComponents: boolean;  
  }
  ```

* **描述**：套装商品信息，包括组件。`itemComponents` 是组件对象数组——对其进行 map 以渲染每个套装组件。

`showDetailsText`

* **类型**：`string | undefined`

* **描述**："显示详情"操作的文本

* **用法**：显示展开按钮文本

`hideDetailsText`

* **类型**：`string | undefined`

* **描述**："隐藏详情"操作的文本

`isExpanded`

* **类型**：`boolean`

* **描述**：套装详情是否已展开

`toggleCollapsible`

* **类型**：`() => void`

* **描述**：切换套装详情可见性的函数

* **用法**：处理展开/折叠操作

`chevronDownIconComponent`

* **类型**：`React.ReactElement`

* **描述**：预渲染的展开/折叠 V 形图标

* **用法**：显示一致的展开/折叠指示器

<div id="available-props-price-template">
  ### **可用 Props - Price template**
</div>

<img src="https://mintcdn.com/aftersell/uxKAdY-e0h16xa48/images/upcart/custom-template-cart-price-strikethrough.png?fit=max&auto=format&n=uxKAdY-e0h16xa48&q=85&s=34deca3e39b1aabbafae6ed19d209450" alt="购物车价格，显示被划掉的原价、促销价和节省金额" width="250" data-path="images/upcart/custom-template-cart-price-strikethrough.png" />

`compareAtPrice`

* **类型**：`string | undefined`

* **描述**：格式化的原价（compare-at price）

* **用法**：为促销商品显示原价

`price`

* **类型**：`string`

* **描述**：格式化的当前价格

* **用法**：显示商品当前价格

`savings`

* **类型**：`string | undefined`

* **描述**：格式化的节省金额

* **用法**：显示客户节省了多少

<div id="cartitem-object-properties">
  ### **CartItem 对象属性**
</div>

`CartItem` 对象包含购物车订单项的所有详细信息。该对象在 Product Tile 模板中以 props.rawItem 提供，在 Variant 模板中以 props.item 提供。

<div id="core-identification">
  #### **核心标识**
</div>

* `key (string)` - 此购物车商品的唯一标识符。

* `id (number)` - 变体 ID（旧字段，请改用 variant\_id）

* `variant_id (number)` - 此商品的 Shopify 变体 ID

* `product_id (number)` - Shopify 商品 ID

* `lineIdxFrom1 (number)` - 此商品在修改前原始购物车中的索引（从 1 开始）

<div id="product-information">
  #### **商品信息**
</div>

* `title (string)` - 订单项标题（通常是变体标题）

* `product_title (string)` - 主商品标题

* `handle (string)` - 商品 URL handle（例如 "camp-stool"）

* `vendor (string)` - 商品供应商/品牌名称

* `product_type (string)` - 用于税务目的的商品类别/类型

* `sku (string)` - 库存单位标识符

* `product_description (string)` - 完整的商品描述

* `product_has_only_default_variant (boolean)` - 商品是否只有一个变体

<div id="pricing-all-prices-in-cents">
  #### **定价（所有价格以分为单位）**
</div>

* `quantity (number)` - 购物车中此商品的数量

* `price (number)` - 折扣前的单价

* `original_price (number)` - 与 price 相同

* `discounted_price (number)` - 商品级折扣后的单价

* `compare_at_price (number | null)` - 原价（MSRP）。注意：此字段由 Upcart 添加，不是由 Shopify 的购物车 API 提供

* `final_line_price (number)` - 商品级折扣后的总价（quantity × discounted\_price）

* `original_line_price (number)` - 折扣前的总价（quantity × price）

* `line_price (number)` - 所有折扣后的总价

* `final_price (number)` - **已弃用** - 商品折扣后的单价（不考虑数量）

* `total_discount (number)` - 与 line\_level\_total\_discount 相同

* `line_level_total_discount (number)` - 应用于此订单项的总折扣金额

<div id="media-urls">
  #### **媒体和 URL**
</div>

* `image (string)` - 主要商品图片 URL

* `url (string)` - 商品页面的相对 URL 路径（例如 "/products/camp-stool?variant=42789611372803"）

* `featured_image (object | null)` - 主图详情：

  * `alt (string)` - 图片替代文本
  * `aspect_ratio (number)` - 图片宽高比
  * `height (number)` - 图片高度（像素）
  * `url (string)` - 图片 URL
  * `width (number)` - 图片宽度（像素）

<div id="variants-options">
  #### **变体和选项**
</div>

* `variant_title (string | null)` - 变体标题（例如 "Large / Red"）

* `variant_options (string[])` - 变体选项值数组

* `options_with_values (Array)` - 详细的选项信息：

  * `name (string)` - 选项名称（例如 "Size"）
  * `value (string)` - 选项值（例如 "Large"）

* `untranslated_product_title (string | undefined)` - 翻译前的原始商品标题（仅在购物车变更响应中提供）

* `untranslated_variant_title (string | undefined)` - 翻译前的原始变体标题（仅在购物车变更响应中提供）

<div id="custom-properties-metadata">
  #### **自定义属性和元数据**
</div>

* `properties (Record<string, any> | null)` - 自定义订单项属性，当该行没有属性时为 `null`——读取键之前请先检查。键以 `__` 开头的属性始终对客户隐藏；当 **Hide properties starting with single underscore "\_"** 购物车设置开启时，以单个 `_` 开头的键也会被隐藏。

* `gift_card (boolean)` - 此商品是否为礼品卡

* `taxable (boolean)` - 此商品是否需缴税

* `requires_shipping (boolean)` - 此商品是否需要配送

* `grams (number)` - 商品重量（克）

<div id="discounts-promotions">
  #### **折扣和促销**
</div>

* `discounts (Array)` - 简化的折扣信息：

  * `amount (number)` - 折扣金额（分）
  * `title (string)` - 折扣标题/名称

* `line_level_discount_allocations (Array)` - 详细的折扣分配信息：

  * `amount (number)` - 折扣金额（分）
  * `discount_application (object)` - 完整的折扣应用详情：

    * `allocation_method (string)` - 折扣的分配方式
    * `created_at (string)` - 折扣创建时间
    * `description (string | null)` - 折扣描述
    * `key (string)` - 折扣键标识符
    * `target_selection (string)` - 折扣的目标选择
    * `target_type (string)` - 目标类型
    * `title (string)` - 折扣标题
    * `total_allocated_amount (number)` - 分配的总金额
    * `type ('discount_code' | '')` - 折扣类型（自动折扣为空字符串）
    * `value (string)` - 折扣值
    * `value_type (string)` - 值的应用方式

<div id="bundle-products">
  #### **套装商品**
</div>

* `has_components (boolean | undefined)` - 此商品是否为包含其他商品的套装（仅在 GET 购物车响应中提供）

* `item_components (Array | null | undefined)` - 套装组件详情：

  * `quantity (number)` - 此组件的数量
  * `image (object)` - 组件图片：

    * `url (string)` - 图片 URL
    * `height (number | null)` - 图片高度
    * `width (number | null)` - 图片宽度
    * `alt (string)` - 替代文本

* `product (object)` - 组件商品信息：

  * `title (string)` - 商品标题
  * `has_only_default_variant (boolean)` - 商品是否只有默认变体

* `variantTitle (string)` - 组件变体标题

<div id="business-rules">
  #### **业务规则**
</div>

* `quantity_rule (object | undefined)` - 数量约束（仅在 GET 购物车响应中提供）：

  * `min (number)` - 允许的最小数量
  * `max (number | null)` - 允许的最大数量（null = 无限制）
  * `increment (number)` - 数量增量步长

<div id="subscription-information">
  #### **订阅信息**
</div>

* `selling_plan_allocation (object | undefined)` - 订阅/销售方案详情：

  * `price (number)` - 订阅价格（分）
  * `compare_at_price (number | null)` - 订阅原价
  * `per_delivery_price (number)` - 每次配送的价格
  * `selling_plan (object)` - 销售方案详情：

    * `id (number)` - 销售方案 ID
    * `name (string)` - 方案名称
    * `description (string)` - 方案描述
    * `options (Array)` - 方案选项：

      * `name (string)` - 选项名称
      * `position (number)` - 选项位置
      * `value (string)` - 选项值
    * `recurring_deliveries (boolean)` - 方案是否包含循环配送

<div id="integration-metadata">
  #### **集成元数据**
</div>

* `__appIntegrated (object | undefined)` - 第三方应用集成数据：

  * `app ('stay.ai')` - 已集成应用的标识符
  * `bundleRole ('parent' | 'child')` - 在套装结构中的角色

<div id="upsells">
  ## Upsells
</div>

Upsells 模块允许你使用自己的设计自定义 upsell 商品显示，同时保持基本的电商功能，例如变体选择、加购操作和商品信息显示。

<div id="available-props-upsell-tile-template">
  ### **可用 Props - Upsell tile template**
</div>

<img src="https://mintcdn.com/aftersell/uxKAdY-e0h16xa48/images/upcart/custom-template-upsell-tile-product-sale.png?fit=max&auto=format&n=uxKAdY-e0h16xa48&q=85&s=276d261e795de83ca0882f4cd713ec61" alt="Upsell 磁贴，显示带促销价、变体下拉菜单和 Add 按钮的商品" width="400" data-path="images/upcart/custom-template-upsell-tile-product-sale.png" />

`itemUrl`

* **类型**：`string`

* **描述**：商品页面的 URL

* **用法**：创建指向商品详情页的链接，以增强用户导航

```
<a href={props.itemUrl} className="product-link">  
  <img src={props.imageUrl} alt={props.altText} />  
</a>
```

`imageUrl`

* **类型**：`string | undefined`

* **描述**：商品图片的 URL

* **用法**：在自定义 upsell 实现中显示商品图片

* **回退**：使用占位图片妥善处理 undefined 值

`description`

* **类型**：`string`

* **描述**：商品的描述

* **用法**：在自定义 upsell 实现中显示商品描述

`altText`

* **类型**：`string`

* **描述**：商品图片的替代文本，用于无障碍访问

* **用法**：提供屏幕阅读器支持并提升无障碍合规性

```
<img   
  src={props.imageUrl}   
  alt={props.altText}  
  className="product-image"  
/>
```

`productId`

* **类型**：`string`

* **描述**：商品的唯一标识符

* **用法**：跟踪商品、实现分析或用于加购功能

`productTitle`

* **类型**：`string`

* **描述**：商品的标题/名称

* **用法**：在自定义 upsell 实现中显示商品名称

```
<div>  
  <h3>{props.productTitle}</h3>  
</div>
```

`oldPrice` 和 `newPrice`

* **类型**：`string | null`（oldPrice）、`string`（newPrice）

* **描述**：格式化的原价和当前价格

* **用法**：显示带有促销标识的价格信息

`isSingleVariant`

* **类型**：`boolean`

* **描述**：指示商品是否只有一个变体

* **用法**：有条件地渲染变体选择 UI 元素

`productOptions`

* **类型**：`{ name: string; position: 1 | 2 | 3; values: string[]; }[]`

* **描述**：完整的商品选项配置，包括所有可用选择

* **用法**：访问详细的商品选项信息，用于高级变体选择 UI

`variantOptions`

* **类型**：`{ label: string; value: string }[]`

* **描述**：商品可用的变体选项

* **用法**：创建变体选择下拉菜单或按钮

* **结构**：每个选项包含一个显示标签和唯一值标识符

`selectedVariantId` 和 `selectedVariantLabel`

* **类型**：string（selectedVariantId）、string | undefined（selectedVariantLabel）

* **描述**：当前选中的变体 ID 及其显示标签

* **用法**：跟踪并显示所选变体的信息

`onVariantChange`

* **类型**：`(variantId: string) => void`

* **描述**：处理变体选择更改的函数

* **用法**：当用户进行选择时更新所选变体

`onAddClick`

* **类型**：`(productId: string, variantId?: string) => void`

* **描述**：处理将商品添加到购物车的函数

* **用法**：使用正确的商品和变体标识实现加购功能

```
<button   
  onClick={() => props.onAddClick(props.productId, props.selectedVariantId)}  
  disabled={props.addLoading}  
>  
  {props.addLoading ? 'Adding...' : props.addButtonText}  
</button>
```

`rating` 和 `reviewCount`

* **类型**：`number | undefined`（rating）、`string | undefined`（reviewCount）

* **描述**：商品评分和格式化的评论数量文本

* **用法**：展示社会认同和商品质量指标

`addLoading` 和 `addButtonText`

* **类型**：`boolean`（addLoading）、`string`（addButtonText）

* **描述**：加购操作的加载状态和按钮文本

* **用法**：在购物车操作期间向用户提供反馈并自定义按钮文本

`cartItemsCount`

* **类型**：`number`

* **描述**：购物车中当前的商品数量

* **用法**：显示购物车状态或实现基于购物车的逻辑

<div id="additional-notes">
  ## Additional Notes
</div>

Notes 模块允许你使用自己的设计自定义购物车备注功能，同时保持基本的备注功能，例如可展开区域、文本输入处理和加载状态。

<div id="available-props-full-template-5">
  ### **可用 Props - Full template**
</div>

<img src="https://mintcdn.com/aftersell/uxKAdY-e0h16xa48/images/upcart/custom-template-cart-notes-section-expandable.png?fit=max&auto=format&n=uxKAdY-e0h16xa48&q=85&s=ce3f2a79f875029e6358c2227cd024d9" alt="购物车备注区域，带有可展开的特殊说明文本字段" width="400" data-path="images/upcart/custom-template-cart-notes-section-expandable.png" />

`cartNote`

* **类型**：`string`

* **描述**：客户输入的当前购物车备注内容

* **用法**：在自定义实现中显示和管理购物车备注文本

```
<textarea  
  value={props.cartNote}  
  ...  
/>
```

`notesPlaceholder`

* **类型**：`string`

* **描述**：备注输入字段的占位符文本

* **用法**：为客户提供关于备注内容的指引

```
<textarea  
  placeholder={props.notesPlaceholder}  
  ...  
/>
```

`notesTitle`

* **类型**：`string`

* **描述**：备注区域的标题/页眉文本

* **用法**：在自定义备注实现中显示区域标题

```
<h3 className="notes-title" dangerouslySetInnerHTML={{ __html: props.notesTitle }} />
```

`chevronDownIconComponent`

* **类型**：`React.ReactElement`

* **描述**：用于展开/折叠功能的预渲染 V 形图标组件

* **用法**：在自定义实现中显示一致的展开/折叠指示器

`loadingIndicatorComponent`

* **类型**：`React.ReactElement | null`

* **描述**：用于异步操作的预渲染加载指示器组件

* **用法**：在备注保存操作期间显示加载状态

`handleCartNoteChange`

* **类型**：`(newCartNote: string) => void`

* **描述**：处理购物车备注内容更改的函数

* **用法**：当用户修改文本时更新购物车备注

`isExpanded`

* **类型**：`boolean`

* **描述**：指示备注区域当前是否展开

* **用法**：控制备注输入区域的可见性

`toggleCollapsible`

* **类型**：`() => void`

* **描述**：切换备注区域展开/折叠状态的函数

* **用法**：绑定到按钮或交互元素上以控制区域可见性

***

<div id="footer-section">
  ## Footer 区域
</div>

<div id="add-ons">
  ## Add-ons
</div>

Addons 模块允许你使用自己的设计自定义附加商品显示，同时保持基本的电商功能，例如商品信息显示、定价、切换控件和货币格式化。

<div id="available-props-full-template-6">
  ### **可用 Props - Full template**
</div>

<img src="https://mintcdn.com/aftersell/uxKAdY-e0h16xa48/images/upcart/custom-template-add-on-product-row-gift-card.png?fit=max&auto=format&n=uxKAdY-e0h16xa48&q=85&s=8a705eec52fbe1e24420467f92978829" alt="附加商品行，显示带价格和启用切换开关的礼品卡" width="400" data-path="images/upcart/custom-template-add-on-product-row-gift-card.png" />

`addonProduct`

* **类型**：

  ```
  {  
    product: {  
      id: number;  
      title: string;  
      description: string;  
    };  
    variant: {  
      id: number;  
      price: number;  
      compare_at_price: number | null;  
    };  
    image: {  
      src: string;  
      alt: string;  
    };  
  }
  ```

* **描述**：完整的附加商品信息，包括商品详情、变体定价和图片数据

* **用法**：访问显示附加商品所需的所有商品信息

* **结构**：包含嵌套的 product、variant 和 image 对象，提供全面的商品数据

  * **Product 对象属性** `addonProduct.product`

    * **id**：商品的唯一数字标识符
    * **title**：附加商品的显示名称
    * **description**：商品的 HTML 描述内容
  * **Variant 对象属性**

    * **id**：变体的唯一数字标识符
    * **price**：当前价格（分）
    * **compare\_at\_price**：原价（分）（如果没有比较价格则为 null）
  * **Image 对象属性**

    * **src**：商品图片的 URL
    * **alt**：图片的替代文本（用于无障碍访问）

`toggle`

* **类型**：

  ```
  {  
    state: 'enabled' | 'disabled' | 'loading';  
    handleEnable: () => void;  
    handleDisable: () => void;  
  } | null
  ```

* **描述**：用于启用/禁用附加项的切换控件状态和处理程序

* **用法**：实现附加项选择的交互式切换功能

* **状态**：三种可能的状态——enabled、disabled 和 loading

* **处理程序**：分别用于启用和禁用操作的独立函数

`moneyFormat`

* **类型**：`string`

* **描述**：用于价格格式化的货币格式字符串

* **用法**：传递给 formatMoney 函数以实现一致的货币显示

`formatMoney`

* **类型**：

  ```
  (options: {  
    cents: string | number;  
    format?: string;  
    shouldRemoveHTML?: boolean;  
  }) => string
  ```

* **描述**：用于格式化货币值的工具函数

* **用法**：按照商店货币设置一致地格式化价格

* **参数**：接受分值、可选的格式字符串和 HTML 移除选项

<div id="discount-codes">
  ## Discount Codes
</div>

Discount Code 模块允许你使用自己的设计自定义折扣码输入功能，同时保持基本的电商功能，例如代码验证、表单提交和用户反馈。

<div id="available-props-full-template-7">
  ### **可用 Props - Full template**
</div>

<img src="https://mintcdn.com/aftersell/uxKAdY-e0h16xa48/images/upcart/custom-template-discount-code-input-field.png?fit=max&auto=format&n=uxKAdY-e0h16xa48&q=85&s=9e8eb5e08805c18b26a3338707a9909a" alt="带 Apply 按钮的折扣码输入字段" width="400" data-path="images/upcart/custom-template-discount-code-input-field.png" />

`indicator`

* **类型**：`'validating' | 'invalid' | 'none'`

* **描述**：折扣码输入的当前验证状态

* **用法**：根据验证状态显示适当的 UI 反馈

* **状态**：

  * `validating`：代码正在处理/验证中
  * `invalid`：代码验证失败
  * `none`：无验证状态（默认/空闲）

`discountCodeInput`

* **类型**：`string`

* **描述**：折扣码输入字段的当前值

* **用法**：显示和管理用户输入的折扣码文本

```
<input  
  type="text"  
  value={props.discountCodeInput}  
  onChange={(e) => props.setDiscountCodeInput(e.target.value)}  
  ...  
/>
```

`discountCodePlaceholder`

* **类型**：`string`

* **描述**：折扣码输入字段的占位符文本

* **用法**：为用户提供关于输入内容的指引

`discountCodeButtonText`

* **类型**：`string`

* **描述**：应用/提交按钮上显示的文本

* **用法**：自定义折扣码提交按钮的文本

`setDiscountCodeInput`

* **类型**：`(value: string | ((prev: string) => string)) => void`

* **描述**：更新折扣码输入值的函数

* **用法**：处理折扣码字段中的用户输入更改

`handleSubmit`

* **类型**：`(e: React.FormEvent<HTMLFormElement>) => void`

* **描述**：处理折扣码应用表单提交的函数

* **用法**：处理折扣码的验证和应用

* **事件**：处理表单提交事件

```
<form onSubmit={props.handleSubmit} >  
  <div className="input-group">  
    <input  
      type="text"  
      value={props.discountCodeInput}  
      onChange={(e) => props.setDiscountCodeInput(e.target.value)}  
      placeholder={props.discountCodePlaceholder}  
    />   
    <button   
      type="submit"  
      disabled={props.indicator === 'validating' || !props.discountCodeInput.trim()}  
    >  
      {props.discountCodeButtonText}  
    </button>  
  </div>  
</form>
```

<div id="cart-summary">
  ## Cart Summary
</div>

Cart Summary 模块允许你使用自己的设计自定义购物车摘要和折扣显示，同时保持基本的电商功能，例如折扣管理、节省金额计算和价格透明度。

<div id="available-props-full-template-8">
  ### **可用 Props - Full template**
</div>

<img src="https://mintcdn.com/aftersell/uxKAdY-e0h16xa48/images/upcart/custom-template-cart-summary-discount-row.png?fit=max&auto=format&n=uxKAdY-e0h16xa48&q=85&s=492e00824117bf0b93bf0c3a1402050f" alt="购物车摘要折扣行，显示已应用的折扣码和金额" width="400" data-path="images/upcart/custom-template-cart-summary-discount-row.png" />

`totalSavingsText`

* **类型**：`string`

* **描述**：总节省金额区域的文本标签

* **用法**：在自定义购物车摘要实现中显示节省标签

`discountApplications`

* **类型**：

  ```
  {  
    key: string;  
    title: string;  
    type: 'discount_code' | '';  
  }[]
  ```

* **描述**：已应用的折扣码和自动折扣的数组

* **用法**：显示所有生效的折扣及其标题和类型

* **结构**：每个折扣包含唯一键、显示标题和类型标识符

`cartTotalDiscount`

* **类型**：`number`

* **描述**：总折扣金额（分）

* **用法**：访问原始折扣值以进行计算或自定义格式化

`showCartTotalDiscount`

* **类型**：`boolean`

* **描述**：指示是否应显示总折扣。已标记为弃用，推荐使用 `showTotalSavings`，但请参阅下面的说明——在自定义模板中，这仍然是你可用的 prop。

* **用法**：根据设置有条件地渲染折扣信息

`formattedCartTotalDiscount`

* **类型**：`string`

* **描述**：总折扣金额的预格式化 HTML 字符串。已标记为弃用，推荐使用 `formattedTotalSavings`，但请参阅下面的说明。

* **用法**：显示带有货币符号的正确格式化折扣金额

<Warning>
  \*\*`showTotalSavings` 和 `formattedTotalSavings` 在自定义模板中不可用。\*\*它们存在于模块的内部上下文中，但 Cart summary 模板只接收 `showCartTotalDiscount` 和 `formattedCartTotalDiscount`——读取较新的这对 props 会返回 `undefined`。请使用上述两个，并注意它们只显示折扣总额；它们不遵循 **Show compare-at price savings in footer total** 设置。
</Warning>

`isRemovingDiscount`

* **类型**：`boolean`

* **描述**：指示折扣移除操作是否正在进行中

* **用法**：在折扣移除期间显示加载状态

`handleRemoveDiscount`

* **类型**：`() => Promise<void>`

* **描述**：处理折扣码移除的函数

* **用法**：从购物车中移除已应用的折扣码

`totalCompareAtPrice`

* **类型**：`number`

* **描述**：原价的累加总额（购物车中所有商品）

* **用法**：计算并显示节省金额或原始价格信息

`totalAfterAllDiscounts`

* **类型**：`number`

* **描述**：应用所有折扣后的最终购物车总额（分）

* **用法**：显示客户最终支付的价格

`originalTotalPrice`

* **类型**：`number`

* **描述**：任何折扣前的原始购物车总额（分）

* **用法**：出于透明度和节省金额计算的目的显示原始价格

`cartItemCount`

* **类型**：`number`

* **描述**：购物车中的商品总数

* **用法**：在购物车摘要中显示商品数量信息

<div id="trust-badges">
  ## Trust Badges
</div>

Trust Badges 模块允许你使用自己的设计自定义信任徽章显示，同时保持基本的信任建立功能，例如条件性徽章可见性和正确的图片处理。

<div id="available-props-full-template-9">
  ### **可用 Props - Full template**
</div>

`showBadge`

* **类型**：`boolean`

* **描述**：指示是否应显示信任徽章

* **用法**：根据模块设置控制信任徽章的可见性

`badgeUrl`

* **类型**：`string`

* **描述**：要显示的信任徽章图片的 URL

* **用法**：自定义实现中信任徽章图片的来源 URL
