I am trying to create a stripe session for my checkout in my Next.js project, and I have two issues. One is that for some reason, when I am sending body information in my fetch call, it does not seem to be arriving there. When I try to extract the information, such as amount, it is undefined.
The second, and bigger issue, is that for some reason I am getting a 500 error. I have followed the instructions and I have my environment variables set up but it does not seem to be working.
I am using the newer app router and this is the code in my api/checkout_session/route.ts file
import { stripe } from "@/lib/stripe";
import { NextApiRequest, NextApiResponse } from "next";
interface CheckoutSessionRequest extends NextApiRequest {
body: {
amount: number;
success_url: string;
cancel_url: string;
};
}
export async function POST(req: CheckoutSessionRequest, res: NextApiResponse) {
if (req.method === "POST") {
const { amount, success_url, cancel_url } = req.body;
try {
const session = await stripe.checkout.sessions.create({
payment_method_types: ["card"],
shipping_address_collection: {
allowed_countries: ["US"],
},
phone_number_collection: { enabled: true },
line_items: [
{
price_data: {
currency: "usd",
product_data: {
name: "Custom Amount",
},
unit_amount: 1499,
},
quantity: 1,
},
],
mode: "payment",
success_url,
cancel_url,
});
res.status(200).json({ id: session.id });
} catch (error) {
res.status(500).json({ error: error });
}
} else {
res.setHeader("Allow", "POST");
res.status(405).end("Method Not Allowed");
}
}
and this is my CheckoutButton
"use client";
import { loadStripe } from "@stripe/stripe-js";
import React from "react";
const stripePromise = loadStripe(
process.env.NEXT_PUBLIC_STRIPE_PUBLIC_KEY as string,
);
interface CheckoutButtonProps {
amount: number;
}
const CheckoutButton: React.FC<CheckoutButtonProps> = ({ amount }) => {
const handleCheckout = async () => {
const response = await fetch("/api/checkout_session", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
amount,
success_url: window.location.origin + "/payment-success",
cancel_url: window.location.origin + "/cancel",
}),
});
const session = await response.json();
const stripe = await stripePromise;
if (stripe) {
await stripe.redirectToCheckout({ sessionId: session.id });
}
};
return (
<button role="link" onClick={handleCheckout}>
Checkout
</button>
);
};
export default CheckoutButton;
The checkout button component is being called in a cart page.
I played with trying to extract the body in a few different ways. And if I console log req.body I get this output “ReadableStream { locked: false, state: ‘readable’, supportsBYOB: false }” which is weird because it doesn’t even have amount or anything else in it that I can see.
As for the 500 error, I have tried a few different things I have seen online, but none have worked and this is currently the closest way to what the documentation seems to show.
Frank Muller is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.