> ## 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.

# 更新 Webhook

> 更新 Webhook 的 URL、事件列表或 secret

更新现有 Webhook 的 URL、订阅事件或通道特定凭据。`channel` 与 `testMode` 字段不可变 —— 如需变更，请删除后重新添加。

```
POST /v1/actions/store/update-webhook
```

**认证方式：** API Key（需要 owner 或 admin 角色）

## 请求体

| 字段       | 类型             | 必需 | 说明                                                                |
| -------- | -------------- | -- | ----------------------------------------------------------------- |
| `id`     | string         | 是  | Webhook UUID（来自 `add-webhook` 返回值或 GraphQL `Store.storeWebhooks`） |
| `url`    | string         | 否  | 替换目标 URL。                                                         |
| `events` | string\[]      | 否  | 替换订阅的事件类型                                                         |
| `secret` | string \| null | 否  | 替换通道特定凭据。传入 `null` 清空。                                            |

<Note>
  `channel` 在 Webhook 记录创建后即固定 —— 如需切换通道，请删除后重新添加。URL 变更会原样接受；商户需自行确保新 URL 与通道匹配。
</Note>

## 请求示例

<CodeGroup>
  ```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!,
  });

  // 为已有 Webhook 增加更多事件
  await client.webhooks.update({
    id: "11111111-2222-3333-4444-555555555555",
    events: ["order.completed", "refund.succeeded", "subscription.canceled"],
  });
  ```

  ```bash cURL theme={"system"}
  curl -X POST https://api.waffo.com/v1/actions/store/update-webhook \
    -H "Content-Type: application/json" \
    -H "X-Merchant-Id: $WAFFO_MERCHANT_ID" \
    -H "X-Signature: ..." \
    -d '{
      "id": "11111111-2222-3333-4444-555555555555",
      "events": ["order.completed", "refund.succeeded"]
    }'
  ```
</CodeGroup>

## 成功响应 (200)

返回更新后的 Webhook 实体。结构与 [`add-webhook`](/zh/api-reference/endpoints/webhooks/add-webhook#成功响应-200) 相同。

## 响应字段

| 字段          | 类型             | 说明                                  |
| ----------- | -------------- | ----------------------------------- |
| `id`        | string         | Webhook UUID                        |
| `storeId`   | string         | 所属门店的 UUID                          |
| `channel`   | string         | Webhook 通道（不可变）                     |
| `url`       | string         | 目标 Webhook URL                      |
| `events`    | string\[]      | 订阅的事件类型                             |
| `testMode`  | boolean        | `true` 对测试交易触发，`false` 对生产交易触发（不可变） |
| `secret`    | string \| null | 通道特定凭据，已清空时为 `null`                 |
| `createdAt` | string         | 创建时间戳（ISO 8601）                     |
| `updatedAt` | string         | 最后更新时间戳（ISO 8601）                   |

## 错误响应

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

| 状态码 | `errors[0].message`                                | 含义                                         | 推荐处理                                         |
| --- | -------------------------------------------------- | ------------------------------------------ | -------------------------------------------- |
| 400 | `Missing required field: id`                       | 未提供 `id`                                   | 修正请求体后重发                                     |
| 400 | `id must be a valid UUID`                          | `id` 不是合法 UUID                             | 修正 `id` 后重发                                  |
| 400 | `Invalid URL format`                               | `url` 无法解析为合法 URL                          | 修正 URL 格式（HTTPS、合法 URL）后重发                   |
| 400 | `events must be a string array`                    | `events` 不是字符串 JSON 数组                     | 以字符串数组形式发送 `events`（如 `["order.completed"]`） |
| 400 | `secret must be a string or null`                  | `secret` 既不是 string 也不是 `null`             | 发送字符串值，或 `null` 表示清空                         |
| 403 | `Not authorized to manage webhooks for this store` | 调用方在所属门店上的 merchant 角色不是 `owner` 或 `admin` | 换用拥有所需角色的 API Key                            |
| 404 | `Webhook not found`                                | 指定 `id` 的 webhook 不存在（或被并发请求删除）            | 先验证 `id`；若刚被移除，重新拉取 webhook 列表后再决定           |
| 500 | `Internal server error`                            | 服务端意外失败                                    | 指数退避重试（起步 5s，最多 3 次）                         |
