-
Notifications
You must be signed in to change notification settings - Fork 9.4k
Carrier codes with '_' (underscores) break several payment API's #13902
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
@thlassche, thank you for your report. |
@magento-engcom-team I saw this when using it in combination with onestepcheckout. Please see here for the code that's definitely wrong in my opinion: You can't explode by '_', compare it with this one: |
I have this same problem with Magento 2.1.12. And only with logged in customers. This problem does not seem to affect guest checkout. The bpost shipping carrier has carrier codes with underscores, like:
The code in
I'm still looking where something like In my opinion there are two options here:
|
As a temporary solution (at least for 2.1.12) I came op with a plugin that fixes this for 99.9%.
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<!--
Addresses GITHUB-13902, where logged in customers cannot use shipping carriers that contain an underscore
@see https://github.com/magento/magento2/issues/13902
-->
<type name="Magento\Checkout\Model\PaymentInformationManagement">
<plugin name="fix-carriers-with-underscore-bug" type="Vendor\Module\Plugin\Magento\Checkout\Model\PaymentInformationManagement"/>
</type>
</config>
<?php
namespace Vendor\Module\Plugin\Magento\Checkout\Model;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Quote\Api\CartRepositoryInterface;
use Magento\Quote\Api\Data\AddressInterface;
use Magento\Quote\Api\Data\PaymentInterface;
use Magento\Quote\Api\PaymentMethodManagementInterface;
use Magento\Store\Model\ScopeInterface;
/**
* Class PaymentInformationManagement
* @package Vendor\Module\Plugin\Magento\Checkout\Model
*/
class PaymentInformationManagement
{
/**
* @var PaymentMethodManagementInterface
*/
protected $paymentMethodManagement;
/**
* @var ScopeConfigInterface
*/
protected $scopeConfig;
/**
* @var CartRepositoryInterface
*/
protected $cartRepository;
/**
* PaymentInformationManagement constructor.
* @param PaymentMethodManagementInterface $paymentMethodManagement
* @param ScopeConfigInterface $scopeConfig
* @param CartRepositoryInterface $cartRepository
*/
public function __construct(
PaymentMethodManagementInterface $paymentMethodManagement,
ScopeConfigInterface $scopeConfig,
CartRepositoryInterface $cartRepository
) {
$this->paymentMethodManagement = $paymentMethodManagement;
$this->scopeConfig = $scopeConfig;
$this->cartRepository = $cartRepository;
}
/**
* @param \Magento\Checkout\Model\PaymentInformationManagement $subject
* @param callable $proceed
* @param $cartId
* @param PaymentInterface $paymentMethod
* @param AddressInterface|null $billingAddress
* @return bool
* @throws \Magento\Framework\Exception\NoSuchEntityException
* @throws \Magento\Framework\Exception\State\InvalidTransitionException
*/
public function aroundSavePaymentInformation(
\Magento\Checkout\Model\PaymentInformationManagement $subject,
callable $proceed,
$cartId,
PaymentInterface $paymentMethod,
AddressInterface $billingAddress = null
) {
if ($billingAddress) {
/** @var \Magento\Quote\Model\Quote $quote */
$quote = $this->cartRepository->getActive($cartId);
$quote->removeAddress($quote->getBillingAddress()->getId());
$quote->setBillingAddress($billingAddress);
$quote->setDataChanges(true);
$shippingAddress = $quote->getShippingAddress();
if ($shippingAddress && $shippingAddress->getShippingMethod()) {
$shippingDataArray = explode('_', $shippingAddress->getShippingMethod());
$shippingCarrier = array_shift($shippingDataArray);
// Start fix for GITHUB-13902
while (!$this->isExistingCarrier($shippingCarrier)) {
$shippingCarrier .= '_' . array_shift($shippingDataArray);
}
// End fix for GITHUB-13902
$shippingAddress->setLimitCarrier($shippingCarrier);
}
}
$this->paymentMethodManagement->set($cartId, $paymentMethod);
return true;
}
/**
* @param string $shippingCarrier
* @return bool
*/
protected function isExistingCarrier(string $shippingCarrier): bool
{
$carrierConfig = $this->scopeConfig->getValue('carriers/' . $shippingCarrier, ScopeInterface::SCOPE_STORE);
return !empty($carrierConfig);
}
} The 0.1% that is not fixed is if there are carriers that have matching names with underscores. For example: Another risk is an infinite loop if the store owner deletes or disables the selected carrier in between selecting the shipping method and completing the order :-P |
@kanduvisla Thanks, added the login step to the steps to reproduce section |
having the same problem in 2.1.11 since the carrier code is just determined by exploding the shipping method with '_'. For every shipping carrier containing an underscore the checkout does not work anymore For 2.1 this was introduced in the update from 2.1.10 to 2.1.11 |
@irenelagno or @nmalevanec: since you guys introduced this code in 3495e60 and 179f984, would you be so kind to review the above discussion and see if there is a good solution for this problem? @kanduvisla: would using a regular expression to try and extract the carrier work as well? Something like |
@hostep: I don't exactly understand what you mean. The problem is that Magento concatenates the carrier code and the shipping method as one string, and later on tries to 'guess' it back, using a string. This works great for codes like
Now Magento gets the string
edit: @hostep: upon reading your comment again I do know what you mean and no: carrier code and shipping method are not always the same. They are often the same if a carrier only has one method, but it's perfectly fine for a carrier to have multiple shipping methods. In that case the code of the shipping method differs. |
Imo this is a pretty serious issue; If Magento would choose not to allow an underscore in the carrier code & method there will be a lot of people unhappy and a lot of extra work will be needed for people to fix this. Of the above solutions I would prefer the 3th option as it indeed follows carrier/method model. |
In M1, I've seen shipping method codes with |
Thanks for the feedback all! I've had some chance to dig into this a bit further in the mean time. So here's my opinion: So we need to replace the splitting of carrier & shipping method with underscore by something else, that was indeed M1 behavior, but I don't think it applies to M2 anymore. The carrier code should be available without extracting it out of another string. The only thing we need is figure out a way to replace these lines with the carrier code which we need to get from somewhere. The question is: where should we get it from? Possible solutions:
Just my 2 cents. Maybe @magento-engcom-team can try to invite some core devs in here to figure out the best solution for this problem? |
although it might be a bigger change, I think it would solve the problem for good to separate carrier code and shipping method code. They are separated (and also needed to be separated) nearly everywhere. Only at this point in the database for some reason they are merged. This really makes no sense. |
I would also give my +1 to separate the carrier code and shipping method code in the database. It makes it much more consistent and easier to work with. But I also would like to hear what @magento-engcom-team has to say about this. For example:
|
I've just noticed this wiki page, so let's try to get @paliarush involved in here since he is in charge of the Checkout modules. |
I have also encountered this bug after upgrading M2.1 to M2.2. It took a while to debug this issue. I have made a small module which has the fix from @kanduvisla. It can be found here: |
Confirming we're also seeing this issue. @paliarush — are we able to get confirmation that this can be treated as a bug that needs to be fixed? |
@thlassche thanks for reporting the issue. Internal ticket has been created MAGETWO-92416 |
@thlassche, thank you for your report. |
In Magento 2.2.6 I experienced the issue again. The problem now also seem to persist in Too bad this is a private method, this makes the temporary fix uglier ... :-( |
Hi @vpodorozh. Thank you for working on this issue.
|
- update the click and collect method instance name to remove the underscore - ensures backwards-compatibility is maintained for orders already created using the older method instance name - resolves a magento core bug introduced in Magento v2.1 with regards to handling shipping methods that contain an underscore in the instance name (magento/magento2#13902) Signed-off-by: Matthew Muscat <[email protected]>
Hi folks It looks like this issue gets resolved by the following PR's. For Magento 2.3:
For Magento 2.2:
I've verified the fix for logged in users, not yet for guest users as I was using Magento 2.2.3 for my testing. Update 2019-02-19: added backport for guest users for Magento 2.2 |
I just wasted two days of work because of this issue. Magento concatenates the carrier code and shipping method with underscores: Up_Express and uses explode('_') and unshift() to get the name of the carrier and put it on setLimitCarrier() hence it only gets the part of the name before the underscore even tho the name is properly stored in the database and everything! |
Hello @thlassche @VitorGit @hostep Thank you all for contribution and collaboration! As I can see from the comment #13902 (comment) the issue is fixed and delivered There is Open PR #21340 that will be processed and delivered soon. |
Hi @thlassche. Thank you for your report. The fix will be available with the upcoming 2.2.9 release. |
so is the solution to not use underscores in either the carrier or the method? It's kinda scary that such a simple thing can have such devastating impact. Is modifying the order table to store the carrier and method separately not an option? This is closed, but is very much still an issue, as explained by the #31311 issue. Is the quick solution to modify any custom shipping method or carrier that has an underscore to use a hyphen or something instead? |
Uh oh!
There was an error while loading. Please reload this page.
Preconditions
Steps to reproduce
Expected result
Actual result
The cause of this is several explode's by '_' in the code, where
$addressInformation->getShippingCarrierCode()
should have been used in my opinion. Example: https://github.com/magento/magento2/blame/2.3-develop/app/code/Magento/Checkout/Model/PaymentInformationManagement.php#L118The text was updated successfully, but these errors were encountered: