Tworzenie zamówienia "create-order"
Przegląd
Endpoint POST /create-order tworzy zamówienie klienta na podstawie listy produktów. AMPER sam wylicza ceny – cenę klienta z jego cennika i najlepszą dostępną promocję – i zwraca je w odpowiedzi. W trybie playground można tylko policzyć ceny, bez tworzenia zamówienia.
Przed wywołaniem trzeba uzyskać token JWT przez endpoint /auth/. Klucz API (api_key) z API zewnętrznego tutaj nie działa.
1. Autoryzacja – uzyskanie tokena
1.1 Pobranie tokena (logowanie)
POST /auth/
Content-Type: application/json
Body żądania:
{
"username": "login_uzytkownika",
"password": "haslo"
}
Przykład (curl):
curl -X POST https://<host>/auth/ \
-H "Content-Type: application/json" \
-d '{"username": "jan.kowalski", "password": "tajnehaslo"}'
Odpowiedź (200 OK):
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cC...",
"expires_in": 300,
"refresh_expires_in": 1800,
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5c...",
"token_type": "Bearer",
"not-before-policy": 0,
"session_state": "abc123...",
"scope": "amper",
"amper-company-assigned": "amper-xyz"
}
| Pole | Opis |
|---|---|
access_token |
token JWT do autoryzacji żądań API |
expires_in |
czas ważności tokena w sekundach (zwykle 300 s = 5 min) |
refresh_token |
token do odświeżenia sesji bez ponownego logowania |
refresh_expires_in |
czas ważności refresh tokena w sekundach |
amper-company-assigned |
identyfikator instalacji AMPER, do której należy konto |
Konto musi należeć do instalacji AMPER, do której się logujesz – inaczej odpowiedź to 403.
1.2 Odświeżenie tokena
Gdy access_token wygaśnie, użyj refresh_token zamiast ponownie logować użytkownika.
POST /auth/token-refresh/
Content-Type: application/json
Body żądania:
{
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5c..."
}
Przykład (curl):
curl -X POST https://<host>/auth/token-refresh/ \
-H "Content-Type: application/json" \
-d '{"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5c..."}'
Odpowiedź: taki sam format jak przy logowaniu – nowy access_token i refresh_token. Wygasły refresh token daje odpowiedź 400 z błędem invalid_grant – wtedy zaloguj się ponownie przez /auth/.
2. Tworzenie zamówienia
Endpoint
POST /create-order
Authorization: Bearer <access_token>
Content-Type: application/json
Wymagane uprawnienia
Token musi należeć do użytkownika z zakresem B2B (konto klienta) lub TRANSLATOR (konto integracji ERP).
2.1 Parametry żądania
Body żądania (JSON):
| Pole | Typ | Wymagane | Opis |
|---|---|---|---|
customer_id |
integer |
Tak* | ID klienta w AMPER |
customer_external_id |
string |
Tak* | ID klienta w systemie ERP (alternatywa dla customer_id) |
lines |
array |
Tak | linie zamówienia (patrz niżej) |
playground |
boolean |
Nie | true – tylko wyliczenie cen, bez zapisu zamówienia (domyślnie false) |
description |
string |
Nie | uwagi do zamówienia |
recipient_order_number |
string lub integer |
Nie | własny numer zamówienia odbiorcy; trafia do uwag jako pierwsza linia: Własny identyfikator zamówienia: <numer> |
shipment_type_id |
integer |
Nie | ID rodzaju wysyłki – listę zwraca /external/v1/shipment-types/ |
* Wymagane jest podanie
customer_idlubcustomer_external_id.
Pola obiektu w tablicy lines:
| Pole | Typ | Wymagane | Opis |
|---|---|---|---|
product_id |
integer |
Tak* | ID produktu w AMPER |
product_external_id |
string |
Tak* | ID produktu w systemie ERP |
ean |
string |
Tak* | kod EAN produktu albo opakowania zbiorczego – dla EAN-u opakowania ilość jest przeliczana na jednostki podstawowe |
quantity |
decimal |
Tak | ilość w jednostce podstawowej (zaokrąglana w górę do kroku jednostki produktu) |
suggested_price |
decimal lub null |
Tak | pole musi wystąpić, ale AMPER nie używa go do wyceny (patrz niżej) |
promotion_id |
integer |
Nie | ID promocji – AMPER sprawdza wtedy tylko tę jedną promocję |
* Linia musi zawierać
product_id,product_external_idlubean(sprawdzane w tej kolejności).
Nie wysyłaj pola
order_line_promotion_id. To pole wewnętrzne – linia, która je zawiera, jest pomijana i nie trafia do zamówienia.
Zamówienia producenckie (tylko konto Translatora)
Zamówienie złożone przez kanał sprzedaży producenta (EDI itp.) w imieniu klienta. Pola są brane pod uwagę tylko wtedy, gdy wysyła je konto z zakresem TRANSLATOR; dla innych kont są ignorowane.
| Pole | Typ | Wymagane | Opis |
|---|---|---|---|
is_producer_order |
boolean |
Nie | true – zamówienie producenckie |
producer_order_number |
string lub integer |
Tak, gdy is_producer_order |
numer zamówienia u producenta (najwyżej 128 znaków) |
document_provider_short_name |
string |
Nie | skrót dostawcy dokumentu (producenta) |
Ponowne wysłanie zamówienia o tym samym numerze i dostawcy nie tworzy duplikatu – odpowiedź to 200 OK z "already_exists": true i ID istniejącego zamówienia.
2.2 Jak AMPER wylicza ceny
- Cena linii to cena promocyjna (
given_price), jeśli warunki promocji są spełnione, a w przeciwnym razie cena klienta z jego cennika (customer_price). Wartośćsuggested_pricez żądania nie wpływa na cenę. - Promocje są wybierane automatycznie: AMPER szuka najkorzystniejszej promocji typu stała cena, której warunki spełnia całe zamówienie. Podanie
promotion_idzawęża wybór do tej jednej promocji. - Ilość jest zaokrąglana w górę do kroku jednostki produktu – np. przy kroku 5 zamówienie 7 szt. zostanie zaokrąglone do 10.
- Linie są pomijane, gdy produkt nie istnieje, nie jest dostępny dla klienta albo klient nie ma wymaganej koncesji (np. na alkohol). Pominięte linie nie pojawiają się w odpowiedzi.
2.3 Przykłady żądań
Przykład z wewnętrznymi ID:
curl -X POST https://<host>/create-order \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cC..." \
-H "Content-Type: application/json" \
-d '{
"customer_id": 42,
"lines": [
{
"product_id": 101,
"quantity": 10,
"suggested_price": null
},
{
"product_id": 205,
"quantity": 5,
"suggested_price": null,
"promotion_id": 7
}
],
"description": "Zamówienie testowe"
}'
Przykład z zewnętrznymi ID i EAN-em (integracja ERP):
curl -X POST https://<host>/create-order \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cC..." \
-H "Content-Type: application/json" \
-d '{
"customer_external_id": "ERP-KLIENT-0042",
"recipient_order_number": "ZAM/2026/10/0153",
"lines": [
{
"product_external_id": "SKU-ABC-001",
"quantity": 10,
"suggested_price": null
},
{
"ean": "5901234123457",
"quantity": 2,
"suggested_price": null
}
]
}'
Przykład trybu playground (tylko wyliczenie cen):
curl -X POST https://<host>/create-order \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cC..." \
-H "Content-Type: application/json" \
-d '{
"customer_id": 42,
"playground": true,
"lines": [
{
"product_id": 101,
"quantity": 10,
"suggested_price": null
}
]
}'
2.4 Odpowiedź
Sukces – 201 Created:
{
"order_id": 12345,
"lines": [
{
"product_id": 101,
"product_external_id": "SKU-ABC-001",
"quantity": 10,
"suggested_price": null,
"default_price": 100.00,
"customer_price": 95.00,
"given_price": 90.00,
"promotion": {
"price": 90.00,
"promotion_min_order_quantity": 5,
"promotion_condition_item_id": 123,
"promotion_condition_id": 456,
"relation_id": 789,
"promotion_name": "Letnia wyprzedaż",
"promotion_id": 999,
"promotion_url": "https://<adres-b2b>/promotions/999/"
}
}
]
}
| Pole | Opis |
|---|---|
order_id |
ID utworzonego zamówienia; 0, gdy playground=true, gdy żadna linia nie została przyjęta albo gdy nie znaleziono klienta |
lines |
przyjęte linie z wyliczonymi cenami |
lines[].default_price |
cena katalogowa netto |
lines[].customer_price |
cena netto z cennika klienta |
lines[].given_price |
cena promocyjna netto; 0, gdy żadna promocja nie ma zastosowania |
lines[].promotion |
zastosowana promocja albo null |
Utworzone zamówienie ma status Oczekujące (Pending) i jest eksportowane do ERP jak każde inne. Zamówienie producenckie może od razu trafić do przedstawiciela handlowego klienta jako dokument do sprawdzenia – zależy to od konfiguracji instalacji.
Uwaga: kod
201nie gwarantuje, że zamówienie powstało. Zawsze sprawdzajorder_id– wartość0oznacza, że zamówienia nie utworzono.
3. Kody odpowiedzi
| Kod | Endpoint | Opis |
|---|---|---|
200 OK |
/auth/, /auth/token-refresh/ |
token wydany |
200 OK |
/create-order |
zamówienie producenckie już istnieje (already_exists: true) |
201 Created |
/create-order |
żądanie przyjęte – sprawdź order_id |
400 Bad Request |
/create-order |
błędny recipient_order_number (musi być tekstem lub liczbą) albo błędne pola zamówienia producenckiego |
400 Bad Request |
/auth/token-refresh/ |
refresh token wygasł lub jest nieprawidłowy |
401 Unauthorized |
/create-order |
brak lub nieprawidłowy nagłówek Authorization |
403 Forbidden |
/auth/ |
błędny login lub hasło, konto wyłączone albo konto spoza tej instalacji |
403 Forbidden |
/create-order |
token ważny, ale bez wymaganego zakresu (B2B lub TRANSLATOR) |
403 Forbidden |
/auth/token-refresh/ |
brak pola refresh_token |
404 Not Found |
/auth/ |
pusty login lub hasło |
422 Unprocessable Entity |
/create-order |
instalacja nie jest skonfigurowana do zamówień producenckich – nic nie utworzono, wyślij zamówienie ponownie później |
4. Pełny przepływ integracji
1. POST /auth/ → otrzymujesz access_token + refresh_token
│
▼
2. POST /create-order → zamówienie zostaje utworzone (sprawdź order_id)
Authorization: Bearer <access_token>
│
▼
3. Gdy access_token wygaśnie (expires_in sekund):
POST /auth/token-refresh/ → otrzymujesz nowy access_token
{ "refresh_token": "..." }
Rekomendowane podejście w kliencie:
- Przechowuj
access_tokenirefresh_tokenw pamięci sesji. - Przed każdym żądaniem sprawdzaj, czy token nie wygasł (
expires_in). - Po odpowiedzi
401odśwież token przez/auth/token-refresh/i ponów żądanie. - Gdy
refresh_tokenrównież wygaśnie, ponownie pobierz token przez/auth/. - Przy ponawianiu zamówień producenckich wysyłaj ten sam
producer_order_number– AMPER nie utworzy duplikatu.
No comments to display
No comments to display