3. Authorize

When the customer presses the buy/continue* submit button on your checkout page, you call our Javascript SDK to authorize the order at Klarna and receive an authorization token in return. The authorization token gives you the flexibility to authorize and place the order in separate steps.

*If you have a

  • single-page checkout, you call authorize when the consumer presses the buy button
  • multiple-page checkout, you call authorize when the consumer presses the continue/review order button and finalize the order when the consumer presses the buy button

Placing the final order can then be done either immediately, or on a separate page. This is entirely up to you.

3.1 Authorize the order

As a merchant you will not handle the potentially sensitive information that is entered by the consumer, this information is only available to Klarna. A successful authorization guarantees that the order can be created within 60 minutes.

The authorization is made with a client side call to authorize(). The result of a successful authorization (approved: true) is an authorization_token that should be used when creating the order. The response object also includes a key show_form which indicates whether or not the Klarna payment option should remain available (i.e. success case or errors that the user can resolve) or if you should remove the option entirely (i.e. final rejection).

If you integrate a multi-step checkout you can call authorize() with the auto_finalize: false property set in order to indicate that there is a finalization step. In this case the response may differ. More information is provided in the Finalize paragraph.

In the authorize() call you may also pass the billing (and optionally shipping) address. Klarna will use all information that has been collected during this session when authorizing the order.

Also, to ensure that customers understand that some processing is going on in the background, when authorize() is called, it should be visually shown that something is happening (e.g. a spinner in the button that triggered the authorize() call).

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
Klarna.Payments.authorize({
  payment_method_category: "pay_later"
}, {
  purchase_country: "GB",
  purchase_currency: "GBP",
  locale: "en-GB",
  billing_address: {
    given_name: "John",
    family_name: "Doe",
    email: "john@doe.com",
    title: "Mr",
    street_address: "13 New Burlington St",
    street_address2: "Apt 214",
    postal_code: "W13 3BG",
    city: "London",
    region: "",
    phone: "01895808221",
    country: "GB"
  },
  shipping_address: {
    given_name: "John",
    family_name: "Doe",
    email: "john@doe.com",
    title: "Mr",
    street_address: "13 New Burlington St",
    street_address2: "Apt 214",
    postal_code: "W13 3BG",
    city: "London",
    region: "",
    phone: "01895808221",
    country: "GB"
  },
  order_amount: 10,
  order_tax_amount: 0,
  order_lines: [{
    type: "physical",
    reference: "19-402",
    name: "Battery Power Pack",
    quantity: 1,
    unit_price: 10,
    tax_rate: 0,
    total_amount: 10,
    total_discount_amount: 0,
    total_tax_amount: 0,
    product_url: "https://www.estore.com/products/f2a8d7e34",
    image_url: "https://www.exampleobjects.com/logo.png"
  }],
  customer: {
    date_of_birth: "1970-01-01",
    gender: "male"
  },
}, function(res) {
  console.debug(res);
})
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
Klarna.Payments.authorize({
  payment_method_category: "pay_later"
}, {
  billing_address: {
    given_name: "Omer",
    family_name: "Heberstreit",
    email: "omer@Heberstreit.com",
    title: "Herr",
    street_address: "Im Friedenstal 38",
    street_address2: "2. Stock",
    postal_code: "55006",
    city: "WestSchon Matishagenfeld",
    region: "",
    phone: "+491522113356",
    country: "DE"
  },
  customer: {
    date_of_birth: "1970-01-01",
    gender: "male"
  }
}, function(res) {
  console.debug(res);
})

// Success -> {authorization_token: "b4bd3423-24e3", approved: true, show_form: true}
// Error in update → {approved: false, show_form: true, error: {invalid_fields: ["billing_address.email"]}}
// Other customer resolvable error → {approved: false, show_form: true}
// None resolvable error (hide payment option) → {approved: false, show_form: false}
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
Klarna.Payments.authorize({
  payment_method_category: "pay_later"
}, {
  billing_address: {
    given_name: "Edwin",
    family_name: "Blochwitz",
    email: "edwin@blochwitz.com",
    title: "Herr",
    street_address: "Paul Peters-Gasse 60b",
    postal_code: "1733",
    city: "WestZerlachmouth",
    region: "OO",
    phone: "+43 676 2600000",
    country: "AT"
  },
  customer: {
      date_of_birth: "1970-01-01",
      gender: "male"
  }
}, function(res) {
  console.debug(res);
})

// Success -> {authorization_token: "b4bd3423-24e3", approved: true, show_form: true}
// Error in update → {approved: false, show_form: true, error: {invalid_fields: ["billing_address.email"]}}
// Other customer resolvable error → {approved: false, show_form: true}
// None resolvable error (hide payment option) → {approved: false, show_form: false}
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
Klarna.Payments.authorize({
  payment_method_category: "pay_later"
}, {
  purchase_country: "NL",
  purchase_currency: "EUR",
  locale: "nl-NL",
  billing_address: {
    given_name: "Sander",
    family_name: "Dekker",
    email: "sander@dekker.com",
    title: "Dhr.",
    street_address: "Boerpark 742 II",
    postal_code: "7551 JI",
    city: "Enschede",
    region: "",
    phone: "06-14341727",
    country: "NL"
  },
  shipping_address: {
    given_name: "Sander",
    family_name: "Dekker",
    email: "sander@dekker.com",
    title: "Dhr.",
    street_address: "Boerpark 742 II",
    postal_code: "7551 JI",
    city: "Enschede",
    region: "",
    phone: "06-14341727",
    country: "NL"
  },
  order_amount: 10,
  order_tax_amount: 0,
  order_lines: [{
    type: "physical",
    reference: "19-402",
    name: "Battery Power Pack",
    quantity: 1,
    unit_price: 10,
    tax_rate: 0,
    total_amount: 10,
    total_discount_amount: 0,
    total_tax_amount: 0,
    product_url: "https://www.estore.com/products/f2a8d7e34",
    image_url: "https://www.exampleobjects.com/logo.png"
  }],
  customer: {
    date_of_birth: "1970-01-01",
    gender: "male"
  },
}, function(res) {
  console.debug(res);
})
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
Klarna.Payments.authorize({
  payment_method_category: "pay_later"
}, {
  purchase_country: "DK",
  purchase_currency: "DKK",
  locale: "da-DK",
  billing_address: {
    given_name: "Michael",
    family_name: "Sorensen",
    email: "michael@sorensen.com",
    street_address: "Nygyde 8",
    postal_code: "2042",
    city: "MunkeRudvaerklose",
    region: "",
    phone: "29911076",
    country: "DK"
  },
  shipping_address: {
    given_name: "Michael",
    family_name: "Sorensen",
    email: "michael@sorensen.com",
    street_address: "Nygyde 8",
    postal_code: "2042",
    city: "MunkeRudvaerklose",
    region: "",
    phone: "29911076",
    country: "DK"
  },
  order_amount: 10,
  order_tax_amount: 0,
  order_lines: [{
    type: "physical",
    reference: "19-402",
    name: "Battery Power Pack",
    quantity: 1,
    unit_price: 10,
    tax_rate: 0,
    total_amount: 10,
    total_discount_amount: 0,
    total_tax_amount: 0,
    product_url: "https://www.estore.com/products/f2a8d7e34",
    image_url: "https://www.exampleobjects.com/logo.png"
  }],
  customer: {
    national_identification_number: "3108971100",
    gender: "male"
  },
}, function(res) {
  console.debug(res);
})
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
Klarna.Payments.authorize({
  payment_method_category: "pay_later"
}, {
  purchase_country: "NO",
  purchase_currency: "NOK",
  locale: "nb-NO",
  billing_address: {
    given_name: "Marius",
    family_name: "Huseby",
    email: "marius@huseby.com",
    street_address: "Hagens Gate 53",
    postal_code: "2151",
    city: "Oslo",
    region: "",
    phone: "+45 40 123 456",
    country: "NO"
  },
  shipping_address: {
    given_name: "Marius",
    family_name: "Huseby",
    email: "marius@huseby.com",
    street_address: "Hagens Gate 53",
    postal_code: "2151",
    city: "Oslo",
    region: "",
    phone: "+45 40 123 456",
    country: "NO"
  },
  order_amount: 10,
  order_tax_amount: 0,
  order_lines: [{
    type: "physical",
    reference: "19-402",
    name: "Battery Power Pack",
    quantity: 1,
    unit_price: 10,
    tax_rate: 0,
    total_amount: 10,
    total_discount_amount: 0,
    total_tax_amount: 0,
    product_url: "https://www.estore.com/products/f2a8d7e34",
    image_url: "https://www.exampleobjects.com/logo.png"
  }],
  customer: {
    national_identification_number: "01125637848",
    gender: "male"
  },
}, function(res) {
  console.debug(res);
})
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
Klarna.Payments.authorize({
  payment_method_category: "pay_later"
}, {
  purchase_country: "FI",
  purchase_currency: "EUR",
  locale: "fi-FI",
  billing_address: {
    given_name: "Saimi",
    family_name: "Pennanen",
    email: "saimi@pennanen.com",
    street_address: "Meriluotokatu 447",
    postal_code: "78164",
    city: "Helsinki",
    phone: "+358 401234567",
    country: "FI"
  },
  shipping_address: {
    given_name: "Saimi",
    family_name: "Pennanen",
    email: "saimi@pennanen.com",
    street_address: "Meriluotokatu 447",
    postal_code: "78164",
    city: "Helsinki",
    phone: "+358 401234567",
    country: "FI"
  },
  order_amount: 10,
  order_tax_amount: 0,
  order_lines: [{
    type: "physical",
    reference: "19-402",
    name: "Battery Power Pack",
    quantity: 1,
    unit_price: 10,
    tax_rate: 0,
    total_amount: 10,
    total_discount_amount: 0,
    total_tax_amount: 0,
    product_url: "https://www.estore.com/products/f2a8d7e34",
    image_url: "https://www.exampleobjects.com/logo.png"
  }],
  customer: {
    national_identification_number: "070857-7573",
    gender: "male"
  },
}, function(res) {
  console.debug(res);
})
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
Klarna.Payments.authorize({
  payment_method_category: "pay_later"
}, {
  purchase_country: "SE",
  purchase_currency: "SEK",
  locale: "sv-SE",
  billing_address: {
    given_name: "Håkan",
    family_name: "Larsson",
    email: "hakan.larsson.test@klarna.com",
    street_address: "Lars Väg 399",
    postal_code: "11354",
    city: "Stockholm",
    phone: "0765260000",
    country: "SE"
  },
  shipping_address: {
    given_name: "Håkan",
    family_name: "Larsson",
    email: "hakan.larsson.test@klarna.com",
    street_address: "Lars Väg 399",
    postal_code: "11354",
    city: "Stockholm",
    phone: "0765260000",
    country: "SE"
  },
  order_amount: 10,
  order_tax_amount: 0,
  order_lines: [{
    type: "physical",
    reference: "19-402",
    name: "Battery Power Pack",
    quantity: 1,
    unit_price: 10,
    tax_rate: 0,
    total_amount: 10,
    total_discount_amount: 0,
    total_tax_amount: 0,
    product_url: "https://www.estore.com/products/f2a8d7e34",
    image_url: "https://www.exampleobjects.com/logo.png"
  }],
  customer: {
    national_identification_number: "410321-9202",
    gender: "male"
  },
}, function(res) {
  console.debug(res);
})
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
Klarna.Payments.authorize({
  payment_method_category: "pay_over_time"
}, {
  purchase_country: "US",
  purchase_currency: "USD",
  locale: "en-US",
  billing_address: {
    given_name: "John",
    family_name: "Doe",
    email: "john@doe.com",
    title: "Mr",
    street_address: "Lombard St 10",
    street_address2: "Apt 214",
    postal_code: "90210",
    city: "Beverly Hills",
    region: "CA",
    phone: "333444555",
    country: "US"
  },
  shipping_address: {
    given_name: "John",
    family_name: "Doe",
    email: "john@doe.com",
    title: "Mr",
    street_address: "Lombard St 10",
    street_address2: "Apt 214",
    postal_code: "90210",
    city: "Beverly Hills",
    region: "CA",
    phone: "333444555",
    country: "US"
  },
  order_amount: 10,
  order_tax_amount: 0,
  order_lines: [{
    type: "physical",
    reference: "19-402-USA",
    name: "Battery Power Pack",
    quantity: 1,
    unit_price: 10,
    tax_rate: 0,
    total_amount: 10,
    total_discount_amount: 0,
    total_tax_amount: 0,
    product_url: "https://www.estore.com/products/f2a8d7e34",
    image_url: "https://www.exampleobjects.com/logo.png"
  }],
  customer: {
    date_of_birth: "1970-01-01",
    gender: "male"
  },
}, function(res) {
  console.debug(res);
})

There is no need to provide fields that have already been provided previously during the session, unless the content in those fields has changed. That said, providing the same data again will not break anything. Best practice is to call authorize using a full request (like in the example above) to be sure the most up to date content is being authorized.

User interaction during the authorize call

When authorizing the order, Klarna conducts a full risk assessment. Therefore, from the point where you call authorize until you receive the callback you must:

  1. Avoid sending another authorize call (e.g. disable the buy button from being clicked again)
  2. Show to the consumer that the order is being processed (e.g. by showing a loading spinner)
  3. Prevent consumer from changing order or billing details (e.g. lock the input fields on your page)

The callback is typically received within seconds, but may take up to a minute or so in case a consumer sign-up is required when the user interacts with the widget.

3.2 Act on the callback from the authorize call

When the widget has processed the authorization, the callback will be executed.

The callback function parameter is an object containing the following properties

  • approved (true/false) - the authorization result, approved or denied
  • show_form (true/false) - whether the Klarna Widget should be displayed or hidden
  • authorization_token - a token which allows you to place the order via a server side call, only returned if the authorization was approved
  • error - contains details of potential error messages

Finalize the authorization

finalize() is a special call that is needed for the Pay Now payment method category in multi-step checkouts. In a multi-step checkout scenario the authorize() call can be triggered when the consumer selects the payment method and then presses the “continue” button to go to the next step of the checkout. With Pay Now as payment method category however transferring the funds should only happen once the consumer has pressed the “buy” button to finalize the purchase. To cater for such a scenario authorize() can still be called when the consumer has selected the payment method, but with the auto_finalize property set to false.

authorize() example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14

Klarna.Payments.authorize(
  { payment_method_category: ‘pay_now’, auto_finalize: false},
  {}, 
  function(res) {
  // proceed to next checkout page. The finalize_required property in the response indicates 
  // if finalize is needed or not.
  // 
  // res = {
  //   show_form: true,
  //   approved: false,
  //   finalize_required: true
  // }
})

Now when the consumer reached the last page in the checkout and can finalize the purchase finalize() is called. This will then trigger the transfer of funds and return the authorization token in the finalize callback. The flow is transparent to all payment method categories. That means if finalization was not needed in the authorize() call (e.g. for pay later) finalize() can be still be called and will return the authorization_token so that the implementation remains the same for all payment method categories.

finalize() example:

1
2
3
4
5
6
7
8
9
10
11

Klarna.Payments.finalize(
  {payment_method_category: ‘pay_now’},
  {}, 
  function(res) {
  // res = {
  //   show_form: true,
  //   approved: true,
  //   authorization_token: ...
  // }
})

Order approved

If approved: true, then Klarna has approved the authorization of credit for this order.

1
2
3
4
5
{
  authorization_token: "b4bd3423-24e3", 
  approved: true, 
  show_form: true
}

The authorization_token allows you to complete the order by the server side place order call. The token is valid for 60 minutes. During this time, the authorization is guaranteed. In case the place order is performed beyond the expiry, Klarna will try to re-authorize the order but cannot guarantee a successful outcome.

  • Best practice tip: You may store the authorization_token in a hidden form field and submit it to the backend with the “buy” / “Place order” form submit button.

Order not approved

If approved: false, Klarna cannot approve the purchase. There are now two options

More information needed

show_form: true and e.g error: { invalid_fields: ["billing_address.email"] } } the widget will display an error message to the consumer, asking them to correct it before you re-authorize the order. You may use the error message in the callback object to highlight a particular entry field (in this case the customers email address) on your page.

Customer interaction aborted

If show_form: true and no error is included in the callback, the customer has aborted a required interaction in the widget i.e. the credit signup flow. In this case you should continue to show Klarna’s options as the customer might want to make another attempt at completing the purchase with Klarna.

Order declined

If show_form: false, the order is declined. The widget should be hidden and the user should select another payment method.

Tokenization

With an authorization_token, it is possible to create tokens for recurring charges or directly place an order using the order endpoint. The token endpoint is called to tokenize the payment method and create the chargeable customer token. The server call includes the authorization_token in the URL and a successful registration for a token would return a customer_token id. The customer token can then be used in order to charge the customer without the customer being present.

3.3 Create Customer Token

After having obtained an authorization token instead of placing the order you can use the authorization token to create a customer token. There is no need to charge the customer at this point, the customer token can be created, stored, and charged at a later stage.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
POST /payments/v1/authorizations/{authorizationToken}/customer-token
Authorization: Basic pwhcueUff0MmwLShJiBE9JHA==
Content-Type: application/json

{
  "purchase_country": "SE",
  "locale": "sv-SE",
  "billing_address" : {
    "given_name": "Doe",
    "family_name": "John",
    "email": "direct_debit@klarna.com",
    "phone": "01895808221",
    "street_address": "Stårgatan 1",
    "postal_code": "12345",
    "city": "Ankeborg",
    "country": "SE"
  },
  "description": "MySaaS subscription",
  "intended_use": "subscription",
  "merchant_urls": {
    "confirmation": "string"
  }
}

The response will contain a redirect URL to which the user should be redirected. The user will bounce through Klarna and be redirected to the confirmation URL provided in the API calls.

1
2
3
4
5
6
7
8
9
HTTP/1.1 200 OK

Content-Type: application/json
Klarna-Correlation-Id: e19dc121-1276-419d-882a-c343d58fb9aa

{
  "token_id": "0b1d9815-165e-42e2-8867-35bc03789e00",
  "redirect_url": "string"
}

3.4 Release Authorization

After creating a token the authorized amount can be released if it the authorization token won’t be used to place an order immediately. Releasing the authorized amount will free up the available purchase amount for this customer. Realising the authorized amount is done by performing a Delete operation. Additional reading can be found here.

Example request:

1
2
3
4
DELETE /payments/v1/authorizations/{authorizationToken}
Authorization: Basic pwhcueUff0MmwLShJiBE9JHA==
Content-Type: application/json
{ }

Example response:

1
2
3
4
5
6
7
HTTP/1.1 204 No Content

Content-Type: application/json
Klarna-Correlation-Id: e19dc121-1276-419d-882a-c343d58fb9aa

{ }

What’s next?

Using the authorization token, you will now call the server side REST API to place the order