Free payments with custom Offsite Gateway

Created on 13 March 2025, 20 days ago

Describe your bug or feature request.

The new interface for handling free orders β†’ is great, but our sole offsite custom payment gateway does not yet implement this new interface.
Reference: commerce_touchnet_upay.

After exploring multiple approaches, I'm trying to determine the recommended solution.
Our options seem to be:

  • Assign the order to the manual payment gateway (but that gateway does not implement SupportsZeroBalanceOrderInterface, which enforces SupportsStoredPaymentMethodsInterface as I would have expected... follow-up issue?).
  • Implement SupportsZeroBalanceOrderInterface along with SupportsStoredPaymentMethodsInterface in commerce_touchnet_upay, upgrade to 3.x, and resolve the issue properly.

Context (Commerce 2.x):

In 2.x, we encountered an issue where a product with a price of $0 triggers an error in finalizeCart().
This happens because the payment gateway is null when processing a zero-value order.
Interestingly, this issue does not occur when a product is discounted to $0β€”only when its original price is $0, such as for a free event product.

As a workaround, we manually assign a payment gateway if none is set for a zero-value order:

/**
 * Implements hook_commerce_order_update().
 */
function MODULE_commerce_commerce_order_update(OrderInterface $order) {
  // Ensure the order has an assigned payment gateway for zero-value orders.
  if ($order->getTotalPrice()->isZero() && $order->get('payment_gateway')->isEmpty()) {
    $payment_gateway = PaymentGateway::load('upay');
    if ($payment_gateway) {
      $order->set('payment_gateway', $payment_gateway->id());
      $order->save();
    }
  }
}

Steps to reproduce (clean install):

  1. Enable an offsite payment gateway.
  2. Create a product with a price of $0.
  3. Proceed to checkout.
  4. Encounter errors:
    • In 3.x: There are no payment gateways available for this order. (when the interface is not implemented).
    • In 2.x: Error: Call to a member function getPlugin() on null in Drupal\commerce_cart\CartProvider->finalizeCart() (line 127 of commerce/modules/cart/src/CartProvider.php).

Request for Guidance:

Should we:

  • Assign free orders to the manual payment gateway despite it not implementing SupportsZeroBalanceOrderInterface?
  • Implement SupportsZeroBalanceOrderInterface and SupportsStoredPaymentMethodsInterface in commerce_touchnet_upay?
  • Handle this scenario differently?

Any recommendations would be appreciated! I made this a support request because it's been reported in various other ways including the parent related issues, and it's more of a question on the correct approach to take from maintainers

πŸ’¬ Support request
Status

Active

Version

3.0

Component

Developer experience

Created by

πŸ‡¨πŸ‡¦Canada joelpittet Vancouver

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Production build 0.71.5 2024