Skip to content

@hibiki-js/stripe ​

Hibiki 向けの公式 Stripe Webhook プロバイダーです。Stripe-Signature を Web Crypto で検証し、よく使うイベントを型付きで公開します。Stripe Node SDK には依存しません。

インストール ​

bash
pnpm add @hibiki-js/core @hibiki-js/stripe

短い例 ​

ts
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) ​

ts
import { stripe } from "@hibiki-js/stripe"

const provider = stripe({
  secret: string,
  tolerance?: number, // 秒。デフォルト 300
})

戻り値は HibikiProvider<"stripe", StripeEvents> です。

オプション型デフォルト説明
secretstring—Stripe Dashboard の Webhook 署名シークレット(whsec_...)
tolerancenumber300署名タイムスタンプの許容秒数

検証 ​

  1. Stripe-Signature ヘッダー(t=…,v1=…)を読む
  2. 欠落・不正なヘッダー、数値でない timestamp を拒否する
  3. tolerance より古い timestamp を拒否する
  4. 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へ送信します。受信側に設定したものと同じ署名シークレットを指定してください。

ts
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 の封筒です。

ts
{
  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任意の署名時刻
StripeCheckoutSessionCheckout Session の data.object
StripePaymentIntentPaymentIntent
StripeInvoiceInvoice
StripeCustomerCustomer
StripeSubscriptionSubscription
StripeChargeCharge
StripePaymentMethodPaymentMethod
StripeDisputeDispute
StripeRefundRefund
StripeSetupIntentSetupIntent

補足 ​

  • Stripe SDK 非依存。検証は crypto.subtle のみ
  • このプロバイダーは Content-Type を制限しない(Stripe は JSON を送り、body は JSON テキストとしてパースする)
  • 未対応の Stripe イベントは Core の strictEvents が無い限り 200 で無視する
  • テストでは @hibiki-js/testing(stripeRequest / createWebhookTest)で署名付きイベントを送る

関連 ​

本文サイズ制限、署名で確認したイベントID、共有保存先での重複防止、再試行時の動作はWebhookを安全に処理するを参照してください。