magento / magento2

Prior to making any Submission(s), you must sign an Adobe Contributor License Agreement, available here at: https://opensource.adobe.com/cla.html. All Submissions you make to Adobe Inc. and its affiliates, assigns and subsidiaries (collectively “Adobe”) are subject to the terms of the Adobe Contributor License Agreement.
http://www.magento.com
Open Software License 3.0
11.54k stars 9.31k forks source link

getAdditionalInformation() is null when buying a virtual product #18255

Closed VirtusB closed 6 years ago

VirtusB commented 6 years ago

Other issues regarding this: https://github.com/magento/magento2/issues/13801 https://github.com/magento/magento2/issues/17302

Preconditions

  1. Magento 2.2.5
  2. Apache 2.2
  3. PHP 7.1
  4. Product is virtual
  5. Third party payment gateway

Steps to reproduce

  1. Use QuickPay or PayPal as payment module (issue is not with them)
  2. Add virtual product to cart
  3. Go to checkout, step 1 of checkout is skipped because product is virtual
  4. Select payment method and click "Place Order"

Expected result

  1. Order is placed successfully with a virtual product, just like simple products

Actual result

  1. 500 internal server error is returned in console (or redirect to 500 page)
  2. Following error "Call to a member function getAdditionalInformation() on null" is returned: image

The code that fails: $this->_objectManager->get('Magento\Checkout\Model\Session')->getLastRealOrder() If the product is virtual then getLastRealOrder() returns an empty order, getPayment() is therefore null and the error is thrown.

The full code of Redirect.php:

namespace QuickPay\Payment\Controller\Payment;

class Redirect extends \Magento\Framework\App\Action\Action
{
    protected $_logger;

    protected $orderRepository;

    public function __construct(
        \Magento\Framework\App\Action\Context $context,
        \Psr\Log\LoggerInterface $logger,
        \Magento\Sales\Api\Data\OrderInterface $orderRepository
    )
    {
        $this->_logger = $logger;
        $this->orderRepository = $orderRepository;

        parent::__construct($context);
    }

    protected function _getCheckout()
    {
        return $this->_objectManager->get('Magento\Checkout\Model\Session');
    }

    /**
     * Redirect to to QuickPay
     *
     * @return string
     */
    public function execute()
    {
        try {
            $order = $this->_getCheckout()->getLastRealOrder();

            $paymentLink = $order->getPayment()->getAdditionalInformation(\QuickPay\Payment\Gateway\Response\PaymentLinkHandler::PAYMENT_LINK);

            return $this->_redirect($paymentLink);
        } catch (\Exception $e) {
            $this->messageManager->addException($e, __('Something went wrong, please try again later'));
            $this->_logger->critical($e);
            $this->_getCheckout()->restoreQuote();
            $this->_redirect('checkout/cart');
        }
    }
}

Just to clarify: this is not an issue with any third party payment module - getPayment() is not supposed to return null when the product is virtual.

magento-engcom-team commented 6 years ago

Hi @VirtusB. Thank you for your report. To help us process this issue please make sure that you provided the following information:

Please make sure that the issue is reproducible on the vanilla Magento instance following Steps to reproduce. To deploy vanilla Magento instance on our environment, please, add a comment to the issue:

@magento-engcom-team give me $VERSION instance

where $VERSION is version tags (starting from 2.2.0+) or develop branches (for example: 2.3-develop). For more details, please, review the Magento Contributor Assistant documentation.

@VirtusB do you confirm that you was able to reproduce the issue on vanilla Magento instance following steps to reproduce?

magento-engcom-team commented 6 years ago

Hi @engcom-backlog-nazar. Thank you for working on this issue. In order to make sure that issue has enough information and ready for development, please read and check the following instruction: :point_down:

ghost commented 6 years ago

Hi @VirtusB, thank you for you report, This problem related to QuickPay not magento core, beacouse all payments in magento paylpal e.g are check if payment have additional information, for virtual product there are not, so if you use paypal or braintree everything will be ok.

Best regards.

VirtusB commented 6 years ago

@engcom-backlog-nazar So it's expected behaviour that getPayment() is null when the product is virtual, but not when the product is simple? getPayment() was not null in 2.2.4 even if the product was virtual, it wasn't a problem till 2.2.5

ghost commented 6 years ago

@VirtusB If product not virtual getPayment() not null, i'm checked with debugger for 2 payments paypal and braintree And have no issue on 2.2-devlop branch.

VirtusB commented 6 years ago

@engcom-backlog-nazar Exactly, if the product is not virtual then getPayment() is not null, but it shouldn't be null for virtual products either. getPayment() and getAdditionalInformation() should also work for virtual products, just like it did in 2.2.4 - how else are you supposed to retrieve the data? I'm sorry but I don't understand how this is intended. I'm not the only one with this issue, there are 2 links at the top that also mentions this.

ghost commented 6 years ago

@VirtusB Ok. but why i'm not able to reproduce your scenario ?

VirtusB commented 6 years ago

@engcom-backlog-nazar Maybe I misunderstood - when you tried, getPayment() was not null for virtual products? And getAdditionalInformation() worked? Did you use version 2.2.5 or 2.2.6? Thanks.

ghost commented 6 years ago

@VirtusB On 2.2-dev instance the same on 2.2.6 this works perfectly. selection_143