# 模拟退款

> 将沙箱账单退款推进至 completed、failed 或 cancelled 终态，并触发对应的签名 webhook。

`POST /v1/sandbox/refunds/:withdrawal_id/simulate`

:::endpoint
POST /v1/sandbox/refunds/:withdrawal_id/simulate
:::

**API 密钥：** `Payment`（沙箱）

仅限沙箱。将已创建的沙箱退款（`is_test: true`）推进至指定的终态（`completed`、`failed` 或 `cancelled`），更新沙箱账本余额，并发送带有完整退款负载的 `withdrawal.completed`、`withdrawal.failed` 或 `withdrawal.cancelled` webhook。

## 请求体

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `status` | string | 是 | 目标终态：`"completed"`、`"failed"` 或 `"cancelled"` |

```json
{
  "status": "completed"
}
```

## 响应（200 OK）

```json
{
  "withdrawal_id": "wdr_6Qm2fK8xR4vN7cT1bY9dL5",
  "invoice_id": "inv_7K2M9P4Q8R1X5Z3A0bC2dE",
  "mode": "full",
  "external_order_id": "refund-1042-full",
  "status": "completed",
  "is_final": true,
  "is_test": false,
  "amount": "100.00",
  "fee": "1.00",
  "currency": "USDT",
  "network": "TRC20",
  "destination_address": "TN3W4H6rK2ce4vX9YnFQHwKENnHjoxb3m9",
  "first_sender": "TN3W4H6rK2ce4vX9YnFQHwKENnHjoxb3m9",
  "tx_hash": "9f3b8c2a1d0e4f6789abc123def4567890abc123def4567890abc123def45678",
  "explorer_url": "https://tronscan.org/#/transaction/9f3b8c2a1d0e4f6789abc123def4567890abc123def4567890abc123def45678",
  "created_at": 1767225600,
  "completed_at": 1767225932,
  "type": "refund",
  "project_id": "prj_3F9xL2mN8pQ4rT6vW1yZ5b"
}
```

## 规则

:::dash-list
- 先使用沙箱 Payment 密钥（`pk_test_`）调用 [`POST /v1/refunds`](/zh-hans/docs/refunds/create.md) 创建沙箱退款，再将其 `withdrawal_id` 传入此端点。
- 对已处于目标终态的退款重复调用 `simulate` 是幂等的，返回 `200 OK` 且不会重复发送 webhook。
- 当退款已进入某一终态后，传入另一个不同的终态调用 `simulate` 会返回 `409 invalid_withdrawal_state`。
- 模拟 `"completed"` 会确认扣除已冻结余额并生成合成的 `tx_hash`。模拟 `"failed"` 或 `"cancelled"` 会将冻结的 `amount + fee` 解冻退回沙箱余额，之后可为该账单重新发起退款。
:::

## 错误码

| 错误码 | HTTP | 触发场景 |
|--------|------|----------|
| `payment_key_required` | 403 | 请求使用了 Payout（`rk_`）密钥签名 |
| `refunds_not_enabled` | 503 | 当前环境未启用账单退款功能 |
| `withdrawal_not_found` | 404 | 该 ID 不存在、不是沙箱退款，或不在当前密钥的项目可见范围内 |
| `invalid_withdrawal_state` | 409 | 退款已处于另一个不同的终态 |
| `field_invalid_enum` | 400 | `status` 不是 `"completed"`、`"failed"` 或 `"cancelled"` |

完整沙箱流程见[测试](/zh-hans/docs/testing.md)，完整错误目录见[错误码](/zh-hans/docs/errors/codes.md)。
