# Klarna Debit Risk for Unified Payments API
To accept Klarna Debit Risk payments:
1. [Request a payment context](#Request_a_payment_context).
2. [Configure Klarna's JavaScript SDK](#Configure_the_Klarna_JavaScript_SDK).
3. [Authorize the session](#Authorize_the_session).
Optionally, you can [verify if Klarna approved the payment context](#Verify_if_Klarna_approved_the_payment_context_).
4. [Request a payment](#Request_a_payment).
---
## Request a payment context
To display the Klarna widget on the checkout page, you must request a Checkout.com payment context. The payment context will return a `session_id` and `client_token`, which you'll need to provide in later requests.
> **Information**
>
> The Payment Contexts API supports [idempotency](https://www.checkout.com/docs/developer-resources/api/idempotency.md). You can safely retry API requests without the risk of duplicate requests.
**Live**
`POST` `https://{prefix}.api.checkout.com/payment-contexts`
**Sandbox**
`POST` `https://{prefix}.api.sandbox.checkout.com/payment-contexts`
### Request example
```json
{
"currency": "EUR",
"amount": 1000,
"source": {
"type": "klarna",
"account_holder": {
"billing_address": {
"country": "DE"
}
}
},
"items": [
{
"name": "Battery Power Pack",
"quantity": 1,
"unit_price": 1000,
"total_amount": 1000,
"reference": "BA67A"
}
],
"processing": {
"locale": "en-GB"
},
"processing_channel_id": "{pc_xxxx}"
}
```
You must provide the `items[]` array when you request a Klarna payment context. The value of `items[].reference` is the reference shown to your customer in the Klarna application when confirming the payment.
For the full API specification, see the [API reference](https://api-reference.checkout.com/tag/Payment-Context/#operation/requestAPaymentContext).
You must provide the `items[]` array when you request a Klarna payment context. The value of `items[].reference` is the reference shown to your customer in the Klarna app when confirming the payment.
If you receive a `201 Created` response code, your request was successful.
A successful request will contain the following fields in the response's `partner_metadata` object:
- `session_id`
- `client_token`
```json
{
"id": "pct_jwvjl5tin54ubn7x2stvmunske",
"partner_metadata": {
"session_id": "kcs_55xomnyd3ftujckeoyuvtkx2ue",
"client_token": "eyJhbGciOiJub25lIn0.ewogICJzZXNzaW9uX2lkIiA6ICI1MGEzYTNiOS02NGE5LTYwNjMtODNmNC1hMzRlM2Q4MjRiNGIiLAogICJiYXNlX3VybCIgOiAiaHR0cHM6Ly9rbGFybmEtcGF5bWVudHMtZXUucGxheWdyb3VuZC5rbGFybmEuY29tIiwKICAiZGVzaWduIiA6ICJrbGFybmEiLAogICJsYW5ndWFnZSIgOiAiZW4iLAogICJwdXJjaGFzZV9jb3VudHJ5IiA6ICJHQiIsCiAgImFuYWx5dGljc19wcm9wZXJ0eV9pZCIgOiAiVUEtMzYwNTMxMzctMTEiLAogICJ0cmFjZV9mbG93IiA6IGZhbHNlLAogICJlbnZpcm9ubWVudCIgOiAicGxheWdyb3VuZCIsCiAgIm1lcmNoYW50X25hbWUiIDogIlBsYXlncm91bmQgRGVtbyBNZXJjaGFudCIsCiAgInNlc3Npb25fdHlwZSIgOiAiUEFZTUVOVFMiLAogICJjbGllbnRfZXZlbnRfYmFzZV91cmwiIDogImh0dHBzOi8vZXZ0LnBsYXlncm91bmQua2xhcm5hLmNvbSIKfQ."
},
"_links": {
"self": {
"href": "https://{prefix}.api.checkout.com/payment-contexts/pct_jwvjl5tin54ubn7x2stvmunske"
}
}
}
```
---
## Configure the Klarna JavaScript SDK
The Klarna JavaScript SDK enables you to display the Klarna widget in your site:
1. Add the Klarna script to your web application.
```javascript
```
2. Initialize the Klarna SDK with the `client_token` received in the `payment_context` response.
```javascript
window.klarnaAsyncCallback = function () {
Klarna.Payments.init({
client_token:"eyJhbGciOiJub...",
});
};
```
> **Note**
>
> `client_token` relies on the Klarna session created with the payment context request. The payment context request expires after 48 hours, after which payments might fail.
3. Place a container on your page to render Klarna as a payment option.
```javascript
```
4. Load the Klarna widget in the placeholder.
```javascript
Klarna.Payments.load(
{
container: '#klarna-payments-container'
},
{},
function (res) {
console.debug(res);
}
)
```
> **Information**
>
> For a better user experience, call `load()` when you load your checkout page. This ensures that the container for Klarna payments loads immediately in a hidden container, and is ready to display when needed.
For more information, see Klarna Docs:
- [Klarna Payments SDK Reference](https://docs.klarna.com/klarna-payments/in-depth-knowledge/klarna-payments-sdk-reference/)
- [Klarna payments integration](https://docs.klarna.com/payments/)
- [Klarna brand guidelines](https://docs.klarna.com/resources/marketing-tools/global-marketing-assets/marketing-for-integrated-partners/)
---
## Authorize the session
You must call the authorization endpoint only once. The authorization token is then valid for 60 minutes.
When the customer selects to pay with Klarna, open the Klarna pop-up and authorize the session. To provide a seamless checkout experience, ensure you send the billing and shipping parameters:
```javascript
Klarna.Payments.authorize(
{},
{
billing_address: {
given_name: "Alice",
family_name: "Test",
email: "customer@email.se",
street_address: "Södra Blasieholmshamnen 2",
postal_code: "11 148",
city: "Stockholm",
phone: "+46701740615",
country: "SE",
},
shipping_address: {
given_name: "Alice",
family_name: "Test",
email: "customer@email.se",
street_address: "Södra Blasieholmshamnen 2",
postal_code: "11 148",
city: "Stockholm",
phone: "+46701740615",
country: "SE",
},
customer: {
date_of_birth: "1941-03-21",
},
},
function (res) {
console.log("Authorize outcome:", res);
}
)
```
There are two potential cases that you need to handle based on the response:
- Success response `show_form: true` – Klarna performed a pre-assessment and authorized the purchase. You receive a `payment_context_approved` webhook. Once the payment context is approved, the approval is valid for 60 minutes.
- Error response `show_form: false` – Klarna performed a pre-assessment and didn't authorize the purchase. You cannot offer Klarna as a payment option and need to hide it for the customer at checkout. The customer must select another payment method.
Once the customer confirms payment in the Klarna pop-up, you receive a `payment_context_approved` webhook.
### Verify if Klarna approved the payment context `Optional`
Optionally, you can verify if Klarna approved the payment context by calling the [Get payment context](https://api-reference.checkout.com/tag/Payment-Context/#operation/getPaymentContext) endpoint to verify its `status`:
**Live**
`GET` `https://{prefix}.api.checkout.com/payment-contexts/{id}`
**Sandbox**
`GET` `https://{prefix}.api.sandbox.checkout.com/payment-contexts/{id}`
#### Response example
```json
{
"status": "Approved",
"payment_request": {
"source": {
"type": "klarna",
"account_holder": {
"first_name": "Bose",
"last_name": "Gold",
"date_of_birth": "1990-10-12",
"email": "test@example.com",
"billing_address": {
"address_line1": "654 Main St.",
"country": "US",
"state": "OH"
},
"phone": {
"country_code": "",
"number": ""
},
"identification": {
"number": ""
},
"company_name": "Checkout.com"
}
},
"amount": 1000,
"currency": "EUR",
"shipping": {
"company_name": "Checkout.com",
"first_name": "Test",
"last_name": "Account",
"address": {
"address_line1": "Von-Reiche-Straße 9",
"address_line2": "6th floor",
"zip": "63930",
"city": "Furth",
"country": "DE"
},
"phone": {
"country_code": "+353",
"number": "6789010"
}
},
"items": [
{
"name": "Battery Power Pack",
"quantity": 1,
"unit_price": 1000,
"tax_rate": 0,
"total_amount": 1000,
"tax_amount": 0,
"reference": "BA67A",
"url": "https://product.url.com",
"image_url": "https://image.url.com"
}
],
"processing": {
"locale": "en-IE",
"tax_amount": 0,
"custom_payment_method_ids": [
"6m_149APR",
"6m_0APR",
"12m_149APR",
"12m_0APR",
"24m_149APR",
"24m_0APR"
]
}
},
"partner_metadata": {
"session_id": "kcs_55xomnyd3ftujckeoyuvtkx2ue",
"client_token": "eyJhbGciOiJub25lIn0.ewogICJzZXNzaW9uX2lkIiA6ICI1MGEzYTNiOS02NGE5LTYwNjMtODNmNC1hMzRlM2Q4MjRiNGIiLAogICJiYXNlX3VybCIgOiAiaHR0cHM6Ly9rbGFybmEtcGF5bWVudHMtZXUucGxheWdyb3VuZC5rbGFybmEuY29tIiwKICAiZGVzaWduIiA6ICJrbGFybmEiLAogICJsYW5ndWFnZSIgOiAiZW4iLAogICJwdXJjaGFzZV9jb3VudHJ5IiA6ICJHQiIsCiAgImFuYWx5dGljc19wcm9wZXJ0eV9pZCIgOiAiVUEtMzYwNTMxMzctMTEiLAogICJ0cmFjZV9mbG93IiA6IGZhbHNlLAogICJlbnZpcm9ubWVudCIgOiAicGxheWdyb3VuZCIsCiAgIm1lcmNoYW50X25hbWUiIDogIlBsYXlncm91bmQgRGVtbyBNZXJjaGFudCIsCiAgInNlc3Npb25fdHlwZSIgOiAiUEFZTUVOVFMiLAogICJjbGllbnRfZXZlbnRfYmFzZV91cmwiIDogImh0dHBzOi8vZXZ0LnBsYXlncm91bmQua2xhcm5hLmNvbSIKfQ."
}
}
```
If `status` is returned as `Approved`, Klarna has authorized this purchase and you can request the payment.
---
## Request a payment
**Live**
`POST` `https://{prefix}.api.checkout.com/payments`
**Sandbox**
`POST` `https://{prefix}.api.sandbox.checkout.com/payments`
### Request example
```json
{
"payment_context_id": "pct_xxx",
"processing_channel_id": "pc_xxx"
}
```
### Response example
Your request was successful if you receive a `202 Success` response code with a `status` field set to `Pending`.
```json
{
"id": "pay_mnnf6wnp7fdupa2jechtgg5cr4",
"status": "Pending",
"payment_type": "Installment",
"payment_plan": {
"financing": true
},
"processing": {
"partner_order_id": "dc3b8712-123a-45ef-bc3d-b356a158b31b",
"partner_fraud_status": "ACCEPTED"
},
"_links": {
"self": {
"href": "https://{prefix}.api.sandbox.checkout.com/payments/pay_mnnf6wnp7fdupa2jechtgg5cr4"
}
}
}
```
---
## Payment flow and timing
When we you send us the payment request:
1. We run syntax validation and compliance checks on the payment data.
2. If all checks are successful, we set the payment status to `pending` and send your request to Klarna.
- If unsuccessful, we set the payment status to `declined`.
3. Once Klarna confirms they sent the request to the bank, we move the payment to `capture pending` and send you a `payment_capture_pending` webhook.
4. If and when Klarna confirms they received the funds from the customer bank, we move the payment to `captured` and send you a `payment_captured` webhook.
- If and when Klarna closes the transaction because they did not receive the funds from the customer's bank, we move the payment to `declined` and send you a `payment_capture_declined` webhook.
On average, it takes one to three business days to receive an answer from the bank, but it can take up to 10 business days to receive the final answer. If the customer funds reach Klarna after the 10 business days window, Klarna returns the money to the customer without notifying us.
---
## Get payment details
Use the `payment_id` from the payment response to retrieve details about the payment.
**Live**
`GET` `https://{prefix}.api.checkout.com/payments/{id}`
**Sandbox**
`GET` `https://{prefix}.api.sandbox.checkout.com/payments/{id}`
### Response example
```json
{
"id": "pay_mnnf6wnp7fdupa2jechtgg5cr4",
"requested_on": "2024-08-13T15:14:28.1308176Z",
"source": {
"type": "klarna",
"account_holder": {
"first_name": "Hannah",
"last_name": "Bret",
"billing_address": {
"address_line1": "Bodestr. 1-3",
"city": "Berlin",
"zip": "10178",
"country": "DE",
"state": ""
},
"email": "generated_email_de+1698763875860@example.com",
"date_of_birth": "1992-01-01",
"phone": {
"number": "+4915257607960"
},
"account_holder_name": "Hannah Bret",
"gender": "female",
"account_number": "1234567890",
"bank_name": "Test Bank",
"bank_code": "012345678",
"bic": "SFRTDE20XXX",
"iban": "DE06000000000023456789"
}
},
"payment_type": "Installment",
"payment_plan": {
"financing": true
},
"items": [
{
"name": "OTR-AC Elite 90 Capsules",
"quantity": 1,
"unit_price": 4998,
"total_amount": 4998,
"tax_amount": 0,
"discount_amount": 0
},
{
"name": "Discount",
"quantity": 1,
"unit_price": 1000,
"total_amount": 1000,
"discount_amount": 0
}
],
"amount": 3998,
"currency": "EUR",
"status": "Captured",
"approved": true,
"balances": {
"total_authorized": 3998,
"total_voided": 0,
"available_to_void": 0,
"total_captured": 3998,
"available_to_capture": 0,
"total_refunded": 0,
"available_to_refund": 3998
},
"shipping": {
"first_name": "Samuel",
"last_name": "Rudd",
"email": "srudd@email.com",
"address": {
"address_line1": "Rotherstraße 19",
"city": "Berlin",
"state": "",
"zip": "10245",
"country": "DE"
},
"phone": {
"number": "+4930774615846"
}
},
"processing": {
"partner_session_id": "43c4421b-605a-47c2-88bb-d5dd9025222b",
"partner_order_id": "dc3b8712-123a-45ef-bc3d-b356a158b31b",
"fraud_status": "ACCEPTED",
"locale": "en-GB",
"tax_amount": 0,
"shipping_amount": 0
},
"_links": {
"self": {
"href": "https://{prefix}.api.sandbox.checkout.com/payments/pay_mnnf6wnp7fdupa2jechtgg5cr4"
},
"actions": {
"href": "https://{prefix}.api.sandbox.checkout.com/payments/pay_mnnf6wnp7fdupa2jechtgg5cr4/actions"
},
"refund": {
"href": "https://{prefix}.api.sandbox.checkout.com/payments/pay_mnnf6wnp7fdupa2jechtgg5cr4/refunds"
}
}
}
```
---
## Refund a payment
Klarna Debit Risk supports both partial and full refunds.
You can refund the payment in the [Dashboard](https://dashboard.checkout.com).
Alternatively, call the [Refund a payment](https://api-reference.checkout.com/tag/Payments/#operation/refundAPayment) endpoint, and provide the `payment_id` value from the [Request a payment](#Request_a_payment) response as the `{id}` path parameter.
> **Information**
>
> Your base URL's `{prefix}` value is unique to your account and environment. To learn how to retrieve your base URLs for the sandbox and production environments, see [API endpoints](https://www.checkout.com/docs/developer-resources/api/api-endpoints.md).
**Production**
`POST` `https://{prefix}.api.checkout.com/payments/{id}/refunds`
**Sandbox**
`POST` `https://{prefix}.api.sandbox.checkout.com/payments/{id}/refunds`
To provide a better customer experience when you perform a partial refund, provide information about the refunded items in the `items[]` object in the refund request.
For more information, see [Refund a payment](https://www.checkout.com/docs/payments/manage-payments/refund-a-payment).
---
## Test your integration
To test your Klarna integration:
1. Contact your account manager or [request support](https://dashboard.checkout.com/support/new?topic=case_account_management_and_access&issue=issue_account_changes) to activate Klarna payments in your Checkout.com sandbox environment.
2. Create a Klarna transaction by following the [Klarna Payment flow](#Klarna_payment_flow) and using Klarna's [test environment data](https://docs.klarna.com/payments/web-payments/additional-resources/use-cases/klarna-debit-risk/#before-you-start-test-environment).
3. [Using the Klarna JS SDK](https://docs.klarna.com/klarna-payments/in-depth-knowledge/klarna-payments-sdk-reference/), embed the JWT token to render the UI components, and carry out the payment via the pop-up window.
4. Complete the payment.
If successful, you will then be redirected to your predefined success URL.
---
## Move your integration to the production environment
Contact your account manager or [request support](https://dashboard.checkout.com/support/new?topic=case_account_management_and_access&issue=issue_account_changes) to move your integration to a production environment.
---
## Optional features
Optional features include:
- Extra merchant data
- Discounts
### Extra merchant data
Depending on the merchant segment or the services available to consumers, Klarna may require additional information regarding the customer, the merchant, and/or the purchase. This information is known as extra merchant data (EMD) and is data that is typically not available at checkout. Klarna uses this information to complete an assertive risk assessment, enable new promotional products, and improve conversion rates for a boost in performance.
If you enable consumers to register to your site, EMD enables Klarna to identify your returning consumers and enhance the services offered even if they have no previous history paying with Klarna. This can also help Klarna to offer enhanced services and personalize the customer experience.
To use EMD for registered checkout and Klarna deals, send the following objects as a serialized JSON object when [authorizing the session](#Authorize_the_session) using Klarna JS SDK:
- `customer_account_info`
- `payment_history_full`
- `payment_history_simple`
If you operate within the travel or ticketing segments, you must provide Klarna with the required EMD data points:
**EMD required for travel**
If you are selling services associated to the travel segment, you must provide information about the passengers and the itinerary to be booked via the applicable EMD for the service provided:
- `air_reservation_details`
- `train_reservation_details`
- `bus_reservation_details`
- `ferry_reservation_details`
- `car_rental_reservation_details`
- `hotel_reservation_details`
- `trip_reservation_details`
**EMD required for ticketing**
If you sell tickets to an event, you must provide information about the event using the `event` object.
For more information about the EMD objects, see the [Klarna's extra merchant data documentation](https://docs.klarna.com/api/extra-merchant-data/)
### Tax
You can provide tax information from the payment you are processing.
You can provide tax information for each item using the following fields:
- `items[].tax_rate`
- `items[].tax_amount`
You can provide either one of these fields and then Checkout.com calculates the other:
- `tax_amount` = (`tax_rate` * `total_amount`) / (100 + `tax_rate`)
- `tax_rate` = (100 * `tax amount`) / (`total_amount` - `tax amount`)
```json
{
"currency": "EUR",
"amount": 1000,
"source": {
"type": "klarna",
"account_holder": {
"billing_address": {
"country": "DE"
}
}
},
"amount": 1000,
"items": [
{
"type": "Physical",
"name": "jumper",
"quantity": 1,
"reference": "98-765-XYZ",
"total_amount": 20000,
"unit_price": 100,
"tax_rate": 2000,
"tax_amount": 9917,
"total_amount": 59500
}
],
"processing_channel_id": "pc_rikhvutraenu7eno62f5u2buge",
"processing": {
"locale": "en-GB"
}
}
```
### Discounts
You can apply a discount to an individual item or to all items in the transaction:
- For an individual item, provide the discount amount in the item's `items[].discount_amount` field.
- For all items, provide:
- A new item object with type `discount` (`"items[].type:"discount"`)
- The discount amount in `"items[].total_amount"`
You can apply both discounts to the same transaction.
#### Discount example
The following example shows two individual items with individual discounts applied, and an additional discount to the entire transaction:
##### 1 x jumper 50 EUR discounted 15%, tax 25%
- `items[0].quantity`: 1
- `items[0].unit_price`: 5000
- `items[0].discount_amount`: 15% of 5000 = 750
- `items[0].total_amount`: (5000 * 1) - 750 = 4250
- (`unit_price`x quantity) - `discount_amount`
- `items[0].tax_rate`: 2500
- `items[0].tax_amount`: (25 * 4250) / (100 + 25) = 850
- (tax rate * `total_amount`) / (100 + tax rate)
##### 3 x white t-shirt 15 EUR discounted 10%, tax 25%
- `item.[1].quantity`: 3
- `item.[1].unit_price`: 1500
- `items[1].discount_amount`: 15% of 1500 = 450
- `items[1].total_amount`: (1500 * 3) - 450 = 4050
- (`unit_price` x quantity) - `discount_amount`
- `items[1].tax_rate`: 2500
- `items[1].tax_amount`: (25 * 4050) / (100 + 25) = 810
- (tax rate * `total_amount`) / (100 + tax rate)
##### 10% discount on an 83 EUR order
- 1 x order = 8300
- `items[2].type`: discount
- `items[2].total_amount`: (4250 + 4050) * 0.1 = 830
- (`items[0].total_amount` + `items[1].total_amount`) x discount rate
#### Request example
```json
{
"currency": "EUR",
"source": {
"type": "klarna",
"account_holder": {
"billing_address": {
"country": "DE"
}
}
},
"amount": 7470,
"items": [
{
"type": "Physical",
"name": "jumper",
"quantity": 1,
"reference": "98-765-XYZ",
"total_amount": 4250,
"discount_amount": 750,
"tax_amount": 850,
"tax_rate": 2500,
"unit_price": 5000
},
{
"type": "Physical",
"name": "white t-shirt ",
"quantity": 3,
"reference": "12-345-ABC",
"total_amount": 4050,
"discount_amount": 450,
"tax_amount": 810,
"tax_rate": 2500,
"unit_price": 1500
},
{
"type": "discount",
"name": "10% discount",
"quantity": 1,
"reference": "PROMO10",
"total_amount": 830,
"unit_price": 830
}
],
"processing_channel_id": "pc_rikhvutraenu7eno62f5u2buge",
"processing": {
"locale": "en-DE",
"shipping_amount": "0",
"tax_amount": "1660"
}
}
```