Jednym z wyzwań dotyczących integracji systemów informatycznych jest komunikacja między serwerami – działanie niezbędne w celu wymiany danych pomiędzy różnymi aplikacjami. W przypadku oprogramowania sklepu internetowego takim przykładem  jest wymiana danych np. z systemem klasy ERP, z firmą logistyczną, czy narzędziem do e-mail marketingu.

Konieczność komunikacji między serwerami często doprowadza do sytuacji, w której sklep internetowy jest cyklicznie odpytywany przez aplikacje zewnętrzne w celu weryfikacji wystąpienia ewentualnych zmian.

Intesyfikacja zapytań może doprowadzić do problemów z wydajnością sklepu, ponieważ zautomatyzowane requesty potrafią mocno obciążyć serwer aplikacji. Co więcej ciężko wychwycić tę zależność w statystykach samego sklepu, ponieważ requestów jest zazwyczaj dużo mniej niż odwiedzin użytkowników na froncie sklepu. Często w przypadku większej liczby integracji, a co za tym idzie, większej ilości zapytań, dochodzi do rozłożenia ich w czasie, by nie powodować problemów z wydajnością. W konsekwencji czego dane nie są przekazywane na bieżąco, co z kolei powoduje opóźnienie innych procesów biznesowych (np. niezaktualizowanie się listy zamówień może spowodować opóźnienia w przesyłkach). W perspektywie rozwoju systemu trzeba ten fakt przewidzieć i zastosować odpowiednie rozwiązania.

Odpowiedzią są Webhooks!

Webhooks to nowy mechanizm w sklepach Shoper, pozwalający na wysyłanie requestów pod ustalony przez administratora adres url, bezpośrednio po wykonaniu zdefiniowanych wcześniej akcji np. po opłaceniu zamówienia czy rejestracji klienta (pełna lista zdarzeń została dołączona na dole artykułu). Rozwiązanie zapewnia prostą i skuteczną metodę komunikacji pomiędzy sklepem a serwerem zewnętrznym, bez potrzeby cyklicznego odpytywania aplikacji.
Dzięki temu:

  • otrzymujemy powiadomienia o zdarzeniach dokładnie w momencie ich zaistnienia, bez konieczności zbyt częstego odpytywania aplikacji, możemy wydajniej synchronizować dane pomiędzy serwerami,
  • mamy możliwość tworzenia łańcuchów zdarzeń – np. sklep wysyła informację na serwer, który będzie się dalej komunikował np. z aplikacją ERP
  • rozszerzamy działanie aplikacji sklepu o funkcje komplementarne np. wysłanie potwierdzenia dokonania zamówienia dodatkowo poprzez sms, możemy rozbudować sklep o całkiem nową funkcjonalność.

Możliwości jest sporo i wszystko zależy od naszej kreatywności. Co więcej możemy uzyskać nową funkcjonalność w sklepie bez konieczności edycji jego kodu. Wszystko to jest możliwe przy zachowaniu bezpieczeństwa: szyfrowaniu przesyłania danych poprzez certyfikat SSL, weryfikacji autentyczności requestu za pomocą sumy kontrolnej czy wreszcie (w niektórych przypadkach) weryfikacji sklepu po IP.

Przykładowy skrypt odbierający webhooka:

<?php
$secret_key = '12345′;
$data = file_get_contents(„php://input”);

$log .= “Data: “.date(“Y-m-d H:i:s”).PHP_EOL;
$log .= “Suma kontrolna: “. sha1($_SERVER[’HTTP_X_WEBHOOK_ID’] . ’:’ . $secret_key . ’:’ . $data) . PHP_EOL;

if(    empty($data) ||
!isset($_SERVER[’HTTP_X_WEBHOOK_ID’]) ||
!isset($_SERVER[’HTTP_X_WEBHOOK_SHA1′]) ||
sha1($_SERVER[’HTTP_X_WEBHOOK_ID’] . ’:’ . $secret_key . ’:’ . $data) !== $_SERVER[’HTTP_X_WEBHOOK_SHA1′]
) {
$log.= “Invalid Hash”.PHP_EOL;
}

$log .= 'SHOP VERSION: ’ . $_SERVER[’HTTP_X_SHOP_VERSION’] . PHP_EOL;
$log .= 'SHOP HOSTNAME: ’ . $_SERVER[’HTTP_X_SHOP_DOMAIN’] . PHP_EOL;
$log .= 'SHOP LICENSE: ’ . $_SERVER[’HTTP_X_SHOP_LICENSE’] . PHP_EOL;
$log .= 'WEBHOOK ID: ’ . $_SERVER[’HTTP_X_WEBHOOK_ID’] . PHP_EOL;
$log .= 'WEBHOOK NAME: ’ . $_SERVER[’HTTP_X_WEBHOOK_NAME’] . PHP_EOL;
$log .= 'WEBHOOK SHA1: ’ . $_SERVER[’HTTP_X_WEBHOOK_SHA1′] . PHP_EOL;
$log .= 'USERAGENT: ’ . $_SERVER[’HTTP_USER_AGENT’] . PHP_EOL;

preg_match(’/^(.*); charset=(.*)$/’, $_SERVER[’CONTENT_TYPE’], $matches);

$log .= 'CONTENT TYPE: ’ . $matches[1] . PHP_EOL;
$log .= 'ENCODING: ’ . $matches[2] . PHP_EOL;
$log .= ‘DATA: ’. $data. PHP_EOL;

if($matches[1] === 'application/json’) {
$data = json_decode($data);
// …
} elseif($matches[1] === 'text/xml’) {
$data = simplexml_load_string($data);
// …
} else {
$log.= “Content type not supported”.PHP_EOL;
}

file_put_contents(“log.txt”, $log, FILE_APPEND);

Zachęcamy do wypróbowania swoich własnych Webhooks używając np. http://requestb.in/

Do każdego wysłanego webhooka dołączane są następujące nagłówki:

NagłówekOpis
HTTP_CONTENT_TYPEW zależności od wybranego formatu danych: application/json lub text/xml
HTTP_X_SHOP_VERSIONWersja sklepu
HTTP_X_SHOP_DOMAINHostname sklepu
HTTP_X_WEBHOOK_IDIdentyfikator webhooka
HTTP_X_WEBHOOK_NAMENazwa webhooka
HTTP_X_WEBHOOK_SHA1Suma kontrolna SHA1 wysyłanych danych liczona w następujący sposób:sha1({webhook_id}:{user_secret}:{webhook_data})

  • {webhook_id} – to identyfikator webhooka podany w nagłówku HTTP_X_WEBHOOK_ID
  • {user_secret} – to sekretna fraza podana podczas tworzenia webhooka
  • {webhook_data} – string danych wysyłanych w ramach requestu.
HTTP_X_SHOP_LICENSEIdentyfikator licencji sklepu służący do rozpoznania instancji sklepu

Obsługiwane zdarzenia:
order.create – Wysyła dane o zamówieniu po utworzeniu nowego obiektu
order.edit – Wysyła dane o zamówieniu po edycji obiektu
order.paid – Wysyła dane o zamówieniu po jego opłaceniu
order.status – Wysyła dane o zamówieniu po zmianie jego statusu
order.delete – Wysyła dane o zamówieniu po usunięciu obiektu
client.create – Wysyła dane o kliencie po utworzeniu nowego obiektu
client.edit – Wysyła dane o kliencie po edycji obiektu
client.delete – Wysyła dane o kliencie po usunięciu obiektu
product.create – Wysyła dane o produkcie po utworzeniu nowego obiektu
product.edit – Wysyła dane o produkcie po edycji obiektu
product.delete – Wysyła dane o produkcie po usunięciu obiektu
parcel.create – Wysyła dane o przesyłce po utworzeniu nowego obiektu
parcel.dispatch – Wysyła dane o przesyłce po oznaczeniu jej jako wysłana
parcel.delete – Wysyła dane o przesyłce po usunięciu obiektu