Implementing Klarna Checkout

In this tutorial we're going to look at how we can implement Klarna Checkout on our webshop in a few easy steps.

This tutorial assumes you've already got a functional webshop, as well as user credentials from Klarna.

The first thing you'll want to do before implementing Klarna Checkout is to update your website to the latest version of Relatude. If you're already using Relatude with Nuget then just go ahead and grab the latest version from there; otherwise you might want to have a look at this article.

 

Once you've made sure that you have the latest version of Relatude installed, go to the Relatude UI and locate the Shop-content you want to use Klarna on.

Create a new CreditCardPaymentMethod for the shop, by adding a PaymentMethod.

Skjermbilde 2021-01-14 164558

 

You will need to fill out the MerchantId, Token, Return Url and Callback Url values. Under the 'Payment method' tab you'll need to set 'Type of payment' to 'Two phase' and set 'Payment provider' to 'KlarnaCheckoutProvider'. Also make sure that your shop is present in the 'Shops' relation field, and add any other shops you want to use with this payment method.

The merchantId should be your Klarna merchantId, and the token should be your merchantId and your Klarna password joined by a colon ':'. Like this: MerchantId:Password

 

The default value for 'Return Url' is 'https://your.site/wafclient/paymentprovider/KlarnaCheckoutConfirmOrder?klarna_order_id={checkout.order.id}'

 The default value for 'Callback Url' is 'https://your.site/wafclient/paymentprovider/KlarnaCheckoutPush?klarna_order_id={checkout.order.id}'

 klarna

 

 Now we can implement the necessary code on our checkout page.

 Here's our example checkout page:

Example checkout

 

Once we click on 'Next', we're going to render an html-snippet from Klarna in an empty <div> below the button. Here's the code:

    protected void btnNext_Click(object sender, EventArgs e) {
        // Fetch order
        var order = WAFShopHelper.GetCurrentOrder(Request, Response);
        order.CalculateAndSaveAmounts();
        order.UpdateChanges();
        order = WAFContext.Session.GetContent<WAF.Engine.Content.Native.Order>(order.NodeId);

        // Get the PaymentMethod and PaymentMethodProvider
        var paymentMethod = order.PaymentMethod.Get();
        var paymentProvider = paymentMethod.GetPaymentProvider();

        // Create payment data
        var paymentMethodData = new PaymentMethodData();
        if (paymentProvider is KlarnaCheckoutProvider) {
            paymentMethodData.PaymentData.Add("Terms", string.Format("{0}/{1}", WAFRuntime.UrlFromRootToApp.TrimEnd('/'), "terms"));
        }
        paymentMethodData.PaymentMethodNodeId = paymentMethod.NodeId;
        paymentMethodData.SetPropertiesFromOrder(order);

        // Create or update order at Klarna. Get html snippet
        var paymentActionResult = paymentProvider.CreateSession(paymentMethodData);

        if (paymentActionResult.Success) {
            switch ((PaymentMethodEnum)order.PaymentMethod.GetId()) {
                case PaymentMethodEnum.Invoice:
                    // PROCESS INVOICE HERE
                    break;
                case PaymentMethodEnum.KlarnaCheckout:
                    var html_string = paymentActionResult.PostValues.Get("html_snippet");
                    if (!string.IsNullOrEmpty(html_string)) 
                        CreateKlarnaCheckoutSession(html_string);
                    break;

                default:
                    return;
            }
        }
    }

    /// <summary>
    /// Render html snippet from Klarna
    /// </summary>
    /// <param name="html_snippet"></param>
    private void CreateKlarnaCheckoutSession(string html_snippet) {
        var sb = new StringBuilder();
        sb.AppendLine("<div id=\"my-checkout-container\">");
        sb.AppendLine(html_snippet);
        sb.AppendLine("</div>");
        litHtml.Text = sb.ToString();
        btnNext.Visible = false;
    }

 

Resulting view:

Skjermbilde 2021-01-20 165927

 

 

The rest of the checkout logic is handled by Klarna. Now we need to handle when the user arrives at the 'Order received' page (which is set on the Shop-content).

We're going to render another html snippet. Here's how:

public partial class OrderReceivedPage : System.Web.UI.Page {
    protected void Page_Load(object sender, EventArgs e) {

        // Check if there's an 'orderref' parameter. If there is, fetch the corresponding order
        if (Request["orderref"] != null) {
            Order order = WAFContext.Session.Query<Order>().Where(AqlOrder.OrderReference == Request["orderref"].ToString()).Execute(1).FirstOrDefault();
            if (order != null) {

                // Get the payment method and payment method provider
                var pm = order.PaymentMethod.Get();
                var provider = pm.GetPaymentProvider();

                // If the payment method provider is Klarna Checkout, get the html snippet and render it in an empty <div>
                if (provider is KlarnaCheckoutProvider) {

                    // Create PaymentMethodData based on the order
                    var pmd = new PaymentMethodData();
                    pmd.SetPropertiesFromOrder(order);

                    var snippet = ((KlarnaCheckoutProvider)provider).GetCheckoutConfirmationSnippet(pmd).PostValues.Get("html_snippet");

                    litOrderRef.Text = snippet;
                } else {
                    // Handle other payment methods here
                }
            }
        }
    }
}

 

 

And here's the result:

received