Hello,

I've finally ended up creating a new issue, because this issue is driving me crazy. Working on commerce_funds I'm trying to implement a new plugin class for PaymentInformation. The issue is that the checkout flow never goes to the process payment. I can complete it and ends up to the completion message but it just jumps over the payment process.

As requested in the comment (Drupal\commerce_checkout\Plugin\Commerce\CheckoutPane\CheckoutPaneBase\PaymentInformation) I have implemented hook_commerce_checkout_pane_info_alter(array &$panes) to point payment_information to my class, but still, it doesn't work.

The plugin DepositPaymentInformation is an extension of PaymentInformation class and I'm basically just adding a bit of code to it, Otherwise, the class is the same.

Am I doing something wrong or is it a bug? I'm willing to help, but have investigated a lot already and still didn't get the full structure/relationship between the panes. From my investigations, it could be the call to the hook which is called too late. I've dumped the variables from the checkout controller on "review" page in attachment (same as the other screenshot).

Any help, guidance, will be appreciated.

Thanks.

Comments

Aporie created an issue. See original summary.

bojanz’s picture

I have trouble seeing what's actually going wrong. Could you try describing again?

Also, can you share your hook?

aporie’s picture

When being at the Review pane, whereas having the option to pay and complete the order, I just have the "complete checkout" form submit button. So no payment is made.

Here is my hook :

function commerce_funds_commerce_checkout_pane_info_alter(array &$panes) {
  $panes['payment_information']['id'] = 'funds_payment_information';
  $panes['payment_information']['class'] = 'Drupal\commerce_funds\Plugin\Commerce\CheckoutPane\DepositPaymentInformation';
  $panes['payment_information']['provider'] = 'commerce_funds';
}

I've changed every parameter just for testing.

aporie’s picture

Issue summary: View changes
bojanz’s picture

You must not change $panes['payment_information']['id'], the whole point of the alter hook is to replace the class without changing the ID.

aporie’s picture

Yeah, the result is the same if I just alter the "class". So I think it's probably an issue. I wasn't sure I wasn't doing something wrong.

You know where this hook lives?

bojanz’s picture

It's fired by CheckoutPaneManager, but it's essentially core plugin code. We've had no issues with the hook so far.

Make sure that DepositPaymentInformation doesn't have an annotation of its own.
If it does, you might have have accidentally configured your checkout flow to use that pane instead of the original Payment information one.

aporie’s picture

StatusFileSize
new57.98 KB

But yes I do, I've implemented it like a new plugin as it was what I wanted to achieve.

I want to replace PaymentInformation pane by DepositPaymentInformation pane. Indeed I could alter the default pane but I want to make specific entities and plugin for commerce_funds as it'll give me more flexibility in case I need them in the future.
Checkout flow

I feel like this hook is fired and then overwritten by something which put it to its first value. I think an easy way to reproduce the issue is to make any custom plugin which extends PaymentInformation and to put it in the checkout flow in place of PaymentInformation, you'll end up jumping over the payment process ...

bojanz’s picture

Your screenshot confirms that your checkout flow is misconfigured.

"Payment information" is supposed to be enabled. That is the entry that you're pointing to your class via the alter hook.
"Deposit payment information" should not be enabled (and is better off not shown altogether).

aporie’s picture

StatusFileSize
new136.72 KB

Ok, I think I got the logic but still doesn't work.

I have re-enabled PaymentInformation as the pane for "order information". I still have my hook altering the class to DepositPaymentInformation. I've tried with

- DepositPaymentInformation as a plugin (with annotation) and disabled.
- DepositPaymentInformation as a regular class (without annotation).

It seems that it's just PaymentInformation pane which comes. I don't have my changes from my custom class.

On the attached picture, we should see the fees applied to each deposit payment method next to them.

Class overriden

Thanks for your time, it's been two days I'm on this ...

aporie’s picture

Status: Active » Fixed

Hey,

So, it has finally worked after reinstalling the module. It seems that clearing all caches is not enough. Thanks for the help.

For others, the way to override PaymentInformation is :

- Make a Class which extends PaymentInformation (no need to make a plugin, the class is needed to override PaymentInformation).
- Override PaymentInformation in the checkout flow with hook_commerce_checkout_pane_info_alter(array &$panes) {
$panes['payment_information']['class'] = 'Path\To\YourNewClass';
}

[Edit] Thanks for noticing. Indeed.

Status: Fixed » Closed (fixed)

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

cameron prince’s picture

In comment #11, the path to your class shouldn't use forward slashes... i.e. should be $panes['payment_information']['class'] = 'Path\To\YourNewClass';

mykola dolynskyi’s picture

Also having same problem for 1+ day.

So, does it mean that it is not possible to create custom PaymentInfo (and may be PaymentProcess?) plugin in a cool way where you pick required Panes via Commerce UI? Only must hardly replace class of core 'payment_information' in hook? Even with custom CheckoutFlow not possible?

UPDATE: found solution, see below ( https://www.drupal.org/project/commerce/issues/3023373#comment-14149243 )

mykola dolynskyi’s picture

@Aporie , you can use your custom PaymentInformation in way you planned (without hook):

/**
 * @CommerceCheckoutPane(
 *   id = "payment_information_aporie",
 *   label = @Translation("Payment information Aporie"),
 *   default_step = "order_information",
 *   wrapper_element = "fieldset",
 * )
 */
class PaymentInformationAporie extends PaymentInformation {
// ... do your magic here
}

but must create custom PaymentProcess also (and enable it in GUI)

/**
 * Provides the payment process pane.
 *
 * @CommerceCheckoutPane(
 *   id = "payment_process_aporie",
 *   label = @Translation("Payment process Aporie"),
 *   default_step = "payment",
 *   wrapper_element = "container",
 * )
 */
class PaymentProcessAporie extends PaymentProcess {
...
  // new function
  public function getPaymentInformationPane() {
    $panes = $this->checkoutFlow->getPanes();
    $name = 'payment_information';
    $namelen = strlen($name);
    $res = [];
    foreach($panes as $k => $p) {
      if( (substr($p->getId(), 0, $namelen) == $name) && $p->isVisible() && $p->getStepId() !== '_disabled') {
        $res[$k] = $p;
      }
    }
    if(count($res) > 1)
      throw new \RuntimeException("getPaymentInformationPane(): too much payment_information enabled");
    if(empty($res))
      throw new \RuntimeException("getPaymentInformationPane(): no payment_information enabled");
    
    return reset($res);
  }
  
  //overriden function
  public function isVisible() {
    if ($this->order->isPaid() || $this->order->getTotalPrice()->isZero()) {
      // No payment is needed if the order is free or has already been paid.
      return FALSE;
    }
    //$payment_info_pane = $this->checkoutFlow->getPane('payment_information');
    $payment_info_pane = $this->getPaymentInformationPane();
    if (!$payment_info_pane->isVisible() || $payment_info_pane->getStepId() == '_disabled') {
      // Hide the pane if the PaymentInformation pane has been disabled.
      return FALSE;
    }

    return TRUE;
  }

  //overriden function
  protected function getErrorStepId() {
    // Default to the step that contains the PaymentInformation pane.
    $payment_info_pane = $this->getPaymentInformationPane();
    $step_id = $payment_info_pane->getStepId();
    //$step_id = $this->checkoutFlow->getPane('payment_information')->getStepId();
    if ($step_id == '_disabled') {
      // Can't redirect to the _disabled step. This could mean that isVisible()
      // was overridden to allow PaymentProcess to be used without a
      // payment_information pane, but this method was not modified.
      throw new \RuntimeException('Cannot get the step ID for the payment_information pane. The pane is disabled.');
    }

    return $step_id;
  }
...
}

tested this right now, is working

aporie’s picture

Hi Mykola,

Thanks for the update.

I'll take a look when I have a bit of time.