@hibiki-js/stripe
Hibiki 向けの公式 Stripe Webhook プロバイダーです。Stripe-Signature を Web Crypto で検証し、よく使うイベントを型付きで公開します。Stripe Node SDK には依存しません。
インストール
pnpm add @hibiki-js/core @hibiki-js/stripe短い例
import { Hibiki } from "@hibiki-js/core"
import { stripe } from "@hibiki-js/stripe"
const app = new Hibiki().use(stripe({
secret: process.env.STRIPE_WEBHOOK_SECRET!,
tolerance: 300,
}))
app.on("stripe.checkout.session.completed", async ({ event }) => {
console.log(event.id, event.data.object.id)
})
export async function POST(request: Request) {
return app.handle(request, { provider: "stripe" })
}ハンドラは stripe. プレフィックスを使います。Stripe 側の型名(checkout.session.completed)は stripe.checkout.session.completed になります。
stripe(options)
import { stripe } from "@hibiki-js/stripe"
const provider = stripe({
secret: string,
tolerance?: number, // 秒。デフォルト 300
})戻り値は HibikiProvider<"stripe", StripeEvents> です。
| オプション | 型 | デフォルト | 説明 |
|---|---|---|---|
secret | string | — | Stripe Dashboard の Webhook 署名シークレット(whsec_...) |
tolerance | number | 300 | 署名タイムスタンプの許容秒数 |
検証
Stripe-Signatureヘッダー(t=…,v1=…)を読む- 欠落・不正なヘッダー、数値でない timestamp を拒否する
toleranceより古い timestamp を拒否する- Webhook シークレットで
`${t}.${rawBody}`の HMAC-SHA256 を検証する
失敗時は HIBIKI_VERIFICATION_FAILED(400)の HibikiError です。hex の解釈ミスやシークレット誤りも同じ経路で、応答に暗号の詳細は出しません。
パース
Body は Stripe イベント封筒の JSON である必要があります。対応する type は型付きイベントとして振り分け、それ以外は { kind: "unsupported" } になり、既定では HTTP 200(strictEvents: true なら 400)です。
event.id がある場合は HibikiContext.id にコピーします。
署名付きイベントの送信
createStripeWebhook(url, { secret }) は、Stripe互換の署名を付けたJSONを任意のWebhook URLへ送信します。受信側に設定したものと同じ署名シークレットを指定してください。
import { createStripeWebhook } from "@hibiki-js/stripe"
const sender = createStripeWebhook(process.env.WEBHOOK_URL!, {
secret: process.env.WEBHOOK_SECRET!,
})
const response = await sender.send({
id: "evt_example",
type: "invoice.paid",
data: { object: { id: "in_example", object: "invoice" } },
})
if (!response.ok) throw new Error(`Webhook receiver returned ${response.status}`)send はJSON本文そのものにStripe形式の t=…,v1=… HMAC-SHA256署名を付け、受信側の Response を返します。署名時刻は現在のUnix時刻が使われます。{ timestamp } で上書きできます。この機能は任意URLにStripe互換リクエストを送るもので、Stripe上のイベント作成・配信は行いません。
イベントの形
対応する Stripe ハンドラが受け取るのは内側のオブジェクト単体ではなく、Stripe の封筒です。
{
id: string
type: "invoice.paid" // イベントごとのリテラル
data: { object: StripeInvoice /* など */ }
// ほかの Stripe フィールドは index signature
}このパッケージが export するオブジェクト型(StripeInvoice、StripeCharge など)は、必須の id / object とそれ以外の index signature だけの薄い型です。より詳しい型が必要なら Stripe 公式パッケージ側を使ってください。
export する型
| Export | 説明 |
|---|---|
stripe | プロバイダー工場関数 |
createStripeWebhook | 署名付きWebhook送信クライアントを作成 |
StripeEvents | 対応イベント名 → ペイロード型 |
StripeOptions | { secret; tolerance? } |
StripeWebhookEvent | 対応するStripeイベントpayloadのユニオン |
StripeWebhookSenderOptions | 送信シークレットと任意の fetch |
StripeWebhookSendOptions | 任意の署名時刻 |
StripeCheckoutSession | Checkout Session の data.object |
StripePaymentIntent | PaymentIntent |
StripeInvoice | Invoice |
StripeCustomer | Customer |
StripeSubscription | Subscription |
StripeCharge | Charge |
StripePaymentMethod | PaymentMethod |
StripeDispute | Dispute |
StripeRefund | Refund |
StripeSetupIntent | SetupIntent |
補足
- Stripe SDK 非依存。検証は
crypto.subtleのみ - このプロバイダーは Content-Type を制限しない(Stripe は JSON を送り、body は JSON テキストとしてパースする)
- 未対応の Stripe イベントは Core の
strictEventsが無い限り200で無視する - テストでは
@hibiki-js/testing(stripeRequest/createWebhookTest)で署名付きイベントを送る
関連
- Stripe プロバイダーガイド — 対応イベント一覧
- Next.js + Stripe / Hono + Stripe
- Core リファレンス —
handle・応答・エラー
本文サイズ制限、署名で確認したイベントID、共有保存先での重複防止、再試行時の動作はWebhookを安全に処理するを参照してください。
