This blog post is a follow up on my previous post related to the Geta Klarna checkout module. This time the topic is the process of validating a checkout order.
If you haven't read the first blog post in this series, I recommend you do - here is the link.
In my prevoius post, I used the Confirm method to validate the cart and checkout order. Although this will work, a cleaner solution is to use an optional Klarna checkout function called Validate. Let me explain why and how.
In the event that the user has started the payment process and the cart is no longer valid (i.e. cart or stock has changed) the user should be sent back to checkout start with a message indicating why he/she has to start over.
At this point, you want to re-use the klarna order id created in the prevoius step. In order to do so, the order status have to be "checkout_incomplete".
By the time we get to Confirm it is too late, Klarna has made the reservation in the system (order status is "checkout_complete") and changes to the cart are no longer permitted. Here is a simplified flow overview showing the order status for all methods:
Klarna will include the complete order as part of the request body to the validate url. Because of this, the validate url has to be https. The Klarna module has been updated with a wrapper class OrderJsonWrapper.cs which can be used to deserialize the order data. Here is an example of a Validate method:
public ActionResult Validate()
var orderJson = new System.IO.StreamReader(Request.InputStream).ReadToEnd();
var order = JsonConvert.DeserializeObject<KlarnaOrderJson>(orderJson);
var id = order.Id;
var cart = GetCart();
int cartTotal = order.Cart.TotalPriceIncTax;
// do the validation here - return 200 if all is good
if(cartTotal == cart.Total && InStock(cart))
return new HttpStatusCodeResult(HttpStatusCode.OK);
var url = GetCartNotValidUrl(id); // specifying which url Klarna should redirect to - I'm using the CartNotValid action
public ActionResult CartNotValid(string klarnaOrder)
// user will be redirected here if validate is not OK
TempData["klarnaOrder"] = HttpUtility.HtmlEncode(klarnaOrder);
TempData["cartNotValid"] = GetCartNotValidMessage();
I use the CartNotValid action to put currect Klarna id and a user error message into the TempData collection before redirecting the user back to checkout start (the Index method) - this way I avoid having klarna order id as part of the url.
When generating the checkout snippet I can now reuse the order id:
CheckoutResponse Checkout(IEnumerable<ICartItem> cartItems,
string orderId = null,
ShippingAddress address = null);
Note: If you are not using Validate you should leave order id parameter empty. The module will then create a new Klarna order if the user is sent back to checkout start (see previous blog post).
If the user is logged in, email address and postal code can be prefilled by supplying optional parameter ShippingAddress (see Checkout method above).
In my next blog post I plan to go through order management processes such as complete shipment, cancel reservation and handling of returns. Until then, happy easter!