🐥

"Webhook payload must be provided as a string or a Buffer" (Stripe)

2023/08/14に公開

はじめに

たいしたエラーじゃないですが、検索した際に日本語記事がなかったので、他の人の役に立つこともあるかなと、一応作っておきました。

とはいえ、Expressを使っている人、そのほかフレームワークで入力値に自動フィルタをかけてる人など、かなり限定的な話題ですが。

エラー内容

StripeでWebhookをテストしていたら以下のエラーが出ました。

Webhook payload must be provided as a string or a Buffer (https://nodejs.org/api/buffer.html) instance representing the raw request body.Payload was provided as a parsed JavaScript object instead.
Signature verification is impossible without access to the original signed material.
Learn more about webhook signing and explore webhook integration examples for various frameworks at https://github.com/stripe/stripe-node#webhook-signing

let event;
try {
  event = stripe.webhooks.constructEvent(
    req.body,
    sig,
    process.env.STRIPE_WEBHOOK_SECRET
  );
} catch (err) {
 console.log(err.message);
  res.status(400).send(`Webhook Error: ${err.message}`);
  return;
 }

発生箇所は上記です。

原因

app.use(express.json());
app.use("/webhook", WebhookRouter);

express.json()の影響でした。
シグネチャチェックに使うパラメタにフィルタがかかるのが原因でした。

対策

app.use("/webhook", WebhookRouter);
app.use(express.json());

こちらで解決しました。

他にも試してませんが、フィルタがかかった値をtoString()するなどいくつか方法はあるみたいですが、webhookは独立させているので上記が一番シンプルな対応な気がします。

参考

Stripe - Webhook payload must be provided as a string or a Buffer
Webhook signature verification and bodyParser.json

Discussion