#rtx_checkout-paymentintent
1 messages ยท Page 1 of 1 (latest)
๐ Welcome to your new thread!
โฑ๏ธ We automatically close idle threads, which makes them read-only. Make sure you stick around to chat in realtime!
๐ This thread will always be available, even after it's closed. You can find it again using Discord's search, or you can save this link: https://discord.com/channels/841573134531821608/1212089153601413152
๐ Have more to share? You can add more detail below, including code, screenshots, videos, etc.
โฒ๏ธ We'll be here soon! Typically we respond in a few minutes, but sometimes we might take a bit longer if the server is busy or if you have a particularly tricky question. Thank you for your patience!
@fluid marsh that is expected. The PaymentIntent is not created immediately. It will only be created once the customer is trying to pay on Checkout. This limits the number of "incomplete payments" you would see in the Dashboard.
rtx_checkout-paymentintent
I understand but I would like to link my order in the database with this payment intent id, so that i'm able to find back the linked payment within Stripe.
How else should I do this?
you would "link" the PaymentIntent and the Checkout Session after it was completed successfully
Why aren't these linked automatically tho?
They are linked automatically tho.
You create a Checkout Session. There is no PaymentIntent created yet. Later when the customer goes on Checkout and pays, a PaymentIntent gets created. At that point the Checkout Session would have payment_intent: 'pi_123' set as expected.
But really you don't need to "link" this until after the payment completes successfully and you go through order fullfiment as covered in the doc I shared above. And at that point you can do the reconciliation in your database.
But that's not what this endpoint i have handles right so how else would i get that payment_intent? Do I have to perform a GET request with the checkout session id in order to get the payment_intent id?
I'm looking through the docs but it's in a different coding language, making it a little hard for me to understand
I'm sorry I don't really follow you. The doc I linked supports all languages, you can switch it to pick the one you want.
I also don't really understand what you mean with the first reply. Can you try and be a lot more specific about the exact issue? In theory you would get checkout.session.completed on your WebhookEndpoint and that will have all the information you need
Oh so that's a webhook I have to listen to?
I didn't know I could change the language, my bad!
yeah we changed the layout for code. I think it's less "obvious" I'll share the feedback
No no i'm just stupid ๐ My lazy eyes didn't see it
haha you're not the first one to say this. In the past we had "tabs" for each language and it was a lot more obvious (and you could cmd+F for your language)
I first had this but I guess this isn't exactly the proper way haha
// Node.js example using Express
const express = require("express");
if (process.env.NODE_ENV !== 'production') {
require('dotenv').config();
}
const cors = require("cors");
const app = express();
const stripe = require("stripe")(process.env.STRIPE_SECRET_KEY);
app.use(express.json());
app.use(cors({ origin: process.env.CORS_ORIGIN }));
// Endpoint to create a checkout session
app.post("/create-checkout-session", async (req, res) => {
const { products } = req.body;
try {
const session = await stripe.checkout.sessions.create({
payment_method_types: ["card"],
line_items: products,
mode: "payment",
success_url: `${process.env.FRONTEND_URL}/checkout/success?session_id={CHECKOUT_SESSION_ID}`,
cancel_url: `${process.env.FRONTEND_URL}/cart`,
payment_intent_data: {
statement_descriptor: process.env.STATEMENT_DESCRIPTOR,
},
});
res.json({ sessionId: session.id, status: "success" });
} catch (error) {
res.status(500).send(error.toString());
}
});
// Endpoint to retrieve the checkout session and get the payment_intent
app.get("/retrieve-checkout-session/:sessionId", async (req, res) => {
const { sessionId } = req.params;
try {
const session = await stripe.checkout.sessions.retrieve(sessionId);
// Check if payment_intent is available
if (session.payment_intent) {
res.json({ paymentIntentId: session.payment_intent });
} else {
res.status(404).send("Payment Intent not found for the given session.");
}
} catch (error) {
res.status(500).send(error.toString());
}
});
app.listen(process.env.PORT, process.env.HOST, () => console.log(`Running on port ${process.env.PORT}`));
your success URL is ${process.env.FRONTEND_URL}/checkout/success?session_id={CHECKOUT_SESSION_ID} so after Checkout completes when the customer pays they would end up on /checkout/success so you need a route for this
I have a route for that, but that's also another question I have.
Is CHECKOUT_SESSION_ID automatically replaced with the value?
Already in test mode. Had to learn that the hard way when I accidentally actually paid for something non existent haha
lol
I will let you know as soon as possible if it works
sounds good!
So the first part works haha now gotta do the payment intent stuff
yay!
Does this mean I would have to finalize the creation of an order via a frontend call or is that not the proper way?
Hello! I'm taking over and catching up...
Hey!
You shouldn't rely on the success page ever being reached. Someone can pay successfully in Checkout, then drop off before they get redirected to your success page. What we recommend is that you have both webhooks and the success page trigger fulfillment, with a first-one-to-do-it-wins approach.
So, if you get a checkout.session.completed Event first (or only) use that to trigger fulfillment. If someone lands on the success page first, before you get that Event, you can trigger fulfillment immediately and then when the Event does come in you can ignore it since fulfillment already happened.
Alright thanks. Let me try that! I will notify you if this works
Does the webhook itself have a different secret?
Each Webhook Endpoint has a different webhook signing secret, yeah.
Sorry, I'm not sure what you're referring to. Why are you asking? Are you running into an issue?
Yeah I'm kinda stuck here.
What endpoint URL should I even put there? My localhost:3000/webhook ?
Stripe is never going to be able to reach localhost? xD
If you're testing locally you need to use Stripe CLI to forward Events to your local web server. Webhook Endpoints you set up in the Dashboard only work with URLs that are live and reachable online.
Have a look here: https://docs.stripe.com/webhooks#test-webhook
Hmm mkay. Is there a different way I can do this without having to use Webhooks?
I feel like if I have to do so much effort just to get the Payment Intent Id, it's not really worth getting it this way?
I don't want to sound lazy ๐ but this sounds like a lot of setting up to do for just an id
Not really, webhooks are recommended to make sure you know when someone pays you. I actually should have linked to this instead, as it's specific to Checkout and closer to what you're doing: https://docs.stripe.com/payments/checkout/fulfill-orders
Alrighty. So i just tested it with the CLI and the event was successful.
Sounds like Il have to put in my production URL in then if I want it to work without cli
Yep. Stripe CLI is for testing locally, the Webhook Endpoints are for live URLs that are reachable online.