Vulnerability in EPiServer.Forms
Is there any way to set the CustomerContext.Current? We have a problem with external payment methods in Klarna.
You can add an external payment method in Klarna Checkout, for example PayPal. You give Klarna a url to redirect to if that options is selected.You select PayPal, click Finish and are redirected to a specific URL on our server. This will be a new session since the redirect is coming from Klarna so the LoadCart() wont work.No worries, we send the cartId in the URL so that we can load the specific cart, create a purchaseorder, ProcessPayments() which will take us to the PayPal dialog. So far so good.If you pay with PayPal you will be redirected to the order confirmation page, perfect. But if you cancel the order you will be redirected to the checkout page. The checkout page will perform LoadCart() and we will end up with an empty cart. Sure, we can maybe add the cart id in the cancel url but that will only load the cart correct on that page. If you add another product it will be added to the empty cart.
I guess the best would be set the CustomerContext.Current when the call is coming from Klarna using the cart id, then everything would work just fine but I don't know if that is possible?We can always access the created purchaseorder so maybe the best thing is to copy that one to the new cart?
Or maybe I'm completely missing something here. :-)
Thanks for your help!
You don't have to. Just use other overload that takes CustomerId, so
IOrderRepository.Load<T>(Guid customerId, string name)
But will that also set the current cart for the user? On like every other page we are using _cartService.LoadCart() which loads the cart this way:
var cart = _orderRepository.LoadCart<ICart>(CustomerContext.CurrentContactId, name, CurrentMarket);
Sure, the cart will be loaded just fine the first time but if a navigate to another page the LoadCart() will run and the wrong cart will be loaded.So what I'm actually are looking for is to set a specific cart to the current user.
I'm not sure I understand the problem, but if you load the cart by the contactid , then it should load the cart belongs to that contact.
if you want to, you can always set the cart.CustomerId to the desired contactid, but again I'm not sure I understand the whole picture here so proceed with caution :)
Yes, but when the user navigates to another page we don't have the Contactid anymore and the CustomerContext.CurrentContactId will be used which will be a new id since the call comes from Klarna as a new session. But maybe that is the way to do? Set the cart.CustomerId with the new CustomerContext.CurrentContactId. I guess that will fix my problem.
I will try that!
Ok, I found out what happens. In the Geta library for Klarna Checkout they change the name on the cart to OnHold in the validation step and then creates a new one called Default.Therefor we get an empty cart. The customer guid is still the same but since the cart to use is called OnHold a new cart is created on LoadCart().
I will try to talk with Geta what the purpose is with that...
I haven't used the version of the Geta Checkout library that you're talking about. But I'm pretty sure I know why it's necessary.
It's because of the asynchronous nature of Klarnas Callbacks.
When the customer presses "Buy" they get redirected to some kind of order confirmation page, meanwhile Klarna are trying to send you another callback intended for actually processing the order.
The issue is that this callback might not come instantly. Which means that the customer could place an order, go to another page and still have their old cart there. If they then modify that cart, all kinds of issues will occur once the callback intended for order processing actually comes through.I assume that they do it in the validation step (once it's validated ok, I assume) because it's the one that comes first, before the customer gets redirected to the order confirmation page and before Klarna starts sending the order processing callback.
So to sum it all up - it's error handling. :P
Regarding the specific issue, it seems like the cart name being changed in the validation might not be a good idea if the order can fail after that when using external payment providers.
So the error handling needs error handling, hehe. :D
Where is the cancellation redirect configured? At the external payment provider or with Klarna Checkouts:
Either you try to do something with sending back some kind of order Id to the checkout page through the redirect url and then change the name back on that cart before populating your views.
Or another approach would be moving the cart renaming to the start of loading the order confirmation page. That way the customer gets to see the cart (if it hasn't been turned to a purchase order already by the order processing callback) and it still gets disconnected from the active session in case the order processing callback takes a while.