#lumen-paymentintent
1 messages · Page 1 of 1 (latest)
Hi there!
Can you give me some advice, let me know if there's a better way to handle this?
First it's important to note that from Stripe's point of view there's no downside to creating many PaymentIntent even if you don't use them. But that being said you could improve things by, for example:
- Only create the PaymentIntent when your users click to open the modal
- Or only create one PaymentIntent per user, and only use it when the click to open the modal
Ah, so having a bunch of incomplete payment intents in my dashboard (as on the screenshot above) is not a big deal, it doesn't mean that I'm doing something wrong, that's just how it works?
If I only create a payment intent only when the user opens the modal, I'd make fewer of them, but there'd still be extra ones for all the users who opened the modal but didn't decide to go through with the payment.
Ah, so having a bunch of incomplete payment intents in my dashboard (as on the screenshot above) is not a big deal, it doesn't mean that I'm doing something wrong, that's just how it works?
correct
If I only create a payment intent only when the user opens the modal, I'd make fewer of them, but there'd still be extra ones for all the users who opened the modal but didn't decide to go through with the payment.
true, but once again there's no issue from Stripe's point of view. and this option might be cleaner.
Thanks a lot!
I have one more related question. The quickstart guide tells me that I should pass the payment intent to <Elements/> provider like so:
<Elements options={{clientSecret}} stripe={stripePromise}>
<CheckoutForm />
</Elements>
If I want to fetch the payment intent only when the user opens the modal, it'd make sense to put the payment-intent-fetching code inside of my PurchaseModal component.
But as far as I understand, I'm supposed to put <Elements/> provider into _app.tsx, to wrap all the components (to be able to use stripe on the payment result page, for example).
Is there some other way to pass payment intent secret to my form? Because I don't think it makes sense to fetch payment intent inside the _app.tsx
If I want to fetch the payment intent only when the user opens the modal, it'd make sense to put the payment-intent-fetching code inside of my PurchaseModal component.
Agreed
But as far as I understand, I'm supposed to put <Elements/> provider into _app.tsx, to wrap all the components (to be able to use stripe on the payment result page, for example).
Yes I guess it depends on how/where you plan to display the payment result page
Is there some other way to pass payment intent secret to my form?
No I don't think so.
Yes, so I have a <PurchaseModal/> component where I fetch the payment intent code, and I have a separate payment results page I redirect to after the payment is successful.
There's no way to pass the fetched payment intent from <PurchaseModal/> to the _app.tsx. I mean I can do this, but it'd be extraordinarily ugly, I'd have to create context just for that, and I couldn't even use it in the <App/> component, since it's the root component that can't be wrapped into context, so I'd have to create an extra child component under the <App/>, which wraps everything, just to pass payment intent from <Modal/> into the checkout form that's right inside this same modal! All that just so I could display the credit card form. That can't be right, this is terrible.
How do more experienced developers usually solve this? I can't be the first person to encounter this issue.
Hey, taking over here
To be clear, you don't have to invoke the <Elements> provider in your root application
That's simply a recommendation, but you can include that only where you require if it simplifies your integration
If you do that, I'd still recommend initialising Stripe.js (via loadStripe) in the root of your application
Ah, interesting!
So I'd loadStripe in the root of my app, pass it down to all my components, and then have multiple <Elements/> providers, one inside my <PurchaseModal/>, and another one on my payment results page?
Yep, that should work
Oh, that's perfect, I think that solves my problem!
Thank you so much for your help!
Of course, np!
Thank you, this is really nice! Do you think it's possible to replace with my custom loader?
Here's how it looks now:
At first my own <Spinner/> shows up (the small spinny circle), then Stripe's loader shows up briefly (the blank form with no fields and animated gradients), and then the form loads. I think it'd be neater if I could show my own loader in place of stripe's loader.
Or maybe find some other way to handle this, so that it doesn't look as awkward when UI loads in stages.
I'd really appreciate some advice on making it look better, but if that's just how it works I guess it's okay, I can live with that.
Well you can disable our loader
Then it'll just show a blank space for a brief moment while the form loads.
If <PaymentElement/> had some kind of function I can pass to it that will tell me when it has finished loading, that'd be really neat.
Or maybe a way to pass it a custom spinner.
Take a look here:
https://stripe.com/docs/payments/payment-element
This page shows me a small spinner while the form loads. How did they do that?
Nope, without my spinner it's just blank:
<div className="payment-form">
{clientSecret && (
<Elements options={options} stripe={stripePromise}>
<CheckoutForm />
</Elements>
)}
</div>
What is your options hash?
const appearance = {
theme: 'stripe' as any,
variables: {
colorPrimary: '#b55dff',
colorText: '#374151',
},
}
const options = {
clientSecret,
appearance,
}
Trying passing loader: 'always'
const options = {
clientSecret,
appearance,
loader: 'always'
}
Then it looks like this:
My button shows up as soon as clientSecret has finished loading, and then there's a stripe loader in place of the form for a second.
There are two times I have to wait, first for clientSecret to load, then for <PaymentElement/> to load. What I'm trying to do is to make two loaders look the same, so that it looks seamless.
Just checking on how we do this on the demo you linked
Can you also help me find the docs page for <PaymentElement/> that shows me all the props it can accept?
Looks like we have a loading prop in state:
{loading && (
<Spinner />
)}
{clientSecret && (
<Elements
stripe={stripePromise}
options={options}
>
...
</Elements>
)}
Then loading is unset after the PI promise resolves
Ah, I see, so you guys just aren't showing the loader while the <PaymentElement/> loads. Only the PI promise loader. That's alright, it doesn't look too bad anyway, I can live with the way it works now.
Thank you so much for taking the time to help me out!
np!