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. 05Hookdeck CLIによるローカルテスト

活用シーン

  1. 01Chargebee Webhookエンドポイントの実装
  2. 02Basic 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 Webhooks

このスキルを使う場面

  • Chargebee の Webhook ハンドラーを設定するとき
  • Basic Auth の検証失敗をデバッグするとき
  • Chargebee のイベントタイプとペイロードを理解するとき
  • サブスクリプションの請求イベントを処理するとき

基本的なコード

Chargebee は Webhook の検証に Basic Authentication を使用します。実装方法は次のとおりです。

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 で開く):

関連するスキル

コメント