magento2: Carrier codes with '_' (underscores) break several payment API's
Preconditions
- Magento version >= 2.2
Steps to reproduce
- Create a carrier with carrier code ‘test_carrier’ for example config.xml:
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
<default>
<carriers>
<test_carrier>
<active>1</active>
<title>Flatrate</title>
<name>Flatrate 1</name>
<price>0</price>
<model>Namespace\Vendor\Model\Carrier\Flatrate1</model>
<sallowspecific>0</sallowspecific>
<specificerrmsg>This shipping method is not available.</specificerrmsg>
</test_carrier>
</carriers>
</default>
</config>
- Login as customer
- Go to the checkout, select created carrier and see that for example POST set-payment-information fails
Expected result
- Order placement works
Actual result
- Several web api request fail with 400 bad request, please specify a shipping method
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#L118
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 5
- Comments: 25 (22 by maintainers)
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?
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 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: https://github.com/EliasKotlyar/Twinsen_CarrierCodeFix/tree/master
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:
@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
flatrate_flatrate, ordhl_express, but what if you have:foowith the methodfoo_foo, and:foo_foowith the methodfoo.Now Magento gets the string
foo_foo_foo. How can it determine which carrier / method are chosen here? I think the main issue here is an architectural one: because theshipping_methodis saved as a concatenated string, issues like this are unavoidable. This can be fixed in various ways:carrier_codeandshipping_method, stating that it cannot contain an underscore (might break several carrier modules).carrier_code::shiping_method). Might break BC for older quotes / orders that already exist in the database).shipping_method-column in database with extracarrier_code-column. Might be a big commit to the code, but is more in line with the carrier/method-model, and BC can be achieved by checking ifcarrier_codeisnullin the database.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.
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
see: https://github.com/magento/magento2/blob/2.1-develop/app/code/Magento/Checkout/Model/PaymentInformationManagement.php#L124
For 2.1 this was introduced in the update from 2.1.10 to 2.1.11
As a temporary solution (at least for 2.1.12) I came op with a plugin that fixes this for 99.9%.
di.xml:app/code/Vendor/Module/Plugin/Magento/Checkout/Model/PaymentInformationManagement.php:The 0.1% that is not fixed is if there are carriers that have matching names with underscores. For example:
carrier_fooandcarrier_foo_bar. In this case, whencarrier_foo_baris selected, it will be rebuild and matched withcarrier_foo. But as I said: it’s a temporary fix and it’s currently design to only work in my situation but perhaps it will help someone.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 😛
@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:
https://github.com/magento/magento2/blame/2.3-develop/app/code/Magento/Checkout/Model/PaymentInformationManagement.php#L118
You can’t explode by ‘_’, compare it with this one:
https://github.com/magento/magento2/blob/2.3-develop/app/code/Magento/Checkout/Model/ShippingInformationManagement.php#L160