Problem / motivation

When a payment method is selected during checkout, it is not used to make a payment.

Proposed resolution

Perform the payment transaction when the checkout complete event is fired.

Remaining tasks

  1. Implementation
  2. Tests
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

steveoliver created an issue. See original summary.

steveoliver’s picture

Assigned: steveoliver » Unassigned
Status: Active » Needs work

From the PR: "This works, but needs some cleanup (see @todos). Also needs test(s) - I tried in https://gist.github.com/steveoliver/3135b75b573d0fb902ebc7cf23426505#fil..., but had issues getting a payment method to be created this way. I'd like someone else to take it from here."

mglaman’s picture

So I have concerns about the event listener.

With 'commerce_order.place.post_transition' => 'onOrderPostPlace', the event will run on admin placed orders and checkout. Checkout and admin have two flows, in my opinion. With checkout an order collects payment information before being placed. An admin workflow probably leads to an order being placed then collecting payment. We cannot always assume we have payment method information on the placed transition, only when in the checkout context.

steveoliver’s picture

Assigned: Unassigned » steveoliver
Status: Needs work » Active

Ah, good point. I'll take another look at it.

steveoliver’s picture

The way forward is to use (re-add) the Checkout complete event.

steveoliver’s picture

We also need a way to create a payment transaction with knowledge of whether to capture or not.

ChrisGrewe’s picture

Steve, building on what bojanz said here in #2822056, could your code potentially work in CheckoutFlowBase::validateForm (with a similar condition to what's firing the complete event) to create the payment? We could trap any exceptions there and redirect back to the current step with an error message if the payment fails or proceed to complete if it's good.

ChrisGrewe’s picture

I'm working on a payment processor implementation right now, so I went ahead and took Steve's code from the event listener and moved it to CheckoutFlowBase::validateForm (with appropriate conditionals and one minor fix, which was to use the $payment_gateway->id() for the payment gateway as opposed to the plugin ID, which only worked if the name of the plugin for the gateway was the same as the gateway plugin's ID). This seemed to work for me and could be used as a starting point at least. We'd needed a dependency on commerce_payment added to commerce_checkout if this is to work though.

steveoliver’s picture

@ChrisGrewe, we won't be able to make a dependency for commerce_payment in commerce_checkout -- the modules are intended to not be required. We will need to find a way to safely support payments on checkout without the hard dependency.

I'll see what I can come up with.

steveoliver’s picture

Status: Active » Needs review

Attached patch moves payment creation into payment module by setting values on form_state in checkout, signifying that the form is a commerce_checkout_form and when it is complete. No dependency between modules. May need some tweaking and there are follow-up todos, but this seems to work. Needs a test or two.

steveoliver’s picture

FileSize
7.57 KB

Whoops, patch attached.

steveoliver’s picture

FileSize
4.15 KB

Attaching actual patch, last one was interdiff.

nikathone’s picture

Tested patch #12 with commerce braintree and dev version of commerce module and it seems to be working.

mglaman’s picture

Assigned: steveoliver » mglaman
Status: Needs review » Needs work

Going to take a stab at wrapping this up. Here's a tl;dr of what I discussed with bojanz that will help support onsite and offsite payment gateways

  • All checkout flows have the offsite_payment step
  • Rename aforementioned step to "payment"
  • The payment_information will allow selecting payment gateway and selecting payment method if an onsite gateway
  • Create a new pane called payment_process that lives on Payment page
  • If the gateway is an onsite gateway, run createPayment w/ auth/capture setting
  • If the gateway is offsite, do redirect

This then places all payment collection logic in one place. Onsite payments will provide the form redirect based on success or failure.

mglaman’s picture

mglaman’s picture

FileSize
29.26 KB

Came across an issue that I think we should handle in a follow-up. On-site payment gateways will cause the payment page to be skipped (we have a payment method and we run it to create a payment.) This only needs to be present when the user has selected an offsite payment gateway.

I have messed around with ::isVisible a bit but there isn't a good solution. I tried to return FALSE if the gateway was OnSite, but then it caused the page to be skipped. But this was also an issue in 1.x with the checkout progress module.

bojanz’s picture

  • bojanz committed 2181872 on 8.x-2.x authored by mglaman
    Issue #2820931 by steveoliver, ChrisGrewe, mglaman: Perform payment...
bojanz’s picture

Status: Needs work » Fixed

BOOM!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.