# PaymentSummary

`PaymentSummary` 组件是任何结账流程中至关重要的 UI 元素。它提供了订单的详细分类，包括所有订单项、试用期信息、质押要求和最终总金额。它的设计是响应式的，可以为移动设备调整其布局。

该组件与 `ProductItem` 和 `ProductDonation` 协同工作，以渲染购物车中的每个商品，并处理用户交互，如应用交叉销售或更改数量。

## Props

`PaymentSummary` 组件接受以下 props 以自定义其行为和显示：

| Prop | Type | Required | Description |
| --- | --- | --- | --- |
| `items` | `TLineItemExpanded[]` | 是 | 要在摘要中显示的订单项数组。 |
| `currency` | `TPaymentCurrency` | 是 | 用于格式化金额的货币对象。 |
| `trialInDays` | `number` | 是 | 周期性订阅的试用天数。 |
| `billingThreshold` | `number` | 是 | 计费阈值金额。如果适用，用于质押计算。 |
| `trialEnd` | `number` | 否 | 试用结束的 Unix 时间戳。会覆盖 `trialInDays`。 |
| `showStaking` | `boolean` | 否 | 如果为 `true`，则显示质押详情。默认为 `false`。 |
| `onUpsell` | `(from: string, to: string) => void` | 否 | 用户接受增销提议时的回调函数。 |
| `onDownsell` | `(from: string) => void` | 否 | 用户恢复增销提议时的回调函数。 |
| `onQuantityChange` | `(itemId: string, quantity: number) => void` | 否 | 更改商品数量时的回调函数。 |
| `onChangeAmount` | `(itemId: string, amount: string) => void` | 否 | 用于更改自定义金额项目（如捐赠）金额的回调。 |
| `onApplyCrossSell` | `(crossSellId: string) => void` | 否 | 用户添加交叉销售商品时的回调函数。 |
| `onCancelCrossSell` | `() => void` | 否 | 用户移除交叉销售商品时的回调函数。 |
| `checkoutSessionId` | `string` | 否 | 结账会话的 ID，用于获取潜在的交叉销售商品。 |
| `crossSellBehavior` | `string` | 否 | 定义交叉销售商品的行为（例如，`'required'`）。 |
| `donationSettings` | `DonationSettings` | 否 | 捐赠项目的配置。 |
| `action` | `string` | 否 | 摘要部分的自定义标题，替换“订单摘要”。 |
| `completed` | `boolean` | 否 | 如果为 `true`，则禁用数量调整等交互式元素。默认为 `false`。 |

## 用法

`PaymentSummary` 组件应放置在 `PaymentProvider` 中，并且通常用作更复杂的结账表单的一部分。你需要为其提供订单项和货币信息。

以下是如何集成 `PaymentSummary` 组件的基本示例。

```tsx PaymentSummary Example icon=lucide:shopping-cart
import React from 'react';
import { PaymentProvider, PaymentSummary } from '@blocklet/payment-react';
import { useSessionContext } from '../hooks/session-context'; // 你的会话上下文钩子

// 用于演示的模拟数据
const mockCurrency = {
  id: 'usd_4573516104843264',
  symbol: '$',
  name: 'USD',
  decimal: 2,
  isDefault: true,
};

const mockItems = [
  {
    id: 'li_1',
    price_id: 'price_1',
    quantity: 1,
    adjustable_quantity: { enabled: true, minimum: 1, maximum: 10 },
    price: {
      id: 'price_1',
      type: 'recurring',
      recurring: { interval: 'month', interval_count: 1, usage_type: 'licensed' },
      unit_amount: '2000',
      product: {
        name: 'Pro Plan',
        images: [],
      },
    },
  },
];

export default function MyCheckoutPage() {
  const { session, connectApi } = useSessionContext();

  const handleQuantityChange = (itemId, newQuantity) => {
    console.log(`Item ${itemId} quantity changed to ${newQuantity}`);
    // 在这里，你通常会更新你的状态并重新获取结账信息
  };

  return (
    <PaymentProvider session={session} connectApi={connectApi}>
      <PaymentSummary
        items={mockItems}
        currency={mockCurrency}
        trialInDays={14}
        billingThreshold={0}
        showStaking={true}
        onQuantityChange={handleQuantityChange}
      />
    </PaymentProvider>
  );
}
```

### 显示质押和总计

如果 `showStaking` 设置为 `true`，该组件将计算并显示周期性项目所需的质押金额。它将立即支付的金额与质押所需的金额分开，为用户提供清晰的财务摘要。最终总额是这些金额的总和。

### 处理试用期

该组件向用户清晰地传达试用期信息。通过传递 `trialInDays` 或 `trialEnd`，总额下方将显示类似“然后 $20.00 / 月”的消息，告知用户试用期结束后的周期性费用。

### 交互功能

- **数量调整**：如果一个项目的 `adjustable_quantity.enabled` 设置为 `true`，`PaymentSummary`（通过其子组件 `ProductItem`）将渲染用于增加或减少数量的控件。修改时会触发 `onQuantityChange` 回调。
- **增销/减销**：对于具有增销配置的产品，会渲染一个开关，允许用户升级他们的计划。`onUpsell` 和 `onDownsell` 回调处理这些操作。
- **交叉销售**：如果提供了 `checkoutSessionId`，该组件可以获取并显示建议的交叉销售商品。添加或移除这些商品的按钮会触发 `onApplyCrossSell` 和 `onCancelCrossSell` 回调。

### 移动端响应式设计

在移动设备上，产品列表默认是可折叠的以节省空间，特别是对于包含许多商品的订单。用户可以点击以展开或折叠列表，从而在较小的屏幕上提供更清晰、更友好的用户体验。