Integrate Sign in with Klarna to enable secure authentication on your website.
Offer Sign in with Klarna by displaying the Klarna “Sign in with Klarna” button wherever you want users to log in or register. Consumers simply click the button to authenticate via Klarna, granting permission to share selected profile data (e.g. name, email, billing address, shipping address) so they can create or sign in to your site in a single step.
![]() | ![]() | ![]() |
Registration banners and modals | Sign-in process | Registration at Checkout |
Before you integrate Sign in with Klarna, check that you meet the following prerequisites:
If you’ve previously generated a client identifier for your store, you can use it to build your Sign in with Klarna integration.
For a comprehensive, step-by-step walkthrough of these prerequisites, refer to the detailed integration guide.
The simplest and fastest way to start using Sign in with Klarna is to use the minimal template below.
This guide applies to the PUBLIC client type. If your client is set to CONFIDENTIAL, please refer to the next section.
Basic example: Assume that you are serving these 2 files from your web server.
You would need to also obtain the `CLIENT_SECRET`.
After obtaining the code response, pass it to your server to perform the token exchange. Here’s a JavaScript snippet demonstrating how to send a request to the token endpoint for the exchange:
// An example of the request to exchange for the token.
const { URLSearchParams } = require('url');
const fetch = require('node-fetch');
const encodedParams = new URLSearchParams();
encodedParams.set('grant_type', 'authorization_code');
encodedParams.set('client_id', '[YOUR CLIENT ID]');
encodedParams.set('client_secret', '[YOUR API KEY]');
encodedParams.set('code', 'krn:login:eu1:code:eed137f6-8f06-4791-8180-576a89e....');
Sign in with Klarna ideally will start in a Popup window to avoid users leaving the merchant's website. However, due to various reasons popup window can be blocked. Thus, having a redirect callback page
is REQUIRED to allow users to continue their sign in flow in case their popup is blocked. You can use the callback.html template provided in the example above.
To successfully implement the REDIRECT mode, below prerequisites must be met:
button
method with the redirectUri property or klarna-identity-button
element with data-redirect-uri
attribute.signin
must be registered.The Sign in with Klarna flow can be initiated in two main modes: DEVICE_BEST or REDIRECT.
DEVICE_BEST allows Web SDK to automatically decide the most suitable mode, based on user's device configurations. For instance, Web SDK may opt for a REDIRECT if popup blockers are enabled or the page is loaded in an web frame.
By default, DEVICE_BEST mode starts the flow in a popup window for web browsers. This is ideal for merchants who don't want their customers to leave their website. However, if the popup is blocked, Web SDK will switch to REDIRECT mode and the user will be redirected to the login page on the current tab.
REDIRECT
mode redirects the user to the login page on the current tab. However, user will be redirected back to the merchant's redirect callback page at the end of the sign in flow with Authorization tokens or OAuth2Error parameters.
Please note that you can also just load the Web SDK script without the dataset attributes and use the init
method to initialise the Web SDK.
<script type="module">
const { KlarnaSDK } = await import("https://js.klarna.com/web-sdk/v2/klarna.mjs");
const klarna = await KlarnaSDK({
clientId: "[YOUR CLIENT ID]",
});
</script>
After initialising the Web SDK, all Sign in with Klarna related API can be found under the Identity
namespace.
See all details on WebSDK specifications
Web SDK provides a flexible API that allows merchants to integrate Sign in with Klarna based on their preference.
Web SDK provides a default button that has all functionalities built-in and styled based on official Klarna design guidelines.
Web SDK registers a custom web component klarna-identity-button, that renders the Sign in with Klarna button where it is mounted.
<klarna-identity-button
id="klarna-identity-button"
data-scope="openid offline_access payment:request:create profile:name"
data-redirect-uri="http://localhost:3000/callback.html"
data-locale="en-GB"
></klarna-identity-button>
Web SDK provides the button
method that allows to create and mount the Sign in with Klarna button programmatically.
const siwkButton = klarna.Identity.button({
id: "klarna-identity-button",
scope: "openid offline_access payment:request:create profile:name",
redirectUri: "http://localhost:3000/callback.html",
locale: "en-GB"
});
siwkButton.mount("#button-container");
If the button
method is called more than once with the configuration object, it will create multiple button instances. If you do not need more than one button, please make sure the button method is only called once.
If you do need multiple buttons make sure you provide an id
attribute to each button instance.
You can provide a string button id to the button method, to retrieve an existing button instance. For more information, see the Identity API Overview > Type Definitions.
If a merchant wants to use a custom button matching with Klarna's but also with their own design guidelines, they can use the attach method that is provided by Web SDK. The attach method will register the necessary event handlers to start the sign in flow.
Please refer to our Custom button article for essential design considerations.
const siwkButton = klarna.Identity.button({
id: "klarna-identity-button",
scope: "openid offline_access payment:request:create profile:name",
redirectUri: "http://localhost:3000/callback.html",
locale: "en-GB"
});
// notice, we are using the `attach` method
// and providing a button id instead of a container id
siwkButton.attach("#merchants-custom-button-id");
Web SDK Identity API can emit two events: signin
and error
which can be handled as below:
// 1. Listen for `signin` event to receive signin response object
klarna.Identity.on("signin", async (signinResponse) => {
console.log(signinResponse);
});
// 2. Listen for `error` event to handle error object
klarna.Identity.on("error", async (error) => {
console.log(error);
});
Sign in with Klarna buttons can emit two events: ready
and click
.
// Please notice that we can retrieve the button instance,
// by providing the button instance id to the button method
const siwkButton = klarna.Identity.button("klarna-identity-button");
siwkButton.on('ready', async () => {
// handle ready event
})
siwkButton.on('click', async () => {
// handle click event
The table below lists the available scopes and how they correspond to claims and permissions.
Scope | Claims | Type | Can be toggled off |
---|---|---|---|
profile:name | given_name | string | No |
profile:name | family_name | string | No |
profile:email | string (Email) | No | |
profile:email | email_verified | boolean No | |
profile:phone | phone | string (E. 164) | No |
profile:phone | phone_verified | boolean No | |
profile:date_of_birth | date_of_birth | string (ISO 8601) | Yes |
profile:billing_address | street_address | string | Yes |
profile:billing_address | street_address2 | string Yes | |
profile:billing_address | postal_code | string Yes | |
profile:billing_address | city | string Yes | |
profile:billing_address | region | string Yes | |
profile:billing_address | country | string (ISO 3166-1 alpha-2) Yes | |
profile:shipping_address | street_address | string | Yes |
profile:shipping_address | street_address2 | string | Yes |
profile:shipping_address | postal_code | string | Yes |
profile:shipping_address | city | string | Yes |
profile:shipping_address | region | string | Yes |
profile:shipping_address | country | string (ISO 3166-1 alpha-2) | Yes |
profile:national_id | national_id | string | Yes |
profile:country | country | string (ISO 3166-1 alpha-2) | Yes |
profile:locale | locale | string (ISO 3166) | Yes |
Remember to always add 'openid', 'offline_access' and 'customer:login' scopes to receive full functionality of Sign in with Klarna.
The mock-ups below show how users will see required versus optional scopes when entering the Sign in with Klarna flow.
Required scopes in Sign in with Klarna | Optional scopes in Sign in with Klarna |
Before using data from the id_token
, it needs to be validated. More about it under Token Validation.
Upon completing the sign-in process, utilise a specific claim
(such as phone, email, or national identification number for Sweden) as a unique customer identifier.
Make sure you are handling the following scenarios to ensure seamless integration:
user_account_linking_refresh_token
within that record.Account Merging | User Confirmation for Merging |
---|---|
Merge the account automatically, add customer data from Klarna that was missing in the existing record and save the user_account_linking_refresh_token in it | Prompt the user to confirm if they wish to merge their existing account. If yes, follow Account Merging above. If not, ask them to login with a different Klarna account |
By carefully managing these scenarios, you can provide a fluid and integrated user experience, leveraging the comprehensive data and functionality offered through the Sign in with Klarna.
To receive a new set of tokens, perform a token exchange through a POST
request to the token endpoint. Remember to always save the new refresh_token
in the database, since the old one will be invalid.
Access tokens are opaque - they are random strings that you cannot decode. Validation should only be performed on the id_token
. You do not have to validate the access token before using it.
const data = new URLSearchParams();
data.append("refresh_token", "<your refresh token>");
data.append("client_id", "<your client id>");
data.append("grant_type", "refresh_token");
fetch("https://login.klarna.com/eu/lp/idp/oauth2/token", {
method: "POST",
headers: {
At any point of time you can request the latest user data using the /userinfo endpoint. It requires a valid access_token as authorization and returns the same data structure as you can find in the id_token. Remember to get the fresh access_token, described in step 5. Integrate in purchase flow, using /userinfo. Using a new access_token
in the /userinfo
ensures you get the most up to date information we have for the customer without requiring them to re-login.
fetch("https://login.klarna.com/eu/lp/idp/userinfo", {
headers: {
Authorization: "Bearer <access token>",
}
})
Validate id_token
: validating an OAuth 2.0 token using a JWKS (JSON Web Key Set) endpoint, such as the one provided by Klarna, involves several steps. Here's an outline of how you might proceed:
Node sample implementation
const jwt = require('jsonwebtoken');
const jwkToPem = require('jwk-to-pem');
async function verifyTokenWithJWKS(token, jwksUri) {
try {
// Decode the token header without verification
const { header } = jwt.decode(token, { complete: true });
if (!header || !header.kid) {
throw new Error('Invalid token header');
}
In case the customer already has an account with you, based on a an identifier match, such as email or mobile number, and now want to sign in with Klarna, you should allow the connection of the accounts by merging the accounts in the back-end, rather than reject the sign in.
This should allow the customer to be able to sign in to the connected account using both sign in methods.
Once a customer has logged in with Klarna, always utilize the data you collect to improve the customer’s experience. Use the information available to pre-fill the customer’s profile and checkout form fields is a basic use case to leverage the data available:
Data collection | Pre-filled profile | Pre-filled checkout |
Once the customer creates their account and is redirected back to the Partner’s platform, they should be taken directly to a personalized shopping experience, in a logged-in state.
Customer signs in with Klarna account | Personalized shopping experience |
There shouldn’t be any additional steps after the customer creates their account. Especially not asking for the same information that was provided during account creation, or asking to verify already verified details.
After a purchase is complete, many customers find it valuable to have a way to track their order and access their purchase history. For those who have checked out as guests, the order confirmation page provides a seamless opportunity to invite them to create an account using Sign in with Klarna.
By implementing the Sign in with Klarna button on the success page, you can offer customers a quick and secure way to set up an account after their purchase, enhancing their post-purchase experience and opening up new engagement opportunities.
Creating an account provides customers with access to past and future purchases, personalized order updates, and exclusive promotions. For your business, it enables deeper customer relationships, higher retention rates, and more effective communication. Adding SIWK at this critical touchpoint can make a significant impact on customer loyalty and engagement.
Invite customers to create an account using Sign in with Klarna | Customer sets up an account | Personalized experience with access to more data |
Enabling account creation on the order confirmation screen allows customers to:
For your business, this is a unique opportunity to convert guest customers into account holders, increasing the chance of future interactions and building a stronger, loyal customer base.
To integrate the Sign in with Klarna button on the order confirmation screen, you should embed the SIWK button in a visible, user-friendly location on the order confirmation (or “thank you”) page on your website where customers land after completing a purchase. A sample prompt could be, "Create an account to view your order history and enjoy a more personalized experience.".
Use Klarna’s SDK to authenticate users via the SIWK button. Once authenticated, check for an existing user account. If none exists, prompt them to complete the quick setup to create a new account tied to their recent purchase.
Finally, provide a confirmation message once the account is created, such as "Your account has been set up! You can now track this and future orders in your account.". Consider redirecting users to their new account profile or order history page to immediately reinforce the benefits of having an account.