System Information
- Strapi Version: 4.10.1
- Operating System: Windows 11
- Database: PostgreSQL
- NextJS Version: 13.3.3
- Axios Version: 1.4.0
- Node Version: 18.16.0
- NPM Version: 9.2.0
I am making an e-commerce app with Strapi, Nextjs, and Stripe. Every time I make a payment request, there is an error: POST http://localhost:1337/api/orders 401 (Unauthorized)
This is my Orders controller :
("use strict");
const stripe = require("stripe")(process.env.STRIPE_KEY);
/**
* order controller
*/
const { createCoreController } = require("@strapi/strapi").factories;
module.exports = createCoreController("api::order.order", ({ strapi }) => ({
async create(ctx) {
const { products } = ctx.request.body;
try {
const lineItems = await Promise.all(
products.map(async (product) => {
const item = await strapi
.service("api::product.product")
.findOne(product.id);
console.log("this is item------->", item);
console.log("this is product------->", product);
return {
price_data: {
currency: "inr",
product_data: {
name: item.name,
},
unit_amount: Math.round(item.price * 100),
},
quantity: product.quantity,
};
})
);
const session = await stripe.checkout.sessions.create({
shipping_address_collection: { allowed_countries: ["IN"] },
payment_method_types: ["card"],
mode: "payment",
success_url: process.env.CLIENT_URL + `/success`,
cancel_url: process.env.CLIENT_URL + "/failed",
line_items: lineItems,
});
await strapi
.service("api::order.order")
.create({ data: { products, stripeId: session.id } });
return { stripeSession: session };
} catch (error) {
ctx.response.status = 500;
return { error };
}
},
}));
My checkout page:
"use client";
import { useDispatch, useSelector } from "react-redux";
import { useEffect, useState } from "react";
import { setSubTotal } from "@/app/redux/features/cartSlice";
import Image from "next/image";
import { loadStripe } from "@stripe/stripe-js";
import { api } from "@/http";
const stripePromise = loadStripe(`${process.env.STRIPE_PK}`);
const Checkout = () => {
const { cartItems } = useSelector((state: any) => state.cart);
const cart = useSelector((state: any) => state.cart);
const dispatch = useDispatch();
useEffect(() => {
dispatch(setSubTotal());
}, [cart, dispatch]);
const [loading, setLoading] = useState<boolean>(false);
const handlePayment = async () => {
try {
setLoading(true);
const stripe = await stripePromise;
const {data} = await api.post("/api/orders", {
products: cartItems,
});
const res = JSON.parse(data)
console.log(res)
await stripe?.redirectToCheckout({
sessionId: res.stripe_session_id.id,
});
} catch (error) {
setLoading(false);
console.log(error);
}
};
return (
<div>
<div className="container mx-auto">
<h1 className="text-4xl font-semibold mb-6">Review Products:</h1>
{cartItems.length <= 0 ? (
<p className="text-center">No products are here.</p>
) : (
<div>
{cartItems.map((item: any) => {
return (
<div className="my-6" key={item.id}>
<div className="flex">
<Image
alt="Image"
width={750}
height={750}
className="h-auto w-14 rounded"
src={item.attributes.main_img.data.attributes.url}
/>
<div>
<p className="text-xl text-ellipsis lg:max-w-5xl md:max-w-3xl sm:max-w-lg max-w-sm whitespace-nowrap overflow-x-hidden">
{item.attributes.title}
</p>
<p className="text-base">₹{item.totalPrice}</p>
</div>
</div>
</div>
);
})}
<p className="text-xl">SubTotal: {cart.subTotal}</p>
<button
className="px-2 py-2 bg-blue-700 rounded text-white outline-none hover:bg-blue-600"
onClick={handlePayment}
>
Checkout{" "}
{loading && (
<div className="w-10 h-40 animate-spin">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"
/>
</svg>
</div>
)}
</button>
</div>
)}
</div>
</div>
);
};
export default Checkout;
Axios index.ts:
import axios from "axios";
export const api = axios.create({
baseURL: process.env.BASE_URL || 'http://localhost:1337',
headers: {
Authorization: `Bearer ${process.env.BACKEND_API_KEY}`
}
})