Klarna Integration
For additional information, see the following pages:
Klarna Webstore Integration
The webstore integration and Klarna payment process includes five major steps:
Authenticate as a webstore with Radial and get a access token.
Include radial-hostedpayments-js-sdk.js and initialize the Klarna JavaScript with order data.
The customer accepts the order and the radial.processKlarnaPayment() JavaScript method is called. The webstore records the returned Klarna authorization_token.
Radial's InstantFinanceAuthRequest payment API is called to finalize authorization for the purchase.
After a successful authorization response, the order is accepted and sent to the order management system, from where the capture or refund flows happen.
Detailed information about the above steps appears in the following sections.
Prerequisite: Server Whitelisting
The JavaScript integration makes a cross-site call from the browser to Radial's server instead of to the originating webstore server. This is a CORS request. For the request to be successful, Radial must first whitelist the IP or domain names of the servers from which the request originates. If you plan on using this integration, send your domain name/IP list to Radial so that your server can be whitelisted.
Authentication & JWT accessToken
For security purposes, Radial must authenticate the webstore prior to transmitting any data. To facilitate that, Radial exposes a REST https endpoint. If you have previously integrated with Radial's Tokenization or 3D Secure capability, this process is similar.
Environment | Endpoint |
---|---|
Test | <https://hps-auth.uat.radial.com/oauth2/token> |
Production | <https://hps-auth.radial.com/oauth2/token> |
This is a server-to-server call. The webstore is provided with authentication credentials that they are expected to supply in this request. The following example is a sample authentication request via curl:
curl --location --request POST 'https://hps-auth.uat.radial.com/oauth2/token?grant_type=client_credentials&client_id=xyz&scope=hostedpayments-dev/web-ui-js' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Authorization: Basic {Base64String}' \
--data ''
The above request will provide a response similar to the following example:
{
"access_token": "eyJraWQiOiJCdE1nOWg...oXHgw37FYwDnl6BQK4Wrw",
"expires_in": 3600,
"token_type": "Bearer"
}
The webstore must capture the response and send the information to the browser. The access_token returned in the response is required for authentication in the JavaScript library calls.
In case of an error, a payload similar to the below example will be returned:
{
"errorCode": "40001",
"errorMessage": "Invalid Authentication Error",
"errorDescription": "provided ACCESS TOKEN (JWT) is either invalid or expired"
}
The following table lists the possible errors that can be returned.
Error Code | Error Message | Description |
---|---|---|
40001 | Invalid Authentication Error | The credentials used to connect to Radial are invalid. |
50003 | RadialInternalError | There was an internal error in Radial's system. You can retry the request again in this case. |
Step 2: Include and Initialize JavaScript
Include radial-hostedpayments-js-sdk.js
Radial provides a hosted JavaScript library, radial-hostedpayments-js-sdk.js, that supports functionality related to Klarna payment processing. You must include this .js file in the payment page where you plan on having Klarna integration. Add this script tag to your page to get started with radial-hostedpayments-js-sdk.js:
Environment | Tag |
---|---|
Test | <script src=<https://hps-ui.uat.radial.com/sdk/radial-hostedpayments-js-sdk.js></script> |
Production | <script src=<https://hps-ui.radial.com/sdk/radial-hostedpayments-js-sdk.js></script> |
Initialize Radial function
After including the radial-hostedpayments-js-sdk.js file, the webstore should invoke the `Radial()` method by passing the access token (JWT), In other words, `Radial()` should be invoked in the checkout page onload event to initialize the Radial Payment JavaScript file.
Once the Radial JS is executed successfully, the Radial Object (typically define a const ex: `radial` when calling Radial() and use that const name to represent Radial Object, from now on we refer Radial payment JS as radial object) is available to window global scope to continue use with Radial JS functionalities. (At any point in time, if control is switched to new page Radial JS should be re-initiate).
Note: Not all features are available for all clients. Reach out to the PTF Support to team to enable additional features mentioned in this documentation.
Klarna Content Placeholder
On the payment page, you must insert a div tag that is a placeholder. This placeholder is dynamically populated by Klarna content. Use the following snippet to create this placeholder in the page.
<div id="klarna-payments-container" />
The webstore should have code to display the Klarna widget (change div state from hidden to block) after the initialization process has been completed.
Create Order Data
The order data object contains information about the order. This data is required in various steps throughout the Klarna integration process. The following properties are required when the initial setup call is made:
purchase_currency - Country code for the purchase. This must be one of the countries listed as supported in the hosted payment configuration
locale - Locale of the purchase. This must be one of the locales listed as supported in the hosted payment configuration
billing_address.given_name
billing_address.family_name
billing_address.street_address
billing_address.city
billing_address.postal_code
billing_address.country
billing_address.email
Note regarding shipping address:
In certain orders for electronic delivery items, a shipping address may not be available. In these cases, Radial recommends that you 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.
Klarna Order Object Format
The following is the full structure of the Klarna Order object.
Field Name | Description | Required? | Field Type |
---|---|---|---|
order_data | Root JSON Object that holds the order information | Yes | object |
purchase-country | ISO 3166 alpha-2 purchase country. Example: US for United States | Yes | string |
purchase-currency | ISO 4217 purchase currency. Example "USD" | Yes | string |
locale | RFC 1766 customer's locale. Example: "en-US" | Yes | string |
billing-address | Parent object tag for the Billing Address information of the Customer. This information is required for Klarna Checkout and needs to be collected. | Yes | Object parent |
billing_address/title | Title - eg: Mr/Mrs/Ms etc | No | string |
billing_address/given_name | Given name or First Name of the customer | Yes | string |
billing_address/family_name | Family name or last name of the customer | Yes | string |
billing_address/email | E-mail address of the customer. | Yes | string |
billing_address/street_address | Street address. first line | Yes | string |
billing_address/street_address2 | Street address. second line | No | string |
billing_address/postal_code | Postal/post code or ZIP code | Yes | string |
billing_address/city | City | Yes | string |
billing_address/region | State or region | Yes | string |
billing_address/phone | Phone number | Yes | string |
billing_address/country | ISO 3166 alpha-2. Country. | Yes | string |
shipping_address | Shipping Address of the customer. In case of digital goods or when a shipping address is not available, these fields need to be filled in with a copy of the billing address. | Yes | object |
shipping_address/title | Title - eg: Mr/Mrs/Ms etc | No | string |
shipping_address/given_name | Given name or First Name of the customer | Yes | string |
shipping_address/family_name | Family name or last name of the customer | Yes | string |
shipping_address/email | E-mail address of the customer. | Yes | string |
shipping_address/street_address | Street address. first line | Yes | string |
shipping_address/street_address2 | Street address. second line | No | string |
billing_address/postal_code | Postal/post code or ZIP code | Yes | string |
shipping_address/city | City | Yes | string |
shipping_address/region | State or region | Yes | string |
shipping_address/phone | Phone number | Yes | string |
shipping_address/country | ISO 3166 alpha-2. Country. | Yes | string |
order_amount | Total amount of the order, including tax and any discounts. All amounts must be passed in minor units with 2 implied decimals (example: $10.00 = 1000). Note that an implicit decimal point is used for currency amounts in this JSON object, while the XML request message for the Instant Finance Authorization API uses an explicit decimal point for currency amounts. | Yes | integer |
order_tax_amount | The total tax amount of the order. All amounts must be passed in minor units with 2 implied decimals (example: $10.00 = 1000) | Yes | integer |
order_lines | The applicable order lines (max 1000) | Yes | array of order lines |
order_lines/types | Order line type. Possible values:physical, discount, shipping_fee, sales_tax, digital, gift_card, store_credit, surcharge | Yes | string |
order_lines/reference | Article number, SKU or similar. | No | string |
order_lines/name | Descriptive item name | Yes | string |
order_lines/quantity | Non-negative. The item quantity. | Yes | integer |
order_lines/quantity_unit | Unit used to describe the quantity, such as kg, pcs, etc. If defined must be 1-8 characters | No | string |
order_lines/unit_price | Minor units. Excludes discount. (max value: 100000000). All amounts must be passed in minor units with two implied decimals (example: $10.00 = 1000) | Yes | integer |
order_lines/tax_rate | Non-negative. In percent, two implicit decimals. For example, 2500 = 25%. Optional for US stores. | No for US stores | integer |
order_lines/total_amount | Includes tax and discount. Must match (quantity \* unit_price) - total_discount_amount within ±quantity. (max value: 100000000). All amounts must be passed in minor units with 2 implied decimals (example: $10.00 = 1000) | Yes | integer |
order_lines/total_discount_amount | Non-negative minor units. Optional for US stores. All amounts must be passed in minor units with two implied decimals (example: $10.00 = 1000) | No for US stores | integer |
order_lines/total_tax_amount | Should always be sent as 0 for all order lines except when the type of the order line is "sales_tax" | No for US stores | integer |
order_lines/merchant_data | Any merchant/webstore specific data can be provided here. (max 255 characters) | No | string |
order_lines/product_url | URL to an image that can be later embedded in communications between Klarna and the customer. (max 1024 characters) If not present, do not send this field. Sending empty "{}" value for this field will generate an error. | No | string |
order_lines/image_url | URL to an image that can be later embedded in communications between Klarna and the customer. (max 1024 characters). If not present, do not send this field. Sending empty "{}" value for this field will generate an error. | No | string |
merchant_reference1 | Can be used to pass the webstore order id and such information that can be used to correlate the order in communication with Klarna | No | string |
merchant_urls | Can be used to pass confirmation URL and such information that Klarna can use in its communication with various parties | No | string |
Klarna Order Object Example for North America Merchant: With Tax
{
"purchase_country": "US",
"purchase_currency": "USD",
"locale": "en-US",
"billing_address": {
"given_name": "John",
"family_name": "Doe",
"email": "johndoe+require_signup@example.com",
"street_address": "935 First Ave",
"postal_code": "19406",
"city": "King of Prussia",
"region": "PA",
"phone": "+16145551234",
"country": "US"
},
"shipping_address": {
"given_name": "John",
"family_name": "Doe",
"email": "johndoe+require_signup@example.com",
"street_address": "935 First Ave",
"postal_code": "19406",
"city": "King of Prussia",
"region": "PA",
"phone": "+16145551234",
"country": "US"
},
"order_amount": 63500,
"order_tax_amount": 3000,
"order_lines": [
{
"type": "physical",
"reference": "coolthing1",
"name": "cool thing 1",
"image_url": "https://www.estore.com/image1.png",
"product_url": "https://lwww.estore.com/product1/",
"quantity": 1,
"unit_price": 50000,
"total_amount": 50000,
"tax_rate": 0,
"total_tax_amount": 0
},
{
"type": "physical",
"reference": "coolthing2",
"name": "cool thing 2",
"image_url": "https://www.estore.com/image2.png",
"product_url": "https://www.estore.com/product2/",
"quantity": 1,
"unit_price": 10000,
"total_amount": 10000,
"tax_rate": 0,
"total_tax_amount": 0
},
{
"type": "sales_tax",
"reference": "Tax",
"name": "Tax",
"quantity": 1,
"unit_price": 3000,
"tax_rate": 0,
"total_tax_amount": 0,
"total_amount": 3000
},
{
"type": "shipping_fee",
"reference": "Shipping",
"name": "Shipping",
"quantity": 1,
"unit_price": 500,
"tax_rate": 0,
"total_amount": 500,
"total_tax_amount": 0
}
],
"merchant_reference1": "Merchant OrderID",
"merchant_urls": {
"confirmation": "https://www.estore.com/confirmation"
}
}
Klarna Order Object Example for North America Merchant: Without Tax
{
"purchase_country": "US",
"purchase_currency": "USD",
"locale": "en-US",
"billing_address": {
"given_name": "John",
"family_name": "Doe",
"email": "johndoe+require_signup@example.com",
"street_address": "935 First Ave",
"postal_code": "19406",
"city": "King of Prussia",
"region": "PA",
"phone": "+16145551234",
"country": "US"
},
"shipping_address": {
"given_name": "John",
"family_name": "Doe",
"email": "johndoe+require_signup@example.com",
"street_address": "935 First Ave",
"postal_code": "19406",
"city": "King of Prussia",
"region": "PA",
"phone": "+16145551234",
"country": "US"
},
"order_amount": 60500,
"order_tax_amount": 0,
"order_lines": [
{
"type": "physical",
"reference": "coolthing1",
"name": "cool thing 1",
"image_url": "https://www.estore.com/image1.png",
"product_url": "https://lwww.estore.com/product1/",
"quantity": 1,
"unit_price": 50000,
"total_amount": 50000,
"tax_rate": 0,
"total_tax_amount": 0
},
{
"type": "physical",
"reference": "coolthing2",
"name": "cool thing 2",
"image_url": "https://www.estore.com/image2.png",
"product_url": "https://www.estore.com/product2/",
"quantity": 1,
"unit_price": 10000,
"total_amount": 10000,
"tax_rate": 0,
"total_tax_amount": 0
},
{
"type": "sales_tax",
"reference": "Tax",
"name": "Tax",
"quantity": 1,
"unit_price": 0,
"tax_rate": 0,
"total_tax_amount": 0,
"total_amount": 0
},
{
"type": "shipping_fee",
"reference": "Shipping",
"name": "Shipping",
"quantity": 1,
"unit_price": 500,
"tax_rate": 0,
"total_amount": 500,
"total_tax_amount": 0
}
],
"merchant_reference1": "Merchant OrderID",
"merchant_urls": {
"confirmation": "https://www.estore.com/confirmation"
}
}
Klarna Order Object Example for North America Merchant: With Discount
{
"purchase_country": "US",
"purchase_currency": "USD",
"locale": "en-US",
"billing_address": {
"given_name": "John",
"family_name": "Doe",
"email": "johndoe+require_signup@example.com",
"street_address": "935 First Ave",
"postal_code": "19406",
"city": "King of Prussia",
"region": "PA",
"phone": "+16145551234",
"country": "US"
},
"shipping_address": {
"given_name": "John",
"family_name": "Doe",
"email": "johndoe+require_signup@example.com",
"street_address": "935 First Ave",
"postal_code": "19406",
"city": "King of Prussia",
"region": "PA",
"phone": "+16145551234",
"country": "US"
},
"order_amount": 60090,
"order_tax_amount": 590,
"order_lines": [
{
"type": "physical",
"reference": "coolthing1",
"name": "cool thing 1",
"image_url": "https://www.estore.com/image1.png",
"product_url": "https://lwww.estore.com/product1/",
"quantity": 1,
"unit_price": 50000,
"total_amount": 50000,
"tax_rate": 0,
"total_tax_amount": 0
},
{
"type": "physical",
"reference": "coolthing2",
"name": "cool thing 2",
"image_url": "https://www.estore.com/image2.png",
"product_url": "https://www.estore.com/product2/",
"quantity": 1,
"unit_price": 10000,
"total_amount": 10000,
"tax_rate": 0,
"total_tax_amount": 0
},
{
"type": "sales_tax",
"reference": "Tax",
"name": "Tax",
"quantity": 1,
"unit_price": 590,
"tax_rate": 0,
"total_tax_amount": 0,
"total_amount": 590
},
{
"type": "shipping_fee",
"reference": "Shipping",
"name": "Shipping",
"quantity": 1,
"unit_price": 500,
"tax_rate": 0,
"total_amount": 500,
"total_tax_amount": 0
},
{
"type": "discount",
"reference": "COUPON-123",
"name": "fixed discount",
"quantity": 1,
"quantity_unit": "USD",
"unit_price": -1000,
"tax_rate": 0,
"total_amount": -1000,
"total_tax_amount": 0
}
],
"merchant_reference1": "Merchant OrderID",
"merchant_urls": {
"confirmation": "https://www.estore.com/confirmation"
}
}
Klarna Order Object Example for EU Merchant
For EU merchants, VAT taxes are included in the price of an item and we need to specify the VAT on an item level as shown in example samples below. The order object does not need to have a separate order line item just for tax, as we have for US merchants where we are sending in a specific order line item (order line containing "type" : "sales_tax") as shown in above example samples. For payment service API request, see Klarna Authorization EU merchant example.
Order Object Example for DE (Germany) Order
{
"order_amount": 4694,
"order_tax_amount": 727,
"purchase_country": "DE",
"purchase_currency": "EUR",
"locale": "en-DE",
"billing_address": {
"given_name": "John",
"family_name": "Doe",
"street_address": "Klarna street 1",
"city": "Berlin",
"region": null,
"postal_code": "35440",
"country": "DE",
"phone": "+49151515151515",
"email": "johndoe+require_signup@example.com"
},
"shipping_address": {
"given_name": "John",
"family_name": "Doe",
"street_address": "Klarna street 1",
"city": "Berlin",
"region": null,
"postal_code": "35440",
"country": "DE",
"phone": "+49151515151515",
"email": "johndoe+require_signup@example.com"
},
"merchant_reference1": "TMSUS",
// Payment Service Store ID
"merchant_reference2": "session_id",
// Payment Service Session ID
"order_lines": [
{
"name": "Day of the Dead Scotch Bonnet Hot Sauce",
"quantity_unit": "pcs",
"quantity": 6,
"unit_price": 699,
"total_amount": 4194,
"total_discount_amount": 0,
"image_url": "https://www.estore.com/image1.png",
"product_url": "https://lwww.estore.com/product1/",
"tax_rate": 2100,
"total_tax_amount": 727,
"type": "physical"
},
{
"name": "Standard",
"quantity_unit": "pcs",
"quantity": 1,
"unit_price": 500,
"total_amount": 500,
"total_discount_amount": 0,
"tax_rate": 0,
"total_tax_amount": 0,
"type": "shipping_fee"
}
]
}
Order Object Example for DE (Germany) order with discount (negative amount value) and special character (e.g. ß)
{
"order_amount": 34999,
"order_tax_amount": 4827,
"purchase_country": "DE",
"locale": "en-DE",
"billing_address": {
"given_name": "John",
"family_name": "Doe",
"street_address": "Hellersbergstraße 1",
"street_address2": null,
"city": "Dresden",
"region": "DE",
"postal_code": "01067",
"country": "DE",
"phone": "+49151515151515",
"email": "johndoe+require_signup@example.com"
},
"shipping_address": {
"given_name": "John",
"family_name": "Doe",
"street_address": "Hellersbergstraße 1",
"street_address2": null,
"city": "Dresden",
"region": "DE",
"postal_code": "01067",
"country": "DE",
"phone": "+49151515151515",
"email": "johndoe+require_signup@example.com"
},
"merchant_reference1": "IRBEU",
// Payment Service Store ID
"merchant_reference2": "session_id",
// Payment Service Session ID
"order_lines": [
{
"reference": null,
"name": "Day of the Dead Scotch Bonnet Hot Sauce",
"quantity_unit": "pcs",
"quantity": 1,
"unit_price": 30172,
"total_amount": 30172,
"total_discount_amount": 0,
"image_url": "https://www.estore.com/image1.png",
"product_url": "https://lwww.estore.com/product1/",
"tax_rate": 0,
"total_tax_amount": 0,
"type": "physical"
},
{
"reference": null,
"name": "STANDARD_SHIPPING",
"quantity_unit": "pcs",
"quantity": 1,
"unit_price": 991,
"total_amount": 991,
"total_discount_amount": 0,
"image_url": null,
"product_url": null,
"tax_rate": 0,
"total_tax_amount": 0,
"type": "shipping_fee"
},
{
"reference": null,
"name": "fixed discount",
"quantity_unit": "pcs",
"quantity": 1,
"unit_price": -991,
"total_amount": -991,
"total_discount_amount": 0,
"image_url": null,
"product_url": null,
"tax_rate": 0,
"total_tax_amount": 0,
"type": "discount"
},
{
"reference": null,
"name": "Tax",
"quantity_unit": "pcs",
"quantity": 1,
"unit_price": 4827,
"total_amount": 4827,
"total_discount_amount": 0,
"image_url": null,
"product_url": null,
"tax_rate": 0,
"total_tax_amount": 0,
"type": "sales_tax"
}
]
}
Order Object Example for UK Order
{
"order_amount": 7490,
"order_tax_amount": 1398,
"purchase_country": "GB",
"purchase_currency": "GBP",
"locale": "en-GB",
"billing_address": {
"given_name": "John",
"family_name": "Doe",
"street_address": "3 Edgar Buildings",
"city": "England",
"region": null,
"postal_code": "BA1 2FJ",
"country": "GB",
"phone": "+447911123456",
"email": "johndoe+require_signup@example.com"
},
"shipping_address": {
"given_name": "John",
"family_name": "Doe",
"street_address": "3 Edgar Buildings",
"street_address2": null,
"city": "England",
"region": null,
"postal_code": "BA1 2FJ",
"country": "GB",
"phone": "+447911123456",
"email": "johndoe+require_signup@example.com"
},
"merchant_reference1": "TMSUS",
// Payment Service Store ID
"merchant_reference2": "session_id",
// Payment Service Session ID
"order_lines": [
{
"name": "Day of the Dead Scotch Bonnet Hot Sauce",
"quantity_unit": "pcs",
"quantity": 10,
"unit_price": 699,
"total_amount": 6990,
"total_discount_amount": 0,
"image_url": "https://www.estore.com/image1.png",
"product_url": "https://lwww.estore.com/product1/",
"tax_rate": 2500,
"total_tax_amount": 1398,
"type": "physical"
},
{
"name": "Standard",
"quantity_unit": "pcs",
"quantity": 1,
"unit_price": 500,
"total_amount": 500,
"total_discount_amount": 0,
"tax_rate": 0,
"total_tax_amount": 0,
"type": "shipping_fee"
}
]
}
Order Object Example for UK Order with Discount
{
"order_amount": 24999,
"order_tax_amount": 4166,
"purchase_country": "GB",
"purchase_currency": "GBP",
"locale": "en-GB",
"billing_address": {
"given_name": "John",
"family_name": "Doe",
"street_address": "1098",
"street_address2": "Winchester Avenue",
"city": "Lancaster",
"region": "GB",
"postal_code": "LA1 4HX",
"country": "GB",
"phone": "+447911123456",
"email": "johndoe+require_signup@example.com"
},
"shipping_address": {
"given_name": "John",
"family_name": "Doe",
"street_address": "1098",
"street_address2": "Winchester Avenue",
"city": "Lancaster",
"region": "GB",
"postal_code": "LA1 4HX",
"country": "GB",
"phone": "+447911123456",
"email": "johndoe+require_signup@example.com"
},
"merchant_reference1": "IRBEU", // Payment Service Store ID
"merchant_reference2": "session_id", // Payment Service Session ID
"order_lines": [
{
"reference": null,
"name": "Roomba 606",
"quantity_unit": "pcs",
"quantity": 1,
"unit_price": 20832,
"total_amount": 20832,
"total_discount_amount": 0,
"image_url": "https://shop.store.co.uk//images/large/R.jpg",
"product_url": "https://shop.store.co.uk/de?lang=en_GB",
"tax_rate": 0,
"total_tax_amount": 0,
"type": "physical"
},
{
"reference": null,
"name": "UK Line Cord",
"quantity_unit": "pcs",
"quantity": 1,
"unit_price": 1083,
"total_amount": 1,
"total_discount_amount": 1082,
"image_url": null,
"product_url": "https://shop.store.co.uk/?lang=en_GB",
"tax_rate": 0,
"total_tax_amount": 0,
"type": "physical"
},
{
"reference": null,
"name": "STANDARD_SHIPPING",
"quantity_unit": "pcs",
"quantity": 1,
"unit_price": 792,
"total_amount": 792,
"total_discount_amount": 0,
"image_url": null,
"product_url": null,
"tax_rate": 0,
"total_tax_amount": 0,
"type": "shipping_fee"
},
{
"reference": null,
"name": "Free Shipping on All Orders",
"quantity_unit": "pcs",
"quantity": 1,
"unit_price": -792,
"total_amount": -792,
"total_discount_amount": 0,
"image_url": null,
"product_url": null,
"tax_rate": 0,
"total_tax_amount": 0,
"type": "discount"
},
{
"reference": null,
"name": "Tax",
"quantity_unit": "pcs",
"quantity": 1,
"unit_price": 4166,
"total_amount": 4166,
"total_discount_amount": 0,
"image_url": null,
"product_url": null,
"tax_rate": 0,
"total_tax_amount": 0,
"type": "sales_tax"
}
]
}
Initialize the JavaScript with the access Token and Order Data
After the JWT has been acquired and the order data object prepared, the radial.initKlarnaPayment() function must be used to initialize the JavaScript integration. Radial recommends invoking this function on the payment page when the customer selects the Klarna radio button as their payment option. The following arguments must be passed to the radial.initKlarnaPayment() function:
2. The order object data (described in Create Order Data and Klarna Order Object Format ).
1. The JWT acquired during Step 1
The following example shows the JavaScript integration for setup.
<head>
<script language="JavaScript">
function initKlarna() {
//Hide the Klarna submit button and show a spinner while the js inits
$("#klarna_submit").hide();
$("#spinner").show();
// Invoke Radial’s initKlarnaPayment method
const response = await radial.initKlarnaPayment(orderJsonObject, divid, jwt);
if(response.success){
// Initialization is complete, ok to show the Klarna submit button and hide the spinner now
$("#spinner").hide();
$("#klarna_submit").show();
// Hold on to below client_token. This needs to be passed by webstore in case of multi-page checkouts.
alert(response.client_token);
}
}
</script>
<title>Sample Code</title>
</head>
<body>
<div id="klarna-credit-container" />
<input
type="radio"
name="paymentMethod"
value="klarna"
id="paymentMethod_klarna"
onclick="initKlarna()"
/>
<form
action="/checkout/klarna/complete"
method="POST"
id="complete_checkout_klarna"
>
<input
type="hidden"
id="klarna_order_data"
name="klarna_order_data"
value=""
/>
<input type="submit" id="klarna_submit" value="Complete Order" />
</form>
<div id="spinner" class="spinner" style="display:none;">
<img id="img-spinner" src="spinner.gif" alt="Loading" />
</div>
</body>
After initialization complete, the Klarna widget is successfully shown or initialization returns error information .
Initialization Call Success Handling
When the setup is successful and the session with Klarna has been initialized, it returns the object describing the data used for the Klarna widget.
client_token: Klarna-generated token
session_id: Klarna-generated session id
payment_method_categories: A list of available payment methods including an id, descriptive name, and assets
The following is a sample of the argument that will be passed to the call back function when initialization is successful.
{
"session_id": "83ac4d96-aaaa-aaaa-842c-513ffedc0018",
"client_token": "(token data omitted for readability)",
"payment_method_categories": [
{
"identifier": "pay_later",
"name": "Pay later in 30 days",
"asset_urls": {
"descriptive": "https://x.klarnacdn.net/payment-method/assets/badges/generic/klarna.svg",
"standard": "https://x.klarnacdn.net/payment-method/assets/badges/generic/klarna.svg"
}
},
{
"identifier": "pay_over_time",
"name": "Buy now, pay later",
"asset_urls": {
"descriptive": "https://x.klarnacdn.net/payment-method/assets/badges/generic/klarna.svg",
"standard": "https://x.klarnacdn.net/payment-method/assets/badges/generic/klarna.svg"
}
}
],
"paymentMethodCategoryIdentifiers": ["pay_later", "pay_over_time"]
}
There are two use cases where the values returned by the Klarna setup function response need 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, such total value of the order or quantity of the items, address changes or corrections, and so on.
When the Klarna setup function succeeds, the Klarna widget is populated with the available Klarna payment options and can be displayed to the customer.
Initialization Call Error Handling
The Klarna setup function returns an error object if:
The order data is not in the correct format (JSON object, or JSON formatted string)
The order data is missing required information or contains invalid values. See the order data object description above for order data object requirements.
There was a communication error with the radial hosted payments service, or the klarna service.
In the event of an error, the error object contains:
success: false, indicating failure operation
errorCode: A code for the error which has occurred
errorMessage: A string representing a brief message about the error
errorDescription: A string message further describing the error
When the Klarna setup function returns an error object, a message should be displayed to the customer stating that payments via Klarna are currently unavailable.
Step 3: Accept Order and Authorize
When the customer clicks the Submit button, the webstore must call Radial's radial.processKlarnaPayment() JavaScript method. This method takes two 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.
payment_method_categories, which is captured in the initKlarnaPayment() call response.
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. Typically this form collects information such as the last four digits of the Social Security Number, date of birth, and so on, and provides approval for the loan.
When the customer interaction with the Klarna widget ends, it returns a response object that contains the result of the Klarna loan approval. The response object contains a property actionCode that dictates if the authorization was successful.
Address and Other Corrections
If the order data in the final authorization call does not match the data in the initial order submission, Klarna rejects the order . Even a small address correction, such as adding the +4 digits to a US postal code (for example, correcting "19406" to "19406-1342") can count as a mismatch. Klarna detects a data discrepancy and rejects the final authorization for the order. Thus, it is critical that the order data initially submitted to Klarna exactly matches the order data included in the authorization call made to Radial (described below).
Radial strongly recommends that any address correction be performed prior to submitting the initial authorization. All other data that may be affected by address correction (such as tax calculation) should also be updated appropriately before making the Radial.processKlarnaPayment call.
If any corrections to the order data are made after the Radial.processKlarnaPayment call, the authorization must be updated as described below, using the corrected data, or the Klarna rejects the order.
Action Codes
Action Code | Description |
---|---|
SUCCESS | Use the authorization_token value in the returned JSON object for subsequent server side call to Radial's Authorization Request API. |
FAILURE | Klarna cannot be used as a payment method. The webstore must prompt customer to select a new payment method. |
ERROR | Klarna cannot be used as a payment method. The webstore must prompt customer to select a new payment method. |
Success Handling
When the actionCode is SUCCESS, the response object contains the following properties:
actionCode: SUCCESS
authorization_token: The token identifying the approved authorization. This value must be preserved by the webstore as it is required for making any further updates to the order and as a parameter for the InstantFinanceAuthRequest API. An authorization_token is valid for 60 minutes.
approved: A boolean indicating the result of the credit assessment.
finalize_required: A boolean indicating that the finalize method should be called in order to complete the authorization
show_form: A boolean indicating whether to keep showing the form or to remove it.
Failure Handling
When the actionCode is FAILURE, a message should be displayed to the customer informing them that their authorization was not approved and they need to select an alternate payment method.
Error Handling
When the actionCode is ERROR, an appropriate message should be displayed to the customer informing them that Klarna is currently unavailable as a payment method and another payment method needs to be selected. In case of Radial.processKlarnaPayment errors, an error_code is also returned.
Error Codes
Error Code | Error Message | Description |
---|---|---|
50002 | InvalidLoginError | The access Token used to connect to Radial is invalid or timed out. Renew the access Token and try again. |
40005 | IncompleteGatewayData | The JSON object passed in does not have all the required fields. |
50004 | InvalidGatewaySession | The session used to connect/update to Gateway is invalid. Get a fresh session and try again. |
50011 | Klarna Load Error | Failed to load Klarna. Please try again. |
Sample Response Handler Code
The following code sample provides an example for handling the klarnaAuth response.
switch (response.actionCode) {
case "SUCCESS":
// Capture the authorization token.
// This must be passed in the InstantFinanceAuthRequest API
console.log(response.authorization_token, response.actionCode);
break;
case "FAILURE":
// Klarna cannot be used as payment method.
// Display message to customer and prompt to use alternate payment method.
console.log(response.actionCode);
break;
case "ERROR":
// Handle errors
console.log(response.errorCode, response.errorMessage);
}
}
Single-Page Checkout
A single page checkout refers to a checkout implementation in which the customer's browser remains on a single webpage. Any steps (such as specifying addresses, selecting payment methods, reviewing the order before submission, and so on) are handled via javascript, DOM manipulation, AJAX request, and so on .
For a detailed flow diagram of a single-page Klarna checkout, click here. (Diagram opens in new window.)
Note: In a single page checkout, in general the order object does not change after the authorization is completed.
Multi-Page Checkout
A multi-page checkout is 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.
For a detailed flow diagram of a multi-page Klarna checkout, click one of the links below. (Diagrams open in new windows.)
In a multi-page checkout, the flow typically follows this logic:
The payment page is presented with Klarna as a payment option.
When the customer chooses Klarna as the payment option, the webstore invokes the radial.initKlarnaPayment() function with the jwt, the order object data.
When the initKlarnaPayment() function is completed, the Klarna widget should be displayed. The webstore has to collect and store the client_token, session_id, and payment_methods returned in the response object for future reference.
The customer interacts with the Klarna widget, accepts the terms and conditions, and finally clicks Continue Checkout.
The webstore invokes the radial.processKlarnaPayment(klarnaPaymentMethodCategories, false) Javascript method. Note: The second parameter, referred as the auto finalize flag, must be set to false for multi-page checkout flow.
This action results in a loan approval session between Klarna and the customer. In the "happy path" scenario, the call returns with a response object that contains an actionCode of "SUCCESS" and an authorization_token. The authorization_token value must be used when making the server-to-server call to Radial for authorization using the InstantFinanceAuthRequest API or for any corrections to the order.
The webstore can navigate the customer to the review page as the final step of the method. In the onload event of the review page, the webstore should invoke the radial.klarnaMultiPageSetup() Javascript function. This method takes four parameters:
clientToken: The clientToken that was returned during the Radial.initKlarnaPayment() call.
sessionId: The sessionId that was returned during the Radial.initKlarnaPayment() call.
paymentCategories: The payment_methods returned during the Radial.initKlarnaPayment() call.
klarnaReviewContainer: an optional review container ID; the default is '#klarna-reviewload-container.
The review page should also contain a div tag with the ID klarna-reviewload-container. In the case there is a need for reauthorization, this tag displays the klarna widget. .
Prior to performing the final authorization, the webstore must check to see if the order has changed, including any corrections (See Address and Other Corrections .) If the order has changed, then the webstore must invoke the radial.updateKlarnaOrder() Javascript function. This function takes five parameters:
jwt: The authToken received from Radial Setup call.
cancelOrderData: an order object that Klarna previously authorized now needs to be cancelled due to order data change. (This should contain the previous authorization; see below for required format to cancel)
updatedOrderJsonObject: The updated order json object containing the current information for the order.
divContainerId: an optional container Id to reload klarna widget (default is "#klarna-payments-container")
previousAuthorizationToken: The authorization token that was returned in Step 6 during the Radial.processKlarnaPayment() call. Note: In the case of one or more reauthorizations, this token must be the authorization token from the most recent authorization.
After submitting the updated order information, the customer is presented with the Klarna widget, where they choose loan terms and payment option. When the update process has completed, it returns the success response along with client_token, session_id, payment_method_categories, similar to initKlarnaPayment() call.
To obtain a new authorization token and proceed further, the Javascript should invoke either the radial.processKlarnaPayment() or the radial.klarnaFinalize() method, based on the payment method.
For the Klarna Bank Transfer Payment method, the store should invoke the radial.klarnaFinalize() method to receive the latest authorization token.
For other Payment methods, the store should invoke the radial.processKlarnaPayment() method with the auto-finalize as true to receive the latest authorization token.
After reviewing the order on the review page, the customer submits the order.
When the order is submitted, the webstore should invoke Radial's InstantFinanceAuthRequest REST call with the authorization_token. The authorization token used will either be the token generated in Step 6 if the order did not change, or the new token generated in Step 10 if there was a change in the order. See Step 4 for further details.
Display of Selected Payment Method in Review Page
If the webstore wants to display the payment method selected in the review page, it needs to include a div tag with ID klarna-reviewload-container in the review page. The radial.klarnaMultiPageSetup() function looks for a div with this ID and passes it to Klarna to display the selected payment method.
<div id="klarna-reviewload-container" />
Sample Walkthroughs of Checkouts
In this section, you can view sample walkthroughes with screenshots of multi-page checkouts using the Klarna Integration. Click each heading to view the sample walkthrough.
Klarna Payments Email Flags to Use for Test Scenarios
To test the Klarna integration, specific formats are used for the email address to trigger various scenarios. The following table describes the email format used and the test case that is triggered.
Scenario | Email Format | Description |
---|---|---|
No Offers | {user}+red@{domain} | No Available Offers on load |
New Customer Sign-up required | {user}+require_signup@{domain} | Trigger the account signup flow |
New Customer Denied | {user}+require_signup+denied@{domain} | Trigger the account signup flow but denies the application |
Existing Customer | {user}+accept@{domain} | Accepts authorization for existing customer |
Decline | {user}+denied@{domain} | Declined on authorized |
Use Case 1. New customer selects Klarna Payment on payments page and gets Klarna approved
Use Case 2: New customer is denied Klarna Credit approval
Use case 3: Return customer is denied Klarna Credit application
Use case 4: Return customer is accepted for Klarna Credit application
Step 4: Authorization Call to Radial Payment
The webstore makes an authorization call by sending an InstantFinanceAuthRequest message to Radial’s Authorization API to authorize an order. This is a Server-to-Server call made by the webstore when the customer has submitted the order. Details of the authorization request can be found in the InstantFinanceAuthorization API Documentation. The request payload contains order details, customer details, and the Klarna authorization_token. The order details submitted during this call must be the same as the details provided when the Javascript authorization occurred (either original or the updated order information if the order was updated during a multi-page checkout.)
For a success scenario, the Radial payment response, an InstantFinanceAuthReply message, includes a success status. The webstore can accept the order and send it to downstream systems for order processing.
If the checkout is not completed, or if an order is not placed within 60 minutes, the InstantFinanceAuthRequest call fails with an `ExtendedResponseCode> element giving an "Invalid Authorization Token" message.
Note: Include the Tax Amount in the Auth Request: The webstore must ensure that the amount sent in the authorization request includes the tax amount. If for some reason, the webstore is unable to calculate taxes, the webstore should not accept the order.
The flowchart below shows the steps of the Klarna authorization call.
For API details, see Klarna Authorization.
When the InstantFinanceAuthorization is successful, the webstore can display an order confirmation page to the customer.
Timeout Processing
Radial recommends a timeout of 22 seconds for the Klarna InstanceFinanceAuthRequest REST call. If there is a timeout, the webstore can retry the request. If there is repeated failure, the webstore should prompt the customer to use an alternate payment method.
Failure Processing
If the response code value is FAILURE, the webstore should refuse the order, display a message to the customer indicating that the payment could not be made, and prompt the customer to use an alternate payment method.
Order Management System Integration
Order Management System Flow
After the webstore submits an order to the order management system, the following sequence of calls take place. (Note: This scenario assumes an integration with Radial’s Risk Service.)
Prior to releasing the order for fulfilment, the order management system must make a RiskAssessment call to Radial’s Risk Service. See Risk Assessment API.
The Order management system waits for the Risk Service to return an asynchronous risk assessment reply message.
The Risk Service looks up the fraud status of the order and sends a RiskAssessmentReply message with the result that the order passed the fraud check. (If the RiskAssessmentReply returns a failure result, see the next section, Failure Processing.)
If the Risk Assessment was successful, the order is released for fulfillment.
When the order is ready for shipping, a ConfirmFunds request is sent. If the ConfirmFunds call fails, cancel the order. See Confirm Funds.
If the ConfirmFunds call returns a status of pending, the order should be held and confirm funds called again at a later time.
If the ConfirmFunds call is successful, then the order can be shipped.
It is important for the order management system to have logic to ensure the cumulative sum of the settlement amounts does not exceed the authorization amount. Klarna does not allow the settlement amount to exceed the authorization amount. If this rule is violated, the settlement is rejected.
When the order is shipped, the order management system makes a Settlement call to Payment Service to capture the funds. If there are multiple shipments, the settlement amount is the partial amount for the portion of the order that is shipping.
After all line items are shipped (when no further capture is necessary), the order management system must send one final PaymentSettlement request with the FinalDebit flag set to true. This request finalizes the funds capture; therefore, no more capture settlement requests are possible afterward. See Payment Settlement.
The final request also triggers a back office auth adjustment call to release any surplus funds that are not settled back to the customer’s account.
Failure Processing
If the Risk Service sends a RiskAssessmentReply message with the result that the order failed its fraud check, the order management system should cancel the order.
If the order must be cancelled, the order management system must use the Payment Service’s PaymentAuthCancelRequest API to cancel the authorization hold on the customer's funds. This is an asynchronous call. See Payment Authorization Cancel.
Legacy Clients using JDA
If you are a legacy Radial client using the JDA order management system, you must use a separate FTP folder to push order files that use the Klarna payment method. Radial’s feeds team will provide the location of the folder, which will be on the current FTP site. You should ensure that only orders using the Klarna payment method are present in this folder. These Klarna orders must not be mixed together with orders paid though credit card, PayPal, or other payment methods.
The Klarna order file must follow a special format, which is detailed below.
File Format for Orders with Klarna Payments
For legacy Radial clients using JDA, use this format for the separate file that contains orders with Klarna payments. Push this file in the special Klarna payments FTP folder.
File format details to be provided at a later date.