#jon-waldstein-givewp_unexpected

1 messages ยท Page 1 of 1 (latest)

turbid acornBOT
#

๐Ÿ‘‹ Welcome to your new thread!

โฒ๏ธ 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.

โฑ๏ธ We close idle threads, which makes them read-only. Once a thread is closed it won't be reopened, but you can always start a new thread if you have another question.

๐Ÿ”— 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/1339661116879409275

๐Ÿ“ Have more to share? Add more details, code, screenshots, videos, etc. below.

fossil violet
#

Hello! Not sure I fully understand your question. elements.submit is designed to collect payment info from wallets and the CashApp, but the actual payment happens after that. Can you clarify what specific issue you're running into?

dense parrot
#

Yeah so looking at this here: const {error: submitError} = await this.elements.submit(); this will trigger the cash app to open it's modal, however if you were to exit out of the modal without interacting with cash app, we have no way of knowing that the use did not interact with the payment method. I would assume there would be some kind of error to avoid application logic continuing

fossil violet
#

That does seem unexpected. Currently, though, you're only extracting the error from the result of the Promise resolving. Can you instead grab the entire object and log it to see what it contains in the scenario you're describing?

dense parrot
#

sure let me check

#

Okay, so what's curious here is I logged this right after await this.elements.submit(); and it was immediately logged, implying the resopnse is resolved too soon. In contrast, using a Bank Account Payment method, which also invokes a modal, I never get the console log when exiting the modal

fossil violet
#

Yeah, that seems normal to me. elements.submit is succeeding and returning the selected payment method type (cashapp). I think you may just be expecting elements.submit to do things it's not designed to do. See here for more details: https://docs.stripe.com/js/elements/submit

#

To clarify, elements.submit isn't involved in the actual payment step, it's something that runs before that for various reasons (validation, collecting payment info, etc.) depending on the selected payment method type.

dense parrot
#

hmm, i'm still not sure this is working correctly or maybe is just not intuitive. I would expect cash app to work just like bank account payment method. cash app is resolving elements.submit immediately, when the modal opens. bank account is only resolving elements.submit when successful.

This is what is recorded in Stripe using cash app when the modal is exited, continuing with the application logic of stripe.confirmPayment. The payment goes into an incomplete and/or canceled status

fossil violet
#

bank account is only resolving elements.submit when successful.

Can you clarify what you mean by "when successful" here?

#

I think you might be running into the difference between the business-initiated payment confirmation nature of bank account payments vs. the customer-initiated payment confirmation of CashApp. What you've described above is normal due to the different ways these two payment methods work.

#

To put it another way, elements.submit is not designed to give you any signal about successfully receiving data, like payment info, or indicating any kind of success other than very basic stuff like "the selection they made is valid" when it comes to payment methods like CashApp.

dense parrot
#

okay I think i'm following now

fossil violet
#

Happy to answer any other questions if you have them!

dense parrot
#

I'm discovering on my end, the difference is actually how the payment method modal is invoked. The bank account is invoked manually by a button inside Stripe Payment Element. When we use elements.submit it already has what it needs previously. However, with cash app, we are using elements.submit to both invoke the payment method and resolve it at the same time

#

Is there a programatic way to invoke a payment method like cash app (open the modal) that could be used before we call elements.submit()?

fossil violet
#

No, not that I know of. I'm not sure I understand why you would want to do that though?

dense parrot
#

Essentially what we're trying to avoid is a user going to use a payment method like cash app which opens it's own modal, and then exiting out of the payment method modal. The reason is we don't know that they didn't actually use the payment method so we continue to our server, creating the payment intent and confirming the payment on the front-end.

fossil violet
#

You would know they didn't use it after the time limit passes without the Payment Intent being confirmed. CashApp sessions expire after an hour.

#

To clarify further, closing the dialog or has no material impact on this. If the dialog with the QR code pops up, they can it with their CashApp app, then they close the dialog, they can still complete the payment inside the CashApp app. The dialog being open or closed at that point is irrelevant.

dense parrot
#

okay so is it fair to say that we should rely on the webhooks to make the final call as to whether or not the payment has been completed?

fossil violet
#

For CashApp, absolutely. There isn't really another practical way to do it since the customer can pay anytime in that hour window.

#

Unless you do something like cancel the Payment Intent, of course.

dense parrot
#

Okay, is there no way to cancel a cash app payment? I'm thinking of someone clicking to use cash app but want to use a credit card method instead, there doesn't seem to be a way to do that

fossil violet
#

Are you talking about a scenario where you create a Payment Intent which can accept both CashApp and card payments, then the customer presses CashApp first, they back out of that, then they use card to confirm the Payment Intent? You're wondering how to cancel the oustanding CashApp session in that scenario?

dense parrot
#

Not exactly, I should clarify that i'm using the defer payment intent flow. So we don't create the payment intent until the server. So a customer presses cash app first, then simply wants to exit and use a credit card instead. Currently we're not able to allow that because cash app has already kicked off the payment flow and regardless if they click the escape button we are going to create the intent on the server

fossil violet
#

Ah, knowing you're using the deferred flow helps. I'm still a bit confused about the specifics, though. If they choose CashApp first, then close the dialog, what prevents them from using a card at that point instead?

dense parrot
#

Maybe a visual of our form will help. Once we click donate we are calling elements.submit() which opens the cash app modal. when they close out of the modal, the logic continues to the server to create the intent because it's techincally resolved

#

this is so hard to explain haha! thanks for your patience

fossil violet
#

It might help if you could point me to an example Payment Intent that's at the "they selected Cash App but then closed it without paying" point in the process?

#

Like do you have one from test mode?

dense parrot
#

yup! can you access this one? pi_3Qs7KBC6z5rd6X030SLCcfsz

fossil violet
#

Yep! Looking now...

#

Oh, I see. So at this point you've already called stripe.confirmPayment and the customer's been redirected to your return_url, correct?

dense parrot
#

that correct!

fossil violet
#

Gotcha. Yeah, due to the nature of how CashApp pay works you would need to handle this on your return_url page somehow. For example, you could get the Payment Intent's status (requires_action in this case, because the customer needs to pay via CashApp at this point) and let them know they can either pay via CashApp or they can go back to the payment form and use another payment method (and then link back to the payment form again, of course).

dense parrot
#

ohh okay, I was under the impression that confirmPayment handles those next steps, is that not the case?

fossil violet
#

Which next steps are you referring to?

dense parrot
#

any of those requires_action statuses

When called, stripe.confirmPayment will attempt to complete any required actions, such as authenticating your user by displaying a 3DS dialog or redirecting them to a bank authorization page. Your user will be redirected to the return_url you pass once the confirmation is complete.

fossil violet
#

Ah, yeah, so it does handle the next actions it can handle, but some actions need to be handled by the customer. In the case of CashApp, the next action required is for the customer to pay via CashApp. Showing the customer the QR code is all Stripe can handle; the customer has to take it from there.

#

This goes back to the customer-needs-to-confirm nature of CashApp, vs. the business-needs-to-confirm nature of other payment methods like cards.

turbid acornBOT
dense parrot
#

ohh I see, the customer needs to do the rest in the cash app itself. So at this point we would need to present them with that QR code again.

#

There really does not seem to be a good way to prevent this whole scenario huh?

fossil violet
#

No, that's already happened. You don't need to present the QR code again.

#

I'm still not 100% certain what specific scenario you're trying to prevent, to be honest. ๐Ÿ˜… The flow for CashApp is that they go through the payment form, get shown the QR code, and then they have an hour to pay through the CashApp app. There's no way for you to immediately know if they're going to do that or not, you need to wait to see if it happens during that hour.

#

If someone picks CashApp and proceeds, but then changes their mind and wants to pay another way, you should have the option for them to do so on your return_url page. You would send them back to your payment form (a new, fresh one) and they would start the whole payment process over again using another payment method.

#

You could, optionally, cancel the oustanding CashApp Payment Intent (the one in requires_action status) if you want to prevent them from paying via CashApp if they explicitly indicate they don't want to do that anymore.

dense parrot
#

Alright i'll have to do some experimenting. It sounds like the return_url should be more aware of the payment intent's next actions?

#

or are you saying use the additional params that get added to the return url to determine next steps

fossil violet
#

Yes. The best practice there is to have your return_url, during load, fetch the current status of the Payment Intent and display appropriate information based on that. If the status is succeeded you can display a "thanks for your payment" message. If it's requires_action you can then inspect the payment method type and display appropriate information like "make sure you complete your payment in CashApp" or whatever.

#

The parameters in the return_url are intended to be used to look up the current status of the payment in order to do what I described above.

#
  1. Customer is sent to return_url
  2. You grab the info from the URL
  3. You fetch the appropriate objects from Stripe (e.g., the Payment Intent)
  4. You determine what to display to the customer
  5. You render the return_url page
#

The end result is that, as a customer, if I pay with card, I will end up on a page that says "thanks for your payment" because the payment already went through. For bank account payments it might be something like "your payment is being processed, thank you" since most bank account payments aren't instant. For CashApp it might be something like "you can complete your payment in your CashApp app, or you can go back to our payment form to pay another way".

#

And "our payment form" would be a link back to your payment form, for example.

dense parrot
#

ah okay, I got it now. I think I can work with that and will continue experimenting. thank you for your help!