Dealer API · v1

API-documentatie

De OrangeHub dealer-API levert per dealer een actuele, verrijkte catalogus van Orange Office producten — met dealer-specifieke nettoprijzen.

Base URL
https://orangehub.cyboxlabs.nl/api/v1
Auth
Bearer token
Format
JSON

Authenticatie

Elke request vereist een persoonlijke Sanctum-toegangstoken in de Authorization-header. Tokens worden door een OrangeHub-beheerder aangemaakt in het admin-panel onder de dealer (API-tokens → Genereer token). De plain-text token wordt eenmalig getoond; bij verlies moet er een nieuw token worden gegenereerd.

http
GET https://orangehub.cyboxlabs.nl/api/v1/products HTTP/1.1
Authorization: Bearer <plain-text-token>
Accept: application/json
Foutsituatie Status Body
Geen of foutief token 401 {"message":"Unauthenticated."}
Ingetrokken token 401 {"message":"Unauthenticated."}
Dealer gedeactiveerd 401 {"message":"Dealer is not active."}
GET /products

Gepagineerde lijst van actieve producten — inclusief verrijking, afbeeldingen, documenten en dealer-specifieke nettoprijs.

Parameters

Naam Type Default Toelichting
product_group_id int Filter op productgroep (lokaal id).
per_page int 50 Tussen 1 en 200.
page int 1 Standaard Laravel-paginering.

cURL

bash
curl -s \
  -H "Authorization: Bearer $TOKEN" \
  -H "Accept: application/json" \
  "https://orangehub.cyboxlabs.nl/api/v1/products?per_page=10"

Voorbeeldrespons

json
{
  "data": [
    {
      "external_id": "DVD",
      "sku": "DVD",
      "name": "Kabel doorvoerdop boormaat Ø 60mm",
      "description": "<p>...</p>",
      "manufacturer": "Orange Office",
      "currency": "EUR",
      "parent_sku": null,
      "prices": { "base": 19.0, "override": null, "net": 16.15 },
      "dimensions": { "length_mm": 72, "width_mm": 72, "height_mm": 19 },
      "weight_grams": 50,
      "enriched_content": "<p>...</p>",
      "product_group": {
        "external_id": "OO-cat-1318",
        "name": "Losse componenten",
        "parent_id": 1
      },
      "images": [
        {
          "url": "https://.../storage/products/12/images/DVD-1.jpg",
          "alt_text": null,
          "sort_order": 0,
          "is_primary": true
        }
      ],
      "documents": [
        {
          "url": "https://.../storage/products/12/documents/handleiding.pdf",
          "label": "Handleiding",
          "original_filename": "handleiding.pdf",
          "sort_order": 0
        }
      ],
      "custom_fields": {
        "eu_energy_label": { "value": "A++", "label": "EU Energielabel", "type": "text", "unit": null },
        "power_draw":      { "value": 1500,  "label": "Vermogen",      "type": "integer", "unit": "W" }
      }
    }
  ],
  "links": { "first": "...", "last": "...", "prev": null, "next": "..." },
  "meta": { "current_page": 1, "per_page": 50, "total": 30, "last_page": 1 }
}
GET /products/{sku}

Eén product opvragen via zijn SKU. Identieke shape als één element uit /products, maar dan onder data.

Parameters

Naam Type Default Toelichting
sku string SKU van het product (mag forward slashes bevatten).

cURL

bash
curl -s \
  -H "Authorization: Bearer $TOKEN" \
  -H "Accept: application/json" \
  "https://orangehub.cyboxlabs.nl/api/v1/products/DVD"

Voorbeeldrespons

json
{
  "data": {
    "external_id": "DVD",
    "sku": "DVD",
    "name": "Kabel doorvoerdop boormaat Ø 60mm",
    "prices": { "base": 19.0, "override": null, "net": 16.15 },
    "...": "..."
  }
}

Foutresponses

Foutsituatie Status Body
SKU onbekend 404 {"message":"Product not found."}
SKU bestaat, maar product staat niet op Actief in dealer-API 404 {"message":"Product is not available in the dealer-API."}
GET /product-groups

De volledige productgroep-boom — alleen root-groepen op het hoogste niveau, met children recursief.

cURL

bash
curl -s \
  -H "Authorization: Bearer $TOKEN" \
  -H "Accept: application/json" \
  "https://orangehub.cyboxlabs.nl/api/v1/product-groups"

Voorbeeldrespons

json
{
  "data": [
    {
      "external_id": "OO-cat-25",
      "name": "Werkplekken",
      "parent_id": null,
      "children": [
        {
          "external_id": "OO-cat-1318",
          "name": "Losse componenten",
          "parent_id": 7,
          "children": []
        }
      ]
    }
  ]
}

Pricing

Elk product bevat een prices-object met de basis-, override- en dealer-specifieke nettoprijs.

Sleutel Bron
base base_price uit de feed.
override price_override als een beheerder die handmatig heeft gezet, anders null.
net Effectieve prijs (override of base) minus de dealer-korting die voor het product van toepassing is (productgroep-regel als die bestaat, anders de dealer-brede basis-korting).
formule
effective = override ?? base
discount  = product_group_rule ?? dealer.base_discount_percentage
net       = round(effective * (1 - discount / 100), 2)

De toegepaste korting wordt in deze volgorde bepaald: bestaat er voor de productgroep van het product een DealerDiscount-regel, dan wint die — ook als hij lager is dan de basis-korting. Anders gebruikt de API de base_discount_percentage van de dealer (default 0). Inactieve producten (is_active = false) verschijnen nooit in de API-uitvoer.

Custom fields

Naast de vaste velden kan een beheerder per product ad-hoc extra eigenschappen vastleggen. Die komen terug onder custom_fields als een object met dynamische sleutels — de sleutels verschillen per product, dus programmeer er defensief op. Als een product geen extra velden heeft is het object leeg ({}).

Sleutel per veld Toelichting
value De typed waarde — een string, integer, decimaal, boolean of null.
label Mens-leesbare naam van het veld, door de beheerder ingegeven.
type Eén van text, long_text, integer, decimal, boolean, select.
unit Optionele eenheid/suffix (bv. "kg", "kWh"), of null.

De volgorde van keys in custom_fields reflecteert de volgorde die in het admin-panel is bepaald.