3. Place the order (server-side)

You complete this step leveraging the Instant Shopping Button Keys REST API from your server-side

When the consumer has chosen to finalize the purchase, our server-side will ping you at the merchant_urls.place_order from our server-side, and prompt you to place the order for a specific authorization_token. Remember that the URL for this endpoint has been defined in the [first step]((/documentation/instant-shopping/integration-guide/onsite/1-obtain-button-key) when you created this button key.

You will place the order through our REST API, and will be notified immediately about the successful or failed order placement. So you are able at this point already to create the order within your system.

You can choose to deny the purchase and in this case provide a deny reason and/or a URL to redirect the consumer to.

Note: Read about Klarna’s API URLs to know the base URL, and about Authentication to know how to authenticate when calling our REST API. More detailed documentation on the Instant Shopping orders API is available in the API documentation .

Request prompt for placing Order

During this request we make available to you both the authorization_token to use next for placing the order, but also the details of the authorized order. Below you see an example of how the Request Body looks.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
POST https://example.com/placeOrder.php
Content-Type: application/json
{
    "authorization_token": "a2be5f86-e505-4c6b-8d2c-bebdda7f5956",
    "order" : {
      "integrator_url": "https://example.com/products/an-awesome-product.php",
      "purchase_country": "SE",
      "purchase_currency": "SEK",
      // ...
      "order_amount": 16900,
      "order_tax_amount": 3380,
      "order_lines": [{
        "type": "physical",
        "reference": "19-402",
        "name": "Battery Power Pack",
        "quantity": 1,
        "unit_price": 11900,
        "tax_rate": 2500,
        "total_amount": 11900,
        "total_discount_amount": 0,
        "total_tax_amount": 2380,
        "product_url": "https://www.example.com/products/f2a8d7e34",
        "image_url": "https://www.example.com/products/f2a8d7e34"
      }, {
        "type": "shipping_fee",
        "reference": "express_priority",
        "name": "EXPRESS 1-2 Days",
        "quantity": 1,
        "unit_price": 5000,
        "tax_rate": 2500,
        "total_amount": 5000,
        "total_tax_amount": 1000
      }],
      // ... the rest of the authorized order information
    }
}

At this point it is expected that you perform all validations necessary on your side (stock, shipping capabilities, prices, etc.) and decide whether to approve or reject the order.

It is important that before you return a response to this request, you need to deny or accept the order by informing us accordingly through our API. The response HTTP status can be either of 200, 202 or 204.

Deny the order

If you need to deny the purchase you need to perform a DELETE call though our API and provide some information in the request body. Note that you need to use your API credentials to authenticate.

Below you may find examples of how deny requests may look:

1. Deny order request with code:

1
2
3
4
5
6
7
DELETE /instantshopping/v1/authorizations/{authorization_token}
Authorization: Basic pwhcueUff0MmwLShJiBE9JHA==
Content-Type: application/json
{
  "deny_code": "address_error",
  "deny_message": "We cannot ship at this address."
}

2. Deny order request with predefined code:

1
2
3
4
5
6
DELETE /instantshopping/v1/authorizations/{authorization_token}
Authorization: Basic pwhcueUff0MmwLShJiBE9JHA==
Content-Type: application/json
{
  "deny_code": "address_error"
}

3. Deny order request with own code and message:

1
2
3
4
5
6
7
DELETE /instantshopping/v1/authorizations/{authorization_token}
Authorization: Basic pwhcueUff0MmwLShJiBE9JHA==
Content-Type: application/json
{
  "deny_code": "other",
  "deny_message": "Some other reason for rejecting the order"
}

You can specify a deny_redirect_url only, or a deny_code and deny_message.

  • If you specify a deny_redirect_url then we will redirect the consumer to this page and do not show any information dialog within the Instant Shoppingy Button flow.
  • If you specify a deny_code and deny_message we will use those to show a more detailed message to the consumer regarding the denial.
  • If you do not specify a body we will show a generic message to the consumer notifying them that the purchase is denied by the merchant.

The acceptable values for deny_code are:

  • address_error when there are problems with the provided address,
  • item_out_of_stock when the item has gone out of stock,
  • consumer_underaged when the product has limitations based on the age of the consumer,
  • unsupported_shipping_address when there are problems with the shipping address. You don’t need to specify a deny_message for the above codes.
  • other for which you may specify a deny_message which will be shown to the consumer. It is important that the language of the message matches the locale of the Instant Shopping flow.

The successful response look like below:

1
HTTP 204 No-Content

Place the order

If you accept the order, then you need to place the order with our REST API. You do so by performing an HTTP POST in our API for the specific authorization_token and passing to the request body the complete Order. Note that you need to use your API credentials to authenticate.

Place order request

This is an example of how the Request could look like. Note that potential shipping fees are included in the order_lines object.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
POST /instantshopping/v1/authorizations/{authorization_token}/orders
Authorization: Basic pwhcueUff0MmwLShJiBE9JHA==
Content-Type: application/json
{
  "purchase_country": "SE",
  "purchase_currency": "SEK",
  "locale": "sv-SE",
  "merchant_urls": {
    "confirmation": "https://www.example.com/upsell.php", // mandatory if not given at step #3, this value will ovewrite the one set through button generation
    "push": "https://www.example.com/klarna-completed-orders", // optional, will overwrite the existing value if already set through button generation
    "notification": "https://www.example.com/klarna-pending-orders" // optional, will overwrite the existing value if already set through button generation
  },
  "billing_address": {
    "given_name": "John",
    "family_name": "Doe",
    "email": "john.doe@example.com",
    "street_address": "Sveavägen 46",
    "postal_code": "11134",
    "city": "Stockholm",
    "phone": "+460700020020",
    "country": "SE"
  },
  "customer": {
    "date_of_birth": "1985-10-20",
    "gender": "male"
  },
  "order_amount": 16900,
  "order_tax_amount": 3380,
  "order_lines": [{
    "type": "physical",
    "reference": "19-402",
    "name": "Battery Power Pack",
    "quantity": 1,
    "unit_price": 11900,
    "tax_rate": 2500,
    "total_amount": 11900,
    "total_discount_amount": 0,
    "total_tax_amount": 2380,
    "product_url": "https://www.example.com/products/f2a8d7e34",
    "image_url": "https://www.example.com/products/f2a8d7e34"
  }, {
    "type": "shipping_fee",
    "reference": "express_priority",
    "name": "EXPRESS 1-2 Days",
    "quantity": 1,
    "unit_price": 5000,
    "tax_rate": 2500,
    "total_amount": 5000,
    "total_tax_amount": 1000
  }],
  "merchant_reference1": "45aa52f387871e3a210645d4" // optional
}

The response of the order placement endpoint may be success or failure.

Success response when placing order

1
2
3
4
5
6
HTTP 200 Success
Content-Type: application/json
{
  "order_id": "41475c53-b38e-427e-ade1-db78e3018e19",
  "fraud_status": "ACCEPTED"
}

Pending Order

Instead of immediately accepting the order, it may happen that Klarna flags this transaction for additional review. This is indicated if the fraud_status is PENDING. An order marked as PENDING is subject to manual review which may result in getting rejected. Therefore we advise that you handle those orders carefully and mark them as pending within your internal systems too. Read more about what to do next in our section about pending orders . When it comes to the Instant Shopping flow, the consumer will have been informed of a successful purchase even in this case. This means that you will need to contact them only if the order fails to go through.

Failure response when placing order

1
2
3
4
5
6
HTTP 400 Bad Request
Content-Type: application/json
{
  "error_code": "bad_value",
  "error_message": "bad_value:locale"
}

Other possible error statuses are:

  • HTTP 400 It was not possible to create an order with the provided data because some field constraint was violated.
  • HTTP 401 You were not authorized to execute this operation. Check your authentication credentials.
  • HTTP 403 This order authorization token is invalid or you are not allowed to use it.
  • HTTP 404 The order authorization token used does not correspondes to an authorized order.authorization token.

Get the authorized order

You can use the authorization_token to fetch the complete order authorization information before placing the order. Note that you need to use your API credentials to authenticate.

Request to GET Authorized Order

1
2
3
GET /instantshopping/v1/authorizations/{authorization_token}
Authorization: Basic pwhcueUff0MmwLShJiBE9JHA==
Content-Type: application/json

What’s next?

As soon as the order is approved and the purchase is completed the consumer will be redirected to a post-purchase page of your choice. See how next .