Winkelwagens & Checkout

Cartregels

Producten aan een cart toevoegen, regelhoeveelheden wijzigen en regels verwijderen, inclusief de regels voor varianten, made-to-measure-producten en decimale hoeveelheden.

Bekijk als Markdown

Cartregels bevatten de producten in een cart. Elke regel maakt bij het toevoegen een snapshot van de productnaam en SKU, slaat de bepaalde stukprijs op in minor units en, voor made-to-measure-producten, een volledige configuratiesnapshot. Alle drie de endpoints vereisen de scope commerce:write, een active cart, en doorlopen de cart-eigenaarschapscheck (zie de pagina Carts). Elk endpoint geeft de volledige cart-envelope terug, dezelfde vorm als GET /v1/api/commerce/carts/{id}.

Regels per capability

Hoe een product wordt toegevoegd hangt af van de capability (zie Producten):

  • standard-producten met actieve varianten: variant_id is verplicht en moet een actieve variant van het product zijn.
  • standard-producten zonder varianten: variant_id moet worden weggelaten.
  • made_to_measure-producten: configuration is verplicht en variant_id is niet toegestaan. De configuratie is een object {"dimensions": {...}, "choices": ["choice_id", ...]} dat door de configurator-engine wordt geprijsd; dimensies zijn gehele getallen. De regel slaat een config_hash op plus een volledige snapshot onder attributes.configuration (dimensions, choices, prijsuitsplitsing, componentenlijst, matrixcel). Componentvoorraad wordt per configurator-component gereserveerd.
  • Voor standard-producten is configuration niet toegestaan.
  • Een product waarvan capability_active false is, kan niet worden toegevoegd: de commerce-module verkoopt standard-producten en de configurator-module made_to_measure-producten.

Hoeveelheden

quantity is een JSON-getal groter dan nul met maximaal 8 cijfers voor de komma en maximaal 3 decimalen (maximum 99999999.999). Stuur het als JSON-getal of als gewone decimale string met een punt ("0.75"); een string met een decimale komma of een exponent ("0,75", "1e3") wordt geweigerd. Een product met unit piece accepteert alleen gehele getallen (2 of 2.0, nooit 2.5); een product in elke andere eenheid (kg, m2, hour, ...) accepteert tot drie decimalen, bijvoorbeeld 0.75. Hoeveelheden komen terug als JSON-getallen (0.75, 12). Een regeltotaal is de stukprijs maal de hoeveelheid, half naar boven afgerond op hele minor units.

Weigeringscodes

Wanneer een regel niet kan worden toegevoegd, bevat de 422-body een machineleesbare code op het hoogste niveau naast message en errors:

codeBetekenis
CAPABILITY_INACTIVEDe capability van het product kan nu niet verkocht worden (capability_active is false): de module die het verkoopt is voor de winkel uitgeschakeld. Gemeld op errors.product_id.
INVALID_CONFIGURATIONDe variant of configuratie past niet bij het product: een variant ontbreekt, is onbekend of niet toegestaan; een configuratie ontbreekt of is meegestuurd voor een standard-product; of de configurator-engine weigerde de configuratie (de foutkeys, bijvoorbeeld dimensions.width, worden doorgegeven).
NOT_PURCHASABLEHet product kan niet verkocht worden, bijvoorbeeld omdat er geen prijs voor te bepalen is. Gemeld op errors.product_id.
Response (422, line refusal)
{
  "message": "Width must be a whole number.",
  "errors": {
    "dimensions.width": ["Width must be a whole number."]
  },
  "code": "INVALID_CONFIGURATION"
}

Gewone invoervalidatie (een ontbrekende of ongeldige product_id of quantity, een onbekend of inactief product, een hoeveelheid met decimalen voor een piece-product) gebruikt de standaard 422-envelope zonder code. Branch op code wanneer die aanwezig is, en val anders terug op errors.

Regels dedupliceren op de combinatie van product, variant en configuratiehash: dezelfde combinatie opnieuw toevoegen wordt samengevoegd met de bestaande regel, waarbij de hoeveelheden worden opgeteld en de stukprijs opnieuw wordt bepaald op de nieuwe staffeltrede.

Stukprijzen worden bepaald op basis van de pricingcontext van de request: de klant geïdentificeerd door X-Customer-Token indien aanwezig, anders de aan de cart gebonden klant, anders guest pricing.

POST /v1/api/commerce/carts/{id}/lines

Voegt een product toe aan de cart, of voegt samen met een bestaande identieke regel. Geeft de volledige cart terug met status 201.

Parameters

Pad

NaamTypeVerplichtBeschrijving
idstring (UUID)jaCart-id. Moet een active cart zijn.

Body

NaamTypeVerplichtBeschrijving
product_idstring (UUID)jaHet toe te voegen product. Moet een actief product van de store zijn.
variant_idstring (UUID) of nullconditioneelVerplicht wanneer het product actieve varianten heeft; anders niet toegestaan, en altijd niet toegestaan voor made_to_measure-producten.
quantitynumberjaGroter dan nul, maximaal 3 decimalen; een geheel getal voor een piece-product (zie Hoeveelheden hierboven). De samengevoegde regelhoeveelheid mag max_quantity_per_line uit de policy niet overschrijden.
configurationobjectconditioneelVerplicht voor made_to_measure-producten, anders niet toegestaan. Vorm: {"dimensions": {...}, "choices": [choice_ids]}, met dimensies als gehele getallen. Gevalideerd door de configurator-engine.

Headers

NaamTypeVerplichtBeschrijving
X-Customer-TokenstringneeBepaalt de pricingcontext; vereist als de cart gebonden is aan een niet-guest klant.
Request
curl -X POST https://api.borkol.com/v1/api/commerce/carts/9d3f2a10-6b7c-4e6d-9f21-8a54c1d2e3f4/lines \
  -H "Authorization: Bearer {api_key}" \
  -H "Content-Type: application/json" \
  -d '{
    "product_id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
    "variant_id": "2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e",
    "quantity": 2
  }'
Request (JS)
const res = await fetch(
  `https://api.borkol.com/v1/api/commerce/carts/${cartId}/lines`,
  {
    method: "POST",
    headers: {
      Authorization: `Bearer ${apiKey}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      product_id: "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
      variant_id: "2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e",
      quantity: 2,
    }),
  }
);
const { data: cart } = await res.json();
Response
{
  "data": {
    "id": "9d3f2a10-6b7c-4e6d-9f21-8a54c1d2e3f4",
    "status": "active",
    "lines": [
      {
        "id": "5e6f7a8b-9c0d-4e1f-a2b3-c4d5e6f7a8b9",
        "product_id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
        "variant_id": "2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e",
        "name": "Garden Chair",
        "sku": "CHAIR-GRN-M",
        "quantity": 2,
        "unit_price_amount": 2250,
        "unit_price": { "amount": 2250, "currency": "EUR" },
        "line_total": { "amount": 4500, "currency": "EUR" },
        "attributes": null
      }
    ],
    "...": "same cart shape as GET /v1/api/commerce/carts/{id}"
  }
}

Voor een made_to_measure-product bevat de aangemaakte regel de configuratiesnapshot. components[].qty is een exacte decimale string per geconfigureerde eenheid (vermenigvuldig met de regelhoeveelheid voor de gereserveerde voorraad):

Response (made-to-measure line excerpt)
{
  "attributes": {
    "configuration": {
      "dimensions": { "width": 120, "depth": 180 },
      "choices": ["c1d2e3f4-..."],
      "breakdown": [
        { "label": "Base", "amount": 18900 },
        { "label": "Motor: Motorised", "amount": 7500 }
      ],
      "components": [{ "product_id": "...", "qty": "2.16" }],
      "matrix": { "id": "...", "name": "Fabric blinds" }
    }
  }
}

Fouten

Regelweigeringen zijn 422-fouten met de melding gekoppeld aan het betreffende veld in errors en een code op het hoogste niveau (zie Weigeringscodes hierboven):

StatusBodyWanneer
422errors.product_id: ["Product is not available."]Product onbekend of niet actief. Geen code.
422errors.product_id: ["Product is not available."], code: "NOT_PURCHASABLE"Het product bestaat en is actief maar kan niet verkocht worden, bijvoorbeeld omdat er geen prijs voor te bepalen is.
422errors.product_id: ["Product is not available."], code: "CAPABILITY_INACTIVE"De capability van het product is niet actief voor de winkel (capability_active is false).
422errors.variant_id: ["Choose a variant for this product."], code: "INVALID_CONFIGURATION"Product heeft actieve varianten en variant_id is weggelaten.
422errors.variant_id: ["Variant is not available."], code: "INVALID_CONFIGURATION"Variant-id herleidt niet naar een actieve variant van het product.
422errors.variant_id: ["This product has no variants."], code: "INVALID_CONFIGURATION"variant_id meegestuurd voor een product zonder varianten.
422errors.variant_id: ["Configurable products have no variants."], code: "INVALID_CONFIGURATION"variant_id meegestuurd voor een made_to_measure-product.
422errors.configuration: ["Configure this product before adding it."], code: "INVALID_CONFIGURATION"made_to_measure-product zonder een configuration.
422errors.configuration: ["This product is not configurable."], code: "INVALID_CONFIGURATION"configuration meegestuurd voor een standard-product.
422errors.choices, errors.choices.{choiceId}, errors.dimensions.{key}, errors.configuration, code: "INVALID_CONFIGURATION"Fouten van de configurator-engine, gekoppeld aan hun eigen veldkeys, exact zoals gedocumenteerd in de quote-foutcatalogus, inclusief {Label} must be a whole number. voor een dimensie met decimalen.
422errors.quantity: ["The quantity must be a whole number."]Hoeveelheid met decimalen voor een piece-product. Geen code.
422errors.quantity: ["..."]Hoeveelheid ontbreekt, is geen gewone decimaal (komma, exponent, meer dan 3 decimalen of 8 cijfers voor de komma) of is niet groter dan nul. Geen code.
422{"message": "Quantity exceeds the per-line maximum.", "code": "cart_constraint"}Samengevoegde hoeveelheid zou max_quantity_per_line overschrijden.
422{"message": "Cart line limit reached.", "code": "cart_constraint"}Een nieuwe afzonderlijke regel toevoegen zou max_lines overschrijden.
404{"message": "..."}Cart onbekend, verlopen of niet active.
403eigenaarschaps-, scope-, module- of schorsingsbodyZie de pagina Carts.
429{"message": "Too Many Attempts."}Rate limit overschreden.

PATCH /v1/api/commerce/carts/{id}/lines/{lineId}

Wijzigt de hoeveelheid van een regel, met dezelfde hoeveelheidsregels als bij toevoegen (een geheel getal voor een piece-product). Regels van niet-geconfigureerde producten worden opnieuw geprijsd op de nieuwe hoeveelheid (staffelprijzen) met de pricingcontext van de request. Geconfigureerde regels, en regels waarvan de variant inmiddels is gedeactiveerd, behouden hun opgeslagen stukprijs; onbeschikbaarheid komt pas bij checkout aan het licht. Geeft de volledige cart terug met status 200.

Parameters

Pad

NaamTypeVerplichtBeschrijving
idstring (UUID)jaCart-id. Moet een active cart zijn.
lineIdstring (UUID)jaRegel-id. Moet bij deze cart horen.

Body

NaamTypeVerplichtBeschrijving
quantitynumberjaGroter dan nul, maximaal 3 decimalen, een geheel getal voor een piece-product; maximaal max_quantity_per_line uit de policy.

Headers

NaamTypeVerplichtBeschrijving
X-Customer-TokenstringneeBepaalt de pricingcontext; vereist als de cart gebonden is aan een niet-guest klant.
Request
curl -X PATCH https://api.borkol.com/v1/api/commerce/carts/9d3f2a10-6b7c-4e6d-9f21-8a54c1d2e3f4/lines/5e6f7a8b-9c0d-4e1f-a2b3-c4d5e6f7a8b9 \
  -H "Authorization: Bearer {api_key}" \
  -H "Content-Type: application/json" \
  -d '{"quantity": 3}'
Response
{
  "data": {
    "id": "9d3f2a10-6b7c-4e6d-9f21-8a54c1d2e3f4",
    "lines": [{ "id": "5e6f7a8b-...", "quantity": 3, "...": "..." }],
    "...": "same cart shape as GET /v1/api/commerce/carts/{id}"
  }
}

Fouten

StatusBodyWanneer
422{"message": "...", "errors": {"quantity": ["..."]}}Ontbrekende of ongeldige hoeveelheid, niet groter dan nul, of met decimalen voor een piece-product. Dit endpoint antwoordt nooit met een weigerings-code: een regel die niet meer te bepalen is, houdt zijn prijs tot de checkout.
422{"message": "Quantity exceeds the per-line maximum.", "code": "cart_constraint"}Boven max_quantity_per_line.
404{"message": "..."}Cart onbekend of niet active, of de regel hoort niet bij deze cart.
403eigenaarschaps-, scope-, module- of schorsingsbodyZie de pagina Carts.
429{"message": "Too Many Attempts."}Rate limit overschreden.

DELETE /v1/api/commerce/carts/{id}/lines/{lineId}

Verwijdert een regel uit de cart en geeft eventuele voorraadreserveringen voor de cart vrij. Geeft de volledige cart terug, zonder de verwijderde regel, met status 200.

Parameters

Pad

NaamTypeVerplichtBeschrijving
idstring (UUID)jaCart-id. Moet een active cart zijn.
lineIdstring (UUID)jaRegel-id. Moet bij deze cart horen.

Geen body.

Request
curl -X DELETE https://api.borkol.com/v1/api/commerce/carts/9d3f2a10-6b7c-4e6d-9f21-8a54c1d2e3f4/lines/5e6f7a8b-9c0d-4e1f-a2b3-c4d5e6f7a8b9 \
  -H "Authorization: Bearer {api_key}"
Response
{
  "data": {
    "id": "9d3f2a10-6b7c-4e6d-9f21-8a54c1d2e3f4",
    "lines": [],
    "...": "same cart shape as GET /v1/api/commerce/carts/{id}"
  }
}

Fouten

StatusBodyWanneer
404{"message": "..."}Cart onbekend of niet active, of de regel hoort niet bij deze cart.
403eigenaarschaps-, scope-, module- of schorsingsbodyZie de pagina Carts.
429{"message": "Too Many Attempts."}Rate limit overschreden.