The current "Add payment" form approach reverses a normal merchant's logic. Where a merchant might say, "I'd like to charge $25 to this card," our form currently asks, "What card would you like to charge? How much? Ok, a full charge or just an authorization?"
We should fix the logic and also provide more helpful information on the form, such as the order items and the effect of any previous payments, including a textual representation of the current order balance (instead of just defaulting the current balance in the payment amount field).
This is an in-browser mock-up of the new approach:

Note that it shows the actual order items and also includes in the order totals area a line showing how much has already been paid and what the remaining balance is. We do need to ensure this is backwards compatible, so we should:
- Define a new controller for this new form approach.
- Default Drupal Commerce to using this new controller.
- Look for a setting variable that if set edits the route to use the old controller. Perhaps something as simple as a setting called
use_two_step_add_payment_form. - Mark the old controller as deprecated so it can be deleted in 4.x.
- Embed the order items table atop the form, along with the order total summary.
- Add lines to the summary for the total paid and outstanding balance.
- Put the payment details inside a fieldset to visually match the order comments form on the view page.
- Float the currency selector if present. This isn't a strict requirement, because it can be a pain in the neck to get the vertical alignment right in the abstract. But this would be nicer than vertical stacking.
- Note the changed label, from "Payment option" to "Payment method."
- If the merchant is reusing a payment method, no problem, we process payment on submit.
- If the merchant is entering a new payment method, update the form to include the necessary elements.
- Create the payment method on submit and charge the payment as before.
I'll make a separate ticket specific to supporting a return from an offsite payment solution. The scope of this ticket is primarily to make the form ready for that while also providing a much nicer UX to merchants.
| Comment | File | Size | Author |
|---|---|---|---|
| #11 | 3538209-11.patch | 31.07 KB | adrianandres |
| #10 | 3538209-10.patch | 102.17 KB | jsacksick |
| #9 | 3538209-commerce-2.40-9.patch | 32.46 KB | jsacksick |
Issue fork commerce-3538209
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #4
adrianandres commentedComment #5
rszrama commentedQuick fix needed: the logic of the
use_two_step_add_payment_formsetting is backwards. If it's set toTRUE, then we should use the old style two step form, not if it's set toFALSE.From an update standpoint, I think it's fine for the new version of the form to be the default. Howver, it is fair to question whether or not that breaks backend interfaces or test suites for existing sites. We'll certainly document the change in the release notes, but let's also add an update hook that doesn't actually change anything but displays the following message to users who update:
Otherwise this looks and functions great! Still ways we can improve the styling of the form (e.g., fixing order total summaries, limiting the form width, etc.), but let's consider that out of scope for this ticket.
Comment #6
jsacksick commented@imbatman: Thank you for this.
I haven't tested this manually, but we have to fix the broken tests. I think we need to keep the tests coverage for the existing form, since we're retaining it, while also introducing tests for the new form.
Additionally, couple of possible improvements:
PaymentForm::class(this prevents mistakes).OrderPaymentAddFormor justOrderPaymentForm?Overall, what's actually really good about the new approach is that the logic was broken down into separate methods, which allows a child implementation to override specific parts of the code.
Comment #7
adrianandres commentedComment #8
jsacksick commentedNote that no actions buttons are shown when the payment gateway isn't onsite, so no way to submit a payment for manual gateways etc...
Comment #9
jsacksick commentedOk I'm now exposing the "Add payment" button for all payment options (not just onsite gateways).
A "payment_received" checkbox was added (label "Mark as received") for manual gateways.
Finally, the payment state isn't set to early as most of the createPayment() implementation out there expect a payment with a "new" state passed.
Comment #10
jsacksick commentedAttaching a static patch for Commerce 3.
Comment #11
adrianandres commentedComment #12
damienmckennaShould the setting be namespaced, e.g. "commerce_use_two_step_add_payment_form"?
Comment #13
jsacksick commented#12: definitely.
Comment #15
tbkot commentedConflicts in the MR are resolved, and a new test is added to check a new form to add payments
Comment #16
jsacksick commentedWe're close (I think) though I'm not sure if we kept coverage for the existing form? Or are we just testing the new form?
Let's rename the setting flag to:
commerce_payment_use_legacy_add_payment_formAlso commerce_payment_update_10303 has the following message:
So let's change x.y.z to 3.3.0. and let's actually update "you will need to set a variable in settings.php" to 'you will need to set the "commerce_payment_use_legacy_add_payment_form" variable in settings.php'.
Comment #17
tbkot commented@jsacksick
Tests check only the new form. For the old implementation, we need to set the "commerce_payment_use_legacy_add_payment_form" setting to TRUE in the test. Do we need that?
Comment #19
jsacksick commented