Docs
Firmly Agentic Commerce
Set theme to dark (⇧+D)

Complete Klarna Order

POST https://api.firmly.work/api/v1/domains/{domain}/express/klarna/complete-order

​​ Overview

Completes the checkout process by placing an order with the merchant using the Klarna authorization. This is the final step in the Klarna checkout flow. The endpoint validates the authorization token, places the order, and returns the order confirmation with the merchant’s order number.

Availability and the host this endpoint runs on are covered in the Klarna Express Checkout overview.

​​ Authentication

  • x-firmly-authorization (string, required) — Device access token from Browser Session

​​ Path Parameters

  • domain (string, required) — The merchant domain (e.g., “staging.luma.gift”)

​​ Request Body

  • attributes (object, required) — Klarna payment attributes
    Attributes
    • authorization_token (string) — Conditionally required. The Klarna authorization token. Required unless a prior Authorize call already stored it in the session — in that case it is retrieved automatically and may be omitted.
    • transaction_token (string) — Alternative to authorization_token.
    • redirect_result (string) — The result of a Klarna redirect flow. Also an accepted alternative: any one of the three satisfies the requirement, and each is forwarded to the merchant when supplied.

​​ Response

Returns the order confirmation object.

  • cart_id (string) — Unique identifier for the cart

  • platform_order_number (string) — The order number from the merchant platform

  • cart_status (string) — Status of the cart (e.g., “submitted”)

  • submitted_at (string) — ISO timestamp when the order was submitted

  • display_name (string) — Merchant’s display name

  • platform_id (string) — Identifier of the merchant’s underlying commerce platform. The literal value varies by merchant.

  • shop_id (string) — Merchant domain

  • urls (object) — Relevant URLs for the order

    URLs
    • thank_you_page (string) — URL to the merchant’s order confirmation page

  • line_items (array) — Array of items in the order

    Line Item Details
    • line_item_id (string) — Unique identifier for the line item
    • sku (string) — Product SKU
    • quantity (number) — Quantity ordered
    • description (string) — Product description
    • price (object) — Unit price
    • line_price (object) — Total price for this line item
    • image (object) — Product image information

  • shipping_info (object) — Delivery address details

  • billing_info (object) — Billing address details

  • shipping_method (object) — Selected shipping method with pricing

  • payment_summary (object) — Summary of the Klarna payment

    Payment Summary
    • payment_type (string) — Always "Klarna" for this gateway
    • attributes (object) — Klarna session details
    Attributes
    • session_id (string) — Klarna payment session identifier
    • authorization_token (string) — The authorization token used for this order

  • total (object) — Grand total including all costs

  • sub_total (object) — Subtotal before shipping and tax

  • shipping_total (object) — Shipping cost

  • tax (object) — Tax amount

  • cart_discount (object) — Total discount applied

​​ Code Example


const response = await fetch(
'https://api.firmly.work/api/v1/domains/staging.luma.gift/express/klarna/complete-order',
{
method: 'POST',
headers: {
'x-firmly-authorization': authToken,
'Content-Type': 'application/json'
},
body: JSON.stringify({
attributes: {
authorization_token: 'klarna_auth_token_from_widget'
}
})
}
);
const order = await response.json();
console.log('Order number:', order.platform_order_number);
// Redirect to thank you page
if (order.urls?.thank_you_page) {
window.location.href = order.urls.thank_you_page;
}

import requests
response = requests.post(
'https://api.firmly.work/api/v1/domains/staging.luma.gift/express/klarna/complete-order',
headers={
'x-firmly-authorization': auth_token,
'Content-Type': 'application/json'
},
json={
'attributes': {
'authorization_token': 'klarna_auth_token_from_widget'
}
}
)
order = response.json()
print(f"Order placed: {order['platform_order_number']}")
print(f"Thank you page: {order['urls']['thank_you_page']}")

curl -X POST https://api.firmly.work/api/v1/domains/staging.luma.gift/express/klarna/complete-order \
-H "x-firmly-authorization: YOUR_AUTH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"attributes": {"authorization_token": "klarna_auth_token_from_widget"}}'

​​ Response Example


{
"cart_id": "9cf76530-1344-420f-9ca6-c7a96fb6db45",
"platform_order_number": "6800018416",
"cart_status": "submitted",
"submitted_at": "2026-07-22T18:58:25.000Z",
"display_name": "Example Store",
"platform_id": "example_commerce",
"shop_id": "staging.luma.gift",
"urls": {
"thank_you_page": "https://staging.luma.gift/order/confirmation"
},
"line_items": [
{
"line_item_id": "3e66bef5-43f5-4a80-8957-91c5c8233163",
"sku": "MT12",
"quantity": 1,
"description": "Cassius Sparring Tank",
"price": {
"currency": "USD",
"value": 18,
"number": 1800,
"symbol": "$"
},
"line_price": {
"currency": "USD",
"value": 18,
"number": 1800,
"symbol": "$"
},
"image": {
"url": "https://staging.luma.gift/images/products/mt12-blue_main.jpg"
},
"msrp": {
"currency": "USD",
"value": 21.6,
"number": 2160,
"symbol": "$"
}
}
],
"shipping_info": {
"first_name": "John",
"last_name": "Smith",
"email": "john@example.com",
"phone": "(206) 555-1212",
"address1": "123 Main St",
"city": "Seattle",
"state_or_province": "WA",
"country": "US",
"postal_code": "98101"
},
"billing_info": {
"first_name": "John",
"last_name": "Smith",
"email": "john@example.com",
"phone": "(206) 555-1212",
"address1": "123 Main St",
"city": "Seattle",
"state_or_province": "WA",
"country": "US",
"postal_code": "98101"
},
"shipping_method": {
"id": "s2_2_day",
"description": "2-Day Shipping",
"price": {
"currency": "USD",
"value": 12,
"number": 1200,
"symbol": "$"
}
},
"payment_summary": {
"payment_type": "Klarna",
"attributes": {
"session_id": "kp_abc123def456",
"authorization_token": "klarna_auth_token_from_widget"
}
},
"total": {
"currency": "USD",
"value": 34,
"number": 3400,
"symbol": "$"
},
"sub_total": {
"currency": "USD",
"value": 18,
"number": 1800,
"symbol": "$"
},
"shipping_total": {
"currency": "USD",
"value": 12,
"number": 1200,
"symbol": "$"
},
"tax": {
"currency": "USD",
"value": 2,
"number": 200,
"symbol": "$"
},
"fees": [
{
"description": "Recycle fee",
"currency": "USD",
"value": 2,
"number": 200,
"symbol": "$"
}
],
"fee_total": {
"currency": "USD",
"value": 2,
"number": 200,
"symbol": "$"
},
"cart_discount": {
"currency": "USD",
"value": 0,
"number": 0,
"symbol": "$"
}
}

​​ Error Responses

Errors return a JSON body with code, error, and description. Program against the error value — descriptions are human-readable and may change.

400 — BadRequest

None of authorization_token, transaction_token or redirect_result was supplied, and the cart holds no authorization from a preceding Authorize call. Any one of the three is enough to pass — note the message names only the first two.


{ "code": 400, "error": "BadRequest", "description": "Missing Klarna authorization_token or transaction_token" }
412 — CheckoutError

Merchant-side checkout failure — payment info, billing address, or cart state was rejected.


{ "code": 412, "error": "CheckoutError", "description": "Payment info or billing address invalid." }
412 — MissingShippingMethod

A shipping method has not been selected on the cart yet.


{ "code": 412, "error": "MissingShippingMethod", "description": "Shipping method needs to be set." }
412 — MissingTaxSync

Cart taxes have not been calculated yet. Refresh the cart and retry.


{ "code": 412, "error": "MissingTaxSync", "description": "The taxes are not synced yet. Please refresh the cart and try again." }
422 — CreditCardDeclined

Klarna declined the payment. Ask the user for a different payment method.


{ "code": 422, "error": "CreditCardDeclined", "description": "Credit card declined" }
400 — InvalidToken

The x-firmly-authorization header is missing, empty, or not a well-formed JWT. Device-auth can also surface as MissingAuthHeader or PartnerNotFound; see Authentication errors for the full set.


{ "code": 400, "error": "InvalidToken", "description": "Jwt token is invalid." }
401 — InvalidJWTToken

The device JWT is well-formed but its signature does not verify, or required claims are missing.


{ "code": 401, "error": "InvalidJWTToken", "description": "Jwt token is invalid." }
404 — CartNotFound

No active cart exists for this device on this domain.


{ "code": 404, "error": "CartNotFound", "description": "Cart was not found." }
404 — DomainNotFound

The {domain} path parameter does not match any merchant configured with Firmly, or the merchant has been disabled.


{ "code": 404, "error": "DomainNotFound", "description": "This domain was not found in firmly servers." }
404 — GatewayNotFound

Klarna is not enabled as a payment gateway for this merchant. Check payment_method_options before offering it.


{ "code": 404, "error": "GatewayNotFound", "description": "Payment gateway 'klarna' not found" }
412 — OperationNotSupported

The merchant adapter does not implement Klarna express checkout.


{ "code": 412, "error": "OperationNotSupported", "description": "This operation is not supported for this store." }
503 — StoreUnavailable

The merchant’s own API was unavailable or timed out. Retry with backoff.


{ "code": 503, "error": "StoreUnavailable", "description": "Store temporarily unavailable. Please try again later." }
429 — RateLimited

Too many requests from this device. Back off and retry after the Retry-After window — see Rate Limits.


{ "code": 429, "error": "RateLimited", "description": "Too many requests. Please try again later." }