---
title: "使用 Webhook 处理 Adapty 订阅事件"
description: "通过 Webhook 在服务器端接收并处理 Adapty 订阅事件——涵盖端点配置、身份验证、数据载荷及测试的完整指南。"
---

Webhooks 让您的服务器能够实时接收 Adapty 订阅事件——包括购买、续订、取消、账单问题和退款——从而授予访问权限、同步后端或触发工作流。本指南将带您在同一页面上完成从端点配置到验证、测试的完整集成流程，并介绍如何让 AI 编程助手为您的技术栈编写处理程序。

:::tip
正在使用 AI 编程助手？点击标题下方的 **Copy for LLM**，将整个页面粘贴到您的助手中——它包含所需的配置说明、数据载荷和处理逻辑。
:::
## Adapty Webhook 的工作原理 \{#how-adapty-webhooks-work\}

- **单向实时推送**：当事件发生时，Adapty 会向你的服务器发送 HTTP `POST` 请求，无需轮询。
- **两种请求类型**：一次性验证请求（在你保存集成时发送）和持续的订阅事件通知。
- **每个环境独立 URL**：你需要分别为生产环境和沙盒环境配置独立的接收端点。
- **需要应答每个请求**：请尽快以 `2xx` 状态码响应，否则 Adapty 会在失败时重试。
## 构建你的 Endpoint \{#build-your-endpoint\}

创建一个能处理以下两种请求类型的公开 HTTPS Endpoint：

- **验证请求**：在你保存集成时发送一次，请求体为空 JSON（`{}`）。请返回 `2xx` 状态码及 JSON 响应体。
- **订阅事件**：持续发来的 `POST` 请求，事件内容在请求体中。请在 10 秒内返回 `200`，然后以异步方式处理耗时操作。
选择一个密钥字符串并将其存储为环境变量（例如 `ADAPTY_WEBHOOK_SECRET`）。在每次请求时，验证 `Authorization` 请求头是否与其匹配，若不匹配则拒绝该请求——稍后你将在看板中输入相同的密钥。
```javascript title="webhook.js"

const app = express();
app.use(express.json());

const WEBHOOK_SECRET = process.env.ADAPTY_WEBHOOK_SECRET;

app.post("/adapty/webhook", (req, res) => {
  // 1. Verify the shared secret Adapty echoes back.
  if (req.get("Authorization") !== WEBHOOK_SECRET) {
    return res.sendStatus(401);
  }

  // 2. Acknowledge fast, then process asynchronously.
  res.status(200).json({});

  // 3. The verification request has an empty body — nothing to handle.
  const event = req.body;
  if (!event.event_type) return;

  switch (event.event_type) {
    case "subscription_started":
    case "subscription_renewed":
    case "trial_converted":
      // Grant or extend access.
      break;
    case "subscription_expired":
    case "subscription_refunded":
      // Revoke access.
      break;
    default:
      break;
  }
});

app.listen(3000);
```

在配置集成之前，请先将端点部署到公开的 HTTPS URL——Adapty 会在你保存的瞬间发送验证请求。
### 关键事件及其数据载荷 \{#key-events-and-the-payload\}

每个事件共享相同的外层结构。字段内容因事件类型、应用商店及所启用的选项而有所不同。以下是一个精简版的 `subscription_started` 事件示例：
```json title="Example event"
{
  "profile_id": "00000000-0000-0000-0000-000000000000",
  "customer_user_id": "UserIdInYourSystem",
  "event_type": "subscription_started",
  "event_datetime": "2024-11-15T10:45:36.181000+0000",
  "event_properties": {
    "store": "play_store",
    "currency": "USD",
    "price_usd": 4.99,
    "vendor_product_id": "onemonth_no_trial",
    "transaction_id": "0000000000000000",
    "original_transaction_id": "0000000000000000",
    "subscription_expires_at": "2024-12-15T10:45:36.181000+0000",
    "profile_event_id": "00000000-0000-0000-0000-000000000000"
  },
  "event_api_version": 1
}
```

最常处理的事件：
| 事件类型 | 触发时机 |
| --- | --- |
| `subscription_started` | 用户开始付费订阅 |
| `subscription_renewed` | 订阅成功续期并完成扣款 |
| `subscription_renewal_cancelled` | 用户关闭自动续订（访问权限持续至到期） |
| `subscription_expired` | 订阅未续期到期后访问权限终止 |
| `trial_started` | 用户开始免费试用 |
| `trial_converted` | 试用转换为付费订阅 |
| `billing_issue_detected` | 续订付款失败 |
| `subscription_refunded` | 订阅购买被退款 |
完整的事件列表及每个字段的详细说明，请参阅 [Webhook 事件类型与字段](https://adapty.io/docs/zh/webhook-event-types-and-fields.md)。

:::warning
不要按 `event_datetime` 对事件排序——该字段表示事件的业务发生时间，事件可能乱序到达，也可能具有相同的时间戳。请按自己的接收时间排序，并使用 `profile_event_id` 或事务 ID 进行去重。
:::
## 在 Adapty 中配置 Webhook \{#configure-the-webhook-in-adapty\}
1. 在 Adapty 看板中打开 [Integrations → Webhook](https://app.adapty.io/integrations/customwebhook)。
2. 开启该集成。
3. 在 **Production endpoint URL** 中，输入你部署的端点的 HTTPS URL。
4. 在 **Authorization header value for production endpoint** 中，输入与端点校验逻辑相同的密钥。Adapty 会在每次请求时通过 `Authorization` 请求头将该值回传给你的端点。此项为可选，但强烈建议填写。
5. 如需先在沙盒环境中测试，同样填写 **Sandbox endpoint URL** 及其 **Authorization header value**。
6. 点击 **Save**。Adapty 会立即向你的端点发送验证请求，端点返回 `2xx` 响应后即完成配置。
要选择发送哪些事件、映射事件名称，或启用可选字段（试用价格、历史事件、归因、用户属性、Play Store token），请参阅[设置 Webhook 集成](https://adapty.io/docs/zh/set-up-webhook-integration.md)。

## 用 AI 编程助手来构建 \{#build-it-with-your-ai-coding-agent\}

将本指南和以下参考文档以 Markdown 格式提供给你的 AI 编程助手（在任意页面 URL 后加 `.md` 即可获取），告诉它你的技术栈，让它自动生成处理程序：

- [Webhook 事件类型与字段](https://adapty.io/docs/zh/webhook-event-types-and-fields.md)
- [配置 Webhook 集成](https://adapty.io/docs/zh/set-up-webhook-integration.md)

示例提示词：
```
Read these Adapty webhook docs, then write a webhook handler for my Express app:
verify the Authorization header against ADAPTY_WEBHOOK_SECRET, answer the
verification request, acknowledge events with 200, and grant or revoke access
based on event_type.
```

代理会编写处理程序代码，但无法部署你的端点或配置看板——请自行托管端点，并在 **Integrations → Webhook** 中设置 URL 和密钥。
## 测试您的 Webhook \{#test-your-webhook\}

在正式上线前，请先在沙盒环境中进行测试：

1. 按照上述说明配置沙盒端点和密钥。
2. 在沙盒应用中完成购买、开启试用或申请退款，以触发相应事件。
3. 打开集成页面的 **Last sent events** 部分。已成功投递的事件会显示 **Success** 状态。

如果事件显示 **Sending failed**，说明您的服务器返回了 200–399 范围之外的状态码——将鼠标悬停在状态上可查看详情。完整的测试流程，请参阅[测试 Webhook 集成](https://adapty.io/docs/zh/test-webhook.md)。

## 限制 \{#limits\}

- **10 秒内响应**：如果 Adapty 未能在规定时间内收到响应，会将本次尝试标记为失败并重新发送。
- **重试机制**：如果您返回的状态码不在 200–404 范围内，Adapty 会以指数退避策略进行重试——在 24 小时内最多重试 9 次。
- **取消延迟**：取消事件最多可能延迟 2 小时送达。
- **每个环境仅支持一个 URL**：如需将事件推送至多个服务，请将 Webhook 指向您自己的后端，再由后端进行分发。