Klarna Payments
Last updatedKlarna Payments is a PSP solution designed to incorporate Klarna's payment methods to existing checkout. By integrating with Klarna Payments, merchants retain control over the checkout experience, while also offering customers the convenience of Klarna's payment options to finalize their purchases.
Klarna Payments vs Klarna Checkout - ownership of the integration components#
Klarna Payments is an addition of payment methods to the existing merchant checkout, while Klarna Checkout is a complete checkout solution provided by Klarna including address collection. While the same payment methods are available in both solutions, there are differences in ownership of the components of the integration.
Integration Component | Ownership in Klarna Checkout | Ownership in Klarna Payments | Comments |
---|---|---|---|
Address Collection | Klarna | Frontend | |
B2B customer information collection | Klarna | Frontend | |
Customer national identification number collection | Klarna | Klarna | Required for certain payment methods e.g. credit |
Payment Methods | Klarna | Klarna | |
Payment widget handling (display/lock/unlock) | Frontend via CentraCheckoutScript | Frontend | |
Klarna session API Integration | Centra | Centra | |
Klarna order API Integration | Centra | Centra | |
Klarna server side callback handling | Centra | Centra |
Klarna Payments vs Klarna Checkout - supported use cases#
Use Case | Klarna Payments | Klarna Checkout | Comments |
---|---|---|---|
Age verification | No | Yes | |
Subscriptions | No | Yes | |
B2B Checkout | Yes | Yes | |
Paypal in Klarna as external payment method | No | Yes | |
Post-purchase cross-sell | No | Yes | |
Customer gender and birthdate collection | No | Yes | |
Sending product images | Yes | Yes | |
Sending product sizes | Yes | Yes | |
Payment method cost | Yes | Yes | |
US Tax calculation in the checkout | Only in multistep checkout implementation | Multistep checkout implementation or through address update callback | |
Validation callback | No | Yes | Allows for additional validations in late stage of the checkout when payment is submitted by customer e.g. additional stock check |
Store plugin configuration#
Required configuration#
To ensure that Klarna Payments plugin is properly set up for testing fill in following configuration options:
- Status - set status to
Active
- Plugin name - Name of the plugin
- Name in frontend - Name of the plugin returned by the API
- URI - Plugin identifier. Make sure that you're assigning a unique URI to the store plugin, especially if you're using multiple Klarna Payments plugins with plugin restrictions.
- Secret - Set up to your MID configuration
- E-Store ID - Linked to your MID
- Klarna endpoint - Should point towards proper region as per your MID configuration
Testing#
For testing, set Test mode
to Yes
Available configuration options#
- Default locale - Default locale sent to Klarna when payment session is initiated when Centra cannot match any locale on customer/basket level.
- Send product images to Klarna
- Product image size
- Send product URLs to Klarna
- Frontend prefix for product URLs
- Send product sizes to Klarna
APIs used in the integration#
API references:
Authorization flow#
Checkout initialization#
Checkout initialization starts with POST /payment
call which returns all data required to make a payment with Klarna Payments.
POST /payment
Shop API/Checkout API request- Centra creates session with Klarna and responds to Frontend with
client_token
- Frontend calls
SDK.init()
withclient_token
obtained fromPOST /payment
response - Frontend calls
SDK.load()
and Klarna Payments widget is presented to the shopper in the proper container - Klarna Payments widget is displayed on the checkout page
Example POST /payment
response:
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
{
"action": "form",
"formType": "klarna-payments",
"formFields": {
"client_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.ewogICJzZXNzaW9uX2lkIiA6ICIw",
"authorizePayload": {
"purchase_country": "SE",
"purchase_currency": "SEK",
"locale": "sv-SE",
"order_amount": 20000,
"order_tax_amount": 4000,
"order_lines": [
{
"type": "physical",
"reference": "123_1",
"name": "Brand Test Product Red",
"quantity": 2,
"unit_price": 10000,
"tax_rate": 2500,
"total_amount": 20000,
"total_discount_amount": 0,
"total_tax_amount": 4000
}
],
"billing_address": {
"given_name": "Test Billing",
"family_name": "Testson Billing",
"email": "abc123@example.com",
"street_address": "Address One",
"street_address2": "Address Two",
"postal_code": "12345",
"city": "Malmo",
"region": "",
"phone": "123456789",
"country": "SE"
},
"shipping_address": {
"given_name": "Test Billing",
"family_name": "Testson Billing",
"email": "abc123@example.com",
"street_address": "Address One",
"street_address2": "Address Two",
"postal_code": "12345",
"city": "Malmo",
"region": "",
"phone": "123456789",
"country": "SE"
},
"customer": {
"type": "person"
}
}
}
}
Authorization and order placement#
Authorization starts when customer decides to proceed to payment with Klarna Payments as a payment method. At this point frontend calls authorize() function from Klarna Payments SDK with the payload received from Centra.
Payload required for that call is available on POST /payment
response under response.formFields.authorizePayload
.
If any updates happen to selection state after POST /payment
call, authorizePayload
will be updated and available on every selection response while Klarna Payments is set as a paymentMethod
on the selection.
For the payment to succeed it is crucial to ensure that the authorizePayload
used for authorize()
call is up-to-date with the latest selection state.
- Customer proceeds to payment with Klarna Payments.
- Frontend calls
SDK.authorize(authorizePayload)
. SDK.authorize()
callback is fired withauthorization_token
as a parameter.- Klarna Payments pop-up window is opened.
- Shopper signs in to Klarna, provides payment details and confirms the payment in pop-up window..
- Shopper is redirected to
paymentSuccessPage
. - Frontend calls
POST /payment-result
Centra endpoint withauthorization_token
to finalize authorization and place an order in Centra.POST payment-result
1
2
3
4
5
{
"paymentMethodFields": {
"authorization_token": "abcde2d-1234-567d-bfc9-27a3d0dc396c"
}
}
- Centra creates order in Klarna using
authorization_token
received from the Frontend - customer is charged at this moment. - Centra responds to Frontend with order response and parameters from Klarna including
redirect_url
. - Frontend uses
response.order.paymentMethodData.redirect_url
to redirect Shopper to payment success page.
Error handling
To properly handle user interaction with the widget on the Frontend side and error handling, refer to following Klarna guides:
Handling updates in the checkout#
This section refers to any kind of update that happens in the checkout, which means that session has been already initiated with Klarna Payments via POST /payment
endpoint.
This includes:
- Item quantity updates
- Selection line updates
- Address updates
- Applying/removing voucher
- Selection country update
After choosing Klarna Payments as the selection's payment method and initializing the payment, Klarna Payments session will be created. Each selection response will now contain an object at path selection.pluginFields.klarnaPayments
.
This means there is no need for additional API calls to fetch the required payment data when the checkout is updated.
The object will include all the fields that are required to display or reload the payment widget and start the authorization process:
client_token
- Required to callSDK.init(client_token)
that initiates SDK libraryreplaceSnippet
- Indicates whether SDK needs to be reinitialized by callingSDK.init(client_token)
againauthorizePayload
- Payload required for the authorization call SDK.authorize(authorizePayload). Authorization process will be described in detail in the next section.
Here's an example of klarnaPayments
object on the selection response:
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
{
"selection": {
"pluginFields": {
"klarnaPayments": {
"client_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjgyMzA1ZWJjLWI4MTasasEtMzYzNy1..CbYhjSt---1dzmTgvo3vDRA",
"replaceSnippet": false,
"authorizePayload": {
"purchase_country": "se",
"purchase_currency": "sek",
"locale": "sv-SE",
"order_amount": 20000,
"order_tax_amount": 4000,
"order_lines": [
{
"name": "Brand Test Product Red",
"quantity": 2,
"reference": "123_1",
"tax_rate": 2500,
"total_amount": 20000,
"total_discount_amount": 0,
"total_tax_amount": 4000,
"type": "physical",
"unit_price": 10000
}
],
"billing_address": {
"given_name": "Test Billing",
"family_name": "Testson Billing",
"email": "abc123@example.com",
"street_address": "Address One",
"street_address2": "Address Two",
"postal_code": "12345",
"city": "Malmo",
"region": "",
"phone": "123456789",
"country": "SE"
},
"shipping_address": {
"given_name": "Test Billing",
"family_name": "Testson Billing",
"email": "abc123@example.com",
"street_address": "Address One",
"street_address2": "Address Two",
"postal_code": "12345",
"city": "Malmo",
"region": "",
"phone": "123456789",
"country": "SE"
}
}
}
}
}
}
Reinitialization of the payment widget
Once a Klarna Payments widget has been displayed on the checkout page, on every update to selection listen to klarnaReplaceSnippet
field indicating whether the SDK needs to be reinitialized.
Following code snippet is an example of how to properly handle klarnaReplaceSnippet
flag on the selection response.
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
function handleKlarnaReplaceSnippet(response) {
const klarnaReplaceSnippet = response.selection.pluginFields.klarnaPayments.replaceSnippet;
if (klarnaReplaceSnippet === false) {
Klarna.Payments.load(
{
container: '#payment-container',
payment_method_category: 'klarna'
},
function (res) {
console.log('Klarna Payments widget loaded without re-initialization');
}
);
} else {
document.getElementById('payment-container').innerHTML = ''; //clear old one entirely
Klarna.Payments.init(
{
client_token: response.selection.pluginFields.klarnaPayments.client_token
}
);
Klarna.Payments.load(
{
container: '#payment-container',
payment_method_category: 'klarna'
},
function () {
console.log('Klarna Payments widget loaded with re-initialization after client_token update');
}
);
}
}
Best practices#
Locking the payment widget during selection updates in the Checkout#
As shown on the below diagram, once session with Klarna has been initialized, whenever selection is updated in the checkout using Shop API/Checkout API endpoints, Centra sends session updates to Klarna. It's important to prevent customer from finalizing the payment during the time in which the update is being processed by Centra and Klarna. In case of Klarna Payments integration this kind of locking needs to be implemented on the Frontend side by making the widget non-interactive during the processing of the update.
This ensures that there is no inconsistencies between what customer has paid for and the order is placed in Centra.
Collecting customer address data#
Klarna Payments uses customer address data for fraud prevention and to determine available payment options. This data must be included in the SDK.authorize() call. The formatted payload for this call comes from selection.pluginFields.klarnaPayments.authorizePayload in the selection response. It's crucial to ensure that all customer data is correctly filled in and sent to Centra before the customer proceeds to payment. This ensures that the authorizePayload on the selection matches the checkout state.
There are two possible implementation scenarios:
- Multistep checkout: In this case, customers must provide all their address data before they can view available payment methods or proceed to payment.
- Single step checkout: Here, customers are shown available payment methods, including the Klarna Payments widget, as soon as the checkout page loads. However, the widget remains locked until all address data is correctly filled in.
Handling multiple tabs scenario#
After proceeding to checkout page, the customer might open a 2nd browser tab, modify the selection and proceed to the checkout. This would cause a new payment session to be created with a different client_token
and authorizePayload
than the one from the original tab.
Here are potential steps that customer may take:
- Customer opens the checkout page in the first tab and proceeds to payment with Klarna Payments.
- Customer opens the 2nd tab and modifies the selection.
- Customer proceeds to checkout page in the 2nd tab.
- New payment session is created with new
client_token
andauthorizePayload
. - Customer goes back to the first tab and proceeds to payment with Klarna Payments.
To ensure that the customer proceeds to payment with the up-to-date client_token
and authorizePayload
and there's no errors during payment, keep track of the Klarna Payments session state between tabs.
When customer reopens previously initialized checkout with Klarna Payments, you have to make sure state between tabs is synchronized. Fetch selection and up-to-date Klarna Payments pluginFields
and if client_token
has changed, reinitialize SDK and reload the widget using new client_token
as described in: Reinitialization of the payment widget.
Onsite messaging#
Onsite messaging is a way to inform customers about Klarna's payment methods availability before they reach the checkout. Integration of onsite messaging is outside of Centra's integration scope, however it can be integrated from the client side.
This guide provides step-by-step integration instructions.