Klarna Docs - Best practices

Best practices

Follow our best practices to make your integration robust, fast and secure.

When the customer reaches the checkout page, the merchant loads the html snippet provided in the response of the Create Order request, which will then create the checkout iframe.

  • The Checkout iFrame lives inside the container #klarna-checkout-container.
  • The container is created by the JS snippet retrieved in the order body.
  • The container mustn’t be styled. If the Checkout iFrame should have a restricted width, apply that rule to an element wrapping the container.
  • The width of the Checkout iFrame should at minimum be 320px.
  • The Checkout iFrame must be able to grow and shrink height-wise as the user progresses in the checkout flow.
  • Styling of elements inside the container is being taken care of by the Checkout iFrame. Make sure no merchant CSS is applied to the elements.
  • There can be hidden elements inside the container. The elements mustn’t be styled, since the Checkout iFrame is responsible for showing and hiding them.

Merchant creates a Klarna Checkout Order (session) and needs to know the best practices associated with a new order and an existing order.

For a new order,

  • Assign the merchant_url’s collection to be used for callbacks.
  • Assign the locale properties (Country, Currency, Locale).
  • Assign the order_line object properties for the cart items.
  • Since sales tax is calculated based on the shipping address, it may not be computed at this time. However, a line item for sales_tax could be loaded for the order with a default tax, or assign 0.
  • Assign the checkout options object properties to customize the Klarna snippet. Any not sent will default to False
  • Assign the optional Shipping option properties and add them to the shipping_options collection. If these are not supplied here, they should be supplied after the shipping address is updated. If these are dependent on the shipping address, do not add them now.
  • Create the Order Resource object and assign the properties.
  • Convert the order object to a JSON string
  • Perform a POST request to Create the order

For an existing order,

  • GET (Fetch) the order using the order location uri from the saved session variable.
  • Add/Update the cart items collection.
  • Update the order amounts (tax and total).
  • Perform a POST request to update the cart items and properties.
  • The location stored in the session variable should not change.
  • Show the html snippet returned from the POST. Status will be ‘checkout_incomplete’ in KCO (Klarna Checkout).

When the customer closes down the browser or goes back to the steps before the checkout page (eg: product page, landing page) and later comes back to the checkout page to complete the order.

When the customer has completed shopping and the checkout page is rendered for the first time, a session variable should be used to store the Klarna Order Location URI returned from the initial POST creating the order.

NOTE: This is NOT the snippet, it is the URL for the order

When the customer re-enters the checkout:

  • Check if the Klarna Order session is stored before creating a new order. I.e: https://api-na.playground.klarna.com/checkout/v3/orders/[KlarnaOrderId] or in EU, use the EU playground site https://api-eu.playground.klarna.com/checkout/v3/orders/[KlarnaOrderId]
  • If it exists perform a GET request using this Location.
  • A JSON object containing the current Klarna order is returned which can be updated instead of creating a new order.
  • Deserialize this to a CheckoutOrder object to simplify working with the order.
  • This also includes the snippet that is used to render the checkout.
  • If you get a 4XX or 5XX or any other type of error, you should create a new order.
  • Klarna checkout orders are only valid for 48 hours after merchant update or client interaction and expire after that. This expiration is normal.
  • Checkout orders could also expire early for other internal system issues, so error handling must also be implemented in this step to create a new Checkout Order if the URI is invalid.
  • The Klarna order location URI should be retained because when a customer starts filling out their details they will not have to re-enter them if they leave and come back to the checkout.

After the checkout page is rendered, the customer may change shipping options, enter promo codes, or remove line items or update item quantity from the merchant panel. Anytime this occurs, the Klarna widget will not reflect these changes and will need to be refreshed. This is done by suspending and resuming the checkout frame.

Suspend and Resume

Used while the checkout page is rendered and the user modifies the cart within the merchant order summary panel.

  • Suspend the checkout process using the JavaScript API to the checkout.
  • This “locks” the Klarna checkout so the user may not interact with it.
  • Update the merchant’s cart.
  • Perform a POST to Klarna to update the order.
  • DO NOT create a new order at Klarna.
  • Resume the checkout process using the Klarna JavaScript API to the checkout.
  • This causes KCO to refresh with the data that was just updated via the server side POST.

The merchant has not collected the billing or shipping address and is reliant on Klarna to provide the shipping address. When the address is supplied in the KCO, Klarna will default the shipping address to this address. Anytime the address changes, the tax or shipping may need to be recomputed by the merchant.

Server side

Receiving the address update from Klarna,

  • A callback from Klarna to the merchant is made to the ‘address_update’ URL defined within the merchant_url’s for the order. The URL MUST be an SSL address (https://).
  • Although a self-signed certificate will work here, it would be best to obtain a real certificate since this is required for the final PUSH. The POST from Klarna sends the checkout order as JSON with the billing and shipping address info updated by the customer. The body also contains the order_lines, order_amount and order_tax_amount. The merchant should:
  • Deserialize the JSON and parse out the addresses.
  • Re-compute sales tax.
  • Parse out the sales_tax line and update or add it if not already part of the order_lines.
  • Update the order internally.
  • Determine the shipping cost.
  • Update the shipping cost line item.

Updating the order

As the shipping address is known now,

  • The shipping options may be added to the order if not already supplied.
  • If discount codes are dependent on address, or are not already added to the order, these may be supplied.
  • Optionally, add or update the shipping_fee order line to the order_lines if not already present
  • The updated order details will be sent back to Klarna as the response to the address update POST request, as a JSON.
  • If the merchant responds with any status code other than 2XX, or if they do not respond within 10 seconds, the purchase will not complete and an error message will display and instruct the customer to try again. This will be logged for merchant support.

Client side

  • When the order is received by Klarna with the calculated tax, the KCO is changed to reflect the billing address, new total amount, and an option to change the shipping address.
  • If shipping options are supplied they will be displayed with the ‘preselected’ option checked.
  • Since the merchant panel initially showed 0 tax, it should be changed to reflect these cost changes. This is done by javascript events fired from the KCO.t
  • Optionally, shipping options and discount codes displayed in the Klarna panel may change causing the total amount to change.
  • Javascript events should be wired to the form elements displaying the Tax and Total amounts.
  • Events that may be wired into the merchant panel:
  • ‘change’ – event fires anytime the email address, zip, or names supplied are changed or entered.
  • ‘shipping_address_change’ – event will fire anytime the shipping address changes.
  • ’order_total_change’ – event will fire anytime the order total change
  • ‘shipping_option_change’ - fired anytime the user selects a different shipping option
  • Refresh the entire page. The javascript events on the form elements will update the merchant panel with the changes.
  • Create a new Klarna checkout. This would create a new Klarna order id
  • Perform a POST to create or update the order. The order was updated at Klarna with the response sent back from the POST from Klarna.
  • Perform a GET with the orders location URI. What was sent back with the Response to Klarna is the most current order.

The checkout page contains:

  • Merchant’s order summary panel showing summary of items purchased, cost, quantity, tax, order total, optional discounts and shipping options. This panel can be shown above or beside the Klarna panel.
  • Klarna panel (html_snippet div tag)
  • For a newly created order the html snippet will contain the labels:
  • For existing orders the snippet will be pre-filled and contain:

With the checkout page rendered, the user may change shipping options, enter promo codes, or remove line items or update item quantity from the merchant panel. Anytime this occurs, the Klarna panel will not reflect these changes and will need to be refreshed. This is done by suspending and resuming the checkout process.

User may change shipping address or select a different shipping option or add a discount

  • If any of these occur within the KCO the appropriate events will fire allowing the merchant panel to be re-displayed without performing screen refreshes.
  • The 2 panels should always be in sync.

Once the checkout has completed at Klarna the merchant may want to validate the order items are in stock, or confirm the order items in the cart are the same as what Klarna shows.

If no validate URL is assigned to the merchant_urls the order is updated in Klarna Checkout (KCO) with a status of ‘checkout_complete’. No other changes may be made to the order through the Checkout API’s. Afterwards, changes may only be made through Klarna Order Management API.

Validate – Must complete within 3 seconds else the order is created.

If a ‘validation’ URL (MUST BE SSL ADDRESS) is assigned in the collection of merchant_url’s, then Klarna will perform a POST request to this URL. The entire order is passed back here. The status will still be ‘checkout_incomplete’ so changes may still be made. Typical issues:

  • Out of stock validation - for high turnaround businesses this functionality enables you to verify that an item added to a cart is indeed still in stock before the consumer completes the purchase.
  • Delivery limitations - some products cannot be shipped to certain geographies. This functionality enables you to verify that the products can be shipped to the address the consumer has provided.
  • Order number generation - certain systems have flows that require the creation of an internal order ID when order has been created, such as for tracking purposes. This functionality allows you to create an order ID upon receiving the validation callback and displaying it on the confirmation page.
  • Another issue here could be that the line items are out of synch because something was added to the cart after the checkout was started. Compare the current cart state to the Klarna order state (totals, shipping selection, discounts, and gift cards). If they don’t match there is an issue.
  • No Klarna PUTS or GETS should be done in this function.
  • No updates to the merchant cart done in this function since they should occur on the shopping pages.

Validate OK – Or not completed within 3 seconds

If the validation is not performed within 3 seconds it is considered valid and the confirmation redirect will occur.

  • To approve the purchase, reply with a HTTP status 2XX. The consumer will then be redirected as normal to the checkout confirmation page.

Validate Not OK

  • To deny the purchase, reply with a HTTP status 303. This needs to include a Location header pointing to a page which informs the consumer why the purchase was not completed. The consumer will be redirected to this page.
  • Note: The rejection page needs to be hosted by you and we highly recommend that you give the consumer detailed information as to why you rejected the order.
  • If the rejection is due to line items being out of sync, the easiest way to fix this would be for the customer to click the checkout button again which will open the checkout page and refresh it with the current cart items on the site. This will use the existing Session order URI to GET the order.
  • Complete the checkout process again.
  • The confirmation URL assigned to the list of merchant_url’s is called from Klarna.
  • This URL should NOT be the final page shown to the customer.
  • Klarna will update the order status to ‘checkout_complete’.
  • A final GET is performed returning the order as it exists in Klarna.
  • This page should have logic that commits the order in the merchant system.
  • If the commit of the order succeeds, then another redirect done by the merchant site should be performed to take the customer to the final confirmation page.
  • If the commit fails:
  • The order is placed into a queue at Klarna waiting to load to the Order Management system.

Once the queued order moves to Klarna’s Order Management a POST is made to the ‘push’ URL provided in the list of merchant_url’s. This occurs every 4 hours for 48 hours or until it’s acknowledged. The Merchant should have a process that can ‘Acknowledge’ this in Order Management.

If the order isn’t created in the merchant’s system. It should be done here. Once created the internal merchant order id should be updated to the MerchantReference1 field for the order in Klarnas order management system. If the order for any reason can’t be created in the merchant’s system the order should be canceled with Klarna using the Order Management API.

Acknowledge – through Order Management API

Once the order has been pushed to Order Management it should be ‘Acknowledged’ by the merchant.

  • Send a POST request to ‘Acknowledge’ the order.
  • This may be a good time to update the merchant_reference1 and merchant_reference2 if not already set.
  • Merchant_reference1 is ALWAYS the external customer facing ‘Order Id’ generated by the merchant.
  • Merchant_reference2 can be another id associated to the order.
  • At this point the items may be shipped.
  • Once shipped, the merchant will make capture calls using the Klarna Order Management API.

Example if address is limited to X characters:

  • If address line 1 is greater than X and address line 2 is empty then search for the first occurrence of these abbreviations (search whole word not just in-string):
  • APT
  • BSMT
  • BLDG
  • DEPT
  • FL
  • FRNT
  • HNGR
  • LBBY
  • LOT
  • LOWR
  • OFC
  • PH
  • PIER
  • REAR
  • RM
  • SIDE
  • SLIP
  • SPC
  • STOP
  • STE
  • TRLR
  • UNIT
  • UPPR

and if found split to address line 2.

  • Optionally, truncate Street Address 1 and 2 at X characters

Name length may be limited on your end.

  • Truncate first name at 15 characters
  • Truncate last name at XX characters (confirm length)
  • Replace any of the following characters @ $ ! % ^ & * ( ) ~ < > + # in the first name with a space
  • Confirm the validation for last_name. If needed, should also strip invalid characters from it as well.

Apply a phone number rule. It appears that phone numbers with +1 are being failed for some merchants.

Merchants should support the E.164 number formatting for all phone numbers both in the ‘to’ and ‘from’ fields. This format is the internationally-standardized format for all phone numbers, and it includes all the relevant information to route calls and SMS messages globally. E.164 numbers can have a maximum of fifteen digits and are usually written as follows: [+][country code][subscriber number including area code].

Apply a zip code rule as well that will support both 5 digit zips as well as 5-4 digit zips for the US.