PDW Sp. z o. o. Dokumentacja techniczna API Przygotował: Tomasz Meka (tomek@elibri.com.pl)
Platforma - Dokumentacja techniczna API, Strona 2 Spis treści 1. Historia zmian 2. Wstęp 3. Protokół komunikacji 4. Rejestracja transakcji 5. Pobranie listy dostępnych produktów 6. Pobranie listy wkrótce dostępnych produktów 7. Pobranie listy wkrótce niedostępnych produktów 8. Specyfikacja wymiany plików 9. Specyfikacja szyfrowania plików 10. Anulowanie transakcji 11. Zgłoszenie reklamacji 12. Awaryjne wyłączenie pliku 13. Pobranie listy przygotowanych promocji w systemie 14. Lista dostępnych serwerów 15. Przykład kodu w PHP
Platforma - Dokumentacja techniczna API, Strona 3 Historia zmian 7 marca 2013 pierwsza wersja dokumentu Tomasz Meka Do dyskusji jest procedura awaryjnego wyłączania sprzedaży produktu. 26 marca 2013 Tomasz Meka Informacja o szyfrowaniu przekazywanych plików 4 kwietnia 2013 Tomasz Meka Przy pobieraniu pliku serwer może zwrócić kod 302 (przekierowanie na inny url) 4 kwietnia 2013 Tomasz Meka Specyfikacja xml-a z informacją o promocjach 8 kwietnia 2013 Tomasz Meka Poprawiona informacja o wygasających plikach 16 kwietnia 2013 Tomasz Meka Dodana możliwość anulowania transakcji 16 kwietnia 2013 Tomasz Meka Informacja, jakie metody obsługiwane są na zapasowych serwerach 29 kwietnia 2013 Tomasz Meka Zmiana trybu pobierania zaszyfrowanych plików master
Platforma - Dokumentacja techniczna API, Strona 4 O systemie Platforma Dystrybucyjna Wydawnictw Sp. z o.o. (dalej zwana Platformą) jest spółką założoną przez jedne z największych wydawnictw beletrystycznych w Polsce. Wydawnictwa-założyciele zdecydowali oddać Platofmie do wyłącznej dystrybucji wydawane przez siebie e-booki. W celu obsługi tej sprzedaży powstał system informatyczny, którego zadaniem jest automatyzacja wymiany informacji i plików pomiędzy Platformą a Dystrybutorami (zwanymi w tym dokumencie również sklepami) Komunikacja pomiędzy Dystrybutorem a systemem Platformy odbywa się poprzez API, opisane w poniższym dokumencie. Proces wymiany informacji zaczyna się od metadanych książki. Wydawnictwa zrzeszone w Platformie wykorzystują w tym celu platformę elibri. Opis API metadanych znajduje się pod adresem https://www.elibri.com.pl/doc/api Wydawnictwa eksportują na platformę pliki, które następnie są udostępniane Dystrybutorom na kilka dni przed rozpoczęciem sprzedaży (opis mechanizmu). Za pomocą tego mechanizmu dostarczane są także uaktualnienia plików. Każdy Dystrybutor otrzymuje treść unikalnie znakowaną, co w przypadku odnalezienia jej w internecie, gdzie została nieprawnie udostępniona lub wykorzystana, pozwala ustalić, przez którego z Dystrybutorów plik ten został sprzedany. Dystrybutor może w każdej chwili pobrać listę dostępnych, wygasających oraz przewidywanych do sprzedaży wkrótce produktów. Listy te mogą być różne dla różnych Dystrybutorów, w zależności od zapisanych w systemie przedsprzedaży lub ewentualnych blokad współpracy między Wydawcą a Dystrybutorem. Przed oznaczeniem pliku Dystrybutor jest zobowiązany do zarejestrowania transakcji w systemie dystrybucyjnym Platformy. Tylko takie zarejestrowanie będzie oznaczało możliwość sprzedaży pliku odbiorcy końcowemu. Platforma gwarantuje, że wszystkie E-publikacje, znajdujące się na liście aktualnie dostępnych E-publikacji, będą dostępne dla Dystrybutora do następnego dnia Roboczego, do godziny 12.00 (CET), chyba, że została podana data wygaśnięcia możliwości sprzedaży danej E-publikacji. Po dokonaniu transakcji Dystrybutor ma prawo zgłoszenia reklamacji. Może mieć to miejsce w przypadku, jeśli odbiorca końcowy wycofa się z transakcji (wybrał nieprawidłową książkę, dokonał zwrotu towaru itd). Tak zgłoszona transakcja nie będzie brana pod uwagę w rozliczeniach sprzedaży. Właścicielami oprogramowania jest Platforma Dystrybucyjna Wydawnictw Sp. z o.o., do której należą: Wydawnictwo Czarna Owca Sp. z o.o. Dom Wydawniczy REBIS Sp. z o.o. Wydawnictwo NASZA KSIĘGARNIA Sp. z o.o. Prószyński Media Sp. z o.o. Sonia Draga Sp. z o.o. Wydawnictwo Literackie sp. z o.o. Zysk i S-ka Wydawnictwo Protokół komunikacji Komunikacja z serwerem Platformy odbywa się poprzez protokół HTTP z wykorzystaniem metod GET i POST. Metoda GET służy do pobierania danych, POST służy do wywołania operacji modyfikujących. W przypadku powodzenia operacji serwer zwraca kod HTTP 200 OK. Każdy dystrybutor dostaje token publiczny i prywatny (secret) pierwszy służy do identyfikacji dystrybutora, drugi do podpisywania transakcji. Każde wywołanie metod wymaga przynajmniej trzech parametrów, które służą autentykacji i autoryzacji: token - token otrzymany od Platformy jednoznacznie identyfikujący dystrybutora timestamp - Liczba sekund, która upłynęła od 1 stycznia 1970 roku (Ruby: Time.now.to_i, PHP: time()) sig - Podpis zlecenia za pomocą algorytmu HMAC (stamp jest kluczem, secret podpisywaną wartością) Przykład w Ruby: timestamp = Time.now.to_i hmac = OpenSSL::HMAC.digest('sha1', timestamp.to_s, self.secret) sig = CGI.escape(Base64.encode64(hmac).strip) Przykład w PHP: $stamp = time(); $hmac = hash_mac("sha1", $this->secret, $stamp, true); $sig = rawurlencode(base64_encode($hmac));
Platforma - Dokumentacja techniczna API, Strona 5 W przypadku błędu autoryzacji albo autentykacji mogą zostać zwrócone następujące kody http (wraz z komunikatem o błędzie): 400 zostały podane błędne parametry 401 został podany nieprawidłowy token publiczny lub parametr sig jest błędny 403 nie został znaleziony produkt lub produkt nie jest dostępny (np. nie nastąpiła jeszcze premiera produktu) 408 parametr stamp jest błędny (różnica większa niż 60 sekund) 500 wystąpił wewnętrzny błąd serwera, operacja musi zostać powtórzona z innym serwerem Rejestracja transakcji Dystrybutor jest zobowiązany do zarejestrowania transakcji przed rozpoczęciem watermarkowania plików. Zwrotnie otrzymuje identyfikator transakcji, który powinien zostać użyty jako element watermarka. Ponieważ od momentu złożenia zamówienia przez klienta do dokonania płatności może minąć kilka dni (jest to rzadkie, ale nie można wykluczyć, że klient zapłaci na przykład na poczcie), transakcja może być zarejestrowana przed dokonaniem płatności przez klienta. W takiej sytuacji unikamy problemu, który mógłby powstać, gdyby plik był niedostępny w momencie rejestracji płatności od klienta. Transakcje, które nie zostaną opłacone przez klienta, mogą zostać anulowane w ciągu 14 od zarejestrowania transakcji. POST https://www.platformapdw.pl/api/transactions/new Parametry: isbn lub record_reference - Isbn lub record_reference produktu. record_reference to wewnętrzny identyfikator elibri. netto_price - cena zakupu netto produktu od Platformy client_ip - numer IP klienta (ostatnie dwie cyfry mogą zostać usunięte) order_id - alfanumeryczny numer zamówienia po stronie dystrybutora. Musi być unikalny dla każdego rejestrowanego produktu. W przypadku, gdy klient złożył w systemie dystrybutora zamówienie na kilka ebooków na raz, można jako numer zamówienia zastosować kombinację EAN-u i numeru zamówienia w systemie dystrybutora token timestamp sig Zwracane wartości: Jeśli zlecenie zostało przyjęte, serwer zwraca status 200, a wysłana odpowiedź to alfanumeryczny identyfikator transakcji (trans_id). W przypadku braku zgody na zrealizowanie transakcji, zostanie zwrócony kod 403 wraz z dokładną przyczyną niewyrażenia zgody. Pobranie listy dostępnych produktów Wywołanie to pozwala na pobranie listy dostępnych produktów w postaci json lub xml. GET https://www.platformapdw.pl/api/products/available.json lub GET https://www.platformapdw.pl/api/products/available.xml Parametry
Platforma - Dokumentacja techniczna API, Strona 6 token timestamp sig Jeśli żądanie zostanie przyjęte, serwer zwraca status 200, a w treści znajduje się odpowiednio JSON lub XML, zawierający informacje o dostępnych produktach. System daje gwarancję, że wymienione pliki będą dostępne przynajmniej przez najbliższą godzinę chyba że obok produktu jest podany klucz/tag available_until. Dotyczy to sytuacji, gdy pobieramy listę plików np. o 23:30, a kilka plików jest dostępnych tylko do północy. Te pliki nie będą dostępne przez następną godzinę, a tylko do północy. Tak oznaczone będą też pliki, które mają zostać awaryjnie wyłączone. Przykład w formacie json: [{"record_reference":"f7ad69f3b59a6b83acb9", "isbn":"9788310122797", "title":"czarna owieczka", "publisher_name":"nasza Ksigarnia", "publisher_id":41, {"record_reference":"eee4ed21bc7f36c268a7", "isbn":"9788310124845", "title":"xanth 4", "publisher_name":"nasza Ksigarnia", "available_until":"2013-03-16t00:00:00+01:00", "publisher_id":41] Przykład w formacie xml: <?xml version="1.0" encoding="utf-8"?> <products> <record_reference> fb852defe72f14a88249</record_reference> <isbn> 9788310124296</isbn> <title> O wróbelku Elemelku</title> <publisher_name> Nasza Ksigarnia</publisher_name> <publisher_id> 41</publisher_id> <record_reference> 9a5730235bed940e34ae</record_reference> <isbn> 9788310124777</isbn> <title> Mateuszek</title> <publisher_name> Nasza Ksigarnia</publisher_name> <publisher_id> 41</publisher_id> <available_until> 2013-03-15T00:00:00+01:00</available_until> </products> Pobranie listy wkrótce dostępnych produktów Wywołanie to pozwala na pobranie listy wkrótce dostępnych produktów w postaci json lub xml (wraz z datą dostępności). GET https://www.platformapdw.pl/api/products/soon_available.json lub GET https://www.platformapdw.pl/api/products/soon_available.xml Parametry token timestamp
Platforma - Dokumentacja techniczna API, Strona 7 sig Zwracane wartości Jeśli żądanie zostanie przyjęte, to serwer zwraca status 200, a w treści znajduje się odpowiednio JSON lub XML, zawierający informacje o wkrótce dostępnych produktach. Podane daty zawsze są w formacie yyyy-mm-dd Przykład w formacie json: [{"record_reference":"790f181d7dfe423c91eb", "isbn":"9788310124647", "title":"niewolnice", "publisher_name":"nasza Ksigarnia", "available_date":"2013-03-16", "publisher_id":41, {"record_reference":"2cf197873e8299040dce", "isbn":"9788310124654", "title":"stranicy Nirgali", "publisher_name":"nasza Ksigarnia", "available_date":"2013-03-16", "publisher_id":41] Przykład w formacie xml: <?xml version="1.0" encoding="utf-8"?> <products> <record_reference> fbf958a53f01515078cd</record_reference> <isbn> 9788310124739</isbn> <title> wiat Czarownic</title> <publisher_name> Nasza Ksigarnia</publisher_name> <publisher_id> 41</publisher_id> <available_date> 2013-01-23</available_date> <record_reference> 582caadd81cf58d7c606</record_reference> <isbn> 9788310124753</isbn> <title> Szewczyk Dratewka</title> <publisher_name> Nasza Ksigarnia</publisher_name> <publisher_id> 41</publisher_id> <available_date> 2013-03-15</available_date> </products> Pobranie listy wkrótce niedostępnych produktów Wywołanie to pozwala na pobranie listy wkrótce niedostępnych produktów w postaci json lub xml (wraz z datą planowanego wycofania z dystrybucji). GET https://www.platformapdw.pl/api/products/soon_unavailable.json lub GET https://www.platformapdw.pl/api/products/soon_unavailable.xml Parametry token timestamp sig
Platforma - Dokumentacja techniczna API, Strona 8 Zwracane wartości Jeśli żądanie zostanie przyjęte, to serwer zwraca status 200, a w treści znajduje się odpowiednio JSON lub XML, zawierający informacje o wkrótce niedostępnych produktach. Przykład w formacie json: [{"record_reference":"790f181d7dfe423c91eb", "isbn":"9788310124647", "title":"niewolnice", "publisher_name":"nasza Ksigarnia", "unavailable_date":"2013-03-16t00:00:00+01:00", "publisher_id":41, {"record_reference":"2cf197873e8299040dce", "isbn":"9788310124654", "title":"stranicy Nirgali", "publisher_name":"nasza Ksigarnia", "unavailable_date":"2013-03-16t00:00:00+01:00", "publisher_id":41] Przykład w formacie xml: <?xml version="1.0" encoding="utf-8"?> <products> <record_reference> fbf958a53f01515078cd</record_reference> <isbn> 9788310124739</isbn> <title> wiat Czarownic</title> <publisher_name> Nasza Ksigarnia</publisher_name> <publisher_id> 41</publisher_id> <unavailable_date> 2013-01-23T00:00:00+01:00</unavailable_date> <record_reference> 582caadd81cf58d7c606</record_reference> <isbn> 9788310124753</isbn> <title> Szewczyk Dratewka</title> <publisher_name> Nasza Ksigarnia</publisher_name> <publisher_id> 41</publisher_id> <unavailable_date> 2013-03-15T00:00:00+01:00</unavailable_date> </products> Specyfikacja wymiany plików [UWAGA]: zmiana 29. kwietnia 2013 Wymiana plików master odbywa się poprzez bucket pdw-delivery-files na amazon S3. Każdy dystrybutor otrzymuje dedykowany katalog oraz klucze dostępowe do bucketu. Dystrybutor jest zobowiązany do regularnego sprawdzania bucketu (przynajmniej raz każdego dnia roboczego), pobierania nowych i zaktualizowanych plików. Pobrany plik powinien zostać wykasowany z S3 po umieszczeniu go w systemie dystrybutora. Każdy plik umieszczony na S3 ma nazwę w formacie {record_reference.{file_type, i następujące metadane: isbn - isbn produktu type - typ pliku (jednozczny z rozszerzeniem pliku) record_reference - record reference produktu Jako type mogą występować następujące typy: mobi, mobi_excerpt, epub, epub_excerpt, mp3, mp3_excerpt, pdf, pdf_excerpt Przykład w ruby:
Platforma - Dokumentacja techniczna API, Strona 9 require 'rubygems' require 'aws-sdk' access = { "access_key_id"=>"xxx", "secret_access_key" => "xxx", "s3_endpoint"=>"s3-eu-west-1.amazonaws.com" s3 = AWS::S3.new(access) bucket = s3.buckets['pdw-delivery-files'] bucket.objects.with_prefix(distributor_directory).to_a.each do object puts object.key #nazwa pliku data = object.read #pobierz zawarto pliku open(object.key, "w") do f f.write data #nagraj lokalnie end object.delete #wykasuj z S3 end Szyfrowanie plików Pliki przekazywane dystrybutorom są szyfrowane przy użyciu biblioteki OpenSSL Dystrybytor powinien po swojej stronie wygenerować klucz publiczny (plik publickey.pem) i klucz prywatny (plik privatekey.pem), używając polecenia: openssl req -x509 -nodes -days 100000 -newkey rsa:2048 -keyout privatekey.pem -out publickey.pem Dystrybutor przekazuje Platformie drogą mailową swój klucz publiczny (publickey.pem), który to Platforma używa do szyfrowania plików: openssl smime -encrypt -aes256 -in <input_file.epub> -binary -outform DEM -out <encrypted.epub> publickey.pem Dystrybutor po odebraniu pliku od Platformy może go odkodować używając polecenia: openssl smime -decrypt -in <encrypted.epub> -binary -inform DEM -inkey privatekey.pem -out <decrypted.epub> Anulowanie transakcji Jeśli dystrybutor zarejestruje transakcję przed dokonaniem płatności przez klienta, może ją anulować w ciągu 14 dni, jeśli klient nie dokona płatności. POST https://www.platformapdw.pl/api/cancellations/new Parametry trans_id - identyfikator transakcji, która ma zostać zareklamowana token timestamp sig Zwracane wartości: Serwer zwraca kod HTTP 200 OK, jeśli anulowanie transakcji się powiodło Zgłoszenie reklamacji W przypadku, gdy klient złoży w sklepie reklamację i zostanie ona uznana, należy ten fakt zgłosić Platformie, żeby tak zgłoszona transakcja nie została rozliczona na fakturze. Reklamacje są na poziomie technologicznym zawsze rejestrowane.
Platforma - Dokumentacja techniczna API, Strona 10 POST https://www.platformapdw.pl/api/complaints/new Parametry trans_id - identyfikator transakcji, która ma zostać zareklamowana reason - tekstowa informacja wyjaśniająca powód reklamacji token timestamp sig Zwracane wartości: Serwer zwraca kod HTTP 200 OK, jeśli złożenie transakcji się powiodło. Awaryjne wyłączenie pliku Platforma powinna być w stanie zażądać natychmiastowego wycofania produktu ze sprzedaży. W tym celu dystrybutor powinien podać URL, pod który powinno zostać wysłane żądanie wycofania produkty ze sprzedaży wraz z podaniem powodu wycofania. Do ustalenia jest, przez jaki czas plik ma się znajdować jeszcze w sprzedaży. Pobranie listy przygotowanych w systemie promocji Wydawcy zrzeszeni w Platformie mogą przeprowadzać promocje cenowe, udzielając dodatkowego rabatu, naliczanego kaskadowo, albo udzielając innego, wyższego rabatu. Przykład obliczenia rabatu kaskadowego: klient A ma standardowo rabat 20%. Jeśli podczas promocji zostanie mu udzielony kaskadowo dodatkowy rabat 10%, to książka o cenie netto 10 zł zostanie sprzedana za (10 * 0,8) * 0,9 = 7,20 zł. Dystrybutor może pobrać ze strony www Platformy zdefiniowane dla niego promocje w formacie xml. Przykład promocji: <?xml version="1.0" encoding="utf-8"?> <promotion> <id> 11</id> <name> Promocja na kryminay z Czarnej Serii</name> <start_date> 2013-03-06</start_date> <end_date> 2013-03-11</end_date> <products> <isbn> 9788375545746</isbn> <record_reference> e9febde96563631a2f56</record_reference> <title> Najpikniejszy kraj</title> <cascade> true</cascade> <discount> 15</discount> <isbn> 9788375544381</isbn> <record_reference> 8ea13cd21c2a519c9324</record_reference> <title> Zamiast ciebie</title> <cascade> true</cascade> <discount> 15</discount> </products> </promotion> Jeśli w tagu cascade wystąpuje wartość true, to wartość w polu discount jest dodatkowym, liczonym kaskadowo rabatem, wartość false oznacza, że rabat podany w polu discount jest rabatem, jaki będzie naliczany od sugerowanej detalicznej ceny książki. Lista dostępnych serwerów
Platforma - Dokumentacja techniczna API, Strona 11 Żeby zapewnić bardzo wysoką dostępność usługi, utrzymujemy przynajmniej trzy niezależne (umiejscowione w różnych serwerowniach) serwery do rejestracji transakcji. Lista serwerów nie jest stała, może się zmieniać w zależności od czasowego obciążenia serwerów, lub ze względu na planowe prace serwisowe w serwerowniach. Listę serwerów można odczytać w DNS-ie z rekordu TXT domeny transactional-servers.platformapdw.pl. Jest to lista subdomen platoformapdw.pl, rozdzielona przecinkami. Uwaga! Na zapasowych serwerach są dostępne jedynie metody gwarantujące ciągłość sprzedaży: available_products, soon_available_products, soon_unavailable_products oraz rejestracja transakcji. Pozostałe metody są dostępne tylko na głównym serwerze platformy, www.platformapdw.pl Na konsoli można to sprawdzić za pomocą np. nslookup: > nslookup -q=txt transactional-servers.platformapdw.pl transactional-servers.platformapdw.pl text = "www,api" W powyższym przykładzie serwer watermarkingu jest dostępny pod dwoma adresami: www.elibri.platformapdw.pl i api.platformapdw.pl. Proponujemy, żeby wybrać w losowy sposób jeden z dostępnych serwerów, i zarejestrować w nim transakcję. W przypadku, gdy pierwszy wybrany serwer nie odpowie, albo nawiązanie połączenia nie będzie możliwe, albo zwrócony kod HTTP będzie inny, niż 200, proszę wybrać kolejny serwer i spróbować ponownie zarejestrować transakcję. Przykład kodu w PHP Poniższy kod prezentuje, jak można zaimplementować pobieranie listy dostępnych produktów oraz zarejestrować transakcję: <?php //! @brief Wyjatek uzywany w przypadku wystapienia bledu polaczenia z serwerem class PDWAPIConnectionException extends Exception { //! konstruktor wyjatku w przypadku bledu zwroconego przez curl-a function construct($msg, $errno) { parent:: construct($msg, $errno); //! @brief Wyjatek - Podane zostaly bledne parametry class PDWParametersError extends Exception { function construct($msg) { parent:: construct($msg, 400); //! @brief Wyjatek - brak autoryzacji class PDWInvalidAuthException extends Exception { function construct() { parent:: construct("unauthorized", 401); //! @brief Wyjatek po stronie serwera (Internal server error) class PDWServerErrorException extends Exception { function construct() { parent:: construct("server Error", 500); //! @brief Wyjatek po stronie serwera (Forbidden) class PDWForbiddenException extends Exception { function construct($msg) { parent:: construct($msg, 403); //! @brief Wyjatek po stronie serwera (Request Expired) - zle ustawiony czas lokalnie class PDWRequestExpiredException extends Exception {
Platforma - Dokumentacja techniczna API, Strona 12 function construct() { parent:: construct("request Expired", 408); //! @brief Wyjatek - Nieprawidlowy login lub haslo class PDWNotFoundException extends Exception { function construct() { parent:: construct("invalid url or http method", 404); //! @brief Wyjatek - nieznany blad class PDWUnknownException extends Exception { function construct() { parent:: construct("unknow error", 1000); //! @brief Wyjatek - zaden serwer nie odpowiada class PDWNoServerResponsingException extends Exception { function construct() { parent:: construct("no server responsing", 1001); //! @brief PDWAPI abstrahuje wykorzystanie API PDW class PDWClient { private $token; private $secret; private $subdomains; //! @brief Kontruktor obiektu API //! @param String $token - publiczny token //! @param String $secret - prywatny token function construct($token, $secret) { $this->token = $token; $this->secret = $secret; $this->subdomains = $subdomains; //! @brief Rejestruj transakcje //! @param String $ident - ISBN13 (bez myslikow), lub record_reference //! @param String $client_ip - numer IP klienta, uzywany w celach wylacznie statystycznych //! @param float $netto_price - cena zakupu ksiazki w PDW netto //! @param String $order_id - numer zamowienia po stronie dystrybutora //! @return $transid - alfanumeryczny identyfikator transakcji function register_transaction($ident, $client_ip, $netto_price, $order_id) { if (preg_match('/^[0-9]+$/', $ident)) { $ident_type = 'isbn'; else { $ident_type = 'record_reference'; $data = array($ident_type => $ident, 'client_ip' => $client_ip, 'netto_price' => $netto_price, 'order_id' => $order_id); return $this->send_request('transactions/new', $data, TRUE); //! @brief Pobierz liste dostepnych plikow //! Za pomoca tej metody mozesz pobrac liste ksiazek, ktore sa lub beda w najblizszym czasie dostepne //! w systemie PDW function available_products() { return json_decode($this->send_request('available_products.json', array(), FALSE), TRUE); private function send_request($method_name, $data, $do_post) { $stamp = time(); $sig = rawurlencode(base64_encode(hash_hmac("sha1", $this->secret, $stamp, true))); $data['stamp'] = $stamp; $data['sig'] = $sig; $data['token'] = $this->token;
Platforma - Dokumentacja techniczna API, Strona 13 $uri = "https://www.platformapdw.pl/api/$method_name"; if (!$do_post) { $uri = $uri. "?". http_build_query($data, '', '&'); $ch = curl_init($uri); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); if ($do_post) { curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data, '', '&')); $curlresult = curl_exec($ch); try { return $this->validate_response($curlresult, $ch); catch (PDWServerErrorException $e) { //silency ignore this error catch (PDWUnknownException $e) { //silency ignore this error catch (PDWAPIConnectionException $e) { //silency ignore this error throw new PDWNoServerResponsingException(); private function validate_response($curlresult, $ch) { if ($curlresult === FALSE) { throw new PDWAPIConnectionException(curl_error($ch), curl_errno($ch)); $response_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); if ($response_code == 404) { throw new PDWNotFoundException(); else if ($response_code == 408) { throw new PDWRequestExpiredException(); else if ($response_code == 400) { throw new PDWParametersError($curlResult); else if ($response_code == 403) { throw new PDWForbiddenException($curlResult); else if ($response_code == 500) { throw new PDWServerErrorException(); else if ($response_code == 401) { throw new PDWInvalidAuthException(); else if (($response_code!= 200) && ($response_code!= 412)) { throw new PDWUnknownException(); return $curlresult;?>