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

# 预览试用期

> 预览订阅 checkout session 的试用资格和试用天数

预览订阅 checkout session 的试用期 — 返回 customer 是否有试用资格以及试用天数。

```
POST /v1/actions/checkout/preview-trial
```

**认证方式：** Store Slug（visitor）— 也接受 customer session token

<Note>
  此端点也接受 customer session token — 见 [Customer Session 端点](/zh/api-reference/endpoints/auth/customer-endpoints)。使用 customer token 调用时，customer 身份从 token 中取得，请求体中的 `buyerIdentity` 字段会被覆盖。
</Note>

## 资格判定规则

资格判定基于 customer 在该产品（或同产品组内任一产品）是否已有试用记录：

* 无试用记录 → `isEligible: true`，`trialDays` 返回产品配置的试用天数
* 已有试用记录 → `isEligible: false`，`trialDays` 为 `null`

Visitor 模式下 `buyerIdentity` 为空时，视为全新 customer，恒返回 `isEligible: true`。

## 请求体

| 字段                  | 类型     | 必需 | 说明                                                                      |
| ------------------- | ------ | -- | ----------------------------------------------------------------------- |
| `checkoutSessionId` | string | 是  | 由「创建 Checkout Session」返回的会话 ID（必须是订阅产品）                                 |
| `buyerIdentity`     | string | 条件 | customer 邮箱。Customer 模式下从 token 取得（必填）；visitor 模式可选 — 不传则视为有完整试用资格，不查记录 |

## 请求示例

<CodeGroup>
  ```typescript TypeScript (SDK) theme={"system"}
  import { WaffoPancake } from "@waffo/pancake-ts";

  const client = new WaffoPancake({
    merchantId: process.env.WAFFO_MERCHANT_ID!,
    privateKey: process.env.WAFFO_PRIVATE_KEY!,
  });

  const result = await client.checkout.previewTrial({
    storeSlug: "my-store-abc123",
    checkoutSessionId: "cs_550e8400-e29b-41d4-a716-446655440000",
    buyerIdentity: "customer@example.com",
  });

  console.log(result.isEligible); // true
  console.log(result.trialDays);  // 14
  ```

  ```typescript TypeScript (Manual) theme={"system"}
  // Assumes callApi() is defined as shown in the Authentication guide
  const result = await callApi("POST", "/v1/actions/checkout/preview-trial", {
    checkoutSessionId: "cs_550e8400-e29b-41d4-a716-446655440000",
    buyerIdentity: "customer@example.com",
  });
  ```

  ```java Java theme={"system"}
  // Assumes callApi() is defined as shown in the Authentication guide
  String result = callApi("POST", "/v1/actions/checkout/preview-trial",
      "{\"checkoutSessionId\":\"cs_550e8400-e29b-41d4-a716-446655440000\","
      + "\"buyerIdentity\":\"customer@example.com\"}");
  ```

  ```python Python theme={"system"}
  # Assumes call_api() is defined as shown in the Authentication guide
  result = call_api("POST", "/v1/actions/checkout/preview-trial", {
      "checkoutSessionId": "cs_550e8400-e29b-41d4-a716-446655440000",
      "buyerIdentity": "customer@example.com",
  })
  ```

  ```go Go theme={"system"}
  // Assumes callAPI() is defined as shown in the Authentication guide
  result, err := callAPI("POST", "/v1/actions/checkout/preview-trial",
      `{"checkoutSessionId":"cs_550e8400-e29b-41d4-a716-446655440000","buyerIdentity":"customer@example.com"}`)
  ```

  ```rust Rust theme={"system"}
  // Assumes call_api() is defined as shown in the Authentication guide
  let result = call_api("POST", "/v1/actions/checkout/preview-trial",
      r#"{"checkoutSessionId":"cs_550e8400-e29b-41d4-a716-446655440000","buyerIdentity":"customer@example.com"}"#
  ).await?;
  ```

  ```c C theme={"system"}
  // Assumes call_api() is defined as shown in the Authentication guide
  call_api("/v1/actions/checkout/preview-trial",
      "{\"checkoutSessionId\":\"cs_550e8400-e29b-41d4-a716-446655440000\","
      "\"buyerIdentity\":\"customer@example.com\"}");
  ```

  ```cpp C++ theme={"system"}
  // Assumes call_api() is defined as shown in the Authentication guide
  auto result = call_api("/v1/actions/checkout/preview-trial",
      R"({"checkoutSessionId":"cs_550e8400-e29b-41d4-a716-446655440000","buyerIdentity":"customer@example.com"})");
  ```

  ```bash cURL theme={"system"}
  curl -X POST "https://api.waffo.ai/v1/actions/checkout/preview-trial" \
    -H "Content-Type: application/json" \
    -H "X-Store-Slug: my-store-abc123" \
    -H "X-Environment: test" \
    -d '{
      "checkoutSessionId": "cs_550e8400-e29b-41d4-a716-446655440000",
      "buyerIdentity": "customer@example.com"
    }'
  ```

  ```bash wget theme={"system"}
  wget -qO- \
    --header="Content-Type: application/json" \
    --header="X-Store-Slug: my-store-abc123" \
    --header="X-Environment: test" \
    --post-data='{"checkoutSessionId":"cs_550e8400-e29b-41d4-a716-446655440000","buyerIdentity":"customer@example.com"}' \
    "https://api.waffo.ai/v1/actions/checkout/preview-trial"
  ```
</CodeGroup>

## 成功响应 (200) -- 有试用资格

```json theme={"system"}
{
  "data": {
    "isEligible": true,
    "trialDays": 14
  }
}
```

## 成功响应 (200) -- 无试用资格

```json theme={"system"}
{
  "data": {
    "isEligible": false,
    "trialDays": null
  }
}
```

### 响应字段

| 字段           | 类型             | 说明                      |
| ------------ | -------------- | ----------------------- |
| `isEligible` | boolean        | 是否有试用资格（无试用记录为 `true`）  |
| `trialDays`  | number \| null | 有资格时返回试用天数；无资格时为 `null` |

## 错误响应

> **重试策略**：4xx 一律不要重试 — 修正请求后重发。5xx 指数退避重试（起步 5s，最多 3 次）。

| 状态码 | `errors[0].message`                                    | 含义                            | 推荐处理                         |
| --- | ------------------------------------------------------ | ----------------------------- | ---------------------------- |
| 400 | `Invalid JSON body`                                    | 请求体不是合法 JSON                  | 修正请求体后重新提交                   |
| 400 | `Missing required field: checkoutSessionId`            | 未提供 `checkoutSessionId`       | 修正请求体后重新提交                   |
| 400 | `Session product type mismatch: expected subscription` | Session 是一次性产品创建的             | 创建订阅类型的 checkout session 再重试 |
| 401 | `Unauthorized`                                         | Store Slug 或 session token 无效 | 检查认证请求头                      |
| 404 | `Session not found`                                    | Checkout session 不存在或已过期      | 重新创建 checkout session 再重试    |
| 404 | `Session does not belong to this store`                | Session 属于其他门店                | 使用调用方门店的 session             |
| 500 | `Internal server error`                                | 服务端意外失败                       | 指数退避重试（起步 5s，最多 3 次）         |
