#coachleyton

1 messages ยท Page 1 of 1 (latest)

amber spireBOT
vivid pelican
#

๐Ÿ‘ go ahead!

solid geyser
#

1 * User goes to Checkout page on my website

2 * Immediately create a PaymentIntent server side, and return the client secret to the front-end. We need this because we can't load the React <Elements> component without it? Not sure why tbh. This step seems to just create a load of PaymentIntents stuck on a status of "requires_payment_method" if the user rapidly goes to and from the Checkout page. Before creating the PaymentIntnet, I have to manually cancel all those other ones stuck on "requires_payment_method"

3 * Assume we're taking a new payment method on the client side, rather than using a previously attached payment method. Then assume the user has filled in the card form and clicked "submit".

4 * We call stripe.createPaymentMethod to create a payment method from the card details that the user just provided

5 * Then attach this newly created payment method to the Customer

#

6 * Then on the server side, using the paymentMethodId of that newly created and attached payment method, create (or update) a Subscription for the desired product. Return this newly created Subscription to the front-end.

7 * If the payment had a trial, then a pendingSetupIntent is returned on the Subscription. If not, then an Invoice is created and the Subscription will have a "latestInvoice.paymentIntent". We'll call this the "intent" (referenced in step 10)

8 * If after the creation or updating of the Subscription, if it's status is "trialing" or "active", then I count this as a success. All has gone well.

9 * If the status of the Subscription is "requires_action", then I call stripe.confirmCardPayment to begin 3D Secure. This should return a "PaymentIntentResult", which contains a "paymentIntent". If the status of that payment intent is "success", then the 3D secure has gone well. If not, some error has occured and show that t the user.

10 * If the subscription status if "incomplete" or it's "intent" (mentioned at the end of step 7) has a status of "requires_payment_method", then there's been an error with the payment, and show the user

#

Please let me know if any step doesn't make sense ๐Ÿ™‚

vivid pelican
solid geyser
#

Ooh, I'll check this out and get back to you. Please don't close this thead ๐Ÿ™‚

vivid pelican
#

๐Ÿ‘

solid geyser
vivid pelican
#

Yeah, you'd need to specify the amount (I do think there's some work being done to remove this requirement, but it's not public yet)

solid geyser
#

ahhh right

#

yeahh now that I think about it, this is why I didn't do this approach

#

because I don't know precisely how much it's gonna cost before hand (my plans and prices are configurable in a custom admin section in my website), so I'd need to fetch that data from the server-side

#

and idk, I just didn't feel it was secure?

#

Like, is it possible for some malicious user to alter that price to something much cheaper if it is on the client side?

vivid pelican
#

Yeah that's a fair question - we don't recommend that you just blindly trust the amount value that was set client-side. Ideally you'd have some validation or logic on your end to make sure you're charging them the correct amount

solid geyser
#

hmmm. But how could I validate that?

#

Considering my payment flow, how could I alter that to validate the payment amount?

vivid pelican
#

What logic are you using to create your payment intent and know how much to create it for? I assume you'd want to use the same thing

solid geyser
#

This is basically how I create a payment intent

#

that "plan" variable on the first line is a custom entity of my own btw, not a Stripe.Plan

vivid pelican
#

yeah let me give a quick rundown of what i'd expect to do with your flow:

  1. User goes to your checkout page
  2. You use the amount and mode docs I sent you to render PaymentElement (that way you don't have a bunch of unnecessary PIs lying around)
  3. Call createPaymentMethod client-side and send that payment method to your server
  4. On your server you'll attach that PM to your customer, set it as the default, and create a Subscription for your customer
  5. If payment wasn't successful and the PI is in a state of requires_action then return the underlying client_secret to your frontend and call handleNextAction
  6. If payment wasn't decline then surface that to your customer
solid geyser
vivid pelican
#

You'd just create your subscription like you normally do - by checking your own internal presentation of "plan" to make sure the amount is correct

#

To put it another way - it sounds like what you're already doing is correct. You create your subscription based on the prices you have defined internally, and you're not relying on any client-side information for that

solid geyser
#

yeah, I don't rely on any client side stuff to determine the price. Sooo the amount that I specify in the <Elements options={} /> wouldn't even be used?

#

so I could just enter some dummy value there?

vivid pelican
#

Yeah the amount specified client-side is primarily used for two things:

  • it's shown in UIs like google pay or apple pay
  • if you're using automatic payment methods then we use it for filtering which pm types are allowed
solid geyser
#

Sorry, I'm not sure what you mean by "automatic payment methods"

vivid pelican
#

So there's two things you can do with the flow where you don't create a Payment Intent upfront

solid geyser
#

so I could just say paymentMethodTypes: ["card"] (I only want card payments), and then pass some dummy value for the amount?

#

sorry for my ignorance here btw

vivid pelican
#

no worries at all - a lot of this stuff is new, and there's so many ways to integrate nowadays

#

and yes what you mentioned would be correct - ideally you'd pass in the amount you'd expect to charge, but if you can just give an estimate that's fine

#

and this should likely get better when amount is made to be optional

solid geyser
#

Thanks for this, I appreciate it. Learning how payments work has been the single hardest part of my entire project!! But your support team has been great

vivid pelican
#

๐Ÿ‘ happy to help!