#lumen-paymentintent

1 messages · Page 1 of 1 (latest)

marsh basalt
#

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
ruby rapids
#

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.

marsh basalt
#

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.

ruby rapids
#

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

marsh basalt
#

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.

ruby rapids
#

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.

fickle glade
#

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

ruby rapids
#

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?

fickle glade
#

Yep, that should work

ruby rapids
#

Oh, that's perfect, I think that solves my problem!

Thank you so much for your help!

fickle glade
#

Of course, np!

ruby rapids
#

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.

fickle glade
#

Well you can disable our loader

ruby rapids
#

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.

fickle glade
#

I'm pretty sure that's the default behaviour

#

Try removing your <Spinner> component

ruby rapids
#

Nope, without my spinner it's just blank:

<div className="payment-form">
  {clientSecret && (
    <Elements options={options} stripe={stripePromise}>
      <CheckoutForm />
    </Elements>
  )}
</div>
fickle glade
#

What is your options hash?

ruby rapids
#
  const appearance = {
    theme: 'stripe' as any,
    variables: {
      colorPrimary: '#b55dff',
      colorText: '#374151',
    },
  }
  const options = {
    clientSecret,
    appearance,
  }
fickle glade
#

Trying passing loader: 'always'

#
const options = {
  clientSecret,
  appearance,
  loader: 'always'
}
ruby rapids
#

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.

fickle glade
#

Just checking on how we do this on the demo you linked

ruby rapids
#

Can you also help me find the docs page for <PaymentElement/> that shows me all the props it can accept?

fickle glade
#

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

ruby rapids
#

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!

fickle glade
#

np!