mcpField
C
chargebee-webhooks

chargebee-webhooks

github.com/hookdeck开发95195 次安装今天更新
代码仓库

关于 chargebee-webhooks

chargebee-webhooks 面向实现和排查 Chargebee Webhook 处理程序的开发者,介绍 Basic Auth 验证、事件负载和订阅计费事件,并提供 Express.js、Next.js 与 FastAPI 示例。

主要功能

  1. 01Basic Auth 验证指南
  2. 02Chargebee 事件类型参考
  3. 03订阅计费事件处理
  4. 04Express.js、Next.js 和 FastAPI 示例
  5. 05使用 Hookdeck CLI 本地测试

适用场景

  1. 01实现 Chargebee Webhook 端点
  2. 02排查 Basic Auth 验证失败
  3. 03处理订阅和付款事件

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/hookdeck/webhook-skills --skill chargebee-webhooks

安装后在 Claude Code 中输入/chargebee-webhooks确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

TODO.md
examples/express/
.env.example
jest.config.js
package.json
README.md
examples/express/src/
index.js
examples/express/test/
webhook.test.js
examples/fastapi/
.env.example
main.py
README.md
requirements.txt
test_webhook.py
examples/nextjs/
.env.example
next.config.js
package.json
README.md
tsconfig.json
vitest.config.ts
examples/nextjs/app/
layout.tsx
page.tsx
examples/nextjs/app/webhooks/chargebee/
route.ts
examples/nextjs/test/
webhook.test.ts
references/
overview.md
setup.md
verification.md

详细介绍

Chargebee Webhook

何时使用此技能

  • 设置 Chargebee webhook 处理程序
  • 调试 Basic Auth 验证失败问题
  • 了解 Chargebee 事件类型和负载
  • 处理订阅账单事件

核心代码

Chargebee 使用 Basic Authentication 验证 webhook。以下是实现方法:

Express.js
// Verify Chargebee webhook with Basic Auth
// NOTE: Chargebee uses Basic Auth (not HMAC signatures), so raw body access
// is not required. Use express.json() for automatic JSON parsing:
app.post('/webhooks/chargebee', express.json(), (req, res) => {
  // Extract Basic Auth credentials
  const auth = req.headers.authorization;
  if (!auth || !auth.startsWith('Basic ')) {
    return res.status(401).send('Unauthorized');
  }

  // Decode and verify credentials
  const encoded = auth.substring(6);
  const decoded = Buffer.from(encoded, 'base64').toString('utf-8');
  const [username, password] = decoded.split(':');

  const expectedUsername = process.env.CHARGEBEE_WEBHOOK_USERNAME;
  const expectedPassword = process.env.CHARGEBEE_WEBHOOK_PASSWORD;

  if (username !== expectedUsername || password !== expectedPassword) {
    return res.status(401).send('Invalid credentials');
  }

  // Access the parsed JSON directly
  const event = req.body;
  console.log(`Received ${event.event_type} event:`, event.id);

  // Handle specific event types
  switch (event.event_type) {
    case 'subscription_created':
    case 'subscription_changed':
    case 'subscription_cancelled':
      // Process subscription events
      break;
    case 'payment_succeeded':
    case 'payment_failed':
      // Process payment events
      break;
  }

  res.status(200).send('OK');
});

// Note: If you later need raw body access (e.g., for HMAC signature
// verification with other providers), use express.raw():
// app.post('/webhooks/other', express.raw({ type: 'application/json' }), (req, res) => {
//   const rawBody = req.body.toString();
//   // ... verify signature using rawBody ...
// });
Next.js (App Router)
// app/webhooks/chargebee/route.ts
import { NextRequest } from 'next/server';

export async function POST(req: NextRequest) {
  // Extract Basic Auth credentials
  const auth = req.headers.get('authorization');
  if (!auth || !auth.startsWith('Basic ')) {
    return new Response('Unauthorized', { status: 401 });
  }

  // Decode and verify credentials
  const encoded = auth.substring(6);
  const decoded = Buffer.from(encoded, 'base64').toString('utf-8');
  const [username, password] = decoded.split(':');

  const expectedUsername = process.env.CHARGEBEE_WEBHOOK_USERNAME;
  const expectedPassword = process.env.CHARGEBEE_WEBHOOK_PASSWORD;

  if (username !== expectedUsername || password !== expectedPassword) {
    return new Response('Invalid credentials', { status: 401 });
  }

  // Process the webhook
  const event = await req.json();
  console.log(`Received ${event.event_type} event:`, event.id);

  return new Response('OK', { status: 200 });
}
FastAPI
# main.py
from fastapi import FastAPI, Header, HTTPException, Depends
from typing import Optional
import base64
import os

app = FastAPI()

def verify_chargebee_auth(authorization: Optional[str] = Header(None)):
    """Verify Chargebee webhook Basic Auth"""
    if not authorization or not authorization.startswith("Basic "):
        raise HTTPException(status_code=401, detail="Unauthorized")

    # Decode credentials
    encoded = authorization[6:]
    decoded = base64.b64decode(encoded).decode('utf-8')

    # Split username:password (handle colons in password)
    if ':' not in decoded:
        raise HTTPException(status_code=401, detail="Invalid authorization format")

    colon_index = decoded.index(':')
    username = decoded[:colon_index]
    password = decoded[colon_index + 1:]

    expected_username = os.getenv("CHARGEBEE_WEBHOOK_USERNAME")
    expected_password = os.getenv("CHARGEBEE_WEBHOOK_PASSWORD")

    if username != expected_username or password != expected_password:
        raise HTTPException(status_code=401, detail="Invalid credentials")

    return True

@app.post("/webhooks/chargebee")
async def handle_chargebee_webhook(
    event: dict,
    auth_valid: bool = Depends(verify_chargebee_auth)
):
    """Handle Chargebee webhook events"""
    event_type = event.get("event_type")
    print(f"Received {event_type} event: {event.get('id')}")

    # Process event based on type
    if event_type in ["subscription_created", "subscription_changed", "subscription_cancelled"]:
        # Handle subscription events
        pass
    elif event_type in ["payment_succeeded", "payment_failed"]:
        # Handle payment events
        pass

    return {"status": "OK"}

常见事件类型

⚠️ 警告:请核实事件名称!

以下事件类型名称仅为示例,必须根据你的 Chargebee 配置,参照 Chargebee API 文档进行核实。事件名称可能因 API 版本和配置而有显著差异。

请特别注意:

  • 支付事件(下方示例为 payment_succeeded 和 payment_failed)
  • 发票事件(下方示例为 invoice_generated)
  • 任何针对你的 Chargebee 设置的自定义事件

请务必检查 Chargebee Webhook 设置,确认账户使用的准确事件名称。

事件触发时机常见用例
subscription_created创建新订阅时开通访问权限,发送欢迎邮件
subscription_changed修改订阅时更新用户权限,同步变更
subscription_cancelled取消订阅时撤销访问权限,触发留存流程
subscription_reactivated重新激活已取消的订阅时恢复访问权限,发送通知
payment_succeeded成功处理付款时更新付款状态,发送收据
payment_failed付款尝试失败时重试付款,通知客户
invoice_generated创建发票时向客户发送发票
customer_created创建新客户时创建用户账户,同步数据

环境变量

# Chargebee webhook Basic Auth credentials
CHARGEBEE_WEBHOOK_USERNAME=your_webhook_username
CHARGEBEE_WEBHOOK_PASSWORD=your_webhook_password

本地开发

如需在本地测试 webhook,请使用 Hookdeck CLI:

npx hookdeck-cli listen 3000 chargebee --path /webhooks/chargebee

无需账户。提供本地隧道和 Web UI,可用于检查请求。

参考资料

  • 概述 - 介绍 Chargebee webhook 和常见事件类型
  • 设置 - 在 Chargebee 控制面板中配置 webhook
  • 验证 - Basic Auth 验证详情和注意事项

示例

推荐:webhook-handler-patterns

我们建议同时安装 webhook-handler-patterns 技能,以了解处理程序顺序、幂等性、错误处理和重试逻辑。主要参考资料(在 GitHub 上查看):

相关技能

评论

支持 Markdown