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 attributesAttributes
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 toauthorization_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 orderURLs
thank_you_page(string) — URL to the merchant’s order confirmation page
-
line_items(array) — Array of items in the orderLine Item Details
line_item_id(string) — Unique identifier for the line itemsku(string) — Product SKUquantity(number) — Quantity ordereddescription(string) — Product descriptionprice(object) — Unit priceline_price(object) — Total price for this line itemimage(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 paymentPayment Summary
payment_type(string) — Always"Klarna"for this gatewayattributes(object) — Klarna session details
Attributes
session_id(string) — Klarna payment session identifierauthorization_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 pageif (order.urls?.thank_you_page) {window.location.href = order.urls.thank_you_page;}
import requestsresponse = 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": "$"}}
Related Endpoints
- Start Klarna Checkout — Create Klarna session
- Authorize Klarna Checkout — Confirm authorization
- Complete Order (Credit Card) — Alternative credit card flow
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." }