Next.jsでは、リクエストBodyを処理しやすい形に内部で事前処理されます。
そのため、Stripe WebhookのAPIを実装するには、すこし設定作業が必要でした。
import Stripe from 'stripe'
+import {buffer} from 'micro'
const endpointSecret = 'whsec_xxxxxx'
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, {
apiVersion: '2020-08-27'
})
+export const config = {
+ api: {
+ bodyParser: false
+ }
+}
export default async function handler(
request,
response
) {
const sig = request.headers['stripe-signature'];
+ const buf = await buffer(request)
let event;
try {
if (!sig) throw new Error("No signature provided")
event = stripe.webhooks.constructEvent(buf, sig, endpointSecret);
} catch (e) {
const err = e instanceof Error ? e : new Error("Bad Request")
console.log(err)
response.status(400).send(`Webhook Error: ${err.message}`);
return;
}
console.log(event)
return response.status(200).end()
}
こちらの詳細については、以下の記事をご覧ください。
Next.js(version 13)から追加された「App Router」で、Stripe Webhook APIを作成する
Next.jsで新しく追加された「App Router」では、ディレクトリ構造を含めて様々な変更が行われました。
Stripe Webhookを処理するAPIを作る場合も、コードの書き方が変わります。
app/api/webhook/route.ts
import { NextResponse } from "next/server";
import Stripe from "stripe";
const stripe = new Stripe(process.env.STRIPE_SECRET_API_KEY as string, {
apiVersion: '2022-11-15'
})
export async function POST(request: Request) {
const signature = request.headers.get("stripe-signature");
if (!signature) {
return NextResponse.json({
message: 'Bad request'
}, {
status: 400
})
}
try {
const body = await request.arrayBuffer();
const event = stripe.webhooks.constructEvent(
Buffer.from(body),
signature,
process.env.STRIPE_WEBHOOK_SECRET as string
);
console.log({
type: event.type,
id: event.id,
})
return NextResponse.json({
message: `Hello Stripe webhook!`
});
} catch (err) {
const errorMessage = `⚠️ Webhook signature verification failed. ${(err as Error).message}`
console.log(errorMessage);
return new Response(errorMessage, {
status: 400
})
}
}
Astroと書き方が似ていますが、環境変数の取得方法やレスポンスのフォーマットが異なる点に注意しましょう。
参考資料など