verbb / formie

The most user-friendly forms plugin for Craft CMS.
Other
93 stars 68 forks source link

Stripe payments incomplete when using multi-page form #1898

Closed d-karstens closed 1 month ago

d-karstens commented 1 month ago

Describe the bug

Hi,

We are trying to set up a form where a user can do a one-off Stripe payment on the first page, and then enter some additional details for a different integration on the second

The issue we're having is the payment only seems to be processed when the second page is submitted so it comes through as incomplete in the Stripe dashboard with the following message, and the submission is marked as incomplete in Craft

Screenshot 2024-05-22 at 3 56 47 PM

The client asked if we could process the payment on the first page and then show the second so I had the thought to keep it as a single page form and redirect the user to another page with a second form, but it would be preferable if it wasn't possible for the public to stumble onto the second page somehow and trigger the second integration without paying

Thanks!

Steps to reproduce

  1. Create a form with two pages, with a Stripe field on the first page
  2. Try to submit and payment comes through as incomplete in Stripe, and submission is incomplete

Form settings

Craft CMS version

5.1.4

Plugin version

3.0.0-beta.11

Multi-site?

No

Additional context

No response

engram-design commented 1 month ago

I believe this is expected behaviour for Stripe, as the payment intent is created when you enter in the details (client-side), and only captured upon form submission (completion).

I really don't think this is something we're going to implement, as I can see some issues cropping up from this.

Firstly, it's very unusual behaviour to capture payment in the middle of a form submission. I don't think I've ever seen a real-world instance of this. As such, this goes against what most users would expect and assume, which doesn't bode well for UX and doing something unexpected.

The second issue is that users can go back to the first page, and submit the first page again. What if this captures payment multiple times?

Finally, Stripe itself strongly recommends to show payment fields on the last page of a form.

As for your use case, I think one way to handle that would be to split the form pages into two different forms. In the first form that captures payment, add a dynamic attribute to the Redirect URL, like other-form?uid={uid} which is going to pass on the submission's UID to the other-form template.

On that template, you render the second page's form (now just a single page) and you add some checks to prevent casual browsing to that page. Using the UID is safer than an ID which could be guessed or brute-forced with ease.

{% set submissionUid = craft.app.request.getParam('uid') %}

{% if not submissionUid %}
    {% exit 404 %}
{% endif %}

{% set submission = craft.formie.submissions.uid(submissionUid).one() %}

{% if not submission %}
    {% exit 404 %}
{% endif %}
d-karstens commented 1 month ago

Yeah, those concerns make a lot of sense - I did feel it was an odd issue, but thought I would ask anyway

For context, the client's current setup is they take a payment and then give the user a PDF to fill out and send back so someone can manually enter the data into their CRM - I guess they would prefer the additional fields to not be front facing, so your suggested method using two forms and a submission's UID will work perfectly

Cheers!

engram-design commented 1 month ago

Sure thing, it's a pretty common scenario and is covered in our gated download page user guide.