NEXT JS: I am trying to put the content of a state variable "cart" into the body of the POST request to the STRIPE api. Cart has the format [{id: 1, amount: 1}, {id: , amount: }.......]
I tried putting items directly into the api handler (list_items) and that works. But I cannot get my "cart" variable to show up there, so I guess I have to include the items in the POST request itself. Have tried getting that to run (including an object there and JSON.stringify as property to a "line_items" - variable, but to no avail. Maybe somebody could help me out?
API handler:
import Stripe from 'stripe';
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
export default async function handler(req, res) {
if (req.method !== 'POST') {
return res.send({
error: 'Method need to be POST',
});
}
const domainURL = 'http://localhost:3000';
// const { quantity, mode, productKey } = req.body;
const pmTypes = ['card'];
const session = await stripe.checkout.sessions.create({
payment_method_types: pmTypes,
mode: 'payment',
locale: 'en',
line_items: the_variable????,
success_url: `${domainURL}/success?session_id={CHECKOUT_SESSION_ID}`,
cancel_url: `${domainURL}/cart`,
});
res.send({
sessionId: session.id,
});
}
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
POST request :
const stripeLoader = loadStripe(props.pk);
const redirectToCheckout = async () => {
const stripeClient = await stripeLoader;
const { sessionId } = await fetch('api/checkout_sessions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body : {????}
}).then((res) => res.json());
stripeClient.redirectToCheckout({ sessionId });
};
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
I figured out how to make the POST request. The body has to look like this:
body: JSON.stringify({
lineItems: props.cart.map((singleItem) => {
return {
price: <the_stripe_price_key_for_the_given_product>,
quantity: <the_amount>,
};
}),
})
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
included the following line in the API handler: const { lineItems } = req.body;
and set line_items: lineItems
So, just as Nolan pointed out, line_items will accept an array of objects (in my case generated through mapping of my 'cart' state variable).
CodePudding user response:
You can use any structure you like to communicate between your client and backend, but your API request to Stripe to create the session must conform to the line_items
API parameter expected shape (docs).
You can either define pricing on the fly with price_data
on each item:
const session = await stripe.checkout.sessions.create({
payment_method_types: ['card'],
line_items: [
{
price_data: {
currency: 'usd',
product_data: {
name: 'T-shirt',
},
unit_amount: 2000,
},
quantity: 1,
},
],
mode: 'payment',
success_url: 'https://example.com/success',
cancel_url: 'https://example.com/cancel',
});
Or you can use predefined prices:
const session = await stripe.checkout.sessions.create({
payment_method_types: ['card'],
line_items: [{
price: 'price_123',
quantity: 1,
},{
price: 'price_456',
quantity: 3,
}],
mode: 'payment',
success_url: 'https://example.com/success?session_id={CHECKOUT_SESSION_ID}',
cancel_url: 'https://example.com/cancel',
});