Embed the Checkout Snippet

This tutorial starts after the customer has selected their product(s) on your site, and wants to proceed to checkout.

In the steps below, you will be guided in how to render the Klarna Checkout HTML snippet on your checkout page. The Checkout snippet is where the customer enters their address details and completes their payment with one of the payment methods offered within the checkout.

Authentication

Klarna uses HTTP Basic Auth for authentication. Use the API credentials provided to you to authenticate with Klarna. The credentials consists of two elements:

  • Username: a username linked to your Merchant ID at Klarna
  • Password: a unique password that is associated with the username

Authentication: Base64(username:password)

Endpoints (URLs)

Klarna's European and North American environments have different endpoints (URLs) for testing and for live purchases. All requests to Klarna go through HTTPS. Read more here.

 

Create a Checkout Order

1. Configure the Checkout Order

In order for Klarna to construct a checkout order, we require that you set some configurations which reflect your website endpoints. These are the items that you should configure:

  • Specify the merchant ID and API Credentials provided to you by Klarna.
  • Set the currency, language (locale) and country to be used.
  • Endpoints to be used by Klarna Checkout:
    • Terms: URL for your terms and conditions. Mandatory.
    • Checkout: URL to your checkout page. Mandatory.
    • Confirmation: URL to your confirmation page. This is where customers will be redirected after completing their purchase. Mandatory.
    • Push: URL to which Klarna will send an HTTP post request to confirm the order. Mandatory. 
    • Order validation, Tax & Shipping changes and other order notifications. To learn more about Tax & Shipping click here.

Find out more in the API reference on the Merchant Urls Object.

Note:

  • Use the locale and purchase country/currency to match the customer experience you want to render.
  • If a checkout session already exists, you should use the order from that session instead of creating a new one.

Optimize the Checkout for Returning Customers

When you render the checkout snippet you may choose to add data about the customer. We recommended this feature for customers who have already registered with your website and provided auxiliary data about themselves. If you choose to add customer data, a lot of the customer-defined fields on the checkout form will be pre-populated, which will increase your conversion. To find more about this feature visit the API Reference.

2. Create a Checkout Order

Once all configurations and cart items have been set, it’s time to create an order in Klarna’s system.

Create Checkout Order Request

POST /checkout/v3/orders
Authorization: Basic pwhcueUff0MmwLShJiBE9JHA==
Content-Type: application/json
{
 "purchase_country": "se",
 "purchase_currency": "sek",
 "locale": "en-GB",
 "billing_address": {
   "given_name": "Testperson-se",
   "family_name": "Approved",
   "email": "youremail@email.com",
   "street_address": "Stårgatan 1",
   "postal_code": "12345",
   "city": "Ankeborg",
   "phone": "+46765260000",
   "country": "se"
 },
 "order_amount": 503341,
 "order_tax_amount": 100668,
 "order_lines": [
   {
     "type": "physical",
     "reference": "19-402-SWE",
     "name": "Camera Travel Set",
     "quantity": 1,
     "quantity_unit": "pcs",
     "unit_price": 603341,
     "tax_rate": 2500,
     "total_amount": 503341,
     "total_discount_amount": 100000,
     "total_tax_amount": 100668,
     "image_url": "http://merchant.com/logo.png"
   }
 ],
 "merchant_urls": {
   "terms": "http://merchant.com/tac.php",
   "checkout": "http://merchant.com/checkout.php?sid={checkout.order.id}",
   "confirmation": "http://merchant.com/thankyou.php?sid={checkout.order.id}",
   "push": "http://localhost/kco/push.php?checkout_uri={checkout.order.id}"
 },
 "shipping_options": [
   {
     "id": "free_shipping",
     "name": "Free Shipping",
     "description": "Delivers in 5-7 days",
     "price": 0,
     "tax_amount": 0,
     "tax_rate": 0,
     "preselected": true,
     "shipping_method": "Home"
   },
   {
     "id": "pick_up_store",
     "name": "Pick up at closest store",
     "price": 399,
     "tax_amount": 0,
     "tax_rate": 0,
     "preselected": false,
     "shipping_method": "PickUpStore"
   }
 ]
}

Note: The numeric values in the create checkout order request are 1/100-eds (e.g. 100 = 1.00 SEK and tax rate 2500 = 25.00%).

Create Checkout Order Response

The JSON response from the create checkout order call contains a unique order_id generated by Klarna which you need to keep track of since it is a reference to the order you created. The JSON response payload also contains the HTML snippet that you need to include on your page to render the checkout.

{
 "order_id": "1203c28c-f101-765f-bed8-f57a2d5e83e0",
 "status": "checkout_incomplete",
 "purchase_country": "se",
 "purchase_currency": "sek",
 "locale": "en-GB",
 "billing_address": {
   "given_name": "Testperson-se",
   "family_name": "Approved",
   "email": "youremail@email.com",
   "street_address": "Stårgatan 1",
   "postal_code": "12345",
   "city": "Ankeborg",
   "phone": "+46765260000",
   "country": "se"
 },
 "customer": {},
 "shipping_address": {
   "given_name": "Testperson-se",
   "family_name": "Approved",
   "email": "youremail@email.com",
   "street_address": "Stårgatan 1",
   "postal_code": "12345",
   "city": "Ankeborg",
   "phone": "+46765260000",
   "country": "se"
 },
 "order_amount": 503341,
 "order_tax_amount": 100668,
 "order_lines": [
   {
     "type": "physical",
     "reference": "19-402-SWE",
     "name": "Camera Travel Set",
     "quantity": 1,
     "quantity_unit": "pcs",
     "unit_price": 603341,
     "tax_rate": 2500,
     "total_amount": 503341,
     "total_discount_amount": 100000,
     "total_tax_amount": 100668,
     "image_url": "http://merchant.com/logo.png"
   }
 ],
 "merchant_urls": {
   "terms": "http://merchant.com/tac.php",
   "checkout": "http://merchant.com/checkout.php?sid={checkout.order.id}",
   "confirmation": "http://merchant.com/thankyou.php?sid={checkout.order.id}",
   "push": "http://localhost/kco/push.php?checkout_uri={checkout.order.id}"
 },
 "html_snippet": "<div id=\"klarna-checkout-container\".................",
 "started_at": "2018-01-24T14:21:55Z",
 "last_modified_at": "2018-01-24T14:21:55Z",
 "options": {
   "allow_separate_shipping_address": false,
   "date_of_birth_mandatory": false,
   "require_validate_callback_success": false
 },
 "external_payment_methods": [],
 "external_checkouts": [],
 "shipping_options": [
   {
     "id": "free_shipping",
     "name": "Free Shipping",
     "description": "Delivers in 5-7 days",
     "price": 0,
     "tax_amount": 0,
     "tax_rate": 0,
     "preselected": true,
     "shipping_method": "Home"
   },
   {
     "id": "pick_up_store",
     "name": "Pick up at closest store",
     "price": 399,
     "tax_amount": 0,
     "tax_rate": 0,
     "preselected": false,
     "shipping_method": "PickUpStore"
   }
 ],
 "selected_shipping_option": {
   "id": "free_shipping",
   "name": "Free Shipping",
   "description": "Delivers in 5-7 days",
   "price": 0,
   "tax_amount": 0,
   "tax_rate": 0,
   "preselected": true,
   "shipping_method": "Home"
 }
}

3. Render the Snippet in Your Checkout Page

It's now time to render the checkout snippet.

Get the value of the html_snippet from the create checkout order call response and embed it into your page where you would like the Klarna Checkout to be rendered. You can either:

  • Embed the HTML snippet in your page served by your backend from an endpoint
String htmlSnippet = "<div id=\"klarna-checkout-container\"...";
System.out.println(String.format("<div>%s</div>", htmlSnippet));
  • Get the snippet via an ajax call from you server and inject it dynamically, using javascript, into your page. In this case, we should be sure that the script tag(s) are parsed and evaluated, which means inserting the snippet. Using innerHTML is not going to work.
getSnippet(function (htmlSnippet) {
   var checkoutContainer = document.getElementById('my-checkout-container')
   checkoutContainer.innerHTML = htmlSnippet
   var scriptsTags = checkoutContainer.getElementsByTagName('script')
   // This is necessary otherwise the scripts tags are not going to be evaluated
   for (var i = 0; i < scriptsTags.length; i++) {
       var parentNode = scriptsTags[i].parentNode
       var newScriptTag = document.createElement('script')
       newScriptTag.type = 'text/javascript'
       newScriptTag.text = scriptsTags[i].text
       parentNode.removeChild(scriptsTags[i])
       parentNode.appendChild(newScriptTag)
   }
})

Note: The most straightforward approach for rendering the checkout page is to include the snippet via server side.

This is what it should look like:

 

Handling an Existing Order

You should keep track of the Klarna order_id associated with the current customer to avoid creating a new order every time the customer loads the checkout page. This will allow the customer to reload the checkout page without having to re-enter any information they have already provided. 

When the customer loads the checkout page and have a Klarna order_id associated with their session you should fetch the order from Klarna. If the order contents have changed you should make an update to the order.

1. Retrieve the Order

Use the checkout order_id to fetch the order from Klarna.

Retrieve Checkout Order Request

GET /checkout/v3/orders/order_id
Authorization: Basic pwhcueUff0MmwLShJiBE9JHA==
Content-Type: application/json
{
 "order_id": "1203c28c-f101-765f-bed8-f57a2d5e83e0",
 "status": "checkout_incomplete",
 "purchase_country": "se",
 "purchase_currency": "sek",
 "locale": "en-GB",
 "billing_address": {
   "given_name": "Testperson-se",
   "family_name": "Approved",
   "email": "youremail@email.com",
   "street_address": "Stårgatan 1",
   "postal_code": "12345",
   "city": "Ankeborg",
   "phone": "+46765260000",
   "country": "se"
 },
 "customer": {},
 "shipping_address": {
   "given_name": "Testperson-se",
   "family_name": "Approved",
   "email": "youremail@email.com",
   "street_address": "Stårgatan 1",
   "postal_code": "12345",
   "city": "Ankeborg",
   "phone": "+46765260000",
   "country": "se"
 },
 "order_amount": 503341,
 "order_tax_amount": 100668,
 "order_lines": [
   {
     "type": "physical",
     "reference": "19-402-SWE",
     "name": "Camera Travel Set",
     "quantity": 1,
     "quantity_unit": "pcs",
     "unit_price": 603341,
     "tax_rate": 2500,
     "total_amount": 503341,
     "total_discount_amount": 100000,
     "total_tax_amount": 100668,
     "image_url": "http://merchant.com/logo.png"
   }
 ],
 "merchant_urls": {
   "terms": "http://merchant.com/tac.php",
   "checkout": "http://merchant.com/checkout.php?sid={checkout.order.id}",
   "confirmation": "http://merchant.com/thankyou.php?sid={checkout.order.id}",
   "push": "http://localhost/kco/push.php?checkout_uri={checkout.order.id}"
 },
 "html_snippet": "<div id=\"klarna-checkout-container\"...................",
 "started_at": "2018-01-24T14:21:55Z",
 "last_modified_at": "2018-01-24T14:21:55Z",
 "options": {
   "allow_separate_shipping_address": false,
   "date_of_birth_mandatory": false,
   "require_validate_callback_success": false
 },
 "external_payment_methods": [],
 "external_checkouts": [],
 "shipping_options": [
   {
     "id": "free_shipping",
     "name": "Free Shipping",
     "description": "Delivers in 5-7 days",
     "price": 0,
     "tax_amount": 0,
     "tax_rate": 0,
     "preselected": true,
     "shipping_method": "Home"
   },
   {
     "id": "pick_up_store",
     "name": "Pick up at closest store",
     "price": 399,
     "tax_amount": 0,
     "tax_rate": 0,
     "preselected": false,
     "shipping_method": "PickUpStore"
   }
 ],
 "selected_shipping_option": {
   "id": "free_shipping",
   "name": "Free Shipping",
   "description": "Delivers in 5-7 days",
   "price": 0,
   "tax_amount": 0,
   "tax_rate": 0,
   "preselected": true,
   "shipping_method": "Home"
 }
}

2. Update the Checkout Order

You should update the checkout order to reflect the changes that the customer has made to the cart. The request below will update the order with adding another item to the card.

Updating Order Request

POST /checkout/v3/orders/order_id
Authorization: Basic pwhcueUff0MmwLShJiBE9JHA==
Content-Type: application/json
{
 "order_amount": 756682,
 "order_tax_amount": 151336,
 "order_lines": [
   {
     "type": "physical",
     "reference": "19-402-SWE",
     "name": "Camera Travel Set",
     "quantity": 1,
     "quantity_unit": "pcs",
     "unit_price": 603341,
     "tax_rate": 2500,
     "total_amount": 503341,
     "total_discount_amount": 100000,
     "total_tax_amount": 100668,
     "image_url": "http://merchant.com/logo.png"
   },
   {
     "type": "physical",
     "reference": "19-403-SWE",
     "name": "MP3 Player with Audio",
     "quantity": 1,
     "quantity_unit": "pcs",
     "unit_price": 303341,
     "tax_rate": 2500,
     "total_amount": 253341,
     "total_discount_amount": 50000,
     "total_tax_amount": 50668,
     "image_url": "http://merchant.com/logo.png"
   }
 ]
}
{
 "order_id": "1203c28c-f101-765f-bed8-f57a2d5e83e0",
 "status": "checkout_incomplete",
 "purchase_country": "se",
 "purchase_currency": "sek",
 "locale": "en-GB",
 "billing_address": {
   "given_name": "Testperson-se",
   "family_name": "Approved",
   "email": "youremail@email.com",
   "street_address": "Stårgatan 1",
   "postal_code": "12345",
   "city": "Ankeborg",
   "phone": "+46765260000",
   "country": "se"
 },
 "customer": {},
 "shipping_address": {
   "given_name": "Testperson-se",
   "family_name": "Approved",
   "email": "youremail@email.com",
   "street_address": "Stårgatan 1",
   "postal_code": "12345",
   "city": "Ankeborg",
   "phone": "+46765260000",
   "country": "se"
 },
 "order_amount": 756682,
 "order_tax_amount": 151336,
 "order_lines": [
   {
     "type": "physical",
     "reference": "19-402-SWE",
     "name": "Camera Travel Set",
     "quantity": 1,
     "quantity_unit": "pcs",
     "unit_price": 603341,
     "tax_rate": 2500,
     "total_amount": 503341,
     "total_discount_amount": 100000,
     "total_tax_amount": 100668,
     "image_url": "http://merchant.com/logo.png"
   },
   {
     "type": "physical",
     "reference": "19-403-SWE",
     "name": "MP3 Player with Audio",
     "quantity": 1,
     "quantity_unit": "pcs",
     "unit_price": 303341,
     "tax_rate": 2500,
     "total_amount": 253341,
     "total_discount_amount": 50000,
     "total_tax_amount": 50668,
     "image_url": "http://merchant.com/logo.png"
   }
 ],
 "merchant_urls": {
   "terms": "http://merchant.com/tac.php",
   "checkout": "http://merchant.com/checkout.php?sid={checkout.order.id}",
   "confirmation": "http://merchant.com/thankyou.php?sid={checkout.order.id}",
   "push": "http://localhost/kco/push.php?checkout_uri={checkout.order.id}"
 },
 "html_snippet": "<div id=\"klarna-checkout-container\"................",
 "started_at": "2018-01-24T14:21:55Z",
 "last_modified_at": "2018-01-24T15:03:10Z",
 "options": {
   "allow_separate_shipping_address": false,
   "date_of_birth_mandatory": false,
   "require_validate_callback_success": false
 },
 "external_payment_methods": [],
 "external_checkouts": [],
 "shipping_options": [
   {
     "id": "free_shipping",
     "name": "Free Shipping",
     "description": "Delivers in 5-7 days",
     "price": 0,
     "tax_amount": 0,
     "tax_rate": 0,
     "preselected": true,
     "shipping_method": "Home"
   },
   {
     "id": "pick_up_store",
     "name": "Pick up at closest store",
     "price": 399,
     "tax_amount": 0,
     "tax_rate": 0,
     "preselected": false,
     "shipping_method": "PickUpStore"
   }
 ],
 "selected_shipping_option": {
   "id": "free_shipping",
   "name": "Free Shipping",
   "description": "Delivers in 5-7 days",
   "price": 0,
   "tax_amount": 0,
   "tax_rate": 0,
   "preselected": true,
   "shipping_method": "Home"
 }
}

Note: Find out more about the different fields in the cart items list in the API Reference.

 

Update an Ongoing Checkout Order

If you want to update an order while the customer is on the checkout page, you will need to suspend the checkout, update the order, and then resume the checkout to make sure the information shown in the checkout is up to date.

The flow is visualized in the chart below:

1. Suspend the Checkout

Suspending the checkout puts it in a waiting state, preventing customer input. A loading icon is rendered on top of the iframe indicating to the customer that the checkout is loading.

You can do this by issuing a Javascript command, as per the code example below:

window._klarnaCheckout(function (api) {
    api.suspend();
});

2. Update the Order

Update the order as you did in the example above.

3. Resume the Checkout

Resuming the checkout forces it to fetch the most recent order data from Klarna. The loading indicator will disappear, the form will become enabled. The amount presented in the checkout will now reflect the new order total.

window._klarnaCheckout(function (api) {
    api.resume();
});

 

Validating the Order Before it is Completed

For a number of different reasons there could be a need to validate the order before it is completed. You can register a callback on the order create (where you can do the final merchant validation) that Klarna will call when the customer clicks the buy button. Find out more in the Order validation API.

 

What's next?

You have integrated Klarna Checkout into your checkout page.

The next step is to render the confirmation snippet.