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

# 沙箱模拟器

> 在沙箱环境中使用模拟器以模拟各种支付场景的说明。

沙盒环境不连接真实支付渠道，而是通过模拟器让你直接控制支付结果，快速验证集成逻辑。

## 一次性支付模拟

<Steps>
  <Step title="创建订单">
    调用 `POST /api/v1/order/create` 创建订单。
  </Step>

  <Step title="获取收银台 URL">
    从响应的 `orderAction` 中获取收银台 URL。
  </Step>

  <Step title="打开收银台页面">
    在浏览器打开收银台页面，页面上会显示模拟按钮。
  </Step>

  <Step title="选择支付结果">
    点击对应按钮模拟支付结果：

    * **Payment succeeded** — 模拟用户完成支付，订单状态变为 `PAY_SUCCESS`
    * **Payment failed** — 模拟支付被拒绝，订单状态变为 `ORDER_CLOSE`

    点击后 Waffo 会自动向 `notifyUrl` 发送 `PAYMENT_NOTIFICATION` Webhook。
  </Step>
</Steps>

<Frame>
  <img src="https://mintcdn.com/waffo-docs/Pi4mlrktV3FjQDJZ/images/developer-docs/sandbox-simulator/payment-simulator.png?fit=max&auto=format&n=Pi4mlrktV3FjQDJZ&q=85&s=e7e32c7af13835c81798f8c66a5e7b96" alt="沙盒支付模拟器界面" width="1110" height="1878" data-path="images/developer-docs/sandbox-simulator/payment-simulator.png" />
</Frame>

<Note>
  沙盒收银台是模拟器界面，不会出现真实的支付方式选择或卡号输入。所有支付方式的模拟流程相同。
</Note>

如果需要模拟真实的卡号输入流程（如测试 3DS），可以使用测试卡号（见下方[测试卡号](#测试卡号)），但大部分场景直接使用模拟按钮即可。

## 订阅模拟

### 首期支付

与一次性支付相同：

<Steps>
  <Step title="创建订阅">
    调用 `POST /api/v1/subscription/create` 创建订阅。
  </Step>

  <Step title="打开收银台页面">
    从响应中获取收银台 URL 并在浏览器打开。
  </Step>

  <Step title="模拟首期支付">
    点击**支付成功**或**支付失败**按钮。首期成功后，订阅状态变为 `ACTIVE`，触发 `SUBSCRIPTION_STATUS_NOTIFICATION`。
  </Step>
</Steps>

### 模拟下期续费

订阅激活后，如果要快速测试续费（不等待真实周期到期）：

<Steps>
  <Step title="获取管理页 URL">
    调用 `POST /api/v1/subscription/manage` 获取管理页 URL。

    <CodeGroup>
      ```json 请求 theme={null}
      {
        "subscriptionId": "SUB20260325000001"
      }
      ```

      ```json 响应 theme={null}
      {
        "code": "0",
        "msg": "Success",
        "data": {
          "managementUrl": "https://cashier.waffo.com/subscription/manage?token=xxx",
          "expiredAt": "2026-03-25T11:00:00.000Z"
        }
      }
      ```
    </CodeGroup>
  </Step>

  <Step title="打开管理页">
    在浏览器打开 `managementUrl`。
  </Step>

  <Step title="模拟续费结果">
    管理页上会显示两个模拟按钮：

    * **模拟下期支付成功** — 触发续费成功，发送 `PAYMENT_NOTIFICATION` 和 `SUBSCRIPTION_PERIOD_CHANGED_NOTIFICATION`
    * **模拟下期支付失败** — 触发续费失败，发送 `PAYMENT_NOTIFICATION`（失败）
  </Step>
</Steps>

<Note>
  每次点击模拟一期续费。可以多次点击测试多期场景（如第 2 期成功、第 3 期失败等）。
</Note>

订阅续费管理页示例：

<Frame>
  <img src="https://mintcdn.com/waffo-docs/rmCSHSqVvv7UyIAx/images/developer-docs/sandbox-simulator/subscription-renewal-simulator.png?fit=max&auto=format&n=rmCSHSqVvv7UyIAx&q=85&s=a488ab3312d460a3c15fecd695d2dae8" alt="订阅续费模拟管理页示例" width="599" height="1065" data-path="images/developer-docs/sandbox-simulator/subscription-renewal-simulator.png" />
</Frame>

### 模拟订阅取消

在管理页上也可以执行用户侧取消操作，触发 `SUBSCRIPTION_STATUS_NOTIFICATION`（状态变为 `USER_CANCELLED`）。

## 特殊金额触发异常

<Warning>
  以下金额仅用于沙盒验收和异常处理测试。如果你在沙盒环境中传入这些金额，Waffo 会按预设返回对应错误码。这不是生产环境规则。
</Warning>

以下金额来自当前验收用例模板，可用于快速复现指定异常：

| 场景                           | 示例金额                             | 预期结果                              |
| ---------------------------- | -------------------------------- | --------------------------------- |
| 一次性支付创单渠道拒绝                  | `90`、`990`、`1990`、`19990`        | `C0005 Payment Channel Rejection` |
| 订阅创单渠道拒绝                     | `90`、`990`、`1990`、`19990`        | `C0005 Payment Channel Rejection` |
| 创单系统不可用（一次性支付 / 订阅）          | `9.1`、`91`、`991`、`1991`、`19991`  | `C0001 System Error`              |
| 创单 Unknown 状态（一次性支付 / 订阅）    | `9.2`、`92`、`992`、`1992`、`19992`  | `E0001 Unknown Status`            |
| 取消接口系统不可用（订单取消 / 订阅取消）       | `9.3`、`93`、`993`、`1993`、`19993`  | `C0001 System Error`              |
| 取消接口 Unknown 状态（订单取消 / 订阅取消） | `9.4`、`94`、`994`、`1994`、`19994`  | `E0001 Unknown Status`            |
| 退款接口系统不可用                    | `9.5`、`95`、`995`、`1995`、`19995`  | `C0001 System Error`              |
| 退款接口 Unknown 状态              | `9.6`、`96`、`996`、`1996`、`199996` | `E0001 Unknown Status`            |

* 如果你只想走正常成功 / 失败链路，请避开上述金额。
* 幂等错误 `A0011` 不是特殊金额触发，而是同一请求 ID 搭配不同金额或币种触发。
* 退款参数校验失败 `A0003` 不是特殊金额触发，而是退款金额超过原支付金额触发。

## 测试卡号

### 信用卡（Credit Card）

| payMethodName  | 成功卡号               | 失败卡号               |
| -------------- | ------------------ | ------------------ |
| CC\_VISA       | `4576750000000110` | `4576750000000220` |
| CC\_MASTERCARD | `2226900000000110` | `2226900000000220` |
| CC\_JCB        | `3528000000000440` | `3528000000000660` |
| CC\_AMEX       | `3799960000000110` | `3799960000000220` |

### 借记卡（Debit Card）

| payMethodName  | 成功卡号               | 失败卡号               |
| -------------- | ------------------ | ------------------ |
| DC\_VISA       | `4001700000000110` | `4001700000000220` |
| DC\_MASTERCARD | `2226930000000110` | `2226930000000220` |
| DC\_JCB        | `3088200000000440` | `3088200000000660` |
| DC\_AMEX       | `3421560000000110` | `3421560000000220` |

### 通用信息

* 有效期：任意未来日期
* CVV：任意 3 位数字（AMEX 为 4 位）

## 沙箱环境信息

| 项目       | 值                               |
| -------- | ------------------------------- |
| Base URL | `https://api-sandbox.waffo.com` |
| SDK 配置   | `Environment.SANDBOX`           |

<Warning>
  沙箱环境使用与生产环境不同的 API Key 和 RSA 密钥对。请勿混用。
</Warning>
