Currently we're facing some challenges in our EPI Commerce implementation. In our setup convert a cart to an purchase order after the payment step (last step) in the checkout process has been completed. However some users open the webshop in multiple tabs which can cause issues with cart modifications during online payment.
A user has a cart and want to convert this into a purchase order and pays online. They stay in the online payment provider screen and they (accidently) add a new product in the second tab (which is using the same session and cart). Then they complete the payment step and the system detects that they payed the wrong amount as the cart amount is higher than the amount they payed.
Is there a way that we can lock cart operations in EPI Commerce during the payment process, such that we can use the OOTB validation system to block all cart modifications during the payment process? In that case we can easily prevent payment errors because of users which have multi tabs opened.
I don't know about a OOTB functionality for this scenario.
But unless the issue happens all the time, I would probably just add some extra validation on the payment authorization callback. Then if the total cart amount changed while being on the external payment provider, I would fail the checkout process nicely (asking the customer to retry payment).
The validation could look like this:
decimal authorizedAmount = orderGroup.Forms.Sum(form => form.AuthorizedPaymentTotal);
decimal cartAmount = orderGroup.GetTotal(_orderGroupCalculator).Amount;
if (authorizedAmount != cartAmount)
// Void the authorization.
// Print an error message, asking the customer to try again.
I normally use the same approach as @Stefan descibed above.
I will come back with more information, but I'd suggest to try https://world.episerver.com/documentation/class-library/?documentId=commerce/9/AB03FD9F
@Stefan: We already use something like that during the payment, but the thing is that the user already made an succesful payment with the wrong amount, so it would be nicer if we can block cart modifications during the payment process. We only convert the cart into an order after the payment went successfull as otherwise you would loose the cart when the payment is canceled or the user accidently closes payment screen.
@Quan Mai: Thanks, will look into this further to see if this is an feasible solution.
I also convert carts to purchase orders after the payment authorization. Do you add a payment object to the cart before redirecting the customer to the payment provider? If you do, then you have the original cart amount on that payment. Then when you reload the cart on payment callback and the amount does not match the cart payment amount, you know something is wrong. And the already authorized payment, you can void by creating a void payment on the same cart and process it, if the amounts don't match.
If you go with cart level locking, be aware that performance may degrade. Because you will need to check whether a lock exists on every update action (add, remove, change line items) on the cart. To keep up performance, remember to cache those locks, not only when they exists, but also when they don't. Otherwise you will be hitting the database a lot, checking for locks, when actually the cart has none (which will be most of the time).