-
Notifications
You must be signed in to change notification settings - Fork 152
Alternative checkout flow proposal #192
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
Alternative checkout flow proposal #192
Conversation
* Gift cards | ||
* Store credit | ||
* Customer (optional) | ||
6. Place Order: Order |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we allow creating multiple quotas based on the single cart (quote segregation based on addresses), from my standpoint it makes sense to make order placement as an atomic operation which allows submitting multiple quotes. It runs us in another question - multiple payments handling together. but this also has a sense. Orders with different destination mean addresses may have different process flow which is fine. For example, the multi-tenant installation will require such functionality.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I second this, quotes split by shipping address should still be payable with a single payment during checkout. This has been a major limitation of the current design and is one of the reasons so few merchants utilize the multi address checkout. Having to do separate payments for each order makes the process incompatible with most current payment processors.
* Shipping (requited for physical products) | ||
* Addresses | ||
* Selected Shipping Methods | ||
* Billing address (required for virtual products). How to deal with multi-payment? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's reverse this question, can multiple quotes have the same payment method and billing address? In my opinion, this is a more relevant case for e-commerce. Definitely, for processing and querying, each order will have its own billing address but for creation argument, I would suggest to keep it as a single argument.
* Price | ||
4. Applicable cart rules calculator arguments | ||
* Cart | ||
* Addresses |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we need to pass some kind buyer representation here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As a response to a previous comment: the "buyer" that needs to be would be the customer.
* Selected Shipping Method | ||
* Billing address (required for virtual products). Need use cases | ||
* Coupons | ||
* Gift cards |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gift cards, coupons and store credits may be moved to the payment step.
* Cart rule discounts | ||
* Billing addresses | ||
* Shipping addresses | ||
* Coupons |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are coupons, gift card codes, store credit are not part of (price) Adjustments? It would make sense for quotes to accept a list of abstract PriceAdjustmentInterface which would be used when calculating totals and to show users which adjustments were applied to their cart/order/quote. I don't think that quote should explicetly rely on taxes, coupons etc. And there must be a mechanism for 3rd-party developers to add their own adjustments. Having an abstract PriceAdjustmentInterface DTO seems that quotes would receive seems like a step to that direction
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The checkout is a large and high impact store front API.
As such, I think it will likely have several design flaws that will only become obvious once it is in use (we are only human).
Fixing these flaws will will break backward compatibility. For this reason it would be good to release a new checkout API for public consumption without declaring it to be stable or deprecating existing APIs.
Please include a paragraph in the proposal head that the new API will be introduced alongside the current API and that the current API will not be deprecated until the new alternative checkout flow has matured and is widely in use.
Should the new API fail to be adopted by external developers, even after several iteration of improvements, then the right decision might be to abandon the new API instead of the old one, or try another different design for the API might be preferable.
That said, as a third party developer, it would be nice to see a prototype implementation of the alternative checkout flow. The current store front would not have to use the new API to be able to try it out. That could continue to use the current API.
From my point of view it would be enough to expose the alternative API only via GraphQl and as a PHP API.
|
||
Each quote is used to create a separate order. Multiple payment methods (with independent billing address each) can be selected during each order creation. | ||
|
||
Cart will depend on Catalog. Quote will depend on Cart and must not depend on Catalog. Order will depend on Quote and must not depend on Cart or Catalog. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Quote will depend on Cart and must not depend on Catalog
Why?
I don't see the benefit of this. I see the attraction of it, but I think it's wrong. It's an unnatural restriction. Signs of this are how awkward it is to pass the product dimensions. The same problems will occur also for example when other product data is required for totals calculation by third parties.
* Quantity | ||
* Regular price | ||
* Price | ||
4. Applicable cart rules calculator arguments |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the benefit of separating out the cart rules from the totals calculation?
* Price | ||
4. Applicable cart rules calculator arguments | ||
* Cart | ||
* Addresses |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As a response to a previous comment: the "buyer" that needs to be would be the customer.
* Cart | ||
* Addresses | ||
* Date & Time (admin preview) | ||
2. Quote factory arguments: Quote |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Quote/QuoteFactory still seems like an aggregate for all entities required by checkout to me. If I understand correctly one of the suggestions of this proposal is to not build the quote over time, but all required data has to be provided at creation.
If this data is aggregated over time, where would it be stored? In the API client (e.g. store front)?
* Store credit | ||
* Cart rules (calculated by Applicable catalog rules calculator) | ||
* Customer | ||
2. Totals calculator: Totals |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in the video of the architecture meeting where this proposal was discussed it was mentioned that totals are entities. Was that meant literally?
From my point of view the totals are a function of the quote.
The results of the calculation may be stored for performance reasons, but a total does not have any identity over time.
Also, I didn't understand the point about how this new proposal allows for sorting of total calculation.
It sounded as if that is not possible in the current implementation. However, it certainly is possible.
The downside of the current implementation is that each total aggregates it's results on the quote items and the quote. Shared mutable state is always tricky. However, it does allow for many customizations where one total calculation can change the value of a previous one. After listening to the discussion, I'm not sure if the total results where supposed to be immutable or not. If they are, how would such customizations be possible?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in the video of the architecture meeting where this proposal was discussed it was mentioned that totals are entities. Was that meant literally?
The idea is to have a separate immutable extensible entity for totals which can be used in other entities like order, invoice, credit memo because there are issues with the calculation of their total.
I didn't understand the point about how this new proposal allows for sorting of total calculation.
There will be some kind of class which will check the configuration and create to a composite of totals in the order according to configuration or applied rules (like cart rules).
It sounded as if that is not possible in the current implementation.
Actually no. The point was that the current mechanism is hard to understand because you can see the only configuration in Admin Panel and logic is smashed across the code. The main idea is making it more visible (even provide some kind of visualization in Admin Panel) and have only one place in the code.
After listening to the discussion, I'm not sure if the total results where supposed to be immutable or not. If they are, how would such customizations be possible?
Totals should be immutable. Each totals calculator uses the result of previous totals calculator, any extension/customization can add own calculator to the list.
* For physical products on Review & Payments step | ||
* For virtual products billing address has to be entered first | ||
1. Cart properties: | ||
* Line Items: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can more information on how different product types would be represented be added to the proposal?
Currently a product in the quote is represented by one or more quote items. Each quote item can have one or more quote item options to store relevant data.
These options are used for many different things, starting from enabling reorders to linking of related quote items over additional data to display on line items to many different types of customizations.
Because they are so heavily used I would like to read a little on how those problems would be solved with this proposal
- Added totals calculations - Added summary
- Added items for re-calculation
…tive checkout flow verification
 | ||
|
||
Each calculator receives Quote DTO and Totals List, calculates totals, creates new Totals DTO with the calculated amount and adds it to Totals List. This approach allows to do not change a quote object, have a defined interface for totals and change the order of calculation. Magento provides multiple configurations to change the order of calculation, for example, discount can be applied before shipping amount or after. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One common customization for the current totals calculation is that custom discounts are implemented by adjusting prior totals, e.g. the subtotal, from a later total model. If the totals are immutable, there should be an option for total models to return a changed list of totals, e.g. remove or replace total models that where calculated by prior. Each total model then can be immutable, but can be replaced or removed from the TotalsListInterface
as needed by customizations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if I clearly understand your point but totals calculators will be created in runtime according to the configuration and priority and each calculator has isApplicable
method (the customization can disable needed calculator, add a new one) which decides if calculator should be executed or not, for example, it does not make sense to execute a shipping calculator for the quote only with virtual products.
A custom discount calculator can be added in the same way as standard calculators with own priority and grand total calc will automatically collect all amounts and adjustments.
Sorry to harp on and on about backward compatibility, but I still think it would be good to include a paragraph into the design document about how the new API will be introduced. Without using this approach merchant developers will simply see "Magento broke the checkout flow in a major way without adding any benefit, so now we have to pay many hours of upgrading customizations, just to be able to use the latest version of Magento, without having any real return of investment, because the current checkout was working fine for years.". This would be really painful, l and is the reason why I hope some thoughts on the introduction process will be included in the PR. |
@Vinai thanks for your feedback. The current version of the proposal contains just mention that it will an alternative API and we don't have intentions to replace everything in the current checkout. Currently, we are focusing on use cases coverage, missed parts in existing checkout, and most "painful things". The next stage is defining extension points in the current API to see how to integrate alternative flow in the Magento ecosystem: Catalog, Sales, Payments. If you have any thoughts like stuff which difficult to customize/extend, missed functionality, please share your opinion. |
Over the last few years I've worked on a few customizations that involved dynamically making specific products free. So far I've implemented that by adding a quote item option to the free product (so it is listed as a separate line item and not merged with the same regular priced product in the cart) and custom total models which set the free line item cart price to zero and adjusted the subtotal result. How would that be implemented with the new checkout flow? |
Cart and Quote entities will be separated, the Cart will use own totals estimator (some calculators might be reused from quote) based on Catalog prices, also Cart will have own products representation, for example, groups can be used for products separation. The quote items will be calculated with prices from PIM. Based on the provided case, I see there a few possible approaches:
|
Because the one item is free, and the others are not. The quote can not get a zero price from the PIM because the product is not generally free. It's just the one item in the cart that is free. Imagine you want to order pizzas. You order two and get a bottle of coke for free. Other bottles of coke you also add to the cart are not free. The PIM only knows about regular priced bottles of coke. Line items in the cart:
There are many similar scenarios. In a different site color sample sheets where added to the cart for free if the customer was in a certain customer group. And so on. All scenarios have in common that a regular priced product sometimes is added to the cart as a separate line item for a different price (sometimes free, sometimes with some other price adjustment). Creating a separate free version of a product in the PIM is not feasible (same SKU and same stock). So far such price adjustments for specific line items where simple to implement with total models (and quote item options): The line item with the adjusted price is added to the cart with a custom quote item option. This separates it from the other line items of the same product. Then, during totals calculation
How would that be done with the new checkout and totals calculation flow? |
|
||
The Cart will depend on Catalog. Quote will have a knowledge about PIM, Shipping Rates estimator, Coupons, Store Credit and other services for totals calculation. Cart will provide data for Quote. Quote will provide data for Order. Order will not have any knowledge about Catalog, Quote, Cart. | ||
|
||
 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On the diagram we have separate total calculation for cart and quote. Considering that a lot of totals will be the same, can we have unified way for totals calculation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Totals won't be the same. In most cases, cart totals contain items summary and some adjustments like free item, the quote totals - shipping rate, discounts, taxes, customer balance, gift cards. But, in general, I don't see restrictions to don't use it for cart re-calculation, as calculation should be used for different scenarios like B2B quotes.
The current shopping cart contains summary estimation block (with shipping, taxes, etc.) but actually it's not a shopping cart but a quote estimation as right now we don't have a separation to cart and quote.
|
||
The following sequence diagram shows how the place order will look like according to the proposed solution: | ||
|
||
 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We recalculate totals on the place order again. As I understand this is for the case when coupon balance, store credit or gift card balance may change. Are we going to recalculate shipping rates and taxes too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All totals will be recalculated based on configuration and provided data including taxes, discounts, gift cards, customer balance, line items, shipping rate, etc. The shipping rate will be recalculated only for the selected shipping method, it doesn't make sense to go through all available carriers because the quote already has the selected shipping method.
- Added flow explanation
Problem
In scope of work on GraphQL and storefront APIs we have an opportunity to improve design and features of storefront checkout.
The purpose of this document is to discuss possible alternatives to current Magento checkout flow.
Solution
This document is under discussion. Participants are welcome.
Requested Reviewers