Magento 2, logged-in customer can't place order, new shipping method, cartId = null

by someGuyOnTheWeb   Last Updated April 04, 2018 10:09 AM

Intro: While developing a custom extension, that is creating a custom shipping method (pickup type) and extending Magento2 Checkout, an issue came up with order creation.
The issue - logged in customers can't place orders (not-logged-in ones can place orders).

Details Lets call the custom extension vendor_extension.

  1. The vendor_extension adds custom shipping method (method:click_and_collect). Here is the model creating the method:
namespace Vendor\Extension\Model\Carrier;

 use Magento\Quote\Model\Quote\Address\RateRequest;
 use Magento\Shipping\Model\Carrier\AbstractCarrier;
 use Magento\Shipping\Model\Carrier\CarrierInterface;

 class ClickAndCollect extends AbstractCarrier implements  CarrierInterface
 {
    protected $_code = 'click_and_collect';
    protected $_isFixed = true;
    protected $_rateResultFactory;
    protected $_rateMethodFactory;
    public function __construct(

        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
        \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory,
        \Psr\Log\LoggerInterface $logger,
        \Magento\Shipping\Model\Rate\ResultFactory $rateResultFactory,
        \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory,
        array $data = [] - List item
    ) {660b2d37306b1d83fe82c17b8adbeb99
        $this->_rateResultFactory = $rateResultFactory;
        $this->_rateMethodFactory = $rateMethodFactory;
        parent::__construct($scopeConfig, $rateErrorFactory, $logger, $data);
    }
660b2d37306b1d83fe82c17b8adbeb99
    public function collectRates(RateRequest $request)
    {
        $result = $this->_rateResultFactory->create();
        $method = $this->_rateMethodFactory->create();
        $method->setCarrier('click_and_collect');
        $method->setCarrierTitle('click_and_collect');
        $method->setMethod('click_and_collect');660b2d37306b1d83fe82c17b8adbeb99
        $method->setMethodTitle('click_and_collect');
        $amount = $this->getConfigData('price');2
        $method->setPrice($amount);
        $method->setCost($amount);
        $result->append($method);660b2d37306b1d83fe82c17b8adbeb99
        return $result;       
    }
    public function getAllowedMethod()
    {
        return ['click_and_collect' => $this->getConfigData('name')];22
    }
}
  1. For the checkout, it overrides in the extension's checkout_index_index.xml, <item name="shippingMethodItemTemplate" xsi:type="string"> <item name="shippingMethodListTemplate" xsi:type="string"> shippingMethodListTemplate and shippingMethodItemTemplate are irrelevant, for the question, I can provide the code if need be.

  2. There is also a mixin, which creates a few knockout.js methods/vars for usage in the templates.

Steps 1. A user, logged-in or not, enters the Checkout, selects "click_and_collect" shipping method, enters checkout#payments step, hits "Place Order" button:

1.1 Not-logged-in user - order is placed, redirect to success screen happens, the new order is visible in admin panel.

1.2. Logged-in user - an error message pops-up

email is required field.

1.2.1 After that I edit vendor/magento/module-checkout/view/frontend/web/js/action/place-order.js to test, if overriding it, could solve the issue:

 {
    payload = {
        cartId: quote.getQuoteId(),
        billingAddress: quote.billingAddress(),
        paymentMethod: paymentData
    };
    if (customer.isLoggedIn()) {
        serviceUrl = urlBuilder.createUrl('/guest-carts/mine/payment-information', {});
        payload.email = window.customerData.email;
        window.quote = quote;
    } else {
        window.quote = quote;
        serviceUrl = urlBuilder.createUrl('/guest-carts/:quoteId/payment-information', {
            quoteId: quote.getQuoteId()
        });
        payload.email = quote.guestEmail;
    }
    return placeOrderService(serviceUrl, payload, messageContainer);660b2d37306b1d83fe82c17b8adbeb99
}
 

After that, the error message that originates from QuoteRepository.php changes to

No such entity with cartId = null

p.s. additional info, seems that quoteId/cartId for non-logged-in users are unique hash values like

660b2d37306b1d83fe82c17b8adbeb99

and for logged in customers are of type integer

int (6)

Guessing it is designed this way, to give ability to edit carts from previous sessions for registered customers. Naturally, I have split-screen compared mine shipping-method model against shipping-method models, that work for logged in customers.

p.s.tools used: analyzed via xdebug, die-var-dumps, browser-dev-tools-step-debugger and others.



Related Questions


Magneto 2 Shipping

Updated February 08, 2018 04:09 AM


Overriding Magento 1.9 interface

Updated August 21, 2016 08:03 AM

Table Rate Shipping Extension

Updated March 01, 2016 01:04 AM