Skip to content

Instant purchase "cheapest shipping" broken for configurable products #38811

Closed
@Tomasito665

Description

@Tomasito665

Preconditions and environment

(1) Install magento

  • Do a composer-based installation of magento 2.4.7. We need the magento/inventory modules for in-store delivery, which are not part of the core magento repository but are automaticallMore colorsy included for composer-based installations.

  • Deploy sample data into your Magento installation. The steps described in this issue assume this sample data to be installed. See https://github.com/magento/magento2-sample-data for more info.

  • Install the [magento-instant-purchase-mock](https://github.com/Tomasito665/magento-instant-purchase-mock/tree/main] extension. This extension was designed specifically for this issue and does minimal surgical changes to magento's InstantPurchase module to enable the Instant Purchase button without installing and configuring [Payment Services|https://experienceleague.adobe.com/en/docs/commerce-merchant-services/payment-services/guide-overview] or [Braintree|https://experienceleague.adobe.com/en/docs/commerce-admin/stores-sales/payments/braintree), which is normally required for enabling instant purchase functionality but is not necessary for the demonstration of this bug.

(2) Set up in-store delivery

  • Enable in-store pickup

    • In the admin page, go to Stores → Configuration → Sales → Delivery Methods → In-Store Delivery.
    • Set Enabled to Yes.
  • Create in-store pickup source

    • In the admin page, go to Stores → Inventory → Sources.
    • Click on Add New Source, and fill in the following.
      • Name: ISPU source
      • Code: ispu_source
      • Is Enabled: Yes
      • Description: ISPU source
      • Latitude: 30.258726
      • Longitude: -97.753063
      • Use As Pickup Location: Yes
      • Contact Name: ISPU
      • Email: ispu_source@hotmail.com
      • Phone: 123456789
      • Country: United States
      • State/Province: Texas
      • City: Austin
      • Street: 123 Test St
      • Postcode: 78758
      • Pickup Name: ISPU
      • Frontend Description: ISPU
    • Click on Save & Continue.
  • Create in-store pickup stock

    • In the admin page, go to Stores → Inventory → Stocks.
    • Click on Add New Stock, and fill in the following.
      • Name: ISPU stock
      • Websites: Main Website
      • Assign Sources: ISPU source
    • Click on Save & Continue.

(3) Enable products for in-store pickup

  • Assign simple product to ISPU source

    • In the admin page, go to Catalog → Products.
    • Find the Joust Duffle Bag (should be the first product) and click on Edit.
    • Under Sources, click on Assign Sources.
    • Select the ISPU source and click on Done.
    • Set the ISPU source to In stock and Qty to 100.
    • Click on Save.
  • Assign configurable product to ISPU source

    • In the admin page, go to Catalog → Products.
    • In the Search by keyword textbox, fill in “Chaz Kangeroo Hoodie” and press Enter.
    • Click on the checkbox in the table header and click on Select All — should select 16 records.
    • Under Actions, click on Transfer Inventory to Source, and fill in.
      • Transfer from the origin source: Default Source
      • To the destination source: ISPU source
      • Unassign the origin source from selected products after transfer: No
    • Click on Transfer Inventory.

(4) Configure flat rate as the cheapest option

  • In the admin page, go to Stores → Configuration → Sales → Delivery Methods.
  • Under Flat Rate, make sure that Enabled: Yes, and Price: 5.00 (= default values).
  • Under In-Store Delivery, set Price to 6.00, i.e., more expensive than Flat Rate.

(5) Create a customer account

  • On the frontend page, click on Create an Account to create a customer account.

  • Once logged in, go to My Account → Address Book → Default Billing Address.

  • Click on Edit Address and fill in the following.

    • First Name: John
    • Last Name: Smith
    • Phone Number: 123456789
    • Street Address: 123 Test St
    • Country: United States
    • State/Province: Texas
    • City: Austin
    • Zip/Postal Code: 78758
  • Make sure that the address appears both as:

    • Default Billing Address
    • Default Shipping Address
  • Log out and log in again to refresh instant purchase options.

(6) Verify that in-store delivery is available

Try purchasing a Joust Duffle Bag and a Chaz Kangeroo Hoodie through the checkout flow using in-store delivery. We assigned stock for both products to our in-store delivery source in step 3. Thus, in-store delivery should be available for both. Furthermore, we configured in-store delivery to cost 6$, which is more expensive than the 5$ flat-rate shipment method. These prices should show on the checkout page as seen in the screenshots below.

Simple product checkout Configurable product checkout
Step6*CheckoutSimpleProduct Step6*CheckoutConfigurableProduct

(7) Verify that instant purchase is available

Open any product detail page and ensure that the Instant Purchase button renders. If it does not, make sure that the Magento_InstantPurchaseMock module is correctly installed and enabled as described in step 1. Also, the Instant Purchase button only renders if you are logged in as a customer and if that customer has both a default billing and a default shipping address. Make sure these addresses are properly configured as described in step 5.

Instant Purchase button
Step7_InstantPurchaseButton

Steps to reproduce

  • On the frontend page, make sure you are logged in with the previously created customer account.
  • Click on the “Search entire store here…” textbook, type “Chaz Kangeroo Hoodie”, and press Enter.
  • There should be only one result. Click on it to open the product details page for “Chaz Kangeroo Hoodie”.
  • Click on the Instant Purchase button. You’ll see a confirmation popup with Shipping Method: Cheapest price.
  • Click on OK to confirm the purchase.

Expected result

The order is placed using the cheapest shipment method, which, as we saw in step 6, is the $5.00 Flat Rate shipment method.

<img width="1124" alt="Expected behavior" src="https://github.com/magento/magento2/assets/12563382/541e573b-0e3a-4174-b066-1f1c4f99160f"]

Actual result

The order is placed using the $6.00 In-Store Delivery shipment method, which is NOT the cheapest shipment method.
{quote}[!NOTE]
{quote}
{quote}As seen in the screenshot, with my setup, the order placement does not finish successfully and ends with a "Quote does not have Pickup Location assigned" error. The cause of this error is irrelevant to the bug described in this issue. However, the fact that it gives this error in particular shows that the instant purchase flow attempts to place the order using the In-Store Delivery shipment method, which is sufficient to demonstrate the bug.
{quote}
[img width="1136" alt="ActualBehavior_2of2" src="https://github.com/magento/magento2/assets/12563382/bce0144a-5faf-4f2e-9487-4da90f8315df">

Additional information

It works for simple products

While the "cheapest price" shipment method does not work for configurable products, it does work for simple products—see screenshots below.

For simple products ... ... it works
ExpectedBehavior*1of2 ExpectedBehavior*2of2

Flat rate counted double for configurable products 🐛

The "cheapest price" shipment method is calculated in the CheapestMethodDeferredChooser class in the following method. The $5.00 Flat Rate shipping is not correctly identified as the cheapest option because, for reasons unclear to me, its price is doubled when performing the comparison to the $6.00 In-Store Delivery.
<https://github.com/magento/magento2/blob/001e5188cd59309f5de9205946ede5ddccdadaff/app/code/Magento/InstantPurchase/Model/ShippingMethodChoose/CheapestMethodDeferredChooser.php#L35-L50]

When debugging the instant purchase of the Joust Duffle Bag simple product, we see that the $shippingRates array contains the following rates.

``{{javascript
[
{_data:

Unable to find source-code formatter for language: "flatrate_flatrate", carrier: "flatrate", price: 5.0, .... Available languages are: actionscript, ada, applescript, bash, c, c#, c<ins></ins>, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yaml{code}
, ...},
{_data:
{code}
Unable to find source-code formatter for language: "instore_pickup", carrier: "instore", price: 6.0, .... Available languages are: actionscript, ada, applescript, bash, c, c#, c<ins></ins>, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yaml{code}
, ...},
{_data:
{code}
Unable to find source-code formatter for language: "tablerate_bestway", carrier: "tablerate", price: 15.0, .... Available languages are: actionscript, ada, applescript, bash, c, c#, c<ins></ins>, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yaml{code}
, ...},
]
}}``

However, when debugging the instant purchase of some permutation of the Chaz Kangeroo Hoodie configurable product, we see that the `$shippingRates` array contains different rates—double flat rate price.

``{{javascript
[
{_data:
{code}
Unable to find source-code formatter for language: "instore_pickup", carrier: "instore", price: 6.0, .... Available languages are: actionscript, ada, applescript, bash, c, c#, c<ins></ins>, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yaml{code}
, ...},
// twice the 5.00 flat rate shipment method item price for only 1 item 💥👇
{_data:
{code}
Unable to find source-code formatter for language: "flatrate_flatrate", carrier: "flatrate", price: 10.0, .... Available languages are: actionscript, ada, applescript, bash, c, c#, c<ins></ins>, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yaml{code}
, ...},
{_data:
{code}
Unable to find source-code formatter for language: "tablerate_bestway", carrier: "tablerate", price: 15.0, .... Available languages are: actionscript, ada, applescript, bash, c, c#, c<ins></ins>, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yaml```
, ...},
]
}}``

In this case, Flat Rate costs not the expected $5.00 but $10.00, which is indeed not the cheapest option anymore. In that case, the $6.00 In-Store Delivery shipment is the cheapest method, which explains why the instant purchase flow attempts to place the order using in-store delivery. I believe that the crux of the issue boils down to why the price is doubled for configurable products. It clearly shouldn't. Even though for configurable products there are two items (parent and child), there is only one item shipped (= child). So, the Flat Rate item price should be $5.00, not $10.00.
### Release note

"magento/product-community-edition": "2.4.7"

### Triage and priority
 - [ ] Severity: **S0** *- Affects critical data or functionality and leaves users without workaround.*
 - [X] Severity: **S1** *- Affects critical data or functionality and forces users to employ a workaround.*
 - [ ] Severity: **S2** *- Affects non-critical data or functionality and forces users to employ a workaround.*
 - [ ] Severity: **S3** *- Affects non-critical data or functionality and does not force users to employ a workaround.*
 - [ > Severity: **S4** *- Affects aesthetics, professional look and feel, “quality” or “usability”.*

Metadata

Metadata

Assignees

Labels

Issue: On HoldPriority: P1Once P0 defects have been fixed, a defect having this priority is the next candidate for fixing.Progress: doneReported on 2.4.7Indicates original Magento version for the Issue report.

Type

No type

Projects

Status

Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions