API ENGINE
Instrukcja dla użytkowników
Metryczka zmian w dokumencie
Data zmiany |
Wersja dokumentu |
Autor |
Opis zmian |
04.03.2020 |
1.0.0 |
Paweł Sierakowski |
Przebudowa i uzupełnienie informacji |
|
|
|
|
|
|
|
|
Informacje wstępne
Celem korzystania z API ENGINE jest wyłącznie wykorzystanie SaldeoSMART jako silnika do odczytywania dokumentów w integracji zewnętrznymi systemami, w tym księgowymi (nazywanymi w dokumencie APP). Główne założenia:
- wymiana danych odbywa się w modelu REST żądanie-odpowiedź typu GET oraz POST
- połączenie jest bez stanowe, czyli za każdym razem należy przesyłać dane uwierzytelniające zawierające następujące parametry
- username
- req_id
- req_sig
Dodatkowo system wyposażony jest w zabezpieczenie powtórnego wysłania żądania - przez zastosowanie unikalnego (w obrębie danego użytkownika) numeru ID - req_id przesyłanego w każdym żądaniu.
Uwierzytelnianie
Odbywa się poprzez wartość username (login zdefiniowany na etapie rejestracji konta) oraz znajomości sekretnego klucza dla użytkownika - api_token
Powyższy token jest kluczem bezpieczeństwa i nie jest jawnie przesyłany w żądaniach. Aby uzyskać ten klucz (api_token), należy po utworzeniu konta zalogować się poprzez username i przejść do sekcji ustawienia, jeżeli token nie został jeszcze wygenerowany klikamy na samym dole “Generuj nowy token”.
Algorytm wyliczenia “req_sig”
W każdym przesyłanym żądaniu niezbędne jest aby wyliczyć sumę kontrolną, będącą zabezpieczeniem przeciwko odczytaniu informacji w locie, jego podmianie itp. Sposób wyliczenia tej sumy kontrolnej przedstawia się następująco:
- Posortować wszystkie parametry żądania według klucza nazwy parametru (parametry nie mogą powtarzać się i nie mogą być puste)
- Utworzyć string bazowy łącząc posortowane alfabetycznie parametry - <nazwa_parametru> + = + <wartość>, (np. req_id=20140301123056)
- String bazowy zakodować za pomocą URL_ENCODING (opis funkcji poniżej) dodać na koniec bazowy token - api_token z całości wyliczyć MD5 i zapisać w formacie Hex (wielkość liter nie istotna).
W całości funkcja prezentuje się następująco:
HEX(MD5(URL_ENCODING(“req_id=<req-id>username=<username>”) + <api-token>) ) |
Przykład wyliczenia:
username: user api_token: token req_id: request-id gdzie req_sig zostało wyliczone jako: HEX( MD5( URL_ENCODING(“req_id=request-idusername=user”) + “token”)) parametry muszą być posortowane alfabetycznie (tylko i wyłącznie) w wyliczeniu MD5 podpisu.
GET https://saldeo.brainshare.pl/api/xml/1.0/company/list?username=user&req_id=request-id&req_sig=d73710fdff6acc96361f5b9cb3425cee |
Format komunikatów
Żądania
Komunikaty (treść do przesłania do i z serwera) są zapisywane (serializowane) w formacie XML z kodowaniem UTF-8. Przesyłane są w request HTTP jako parametr command.
W celu przesłania XML należy go przed dodaniem do parametru command odpowiednio sformatować (ze względu na ograniczenia w HTTP oraz niższe użycie łącza) według poniższych wytycznych.
Dla przesłania XML w żądaniu należy dokonać następujących kodowań:
- “Zbudować” XML według specyfikacji operacji którą wykonujemy
- Wykonać na nim gzip (https://pl.wikipedia.org/wiki/Gzip) i otrzymać tablicę bajtów
- Kodujemy tablicę bajtów poprzez algorytm base64, w celu uzyskania wszystki znaków drukowanych (http://en.wikipedia.org/wiki/Base64), na powyższym przykład
Treść przesyłamy w parametrze “command”.
Przykład:
Ad. 1. XML:
<?xml version='1.0' encoding='UTF-8' standalone='no' ?><ROOT><COMPANIES><COMPANY>1</COMPANY></COMPANIES></ROOT>
https://drive.google.com/open?id=0B30HQPm5wwPjc3YwTTA2VGxIa0E
Ad. 2. Po gzip zawartości z kroku nr 1 otrzymujemy bajty:
UWAGA: gzip może przyjąć różne parametry i poniższa reprezentacja nie musi pokrywać się uzyskaną u Was. Ważniejsze jest czy poniższy ciąg bajtów możecie rozkodować za pomocą swojego gzip do formy z kroku 1:
https://drive.google.com/open?id=0B30HQPm5wwPjRElfNHVVWXMtM1E
Ad. 3. Po base64 zawartości kroku nr 2:
base64:
H4sIAAAAAAAAALOxr8jNUShLLSrOzM+zVTfUM1BXSM1Lzk/JzEu3VQ8NcdO1UFcoLknMS0nMyc9LtVXPy1dXsLezCfL3D7Gzcfb3DXD083QNhjEj7Qxt9GFMGAssrw/WAQD5GQrgbwAAAA==
Odpowiedzi
Odpowiedzi są w formacie XML z kodowaniem UTF-8 oraz dodatkowo są poddane gzip. Gzip będzie zastosowany tylko i wyłącznie jeżeli w żądaniu zostanie dodany nagłówek:
Accept-Encoding: gzip, deflate
W odpowiedzi zostanie dodany również nagłówek określający że odpowiedź jest w formie gzip:
Content-Encoding: gzip
Informacja: Klient HTTP może już automatycznie realizować rozpakowanie zawartości.
Wersje operacji API
Każda operacja API posiada wersje. Zawarta jest ona w URL - jako element adresu, np:
/api/xml/1.0/document/list_recognized
W powyższym przykładzie jest zastosowana wersja 1.0.
Dla zachowania spójności zbudowanych mechanizmów u istniejących klientów łączących się po API, raz wydana wersja nie zmieni swojego działania (formatu komunikatów, funkcjonalności, itd). w trakcie rozbudowy i zmian w systemie oraz API.
W przypadku zmian dokonywanych w systemie na istniejących operacjach, zmieniana jest również wersja np. 1.0, 1.1, 1.2, itd.
Na serwerze są zawsze dostępne wszystkie dotychczasowe wersje operacji.
UWAGA: Wersjonowanie jest zależne od struktury danej, a nie samej operacji, przez co może być taka sytuacja, że dana operacja będzie dostępna tylko w niektórych wersjach - nie będzie zachowana ciągłość, np. 1.1, 1.2, 1.4, 1.7.
Macierz operacji oraz występowania w wersjach znajduje się tutaj:
https://saldeo.brainshare.pl/static/doc/api/versions_matrix.html
Zmiana jest opisana w dokumentacji poniżej opisu operacji.
Dostępne operacje
Dodaj i odczytaj dokument
Operacja pozwalająca na dodanie dokumentu i równoczesne wysłanie go do odczytu.
POST /api/xml/2.0/document/add_recognize
Dostępne parametry:
- attmnt_[ID]
Plik jest przesyłany jako parametr http, którego nazwa ma przedrostek attmnt_ po tym przedrostku następuje identyfikator pliku Identyfikator pliku musi spełniać założenia:
- unikalny w obrębie żądania http
- zgodny z wyrażeniem regularnym [a-zA-Z0-9]{1,255}
Jednocześnie zawartość pliku jest wartością parametru poddana kodowaniu w taki sam sposób jak sam xml (bajty -> gzip (lub zip) -> base64 = string)
Proces rozpoznawania jest asynchroniczny, po udanym przekazaniu dokumentu do odczytu dostajemy w odpowiedzi ID (OCR_ORIGIN_ID) obiektu, który reprezentuje dane dokumentu w procesie rozpoznawania. Ten identyfikator może być potem wykorzystany do odpytania SaldeoSMART o wyniki rozpoznawania za pomocą funkcji
Przesyłane dokumenty wysyłamy wraz z żądaniem XML w którym określamy następujące parametry:
- VAT_NUMBER - (wymagany) podajemy NIP firmy odbiorcy dokumentu, strony która go księguje
- DOCUMENT_TYPE - (opcjonalny) określa typ dokumentu do wybory mamy 2 typy:
COST - dokument kosztowy
SALE - dokument sprzedaży
- SPLIT_MODE - (opcjonalny) określa sposób podziału stron w przesłanym dokumencie, tak aby system przy odczytywaniu dzielił na odrębne dokumenty:
NO_SPLIT - nie dziel dokumentu
SPLIT_ONE_SIDED - podziel plik na dokumenty jednostronicowe
SPLIT_TWO_SIDED - podziel plik na dokumenty dwustronicowe
AUTO_ONE_SIDED - automatycznie podziel plik na dokumenty jednostronicowe
AUTO_TWO_SIDED - automatycznie podziel plik na dokumenty dwustronicowe
Jeżeli nie zostanie podana to domyślnie przyjmuje wartość SPLIT_ONE_SIDED
Przykładowe żądania XML
Przykładowe zwrotne odpowiedzi XML
Lista dokumentów po rozpoznaniu
POST /api/xml/1.23/document/list_recognized
Pobieranie listy wyników rozpoznania na podstawie przesłanego ID (OCR_ORIGIN_ID) otrzymanego po rozpoznaniu dokumentu z wykonania operacji Dodaj i odczytaj dokument. Funkcja umożliwia jednocześnie odpytywanie się o wiele dokumentów, jednakże wszystkie muszą należeć do tego samego podmiotu.
W samym wywołaniu jest jednocześnie zawarty numer wersji API zalecamy korzystać z najnowszej wersji (więcej informacji tu), która zawiera wszystkie wprowadzone nowości które z biegiem lat SaldeoSMART nauczyło się odczytywać, i które może zwrócić do programu księgowego. W powyższym przykładzie podano numer 1.23 - najnowszą na moment pisania niniejszej dokumentacji.
Przykładowe żądanie:
Przykładowe pliki XML odpowiedzi:
Informacje dodatkowe
Funkcja URL_ENCODING
Bazuje na powszechnym sposobie kodowania znaków wykorzystywanym m.in. w protokole http. W świecie rzeczywistym istnieje wiele implementacji tej funkcji różniących się sposobem kodowania niektórych znaków. Dekodowanie jest już jednoznaczne, więc te różnice nie stanowią problemu w tekście jawnym. Na potrzeby uwierzytelniania tak serwer jak i klient muszą używać tego samego sposobu kodowania żeby zapewnić zgodność sygnatur.
Używana przez nas funkcja jest prawie zgodna z REF-3986 (sekcja 2.1) z różnicą kodowania 3 znaków, mianowicie:
- ‘<space>’ kodowana jest jako ‘+’ a nie ‘%20’
- ‘*’ nie podlega kodowaniu i pozostaje ‘*’ zamiast ‘%2A’
- ‘~’ kodowana jest jako ‘%7E’ zamiast ‘~’
Dodatkowo zakładamy, że HEX w reprezentacji procentowej jest upper case i koduje on wartość UTF-8 danego znaku. Czyli znak “=” zamieniamy na na “%3D” a nie na “%3d”. Natomiast znak “Ł” zamieniamy na “%C5%81” zgodnie z jego reprezentacją w UTF-8 a nie na “%A3” odpowiadające CP1250.
Dla uszczegółowienia poniżej jest tabela z przykładowymi odwzorowaniami:
Znak |
Wartość URL_ENCODING |
A |
A |
B |
B |
C |
C |
D |
D |
a |
a |
b |
b |
c |
c |
d |
d |
0 |
0 |
1 |
1 |
2 |
2 |
3 |
3 |
<space> |
+ |
! |
%21 |
" |
%22 |
# |
%23 |
$ |
%24 |
% |
%25 |
& |
%26 |
' |
%27 |
( |
%28 |
) |
%29 |
* |
* |
+ |
%2B |
, |
%2C |
- |
- |
. |
. |
/ |
%2F |
: |
%3A |
; |
%3B |
< |
%3C |
= |
%3D |
> |
%3E |
? |
%3F |
@ |
%40 |
[ |
%5B |
] |
%5D |
^ |
%5E |
_ |
_ |
` |
%60 |
{ |
%7B |
| |
%7C |
} |
%7D |
~ |
%7E |
Ł |
%C5%81 |
ł |
%C5%82 |
Ó |
%C3%93 |
ó |
%C3%B3 |
€ |
%E2%82%AC |
Ā |
%C4%80 |
Znane biblioteki w różnych językach programowania zgodne z URL_ENCODING
- Java:
funkcja java.net.URLEncoder.encode(String, String) z jre
http://docs.oracle.com/javase/8/docs/api/java/net/URLEncoder.html - C#: Spośród znanych nam implementacji tej funkcji (HttpUtility.UrlEncode, HttpUtility.UrlEncodeUnicode, HttpUtility.UrlPathEncode, Uri.EscapeDataString, Uri.EscapeUriString, HttpUtility.HtmlEncode, HttpUtility.HtmlAttributeEncode, Uri.HexEscape) żadna nie jest w 100% zgodna z naszymi wymaganiami. Najbliżej ich jest HttpUtility.UrlEncode z tym, że reprezentacja “procentowa” nie jest uppercase.
(ostatnia aktualizacja 19.05.2021)
Komentarze
Komentarze: 0
Zaloguj się, aby dodać komentarz.