LoginSignup
6
1

Next.jsのApp RouterでStripeのWebhookイベントを処理するREST APIを作成する方法

Posted at

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と書き方が似ていますが、環境変数の取得方法やレスポンスのフォーマットが異なる点に注意しましょう。

参考資料など

6
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
1