External prices

How to manage prices via external services

Sometimes, you can decide not to manage prices within Commerce Layer but use an external service instead. You may want to do that in order to support more dynamic pricing or just leverage an existing service that you want to keep as your system of records.

Fetching external prices

curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/line_items' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
  "data": {
    "type": "line_items",
    "attributes": {
      "quantity": 2,
      "sku_code": "TSHIRTMM000000FFFFFFXLXX",
      "_external_price": true
    },
    "relationships": {
      "order": {
        "data": {
          "type": "orders",
          "id": "QWERtyUpBa"
        }
      }
    }
  }
}'

Upon line item creation, Commerce Layer triggers a POST request to the specified external_prices_url endpoint, sending the line item payload (including the order) in the request body.

Request

The request payload is a JSON:API-compliant object you can query to perform your own computation. Aside from the target resourceline_items in this specific case — some relationships are also included to avoid useless API roundtrips:

  • order

  • order.customer

  • order.customer.tags

  • order.line_items

  • order.market

  • item

{
  "data": {
    "id": "xYZkjABcde",
    "type": "line_items",
    "links": { ... },
    "attributes": {
      "quantity": 2,
      "sku_code": "TSHIRTMM000000FFFFFFXLXX",
      "_external_price": true
    },
    "relationships": { ... },
    "meta": { ... }
  },
  "included": [
    {
      "id": "wBXVhKzrnq",
      "type": "orders",
      "links": { ... },
      "attributes": { ... },
      "relationships": { ... },
      "meta": { ... }
    },
    {
      "id": "bGvCXzYgNB",
      "type": "customers",
      "links": { ... },
      "attributes": { ... },
      "relationships": { ... },
      "meta": { ... }
    },
    {
      "id": "YawgnfmKad",
      "type": "tags",
      "links": { ... },
      "attributes": { ... },
      "relationships": { ... },
      "meta": { ... }
    },
    {
      "id": "hJnnKTGfRd",
      "type": "line_items",
      "links": { ... },
      "attributes": { ... },
      "relationships": { ... },
      "meta": { ... }
    },
    {
      "id": "DvlGRmhdgX",
      "type": "markets",
      "links": { ... },
      "attributes": { ... },
      "relationships": { ... },
      "meta": { ... }
    },
    {
      "id": "XGZwpOSrWL",
      "type": "skus",
      "links": { ... },
      "attributes": { ... },
      "relationships": { ... },
      "meta": { ... }
    }
  ]
}

In case the call to your external endpoint goes timeout, responds with an internal server error, or is blocked by the open circuit breaker, the API responds with a 422 status code by using the response error message. The circuit breaker internal counter (if closed) is incremented.

Response

Your service response (or error) must match the format described in the example below.

Example

The successful response must be a JSON object, returning the unit price computed by the external logic and the SKU code of the related product, along with some additional information and metadata:

{
  "success": true,
  "data": {
    "sku_code": "TSHIRTMM000000FFFFFFXLXX",
    "unit_amount_cents": 4900,
    "metadata": {
      "foo": "bar"
    }
  }
}

If needed, you can specify in the response also the compare_at_amount_cents of the price, which should be greater than the unit_amount_cents. If not (i.e. if it's not specified or lower than the unit amount) it will be automatically set as equal to the unit_amount_cents.

SKUs availability

When you fetch a list of SKUs with a sales channel, you only get those SKUs that have a price defined in the market's price list and at least a stock item in one of the market stock locations.

In case you manage prices externally, the price filter is not considered.

Security

When you activate external prices, a shared secret is generated at the market level. We recommend verifying the callback authenticity by signing the payload with that shared secret and comparing the result with the callback signature header.

pageCallbacks security

Last updated