#rezamirzad
1 messages ยท Page 1 of 1 (latest)
Hi,
Are you referring to this guide?
https://stripe.com/docs/payments/quickstart
yes
as of now, i have no way to tell my backend which product is being purchased in the checkout.
If so, when your frontend calls your backend, you need to send all the information you need via the request body
in the checkout.js, when calling /create-payment-intent you need to pass all information that you need
can you direct my to the whole syntax?
all i have is:
fetch(${Env.REACT_APP_API_URL}/create-payment-intent, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ items: [{ id: "xl-tshirt" }] }), })
where do i pass the product id in the body of my post request?
and then, how do i use it on the backend?
Yes exactly there,
you send in the body your products ids, something like:
const items = [{ productId: "prod_123" }];
const response = await fetch("/create-payment-intent", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ items }),
});
And in your backend, you need to follow the definition of the /create-payment-intentin server.js
const { items } = req.body;
items[0].productId...
```
ok cool
so, in my calculateOrderAmount, i get the item productId.
how do i retrieve the price for said productId?
You can search for prices by productId using search API:
https://stripe.com/docs/api/prices/search
https://stripe.com/docs/search#query-fields-for-prices
so, i would basically do a querty like this?
const price = await stripe.prices.search({ query: "active:'true' AND metadata['price_id']:items[0].productId'", });
Something like this:
const price = await stripe.prices.search({query: "active:'true' AND product:items[0].productId'"});
so this
const price = await stripe.prices.search({ query: "active:'true' AND product:items[0].productId'", });
console.log(price);
returns:
{
object: 'search_result',
data: [],
has_more: false,
next_page: null,
url: '/v1/prices/search'
}
i do not see the price anywhere
Can you share the ID (req_xxx) of that API request?
https://support.stripe.com/questions/finding-the-id-for-an-api-request
req_wtvmKwW5FSlnSu
You are sending this as a request Body:
{
query: "active:'true' AND product:'items[0].priceId'",
}
```
You are searching price by product using a priceId?
Probably you should replace `items[0].priceId` with `items[0].priceId`. sorry I have a typo in my suggested message above:
const price = await stripe.prices.search({query: "active:'true' AND product:'"+items[0].priceId+"'"});
so i give the priceId from my front?
it still returns no data
const price = await stripe.prices.search({ query: "active:'true' AND product:'" + items[0].priceId + "'", });
price
{
object: 'search_result',
data: [],
has_more: false,
next_page: null,
url: '/v1/prices/search'
}
although, i can see that i pass the priceId correctly
[ { priceId: 'price_XXXXXX' } ]
Can you share the ID (req_xxx) of the failing API request? https://support.stripe.com/questions/finding-the-id-for-an-api-request
Find help and support for Stripe. Our support center provides answers on all types of situations, including account information, charges and refunds, and subscriptions information. Get your questions answered and find international support for Stripe.
What is the value of your items[0].priceId variable?
You need to pass prod_xxx ID to the product query param: https://stripe.com/docs/search#query-fields-for-prices
I don't get what you'd be searching for Price objects if you already have the price_xxx ID?
ok so now i have my amount
{
object: 'search_result',
data: [
{
id: 'price_1MQvcaGMR3u9Lz70hZdkwLVQ',
object: 'price',
active: true,
billing_scheme: 'per_unit',
created: 1673886800,
currency: 'eur',
custom_unit_amount: null,
livemode: false,
lookup_key: null,
metadata: {},
nickname: null,
product: 'prod_NBICRRUIfpPLxd',
recurring: null,
tax_behavior: 'unspecified',
tiers_mode: null,
transform_quantity: null,
type: 'one_time',
unit_amount: 9900,
unit_amount_decimal: '9900'
}
],
has_more: false,
next_page: null,
url: '/v1/prices/search'
}
therefore, i want to pass it to
const paymentIntent = await stripe.paymentIntents.create({
setup_future_usage: 'off_session',
amount: price.data.unit_amount, //amount: price, currency: 'eur', automatic_payment_methods: { enabled: true, }, });
but price.data.unit_amount is undefined
Because price.data is a list (array). You'd need to do amount: price.data[0].unit_amount
aha, yes, i see now.
great, thank you
one more question
const { error } = await stripe.confirmPayment({
elements,
confirmParams: {
return_url: "http://localhost:3000/step",
}, });
how do stock the redirect_status received from the server, in order to make sure that the payment has passed?
could easily be manipulated by the client
You shouldn't rely on the return_url for success/fulfilment, and instead use webhooks: https://stripe.com/docs/payments/handling-payment-events
ok i get it.
so, when i get to my return_url, I check the status of the payment with the webhook?
No, the webhook is a different process separate to your payment UI. It happens asynchronously. You setup a server/endpoint, and we send events to that endpoint (like payment_intent.suceeded) which indicate activity on your account that you can then action
There's no guarantee than any customer stays in your payment flow long enough to be redirected back to your site, so you shouldn't use that as confirmation of payment/success. Just display a nice order confirmation page, or something
so, where and when do i use the webhook?
let's say, i redirect the client to the next url.
but now, i wanna make sure that the payment actually succeeded.
what do i need to do in order to get that confirmation?
Did you read the doc I sent: https://stripe.com/docs/payments/handling-payment-events
You don't 'use' the webhook. It just happens asynchonrously in the background, assuming correctly setup
i.e. your customer completes a payment, we flag that payment as successful and omit a payment_intent.succeeded event. Your webhook is configured to receive those events, so will required a POST HTTP request with the payment details in the body that you can action as required
If you have the endpoint configured locally, I'd recommend testing it with the CLI: https://stripe.com/docs/payments/handling-payment-events#use-cli
ok, but even though i installed the cli,
How did you install it?
Did you move it to a global dir so that the stripe command is available everywhere?
It's easier to install via homebrew if you can
yes it is working now
so, when i proceeed with the payment, i can see the webhook returning
idempotency_key: '3a095ed6-8698-42d6-b51f-1f4d6d5df7b6'
},
type: 'payment_intent.succeeded'
}
i want to create some data on my database.
i use the backend webhook, and just check if "succeeded" in order to trigger the graphql queries and resolvers?
Well with the payment_intent.succeeded event, the status will always be succeeded
So on receipt of that event you can always infer that the payment was fine and the balance due to your Stripe balance
So yes, at that point you can write your custom fulfilment logic in your webhook
i see
but i want my custom code to be executed only if the payment was received
what field of the webhook response do i have to check?
What do you mean by received?
In that case you'd only run that specific logic for payment_intent.succeeded events, via like a switch handler: https://stripe.com/docs/webhooks/quickstart
i mean the client enters his card information on the checkout form.
stripe processes the payment.
i want to create the data on my data base, only when the payment is successful
but the payment_intent.succeeded is also triggered at the creation of the payment intent
if I got it correctly, what i want is the "paid" field, write?
but the payment_intent.succeeded is also triggered at the creation of the payment intent
Shouldn't be, that'd bepayment_intent.created
You need to add a filter to your webhook to only process the event types you care about (i.e. payment_intent.succeeded) via a switch statement or similar. You can check the type field on the payload: https://stripe.com/docs/api/events/object#event_object-type
Complete reference documentation for the Stripe API. Includes code snippets and examples for our Python, Java, PHP, Node.js, Go, Ruby, and .NET libraries.
Even better, configure the webhook in Stripe to only listen for payment_intent.succeeded events as I suspect that's all you care about right now
yes, i think I got it.
will come back if i have other questions
thank you ver much @tawny night ๐
np!
can you explain me how is the webhook "payment_intent.succeeded" triggered when it is on my backend code, and i do not call it anywhere?
basically, if i do not run the stripe cli, the webhook is not called
Did you configure a webhook in the Dashboard? https://stripe.com/docs/development/dashboard/register-webhook
my backend is on localhost:8888
and i want the listener to be active regardless of the stripe cli
You need to setup a webhook at the URL where it will be deployed then
aha, can not be on localhost then?
to test on localhost, it will need to be absolutely with the stripe cli?
like if my colleague wants to test and work on my git branch, he will need to set up the stripe cli, righht?
Our API cannot reach your localhost no. That's the purpose of the CLI, or a tool like ngrok
i see
thanks again
one more thing, can you give me the list of all parameters in confirmParams?
i am using the receipt_email with the email entered on the checkout form.
but i do not receive any email
Yeah that's not a valid param: https://stripe.com/docs/js/payment_intents/confirm_payment
i still do not get the email with this
Well, 2 issues:
- We don't send emails in test mode: https://stripe.com/docs/receipts#:~:text=Receipts for payments created using your test API keys are not sent automatically. Instead%2C you can view or manually send a receipt using the Dashboard.
- That's the email set on the Payment Method object, not the Payment Intent