# Checkout 价格迁移指南

了解如何升级您的集成来使用 Stripe Checkout 的价格功能。

[Prices API](https://docs.stripe.com/api/prices.md) 集成包括：

- 统一对 Checkout 项目建模，不再采用方案、*SKU* (SKUs (Stock Keeping Units) represent a specific Product variation, taking into account any combination of attributes and cost (for instance, size, color, currency, cost)) 和内联明细项，每个项目都是一个_价格_。
- 能够为重复出现的项目呈现产品图片。
- 能够创建可重复使用的产品和价格目录，而不是一次性的明细项。
- 能够为*订阅* (A Subscription represents the product details associated with the plan that your customer subscribes to. Allows you to charge the customer on a recurring basis)创建内联定价。
- [订阅](https://docs.stripe.com/billing/taxes/collect-taxes.md?tax-calculation=tax-rates#adding-tax-rates-to-checkout)和[一次性付款](https://docs.stripe.com/payments/checkout/taxes.md)的动态税率。

如果您不想迁移，可以继续使用当前的集成，但我们不会再添加新功能。您可以在现有 API 调用的 `plan` 参数中使用您创建的新方案或周期性价格。

## 产品和价格概览

*价格* (Prices define how much and how often to charge for products. This includes how much the product costs, what currency to use, and the interval if the price is for subscriptions)是 Stripe 中的核心实体，与订阅、*账单* (Invoices are statements of amounts owed by a customer. They track the status of payments from draft through paid or otherwise finalized. Subscriptions automatically generate invoices, or you can manually create a one-off invoice)和 Checkout 共同发挥作用。每个价格都与单个*产品* (Products represent what your business sells—whether that's a good or a service)绑定，每个产品可以有多个价格。不同的实物商品或服务层级由不同的产品来表示。

价格由基础价格、货币，以及针对周期性产品的计费周期组成。因此，您可以更改和添加价格，而无需更改您所提供产品的详细信息。例如，您有一款“黄金版”产品，您可以为其设置每月 10 美元、每年 100 美元、每月 9 欧元以及每年 90 欧元的价格。或者，您可以为一款蓝色 T 恤分别设置 20 美元和 15 欧元的价格。

## 一次性付款

一次性付款的集成有以下变化：

- 不再是临时的行项目（即设置名称、金额和货币），创建 Checkout Session 时要求创建 *product* (Products represent what your business sells—whether that's a good or a service)，而且通常要创建 *price* (Prices define how much and how often to charge for products. This includes how much the product costs, what currency to use, and the interval if the price is for subscriptions)。
- 现在要求使用 [mode](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-mode)。

客户端代码保持不变。

### 映射表

不需要再定义 `line_items` 的每个字段，Checkout 会用相关的产品和价格对象来确定名称、描述、金额、货币和图片。您可以用 API 或管理平台来[创建产品和价格](https://docs.stripe.com/payments/accept-a-payment.md)。

| 不使用 PRICES | 使用 PRICES |
| --- | --- |
| `line_items.name` | `product.name` |
| `line_items.description` | `product.description` |
| `line_items.amount` | - `price.unit_amount`
- `price_data.unit_amount`（如果在创建 Checkout Session 时定义了它） |
| `line_items.currency` | - `price.currency`
- `price_data.unit_amount`（如果在创建 Checkout Session 时定义了它） |
| `line_items.images` | `product.images`（显示提供的第一张图片） |

### 内联项目的服务器端代码

以前，您可能只能创建一次性项目内联。有了 Prices，您可以继续配置您的项目内联，但在创建 Checkout Session 时，您也可以用 [price_data](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-line_items-price_data) 动态定义您的价格。

用 `price_data` 创建 Checkout Session 时，通过 [price_data.product](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-line_items-price_data-product) 引用现有产品的 ID，或用 [price_data.product_data](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-line_items-price_data-product_data) 动态定义您的产品详情。以下示例演示一次性项目的创建流程。

#### curl

```bash
curl https://api.stripe.com/v1/checkout/sessions \
  -u <<YOUR_SECRET_KEY>>: \
  -d "line_items[0][quantity]"=1 \
  -d "line_items[0][price_data][unit_amount]"=2000 \
  -d "line_items[0][price_data][product_data][name]"=T-shirt \
  -d "line_items[0][price_data][product_data][description]"="Comfortable cotton t-shirt" \
  -d "line_items[0][price_data][product_data][images][]"="https://example.com/t-shirt.png" \
  -d "line_items[0][price_data][currency]"=usd \
  -d mode=payment \
  -d success_url="https://example.com/success" \
```

### 一次性价格的服务器端代码

通过此集成，您可以预先[创建产品和价格目录](https://docs.stripe.com/payments/accept-a-payment.md)，而无需在每次创建 Checkout Session 时都重新定义金额、货币和名称。

您可以使用 [Prices API](https://docs.stripe.com/api/prices.md) 或通过[管理平台](https://dashboard.stripe.com/products)创建产品和价格。您需要价格 ID 来创建 Checkout Session。以下示例展示了如何通过 API 创建产品和价格：

#### curl

```bash

curl https://api.stripe.com/v1/products \
  -u<<YOUR_SECRET_KEY>>: \
  -d name=T-shirt \
  -d description="Comfortable cotton t-shirt" \
  -d "images[]"="https://example.com/t-shirt.png"

curl https://api.stripe.com/v1/prices \
  -u<<YOUR_SECRET_KEY>>: \
  -d product="{{PRODUCT_ID}}" \
  -d unit_amount=2000 \
  -d currency=usd

curl https://api.stripe.com/v1/checkout/sessions \
  -u <<YOUR_SECRET_KEY>>: \
  -d "line_items[0][quantity]"=1 \
  -d "line_items[0][price]"="{{PRICE_ID}}" \
  -d mode=payment \
  -d success_url="https://example.com/success" \
```

## 订阅

经常性付款的集成有以下变化：

- 所有项目都被传递到一个 [line_items](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-line_items) 字段，而非 `subscription_data.items`。
- 现在要求使用 [mode](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-mode)。如果会话中包含任何经常性项目，则设置 `mode=subscription`。

客户端代码保持不变。在接受经常性价格时可以使用现有方案。

### 使用方案情况下的服务器端代码

这里是一个升级前后创建包含试用且使用现有方案（可以与 Price 互换使用）的 Checkout Session 的示例。该方案现已传递到 `line_items` 内，而非 `subscription_data.items`。

#### curl

```bash
curl https://api.stripe.com/v1/checkout/sessions \
  -u <<YOUR_SECRET_KEY>>: \
  -d "line_items[0][price]"="{{PRICE_OR_PLAN_ID}}" \
  -d "line_items[0][quantity]"=1 \
  -d mode=subscription \
  -d success_url="https://example.com/success" \
```

### 有设置费的经常性价格的服务器端代码

如果您的周期性方案包含一次性设置费，请在创建 Checkout Session 之前，先创建代表该一次性费用的产品和价格。有关`line_items`字段如何映射到此集成，请参阅[映射表](https://docs.stripe.com/payments/checkout/migrating-prices.md#mapping-table-server-one-time)。您可以通过 [Prices API](https://docs.stripe.com/api/prices.md) 或 [Stripe 管理平台](https://dashboard.stripe.com/products)创建产品和价格，也可以[内联创建一次性项目](https://docs.stripe.com/payments/checkout/migrating-prices.md#server-side-code-for-inline-items)。以下示例使用现有的价格 ID：

#### curl

```bash
curl https://api.stripe.com/v1/checkout/sessions \
  -u <<YOUR_SECRET_KEY>>: \
  -d "line_items[0][price]"="{{PRICE_OR_PLAN_ID}}" \
  -d "line_items[0][quantity]"=1 \
  -d "line_items[1][price]"="{{ONE_TIME_PRICE_ID}}" \
  -d "line_items[1][quantity]"=1 \
  -d mode=subscription \
  -d success_url="https://example.com/success" \
```

## 响应对象的变化

Checkout Session 对象使用 `line_items` 列出项目，不再使用 `display_items`。默认情况下，`line_items` 字段与 `display_items` 呈现方式不同，但您可以在创建 Checkout Session 时使用[扩展](https://docs.stripe.com/api/expanding_objects.md) 将其包含在内：

#### curl

```bash
curl https://api.stripe.com/v1/checkout/sessions \
  -u <<YOUR_SECRET_KEY>>: \
  -d "payment_method_types[]"="card" \
  -d "mode"="payment" \
  -d "line_items[0][price]"="{{PRICE_ID}}" \
  -d "line_items[0][quantity]"=1 \
  -d "success_url"="https://example.com/success" \
  -d "expand[]"="line_items"
```

## Webhook 的变化

由于 `line_items` 是可展开的，因此默认情况下，`checkout.session.completed` *Webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) 响应不会列出明细项。较小的响应对象有助于您更快地接收 Checkout Webhook。您可以通过 `line_items` 端点来检索明细项：

#### curl

```bash
curl https://api.stripe.com/v1/checkout/sessions/{{CHECKOUT_SESSION_ID}}/line_items \
  -u <<YOUR_SECRET_KEY>>:
```

更多详情，请查看[通过 Checkout 履行订单](https://docs.stripe.com/checkout/fulfillment.md)。
