Webhook


Webhook 是与 PaymentKit 构建可靠且可扩展集成的重要机制。与其持续轮询 API 以获取状态变更,您可以配置一个 Webhook 端点,当您账户中发生某些事件时,PaymentKit 将会向您指定的 URL 发送实时的 HTTP POST 通知。

这是处理异步事件(如成功支付、订阅更新或完成结账)的推荐方式。通过使用 Webhook,您可以自动化后端流程,例如履行订单、授予服务访问权限或更新客户记录。

有关所有 Webhook 管理方法的详细列表,请参阅 Webhook 端点 API 参考

Webhook 工作原理#

过程非常简单:

  1. 事件发生:您的 PaymentKit 账户中发生了一个操作,例如创建了订阅或支付成功。这会生成一个事件对象。
  2. 发送通知:PaymentKit 向您注册的 Webhook 端点 URL 发送一个包含 JSON 格式事件对象的 POST 请求。
  3. 您的服务器响应:您的服务器接收到请求后,应立即返回一个 200 OK 状态码以确认接收。任何其他状态码都表示失败,PaymentKit 可能会尝试重新发送该事件。
  4. 处理事件:发送成功响应后,您的服务器可以安全地处理事件的有效负载以执行业务逻辑,例如更新数据库或向客户发送电子邮件。

Webhooks

创建 Webhook 端点#

要开始接收事件,您必须注册一个 Webhook 端点。这包括提供您服务器的 URL 并指定您想要订阅的事件类型。

创建 Webhook 端点

import payment from '@blocklet/payment-js';

async function setupWebhook() {
  try {
    const webhookEndpoint = await payment.webhookEndpoints.create({
      url: 'https://example.com/webhook',
      enabled_events: [
        'checkout.session.completed',
        'customer.subscription.created',
        'customer.subscription.updated',
        'customer.subscription.deleted',
        'payment_intent.succeeded',
      ],
    });
    console.log('Webhook endpoint created:', webhookEndpoint.id);
    return webhookEndpoint;
  } catch (error) {
    console.error('Error creating webhook endpoint:', error.message);
  }
}

setupWebhook();

参数

Name

Type

Description

url

string

您的服务器上用于接收 Webhook POST 请求的端点 URL。

enabled_events

string[]

您想要订阅的事件类型字符串数组。使用 ['*'] 以接收所有事件类型。

响应示例

{
  "id": "wh_xxxxxxxxxxxxxx",
  "url": "https://example.com/webhook",
  "enabled_events": [
    "checkout.session.completed",
    "customer.subscription.created"
  ],
  "created_at": "2023-10-27T10:00:00.000Z",
  "updated_at": "2023-10-27T10:00:00.000Z"
}

处理传入事件#

您的 Webhook 处理程序应准备好接收带有 JSON 主体的 POST 请求。以下是使用 Express.js 的基本示例,以说明如何解析和处理传入事件。

Express.js Webhook 处理程序

const express = require('express');
const app = express();

// 使用原始 body 解析器来验证签名非常重要
app.post('/webhook', express.json({ type: 'application/json' }), (request, response) => {
  const event = request.body;

  // 根据事件类型处理事件
  switch (event.type) {
    case 'payment_intent.succeeded':
      const paymentIntent = event.data.object;
      console.log('Payment was successful for:', paymentIntent.amount);
      // TODO: 完成购买
      break;
    case 'customer.subscription.created':
      const subscription = event.data.object;
      console.log('New subscription started:', subscription.id);
      // TODO: 为客户配置服务
      break;
    default:
      console.log(`Unhandled event type: ${event.type}`);
  }

  // 确认收到事件
  response.status(200).send();

See all 3 lines

最佳实践#

  • 快速响应:尽快返回 2xx 状态码以确认事件。在后台作业中执行复杂逻辑以避免超时。
  • 处理幂等性:Webhook 可能会被多次传递。设计您的事件处理逻辑以实现幂等性,以防止重复操作(例如,在再次处理订单之前检查该订单是否已经完成)。
  • 验证签名:为安全起见,验证传入的 Webhook 请求是否源自 PaymentKit 至关重要。每个 Webhook 事件的头部都包含一个签名,您可以使用端点的密钥来验证该签名。

管理 Webhook 端点#

您还可以使用 SDK 以编程方式管理您的端点。

  • 检索端点:获取特定端点的详细信息。
    const webhook = await payment.webhookEndpoints.retrieve('wh_xxx');
  • 更新端点:更改 URL 或已启用事件的列表。
    const updatedWebhook = await payment.webhookEndpoints.update('wh_xxx', {
      url: 'https://new.example.com/webhook',
      enabled_events: ['checkout.session.completed'],
    });
  • 列出端点:检索所有 Webhook 端点的分页列表。
    const webhookList = await payment.webhookEndpoints.list({ pageSize: 10 });
  • 删除端点:永久移除一个 Webhook 端点。
    await payment.webhookEndpoints.del('wh_xxx');