At the moment we have a situation if you are using a third-party payment gateway, and you redirect the user to the payment provider you are losing your cart. So if the user clicks the back button, or cancel they will be redirected to the sylius shop but they cart will be lost.
Is there any suggested solution to keep the cart on the back button, and is there any plan to fix this in future?
From my POV I think we should have a simple ability to complete the order only on successful payment.
The issue is indeed present - I heard clients also complaining about it. Another issue is here probably that not everyone visits the confirmation page and sometimes 'paid' notifications from payment providers are slightly delayed - but there is probably a good solution to this.
we have the same issue on our website, but because it happens quite rarely, we decided to give it low prio.
but as we grow bigger, it becomes more common and at a certain point, it should be addressed.
the problem comes from the way Sylius is handling payments, especially with payment service providers that require redirect of customers on their 3rd party payment pages.
when a customer clicks "Send order" in Sylius, the order is transitioned from cart to order and then sent to 3rd party payment service provider page. if the customer hits back, it is normal, following current logic and implementation to see an empty cart.
ideally, the order should be transitioned from cart to order only after the customer came back from the payment service provider - in the thank you page. but this could imply a great deal of BC Breaks in Sylius. though, if you put yourself in the shoes of the customer, it might not be that bad after all.
another solution I might be thinking without having to change the entire order / cart state machine is to implement the following logic:
of course, this does not help for the usecase when someone hits back because they want to remove a product from cart or if they want to change qtys. if you want to solve this, you need to implement the previous solution.
The major issue, in this case, is that item will be reserved and not will be available for order. It means that even if customer tries to add item into cart once again, it might be not possible.
In any scenario, there is a very high probability to lose the customer.
I see the following possible solutions:
CartContextInterface with fallback strategycart and success states and we have to rid of intermediate new state. Unfortunately, such change will introduce the BC break.@CoderMaggie is it possible to increase the priority of this ticket?
So I have implemented the second option from proposed. Currently, it works but it is very hacky. As I see the only way to solve it properly is to review the state machine states and keep order in cart state until it will be paid or all items from order will be removed (the third option form comment above)
This issue has been automatically marked as stale because it has not had any recent activity. It will be closed in a week if no further activity occurs. Thank you for your contributions.
just raising this cc @coderMaggie
not stale
ping @CoderMaggie
What about changing the Sylius\Bundle\CoreBundle\Checkout\CheckoutResolver and instead of just redirecting to cart page
if ($order->isEmpty()) {
$event->setResponse(new RedirectResponse($this->urlGenerator->generateForCart()));
}
check if session has sylius_order_id, then get the order and redirect to sylius_shop_order_show
@vvasiloi not sure that it will solve the problem with a lost cart. Customer will be redirected to a page with only order information. As I described in the above comments, the customer should be able to proceed with checkout once again.
Anyway redirect will not cover other customers behaviour like just pressing back button from the third-party payment page, that lead to an empty cart also.
pressing back button
@dbalabka that's exactly for this scenario, they will be redirected to the order payment page.
Adding a check like that to the cart page will fix the "lost cart" problem as well.
@vvasiloi am I right that customer:
in your scenario?
Also, interesting what will happen if the customer will try to directly open the cart page in separates browser's tab during a payment process in another separate tab (it is a real-life scenario).
@dbalabka yes, all correct. After the order was placed, it can't be modified by the customer.
Accessing any checkout page, but not cart page, after order is placed will redirect to this page:

It's not hard to implement other scenarios that will improve the UX.
@vvasiloi IMO it is a simple and quick workaround but unfortunately, do not the solve the problem. As I described above, the more correct solution (and most complicated due to BC break) is to rid of order鈥檚 new state.
It is important to give the possibility for the customer to be able to navigate between checkout steps back and forward (to completed steps) or jump between steps in any order. For example, such an approach provides the possibility to handle cart abandonment that might happen on any checkout step even after the failed payment. Customer should be able to return to the cart to make some changes (e.g. apply coupon) and proceed with checkout once again.
Is there any workaround for this issue?
@jordisala1991 I have tried second from this list: https://github.com/Sylius/Sylius/issues/10729#issuecomment-546685929
I鈥檓 not suggesting to waist you time on it because it is complicated and requires a lot of development effort.
IMO we should wait when the third one from the list above will be implemented. new state is really redundant and introduce this issue. Of course there might me other solutions.
@dbalabka I don't think the new state is the issue here.
What is relevant is not the state itself, but the transition.
The order is created (sylius_order transition from cart to new) when the checkout is completed (sylius_order_checkout transition from payment_selected/payment_skipped to complete).
By default this happens when the customer submits the form to sylius_shop_checkout_complete (route config).
If someone does not want the checkout to be completed if the payment is not successful, then the state machine transition should be removed from this route and done somewhere else, like in a sylius_payment state machine transition callback.
Of course, I oversimplified and more changes are required, especially to payment and order state machine callbacks.
A detailed diagram that also includes cascade transitions will certainly help better understand the implications, but I can't do one right now.
An issue I have right now is that quite often customers don't wait for the redirect from payment providers and in a scenario like that the checkout won't be completed and the order won't be created.
Ideally, I would like the checkout flow to easily allow inclusion of external payment (or other) steps, instead of completing right before these, but also easily allow the current flow for scenarios like paying with cash on delivery, invoice or not having to pay at all.
@vvasiloi I appreciate your input to solve this problem. Still, I think that order鈥檚 State Machine might have less steps. I would like find solution that will be bulletproof and cover more edge cases as possible.
One of them is that you have mentioned:
An issue I have right now is that quite often customers don't wait for the redirect from payment providers and in a scenario like that the checkout won't be completed and the order won't be created.
Could you please share your thoughts about possible reliable solutions?
Ideally, I would like the checkout flow to easily allow inclusion of external payment (or other) steps, instead of completing right before these, but also easily allow the current flow for scenarios like paying with cash on delivery, invoice or not having to pay at all.
Fully agree. Currently, it is complicated to integrate PayPal with Payments API to authorize a payment that you can capture later.
Most helpful comment
we have the same issue on our website, but because it happens quite rarely, we decided to give it low prio.
but as we grow bigger, it becomes more common and at a certain point, it should be addressed.
the problem comes from the way Sylius is handling payments, especially with payment service providers that require redirect of customers on their 3rd party payment pages.
when a customer clicks "Send order" in Sylius, the order is transitioned from cart to order and then sent to 3rd party payment service provider page. if the customer hits back, it is normal, following current logic and implementation to see an empty cart.
ideally, the order should be transitioned from cart to order only after the customer came back from the payment service provider - in the thank you page. but this could imply a great deal of BC Breaks in Sylius. though, if you put yourself in the shoes of the customer, it might not be that bad after all.
another solution I might be thinking without having to change the entire order / cart state machine is to implement the following logic:
of course, this does not help for the usecase when someone hits back because they want to remove a product from cart or if they want to change qtys. if you want to solve this, you need to implement the previous solution.