为什么使用 Next JS 14 在 Stripe CLI 中出现 404 错误

问题描述 投票:0回答:1

我正在尝试将 Stripe 与我的 Next JS 项目集成。我已经设置了 Stripe CLI 在本地进行测试。我有一个付款链接,点击它并完成付款后,我将从 Stripe 行项目中打印一些数据。付款已完成,但在终端中我看到 POST 请求响应为 404。我不知道为什么我会弄错。我已经验证了我的所有密钥,这些密钥都是正确的并存储在 .env.local 文件中。

代码: 位置: /app/api/webhook.tsx

import Stripe from "stripe";
import getRawBody from "raw-body";
import { NextApiRequest, NextApiResponse } from "next";

const stripe = new Stripe(process.env['STRIPE_SECRET_KEY'] as string, {
    apiVersion: '2023-10-16'
});

const webhooksecret = process.env['STRIPE_WEBHOOK_SECRET'] as string

// add this line else there will be stream not readable error
export const dynamicParams = false;

export default async function StripeHandler(request: NextApiRequest, response: NextApiResponse) {
    try {
        // if not POST req -> return 405
        if(request.method !== 'POST') {
            return response.status(405).send('Only POST request allowed.');
        }

        const signature: any = request.headers['stripe-signature'];
        const rawBody = await getRawBody(request);

        let event;

        try {
            event = stripe.webhooks.constructEvent(rawBody, signature, webhooksecret);
        } catch (error: any) {
            return response.status(400).send(`Bad Request: ${error.message}`);
        }
        
        if(event.type === 'checkout.session.completed') {
            const sessionLineItems = await stripe.checkout.sessions.retrieve(
                (event.data.object as any).id,
                {
                    expand: ['line_items']
                }
            );

            const lineItems = sessionLineItems.line_items as any;

            if(!lineItems) {
                response.status(500).send("Internal Server Error.");
            }

            try {
                console.log(lineItems.data);
            } catch (error: any) {
                response.status(500).send("Order Not Saved.");
            }
        }
        response.status(200).end();
    } catch (error: any) {
        return 
    }
}

Stripe webhook命令:

stripe listen --forward-to localhost:3000/api/webhook

支付成功后CMD响应

2024-01-27 13:00:07   --> payment_intent.created [evt_3Od6L2SEPGwsgWeg1WWA5BWe]
2024-01-27 13:00:07   --> payment_intent.requires_action [evt_3Od6L2SEPGwsgWeg1xhLgUx1]
2024-01-27 13:00:10  <--  [404] POST http://localhost:3000/api/webhook [evt_3Od6L2SEPGwsgWeg1xhLgUx1]
2024-01-27 13:00:10  <--  [404] POST http://localhost:3000/api/webhook [evt_3Od6L2SEPGwsgWeg1WWA5BWe]
2024-01-27 13:00:19   --> payment_intent.succeeded [evt_3Od6L2SEPGwsgWeg1d8ATaWw]
2024-01-27 13:00:19  <--  [404] POST http://localhost:3000/api/webhook [evt_3Od6L2SEPGwsgWeg1d8ATaWw]
2024-01-27 13:00:20   --> checkout.session.completed [evt_1Od6LGSEPGwsgWegXroSxK4g]
2024-01-27 13:00:20   --> charge.succeeded [evt_3Od6L2SEPGwsgWeg1EbPyunR]
2024-01-27 13:00:20  <--  [404] POST http://localhost:3000/api/webhook [evt_1Od6LGSEPGwsgWegXroSxK4g]
2024-01-27 13:00:20  <--  [404] POST http://localhost:3000/api/webhook [evt_3Od6L2SEPGwsgWeg1EbPyunR]
next.js stripe-payments webhooks
1个回答
0
投票

对于 Next.js v14,此代码一定会对您有所帮助。

文件路径就像

/app/api/webhook/route.ts

// route.ts

import Stripe from "stripe";
import { NextResponse } from "next/server";

const webhooksecret = process.env.STRIPE_WEBHOOK_SECRET as string;

const stripe = new Stripe(webhooksecret, {
  apiVersion: "2023-10-16",
});


export async function POST(request) {
  const rawBody = await request.text();
  const signature = request.headers.get("stripe-signature");

  let event;

  try {
    event = stripe.webhooks.constructEvent(rawBody, signature, webhooksecret);
  } catch (err) {
    console.error(err.message);
    return NextResponse.json(
      { message: "Webhook Error " + err.message },
      { status: 400 }
    );
  }

  if (event.type === "checkout.session.completed") {
    const sessionLineItems = await stripe.checkout.sessions.retrieve(
      (event.data.object as any).id,
      {
        expand: ["line_items"],
      }
    );

    const lineItems = sessionLineItems.line_items as any;

    if (!lineItems) {
      return NextResponse.json(
        { message: "Internal Server Error." },
        {
          status: 500,
        }
      );
    } else {
      try {
        console.log(lineItems.data);
      } catch (error: any) {
        return NextResponse.json(
            { message: "Order Not Saved" },
            {
              status: 500,
            }
          );
      }
    }


  }else {
    return NextResponse.json(
      { message: "Payment is not Successfully Paid" },
      {
        status: 400,
      }
    );
  }
}

解构代码

  1. 导出函数POST(request){}直接监听route.tsx中的POST方法,同样导出函数GET(request){}将监听GET请求
  2. request.body() 将返回原始主体
  3. 从“next/server”导入{NextResponse}

希望这对您有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.