Shopper

Domain for handling the shopper flow from cart to checkout

This domain depends on the Management domain, and will require additional configuration setup in order to proceed with the checkout and payment providers.

Backend-for-Frontend / Proxy

If you are using Shopper behind a backend-for-frontend or other proxy solution you will need to include some security headers for the shopper api to function properly.

Shopper API Key

These are x-shopper-api-key (see instructions below under Rate limiting) and x-forwarded-for.

X-Fowarded-For (Remote Client IP)

The x-forwarded-for should be set to the client's real IP. This is to ensure that WAF protection rules and other security features work as intended.

Rate limiting

The Shopper API utilizes rate limiting on an IP basis per default.

This measure is facilitated through the Brink WAF (Web Application Firewall) to ensure security for merchant integrations, thereby limiting the possibilities of script and bot attacks.

Rate limit values can be found in the Merchant Portal.

Shopper API Key (bypass IP-based rate limiting)

The Shopper API Key (via the x-shopper-api-key header) should be used for all integrations using BFF (Backend for Frontend) or similar reverse proxy where much traffic will come from the same client IP. This is to circumvent our IP-based rate limiting.

The Shopper API Key can be found in the Merchant Portal.

Starting a shopper session

In order to start a shopper session you need to supply us with a StoreGroupID, CountryCode & LanguageCode

POST /shopper/sessions/start
Content-Type: application/json

{
  "storeGroupId": "brinkcommerce",
  "countryCode": "SE",
  "languageCode": "sv"
}

This will create a session containing a cart, and a token (JWT) that is required for subsequent calls to e.g. adding items to the session. It will also include the available capabilities configured for a specific StoreMarket in Store Management

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJicmlua2NvbW1lcmNlLXNob3BwZXIiLCJleHAiOjE2Nzg5NjE5NzQsImlhdCI6MTY3NjM2OTk3NCwianRpIjoiNTk3MDQ3YzktZTU4OS00NzJjLWFiMmItNWViNTY0ZDY4NzZiIiwic2Vzc2lvbklkIjoiNTk3MDQ3YzktZTU4OS00NzJjLWFiMmItNWViNTY0ZDY4NzZiIiwic3RvcmVHcm91cElkIjoiYnJpbmtjb21tZXJjZSIsImNvdW50cnlDb2RlIjoiU0UiLCJjdXJyZW5jeUNvZGUiOiJTRUsiLCJsYW5ndWFnZUNvZGUiOiJzdiIsImlzVGF4SW5jbHVkZWRJblByaWNlIjoidHJ1ZSJ9.fkjdJ2N6HxYZF1UxKQzZ_TGcuR6voJGL9r9kM9fh6xo",
  "cart": {
    "id": "b9077fb9-4752-50ea-8a1c-2e6f42658af3",
    "storeGroupId": "brinkcommerce",
    "countryCode": "SE",
    "currencyCode": "SEK",
    "languageCode": "sv",
    "isTaxIncludedInPrice": true,
    "discountCodes": [],
    "created": "2023-02-14T10:19:34.623042807Z",
    "updated": "2023-02-14T10:19:34.623042807Z",
    "discountAmount": 0,
    "revision": 1,
    "items": [],
    "totals": { "subTotal": 0, "taxTotal": 0, "discountTotal": 0, "grandTotal": 0 }
  },
  "capabilities": {
    "paymentProviders": [
      { "id": "adyen-test", "name": "Adyen" },
      { "id": "kco-test", "name": "KlarnaCheckout" }
    ],
    "shippingProviders": [{ "id": "ingrid-test", "name": "Ingrid" }]
  }
}

Updating the shopper session

In order to update a started session you need to send the token received from the start request as a Bearer token in future requests

POST /shopper/sessions/items
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJicmlua2NvbW1lcmNlLXNob3BwZXIiLCJleHAiOjE2Nzg5NjA2ODAsImlhdCI6MTY3NjM2ODY4MCwianRpIjoiMzc3NWVlM2MtOGExZS00MGIzLWI0MDYtZTM5YWViZjliODMxIiwic2Vzc2lvbklkIjoiMzc3NWVlM2MtOGExZS00MGIzLWI0MDYtZTM5YWViZjliODMxIiwic3RvcmVHcm91cElkIjoiYnJpbmtjb21tZXJjZSIsImNvdW50cnlDb2RlIjoiU0UiLCJjdXJyZW5jeUNvZGUiOiJTRUsiLCJsYW5ndWFnZUNvZGUiOiJzdiIsImlzVGF4SW5jbHVkZWRJblByaWNlIjoidHJ1ZSJ9.upq9QN4MqWjzfYM-BxmrBhtUu2Lm0gHbpJ2k1zWjq6I

{
  "productVariantId": "t-shirt-1.S",
  "quantity": 1
}
{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJicmlua2NvbW1lcmNlLXNob3BwZXIiLCJleHAiOjE2Nzg5NjE5NzQsImlhdCI6MTY3NjM2OTk3NCwianRpIjoiNTk3MDQ3YzktZTU4OS00NzJjLWFiMmItNWViNTY0ZDY4NzZiIiwic2Vzc2lvbklkIjoiNTk3MDQ3YzktZTU4OS00NzJjLWFiMmItNWViNTY0ZDY4NzZiIiwic3RvcmVHcm91cElkIjoiYnJpbmtjb21tZXJjZSIsImNvdW50cnlDb2RlIjoiU0UiLCJjdXJyZW5jeUNvZGUiOiJTRUsiLCJsYW5ndWFnZUNvZGUiOiJzdiIsImlzVGF4SW5jbHVkZWRJblByaWNlIjoidHJ1ZSJ9.fkjdJ2N6HxYZF1UxKQzZ_TGcuR6voJGL9r9kM9fh6xo",
  "cart": {
    "id": "b9077fb9-4752-50ea-8a1c-2e6f42658af3",
    "storeGroupId": "brinkcommerce",
    "countryCode": "SE",
    "currencyCode": "SEK",
    "languageCode": "sv",
    "isTaxIncludedInPrice": true,
    "discountCodes": [],
    "created": "2023-02-14T10:19:34.623042807Z",
    "updated": "2023-02-14T10:19:34.623042807Z",
    "discountAmount": 0,
    "revision": 2,
    "items": [
      {
        "id": "2a566bf4-997f-49ad-b924-0fda42ebafdd",
        "productVariantId": "t-shirt-1.S",
        "productParentId": "t-shirt-1",
        "quantity": 1,
        "name": "T-Shirt",
        "displayName": "T Shirt",
        "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi ac lorem efficitur, interdum justo ac, fermentum metus. Pellentesque porttitor sit amet ipsum ut blandit. Duis quis sagittis lorem. Praesent venenatis hendrerit nunc luctus commodo",
        "displayDescription": "Suspendisse a porta diam, at congue metus. Nam sollicitudin augue lorem, id elementum massa luctus id. Phasellus facilisis ex sed massa posuere, ut dapibus erat fringilla. Ut mauris orci, consequat sit amet arcu vitae, ullamcorper fringilla sapien. Sed ac nunc ante.",
        "taxGroupId": "apparel",
        "basePriceAmount": 50000,
        "salePriceAmount": 50000,
        "discountAmount": 0,
        "taxPercentage": 2500,
        "taxPercentageDecimals": 2,
        "imageUrl": "http://P.wrihNyaaIjjzulhV+YBiPl,RsEHnqO2kTiReoG,hWqWT",
        "customAttributes": [
          { "key": "color", "value": "black" },
          { "key": "size", "value": "S" }
        ],
        "tags": [
          { "key": "category", "value": "t-shirt" },
          { "key": "size", "value": "S" }
        ],
        "created": "2023-02-14T10:19:34.943357529Z",
        "updated": "2023-02-14T10:19:34.943357529Z",
        "revision": 1,
        "totalDiscountAmount": 0,
        "totalPriceAmount": 50000,
        "totalTaxAmount": 10000
      }
    ],
    "totals": { "subTotal": 50000, "taxTotal": 10000, "discountTotal": 0, "grandTotal": 50000 }
  },
  "capabilities": {
    "paymentProviders": [
      { "id": "adyen-test", "name": "Adyen" },
      { "id": "kco-test", "name": "KlarnaCheckout" }
    ],
    "shippingProviders": [{ "id": "ingrid-test", "name": "Ingrid" }]
  }
}

Starting a checkout from a session

In order to start a checkout attempt you will need to supply us with the desired capabilities to use that's available from the current session.

POST /shopper/sessions/checkout/start
Content-Type: application/json
Authorization:

{
  "paymentProvider": { "name":"KlarnaCheckout", "id":"kco-test" },
  "shippingProvider": { "name":"Ingrid", "id":"ingrid-test" }
}

This will return a checkout that contains a new token (JWT) and a snapshot of the current session items and evaluated discount rules

A Brink Session can have multiple Brink Checkout attempts
{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJicmlua2NvbW1lcmNlLXNob3BwZXIiLCJleHAiOjE2Nzg5NjIwNTgsImlhdCI6MTY3NjM3MDA1OCwianRpIjoiNTk3MDQ3YzktZTU4OS00NzJjLWFiMmItNWViNTY0ZDY4NzZiIiwic2Vzc2lvbklkIjoiNTk3MDQ3YzktZTU4OS00NzJjLWFiMmItNWViNTY0ZDY4NzZiIiwic3RvcmVHcm91cElkIjoiYnJpbmtjb21tZXJjZSIsImNvdW50cnlDb2RlIjoiU0UiLCJjdXJyZW5jeUNvZGUiOiJTRUsiLCJsYW5ndWFnZUNvZGUiOiJzdiIsImlzVGF4SW5jbHVkZWRJblByaWNlIjoidHJ1ZSIsImNoZWNrb3V0SWQiOiJlYzQxY2JiMi05NjNhLTQ0MDItYmVmNC05YTQxYWRlZDlkODcifQ.Tro0ef9z0OLcLxTLeg-pUY1r_qrffoaOhgQiK0OesjE",
  "checkout": {
    "id": "ec41cbb2-963a-4402-bef4-9a41aded9d87",
    "sessionId": "597047c9-e589-472c-ab2b-5eb564d6876b",
    "cartRevision": 2,
    "storeGroupId": "brinkcommerce",
    "countryCode": "SE",
    "currencyCode": "SEK",
    "languageCode": "sv",
    "discountCodes": [],
    "isTaxIncludedInPrice": true,
    "created": "2023-02-14T10:20:58.712402549Z",
    "updated": "2023-02-14T10:20:58.712402549Z",
    "items": [
      {
        "id": "2a566bf4-997f-49ad-b924-0fda42ebafdd",
        "productVariantId": "t-shirt-1.S",
        "productParentId": "t-shirt-1",
        "quantity": 1,
        "name": "T-Shirt",
        "displayName": "T Shirt",
        "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi ac lorem efficitur, interdum justo ac, fermentum metus. Pellentesque porttitor sit amet ipsum ut blandit. Duis quis sagittis lorem. Praesent venenatis hendrerit nunc luctus commodo",
        "displayDescription": "Suspendisse a porta diam, at congue metus. Nam sollicitudin augue lorem, id elementum massa luctus id. Phasellus facilisis ex sed massa posuere, ut dapibus erat fringilla. Ut mauris orci, consequat sit amet arcu vitae, ullamcorper fringilla sapien. Sed ac nunc ante.",
        "taxGroupId": "apparel",
        "basePriceAmount": 50000,
        "salePriceAmount": 50000,
        "discountAmount": 0,
        "totalPriceAmount": 50000,
        "totalTaxAmount": 10000,
        "taxPercentage": 2500,
        "totalDiscountAmount": 0,
        "taxPercentageDecimals": 2,
        "imageUrl": "http://P.wrihNyaaIjjzulhV+YBiPl,RsEHnqO2kTiReoG,hWqWT",
        "customAttributes": [
          { "key": "color", "value": "black" },
          { "key": "size", "value": "S" }
        ],
        "tags": [
          { "key": "category", "value": "t-shirt" },
          { "key": "size", "value": "S" }
        ]
      }
    ],
    "shippingOptions": [],
    "discountAmount": 0,
    "capabilities": {
      "paymentProvider": { "id": "kco-test", "name": "KlarnaCheckout" },
      "shippingProvider": {
        "id": "ingrid-test",
        "name": "Ingrid",
        "config": { "baseUrl": "https://api-stage.ingrid.com" }
      }
    },
    "totals": { "subTotal": 50000, "taxTotal": 10000, "discountTotal": 0, "shippingTotal": 0, "grandTotal": 50000 }
  }
}

Checkout capabilities

Now in order to interact with the started checkout attempt you need to use the new checkout token for the specific provider APIs.

For instance ShopperIngrid, and ShopperKlarnaCheckout

In our example above we started our checkout with the shipping provider Ingrid, so we start an Ingrid session connected to the Brink Checkout

POST /shopper-ingrid/sessions/create
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJicmlua2NvbW1lcmNlLXNob3BwZXIiLCJleHAiOjE2Nzg5NjIwNTgsImlhdCI6MTY3NjM3MDA1OCwianRpIjoiNTk3MDQ3YzktZTU4OS00NzJjLWFiMmItNWViNTY0ZDY4NzZiIiwic2Vzc2lvbklkIjoiNTk3MDQ3YzktZTU4OS00NzJjLWFiMmItNWViNTY0ZDY4NzZiIiwic3RvcmVHcm91cElkIjoiYnJpbmtjb21tZXJjZSIsImNvdW50cnlDb2RlIjoiU0UiLCJjdXJyZW5jeUNvZGUiOiJTRUsiLCJsYW5ndWFnZUNvZGUiOiJzdiIsImlzVGF4SW5jbHVkZWRJblByaWNlIjoidHJ1ZSIsImNoZWNrb3V0SWQiOiJlYzQxY2JiMi05NjNhLTQ0MDItYmVmNC05YTQxYWRlZDlkODcifQ.Tro0ef9z0OLcLxTLeg-pUY1r_qrffoaOhgQiK0OesjE

{
  "ingrid": {
    "locales": ["sv-SE", "en-US"]
  }
}

And continuing from our example we need to create a Klarna Checkout Order for our Brink Checkout

POST /shopper-kco/orders
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJicmlua2NvbW1lcmNlLXNob3BwZXIiLCJleHAiOjE2Nzg5NjIwNTgsImlhdCI6MTY3NjM3MDA1OCwianRpIjoiNTk3MDQ3YzktZTU4OS00NzJjLWFiMmItNWViNTY0ZDY4NzZiIiwic2Vzc2lvbklkIjoiNTk3MDQ3YzktZTU4OS00NzJjLWFiMmItNWViNTY0ZDY4NzZiIiwic3RvcmVHcm91cElkIjoiYnJpbmtjb21tZXJjZSIsImNvdW50cnlDb2RlIjoiU0UiLCJjdXJyZW5jeUNvZGUiOiJTRUsiLCJsYW5ndWFnZUNvZGUiOiJzdiIsImlzVGF4SW5jbHVkZWRJblByaWNlIjoidHJ1ZSIsImNoZWNrb3V0SWQiOiJlYzQxY2JiMi05NjNhLTQ0MDItYmVmNC05YTQxYWRlZDlkODcifQ.Tro0ef9z0OLcLxTLeg-pUY1r_qrffoaOhgQiK0OesjE

{
  "klarna": {
    "merchant_urls": {
      "terms": "https://example.com/terms",
      "checkout": "https://example.com/checkout/klarnacheckout",
      "confirmation": "https://example.com/checkout/klarnacheckout/confirmation"
    }
  }
}
Last updated on 2024/9/30