Doporučená aplikace
Pro testování doporučuji používat program Postman, který je dostupný na všech běžných operačních systémech.
API (Application Public Interface) slouží k napojení Vašeho e-shopu nebo ekonomického softwaru na aplikaci multiklientského skladu Flash WMS. API vyžaduje obousměrnou komunikaci, pro zajištění výměny potřebných informací.
Po importu objednávky do systému WMS byste již objednávku neměli měnit a pokud ano, informujte o tom firmu Flash Services.
Naše API je REST API založené na datové struktůře JSON. To znamená, že implementace je v mnoha směrech jednodušší než procedurální implementace SOAP. Přístup k datům se dá popsat pomocí 4 metod a tedy 4 typů dotazů přes API:
Pro některé datové zdroje (resources) nemusí být dostupné všechny metody.
Pro komunikaci používáme šifrované spojení přes HTTPS. Autentizace probíhá pomocí hlavičky (header) dotazu přes atributy X-ApiToken a X-ApiSecret. Autentizace je vyžadována pro každý dotaz a není třeba udržovat spojení či nějaký dočasný token. ApiToken i ApiSecret obdržíte po zažádání o napojení na Flash WMS API.
Pro testování doporučuji používat program Postman, který je dostupný na všech běžných operačních systémech.
Nastavení autentizace aplikace Postman.
Při posílání POST nebo PUT dotazů, je třeba poslat společně s dotazem i data ve formě JSON a to v těle dotazu. V aplikaci Postman se to dělá v záložce Body. Z možností zvolte "raw" a následně JSON (application/json).
Nastavení autentizace aplikace Postman.
V rámci implementace poskytujeme testovací rozhranní, které se ve všech ohledech chová stejně jako produkční prostředí. Přístup k tomuto testovacímu prostředí dostanete na požádání, pokud jste ho již nedostali spolu s odkazem na tuto dokumentaci.
Základní URL testovacího prostředí je http://testwms.flash-services.cz/
V aplikaci Flash WMS pracujeme s několika objekty nebo chcete-li modely. Jsou to:
API klíče jsou dvě hodnoty, které dostanete po úspěšné implementaci napojení na API. Oba klíče jsou tajné a nesmí být sdílené či veřejně dostupné. API klíče je možné získat i přes klientskou zónu. Zde si klíče můžete také přegenerovat nebo nastavit jejich automatické regenerování.
Objednávka je zde ve významu "Žádost k vyskladnění a odeslání na adresu". Tedy Máte-li své zboží v našem multi-klientském skladu, posláním objednávky k nám posíláte žádost k vyskladnění. Objednávka má své stavy viz. stavová logika níže. V různých systémech může být objednávka něcím jiným, např. výdejkou nebo převodkou.
Produkt je zalistovaná položka, která se nachází ve skladě Flash WMS multi-klientského skladu. K produktu jsou pak vztahovány veškeré skladové položky, položky objednávky i veškerá historie. Před vytvořením objednávky je třeba mít produkty, na které se vztahují položky objednávky, zalistované.
Pro testování aplikace, authentizace do aplikace nebo i v průběhu produkčního použití můžete otestovat stav API. V případě, že je API "živá", dostanete odpověď ready a verzi API, na kterou se tážete.
GET: https://[API_URL]/api/[verze_API]/status
{
"status": "ready",
"api_version": 1.0
}
HTTP status: 200
API klíče jsou 2 tajné hodnoty, kterými se prokazujete při posílání všech dotazů na API. Tyto klíče nikomu neprozrazujte a držte je bezpečně uložené ve své aplikaci. Ideální místo je buď databáze Vaší aplikace nebo nějaký šifrovaný mechanizmus ve Vaší aplikaci, např. ENV - environment variables.
Aby mohlo být dosaženo větší bezpečnosti, je dobré čas od času API klíče přegenerovat. To však může být náročné na údržbu Vaší aplikace. API server je schopen takové přegenerování API klíčů provádět jednou měsíčně formou API callbacků. Při blížící se expiraci API klíčů pošle API server PUT dotaz s nově vygenerovanými API klíči. Dotaz je poslán na URL endpoint, kterou si můžete nastavit v klientské zóně. V případě, že na PUT dotaz je odpovězeno HTTP statusem 200 - OK, vygenerované API klíče se uloží a další API volání již musí probíhat přes tyto nově vygenerované API klíče. Automatické přegenerování API klíčů je defaultně vypnuté. Jeho zapnutí však opravdu doporučujeme.
Pro jednorázové přegenerování API klíčů můžete použít API dotaz.
POST: https://[API_URL]/api/[verze_API]/api_keys/generate_api_keys
{
"result": "Success",
"msg": "Request with generated API keys will be send soon."
}
HTTP status: 200
Poté v řádu sekund (maximálně pár minut) bude poslán API callback k Vám na nastavený URL endpoint. Jak již bylo zmíněno, tento URL endpoint si můžete nastavit v klientské zóně nebo přes naši technickou podporu.
API klíče lze jednorázově vygenerovat i přes GUI v klientské zóně, máte-li k tomu příslušná práva.
Callback je zde v dokumentaci ve významu asynchronního dotazu směrem z Flash API do zákaznické aplikace, která se přes API napojuje na Flash WMS.
{
"event": "api_keys_generated",
"api_token": "XXXXX",
"api_secret": "XXXXX",
"api_keys_changed_at": "2019-11-02T18:50:05+0100",
"api_keys_expiration": "1.month",
"api_keys_expiring_at": "2019-11-02T18:50:05+0100"
}
Pokud na tento API callback odpovíte kladně, tedy HTTP statusem 200 - OK, vygenerované API klíče se uloží a dále již bude zapotřebí používat pro další dotazy tyto klíče. Bude-li Vaše odpověď jiná neš HTTP status 200, dojde k opakování API callbacku v různých intervalech, dokud neodpovíte kladně HTTP statusem 200. Opakující se callback dotazy budou na počátku časté - v rádu sekund - později po několika minutách až třeba jednou za hodinu. Tímto eliminujeme možnost propásnutí přijetí API callbacku na Vaší straně třeba z důvodu maintanance či výpadku sítě.
Aby callback mohl správně fungovat, musí vědět, kam se má odeslat. U klientské aplikace je třeba nastavit callback URL. Pokud callback URL nebude nastavena, callback se neodešle. Toto nastavení můžete provést přes klientskou zónu.
Evidence produktů je nutná pro zpracovávání objednávek i příjemek. Produkty mohou být naskladněny pod různými šaržemi a na více pozicích ve skladech.
GET: https://[API_URL]/api/[verze_API]/products
{
"count": 113,
"products": [
{
"id": 1,
"name": "Produkt 1",
"part_number": "TB1254S",
"ean": "5903050383770",
"brand": "Adidas",
"quantity_on_stock": 16,
"created_at": "2019-03-04 15:56:54",
"updated_at": "2019-07-23 12:10:24"
},
{
"id": 2,
"name": "Produkt 2",
"part_number": "AB454S",
"ean": "8809344900753",
"brand": "Nike",
"quantity_on_stock": 0,
"created_at": "2019-01-23 05:03:17",
"updated_at": "2019-07-23 12:26:59"
},
{
"id": 3,
"name": "Produkt 3",
"part_number": "TR4545S",
"ean": "8809344900722",
"brand": "Umbro",
"quantity_on_stock": 0,
"created_at": "2019-01-23 05:03:17",
"updated_at": "2019-07-23 12:26:59"
},
...
HTTP status: 200
Také se můžete podívat na detail produktu, kde naleznete i více informací, např. na které pozici ve skladu produkt je.
GET: https://[API_URL]/api/[verze_API]/products/[ID_produktu]
{
"id": 1,
"name": "Produkt 1",
"part_number": "TB1254S",
"ean": "5903050383770",
"brand": "Adidas",
"quantity_on_stock": 16,
"created_at": "2019-03-04 15:56:54",
"updated_at": "2019-07-23 12:10:24"
"stock_items": [
{
"stock_position": "A-002-01",
"quantity": 16,
"quantity_available": 0,
"reserved_quantity": 0
}
]
}
HTTP status: 200
POST: https://[API_URL]/api/[verze_API]/products
{
"name": "Test 1",
"part_number": "ABC1243",
"ean": "8212456498451",
"brand": "Apple"
}
{
"result": "Success",
"msg": "Produkt byl úspěšně vytvořen",
"product": {
"name": "Test 1",
"part_number": "ABC1243",
"ean": "8212456498451",
"brand": "Apple"
}
}
HTTP status: 200
{
"result": "Error",
"error_code": 1,
"error": "Produkt již v databázi existuje."
}
HTTP status: 422
Příjemka je avizo o plánovaném příjezdu zboží (skladových položek) do skladu. Její zpracování je následující: zboží je překontrolováno a složeno na příjmovou pozici. Následně probíhá vykrývání, kdy se položky postupně naskladňují do disponabilních pozic pro následné vykrytí objednávek.
Pomocí GET metody si můžeme zobrazit index příjemek, které jsou v systému evidovány. Příjemky jsou dostupné za posledních 12 měsíců. Starší příjemky archivujeme a nejsou dostupné ke zobrazení.
GET: https://[API_URL]/api/[verze_API]/income_lists
{
"date_from": "2021-01-18",
"date_to": "2021-02-18",
"count": 121,
"income_lists": [
...
{
"id": 1150,
"number": "OKJ01",
"state": "stocked",
"localized_state": "Naskladněna",
"stocked_at": "2021-01-19 09:19:45",
"created_at": "2021-01-18 08:11:56",
"updated_at": "2021-01-18 11:10:19"
},
{
"id": 1151,
"number": "OKJ04",
"state": "stocked",
"localized_state": "Naskladněna",
"stocked_at": "2021-01-27 11:46:13",
"created_at": "2021-01-25 08:17:44",
"updated_at": "2021-02-25 10:37:51"
},
{
"id": 1349,
"number": "20210717FR",
"state": "stocked",
"localized_state": "Naskladněna",
"created_at": "2021-02-20 10:05:12",
"created_at": "2021-02-17 09:29:00",
"updated_at": "2021-02-17 09:29:31"
}
}
HTTP status: 200
V detailu příjemky naleznete podrobné informace o vytvořené příjemce. Krom vložených informací lze vidět aktuální stav nebo stav naskladnění příjemky.
GET: https://[API_URL]/api/[verze_API]/income_lists/[ID_objednavky]
{
"id": 1150,
"number": "202108251",
"state": "stocked",
"localized_state": "Naskladněna",
"supplier": "Adidas",
"generated_at": "2021-01-18T00:00:00.000+02:00",
"generated_by": "Arnold schwarzenegger",
"stocked_at": null,
"created_at": "2020-04-23 08:11:56",
"updated_at": "2020-04-23 11:10:19",
"items": [
{
"name": "Body 39",
"part_number": "TB1254S",
"ean": "5903050383770",
"brand": "Adidas",
"stock_id": 234324234,
"quantity": 1,
"stocked_quantity": 1,
"expiration_date": "2021-04-15",
"client_stock_name": "Průmyslová 7",
"price": "1999.0",
"total_price": "1999.0",
"currency": "CZK"
}
]
}
HTTP status: 200
POST: https://[API_URL]/api/[verze_API]/income_list
{
"number": "202108251",
"supplier": "Adidas",
"generated_at": "18.1.2021",
"generated_by": "Arnold schwarzenegger",
"items": [
{
"name": "Body 39",
"part_number": "TB1254S",
"ean": "5903050383770",
"brand": "Adidas",
"stock_id": "234324234",
"client_stock_name": "A32",
"quantity": 1,
"expiration_date": "2021-04-15",
"price": "1999.0",
"total_price": "1999.0",
"currency": "CZK"
}
]
}
{
"result": "Success",
"msg": "Income list has been successfully created.",
"order_id": 1212
}
HTTP status: 200
{
"result": "Error",
"errors": [
"Příjemka s tímto číslem 1914116348 již existuje"
]
}
HTTP status: 422
Samozřejmě, že můžou nastat i jiné chybové stavy, vždy je však dodrženo, že HTTP status odpovědi je 200 při úspěchu a jiný při neúspěchu.
Přes API lze Objednávky vytvářet, prohlížet i mazat. Funkci mazání je však možné využít jen v případě, že se s objednávkou ještě nezačalo pracovat.
Pomocí GET metody si můžeme zobrazit index objednávek, které jsou v systému evidovány. Objednávky jsou dostupné za posledních 12 měsíců. Starší objednávky archivujeme a nejsou dostupné ke zobrazení.
GET: https://[API_URL]/api/[verze_API]/orders
{
"date_from": "2018-10-25",
"date_to": "2019-10-25",
"count": 121,
"orders": [
...
{
"id": 119,
"number": "123456787",
"document_number": "123456787",
"transport_name": "geis"
"state": "completed",
"localized_state": "Dokončená",
"deliver_at": "2019-02-12",
"completed_at": "2019-02-12 09:43:30",
"created_at": "2019-02-11 13:29:11",
"updated_at": "2019-02-12 09:43:30"
},
{
"id": 120,
"number": "123456788",
"document_number": "123456788",
"transport_name": "geis"
"state": "completed",
"localized_state": "Dokončená",
"deliver_at": "2019-02-12",
"completed_at": "2019-02-11 16:13:54",
"created_at": "2019-02-11 13:29:11",
"updated_at": "2019-02-11 16:13:54"
},
{
"id": 121,
"number": "123456789",
"document_number": "123456789",
"transport_name": "geis"
"state": "completed",
"localized_state": "Dokončená",
"deliver_at": "2019-02-12",
"completed_at": "2019-02-11 16:14:19",
"created_at": "2019-02-11 13:29:11",
"updated_at": "2019-02-11 16:14:19"
}
}
HTTP status: 200
V detailu objednávky naleznete podrobné informace o vytvořené objednávce. Krom vložených informací lze vidět aktuální stav nebo balíky vytvořené k dané objednávce.
GET: https://[API_URL]/api/[verze_API]/orders/[ID_objednavky]
{
"id": 1,
"number": "1914116348",
"document_number": "1914116348",
"state": "new",
"localized_state": "Nová",
"deliver_at": "2019-10-19",
"completed_at": null,
"comment": "Poznámka k objednávce",
"created_at": "2019-10-18 15:05:18",
"updated_at": "2019-10-18 15:05:18",
"delivery": {
"type": "address",
"transport_name": "Geis",
"transport_system_name": "geis",
"transport_services": [],
"price": "0.0",
"cod_price": "0.0",
"cod_reference": "",
"insurance_price": "0.0",
"currency": "CZK"
},
"shipping_address": {
"company": null,
"first_name": "John",
"last_name": "Snow",
"email": "john.snow@black-castle.com",
"phone": "777123456",
"street": "Pražská 310",
"zip": "14000",
"city": "Praha",
"country": "Česká republika"
},
"items": [
{
"name": "Produkt 1",
"part_number": "TB1254S",
"ean": "5903050383770",
"brand": "Adidas",
"stock_id": "234324234",
"quantity": 1,
"date_expiration": null,
"comment": "Poznámka k objednávce"
}
],
"packages": []
}
HTTP status: 200
POST: https://[API_URL]/api/[verze_API]/orders
{
"number": "1914116348",
"document_number": "1914116348",
"partner_id": "443232452",
"deliver_at": "2019-04-12",
"weight": 3.5,
"comment": "Poznámka k objednávce (max. 255 znaků)",
"shipping_address": {
"company": "Black Castle inc.",
"first_name": "John",
"last_name": "Snow",
"email": "john.snow@black-castle.com",
"phone": "777123456",
"street": "Pražská 310",
"zip": "14000",
"city": "Praha",
"country": "Česká republika"
},
"delivery": {
"type": "address",
"transport_name": "Geis",
"transport_system_name": "geis",
"transport_services": [],
"price": 0.0,
"cod_price": 0.0,
"cod_reference": "2378273287",
"insurance_price": 0.0,
"currency": "CZK"
},
"items": [
{
"name": "Produkt 1",
"part_number": "TB1254S",
"ean": "5903050383770",
"brand": "Adidas",
"stock_id": "234324234",
"quantity": 1,
"expiration_date": "2023-12-05",
"batch_number": "L20231205",
"comment": "Poznámka k položce (max. 255 znaků)"
}
]
}
{
"result": "Success",
"msg": "Order has been successfully created.",
"order_id": 1212
}
HTTP status: 200
{
"result": "Error",
"errors": [
"Objednávka s tímto číslem 1914116348 již existuje"
]
}
HTTP status: 422
Samozřejmě, že můžou nastat i jiné chybové stavy, vždy je však dodrženo, že HTTP status odpovědi je 200 při úspěchu a jiný při neúspěchu.
Dodací informace jsou v blocích "shipping_address" a "delivery". Dodací může být vyplněna buď adresou zákazníka nebo adresou odběrného místa. V bloku "delivery" jsou pak atributy závislé na zvoleném dopravci.
{
...
"delivery": {
"type": "address",
"transport_name": "Geis",
"transport_system_name": "geis",
"transport_services": [],
"service_type": "2", // typ služby, např.: 2, 3, 1, 9
"price": 500.0,
"cod_price": 0.0,
"cod_reference": "2378273287",
"insurance_price": 500.0,
"currency": "CZK"
}
...
}
{
...
"delivery": {
"type": "pickup",
"pickup_point_id": "15451", // ID odběrného místa Zásilkovny
"pickup_point_name": "U Dobráka - Č. Budějovice", // Název odběrného místa (nepovinné)
"transport_name": "Zásilkovna",
"transport_system_name": "packeta",
"price": 500.0,
"cod_price": 0.0,
"cod_reference": "2378273287",
"insurance_price": 500.0,
"currency": "CZK"
}
...
}
{
...
"delivery": {
"type": "address",
"transport_name": "Česká pošta",
"transport_system_name": "cpost",
"transport_services": [7, 45], // doplňové služby přepravce, např.: 7, 45, 41, 1A ...
"service_type": "DR", // typ služby, např.: DR, NP, NB
"price": 500.0,
"cod_price": 0.0,
"cod_reference": "2378273287",
"insurance_price": 500.0,
"currency": "CZK"
}
...
}
{
...
"delivery": {
"type": "pickup",
"pickup_point_id": "14000", // PSČ Balíkovny
"transport_name": "Česká pošta",
"transport_system_name": "cp", // možnosti ['cp', 'cpost', 'CPOST']
"transport_services": [7, 45], // doplňové služby přepravce, např.: 7, 45, 41, 1A ...
"service_type": "NB", // typ služby, např.: DR, NP, NB
"price": 500.0,
"cod_price": 0.0,
"cod_reference": "2378273287",
"insurance_price": 500.0,
"currency": "CZK"
}
...
}
{
...
"delivery": {
"type": "pickup",
"pickup_point_id": "14000", // PSČ pošty
"transport_name": "Česká pošta",
"transport_system_name": "cp", // možnosti ['cp', 'cpost', 'CPOST']
"transport_services": [7, 45], // doplňové služby přepravce, např.: 7, 45, 41, 1A ...
"service_type": "NP", // typ služby, např.: DR, NP, NB
"price": 500.0,
"cod_price": 0.0,
"cod_reference": "2378273287",
"insurance_price": 500.0,
"currency": "CZK"
}
...
}
Objednávka má prozatím 3 stavy a průchod je jednosměrný. Stavy jsou popsané anglicky, v API však zobrazujeme i jejich význam v CZ a to v poli localized_state. Je však pravděpodobné, že v řádu měsíců přidáme další stavy, které popíšou detailněji doručování objednávky. V rámci této změny nebude navyšována verze API, protože se bude jednat o feature. Stav completed bude vždy odpovídat konečnému stavu objednávky.
| Stav | Lokalizovaný stav | Význam |
|---|---|---|
| new | nová | Objednávka je nahraná v systému a čeká na zpracování. |
| to_pick | připravená k picku | Objednávka má rezervované položky ve skladu a čeká na pick. |
| waiting_for_transporter | čeká na dopravce | Objednávka je zabalena a čeká na vyzvednutí dopravcem v DEPU. |
| sent | Předaná dopravci | Objednávku jsme předali dopravci. |
| delivering | Na cestě | Dopravce doručuje objednávku. |
| ready_to_pickup | Připravena k vyzvednutí | Objednávka čeká na vyzvednutí zákazníkem v pickup pointu. |
| completed | dokončená | Objednávka je doručena a životní cyklus stavů objednávky je uzavřen. |
V okamžiku, kdy s objednávkou začneme pracovat, tedy pickujeme položky objednávky ve skladu a následně balíme, přepínáme objednávku do stavu "to_pick" (připravena k picku). Po zabalení a odeslání dat dopravci přechází objednávka do stavu "completed" (dokončená).
Při jakékoli změně stavu posíláme API callback notifikaci na URL nastavenou přes klientskou zónu.
{
"event": "order_state_changed",
"order_id": 1212,
"number": "1914116348",
"document_number": "1914116348",
"partner_id": "443232452",
"state": "to_pick",
"packages": [],
"localized_state": "připravená k picku"
}
{
"event": "order_state_changed",
"order_id": 1212,
"number": "1914116348",
"document_number": "1914116348",
"partner_id": "443232452",
"state": "completed",
"packages": ["DR4940000061C"],
"localized_state": "dokončená"
}
Bude-li Vaše odpověď jiná neš HTTP status 200, dojde k opakování API callbacku v různých intervalech, dokud neodpovíte kladně HTTP statusem 200. Opakující se callback dotazy budou na počátku časté - v rádu sekund - později po několika minutách až třeba jednou za hodinu. Tímto eliminujeme možnost propásnutí přijetí API callbacku na Vaší straně třeba z důvodu maintanance či výpadku sítě.
Aby bylo možné API callback implementovat a otestovat, je potřeba mít možnost danou event vyvolat. Pro tyto případy máme testovací endpoint, který příjme požadavek a vytvoří testovací callback, který obratem zašle na požadovanou URL.
Vyvolat testovací event je možné pro změnu stavu objednávky nebo pro přegenerování API klíčů. Jedná-li se o testovací callback event data se neukládají ani se nejdená o reálnou změnu stavu objednávky. Takový callback je označen atributem "test_request", který je nastaven na true.
POST: https://[API_URL]/api/[verze_API]/test/orders/send_state_notify?order_id=[order_ID]state=[order_state]
Jako parametr uvedete ID objednávky a stav objednávky a který chcete být notifikováni.
POST: https://[API_URL]/api/[verze_API]/test/api_keys/generate_api_keys
Jelikož se jedná o testovací callback, API keys se reálně nezmění. Jinak se ale callback chová stejně jako ten opravdový.
Aby callback mohl správně fungovat, musí vědět, kam se má odeslat. U klientské aplikace je třeba nastavit callback URL. Pokud callback URL nebude nastavena, callback se neodešle. Toto nastavení můžete provést přes klientskou zónu.
API volání může v zásadě dopadnou jen dvěma způsoby. Buď je úspěšné a pak je HTTP status vždy 200 a nebo neúspěšně a to buď s chybou nebo bez chyby. Pokud je HTTP status 422, jde o očekávanou chybu vlivem vstupu nevalidních dat.
| HTTP status | Význam | Poznámka |
|---|---|---|
| 200 | OK | Požadavek byl úspěšně zpracován. |
| 404 | Not Found | Neexistující endpoint API. |
| 405 | Method Not Allowed | Tato metoda není povolena v rámci API přístupu. |
| 422 | Unprocessable Entity | Očekávaná chyba při zpracování požadavku. |
| 500 | Internal Server Error | Došlo k chybě na straně serveru. |
| 501 | Not Implemented | Tato metoda není implementována v rámci API. |
| 502 | Bad Gateway | Došlo k chybě na straně serveru. |
| 503 | Service Unavailable | Server je v maintenance módu. |
| 504 | Gateway Timeout | Vypršel čas na zpracování požadavku. |