Reputation: 93
After a long discussion with ChatGPT, I managed to write code that redirects the user to the Stripe payment page and then captures an event when the transaction is successfully completed.
The problem is that my fetch
request has already received a response from the /checkout
endpoint and is not waiting for a response from /webhook
. And I would like my API to return a properly generated response after successfully finalizing the transaction. What am I doing wrong?
First, I send a request to the /checkout
endpoint, which takes care of generating the payment link and sending it back:
fetch('http://localhost:3001/checkout', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
items: [
{
id: 0,
},
],
}),
})
.then((res) => {
if (res.ok) return res.json();
return res.json().then((e) => console.error(e));
})
.then(({url}) => {
console.log(url);
window.location = url;
})
.catch((e) => {
console.log(e);
});
This code when I press the button redirects me to the Stripe payment page.
Endpoint /checkout
:
app.post('/checkout', async (req, res) => {
try {
const session = await stripe.checkout.sessions.create({
payment_method_types: ['card'],
line_items: req.body.items.map(({id}) => {
const storeItem = storeItems.get(id);
return {
price_data: {
currency: 'pln',
product_data: {
name: storeItem.name,
},
unit_amount: storeItem.priceInCents,
},
quantity: 1,
};
}),
mode: 'payment',
success_url: `${process.env.CLIENT_URL}/success.html`,
cancel_url: `${process.env.CLIENT_URL}/cancel.html`,
});
console.log(session.url);
res.json({url: session.url});
} catch (e) {
// If there is an error send it to the client
console.log(e.message);
res.status(500).json({error: e.message});
}
});
I connected StripeCLI to my server using stripe listen --forward-to localhost:3001/webhook
. Now I can capture the successful transaction event using the /webhook
endpoint, but I have no way to return The transaction was successful
to the client:
app.post('/webhook', (req, res) => {
const event = req.body;
if (event.type === 'checkout.session.completed') {
res.send('The transaction was successful');
}
});
Upvotes: 2
Views: 1048
Reputation: 140
After the suceesful payment the customer should be redirected back to your website. Where you can create success page.
success_url: `${process.env.CLIENT_URL}/success.html`,
If you want to get some data back from the Strapi after the paymant is successful page you can add this
success_url: `${process.env.CLIENT_URL}/success.html?&session_id={CHECKOUT_SESSION_ID}`
At the succes page you just deconstruct the data. And do whatever you want with them :)
If you deconstruct the object for example like this: (Next.js)
const stripe = require("stripe")(`${process.env.STRIPE_SECRET_KEY}`);
export async function getServerSideProps(params) {
const order = await stripe.checkout.sessions.retrieve(
params.query.session_id,
{
expand: ["line_items"],
},
);
const shippingRate = await stripe.shippingRates.retrieve(
"shr_1MJv",
);
return { props: { order, shippingRate } };
}
export default function Success({ order, shippingRate }) {
const route = useRouter();
Yo can log out the whole object to see whats inside
console.log(order);
If the payment was sucessfull you should get in prop variable: payment_status: "paid"
Upvotes: 1
Reputation: 20334
Stripe will automatically redirect the client to the success_url
that you specified when you created a Stripe session.
You can use the webhook for saving the order in the database for example, but not to redirect the client.
Upvotes: 0