How to use Instant Shopping Offsite

During the next steps you will learn how to use Instant Shopping Button outside your domain, aka offsite. Relevant use cases are:

  • Blogs: Buy without redirects from blogs or other posts;
  • Ads: Buy without redirects from ads;
  • QR codes: Scan-and-buy experience with a hosted page by Klarna;
  • Email campaigns: Direct links to buy from email and newsletter campaigns;

The idea is that you create an Instant Shopping button key that includes already all the information necessary for the purchase flow. Then, you leverage the direct links that Klarna offers to distribute and advertise. Those links lead to a page that is hosted by Klarna and offers a simple and smoooth purchase flow.

1. Obtain an Instant Shopping Button Key (server-side)

You complete this step leveraging the Instant Shopping Button Keys API from your server-side

After you complete this step you will have a static Button key ready to be used anywhere and offer a purchase flow through Instant Shopping. The button is static in the sense that it includes all the information necessary to:

  • identify you as a merchant,
  • do the necessary setup in terms of e.g. purchase country, locale, etc.,
  • specify the product(s) being sold,
  • define the applicable shipping options.

An example of a request to the service in order to obtain a Button key is given below. Note that the order_amount and order_tax_amount will be calculated by the service. If the product you want to sell comes in variations (of colors, sizes) it is advised that you configure the button key with all the product variations using the items property.

Note: Read about Klarna’s API URLs to know the base URL, and about Authentication to know how to authenticate when calling our REST API. More detailed documentation on the Instant Shopping orders API is available in the API documentation .

Required Fields It should be noted, the minimum required fields needed to generate a functioning button key for offsite use are as follows:

  • merchant_urls
    • place_order - URL of an endpoint at the merchant side, which will receive a ping to place an order. (must be https, max 2000 characters)
    • terms - URL of a page on the merchant side describing the terms and conditions. (max 2000 characters)
    • confirmation - URL of a page that the consumers will be redirected to after completing a purchase with Instant Shopping. (max 2000 characters)

Request to generate a Button key

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
POST /instantshopping/v1/buttons
Authorization: Basic pwhcueUff0MmwLShJiBE9JHA==
Content-Type: application/json
{
  "purchase_country": "SE",
  "purchase_currency": "SEK",
  "locale": "sv-SE",
  "merchant_urls": {
    "place_order": "https://www.example.com/place_order.php", // mandatory, URL of an endpoint at the merchant side, which will receive a ping to place an order. (must be https, max 2000 characters)
    "terms": "https://www.example.com/terms.php", // mandatory, URL of a page on the merchant side describing the terms and conditions. (max 2000 characters)
    "confirmation": "https://www.example.com/confirmation.php", // mandatory, URL of a page that the consumers will be redirected to after completing a purchase with Instant Shopping. (max 2000 characters)
    "push": "https://www.example.com/push.php", // optional, URL of an endpoint at the merchant side, which will receive a ping when an order is completed within Klarna's order management. (must be https, max 2000 characters)
    "notification": "https://www.example.com/notification.php", // optional, URL of an endpoint at the merchant side, which will receive notifications on pending orders. (must be https, max 2000 characters)
    "update": "https://www.example.com/update.php" // optional, URL for applying price, shipping, tax and purchase currency updates as a result of an update. (must be https, max 2000 characters)
  },
  "items": [
    {
      "type": "physical",
      "reference": "CLBS-52mm-pol",
      "name": "Classic Low Bridge Sunglasses 52mm Polarized",
      "unit_price": 60000,
      "total_amount": 50000,
      "total_tax_amount": 0,
      "tax_rate": 0,
      "total_discount_amount": 10000,
      "image_url": "https://example.com/sunglasses-52mm-polarized.jpg",
      "group_identifier": "demo.store.items",
      "product_attributes": [
        {
          "identifier": "Frame size",
          "identifier_label": "Frame size",
          "value": "52mm",
          "value_label": "52mm"
        },
        {
          "identifier": "Polarization",
          "identifier_label": "Polarization",
          "value": "Polarized",
          "value_label": "Polarized"
        }
      ]
    },
    {
      "type": "physical",
      "reference": "CLBS-58mm-pol",
      "name": "Classic Low Bridge Sunglasses 58mm Polarized",
      "unit_price": 60000,
      "total_amount": 50000,
      "total_tax_amount": 0,
      "tax_rate": 0,
      "total_discount_amount": 10000,
      "image_url": "https://example.com/sunglasses-58mm-polarized.jpg",
      "group_identifier": "demo.store.items",
      "product_attributes": [
        {
          "identifier": "Frame size",
          "identifier_label": "Frame size",
          "value": "58mm",
          "value_label": "58mm"
        },
        {
          "identifier": "Polarization",
          "identifier_label": "Polarization",
          "value": "Polarized",
          "value_label": "Polarized"
        }
      ]
    },
    {
      "type": "physical",
      "available": true,
      "reference": "CLBS-52mm-nonpol",
      "name": "Classic Low Bridge Sunglasses 52mm Non-Polarized",
      "unit_price": 40000,
      "total_amount": 30000,
      "total_tax_amount": 0,
      "tax_rate": 0,
      "total_discount_amount": 10000,
      "image_url": "https://example.com/sunglasses-52mm-nonpolarized.jpg",
      "group_identifier": "demo.store.items",
      "product_attributes": [
        {
          "identifier": "Frame size",
          "identifier_label": "Frame size",
          "value": "52mm",
          "value_label": "52mm"
        },
        {
          "identifier": "Polarization",
          "identifier_label": "Polarization",
          "value": "Non-Polarized",
          "value_label": "Non-polarized"
        }
      ]
    },
    {
      "type": "physical",
      "available": true,
      "reference": "CLBS-58mm-nonpol",
      "name": "Classic Low Bridge Sunglasses 58mm Polarized",
      "unit_price": 40000,
      "total_amount": 30000,
      "total_tax_amount": 0,
      "tax_rate": 0,
      "total_discount_amount": 10000,
      "image_url": "https://example.com/sunglasses-58mm-nonpolarized.jpg",
      "group_identifier": "demo.store.items",
      "product_attributes": [
        {
          "identifier": "Frame size",
          "identifier_label": "Frame size",
          "value": "58mm",
          "value_label": "58mm"
        },
        {
          "identifier": "Polarization",
          "identifier_label": "Polarization",
          "value": "Non-Polarized",
          "value_label": "Non-polarized"
        }
      ]
    }
  ],
  "shipping_options": [{
    "id": "express_priority",
    "name": "Express 1-2 days",
    "description": "Delivery by 4:30pm",
    "price": 5000,
    "tax_amount": 0,
    "tax_rate": 0,
    "shipping_method": "PickUpStore"
  }]
}

Upon success the response of this service will provide you the button key.

Response for created Button key

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
HTTP 201 Created
Content-Type: application/json
Location: /instantshopping/v1/buttons/123e4567-e89b-12d3-a456-426655440000
{
  "button_key": "123e4567-e89b-12d3-a456-426655440000",
  "merchant_urls": { /* ... */ },
  "purchase_country": "string",
  "purchase_currency": "string",
  "locale": "string",
  "items":  [ /*...*/ ],
  "shipping_options": [ /*...*/ ],
  "links": [
    {
      "rel":"hosted_page_url",
      "href":"https://pop.playground.klarna.com/kis-d2f56584-89fe-4b40-8719-4a4ad1a12de6"
    },
    {
      "rel":"hosted_page_qrcode",
      "href":"https://pop.playground.klarna.com/kis-d2f56584-89fe-4b40-8719-4a4ad1a12de6/qr"
    }
  ]
}

In the response body you will also find the distribution links offered by Klarna.

hosted_page_url

This is a link to a page hosted by Klarna, where your customers can buy the specific product inside the Instant Shopping flow.

An example is shown in the image below: Instant Shopping QR codeInstant Shopping QR code

hosted_page_qrcode

This is a link to page page where you can print the QRcode to the above mentioned hosted purchase page by Klarna.

An example is shown in the image below: Instant Shopping QR codeInstant Shopping QR code

The recommended use of these links is for offline campaigns and/or selling online when you do not necessary need to own the webpage and UI.

Here are some ideas where you can use the links you obtained from the previous step:

  • Include the QR code in advertising material, discount coupons, etc.
  • Include the QR code in the product’s label for instore purchase of out of stock items.
  • Use the hosted page as the target of various social media posts, ads or email campaigns.

3. Place the order (server-side)

When customers have followed those distributions links and placed an order through Instant Shopping then you will receive a ping at the endpoint specified by the button key setup option merchant_urls.place_order.

You then decide whether to approve or deny the purchase. It is expected that you will run all necessary validations (stock, shipping capabilities, prices, etc.) on your side. Once those are done, approve or deny the order following the guidelines below.

Deny the order

If you need to deny the purchase you need to perform a DELETE call though our API and provide some information in the request body. Note that you need to use your API credentials to authenticate.

Below you may find an example of how a deny requests may look:

1
2
3
4
5
6
7
DELETE /instantshopping/v1/authorizations/{authorization_token}
Authorization: Basic pwhcueUff0MmwLShJiBE9JHA==
Content-Type: application/json
{
  "deny_code": "address_error",
  "deny_message": "We cannot ship at this address."
}

Place the order

If you accept the order, then you need to place the order with our REST API. You do so by performing an HTTP POST in our API for the specific authorization_token and passing to the request body the complete Order. Note that you need to use your API credentials to authenticate.

Here is an example of how the request to approve/ place the order looks:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
POST /instantshopping/v1/authorizations/{authorization_token}/orders
Authorization: Basic pwhcueUff0MmwLShJiBE9JHA==
Content-Type: application/json
  {
    "purchase_country": "SE",
    "purchase_currency": "SEK",
    "locale": "sv-SE",
    "merchant_urls": {
      "confirmation": "https://www.example.com/upsell.php", // mandatory if not given at step #3, this value will ovewrite the one set through button generation
      "push": "https://www.example.com/klarna-completed-orders", // optional, will overwrite the existing value if already set through button generation
      "notification": "https://www.example.com/klarna-pending-orders" // optional, will overwrite the existing value if already set through button generation
    },
    "billing_address": {
      "given_name": "John",
      "family_name": "Doe",
      "email": "john.doe@example.com",
      "street_address": "Sveavägen 46",
      "postal_code": "11134",
      "city": "Stockholm",
      "phone": "+460700020020",
      "country": "SE"
    },
    "shipping_address": {
      "given_name": "John",
      "family_name": "Doe",
      "email": "john.doe@example.com",
      "street_address": "Sveavägen 46",
      "postal_code": "11134",
      "city": "Stockholm",
      "phone": "+460700020020",
      "country": "SE"
    },
    "customer": {
      "date_of_birth": "1985-10-20",
      "gender": "male"
    },
    "order_amount": 405000,
    "order_tax_amount": 0,
    "order_lines": [{
      "type": "physical",
      "reference": "CLW-52m-5discount",
      "name": "Classic Low Bridge Sunglasses 5% Off Today!",
      "quantity": 1,
      "unit_price": 500000,
      "tax_rate": 2500,
      "total_amount": 500000,
      "total_discount_amount": 0,
      "total_tax_amount": 100000,
      "product_url": "https://www.example.com/products/f2a8d7e34",
      "image_url": "https://www.example.com/products/f2a8d7e34"
    }, {
      "type": "discount",
      "name": "5% Discount",
      "quantity": 1,
      "tax_rate": 0,
      "total_tax_amount": 0,
      "unit_price": -100000,
      "total_amount": -100000
    }, {
      "type": "shipping_fee",
      "name": "express_priority",
      "quantity": 1,
      "tax_rate": 2500,
      "total_tax_amount": 1000,
      "unit_price": 5000,
      "total_amount": 5000
    }],
    "merchant_reference1": "45aa52f387871e3a210645d4"
  }

4. Show post-purchase page

When the purchase is completed the consumer sees a view which summarizes what has been purchased and offers a way to buy again.

An example is shown in the image below: Instant Shopping hosted purchase page receiptInstant Shopping hosted purchase page receipt

Order Management

After the order is created, you can manage the order either manually via our Merchant Portal or through our Order Management API .