Feed zamówień
Feed zamówień umożliwia merchantowi przesyłanie danych zamówień do silnika rekomendacji OpenApp. Dla każdego zamówienia feed zawiera zakupiony koszyk - id produktu, ean, ilości i ceny - oraz identyfikator użytkownika, który je złożył.
Zamówienia złożone przez checkout OpenApp są automatycznie przekazywane do silnika rekomendacji. Wysyłanie ich również przez ten feed jest zbędne - ponowne wysłanie orderId zastępuje zapisane zamówienie, więc nie powoduje żadnych szkód, ale nie przynosi też żadnych korzyści. Feed służy do zamówień z innych kanałów sprzedaży (własny checkout w sklepie internetowym, aplikacja mobilna, sklepy stacjonarne).
Po początkowym pobraniu katalogu OpenApp potrzebuje czasu na przetworzenie danych, zanim pobieranie zamówień i rekomendacji stanie się dostępne. Do zakończenia przetwarzania endpoint odpowiada 409 RecommendationsNotReadyException. Przed rozpoczęciem uzupełniania danych należy poczekać na potwierdzenie od OpenApp.
Ten sam endpoint obsługuje dwa wzorce użycia:
- Początkowe uzupełnienie danych: po aktywacji prześlij historię zamówień w batchach (zalecamy co najmniej ostatnie 12 miesięcy), aby zapewnić silnikowi punkt startowy. Nie uwzględniaj anulowanych zamówień w początkowym uzupełnieniu - przesyłaj anulowania wyłącznie dla zamówień, które zostały wcześniej przekazane do feedu.
- Bieżący feed: przesyłaj nowe zamówienia w miarę ich składania, pojedynczo lub w periodycznych batchach (np. co godzinę).
Żądanie
Zamówienia są przesyłane żądaniem POST do następującego endpointu:
POST {{OpenAppUrl}}/merchant/v1/recommendations/orders
Pojedyncze żądanie może zawierać co najwyżej 100 zamówień.
- Żądanie
- Schemat
{
"orders": [
{
"orderId": "WS1213ASDZXC231A",
"loggedUser": "user-id-from-webshop",
"createdAt": "2026-06-09T17:23:00.000Z",
"channel": "WEB",
"currency": "PLN",
"products": [
{
"id": "id123-red",
"ean": "5901234123457",
"quantity": 2,
"unitPrice": 6000,
"linePrice": 12000
},
{
"id": "id124",
"ean": "5901234123464",
"quantity": 1,
"unitPrice": 6000,
"linePrice": 6000
}
]
},
{
"orderId": "WS1213ASDZXC231B",
"loggedUser": "user-id-from-webshop",
"status": "CANCELLED",
"createdAt": "2026-06-09T18:05:00.000Z",
"channel": "IN_STORE",
"currency": "PLN",
"products": [
{
"id": "id124",
"ean": "5901234123464",
"quantity": 3,
"unitPrice": 5500,
"linePrice": 16500
}
]
}
]
}
orderstablica typu RecommendationOrderWymaganeThe orders to ingest.
minItems: 1 · maxItems: 100
Pokaż parametry podrzędneUkryj parametry podrzędne7
orderIdstringWymaganeThe unique ID of the order in the merchant system.
maxLength: 36
loggedUserstringWymaganeThe merchant's own stable identifier for the user.
maxLength: 255
createdAtstringWymaganeThe moment the order was placed in the merchant system.
format: date-time
statusenumOpcjonalneThe status of the order. Re-send an order with CANCELLED to remove it from the recommendation engine when the user cancels it. Defaults to CREATED.
Możliwe wartości: CREATEDCANCELLED
channelenumOpcjonalneThe sales channel the order was placed through.
Możliwe wartości: WEBMOBILE_APPIN_STOREOTHER
currencystringWymaganeThe currency of all prices in the order.
productstablica typu RecommendationOrderProductWymaganeThe products purchased in the order.
minItems: 1
Pokaż parametry podrzędneUkryj parametry podrzędne5
idstringWymaganeThe catalogue variant ID of the purchased product.
maxLength: 36
eanstringOpcjonalneThe ean (or other barcode) of the product.
maxLength: 36
quantityintegerWymaganeThe number of items in the purchase.
minimum: 1
unitPriceintegerWymaganeThe price paid for a single product. Price is expressed as the number (integer) of 1/100s of the price.
minimum: 0
linePriceintegerOpcjonalneThe price paid for the products. Price is expressed as the number (integer) of 1/100s of the price.
minimum: 0
Surowy schemat JSON
{
"description": "Batch of orders fed by the merchant into the OpenApp recommendation engine - historical backfill, ongoing orders, and status updates.",
"additionalProperties": false,
"type": "object",
"properties": {
"orders": {
"description": "The orders to ingest.",
"maxItems": 100,
"minItems": 1,
"type": "array",
"items": {
"$ref": "#/definitions/RecommendationOrder"
},
"title": "orders"
}
},
"required": [
"orders"
],
"definitions": {
"RecommendationOrder": {
"title": "RecommendationOrder",
"type": "object",
"properties": {
"orderId": {
"description": "The unique ID of the order in the merchant system.",
"maxLength": 36,
"type": "string",
"title": "orderId"
},
"loggedUser": {
"description": "The merchant's own stable identifier for the user.",
"maxLength": 255,
"type": "string",
"title": "loggedUser"
},
"createdAt": {
"description": "The moment the order was placed in the merchant system.",
"format": "date-time",
"type": "string",
"title": "createdAt"
},
"status": {
"description": "The status of the order. Re-send an order with CANCELLED to remove it from the recommendation engine when the user cancels it. Defaults to CREATED.",
"enum": [
"CREATED",
"CANCELLED"
],
"type": "string",
"title": "status"
},
"channel": {
"description": "The sales channel the order was placed through.",
"enum": [
"WEB",
"MOBILE_APP",
"IN_STORE",
"OTHER"
],
"type": "string",
"title": "channel"
},
"currency": {
"description": "The currency of all prices in the order.",
"type": "string",
"title": "currency"
},
"products": {
"description": "The products purchased in the order.",
"minItems": 1,
"type": "array",
"items": {
"$ref": "#/definitions/RecommendationOrderProduct"
},
"title": "products"
}
},
"required": [
"currency",
"loggedUser",
"orderId",
"createdAt",
"products"
]
},
"RecommendationOrderProduct": {
"title": "RecommendationOrderProduct",
"type": "object",
"properties": {
"id": {
"description": "The catalogue variant ID of the purchased product.",
"maxLength": 36,
"type": "string",
"title": "id"
},
"ean": {
"description": "The ean (or other barcode) of the product.",
"maxLength": 36,
"type": "string",
"title": "ean"
},
"quantity": {
"description": "The number of items in the purchase.",
"minimum": 1,
"type": "integer",
"title": "quantity"
},
"unitPrice": {
"description": "The price paid for a single product. Price is expressed as the number (integer) of 1/100s of the price.",
"minimum": 0,
"type": "integer",
"title": "unitPrice"
},
"linePrice": {
"description": "The price paid for the products. Price is expressed as the number (integer) of 1/100s of the price.",
"minimum": 0,
"type": "integer",
"title": "linePrice"
}
},
"required": [
"id",
"quantity",
"unitPrice"
]
}
},
"$schema": "http://json-schema.org/draft-07/schema#"
}
Wartość loggedUser to własny, stabilny identyfikator użytkownika merchanta - OpenApp nie próbuje powiązać go z żadnym kontem OpenApp. Każde zamówienie musi identyfikować użytkownika, który je złożył.
id produktu musi odpowiadać id wariantu z katalogu. Produkty jeszcze nieznane z katalogu są ignorowane i zwracane w ignoredProducts - samo zamówienie jest mimo to przyjmowane. Ponieważ ponowne wysłanie orderId zastępuje zapisane zamówienie, merchant może ponownie przesłać wcześniej odrzucone lub częściowo zignorowane zamówienie po następnej synchronizacji katalogu, aby uzupełnić brakujące produkty.
Status zamówienia i anulowania
Opcjonalne pole status domyślnie przyjmuje wartość CREATED. Gdy użytkownik anuluje zamówienie, które zostało już wysłane do feedu, należy ponownie je przesłać z status: CANCELLED - OpenApp usunie je z silnika rekomendacji. Ponieważ przyjmowanie zamówień jest operacją upsert na orderId, anulowanie jest stosowane przez zastąpienie zamówienia jego odpowiednikiem z anulacją.
Odpowiedź
Zamówienia są przyjmowane niezależnie: problem z jednym zamówieniem nie wpływa na pozostałe w batchu. OpenApp odpowiada 200 OK zawierającym liczbę accepted zamówień, listę rejected dla zamówień, które nie przeszły walidacji, oraz listę ignoredProducts dla produktów nieznanych w katalogu.
- Odpowiedź
- Schemat
{
"accepted": 99,
"rejected": [
{
"orderId": "WS1213ASDZXC231F",
"error": "VALIDATION_FAILED",
"message": "createdAt is missing"
}
],
"ignoredProducts": [
{
"orderId": "WS1213ASDZXC231A",
"productIds": [
"id999"
]
}
]
}
acceptedintegerWymaganeThe number of orders from the request that were ingested.
minimum: 0
rejectedtablica typu RejectedOrderWymaganeThe orders from the request that were not ingested, with the rejection reason. Empty when all orders were accepted.
Pokaż parametry podrzędneUkryj parametry podrzędne3
orderIdstringWymaganeThe ID of the rejected order, as sent in the request.
maxLength: 36
errorenumWymaganeThe rejection reason. VALIDATION_FAILED - the order data is semantically invalid.
Możliwe wartości: VALIDATION_FAILED
messagestringOpcjonalneA human-readable description of the rejection reason.
maxLength: 255
ignoredProductstablica typu IgnoredProductsWymaganeProducts that were ignored during ingestion because they are not yet known from the catalogue, grouped per order. The orders themselves were ingested. Re-send the order after the next catalogue synchronization to capture these products.
Pokaż parametry podrzędneUkryj parametry podrzędne2
orderIdstringWymaganeThe ID of the order whose products were partially ignored.
maxLength: 36
productIdstablica typu stringWymaganeThe IDs of the products that were ignored because they are not known from the catalogue.
Surowy schemat JSON
{
"description": "The result of ingesting a batch of orders into the OpenApp recommendation engine",
"additionalProperties": false,
"type": "object",
"properties": {
"accepted": {
"description": "The number of orders from the request that were ingested.",
"minimum": 0,
"type": "integer",
"title": "accepted"
},
"rejected": {
"description": "The orders from the request that were not ingested, with the rejection reason. Empty when all orders were accepted.",
"type": "array",
"items": {
"$ref": "#/definitions/RejectedOrder"
},
"title": "rejected"
},
"ignoredProducts": {
"description": "Products that were ignored during ingestion because they are not yet known from the catalogue, grouped per order. The orders themselves were ingested. Re-send the order after the next catalogue synchronization to capture these products.",
"type": "array",
"items": {
"$ref": "#/definitions/IgnoredProducts"
},
"title": "ignoredProducts"
}
},
"required": [
"accepted",
"rejected",
"ignoredProducts"
],
"definitions": {
"RejectedOrder": {
"title": "RejectedOrder",
"type": "object",
"properties": {
"orderId": {
"description": "The ID of the rejected order, as sent in the request.",
"maxLength": 36,
"type": "string",
"title": "orderId"
},
"error": {
"description": "The rejection reason. VALIDATION_FAILED - the order data is semantically invalid.",
"enum": [
"VALIDATION_FAILED"
],
"type": "string",
"title": "error"
},
"message": {
"description": "A human-readable description of the rejection reason.",
"maxLength": 255,
"type": "string",
"title": "message"
}
},
"required": [
"orderId",
"error"
]
},
"IgnoredProducts": {
"title": "IgnoredProducts",
"type": "object",
"properties": {
"orderId": {
"description": "The ID of the order whose products were partially ignored.",
"maxLength": 36,
"type": "string",
"title": "orderId"
},
"productIds": {
"description": "The IDs of the products that were ignored because they are not known from the catalogue.",
"type": "array",
"items": {
"maxLength": 36,
"type": "string"
},
"title": "productIds"
}
},
"required": [
"orderId",
"productIds"
]
}
},
"$schema": "http://json-schema.org/draft-07/schema#"
}
Całe żądanie kończy się niepowodzeniem tylko wtedy, gdy samo żądanie jest nieprawidłowe lub zbyt duże - patrz błędy poniżej.
Błędy
| Nazwa błędu | Kod |
|---|---|
OrderValidationException | 400 |
TooManyOrdersException | 413 |
RecommendationsNotReadyException | 409 |