How to use Instant Shopping for Donations

Instant Shopping can be used to capture donations, either one-time or recurring.

The Instant Shopping button and the flow is adjusted in terms of copy and illustrations to help you with your purpose.

A. One-time donations

Following the guidelines and examples will help you setup Instant Shopping for capturing one time donations. The assumption here is that you will want to own the HTML button and merely use Instant Shopping payment flow.

A.1. Setup a Merchant ID

The first step is to setup a Merchant ID and configure Klarna Payments with the suitable payment methods for the capturing one time donations. This configuration should be done for all the billing countries the merchant wants to use Instant Shopping for.

For the next steps you will need the Klarna API Credentials (you can generate new after logging in to the Merchant Portal)

A.2. Create a button key

You need to create a Button key which you can reuse for displaying Instant Shopping in multiple pages. This key is used to identify you as a merchant and also to link to some necessary configuration options.

Since this key can be reused for displaying Instant Shopping in multiple pages, it is advised that you generate it once and then store it somewhere within your system.

To create a key you can use the Instant Shopping Button Keys Service . An example of a request to this service is given below. Note that you need to use your API credentials to authenticate.

Request

1
2
3
4
5
6
7
8
POST /instantshopping/v1/buttons
Authorization: Basic pwhcueUff0MmwLShJiBE9JHA==
Content-Type: application/json
{
  "merchant_urls": {
    "place_order": "< mandatory, URL of an endpoint at the merchant side, which will receive a ping to approve the one time donation. (must be https, max 2000 characters) >"
  }
}

Response

1
2
3
4
5
6
7
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": { /* ... */ }
}

A.3. Load Instant Shopping

In order for the Instant Shopping buttton to not be shown, all you need to do is add a flag to the options with which you load Instant Shopping through JavaScript.

This property is called include_button and should be set to false when you trigger the load JavaScript API method. The example below shows how you can use this:

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
window.klarnaAsyncCallback = function () {
  window.Klarna.InstantShopping.load({
    "setup": {
      "instance_id": "button-123abc456",
      "key": "123e4567-e89b-12d3-a456-426655440000",
      "environment": "production",
      "region": "eu"
    },
    "styling": {
      "theme": {
        "type": "donation"
      }
    },
    "include_button": false,
    "purchase_country": "SE",
    "purchase_currency": "SEK",
    "locale": "en-SE",
    "merchant_urls": {
      "terms": "https://example.com/terms"
    },
    "items": [
      {
        "type": "digital",
        "reference": "gift-100",
        "name": "One time gift",
        "unit_price": 10000,
        "tax_rate": 0,
        "total_amount": 10000,
        "total_tax_amount": 10000,
        "image_url": "https://example.com/logo.svg", // a logo for the gift
        "group_identifier": "one-time-gift",
        "product_attributes": [
          {
            "identifier": "price",
            "identifier_label": "Total",
            "value": "100",
            "value_label": "100 SEK"
          }
        ]
      },
      {
        "type": "digital",
        "reference": "gift-200",
        "name": "One time gift",
        "unit_price": 20000,
        "tax_rate": 0,
        "total_amount": 20000,
        "total_tax_amount": 20000,
        "image_url": "https://example.com/logo.svg", // a logo for the gift
        "group_identifier": "one-time-gift",
        "product_attributes": [
          {
            "identifier": "price",
            "identifier_label": "Total",
            "value": "200",
            "value_label": "200 SEK"
          }
        ]
      },
      {
        "type": "digital",
        "reference": "gift-500",
        "name": "One time gift",
        "unit_price": 50000,
        "tax_rate": 0,
        "total_amount": 50000,
        "total_tax_amount": 50000,
        "image_url": "https://example.com/logo.svg", // a logo for the gift
        "group_identifier": "one-time-gift",
        "product_attributes": [
          {
            "identifier": "price",
            "identifier_label": "Total",
            "value": "500",
            "value_label": "500 SEK"
          }
        ]
      },
      {
        "type": "digital",
        "reference": "gift-1000",
        "name": "One time gift",
        "unit_price": 100000,
        "tax_rate": 0,
        "total_amount": 100000,
        "total_tax_amount": 100000,
        "image_url": "https://example.com/logo.svg", // a logo for the gift
        "group_identifier": "one-time-gift",
        "product_attributes": [
          {
            "identifier": "price",
            "identifier_label": "Total",
            "value": "1000",
            "value_label": "1000 SEK"
          }
        ]
      }
    ]
  }, function (response) {
    console.log('Klarna.InstantShopping.load callback with data:' + JSON.stringify(response))
  })
}

A.4. Build your own HTML button

You can configure Instant Shopping to not include the Buy Button on the page. Instead you can build your own button and ensure that when customers click on your button, you will trigger the JavaScript API that Instant Shopping offers to open up the fullscreen flow .

It the example below, for an HTML button identified by the value my-instant-shopping-button then the following should work:

1
2
3
4
5
6
7
8
9
  document.getElementById('my-instant-shopping-button').onclick = function (e) {
    window.Klarna.InstantShopping.open({
      "setup": {
        "instance_id": "button-123abc456"
      }
    }, function (response) {
      console.log('Klarna.InstantShopping.open callback with data:' + JSON.stringify(response))
    })
  }

A.5. Approve/ Decline the one time donation

When the customer has chosen to finalize the flow, our server-side will ping you at the merchant_urls.place_order endpoint, and prompt you to approve this payment. You do not need to act on this request, you can merely respond with HTTP 200 and proceed.

Receive a ping

Request

At this point we expect that you validate the request body and decide whether you will approve/decline.

1
2
3
4
5
6
7
8
9
10
11
12
13
POST <merchant_urls.place_order>
Content-Type: application/json
{
  button_key: <kis_button_key>,
  authorization_token: <kis_auth_token>,
  order: {
    order_lines: ...,
    locale: '',
    purchase_currency: '',
    purchase_country: '',
    order_amount: ...
  }
}
Response

The response to this request is not important, you can reply with HTTP 200.

Approve

To approve the one time donation, you will need to perform a POST to Instant Shopping API, as shown in the example below. You will use the authorization_token from the ping request body above and provide the order of the request body.

1
2
3
4
5
6
7
8
9
10
POST /instantshopping/v1/authorizations/{authorization_token}/customer-tokens
Authorization: Basic pwhcueUff0MmwLShJiBE9JHA==
Content-Type: application/json
{
  order_lines: ...,
  locale: '',
  purchase_currency: '',
  purchase_country: '',
  order_amount: ...
}

Decline

To decline you will need to perform a DELETE to Instant Shopping API, as shown in the example below. You will use the authorization_token from the ping request body above.

1
2
3
DELETE /instantshopping/v1/authorizations/{authorization_token}
Authorization: Basic pwhcueUff0MmwLShJiBE9JHA==
Content-Type: application/json

A.6. Complete the flow

According to whether you have approved or declined the order, the customer will see a suitable view at the end. In case of approval the customer will see a confirmation of the order and be offered a link to continue to the page that you have specified with merchant_urls.confirmation. This is an ideal page for further engaging with your customers.

B. Recurring donation

Following the guidelines and examples below will help you setup Instant Shopping for creating donation subscriptions. This means that you will receive a customer token that you will then be able to charge according to the terms of the subscription. Charging the customer token is done via the Customer Tokens API

In the examples below, the assumption here is that you will want to use Klarna’s button tailored for Donations.

B. 1. Setup a Merchant ID

The first step is to setup a Merchant ID and configure Klarna Payments with the suitable payment methods for the purpose of generating customer tokens. This configuration should be done for all the billing countries the merchant wants to use Instant Shopping for.

For the next steps you will need the Klarna API Credentials (you can generate new after logging in to the Merchant Portal)

B.2. Create a button key

You need to create a Button key which you can reuse for displaying Instant Shopping in multiple pages. This key is used to identify you as a merchant and also to link to some necessary configuration options.

Since this key can be reused for displaying Instant Shopping in multiple pages, it is advised that you generate it once and then store it somewhere within your system.

To create a key you can use the Instant Shopping Button Keys Service . An example of a request to this service is given below. Note that you need to use your API credentials to authenticate.

Request

1
2
3
4
5
6
7
8
POST /instantshopping/v1/buttons
Authorization: Basic pwhcueUff0MmwLShJiBE9JHA==
Content-Type: application/json
{
  "merchant_urls": {
    "create_customer_token": "< mandatory, URL of an endpoint at the merchant side, which will receive a ping to approve the generation customer token. (must be https, max 2000 characters) >"
  }
}

Response

1
2
3
4
5
6
7
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": { /* ... */ }
}

B.3. Load Instant Shopping

When rendering the page that will include Instant Shopping you need to load the necessary resources to make Instant Shopping available.

Load the Instant Shopping library and invoke the JavaScript API, as soon as possible to achieve optimal rendering times. Also use the HTML element klarna-instant-shopping at the exact position where you want the button to appear in your page.

Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<head>
  ...
  <script src="https://x.klarnacdn.net/instantshopping/lib/v1/lib.js" async></script>
</head>
<body>
  ...
  <klarna-instant-shopping data-instance-id="button-123abc456" />
  ...
  <script>
    window.klarnaAsyncCallback = function () {
      // This is where you start calling Instant Shopping JS SDK functions
      //
      // window.Klarna.InstantShopping.load({....})
    };
  </script>
</body>

When you invoke window.Klarna.InstantShopping.load you need to pass the options necessary to configure the UI and the purpose of the flow.

Important: You need to provide a localized text describing the details of the subscription (cost, duration, start, end dates) by setting up the tokenization.description property.

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
window.klarnaAsyncCallback = function () {
  window.Klarna.InstantShopping.load({
    "setup": {
      "instance_id": "button-123abc456",
      "key": "123e4567-e89b-12d3-a456-426655440000",
      "environment": "production",
      "region": "eu"
    },
    "tokenization": {
      "description": "Legal text, describing the conditions of this subscription."
    },
    "include_button": false,
    "purchase_country": "SE",
    "purchase_currency": "SEK",
    "locale": "en-SE",
    "merchant_urls": {
      "terms": "https://example.com/terms",
      "confirmation": "https://example.com/subscription-thank-you.page"
    },
    "order_lines": [
      {
        "type": "digital",
        "reference": "gift-100",
        "name": "100 SEK/ monthly",
        "quantity": 1,
        "unit_price": 10000,
        "tax_rate": 0,
        "total_amount": 10000,
        "total_tax_amount": 10000,
        "image_url": "https://example.com/logo.svg" // a logo for the gift
      }
    ]
  }, function (response) {
    console.log('Klarna.InstantShopping.load callback with data:' + JSON.stringify(response))
  })
}

B.4. Approve/ Decline the customer token

When the consumer has chosen to finalize the flow, our server-side will ping you at the merchant_urls.create_customer_token endpoint, and prompt you to ask for the generation of a customer token. You do not need to act on this request, you can merely respond with HTTP 200 and proceed.

Receive a ping

Request

At this point we expect that you validate the request body and decide whether you will approve/decline.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
POST <merchant_urls.create_customer_token>
Content-Type: application/json
{
  button_key: <kis_button_key>,
  authorization_token: <kis_auth_token>,
  order: {
    order_lines: <the product the customer saw in KIS FE>,
    locale: '',
    purchase_currency: ''
  },
  customer_token_details: {
    billing_address: {},
    customer: {}
  }
}
Response

The response to this request is not important, you can reply with HTTP 200.

Approve

To approve and receive a customer token you will need to perform a POST to Instant Shopping API, as shown in the example below. You will use the authorization_token from the ping request body above.

1
2
3
POST /instantshopping/v1/authorizations/{authorization_token}/customer-tokens
Authorization: Basic pwhcueUff0MmwLShJiBE9JHA==
Content-Type: application/json

Decline

To decline you will need to perform a DELETE to Instant Shopping API, as shown in the example below. You will use the authorization_token from the ping request body above.

1
2
3
DELETE /instantshopping/v1/authorizations/{authorization_token}
Authorization: Basic pwhcueUff0MmwLShJiBE9JHA==
Content-Type: application/json

B.5. Complete the flow

According to whether you have approved or declined the order, the customer will see a suitable view at the end. In case of approval the customer will see a confirmation of the order and be offered a link to continue to the page that you have specified with merchant_urls.confirmation. This is an ideal page for further engaging with your customers.