Klarna Javascript Integration
Overview
To take advantage of Klarna Payments Support, you can use Radial's foundational JavaScript library to quickly integrate with the Radial Payments Framework . Klarna is a global payments provider that works with retailers to give customers the smoothest online shopping experience by providing unique payment options and superior customer experience. This can be done by loading Radial's radial-hostedpayments-js-sdk.js
and invoking the appropriate methods as needed.
With JavaScript integration, Klarna checkout includes two main steps:
-
Klarna initialization.
-
An API call for payment authorization. For details, see Klarna Get Payment Authorization.
Include radial-hostedpayments-js-sdk.js
Begin by including the library radial-hostedpayments-js-sdk.js
. Add the appropriate script tag to your page:
Test Environment
<script src=<https://hps-ui.uat.radial.com/sdk/radial-hostedpayments-js-sdk.js></script>
Production Environment
<script src=<https://hps-ui.radial.com/sdk/radial-hostedpayments-js-sdk.js></script>
Klarna Initialization
Steps for Klarna initialization
Generate the access Token
access Token generation is a server-to-server call. For security purposes, Radial must authenticate the webstore prior to exchanging any data. To facilitate authentication, Radial exposes an HTTPS REST endpoint where a webstore can submit its credentials in the request body.
During Radial Integration, each webstore is provided with authentication credentials. The webstore must submit these credentials in the body of the access Token generation request.
Use these environment-specific URLs to generate an access Token (jwt):
Environment Endpoint:
-
Test/UAT:
https://hps-auth.uat.radial.com/oauth2/token
- Production:
https://hps-auth.radial.com/oauth2/token
The following is a curl example of an access Token (jwt) generation request.
curl --location --request POST '<https://hps-auth.uat.radial.com/oauth2/token?grant_type=client_credentials&client_id=490491rtpq5&scope=hostedpayments-uat/web-ui-js>' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Authorization: Basic {Base64String}'
The access Token (jwt) generation call provides a response similar to the following.
{
"access_token": "eyJraWQiOiJCdE1nOWg...oXHgw37FYwDnl6BQK4Wrw",
"expires_in": 3600,
"token_type": "Bearer"
}
Note: The access Token (jwt) obtained has an expiration period associated with it. Currently, the expiration duration is set as 300 seconds. But this expiration period can vary from time to time based on security requirements. If the access Token (jwt) times out, you will receive an InvalidAuthenticationError(40001) as a response for subsequent calls. If that occurs, the webstore can make a new server to server authentication call to get a new access Token (jwt).
The webstore must capture the access Token (jwt) generated during the /oauth2/token API response and send that in the subsequent calls to the Radial JavaScript as this required for the JavaScript library. The webstore must ensure this access Token (jwt) value is available in the access Token (jwt) response.
{
"errorCode": "40001",
"errorMessage": "Invalid Authentication Error",
"errorDescription": "Provided JWT is either invalid or expired"
}
Method
radial.initKlarnaPayment(orderData, containerId, jwt)
Parameters
Parameter | Description | Required? |
---|---|---|
orderData | Customer order data | Yes |
containerId | Div container id to load Klarna Window. Pass id with # | Yes |
accessToken | Jwt/accessToken | Optional |
Klarna Processing Steps (redirect)
- The webstore server sends a request to Radial with the client_id and scope provided during Radial Integration.
- The webstore server receives access Token (jwt) and expires_in_seconds in Radial's response.
- The webstore server provides the payment page with access Token (jwt), which is used to initialize the Radial JavaScript (with the Radial() method). Webstore server should invoke the new Radial() JavaScript method during the checkout page onload().
- The user submits the payment on choosing the Klarna payment method and the browser calls radial.initKlarnaPayment() with the order data.
- Radial makes a call to the Gateway Provider.
- Radial receives a response with the url from Gateway Processing provider where authentication of the payment needs to be done.
- Customer will be redirected to the issuer page, where authentication is done. The webstore needs to provide return url in request object, see the section below on the Klarna Json Object Format for further details. Webstore needs to be able to handle the redirect on the server side. Webstore can append query parameters it needs to be in the returnUrl (shopper ids, order ids, etc. Payments will support the query parameters, so the webstore can append what it needs in that url without worry.)
- After customer is redirected to Klarna authentication page, they need to authenticate the payment by choosing the payment option provided by Klarna.
- After authenticating the Klarna payment, customer will be redirected back to redirectUrl which is provided in the order data JSON in step 5 and authenticate data is appended to the redirectUrl after authorizing the payment from Klarna authentication page
- Receive authentication result and paymentId that will be appended in the returnUrl.
- Submit the GetPaymentAuthorizationRequest to Radial using the paymentId and AuthenticationResult.
- Radial sends the authorization request to the Gateway provider.
- Radial receives the authorization response from the Gateway provider.
- The response from the Gateway provider will be sent to the webstore as GetPaymentAuthorizationReply.
- Based on the responseCode from the GetPaymentAuthorizationReply, the webstore shows the result of the transaction in the browser to the shopper.
Klarna JSON Object Format
The table below describes the fields in the json object to be passed in to the radial.initKlarnaPayment() js method. It is recommended that all of the listed fields are passed in, when possible.
Note regarding shipping address: In certain orders for electronic delivery items, shipping address may not be available. In such cases, it is recommended to send the billing address as the shipping address. In scenarios where the order is being shipped to multiple destinations, send the shipping address of the destination that receives the maximum order value.
Field Name | Sub Element | Required | Complex Object | Datatype | Restrictions/ Min | Max | ||
---|---|---|---|---|---|---|---|---|
orderId |
Y |
String |
1 |
40 |
||||
locale |
Y |
BCP 47 language tag |
||||||
ipAddress |
Y |
String |
Not blank check |
Unlimited |
||||
amount |
Y |
Y |
Object |
|||||
value |
Y |
BigDecimal |
0 |
50000 |
||||
currencyCode |
Y |
ISO 4217 currency code |
||||||
redirectUrl |
N |
String |
should start with https:// |
Unlimited |
||||
taxAmount |
N |
Y |
Object |
|||||
value |
Y |
BigDecimal |
0 |
50000 |
||||
currencyCode |
Y |
ISO 4217 currency code |
Currency Enum |
|||||
billingInformation |
N |
Y |
Object |
|||||
name |
Y |
Y |
Object |
|||||
first |
Y |
String |
Not blank check |
Unlimited |
||||
last |
Y |
String |
Not blank check |
Unlimited |
||||
middle |
N |
String |
||||||
honorific |
N |
String |
||||||
address |
Y |
Y |
Object |
|||||
line 1 |
Y |
String |
Not blank check |
Unlimited |
||||
line2 |
N |
String |
||||||
city |
Y |
String |
Not blank check |
Unlimited |
||||
mainDivisionCode |
N |
String |
||||||
postalCode |
N |
String |
||||||
countryCode |
Y |
String |
a-zA-Z, 2 |
3 |
||||
phoneNumber |
N |
String |
0-9, min 1 |
Unlimited |
||||
emailAddress |
N |
String |
||||||
shippingInformation |
N |
Y |
Object |
|||||
name |
Y |
Y |
Object |
|||||
first |
Y |
String |
Not blank check |
Unlimited |
||||
last |
Y |
String |
Not blank check |
Unlimited |
||||
middle |
N |
String |
||||||
honorific |
N |
String |
||||||
address |
Y |
Y |
Object |
|||||
line 1 |
Y |
String |
Not blank check |
Unlimited |
||||
line2 |
N |
String |
||||||
city |
Y |
String |
Not blank check |
Unlimited |
||||
mainDivisionCode |
N |
String |
||||||
postalCode |
N |
String |
||||||
countryCode |
Y |
String |
a-zA-Z, 2 |
3 |
||||
phoneNumber |
N |
String |
0-9, min 1 |
Unlimited |
||||
emailAddress |
N |
String |
||||||
deliveryInformation |
N |
Y |
Object |
|||||
deliveryType |
N |
Enum |
STANDARDEXPRESSSAME_DAYOVERNIGHTELECTRONIC_DELIVERSHIP_TO_STORESHIPPINGPICKUP | |||||
contact |
N |
Y |
Object |
|||||
name |
Y |
Y |
Object |
|||||
first |
Y |
String |
Not blank check |
Unlimited |
||||
last |
Y |
String |
Not blank check |
Unlimited |
||||
middle |
N |
String |
||||||
honorific |
N |
String |
||||||
address |
Y |
Y |
Object |
|||||
line1 |
Y |
String |
Not blank check |
Unlimited |
||||
line2 |
N |
String |
||||||
city |
Y |
String |
Not blank check |
Unlimited |
||||
mainDivisionCode |
N |
String |
||||||
postalCode |
N |
String |
||||||
countryCode |
Y |
String |
a-zA-Z, 2 |
3 |
||||
phoneNumber |
N |
String |
0-9, min 1 |
Unlimited |
||||
emailAddress |
N |
String |
||||||
lineItems |
N |
Y |
List of Objects |
|||||
productDetails |
Y |
Y |
Object |
|||||
name |
Y |
String |
Not blank check |
Unlimited |
||||
sku |
N |
String |
||||||
unitPrice |
Y |
Y |
Object |
|||||
value |
Y |
BigDecimal |
-50000 |
50000 |
||||
currencyCode |
Y |
ISO 4217 currency code |
ISO 4217 currency code |
|||||
url |
N |
String |
||||||
imageUrl |
N |
String |
||||||
quantity |
Y |
Y |
Object |
|||||
unit |
N |
String |
||||||
amount |
Y |
int |
0 |
Integer max value |
||||
total |
N |
Y |
Object |
|||||
value |
Y |
BigDecimal |
0 |
50000 |
||||
currencyCode |
Y |
ISO 4217 currency code |
ISO 4217 currency code |
|||||
discount |
N |
Y |
Object |
|||||
value |
Y |
BigDecimal |
0 |
50000 |
||||
currencyCode |
Y |
ISO 4217 currency code |
ISO 4217 currency code |
|||||
tax |
N |
Y |
Object |
|||||
rate |
N |
BigDecimal |
||||||
amount |
N |
Y |
Object |
|||||
value |
Y |
BigDecimal |
0 |
50000 |
||||
currencyCode |
Y |
ISO 4217 currency code |
ISO 4217 currency code |
|||||
paymentId |
N |
String |
Sample jsonObject Request with All Elements
{
"orderId": "20250211214516_KL",
"amount": {
"value": 10.4,
"currencyCode": "USD"
},
"taxAmount": {
"value": 0.01,
"currencyCode": "USD"
},
"locale": "en-US",
"ipAddress": "127.0.0.1",
"redirectUrl": "https://blue-shirt.com/checkout",
"billingInformation": {
"name": {
"first": "Test",
"last": "Person-us",
"honorific": "Mr.",
"middle": "middle"
},
"phoneNumber": "3106683312",
"emailAddress": "customer@email.us",
"address": {
"line1": "509 Amsterdam Ave",
"line2": "Some street",
"city": "New York",
"mainDivisionCode": "NY",
"postalCode": "10024-3941",
"countryCode": "US"
}
},
"shippingInformation": {
"name": {
"first": "Test",
"last": "Person-us",
"honorific": "Mr.",
"middle": "middle"
},
"phoneNumber": "3106683312",
"emailAddress": "customer@email.us",
"address": {
"line1": "509 Amsterdam Ave",
"line2": "Some street",
"city": "New York",
"mainDivisionCode": "NY",
"postalCode": "10024-3941",
"countryCode": "US"
}
},
"deliveryInformation": {
"deliveryType": "OVERNIGHT",
"contact": {
"phoneNumber": "18778368414",
"emailAddress": "customer@email.us",
"name": {
"first": "Gerald",
"middle": "Norman",
"last": "Springer"
},
"address": {
"line1": "801 Plum St",
"line2": "c/o Jerry",
"city": "Cincinnati",
"mainDivisionCode": "OH",
"postalCode": "45202",
"countryCode": "US"
}
}
},
"lineItems": [
{
"productDetails": {
"name": "green sock",
"sku": "BS-101",
"unitPrice": {
"value": 5.2,
"currencyCode": "USD"
},
"url": "http://buy-bs.com/bs-101",
"imageUrl": "http://look-at-bs.com/images/bs-101.png"
},
"quantity": {
"unit": "sleeves",
"amount": 2
},
"total": {
"value": 10.4,
"currencyCode": "USD"
},
"discount": {
"value": 0,
"currencyCode": "USD"
},
"tax": {
"value": 0.1,
"currencyCode": "USD"
}
}
]
}
Success Response
{
"show_form": true,
"client_token": "eyJhbGciOiJSUzI1Nig79HD-g",
"paymentId": "93b24ac9-769e-67a2-b5fd-3bf3e90456e4",
"payment_method_categories": ["pay_over_time"],
"success": true
}
When the show_form is true, the Klarna widget is loaded onto the given container ID only on which you should provide options for the customer to pay with Klarna and continue with the payment flow. If the show_form is false, Klarna had an error and cannot continue. Klarna also passes back a client token and supported payment method categories.
Error Responses
|
There are two use cases where the response needs to be stored:
-
If the webstore is using a multi-page checkout, make sure to capture the values for later use.
-
If the order data is changed in any way: total value of the order or quantity of the items, address changes or corrections, and so on, be sure to store the response..
When the function is called with a success object, the Klarna widget is populated with the available Klarna payment options and can be displayed on your site.
Sample Klarna Widget
Call ProcessKlarnaPayment
When the customer clicks the Submit button, the webstore must call processKlarnaPayment method. This method takes 2 parameters.
-
An autoFinalize boolean flag:
-
For a single page checkout, send this value as true.
-
For a multi-page checkout, send this value as false.
-
-
A PaymentMethodCategories: You get this value from the response object in the previous step.
When the radial.processKlarnaPayment function is called, Klarna starts a session with the customer in the widget.
Klarna might display a form to collect further information from the customer in the widget. Typically, this form collects information such as the last four digits of their Social Security Number, date of birth, and so on, and provides approval for the payment.
When the customer interaction with the Klarna widget ends, the klarna is invoked with a response object that contains the result of the Klarna loan approval.
In a single page checkout, the order object typically does not change after the authorization is completed.
A multi-page checkout refers to a checkout implementation in which the customer's browser travels to different webpages for the various steps throughout the checkout process; for example, specifying addresses, selecting payment methods, reviewing the order before submission, and so on.
Method
radial.processKlarnaPayment(klarnaPaymentMethodCategories, autoFinalize)
Parameters
Parameter | Description | Required? |
---|---|---|
klarnaPaymentMethodCategories | Pass it from the response radial.initKlarnaPayment | Yes |
autoFinalize | Boolean, in this case it will always be false | No |
Success Response
{
"show_form": true,
"approved": true,
"finalize_required": false,
"merchant_reference1": "TMSUS",
"merchant_reference2": "20250227221316_KL",
"success": true,
"authorizationToken": "e2b25385-8192-652e-9294-cf5a816dbaca"
}
Error Response
Error | Response |
---|---|
Copy
|
Not Authorize for Klarna |
Copy
|
JWT expired or invalid while performing this action |
Copy
|
HPS is down for some responses |
Copy
|
Time out |
Copy
|
An error from Klarna |
Important Note:
If for any reason an order is changed after the Klarna widget authorization is performed, that authorization must be cancelled, and the session must be updated and reauthorized.
It is strongly recommended that Klarna widget authorization is not performed until after the customer has performed all review and accepted the order so that canceling an authorization is not required.