Jak zlecac przelewy

Wstęp home

link Wypróbuj

Wypróbuj działanie Espago API. Obciąż pierwszego klienta wykonując poniższe kroki:

W pierwszym kroku zostanie wywołany iFrame, który pozwala zebrać i przesłać dane karty bezpośrednio do bramki Espago w celu uzyskania tokenu, a następnie umieści otrzymany token w formularzu na stronie sklepu.
Należy użyć karty o numerze 4242 4242 4242 4242, dacie wygaśnięcia 02/2025 i kodzie CVV 123.
Wypróbuj
<!-- konfiguracja iFrame -->
<script 
  async=""
  data-id="EspagoFrameScript"
  data-key="VrYVaA1CjmRooKh63YYv"
  data-live="false"
  data-button="Pay"
    src="https://js.espago.com/iframe.js">
</script>

<!-- formularz z tokenem -->
<form id="espago_form" 
      action="/charge_client" 
      accept-charset="UTF-8" 
      method="post">
</form>
Następnie zostanie wysłane właściwe zapytanie do bramki Espago. Składa się ono kolejno z: nagłówka wskazującego wersję API, danych uwierzytelniających użytkownika, kwoty i waluty. Pole card zwiera token uzyskany w poprzednim kroku, dzięki czemu aplikacja sprzedawcy nie musi przetwarzać danych karty..
curl -i https://sandbox.espago.com/api/charges \
 -H "Accept: application/vnd.espago.v3+json" \
 -u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
 -d "amount=10" \
 -d "currency=pln" \
 -d "card=[card_token]" \
 -d "description=Espago docs"
Spodziewana odpowiedź od bramki Espago w formacie json. Kluczowymi informacjami są tutaj id i state. Więcej na temat back requestów
{
 "id":"pay_7715NocOaPcNTL9O",
 "description":"Espago docs", 
 "channel":"elavon",
 "amount":"10.00",
 "currency":"pln",
 "state":"executed",
 [...]
}

link Opis bramki

Bezpieczeństwo bramki płatności Espago

Dane kart płatniczych są przechowywane przez Espago w sposób bezpieczny i zgodny z najwyższym poziomem standardu PCI DSS - Level 1. Zgodność ze standardem weryfikują i potwierdzają cykliczne zewnętrzne audyty, przeprowadzane przez podmioty certyfikowane przez organizacje kartowe: American Express, Discover, JCB, Mastercard i Visa - zrzeszone w ramach (PCI Security Standards Council)[https://www.pcisecuritystandards.org/about_us/].

Administratorem powierzonych Espago danych osobowych płatnika i danych kart zapisanych w Profilu Klienta jest Akceptant (Sprzedawca), ale dzięki zastosowaniu zasad przetwarzania danych zgodnych z PCI DSS, nie musi on przetwarzać i mieć bezpośredniego dostępu do pełnego numeru karty. Integracja z bramką płatniczą Espago pozwala uniknąć dodatkowych procedur i ryzyka po stronie Akceptanta.

Dane karty w Espago są szyfrowane, a unikalny identyfikator Profilu Klienta pozwala używać ich tylko temu Sprzedawcy, któremu powierzył je posiadacz karty.

W celu zapewnienia odpowiedniego poziomu bezpieczeństwa, niezbędne jest stosowanie przez Akceptanta na jego stronie (w sklepie) certyfikatu SSL (HTTPS). Niezależnie od sposobu integracji z API Espago, wszystkie dane kart płatniczej są przesyłane bezpośrednio z przeglądarki posiadacza karty do bramki Espago z użyciem protokołu HTTPS - z pominięciem serwisu Sprzedawcy. Pozwala to Akceptantowi uwolnić się od konieczności przechowywania i przetwarzania danych kart swoich klientów i wszelkich związanych z tymi procesami zagrożeń, a certyfikacja PCI DSS Sprzedawcy ogranicza się do wypełnienia ankiety po zawarciu umowy z Agentem Rozliczeniowym.

Interfejs bramki płatności Espago i struktura komunikatów

  • Architektura API jest zgodna z wzorcem REST. Wszystkie operacje związane z zarządzeniem płatnościami (inicjowanie, sprawdzenie statusu, zwroty, itd.) są realizowane przy pomocy odpowiednio przygotowanych zapytań HTTP na wskazane, odpowiadające żądaniom adresy URL (endpointy).
  • Treść zapytań w komunikacji z bramką musi być przygotowana w formacie JSON i zawierać treść niezbędną dla poszczególnych metod (lub jej nie zawierać - gdy wyraźnie to wskazano).
  • Treść odpowiedzi bramki z bramki Espago jest przekazywana w formacie JSON. Wśród zmiennych, które są charakterystyczne dla poszczególnych zapytań, przy każdym błędnym zapytaniu, w każdym elemencie tablicy asocjacyjnej errors, zwracana jest zmienna code, która zawiera usystematyzowaną informację o brakującej zmiennej obowiązkowej dla danego zapytania lub niepoprawnej wartości zmiennej. Więcej o wykorzystaniu tej informacji można przeczytać w rozdziale Odpowiedź przy błędnym zapytaniu
  • Treści przekazywane w obie strony są w kodowaniu UTF-8

Czas odpowiedzi bramki płatności Espago na zapytania HTTP

Dla zapytań API, sugerowany maksymalny czas oczekiwania na odpowiedź z Espago (timeout), to 40 sekund, przy czym zdecydowana większość płatności jest przetwarzana w czasie poniżej 2 sekund.

link Sposoby integracji

Istnieją trzy możliwości integracji z bramką płatności Espago:

Płatność na stronie Sprzedawcy wykorzystująca iframe


Umieszczenie skryptu wywołującego iframe (EspagoFrame) lub formularza obsługiwanego przez skrypt Espago JS, który pozwala zebrać dane karty od klienta, a następnie realizacja wszystkich operacji związanych z autoryzacją poprzez zapytania API (czytaj więcej)

Przekierowanie klienta ze strony Sprzedawcy na stronę płatności Espago


Przekierowanie klienta z odpowiednimi parametrami dotyczącymi płatności na bezpieczną stronę płatności Espago, a następnie odebranie informacji o wyniku płatności z bramki Espago i przyjęcie klienta przekierowanego z powrotem na stronę Sprzedawcy. (czytaj więcej)

Integracja strony Sprzedawcy z systemem Przelewy24

Płatności kartowe Espago/Elavon mogą być jedną z lub jedyną metodą płatności dostępną dla klienta poprzez Przelewy24. W takim scenariuszu nie ma potrzeby bezpośredniej integracji z bramką Espago, sprzedawca musi zintegrować sklep jedynie z modułem Przelewy24.

Jest to rozwiązanie szczególnie przydatne w sytuacjach gdy:

  • Sprzedawca jest zainteresowany również przyjmowaniem płatności przez zwykłe/szybkie przelewy bankowe
  • Sprzedawca korzysta z gotowego systemu sklepowego (PrestaShop, Magento i inne) i zależy mu na prostym podłączeniu zwykłych, jednorazowych płatności kartowych
  • Sprzedawca już wykorzystuje płatności Przelewy24

link Zmiany i wymagania wynikające z PSD2

Bramka Espago udostępnia funkcje i mechanizmy potrzebne do realizacji płatności w sposób zgodny z dyrektywą PSD2. Z punktu widzenia Sprzedawców korzystających z płatności kartowych nowe wymagania obejmują przede wszystkim dwa elementy:

1. Każda płatność internetowa inicjowana przez klienta wykorzystuje silne uwierzytelnienie (SCA) jakim jest 3-D Secure;
2. Każda subskrypcja lub zapisanie karty do obciążeń wielokrotnych rozpoczyna się od płatności z SCA, a późniejsze płatności są odpowiednio oznaczone.

Brak wdrożenia SCA będzie skutkował zwiększeniem odrzuceń płatności z użyciem kart wydanych przez europejskie banki. Do Sprzedawców należy weryfikacja i dostosowanie swojej integracji do nowych wymagań.

  1. Jeśli używają Państwo aktualnego APIv3 z włączonym zabezpieczeniem 3D-Secure dla płatności jednorazowych nie muszą Państwo wprowadzać zmian.
  2. Jeśli przed rozpoczęciem płatności cyklicznych dokonują Państwo płatności z flagą cof=storing (funkcja dodana w sierpniu 2019r) to najprawdopodobniej również nie muszą Państwo wprowadzać zmian.
  3. Jeśli Państwa aplikacja używa APIv3 ale bez użycia 3D-Secure, to zabezpieczenie musi zostać włączone i używane dla wszystkich jednorazowych płatności oraz dla płatności inicjujących recurring.
  4. Jeśli używają Państwo starego APIv2 konieczna jest migracja do APIv3.
  5. Jeśli rozpoczynają Państwo płatności cykliczne od utworzenia profilu klienta osobnym zapytaniem i jego podwójnej autoryzacji - należy zmienić proces rejestracji klienta wprowadzając SCA.

Lista kontrolna zmian związanych z PSD2

Aby upewnić się, że spełniają Państwo wymagania związane z PSD2 dotyczące akceptacji kart, należy wykonać poniższe sprawdzenie:

Pytanie Zakres zastosowania Odpowiedź: TAK
Ewentualna lista zmian
Odpowiedź: NIE
Ewentualna lista zmian
1. Czy Państwa integracja opiera się na Espago API v3? Dotyczy wszystkich klientów. Aby upewnić się czy integracja korzysta z API v3 należy sprawdzić czy stosują Państwo odpowiednie nagłówki żądań Tak - należy sprawdzić, czy spełnione są wymagania z dalszych punktów; Nie - należy dokonać integracji z API v3: migracja z API v2 ;
2. Czy wszystkie płatności inicjowane przez posiadacza karty (CIT) wykorzystują silne uwierzytelnienie (SCA)? Dotyczy wszystkich serwisów. Silne uwierzytelnienie to mechanizm 3-D Secure dostarczany przez Espago. Tak - wymaganie spełnione; Nie - należy wprowadzić zmiany:

- jeśli w zapytaniach API o obciążenie stosowany jest parametr “skip_3ds”, należy z niego zrezygnować. Jeśli silna weryfikacja nie jest możliwa ze względu na charakter płatności, należy wykorzystać mechanizm moto (parametr “moto” w żądaniu API).
3. Czy płatności cykliczne, wielokrotne i inicjowane przez sprzedawcę (MIT) są poprzedzone silnym uwierzytelnianiem przy ich inicjowaniu? Dotyczy serwisów wykorzystujących mechanizmy:

- Subskrypcji Espago

- płatności cyklicznych, wielokrotnych i innych w oparciu o mechanizm card on file (COF)
Tak - wymaganie spełnione; Nie - należy dostosować proces płatności aby był zgodny z wymaganiami opisanymi w rozdziale Płatności wielokrotne lub subskrypcje Espago - w zależności od wykorzystywanego mechanizmu.
Istotna zmiana - Profil Klienta (który może być użyty do dalszych obciążeń) jest tworzony podczas płatności inicjującej z parametrem cof=storing, wykorzystującej SCA. Nie ma potrzeby tworzenia go osobnym żądaniem tworzenia profilu klienta.
4. Czy profil klienta dotychczas tworzony był na podstawie tokenu karty, jeszcze przed pierwszą płatnością? Dotyczy płatności wykonywanych zapisanym profilem klienta (w tym Subskrypcji Espago). Tak - należy zmienić proces, aby był zgodny z wymaganiami opisanymi w rozdziale Płatności wielokrotne lub subskrypcje Espago.
Co prawda nadal można stworzyć profil klienta bez wywołania płatności z SCA, ale w takim przypadku pierwsza płatność z użyciem tego profilu musi wykorzystywać SCA lub być oznaczona jako MOTO (nie może być np. płatnością cykliczną z parametrem cof=recurring)
Nie - jeśli wykorzystywany jest profil klienta stworzony przy zastosowaniu płatności z cof=storing - wymaganie spełnione;
5. Czy dotychczas, przy tworzeniu profilu klienta bez wykonania płatności z SCA, wykorzystują Państwo mechanizm automatycznej autoryzacji karty (opcja zaznaczona w panelu secure.espago.com)? Dotyczy płatności wykonywanych zapisanym profilem klienta (w tym Subskrypcje Espago). Tak - należy zrezygnować z tej opcji.

Wprowadziliśmy inny mechanizm, pozwalający określić czy dany profil może być wykorzystany do płatności: jeśli profil klienta został stworzony na podstawie płatności z SCA, jest do niego dodany parametr sca_payment, który świadczy o prawidłowo dokonanej płatności z SCA, co jest podstawą do wykorzystania tego profilu klienta do obciążeń cyklicznych i wielokrotnych. W przypadku braku tego parametru, profil nie nadaje się do obciążeń innych niż z udziałem posiadacza karty (z SCA) lub MOTO.
Nie - wymaganie spełnione;
6. Czy podczas zapisu karty klienta jego początkowa płatność z 3DS lub autoryzacja była natychmiastowo zwracana? Dotyczy głównie Sprzedawców z płatnościami cyklicznymi rozpoczynającymi obciążenia np. od darmowego okresu Tak - należy zmienić integrację, aby początkowa płatność z SCA/3DS nie była wycofywana, gdyż jej wycofywanie będzie przez bank rozumiane jako wycofanie zgody klienta na późniejsze obciążenia. W celu zapisania karty klienta, bez jego obciążania, odpowiednia będzie płatność z cof=storing na kwotę 0 jednostek walutych. Nie - nie ma potrzeby wprowadzania zmian;

Integracja assignment

link Proces integracji

W ramach integracji należy przetestować/zaimplementować działanie funkcji takich jak:

  • tworzenie tokenów
  • obciążenie kart
  • wyświetlanie klientowi informacji o przyczynie odrzucenia nieudanej płatności
  • uzyskiwanie informacji na temat dokonanych płatności
  • realizację zwrotów i anulowanie transakcji
  • tworzenie profilów klienta i zarządzanie nimi (o ile jest uzasadnienie biznesowe, np. w sklepach, w których zakupy klienta mają się powtarzać)
  • tworzenie planów i subskrypcji (o ile jest uzasadnienie biznesowe, tzn. uruchomienie płatności cyklicznych, wywoływanych przez bramkę Espago)
  • odbieranie informacji zwrotnej (o ile jest uzasadnienie biznesowe)

Przejście do drugiego i zarazem końcowego etapu integracji musi zostać poprzedzone testami webaplikacji klienta w środowisku testowym (dokonywanymi przez integrującego się klienta) oraz ogólną weryfikacją webaplikacji i poprawności implementacji formularza płatności (dokonaną przez Dział Wsparcia Espago). Lista wymogów technicznych i merytorycznych Elavon dostępna jest w dokumentacji w dziale “Do pobrania”.
Panel z możliwością przeglądania i ustawiania parametrów oraz przeglądania testowych płatności, zapytań i odpowiedzi dostępny jest pod adresem https://sandbox.espago.com

Aby przełączyć swoją integrację na środowisko produkcyjne, należy dokonać zmian wartości kilku parametrów oraz danych Serwisu - na odpowiadające tym, ze środowiska produkcyjnego. Zmian wymaga:

  1. konfiguracja dla skryptów do tokenizacji danych kart - Espago iFrame (lub Espago.JS - jeśli jest używane w integracji):
    • atrybut data-live w definicji skryptu iframe zmienić na true - w testowej bramce używana jest wartość false. (Nazwa parametru dla dla Espago.JS: live)
    • atrybut data-key w definicji skryptu iframe - ustawić produkcyjny klucz publiczny, który należy odczytać z Panelu Sprzedawcy https://secure.espago.com. (Nazwa parametru dla dla Espago.JS: public_key)
  2. konfiguracja dla zapytań do Espago API:
    • Produkcyjny adres URL bramki do zapytań API zmienić na https://secure.espago.com (bramka testowa dostępna jest pod adresem https://sandbox.espago.com)
    • ID aplikacji - należy odczytać je z Panelu Sprzedawcy
    • Hasło API - należy ustawić je w Panelu Sprzedawcy

Po zintegrowaniu się ze środowiskiem produkcyjnym, środowisko testowe pozostaje w dalszym ciągu do dyspozycji Sprzedawcy. Na prośbę Sprzedawcy Dział Wsparcia Espago może:

  • Dodać nowy serwis w obrębie konta Sprzedawcy (np. do obsługi innej waluty)
  • Włączyć lub wyłaczyć funkcję DCC (domyślnie wyłaczona)
  • Udzielać odpowiedzi i pomagać rozwiązywać problemy związane z integracją.

link Czynności początkowe

Po uzyskaniu dostępu do panelu merchanta należy wykonać następujące czynności:

  1. Przejść do zakładki:
  2. Przejść do okna edycji serwisu klikając przycisk “Edytuj”.
  3. Uzupełnić pole “Hasło API” i “Potwierdzenie hasła API” - wpisana wartość odpowiada za prawidłową autoryzację konta i nie może być ujawniona osobom postronnym wymagane jest również wypełnienie pola “Email BOK”.
  4. Zaakceptować zmiany klikając przycisk “Zatwierdź”.

Naciskając przycisk “Wyświetl” powinny nam się ukazać podobne informacje:

link Niezbędne nagłówki żądań

Do poprawnej komunikacji z aplikacją wykorzystywane są następujące nagłówki HTTP:

Nagłówek Obligatoryjność Zawartość
Authorization1 Wymagany Basic app_id:password
Accept Wymagany application/vnd.espago.v3+json

Zapytanie o tworzenie tokenu jest uwierzytelniane przy pomocy Klucza Publicznego i w przypadku większości serwisów jest wykonywane przez skrypt Espago JS.
Seria nieudanych prób zalogowania skutkuje czasową blokadą konta.


Authorization1 - z parametrami APP_ID i hasła uzyskanego w sekcji “Czynności początkowe” dotyczy wszystkich zapytań na API z wyjątkiem zapytania o tworzenie tokenu.

link Dane kart testowych

Podczas testowania płatności należy używać wyłącznie wymienionych niżej testowych numerów kart. Aby uzyskać konkretną odpowiedź z bramki (sukces lub błąd) należy użyć odpowiednich danych w polu daty ważności lub kodu CVV karty widocznych w drugiej i trzeciej tabelce.

Podczas testów zabronione jest używanie rzeczywistych numerów kart.

Numer karty Marka Waluta 3-D Secure DCC Wymagane w testach
4012000000020006 Visa PLN 3DSv2.1.0
Challenge
Nie Tak
Dla płatności pojedynczych i cof=storing
4916978838794412 Visa PLN 3DSv2.1.0
Frictionless: OK
Nie Tak
4556914091330789 Visa PLN 3DSv2.1.0
Frictionless: Reject
Nie Tak
5432670000041258 Mastercard PLN Mastercard SecureCode Nie Tak
4242424242424242 Visa PLN TAK Nie Tak
4012001037141112 Visa PLN Verified by Visa Nie Nie
od 2022-10 3DSv1 jest wyłączony
375987000000005 American Express PLN Amex SafeKey Nie Jeśli umowa przewiduje Amex
4012888888881881 Visa USD Verified by Visa Tak Jeśli umowa przewiduje DCC
5555555555554444 Mastercard HKD Mastercard SecureCode Tak Jeśli umowa przewiduje DCC
4242421111112239 Visa HKD Nie Tak Jeśli umowa przewiduje DCC
4917484589897107 Visa PLN Nie Nie Jeśli będą stosowane płatności COF
- ta karta wymaga użycia
kodu CVV do każdej transakcji,
nie nadaje się do subskrypcji i cof=recurring.
4012001038443335 Visa PLN 3DSv2.1.0
Frictionless: OK
Nie Nie
6771798021000008 Maestro PLN 3DSv2.2.0
Frictionless: OK
Nie Nie



Jako datę wygaśnięcia karty należy podać dowolną datę z przyszłości. Od wyboru miesiąca zależy otrzymany rezultat transakcji. Dzięki temu można testować zarówno scenariusze negatywne jak i pozytywne.

Miesiąc ważności Skutek Kod odpowiedzi
01-05 transakcja zaakceptowana 00
06 wynik losowy, 50% szans powodzenia transakcji.
Przydatne przy testach subskrypcji.
nd.
07 transakcja odrzucona 04, 07, 41, 43
08 transakcja odrzucona 51
09 transakcja odrzucona 13
10 transakcja odrzucona 00
11 transakcja odrzucona 54
12 transakcja odrzucona 05, 57, 61



Kod CVV Opis działania w bramce testowej
683 Niepoprawny kod CVV. Transakcja zostanie odrzucona ze względu na niepoprawny kod CVV.
Pozostałe CVV Poprawny kod CVV.


Sterowanie kodami odrzuceń

Karta 4012001038443335 pozwala na sterowanie kodami odrzuceń poprzez kwotę transakcji.
Kod odrzucenia przyjmuje wartość kwoty transakcji po przecinku, przykładowo:

Kwota po przecinku Kod odrzucenia
n.04 04
n.51 51
n.43 43
n.65 65

Gdzie n oznacza liczbę naturalną.

link Połączenie testowe

Aby zweryfikować poprawność swojego połączenia należy wysłać zapytanie na adres https://sandbox.espago.com/api/test. Espago w odpowiedzi wysyła parametr state - wartość passed oznacza, iż połączenie jest poprawnie skonfigurowane. Wartość failed oznacza niepoprawne połączenie - wtedy tablica warnings zawiera informacje na temat przyczyn niepoprawnego połącznia.

Przykładowe zapytanie

curl -i https://sandbox.espago.com/api/test \
-X POST \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD
require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
        request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new(user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD')
response = client.send('api/test', method: :post)
puts response.body
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/test');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
{
  "state":"passed",
  "warnings":[]
}
{
  "state":"failed",
  "warnings":[
    {
      "title":"Access denied",
      "message":"Wrong app_id or password."
    },
    {
      "title":"Wrong request headers",
      "message":"Check your 'Accept' header."
    },
        . . .
  ]
}

link Ograniczenia

Udostępnienie API ma na celu nie ograniczanie w żaden sposób technologii wykorzystywanej przez serwisy, w których płatności mają być zintegrowane, a także urządzeń, z których klienci będą dokonywać płatności. Mimo to w komunikacji z bramką Espago istnieją pewne wymagania, które ograniczają kompatybilność względem starych technologii.

Bramka produkcyjna Espago akceptuje tylko połączenia szyfrowane przy pomocy protokołów TLSv1.2 oraz TLSv1.3. Wszystkie nowe wymagania i konfiguracje SSL/TLS są zawsze w pierwszej kolejności wprowadzane bramce testowej https://sandbox.espago.com, więc jeżeli Państwa aplikacja łączy się ze środowiskiem testowym to znaczy, że spełnia najnowsze wymagania i będzie z powodzeniem łączyć się z bramką produkcyjną.


Niektóre starsze systemy, biblioteki lub przeglądarki nie wspierają takich połączeń; powinny one zostać zaktualizowane lub zastąpione nowszymi rozwiązaniami - ten wymóg dotyczy wszystkich połączeń do API, przekierowania 3D-Secure klientów oraz dostępu do panelu WWW.

Lista oprogramowania obsługującego połączenia TLSv1.2 oraz TLSv1.3

System/ aplikacja/ biblioteka Minimalna kompatybilna wersja Uwagi
Windows 7 i nowsze Uwaga: W starszych systemach należy użyć alternatywnych, aktualnych przeglądarek (np. Chrome, Firefox, Opera)
Windows Server 2008 R2 i nowsze Windows 2008 R2 wymaga włączenia obsługi TLSv1.2 w rejestrach systemu oraz włączenia obsługi dodatkowych szyfrów
Android 4.4.4 i nowsze Android API level 20. Częściowe wsparcie dla TLSv1.2 dostępne również w wersi 4.2
OpenSSL 1.0.1 i nowsze Uwaga: OpenSSL w wersji 0.9.8 nie obsługuje TLSv1.2
Apache 2.2.23 i nowsze
Java 8 i nowsze Uwaga: Java 6 oraz Java 7 nie obsługuje TLSv1.2
.NET Framework 4.5.1 i nowsze może wymagać włączenia w ustawieniach, oraz wymaga systemu Windows wspierającego TLSv1.2

Lista protokołów i szyfrów umożliwiających bezpieczne połączenie do bramki Espago

Zaleca się konfigurację aplikacji aby umożliwiała łączenie się przy użyciu najbezpieczniejszych protokołów i szyfrów, a także aby miała możliwość połączenia przy użyciu kilku zestawów szyfrów (tzn. nie wymuszanie jednego, konkretnego szyfru).

Protokół Dostępne zestawy szyfrów
TLSv1.3 TLS_AES_128_GCM_SHA256
TLS_AES_256_GCM_SHA384
TLS_CHACHA20_POLY1305_SHA256
TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256
ECDHE-RSA-AES128-GCM-SHA256
ECDHE-ECDSA-AES256-GCM-SHA384
ECDHE-RSA-AES256-GCM-SHA384
ECDHE-ECDSA-CHACHA20-POLY1305
ECDHE-RSA-CHACHA20-POLY1305

Bezpieczna strona płatności exit_to_app

link Inicjowanie płatności

Płatność z wykorzystaniem bezpiecznej strony płatności można zainicjować na dwa sposoby:
1. Przesłanie formularza HTML - z przeglądarki użytkownika należy wysłać formularz zawierający dane płatności oraz sumę kontrolną na adres: /secure_web_page;
2. Rejestrowanie płatności przez API - płatność należy zarejestrować przez wysłanie zapytania typu POST na adres API Espago: /api/secure_web_page_register. Po rejestracji płatności konieczne jest przekierowanie użytkownika na otrzymany w odpowiedzi adres URL - w parametrze redirect_url.

link Płatność inicjowana formularzem HTML

1. Przesłanie formularza

Klient inicjuje płatność w przeglądarce: klikając przycisk “Kupuję”, przesyła synchronicznie formularz z ukrytymi parametrami płatności do bramki Espago metodą POST. Zostaje w ten sposób przekierowany na stronę płatności Espago.

<form accept-charset="UTF-8" action="https://sandbox.espago.com/secure_web_page" id="espago_secure_web_page" method="post">
  <input name="api_version" type="hidden" value="3" />
  <input name="app_id" type="hidden" value="ms_771eUTliRiZ" />
  <input name="kind" type="hidden" value="sale" />
  <input name="session_id" type="hidden" value="1559655843622983577" />
  <input name="amount" type="hidden" value="10.00" />
  <input name="currency" type="hidden" value="PLN" />
  <input name="title" type="hidden" value="payment_id:294" />
  <input name="description" type="hidden" value="Platność - Jan Kowalski" />
  <input name="positive_url" type="hidden" value="http://example.com/payments/ok" />
  <input name="negative_url" type="hidden" value="http://example.com/payments/bad" />
  <input name="ts" type="hidden" value="1444044688" />
  <input name="checksum" type="hidden" value="938ee2f7729ac4ba1a7c98f5ead8b167" />
  <button name="button" type="submit" class="btn espago-blue pulse">Kupuję</button>
</form>

2. Wprowadzenie danych karty

Klient podaje dane karty na stronie Espago. Dokonywane jest silne uwierzytelnienie mechanizmem 3-D Secure - może nastąpić przekierowanie na stronę banku. Po zakończeniu autoryzacji, do aplikacji sprzedawcy wysyłany jest back request z informacją o stanie transakcji.

3. Przekierowanie użytkownika

W zależności od powodzenia operacji klient zostaje przekierowany na adres odpowiadający pozytywnemu lub negatywnemu wynikowi. W aplikacji sprzedawcy należy wyświetlić użytkownikowi status płatności i ewentualnym powodzie niepowodzenia.

link Przykładowy formularz

Wykorzystanie Strony Płatności Espago polega na przekierowaniu klienta do bramki Espago, na której klient poda dane kart w celu dokonania płatności. Demo można zobaczyć na demo.espago.com

Możesz użyć testowej karty o numerze 4242 4242 4242 4242 i dacie wygaśnięcia 02/2025. Kod CVV może być dowolny (Więcej o kartach testowych)

link Parametry formularza

Parametry płatności należy przekazać wysyłając formularz metodą POST na adres

sandbox URL: https://sandbox.espago.com/secure_web_page
URL: https://secure.espago.com/secure_web_page

Parametr Opis Wymagany Uwagi
amount kwota transakcji done dwa miejsca po przecinku oddzielone kropką
np: 10.00, 1.23, 1.20
api_version wersja api done 3
app_id Identyfikator aplikacji done
channel kanał płatności Kanał, którym ma być procesowana płatność. Domyślnie “elavon_cc”
checksum suma kontrolna done Funkcja skrótu MD5 dla ciągu znaków (app_id + kind + session_id + amount + currency + ts + checksum_key). Łącznikiem pól jest znak “|”
cof Wykorzystanie mechanizmu “Card on file”. Jedyna możliwa wartości parametru dla bezpiecznej strony płatności to storing - służy zapisaniu danych karty do wykorzystania w późniejszych płątnościach typu MIT lub CIT. Szczegóły w rozdziale COF.
currency waluta done
description opis klienta Opis klienta (nie płatności).
email email klienta done E-mail klienta, wymagany do uwierzytelnienia 3D Secure. Na e-mail zostanie wysłane powiadomienie o transakcji.
skip_email Wskaźnik wyłączenia powiadomienia e-mail Boolean. Domyślna wartość: false. Pozwala wyłączyć powiadomienie o transakcji wysyłane przez Espago w formie e-mail.
kind rodzaj transakcji done sale - sprzedaż
preauth - rezerowanie środków przyszłego obciążenia
locale język transakcji pl, en, da, ru, sv
negative_url adres powrotny Adres, na który zostanie przekierowany klient po nieudanej transakcji
positive_url adres powrotny Adres, na który zostanie przekierowany klient po udanej transakcji
reference_number numer referencyjny transakcji Tekst ref. transakcji - widoczny w raportach Elavon. Długość do 20 znaków, tylko alfanumeryczne oraz -_ (myślnik i belka).
session_id Identyfikator transakcji done Losowy, unikalny ciąg znaków wygenerowany przez serwis Sprzedawcy
title opis transakcji done Tytuł płatności wyświetlany klientowi na ekranie płatności kartą, np. “Zamówienie 123/2019”. Musi zawierać od 5 do 100 znaków. Parametr, który powinien zawierać identyfikator z systemu Sprzedawcy umożliwiający identyfikację płatności przy odbiorze Zapytania zwrotnego, np. unikalny numer zamówienia.

Pole “title” będzie następnie widoczne jako pole description we właściwościach płatności (np. w back requście).
ts znacznik czasowy done


Przykładowy sposób wypełnienia formularza:

<form id="espago_secure_web_page" action="https://sandbox.espago.com/secure_web_page" accept-charset="UTF-8" method="post">
  <input type="hidden" name="api_version" value="3" />
  <input type="hidden" name="app_id" value="ms_0CvDQqhnS" />
  <input type="hidden" name="kind" value="sale" />
  <input type="hidden" name="session_id" value="2HWSjEs5G4RcXZjqHqWA" />
  <input type="hidden" name="amount" value="42.94" />
  <input type="hidden" name="currency" value="PLN" />
  <input type="hidden" name="title" value="order_165" />
  <input type="hidden" name="description" value="Transakcja - jan@kowalski.pl 42.94" />
  <input type="hidden" name="email" value="jan@kowalski.pl" />
  <input type="hidden" name="positive_url" value="http://example.com/payments/ok"  />
  <input type="hidden" name="negative_url" value="http://example.com/payments/bad"  />
  <input type="hidden" name="ts" value="1559230283" />
  <input type="hidden" name="checksum"value="532839977fb76ca06ea635c7a936c7db" />
  <div class="button">
    <button name="button" type="submit">Kup Teraz!</button>
  </div>
</form>


link Inicjowanie płatności żądaniem API

Aby zainicjować płatność z wykorzystaniem Secure Web Page, należy wysłać żądanie do API metodą POST, a następnie przekierować klienta na adres URL otrzymany w odpowiedzi - w parametrze redirect_url.

Diagram przedstawiający zainicjowany żądaniem API proces płatności na bezpiecznej stronie płatności:

Inicjowanie płatności odbywa się przy użyciu tych samych parametrów jak w przypadku obciążenia dokonywanego przez API. Wyjątkiem jest parametr cof, który może w tym przypadku przyjmować jedynie wartość storing.

Parametry zapytania
Ścieżka: /api/secure_web_page_register
Metoda: POST

curl -i https://sandbox.espago.com/api/secure_web_page_register \
-X POST \
-H 'Accept: application/vnd.espago.v3+json' \
-u app_id:password \
-d 'amount=199' \
-d 'currency=PLN' \
-d 'description=Opis transakcji' \
-d 'kind=sale' 
require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new(user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD')
response = client.send(
  'api/secure_web_page_register',
  method: :post,
  body: {
    amount: 199,
    currency: 'PLN',
    description: 'Opis transakcji',
    kind: 'sale',
    service_client_id: 'xxxxxx',
    client_description: 'xxxxx'
  }
)

puts response.body
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/secure_web_page_register');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "amount=199&currency=PLN&description=Opis transakcji&kind=sale&service_client_id=xxxxxx&client_description=xxxxx");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'app_id' . ':' . 'password');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
{
  "id": "pay_IZTq8l_qaHuOHH",
  "description": "Opis transakcji",
  "amount": "199",
  "currency": "PLN",
  "state": "new",
  "created_at": 1550224439,
  "transaction_id": "tn_CLN2HhetI",
  "redirect_url": "https://sandbox.espago.com/secure_web_page/tn_CLN2HhetI"
}

iFrame open_in_browser

link Działanie iFrame

Skrypt EspagoFrame pozwoli wyświetlić na stronie okienko iframe, w którym klient będzie mógł podać dane karty. Następnie te dane zostaną przesłane do Espago, a skrypt zwórci do strony ID tokenu, który można użyć do płatności lub utworzenia profilu klienta.
Przykładowe działanie można zobaczyć w sklepie testowym demo.espago.com.

1. Wywołanie iFrame

W pierwszym kroku klient wywołuje iFrame Espago poprzez naciśnięcie przycisku (uruchomienie musi zostać wywołane ręcznie za pomocą funkcji showEspagoFrame()). Następnie podaje dane swojej karty, które po zatwierdzeniu formularza w iFrame zostają przesłane asynchronicznie do bramki Espago w celu wygenerowania tokenu.

 <script src="https://js.espago.com/espago-1.3.js"></script>
 <script 
   async=""
   data-id="EspagoFrameScript"
   data-key="VrYVaA1CjmRooKh63YYv"
   data-live="false"
   data-button="Pay"
   src="https://js.espago.com/iframe.js">
 </script>

 <a id="pay_btn">Zapłać</a>
$('#pay_btn').click( () => {
  showEspagoFrame()
})

2. Odebranie tokenu

Po odebraniu tokenu skrypt Espago wyszukuje formularz o id espago_form, a następnie tworzy w nim pole <input type="hidden" id="card_token" name="card_token" value="[TOKEN]">. Formularz zostaje wysłany na podany adres.

<form id="espago_form" 
      action="/charge_client" 
      accept-charset="UTF-8" 
      method="post">
</form>

Jeżeli Token nie zostanie użyty, to kod CVV z tokenu zostanie automatycznie usunięty po maksymalnie 2 dobach od utworzenia, a cały token po 2 miesiącach.

3. Obciążenie

Serwer po otrzymaniu tokenu powinien wysłać zapytanie metodą POST na adres https://sandbox.espago.com/api/charges.

curl -i https://sandbox.espago.com/api/charges \
 -H "Accept: application/vnd.espago.v3+json" \
 -u ms_771eUTliRiZ:SeCreT_P@ssw0rD \    # app_id:pass
 -d "amount=10" \
 -d "currency=pln" \
 -d "card=cc_8a1kqN20X6JYeuD-Y" \    # token
 -d "description=Espago docs"
require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new(user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD')
response = client.send(
  'api/charges',
  method: :post,
  body: {
    amount: 10,
    currency: 'PLN',
    card: 'cc_8a1kqN20X6JYeuD-Y',
    description: 'Espago docs'
  }
)

puts response.body
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/charges');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "amount=10&currency=pln&card=cc_8a1kqN20X6JYeuD-Y&description=Espago docs");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close ($ch);

więcej o parametrach obciążenia

4. Odpowiedź z Espago

Po wykonaniu zapytania o obciążenie klienta Espago zwraca informacje w formacje JSON na temat płatności. Kluczowym parametrem jest state. executed oznacza, iż płatność się powiodła .
Przykładowa odpowiedź od bramki Espago:

{
 "id":"pay_772FThyrtalisvgk",
 "description":"Espago docs",
 "channel":"elavon",
 "amount":"10.00",
 "currency":"pln",
 "state":"executed",
 "client":"cli_772coQy1BaW3F0Zn",
 "created_at":1559649971,
 "card":
 {
  "company":"VI",
  "last4":"4242",
  "year":2020,
  "month":2,
  "first_name":"Adam",
  "last_name":"Kowalski",
  "authorized":null,
  "created_at":1559649956
 },
 "issuer_response_code":"00",
 "reversable":true,
 "transaction_id":"tr_7728ogw8v"
}
więcej o informacjach zwrotnych

5. Odpowiedź - informacja dla klienta

Po zakończeniu płatności niezbędne jest wyświetlenie jej statusu klientowi oraz powodu odrzucenia w przypadku niepowodzenia. Kody błedów dostępne są w dziale do pobrania.

link Parametry ramki

Parametr Wymagany Wartości domyślne Informacje
async done “” Nie może mieć wartości innej niż domyślna
data-id done EspagoFrameScript Nie może mieć wartości innej niż domyślna
src done adres skryptu Nie może mieć wartości innej niż domyślna
data-key done String, Klucz publiczny Merchanta
data-live true String, Wskazuje czy formularz ma być wysyłany do środowiska produkcyjnego. Wartość ‘true’ oznacza wysyłanie danych na środowisko produkcyjne, wartość ‘false’ na środowisko testowe.
data-lang pl String, Język w jakim będzie wyświetlony formularz w standardzie ISO 639-1. Dostępne: en, pl, bg, cs, da, de, el, es, et, fi, fr, ga, hr, hu, it, lt, lv, mt, nl, no, pt, ro, ru, sk, sl, sv, ua.
data-success function(data) {} Funkcja callback wywoływana w przypadku, gdy token zostanie wygenerowany. Uwaga, podanie funkcji callback wyłącza domyślne działanie skryptu - pole ‘card_token’ nie zostanie dołączone do formularza.
data - string, wygenerowany token z bramki Espago.
data-error function(data) {} Funkcja callback wywoływana w przypadku, gdy token nie zostanie wygenerowany.
data - string; kod błędu otrzymany z bramki Espago wraz z opisem.
data-onclose function() {} Funkcja wywoływana w przypadku, gdy użytkownik zamknie okno dialogowe (klikając “x” lub klawisz “Esc”).
data-target espago_form Nazwa formularza do którego zostanie dodane ukryte pole ‘card_token’ o wartości tokenu.
Uwaga - w przypadku gdy zostanie podany parametr ‘success_callback’ akcja ta nie wykona się. Token zostanie przekazany do tej funkcji.
data-title Dodaj swoją kartę (pl) Nagłówek wyświetlany na górze formularza.
Uwaga - domyślna wartość jest zależna od parametru języka ‘data-lang’
data-subtitle Tekst wyświetlany poniżej nagłówka i nazwy sklepu (pobranej automatycznie z API Espago)
data-button Zapisz (pl) Etykieta tekstowa wyświetlona na przycisku zatwierdzania formularza.
Uwaga - domyślna wartość jest zależna od parametru języka ‘data-lang’
data-styler esp String, Opcjonalne stylowanie formularza. Jeśli została przygotowana specjalna wersja iframe’a dla sprzedawcy, po uzupełnieniu parametru iframe wyświetli się w zamówionej szacie graficznej. Opcja stylowania dostępna tylko po wcześniejszym ustaleniu z Espago.

Płatność jednorazowa attach_money

link Parametry obciążenia

Rozpoczęcie nowego obciążenia następuje w wyniku wysłania żądania typu POST na adres https://sandbox.espago.com/api/charges

Parametr Opis Format Uwagi
amount Kwota transakcji (autoryzacji) Liczba dziesiętna
Przykłady:. 123.45, 0.
Kwota autoryzacji musi spełniać dokładnie jeden z warunków:
- wynosić 0 jednostek walutowych - w przypadku autoryzacji typu “non-payment authorization” stosowanej w celu zapisania karty;
- być równa lub większa niż odpowiednik kwoty 0,01 EUR w danej walucie, np. 0,05 PLN lub 0.01 EUR (Elavon, Worldline).
authentication_ind
opcjonalny
Wskaźnik celu uwierzytelnienia String, 2.
Dostępne i domyślne wartości są opisane w sekcji 3-D Secure.
Dostępność dla kanałów: elavon_cc, ecard_cc.
Istotny przy zastosowaniu cof=storing - określa cel zapisania danych karty w Profilu Klienta.
card Dane karty płatniczej String: ID jednorazowego tokenu karty
Przykład: cc_772ahSzjmMnOt4eIk
lub
Obiekt card (dla integracji PCI DSS)
ID jednorazowego tokenu karty w przypadku zwykłej płatności pojedynczej z SCA (bez użycia parametru client). Wymagany, gdy płatność jednorazowa lub w trybie cof= storing. Dla integracji w trybie PCI DSS można w ten sposób przekazać dane karty.
challenge_ind
opcjonalny
Wskaźnik użycia trybu SCA String, 2.
Dostępne i domyślne wartości są opisane w sekcji 3-D Secure.
Tryby silnego uwierzytelnienia (SCA) są opisane w sekcji 3-D Secure.
channel Kanał płatności String, max: 32.
Domyślna wartość: elavon_cc. Dostępne wartości: elavon_cc, worldline_cc, polcard_cc.
Kanał, którym ma być procesowana płatność.
client
opcjonalny
ID Profilu Klienta String
Przykład: cli_772uWYtgJXnL_F9I
ID istniejącego w Espago Profilu Klienta z zapisaną kartą. Wymagany dla płatności cof innych niż storing. Płatność przy użyciu ID Profilu Klienta, bez zastosowania parametru `cof=recurring
client_description
opcjonalny
Opis do obiektu Profilu Klienta String, max: 64.
Przykład: client_123456789
Opis klienta, który zostanie zapisany w polu description obiektu client utworzonego podczas płatności. Może on służyć Sprzedawcy do powiązania i identyfikacji profilu użytkownika ze swojego systemu, do którego należą zapisane w Espago dane karty.
cof
opcjonalny
Wskaźnik użycia trybu “Card on File” String, max: 32.
Dostępne wartości: storing, recurring, unscheduled.
Dostępne wartości parametru i ich zastosowanie:
- storing - zapisanie danych karty w Espago:
1) gdy do płatności użyto ID tokenu karty: płatność powoduje zapisanie danych karty w obiekcie Profilu Klienta, umożliwiając rozpoczęcie Subskrypcji lub wykorzystanie go w innych scenariuszach trybu “Card on file”;
2) gdy płatność jest wywołana z użyciem już istniejącego Profilu Klienta oraz nowym ID tokenu karty : następuje silne uwierzytelnienie (SCA) i aktualizacja płatności referencyjnej (widocznej w Profilu Klienta jako sca_payment).
Przy zastosowaniu wartości storing istotny jest parametr authentication_ind opisany w sekcji 3-D Secure.

- recurring - możliwa przy użyciu już istniejącego Profilu Klienta: płatność cykliczna, w ramach subskrypcji na stałą kwotę i ze stałym interwałem.

-unscheduled - możliwa przy użyciu już istniejącego Profilu Klienta: płatność wywołana przez Sprzedawcę (MIT), inna niż cykliczna (np. wyrównanie salda po usłudze). Szczegóły opisane są w rozdziale Card on File.
complete
opcjonalny
Wskaźnik autoryzacji Boolean
Domyślna wartość: true.
Dodanie parametru complete=false sprawia, że dana transakcja nie jest pełną autoryzacją, a blokadą środków -preautoryzacją). Preautoryzację należy dokończyć lub zwolnić w okresie 7 dni od założenia blokady. Szczegóły działania blokady są opisane w rozdziale Zarezerwowanie środków przyszłego obciążenia na koncie klienta.
currency Waluta String, 3.
Dostepne wartości: zbiór wg ISO 4217.
Przykłady: PLN, EUR
Trzyliterowy kod waluty w standardzie ISO 4217. Wskazana waluta musi odpowiadać tej, na umowie z agentem rozliczeniowym dla danego Serwisu.
cvv
opcjonalny
Kod CVV/CVC zapisanej w Espago karty String: ID jednorazowego tokenu kodu CVV/CVC
Przykład: cv_772oAPNIwkEZlEIPo.
Przesłanie tokenu kodu CVV/CVC karty zapisanej w Profilu Klienta w Espago umożliwia dodanie kodu CVV w płatności dokonywanej przy użyciu tego Profilu Klienta. Szczegóły dotyczące tworzenia jednorazowego tokenu CVV/CVC opisane są w rozdziale Dosyłanie CVV.
description Opis transakcji String, 5..99. Opis płatności musi składać się z ciągu o długości od 5 do 99 znaków.
email Adres e-mail wymagany do uwierzytelnienia 3D Secure String, max 128. Adres e-mail wymagany do uwierzytelnienia 3D Secure, na który dodatkowo zostanie wysłane powiadomienie o wyniku obciążenia. Jeśli parametr jest użyty równocześnie z paramtrem client wskazującym na ID Profilu Klienta posiadającego już zapisany adres e-mail, to przesłany w żądaniu obciążenia parametr email ma pierwszeństwo.
locale
opcjonalny
Lokalizacja (język) String, 2.
Dostepne wartości: zbiór wg ISO 639-1.
Oznaczenie języka, w którym zostanie przeprowadzony proces płatności. Dostosowane zostaną: wyświetlane komunikaty na stronie płatności i w powiadomieniu (e-mail) - jeśli powiadomienie nie zostanie wyłączone.
moto
opcjonalny
Wskaźnik MOTO Boolean
Domyślna wartość: false.
Dostępność dla kanałów: elavon_cc, worldline_cc.
Dodanie wskaźnika moto=true spowoduje zakwalifikowanie transakcji jako MOTO (Mail Order/Telephone Order). Transakcja taka pomija proces silnego uwierzytelnienia i nie jest zabezpieczona 3-D Secure. Przed użyciem zalecamy konsultację z Espago.
Uwaga: procesowanie transakcji MOTO jest możliwe tylko gdy jest uwzględnione przy umowie z Agentem Rozliczeniowym.
negative_url
opcjonalny
Adres przekierowania zwrotnego dla negatywnego wyniku transakcji String, max 255.
Domyślna wartość: ustawiona dla Serwisu w Panelu Sprzedawcy “URL pozytywnej odpowiedzi”.
Adres powrotny, na który ma zostać przekierowany z Espago płatnik po negatywnym zakończeniu procesu płatności.
payment_referenced
opcjonalny
Referencja do udanej płatności z SCA String: ID płatności z Espago
Przykład: pay_7724l5jFs9EP6Xr0.
Parametr pozwalający powołać się na płatność referencyjną (inicjującą) z silnym uwierzytelnieniem (SCA). Musi przyjmować wartość identyfikatora udanej płatności z SCA w Espago. Parametr może zostać użyty tylko przy zastosowaniu parametru `cof=recurring
positive_url
opcjonalny
Adres przekierowania zwrotnego dla pozytywnego wyniku transakcji String, max 255.
Domyślna wartość: ustawiona dla Serwisu w Panelu Sprzedawcy “URL pozytywnej odpowiedzi”.
Adres powrotny, na który ma zostać przekierowany z Espago płatnik po pozytywnym zakończeniu procesu płatności.
recurring_expiry
opcjonalny
Data zakończenia płatności cyklicznych String, format: RRRRMMDD
Przykład: 20231231.
Dostępność dla kanałów: elavon_cc.
Parametr określający datę ostatniej płatności w serii płatności cyklicznych, którą autoryzuje posiadacz karty. Będzie on wykorzystany do płatności zapisujących dane karty do pryszłych płatności cyklicznych.
Jeśli płatność jest wywołana z oznaczeniem cof=storing, a parametr recurring_expiry nie został podany, to domyślnie przyjmuje datę ważności karty klienta.
Wartość tego parametru może zostać wyświetlona Klientowi na stronie Banku w procesie 3-D Secure.
recurring_freq
opcjonalny
Okres w cyklu płatności cyklicznych Liczba całkowita
Przykład: 30.
Dostępność dla kanałów: elavon_cc.
Parametr określa minimalną liczbę dni pomiędzy poszczególnymi obciążeniami cyklicznymi. Parametr będzie wykorzystany gdy płatność jest wywołana z oznaczeniem cof=storing.
Jeśli płatność jest wywołana z oznaczeniem cof=storing, a ten parametr nie został podany, to domyślnie przyjmuje wartość recurring_freq=1.
Wartość tego parametru może zostać wyświetlona Klientowi na stronie Banku w procesie 3-D Secure.
reference_number
opcjonalny
Numer referencyjny nadany przez Sprzedawcę String, znaki alfanumeryczne oraz - _ (myślnik i podkreślnik), max: 20.
Dostępność dla kanałów: elavon_cc.
Ciąg referencyjny transakcji przekazywany do agenta rozliczeniowego i widoczny w raportach.
skip_email
opcjonalny
Wskaźnik wyłączenia powiadomienia e-mail Boolean
Domyślna wartość: false.
Pozwala wyłączyć powiadomienie wysyłane przez Espago w formie e-mail - nawet jeśli do płatności użyto Profilu Klienta z zapisanym adresem e-mail lub przekazano parametr email w żądaniu obciążenia. Uwaga: w przypadku wyłączenia powiadomienia wysyłanego przez Espago, obowiązek wysłania powiadomienia klientowi ciąży na Sprzedawcy.

link Przykładowe obciążenie

{
  "amount": 10,
  "currency": "pln",
  "card": "cc_772ahSzjmMnOt4eIk",
  "description": "Espago docs"
}
curl -i https://sandbox.espago.com/api/charges \
 -H "Accept: application/vnd.espago.v3+json" \
 -u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
 -d "amount=10" \
 -d "currency=pln" \
 -d "card=cc_772ahSzjmMnOt4eIk" \
 -d "description=Espago docs"
require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new(user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD')
response = client.send(
  'api/charges',
  method: :post,
  body: {
    amount: 10,
    currency: 'pln',
    card: 'cc_8a1kqN20X6JYeuD-Y',
    description: 'Espago docs'
  }
)

puts response.body
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/charges');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "amount=10&currency=pln&card=cc_772ahSzjmMnOt4eIk&description=Espago docs");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close ($ch);
{
  "id":"pay_773ob8rbBtid0PYd",
  "description":"Espago docs",
  "channel":"elavon",
  "amount":"10.00",
  "currency":"pln",
  "state":"executed",
  "client":"cli_7733nQkDLdlhHmh-",
  "created_at":1561990343,
  "card":{
    "company":"VI",
    "last4":"4242",
    "year":2020,
    "month":2,
    "first_name":"Adam",
    "last_name":"Adam",
    "authorized":null,
    "created_at":1561990328
  },
  "issuer_response_code":"00",
  "reversable":true,
  "transaction_id":"tr_773OKuy0b"
}

Więcej na temat odpowiedzi z serwera znajdziesz tutaj.

{
  "id": "pay_772LFdT3JG6KaAir",
  "description": "order_481",
  "channel": "elavon",
  "amount": "9.99",
  "currency": "PLN",
  "state": "new",
  "client": "cli_772mtwcEVYBfRCJ2",
  "created_at": 1560935536,
  "card": { ... },
  "issuer_response_code": "",
  "transaction_id": "tr_772atPpUX",
  "redirect_url": "https://sandbox.espago.com/3d-secure/tr_772atPpUX",
  "tds_redirect_form": { ... }
}

link 3D Secure

3D Secure jest metodą autoryzacji transakcji w internecie. Polega ona na przekierowaniu użytkownika na stronę banku (lub wyświetlenia iFrame) w celu dodatkowej autoryzacji poprzez np kod przysłany SMS'em, zalogowanie się na stronę banku lub potwierdzenie płatności na smartfonie.
Użycie 3-D Secure przenosi ze Sprzedawcy na Bank Klienta ewentualną odpowiedzialność za nadużycia (oszustwa, płatność kradzioną kartą, niezamówione usługi itp). 3-D Secure jest pierwszą częścią płatności

Obsługiwanie kart posiadających zabezpieczenie 3D Secure jest niezbędne zarówno do poprawnego obsługiwania płatności jednorazowych, jak i zapisania karty w celu użycia jej w płatnościach wielokrotnych/cyklicznych.


Po wywołaniu obciążenia klienta posiadającego zabezpieczenie 3D Secure obiekt płatności posiada status new oraz jeden dodatkowy atrybut - redirect_url. Jest to adres, na który należy przekierować użytkownika w celu autoryzacji transakcji w banku.
Po przekierowaniu transakcja otrzyma status tds_redirected. Klient po dokonaniu płatności na stronie banku zostanie przekierowany do sklepu (URL pozytywnej odpowiedzi / URL negatywnej odpowiedzi), a na adres żądania zwrotnego przyjdzie informacja dotycząca statusu płatności [executed, rejected, failed].

Do 2019r standardem było 3-D Secure v1.0.2, aktualnie wprowadzane jest EMV 3-D Secure v2.2.0. Z punktu widzenia Klienta różnica jest niewielka, ale dla Sprzedawcy są wartościowe zmiany:
- pojawiło się wiele dostępnych parametrów mogących lepiej dostosować uwierzytelnienie 3DS do danego typu transakcji lub biznesu. Espago ustawia parametry 3DSv2 w sposób optymalny dla większośći mechanizmów recurringowych, Merchant, poprzez parametr authentication_ind oraz challenge_ind ma możliwość manipulowania tymi opcjami w specyficznych sytuacjach.
- Dostępna jest autoryzacja na kwotę “0” PLN/EUR/itd, przydatna do zapisania danych karty bez obciążania klienta.
- Przy płatności z flagą cof=storing zawsze wymuszane jest SCA (czyli przekierowanie klienta i jego świadome potwierdzenie transakcji). W płatnosciach jednorazowych Bank może na podstawie danych przeglądarki lub/i urządzenia mobilnego podjąć decyzję o autoryzacji i przekierować Klienta od razu do sklepu bez(tzw. frictionless flow, np. przy kwotach poniżej 50 euro, u sprzedawcy u którego już robił zakupy itp).

Dla standardowych płatności (jednorazowych, cyklicznych) Espago ustawia odpowiednie parametry uwierzytelnienia 3-D Secure v2, w specyficznych sytuacjach Sprzedawca ma możliwość wywołać płatność z dodatkowymi wskazaniami dotyczącymi 3DS (choć pośrednio również płatności).

Parametr przy wywoływaniu płatnosci Opis Uwagi
authentication_ind Typ transakcji, których dotyczy uwierzytelnienie

Domyślnie:
“01” dla płatności jednorazowych
“02” dla płatnosci z cof=storing
“04” dla non-payment authorization czyli na kwotę 0 (amount=0) i z cof=storing.
Musi składać się z 2 cyfr. Możliwe wartości:
‘01’: ‘Payment transaction’
‘02’: ‘Recurring transaction’
‘03’: ‘Instalment transaction’
‘04’: ‘Add card’ [do użycia przy płatności inicjującej, gdy późniejsze płatności będą nieregularne (np. opłaty po wypożyczaniu roweru z użyciem cof=unscheduled)
‘05’: ‘Maintain card’
‘06’: ‘Cardholder verification as part of EMV token ID&V’
challenge_ind Wymuszenie uwierzytelnienia z SCA

Domyślnie:
“01” dla płatności jednorazowych
“04” wymuszone zawsze dla płatnosci z cof=storing (brak możliwości zmiany challenge_ind przy zapisie karty)
Musi składać się z 2 cyfr. Możliwe wartości:
‘01’: ‘No preference’
‘02’: ‘No challenge requested’
‘03’: ‘Challenge requested (3DS Requestor preference)’
04’: ‘Challenge requested (SCA wymagane np. ze względu na PSD2)’
‘05’: ‘No challenge requested (transactional risk analysis is already performed)’
‘06’: ‘No challenge requested (Data share only)’
‘07’: ‘No challenge requested (strong consumer authentication performed)’
‘08’: ‘No challenge requested (utilise whitelist exemption if no challenge required)’
‘09’: ‘Challenge requested (whitelist prompt requested if challenge required)’

Od 12 sierpnia 2024 roku Visa zwiększa ilość danych wymaganych dla uwierzytelnienia 3D Secure. Od tej daty, dla każdej transakcji 3D Secure, Sprzedawca będzie miał obowiązek przesłania adresu e-mail posiadacza karty.

W zależności od formy integracji adres e-mail może zostać przekazany:

link eDCC

Usługa DCC (Dynamic Currency Conversion - Dynamiczne Przeliczanie Walut) firmy Elavon umożliwia Ci oferowanie posiadaczom zagranicznych kart VISA® i MasterCard® dokonywania płatności w ich rodzimej walucie.

Przeliczenie kwoty transakcji z waluty w Twoim sklepie na walutę karty klienta następuje w bramce Espago jeszcze przed dokonaniem transakcji, dzięki czemu Twoi klienci mają możliwość poznania ostatecznej kwoty transakcji jeszcze przed dokonaniem płatności, a nie dopiero po otrzymaniu wyciągu z karty. Elavon oferuje usługę DCC dla najpopularniejszych 45 walut z całego świata.

Usługa eDCC nie będzie wywołana w przypadku płatności cyklicznych (recurring=true). W płatności cyklicznej nie bierze udziału posiadacz karty, więc nie może podjąć decyzji DCC. W takim przypadku - przypadku użycia karty w innej walucie niż waluta serwisu do płatności cyklicznych, przewalutowanie nastąpi po stronie banku - wystawcy karty - i według jego zasad.

1. Informacja o wyborze waluty

Transakcja rozpoczyna sie tak jak zawsze. Jeśli merchant ma właczoną usługę eDCC to bramka Espago automatycznie rozpoznaje czy dana karta kwalifikuje się do usługi przeliczenia waluty.

Jeżeli dana karta podlega transakcji DCC bramka odeśle odpowiedź i będzie oczekiwać na decyzję czy klient chce dokonać transakcji w swojej rodzimej walucie. Odpowiedź przy transakcji DCC zawsze pokaże kwotę transakcji w walucie merchanta, kurs wymiany waluty oraz kwotę transakcji w rodzimej walucie posiadacza karty. Płatność oczekująca na decyzję przyjmuje status=dcc_decision.

Jeżeli dana karta nie podlega transakcji DCC, płatność przebiega dalej normalnie.

curl -i https://sandbox.espago.com/api/charges \
-H "Accept: application/vnd.espago.v3+json" \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
-d "amount=49.99" \
-d "currency=pln" \
-d "client=cli_772uWYtgJXnL_F9I" \ # klient z kartą w innej walucie
-d "description=Opis transakcji"
require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new(user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD')
response = client.send(
  'api/charges',
  method: :post,
  body: {
    amount: 49.99,
    currency: 'pln',
    client: 'cli_772uWYtgJXnL_F9I',
    description: 'Opis transakcji'
  }
)

puts response.body
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/charges');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "amount=49.99&currency=pln&client=cli_772uWYtgJXnL_F9I&description=Opis transakcji");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
{
  "id": "pay_7724xNjCpNPWYevy",
  "description": "order_502",
  "channel": "elavon",
  "amount": "17.98",
  "currency": "PLN",
  "state": "dcc_decision",
  "client": "cli_772KDwdXQIbqpFp3",
  "created_at": 1560942887,
  "card": { ... },
  "issuer_response_code": "",
  "transaction_id": "tr_772_lDLkv",
  "dcc_decision_information": {
    "cardholder_currency_name": "HKD",
    "cardholder_amount": "39.74",
    "conversion_rate": "2.210174",
    "redirect_url": "https://sandbox.espago.com/secure_web_page/tr_772_lDLkv",
    "mark_up_percentage": "300"
  }
}

Parametr Opis Uwagi
cardholder_currency_name Nazwa waluty posiadacza karty Zgodie ze standardem ISO 4217
cardholder_amount kwota transakcji w rodzimej walucie posiadacza karty
conversion_rate kurs wymiany waluty
redirect_url odłużenie eDCC po stronie Espago Należy przekierować klienta na ten adres jeżeli decyzja eDCC nie jest rozstrzygana po stronie sklepu
mark_up_percentage oprocentowanie od przewalutowania

2. Decyzja eDCC

Aby wykonać zarezerwowane wcześniej środki na karcie klienta należy wysłać żądanie typu POST na adres https://sandbox.espago.com/api/charges/(:id)/dcc_decision

(:id) - identyfikator płatności oczekującej na decyzję zwiazaną z DCC

Odpowiedzi są takie same jak przy zwykłej transakcji bez eDCC - poszerzone o informacje nt. waluty i kwoty posiadacza karty.

curl -i https://sandbox.espago.com/api/charges/(ID_TRANSAKCJI)/dcc_decision \
-H "Accept: application/vnd.espago.v3+json" \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
-d "decision=Y"
require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new(user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD')
payment_id = 'pay_8a1FKrxqzJG9sszX'
response = client.send(
  "api/charges/#{payment_id}/dcc_decision",
  method: :post,
  body: {
    decision: 'Y'
  }
)

puts response.body
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/charges/(ID_TRANSAKCJI)/dcc_decision');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "decision=Y");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
{
  "id": "pay_77219xeZ-8xvxUdE",
  "description": "order_523",
  "channel": "elavon",
  "amount": "39.96",
  "currency": "PLN",
  "state": "executed",
  "client": "cli_772KEkYX7Vq54DJe",
  "created_at": 1560949080,
  "issuer_response_code": "00",
  "reversable": true,
  "transaction_id": "tr_7722-YsY6",
  "multicurrency_indicator": "Z",
  "dcc_decision_information": {
    "cardholder_currency_name": "HKD",
    "cardholder_amount": "88.32",
    "conversion_rate": "2.210174"
  }
}

multicurrency_indicator - Pole obecne tylko gdy waluta płatności jest inna niż waluta serwisu.
N - Karta bez DCC
Y - DCC odrzucone przez posiadacza karty
Z -DCC możliwe i zaakceptowane przez posiadacza karty

Może nastąpić sytuacja, w której klient z zabezpieczeniem 3D Secure będzie chciał zapłacić w innej walucie. Z tego powodu należy obsłużyć scenariusz, w którym klient najpierw podejmuje decyzję DCC, a następnie zostaje przekierowany na adres zabezpieczenia 3D Secure.
Po podaniu informacji na temat przewalutowania bramka Espago wysyła odpowiedź zawierającą dane do przekierowania 3D Secure, a płatność ma stan “tds_prtcpt”

Przykładowa odpowiedź

{
  "id": "pay_7724l5jFs9EP6Xr0",
  "description": "order_526",
  "channel": "elavon",
  "amount": "16.98",
  "currency": "PLN",
  "state": "tds_prtcpt",
  "client": "cli_772TVMYGxKECDKPZ",
  "created_at": 1560953142,
  "issuer_response_code": "",
  "transaction_id": "tr_772C5ke_m",
  "redirect_url": "https://sandbox.espago.com/3d-secure/tr_772C5ke_m",
  "tds_redirect_form": { ... },
  "multicurrency_indicator": "Z",
  "dcc_decision_information": {
    "cardholder_currency_name": "HKD",
    "cardholder_amount": "37.53",
    "conversion_rate": "2.210174"
  }
}

W niektórych sytuacjach, gdy Sprzedawca spodziewa się, że większość klientów będzie korzystać z eDCC, może odpytać bramkę Espago o aktualne kursy walut. Dzięki temu, istnieje możliwość poinformowania klienta o kursie przewalutowania DCC jeszcze przed rozpoczęciem płatności.

Kursy walut są aktualizowane raz dziennie o godzinie 18:30.

Aby pobrać kursy walut dla waluty serwisu należy wysłać żądanie typu GET na adres https://sandbox.espago.com/api/dcc/rates. Wymagane są standardowe nagłówki do autoryzacji zapytania.

curl -i https://sandbox.espago.com/api/dcc/rates \
-H "Accept: application/vnd.espago.v3+json" \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD
require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new(user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD')
response = client.send "api/dcc/rates", method: :get

puts response.body
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/dcc/rates');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
{
  "timestamp":"2017-12-01T04:48:00.000+01:00",
  "mark_up_percentage":"300",
  "currency_name":"PLN",
  "currency_code":"985",
  "rates":{
    "USD":"0.285413",
    "ARS":"2.546572",
    "RON":"1.136708",
    "CZK":"6.997923",
    "EUR":"0.255955",
    "KWD":"0.085902",
    "MYR":"1.025983",
    "MXN":"4.372453",
    "GBP":"0.183134",
    ...
  }
}

link Możliwe stany płatności

Status “executed” jest potwierdzeniem obciążenia klienta, na jego podstawie w sklepie można uznać zakupy za opłacone.

Stan Opis
new Nowa płatność jeszcze nie obciążająca klienta
executed Płatność została wykonana, konto klienta obciążone. Na podstawie tej wartości/parametru można uznać płatność za wykonaną.
Uwaga: Po wykonaniu transakcji wciąż można zwrócić pobraną wcześniej kwotę (lub pewną jej część).
rejected Płatność odrzucona.
Uwaga: Jeżeli nastąpi ten stan płatności, to w odpowiedzi dostaniemy dodatkowo parametr reject_reason oraz issuer_response_code.
failed Płatność zakończona niepowodzeniem ze względu na czynniki zewnętrzne
preauthorized [Status dostępny tylko w przypadku użycia parametru complete=false]
tds2_challenge [Status dostępny tylko w przypadku włączonej opcji 3D-Secure v2]. Klient został przekierowany na stronę 3D-Secure v2 (stronę banku lub iFrame), oczekiwanie na jego powrót.
tds_redirected [Status dostępny tylko w przypadku włączonej opcji 3D-Secure]. Klient został przekierowany na stronę 3D-Secure (stronę banku), oczekiwanie na jego powrót.
dcc_decision [Status dostępny tylko w przypadku włączonej opcji DCC]. Oczekiwanie na nadesłanie przez Sprzedawcę decyzji dotyczącej wybranej przez Klienta waluty płatności.
resigned Klient zrezygnował z autoryzacji płatności lub porzucił płatność [stan dostępny przy włączonym 3D-Secure, DCC lub/i MasterPass]. W przypadku porzucenia (brak działania klienta przez czas 1,5h) transakcje ze statusem “new”, “tds_redirected” lub “dcc_decision” zmieniają status na “resigned”.
reversed Płatność została anulowana/wycofana w dniu jej wykonania (przed rozliczeniem).
refunded Płatność została zwrócona w całości lub części.
blik_redirected [Status dostępny tylko w przypadku płatności BLIK]. Klient został przekierowany na stronę płatności w celu wpisania kodu BLIK.
transfer_redirected [Status dostępny tylko w przypadku przelewów]. Klient został przekierowany na stronę płatności w celu realizacji przelewu.

link Możliwe przyczyny odrzuceń płatności

Aby uzyskać najlepszą skuteczność procesu płatności - w przypadku odmowy autoryzacji przez agenta rozliczeniowego lub bank - warto poinformować klienta w jaki sposób można rozwiązać problem przy ponownej próbie zapłaty. W tym celu sugerujemy postępować według poniższego schematu:

  1. sprawdź wartość state;
  2. jeśli jest inny niż executed (lub preauthorized w przypadku rezerwacji środków), rozpocznij dalszą analizę - punkt 3 i dalsze;
  3. sprawdź pole behaviour (jednoznaczny komunikat ujednolicony dla wszystkich operatorów);
  4. jeśli rozwiążanie na podstawie pola behaviour nie jest wystarczające, to należy sprawdzić odpowiedź bezpośrednio od acquirera - w polu reject_reason, lub banku - issuer_response_code (ISO 8583-1987).

W przypadku odmowy autoryzacji przez bank, warto prezentować osobie płacącej kartą przyczynę odmowy, ponieważ pozwoli jej to dokonać skutecznie płatności po usunięciu tej przyczyny (np. zmiana limitu lub użycie innej karty).

Parametr “reject_reason” zawiera ogólną informację o odrzuceniu lub odmowie wykonnia płatności na poziomie agenta rozliczeniowego lub banku, która jest pomocna w ustaleniu przyczyny problemu. Konkretna przyczyna odrzucenia płatności, gdy dojdzie do autoryzacji przez bank, podana jest w formie kodu w parametrze “issuer_response_code”.

Komunikat Znaczenie Przyczyna Uwagi
declined transakcja odrzucona Odmowa autoryzacji, nieaktywowany rodzaj usługi (MOTO, ecommerce), brak środków. Szczegóły dotyczące odrzucenia w przypadku próby autoryzacji znajdują się w parametrze issuer_response_code.
Możliwość ponowienia zależy od kodu odpowiedzi.
card expired karta utraciła ważność Przekroczony termin ważności karty. Nie wolno ponawiać transakcji tą kartą. W przypadku płatności zapisanym Profilem Klienta, należy zaktualizować dane karty.
insert card odrzucenie soft decline Użyty Profil Klienta wymaga przeprowadzenia silnego uwierzytelnienia. Jeśli płatność została wywołana z użyciem zapisanych w Profilu Klienta danych karty, należy ponowić ją przeprowadzając silne uwierzytelnienie z udziałem klienta - dodając do żądania API parametr cof=storing.
invalid amount niewłaściwa kwota Przekroczony limit kwotowy/dziennej liczby płatności.
invalid card nieprawidłowa karta Należy użyć innej karty.
invalid profile nieprawidłowe konto MID Odrzucenie przez Elavon, np. ze względu na nieaktywny MID Komunikat występuje wraz z kodem issuer_response_code=00
please retry błąd systemu, należy ponowić płatność Agent rozliczeniowy zgłosił tymczasowy błąd systemu. Komunikat występuje wraz z kodem issuer_response_code=00
referral A / pick up card karta do zatrzymania Karta oznaczona jako zablokowana/zagubiona/skradziona. UWAGA: Nie należy powtarzać obciążeń dla tej karty! Może to zostać uznane za próbę oszustwa!
referral B transakcja wymaga potwierdzenia wymaga kontaktu z bankiem dla potwierdzenia transakcji, transakcja jest traktowana jako odrzucona w systemie Espago
serv not allowed nieobsługiwany typ karty Merchant nie obsługuje danego typu karty np. American Express, Diners Club, w przypadku braku rejestracji BRAM także MasterCard
3ds_not_authorized odrzucenie podczas 3D-Secure Nieprawidłowe poświadczenie 3D-Secure lub inny błąd związany z 3D-Secure.

Parametr “behaviour” zawiera wskazówki dotyczące dalszego postępowania w przypadku odrzucenia lub odmowy wykonnia płatności na poziomie agenta rozliczeniowego lub banku.

Komunikat Znaczenie
abort Nie ponawiaj płatności z użyciem tej karty
retry Spróbuj ponownie
retry_later Spróbuj ponownie później (czasowa niedostępność operatora lub banku).
sca_required Wymagane silne uwiezytelnienie - zastosuj silniejsze wartości parametrów challenge_ind lub authentication_ind.
fix_request Nie ponawiaj płatności z takimi samymi danymi wejściowymi - wymagają poprawki.
invalid_card Nie ponawiaj płatności - należy użyć innej karty lub usunąć przyczynę odmowy autoryzacji, (np. zwiększyć limit lub odblokować kartę).
invalid_amount Kwota transakcji nie została zaakceptowana przez operatora.

Parametr ten jest odpowiedzią pochodzącą bezpośrednio z banku - wydawcy karty. Szczegółowe informacje o przyczynie jego wystąpienia i sposobie rozwiązania problemu posiadacz karty powinien kierować do swojego banku.


Szczegółowe kody odrzuceń zostały podzielone na 4 kategorie. Każda kategoria określa działanie, które Sprzedawca powinien wykonać.
Szczególnej uwagi wymaga kategoria 1, zawierająca kody odrzuceń, dla których płatności bezwzględnie nie można ponawiać.

Kody issuer_response_code, po których nie należy ponawiać obciążeń karty: 04, 07, 12, 14, 15, 41, 43, 46, 57, R0, R1, R3, B14, B15, B41, B43, B54

Kody odrzucenia mówiące o zamkniętym koncie lub koncie, które zostało permanentnie zablokowane.
Ta kategoria obejmuje również kody odrzucenia, które wskazują, że konto jest ważne, jednak transakcja jest niedozwolona ze względu na stałe ograniczenia produktowe/regulacyjne lub błędy transakcji, które uniemożliwiają zatwierdzenie.
Sprzedawca nie powinien nigdy ponawiać płatności dla płatności odrzuconych z tymi kodami.
Ponawianie prób obciążeń karty w poniższych przypadkach może skutkować blokadą konta sprzedawcy po stronie agenta rozliczeniowego.

Kod odrzucenia Oryginalny komunikat Znaczenie Opis/Proponowany komunikat
04 Pick up card (no fraud) Karta zastrzeżona (z powodów innych niż kradzież/zgubienie) ODMOWA - karta zastrzeżona. Skontaktuj się z Twoim bankiem w celu wyjaśnienia przyczyny problemu.
07 Pick up card, special condition (fraud account) Karta zastrzeżona ODMOWA - karta zastrzeżona.
12 Invalid transaction Nieprawidłowa transakcja ODMOWA - transakcja niedostępna dla tej karty. Skontaktuj się z Twoim bankiem w celu wyjaśnienia przyczyny problemu.
14 Invalid account number (no such number) Nieprawidłowy numer karty lub konta ODMOWA - podano nieprawidłowy numer karty. Należy użyć innej karty.
15 No such issuer Nie zidentyfikowano wydawcy karty ODMOWA - podano nieprawidłowy numer karty. Należy użyć innej karty.
41 Lost card, pick up (fraud account) Karta oznaczona jako zgubiona. ODMOWA - karta oznaczona jako zgubiona – skontaktuj się z Twoim bankiem w celu wyjaśnienia przyczyny problemu.
43 Stolen card, pick up (fraud account) Karta oznaczona jako skradziona ODMOWA - karta oznaczona jako skradziona – skontaktuj się z Twoim bankiem w celu wyjaśnienia przyczyny problemu.
46 Closed account Konto zamknięte, tą kartą nie uda się dokonać płatności. ODMOWA - Płatność odrzucona przez bank – proszę użyć innej karty.
57 Transaction not permitted to cardholder Typ transakcji niedozwolony dla karty ODMOWA – bank odrzucił transakcję ponieważ użyta karta nie może zostać użyta to tego typu transakcji (internetowe, MOTO lub cykliczne). Sprawdź ustawienia karty lub użyj innej karty.
R0 Stop Payment Order Płatność odrzucona przez bank - nastąpiło żądanie wstrzymania autoryzacji. ODMOWA - Proszę użyć innej karty lub skontaktować sie z bankiem.
R1 Revocation of authorization order Płatność odrzucona przez bank - nastąpiło żądanie wstrzymania autoryzacji. ODMOWA - Proszę użyć innej karty lub skontaktować sie z bankiem.
R3 Revocation of all authorizations order Płatność odrzucona przez bank - nastąpiło żądanie wstrzymania autoryzacji. ODMOWA - Proszę użyć innej karty lub skontaktować sie z bankiem.

Obejmuje tymczasowe decyzje o odrzuceniu podjęte przez wydawców kart, które mogą ulec zmianie w czasie. Występuje, gdy wystawca jest gotowy do zatwierdzenia transakcji, ale nie może tego zrobić w danym momencie i przyjmie kolejną próbę autoryzacji.

Kod odrzucenia Oryginalny komunikat Znaczenie Opis/Proponowany komunikat
03 Invalid merchant Nieprawidłowe/niepełne dane akceptanta lub nieaktywne konto. ODMOWA - problem z autoryzacją.
19 Re-enter transaction Płatność odrzucona przez bank. Proszę użyć innej karty lub skontaktować sie z bankiem.
51 Not sufficient funds Niewystarczające środki na koncie lub przekroczenie limitu dla danego typu płatności. ODMOWA - niewystarczające środki na koncie lub przekroczenie limitu. Zweryfikuj stan swojego konta i spróbuj ponownie.
59 Suspected fraud Podejrzenie oszustwa ODMOWA - skontaktuj się z Twoim bankiem w celu wyjaśnienia przyczyny problemu
61 Exceeds approval amount limit Przekroczenie limitu transakcji dla karty ODMOWA - przekroczenie limitu kwoty transakcji. Skontaktuj się z bankiem w celu zmiany limitu lub użyj innej karty.
62 Restricted card (card invalid in this region or country) Ograniczenie karty, wykluczenie ze względu na kraj wydawcy. ODMOWA – użycie karty zostało ograniczone, np. ze względu na ograniczenie (embargo) nałożone na kraj wydawcy (banku). Skontaktuj się z bankiem w celu wyjaśnienia szczegółowej przyczyny problemu
65 VISA: Allowable number of transactions exceeded Visa: Przekroczony limit transakcji. ODMOWA – przekroczony limit transakcji w krótkim odstępie czasu lub dzienny. Użyj innej karty lub odczekaj przed następną próbą.
75 Allowable number of PIN entry tries exceeded Przekroczony limit błędnych prób podania CVV/CVC/PIN. ODMOWA – przekroczony limit błędnych prób podania kodu CVV/CVC/PIN. Zweryfikuj poprawność kodu zabezpieczającego na swojej karcie.
78 Blocked, first used Nowa, nieaktywowana karta. ODMOWA – Karta nie została aktywowana. Aktywuj kartę i spróbuj ponownie.
86 Cannot verify PIN Płatność odrzucona przez bank - nie można zweryfikować PIN Proszę użyć innej karty lub skontaktować sie z bankiem.
91 Issuer not available Płatność odrzucona - system autoryzacyjny banku tymczasowo niedostępny. Proszę użyć innej karty lub spróbować później.
93 Transaction cannot be completed - violation of law Płatność odrzucona przez bank. Proszę użyć innej karty lub skontaktować sie z bankiem.
E4 3D-Secure authentication failed. Bank zwrócił informację o negatywnym wyniku uwierzytelnienia 3D-Secure, np. wpisano błędny kod lub nie zaakceptowano płatności w aplikacji. ODMOWA – Negatywny wynik weryfikacji 3D-Secure w banku.

Wystawca nie może zatwierdzić podanych szczegółów, takich jak nieprawidłowy kod CVV2 lub nieprawidłowa data ważności karty.

Kod odrzucenia Oryginalny komunikat Znaczenie Opis/Proponowany komunikat
54 Expired card or expiration date is missing Przeterminowana karta. ODMOWA - karta utraciła ważność. Użyj innej karty.
55 Incorrect PIN or PIN missing Płatność odrzucona - niepoprawny lub brakujący PIN. Proszę użyć innej karty, zweryfikować poprawność kodu CVV/CVC lub skontaktować sie z bankiem.
70 Visa: PIN data required Visa: Wymagane silne uwierzytelnienie (SCA). VIsa: Proszę spróbować ponownie lub skontaktować się z bankiem w celu weryfikacji ustawień płatności internetowych.
65 Mastercard: soft decline Mastercard: wymagane silne uwierzytelnienie (SCA) Mastercard: ODMOWA – ta płatność wymaga dokonania silnego uwierzytelnienia (SCA)
82, N7 Negative CAM, dCVV, iCVV, or CVV results Nieprawidłowy kod CVV ODMOWA – Nieprawidłowy kod CVV. Sprawdź poprawność wprowadzonych danych i spróbuj ponownie. Może to zostać uznane za próbę oszustwa!
1A Visa: soft decline Wymagane silne uwierzytelnienie (SCA) Dla kart Visa: ta płatność wymaga dokonania silnego uwierzytelnienia (SCA).

Ta kategoria obejmuje wszystkie inne kody odrzucenia, z których wiele ma charakter techniczny.

Kod odrzucenia Oryginalny komunikat Znaczenie Opis/Proponowany komunikat
01,02 Refer to card issuer Kod własny wydawcy karty ODMOWA - problem z autoryzacją. Niezbędny kontakt z bankiem.
05 Do not honor Nie honorować Płatność została odrzucona przez bank bez podania szczególnej przyczyny. Prawdopodobnie płatności typu MOTO/eCommerce/subskrypcyjne nieaktywne lub niewspierane. Potrzebny kontakt klienta z bankiem w celu wyjaśnienia.
ODMOWA – bank odrzucił transakcję ze względu na ustawienia zabezpieczeń (np. karta nie obsługuje płatności cyklicznych/bez kodu CVV) albo blokadę środków lub karta nie obsługuje płatności internetowych/MOTO. Sprawdź ustawienia karty lub użyj innej karty.
13 Invalid amount or currency conversion field overflow Nieprawidłowa kwota transakcji (przekroczenie limitu) lub błędne przeliczenie walut. ODMOWA – Sprawdź, czy dla Twojej karty dostępna jest usługa płatności internetowych lub MOTO, zweryfikuj ustawienia limitów dla takich transakcji lub skontaktuj się z Twoim bankiem (wystawcą karty) w celu wyjaśnienia przyczyny odmowy.
30 Format error Błędny format danych wiadomości autoryzacyjnej. ODMOWA - skontaktuj się z Twoim bankiem w celu wyjaśnienia przyczyny problemu
92,94,98 Issuer or switch inoperative Usługa tymczasowo niedostępna, spróbuj Ponownie ODMOWA – Tymczasowy błąd po stronie banku, spróbuj ponownie.
E3 3D-Secure not available Błąd systemu weryfikacji 3D-Secure w banku. ODMOWA – Błąd systemu ACS w banku. Spróbuj ponownie lub skonsultuj się z bankiem lub sprzedawcą.
E5 3D-Secure not available Tymczasowy błąd przy weryfikacji 3D-Secure ODMOWA – Tymczasowy błąd przy weryfikacji 3D-Secure, spróbuj ponownie później lub skontaktuj się ze sprzedawcą.

Dodatkową, kategorią są kody niezwiązane z odrzuceniami przez wydawcę karty. Obejmuja kody związane z akceptacją płatności oraz odrzucenia po stronie Agenta Rozliczeniowego/Espago/

Kod odrzucenia Oryginalny komunikat Znaczenie Opis/Proponowany komunikat
00 Approved and completed successfully Gdy stan płatności executed - brak błędu. Transakcja przebiegła prawidłowo.
00 nd. Gdy stan płatności rejected - odrzucenie transakcji na poziomie operatora (sugerowany kontakt z Espago/Elavon) ODMOWA - wystąpił błąd. Transakcja została odrzucona ze względu na brak odpowiedzi z banku, blokadę konta Sprzedawcy, użycie nieobsługiwanego typu karty lub nieprawidłowe dane karty. Prosimy spróbować ponownie później lub skontaktować się z Działem Wsparcia Technicznego Espago.
85 Not declined Autoryzacja przebiegła prawidłowo Bank potwierdził autoryzację.
B04, B14, B15, B41, B43, B54 Abort Płatność zablokowana przez Espago, ze względu na próbę płatności nieaktywaną lub zastrzeżoną kartą. Należy zaktualizować profil klienta przy użyciu innej karty. ODMOWA - karta utraciła ważność lub jest zablokowana i można jej obciążyć. Użyj innej karty.
B46 Closed account Płatność zablokowana przez Espago. Konto zamknięte, tą kartą nie uda się dokonać płatności. ODMOWA – proszę użyć innej karty.
B1A, B65 Abort Płatność zablokowana przez Espago ze względu na brak silnego uwierzytelnienia (SCA) ODMOWA - Wymagane silne uwierzytelnienie (SCA)
E1 Refusal limit exceeded Płatność zablokowana przez Espago ze względu na przekroczenie limitu odrzuconych powtórzeń i ryzyko dodatkowych opłat u operatora. ODMOWA - przekroczenie limitu odrzuceń transakcji.
Q1 nd. Płatność zablokowana przez agenta rozliczeniowego z powodu podejrzenia oszustwa. Kod odrzucenia nadany przez agenta rozliczeniowego zwracany jest w parametrze reject_reason. Opis/Proponowany komunikat: ODMOWA - podejrzenie oszustwa.
Q2 retry_later Wystąpił błąd podczas komunikacji z systemem agenta rozliczeniowego. Ewentualna dodatkowa informacja dot. błędu zostanie zwrócona w parametrze reject_reason. Spróbuj ponownie później.
N1 Could not use the network token and the full card number is no longer stored Token sieciowy karty jest niedostępny, a pełny numer karty nie jest już przechowywany w Profilu Kienta. Token sieciowy karty nie może zostać użyty.


Czym jest “soft decline”

W związku z wprowadzeniem zasad dotyczących silnego uwierzytelnienia - (SCA - Strong Consumer Authentication), organizacje kartowe wprowadziły dwa kody odpowiedzi informujące o konieczności silnego uwierzytelnienia klienta. Są to kody:

- 1A - wymagane silne uwierzytelnienie - dla kart Visa
- 65 - wymagane silne uwierzytelnienie - dla kart Mastercard

Odrzucenie płatności z jednym z wyżej wymienionych kodów oznacza, że bank wymaga działania klienta w celu potwierdzenia zasadności obciążenia. Nie świadczy to o konieczności użycia innej karty, a jedynie konieczności potwierdzenia przez klienta, np. z użyciem mechanizmu 3D-Secure, w celu umożliwienia realizacji kolejnych obciążeń inicjowanych przez sprzedawcę (MIT).

Jak należy postąpić w przypadku odrzucenia płatności typu “soft decline”

Jeśli próba obciążenia z użyciem zapisanych w Profilu Klienta danych karty zakończyła się niepowodzeniem z kodem odpowiedzi 1A lub 65, należy:
1. Wstrzymać automatyczne ponawianie płatności z użyciem tego Profilu Klienta - jeśli sprzedawca stosuje taki mechanizm, np. subskrypcje, bo płatności te nie powiodą się do momentu silnego uwierzytelnienia;
2. Poinformować klienta o odmowie płatności i konieczności uwierzytelnienia w celu umożliwienia dalszych obciążeń, np. poprzez wiadomość email informującą o konieczności zalogowania się do serwisu w celu aktualizacji formy płatności;
3. Dokonać obciążenia z udziałem klienta, dodając do żądania API na ścieżkę /api/charges, parametr cof=storing - zainicjuje to silne uwierzytelnienie klienta - dlatego niezbędny jest jego udział w tym procesie.

Gdy odrzucenie soft decline nadal wystąpuje
Jeśli po dokonaniu silnie uwierzytelnionej płatności nadal następują odrzucenia typu “soft decline” należy zgłosić ten problem w banku lub użyć innej karty (inicjując cały proces płatności od nowa, ze stworzeniem tokenu dla nowej karty).

Profil klienta, przy użyciu którego dokonana została płatność z wykorzystaniem silnego uwierzytelnienia (SCA), nadaje się dalszych obciążeń bez udziału klienta, czyli inicjowanych przez sprzedawcę (MIT), np. subskrypcji (cof=recurring) lub automatycznego wyrównywania salda po wykonaniu usługi (cof=unscheduled).

link Odpowiedź przy błędnym zapytaniu

Gdy przesłane parametry są niepoprawne lub w zapytaniu do API brakuje części danych, zapytanie zostanie odrzucone z kodem HTTP 422 lub innym, wskazującym na konkretny problem.

Odrzucenie zapytania z kodem HTTP 422 należy rozumieć jako odrzucenie niepoprawnego zapytania do API, a nie odmowę autoryzacji płatności (do próby dokonania płatności w ogóle nie dochodzi).

Dla każdej błędnej lub brakującej zmiennej w zapytaniu, generowany jest element tablicy asocjacyjnej zawierający:
* code - usystematyzowany komunikat z nazwą zmiennej i rodzajem błędu. Lista komunikatów do pobrania
* message - komunikat w języku naturalnym zawierający informację o nazwie zmiennej i rodzaju błędu
* param - nazwę brakującej lub posiadającej błędną wartość zmiennej
* type - rodzaj błędu

Odpowiedź przy niepoprawnym opisie płatności

{
    "errors": [
        {
            "code": "description:invalid_length",
            "message": "Description should be between 5 and 255 characters, was: 0",
            "param": "description",
            "type": "invalid_request_error"
        }
    ]
}

Odpowiedź przy próbie dwukrotnego użycia tokenu karty

{
  "errors": [
    {
      "code": "card:token_not_found",
      "message": "Card token not found",
      "param": "card",
      "type": "card_error"
    }
  ]
}

Odpowiedź przy próbie użycia nieisniejącego/usuniętego profilu klienta, profilu klienta należącego do innego konta lub profilu klienta bez danych karty płatniczej

{
    "errors": [
        {
            "code": "card:blank",
            "message": "Card can't be blank",
            "param": "card",
            "type": "card_error"
        }
    ]
}

link Zarezerwowanie środków przyszłego obciążenia na koncie klienta

Możliwe jest zarezerwowanie środków przyszłego obciążenia karty klienta. Preautoryzacja odbywa się za pomocą wysłania żądania typu POST na adres https://sandbox.espago.com/api/charges

Wysyłane w żądaniu parametry obciążenia są takie same jak w przypadku tworzenia nowego obciążenia (opisane powyżej), z jednym dodatkowym parametrem, który określa to żądanie jako zarezerowowanie środków. Jest to parametr complete, domyślnie przyjmuje on wartość true - wtedy żądanie traktowane jest jako zwykłe obciążenie. Gdy parametr complete przyjmuje wartość false, oznacza to zarezerwowanie środków na karcie klienta dla przyszłego obciążenia.

Preautoryzację można dokończyć dokonując potwierdzenia płatności (zapytanie “complete”, skutkujące zmianą statusu płatności na “executed”) lub anulowania/wycofania (zapytanie “DELETE”, skutkujące zmianą statusu płatności na “reversed”).

Maksymalny okres zablokowania konkretnej kwoty na karcie klienta jest zdefiniowany w regulaminie instytucji wydającej kartę. Ten okres zależy więc od wydawcy karty. Zwykle jest to czas nie dłuższy niż 1-2 tygodnie.

curl -i https://sandbox.espago.com/api/charges \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
-d "card=cc_7724fuzWy0SYasoLV" \
-d "amount=49.99" \
-d "currency=pln" \
-d "description=Opis transakcji" \
-d "complete=false"
require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new(user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD')
response = client.send(
  'api/charges',
  method: :post,
  body: {
    card: 'cc_7724fuzWy0SYasoLV',
    amount: 49.99,
    currency: 'pln',
    description: 'Opis transakcji',
    complete: false
  }
)

puts response.body
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/charges');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "card=cc_7724fuzWy0SYasoLV&amount=49.99&currency=pln&description=Opis transakcji&complete=false");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
{
  "id":"pay_772Zm0D5saC0pEA9",
  "description":"Opis transakcji",
  "channel":"elavon",
  "amount":"49.99",
  "currency":"pln",
  "state":"preauthorized",
  "client":"cli_772yY9NvH2Hyt2DM",
  "created_at":1561559076,
  "card":{ ... },
  "issuer_response_code":"00",
  "completed":false,
  "reversable":true,
  "transaction_id":"tr_772_88A0S"
}

link Obciążenie zarezerwowanych środków na karcie klienta

Aby obciążyć zarezerwowane wcześniej środki na karcie klienta należy wysłać żądanie typu POST na adres https://sandbox.espago.com/api/charges/(:id)/complete

(:id) - identyfikator preautoryzowanych środków na karcie, które mają być teraz obciążone


Uwaga
Żądanie może zawierać kwotę obciążenia. Jeżeli nie zostanie podana kwota obciążenia, zostaje ono wykonane dokładnie na kwotę zarezerwowanych środków. Można obciążyć kartę klienta kwotą większą od 0 do 115 % zarezerwowanych wcześniej środków.

curl -i https://sandbox.espago.com/api/charges/pay_772Zm0D5saC0pEA9/complete \
-X POST \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
-d "amount=35"
require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new(user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD')
payment_id = 'pay_8a1Wx0ggKxvxxmv1'
response = client.send(
  "api/charges/#{payment_id}/complete",
  method: :post,
  body: {
    amount: 35
  }
)

puts response.body
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/charges/pay_772Zm0D5saC0pEA9/complete');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "amount=35");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
{
  "id":"pay_772Zm0D5saC0pEA9",
  "description":"Opis transakcji",
  "channel":"elavon",
  "amount":"35.00",
  "currency":"pln",
  "state":"executed",
  "client":"cli_772yY9NvH2Hyt2DM",
  "created_at":1561559076,
  "issuer_response_code":"00",
  "reversable":true,
  "transaction_id":"tr_772JlqSER"
}

link Wycofanie istniejącej płatności przed rozliczeniem

Wycofanie płatności może odbyć się jedynie przed jej rozliczeniem i każdorazowo dotyczy całej kwoty transakcji. W przypadku środowiska testowego płatności rozliczane są co godzinę, a produkcyjnego co 24 godziny (poniędzy godziną 22:30 a 00:00). Po tym czasie możliwy jest jedynie ich zwrot (refund).
Wycofanie płatności jest również sposobem na anulowanie preautoryzacji, w ten sposób na koncie bankowym klienta szybciej zniknie rezerwacja środków. Wycofanie preautoryzacji może zostać dokonane w ciągu kilku/kilkunastu dni od dnia dokonania preautoryzacji.


W przypadku gdy płatnosć została już rozliczona w Elavon (w banku) próba wycofania płatności nie powiedzie się.

Usunięcie istniejącej płatności przed jej całkowitym rozliczeniem następuje w wyniku wysłania żądania typu DELETE na adres https://sandbox.espago.com/api/charges/(:id)

(:id) - identyfikator płatności, którą chcą Państwo usunąć

curl -i https://sandbox.espago.com/api/charges/pay_772Zm0D5saC0pEA9 \
-X DELETE \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD
require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
payment_id = 'pay_8a1Wx0ggKxvxxmv1'
response = client.send "api/charges/#{payment_id}", method: :delete

puts response.body
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/charges/pay_772Zm0D5saC0pEA9');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');

curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
{
  "id":"pay_772Zm0D5saC0pEA9",
  "description":"Opis transakcji",
  "channel":"elavon",
  "amount":"35.00",
  "currency":"pln",
  "state":"reversed",
  "client":"cli_772yY9NvH2Hyt2DM",
  "created_at":1561559076,
  "issuer_response_code":"00",
  "transaction_id":"tr_772JlqSER"
}

link Wyświetlanie obciążeń

Pobranie danych utworzonego wcześniej obciążenia następuje w wyniku wysłania żądania typu GET na adres https://sandbox.espago.com/api/charges/(:id)

(:id) - identyfikator obciążenia, którego dane chcą Państwo pobrać

curl -i https://sandbox.espago.com/api/charges/pay_771MKFI-15SIK1Pm \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD
require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
payment_id = 'pay_8a1Wx0ggKxvxxmv1'
response = client.send "api/charges/#{payment_id}", method: :get

puts response.body
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/charges/pay_771MKFI-15SIK1Pm');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);

{
  "id": "pay_771MKFI-15SIK1Pm",
  "description": "Espago docs",
  "channel": "elavon",
  "amount": "10.00",
  "currency": "PLN",
  "state": "executed",
  "client": "cli_771Xsyr9GkpN8iTp",
  "created_at": 1559130872,
  "card": {
    "company": "VI",
    "last4": "4242",
    "year": 2024,
    "month": 9,
    "first_name": "Adam",
    "last_name": "Nowak",
    "authorized": null,
    "created_at": 1612977801
  },
  "issuer_response_code": "00",
  "reversable": true,
  "transaction_id": "tr_771EQhf18",
  "reference_number": "Test_doc"
}

Wyświetlanie określonej strony z określoną liczną obciążeń na stronę następuje w wyniku wysłania żądania typu GET na adres https://sandbox.espago.com/api/charges?page=1&per=10&client=client_id

Dostępne parametry HTTP

Parametr Opis Wartość domyślna
page Numer strony 1 (pierwsza strona)
per Liczba obciążeń na każdej stronie 25 (25 obciążeń)
client ID klienta, którego mają dotyczyć transakcje wszyscy klienci
curl -i https://sandbox.espago.com/api/charges \
-X GET \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
-d "page=1" \
-d "per=5" \
-d "client=cli_772YYE_98HM1DmAD"
require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
response = client.send(
  'api/charges',
  method: :get,
  body: {
    client: 'cli_772YYE_98HM1DmAD',
    page: 1,
    per: 5,
  }
)

puts response.body
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/charges');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "page=1&per=5&client=cli_772YYE_98HM1DmAD");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
{
  "count":4,
  "charges":[
    {
      "id":"pay_772xZV-3uSUTIxPz",
      "description":"Payment #88",
      "channel":"elavon",
      "amount":"79.00",
      "currency":"pln",
      "state":"executed",
      "client":"cli_772YYE_98HM1DmAD",
      "created_at":1561645210,
      "card":{ ... },
      "issuer_response_code":"00",
      "reversable":true,
      "transaction_id":"tr_772bk-yP2"
    },
    {
      "id":"pay_772X3bE9o9JHdpZt",
      "description":"Payment #23",
      "channel":"elavon",
      "amount":"19.99",
      "currency":"pln",
      "state":"executed",
      "client":"cli_772YYE_98HM1DmAD",
      "created_at":1561645191,
      "card":{ ... },
      "issuer_response_code":"00",
      "reversable":true,
      "transaction_id":"tr_772ZZm3Zt"
    },
    . . .
  ]
}

link Kody odpowiedzi HTTP

Pomyślnie przetworzone zapytania API otrzymują sychronniczną odpowiedź z bramki z kodem HTTP 200 (OK).
Odpowiedzi z kodem 4xx oraz 5xx świadczą o błędach w procesowaniu zapytania do bramki i nie powinny być utożsamiane z odrzuceniem transakcji.


Kody błędów HTTP w bramce Espago:


HTTP 401

Jest odpowiedzią na błędne dane autoryzacyjne zapytania.

Przykładowa odpowiedź


{
   "error":"Invalid authentication credentials."
}

HTTP 422

Jest wynikiem błędu integratora. Pojawia się gdy dane zawarte w zapytaniu są niepoprawne i nie mogą zostać przeprocesowane.
Komunikat błędu wskazuje na dane, które uniemożliwiają przetworzenie zapytania.

Przykładowa odpowiedź


{
   "errors":[
      {
         "code":"currency:invalid_currency",
         "message":"Currency is not a valid ISO 4217 currency",
         "param":"currency",
         "type":"invalid_request_error"
      }
   ]
}

HTTP 500

Odpowiedzi z kodem 500 oznaczają tymczasowe problemy techniczne Bramki Espago bądź ze strony systemów Agentów Rozliczeniowych. W przypadku uzyskania odpowiedzi HTTP500 zalecany jest kontakt z Działem Wsparcia Technicznego.

Przykładowa odpowiedź


{
   "error":"Something went wrong"
}

Próby obciążeń zakończone kodem HTTP 500 bądź zakończone statusem failed powinny być traktowane jako niezrealizowane w wyniku tymczasowych problemów technicznych oraz ponowione. Wówczas jeśli pomimo problemów technicznych obciążenie się odbędzie, zostanie ono automatycznie wycofane/zwrócone.

Płatności wielokrotne autorenew

link Czym są płatności wielokrotne i cykliczne

Mianem płatności wielokrotnych określamy płatności, które odbywają się z użyciem zapisanych w Espago danych karty. Dzielą się one na:

  • płatności inicjowane przez posiadacza karty (Cardholder Initiated Transaction - CIT);

  • płatności inicjowane przez sprzedawcę (Merchant Initiated Transactions - MIT).

Płatności inicjowe przez posiadacza karty (CIT), to płatności z użyciem zapisanych danych karty, w których czynny udział bierze posiadacz karty. Do tego rodzaju zaliczane są płatności typu one-click, dokonywane za zakup - bez konieczności wprowadzania pełnych danych karty, jednak z wykorzystaniem mechanizmów silnej weryfikacji (SCA).

Płatności inicjowane przez sprzedawcę, to takie, które nie wymagają udziału posiadacza karty, i są realizowane na podstawie umowy sprzedawcy posiadaczem karty, wyrażającym zgodę na jej obciążanie. Są to:

  • płatności cykliczne (recurring payments) - za usługi świadczone w sposób ciągły lub cykliczny, na stałą kwotę, pobierane przez Sprzedawcę w równych odstępach;

  • płatności dokonywane jako wyrównanie salda klienta, za usługi niecykliczne, na różne kwoty;

  • spłata rat kartą;

  • płatności specyficzne dla branży, np. opłata no-show dla rezerwacji hotelowych, rozszerzenie usługi w ramach najmu.

Płatności cykliczne (recurring payments) - subskrypcje

Realizowanie cyklicznych obciążeń kart klientów w ramach bramki Espago możliwe jest na dwa sposoby:

Płatności wielokrotne realizowane po stronie sprzedawcy Płatności cykliczne realizowane po stronie Espago
  • Gdy wysokość lub częstotliwość opłat jest zmienna.
  • Gdy poza opłatami cyklicznymi przez klientów realizowane są również płatności jednorazowe.
  • Gdy Sprzedawca posiada już mechanizmy zarządzające terminami płatności.
  • Gdy Sprzedawca chce oferować szybkie zakupy dla stałych klientów (one-click payment).
  • Gdy wysokość i częstotliwość opłat są stałe, np. miesięczny abonament.

Ten rozdział opisuje płatności inicjowane przez mechanizmy po stronie Sprzedawcy. Więcej informacji na temat subskrypcji Espago można znaleźć w rozdziale Subskrypcje Espago.

link Scenariusz płatności wielokrotnych

Aby spełniać wymogi organizacji kartowych oraz regulatora rynku płatności, prawidłowy przebieg płatności z wykorzystaniem zapisanej w Espago karty musi przebiegać następująco:

  1. Należy wywołanie płatność z parametrem cof=storing (w przypadku płatności nieregularnych przez Elavon dodatkowo odpowiednim authentication_ind) na kwotę równą przyszłemu obciążeniu cyklicznemu lub 0 jednostek walutowych. Płatność ta spowoduje stworzenie w bramce Espago profilu klienta z zapisanymi danymi karty. W odpowiedzi na request API, Sprzedawca otrzymuje szczegóły płatności, w tym identyfikator płatności, profilu klienta i adres do przekierowania w celu realizacji SCA (3-D Secure).
  2. Opcjonalnie, zaraz po płatności z SCA można wywołać płatność z wykorzystaniem stworzonego profilu klienta z określona wartością parametru cof, w celu sprawdzenia, czy karta obsługuje płatności typu MIT - zobacz: Problem kart nie nadających się do płatności cyklicznych.
  3. Następnie, Sprzedawca inicjuje płatności zgodnie z warunkami umowy zawartej z posiadaczem karty, żądaniem do API zawierającym identyfikator profilu klienta, dodając parametr cof o wartości zgodnej z charakterem płatności. Wartości parametru cof

Parametr cof jest konieczny do poprawnego oznaczenia płatności inicjowanych przez sprzedawcę. W przypadku jego braku, płatność z wykorzystaniem zapisanego profilu klienta będzie traktowana jako płatność inicjowana przez posiadacza karty i wymagała przekierowania w celu silnej autoryzacji.
Wartość recurring parametru cof zastępuje wcześniejsze oznaczenie płatności jako recurring=true w bramce Espago. Parametr recurring bramce Espago jest wycofywany.


Uwaga
Gdy zapisane dane karty są wykorzystywane w płatności inicjowanej przez klienta, należy pominąć parametr cof.

link Zasady i dobre praktyki płatności cyklicznych

Działanie Opis / Komentarz
Płatności inicjowane przez sprzedawcę (recurring, płatności wielokrotne) muszą być poprzedzone silnym uwierzytelnieniem. Przed rozpoczęciem serii płatności inicjowanych przez sprzedawcę (MIT, czyli subskrypcji, recurring i płatności wielokrotnych) należy dokonać płatności z silnym uwierzytelnieniem (SCA), korzystającym z mechanizmów 3-D Secure. Płatność ta powinna opiewać na taką samą kwotę co późniejsze obciążenia (w przypadku subskrypcji) lub na kwotę 0 (zero) jednostek w danej walucie (nie dojdzie wtedy do obciążenia salda klienta, ale zostanie dokonane uwierzytelnienie i autoryzacja w banku).
Nie należy wycofywać płatności inicjującej zapisanie karty, chyba że w związku z rezygnacją. Jeśli Klient nie ma być obciążony, ale Sprzedawca chce zapisać jego kartę (np. darmowy okres usługi) płatność z flagą cof=storing powinno się dokonać na kwotę 0 (zero) jednostek w danej walucie (nie dojdzie wtedy do obciążenia salda klienta, ale zostanie dokonane uwierzytelnienie i autoryzacja w banku). Wycofanie płatności może być przez bank rozumiane jako rezygnacja usługi, i skutkować odrzuceniami późniejszych transakcji cyklicznych.
Należy ograniczać do minimum ponawianie płatności w przypadku odrzucenia Organizacje kartowe wprowadziły następujące ograniczenia w zakresie ponawiania próby obciążenia, w przypadku gdy płatność zostanie odrzucona:
- maksymalnie 1 próba obciążenia dziennie;
- maksymalnie 15 prób obciążeń w ciągu 30 dni. Po tym okresie nie wolno dokonywać dalszych prób obciążenia.
Nie należy kumulować zaległych płatności Należy unikać sytuacji, gdy kilka zaległych, nieudanych płatności klienta skutkuje wieloma próbami obciążeń. W praktyce, jeśli klient zalega z wieloma płatnościami, to jeśli próba jednej się nie powiedzie, pozostałe próby też zakończą się niepowodzeniem.
Należy przerwać subskrypcję gdy karta nie nadaje się do płatności Jeśli kod odrzucenia wskazuje na blokadę karty lub inny przypadek wskazany w tabeli kodów odrzuceń, należy zaprzestać dalszych obciążeń, ponieważ ta karta nie jest i nie będzie już aktywna.
Przy zmianie kwoty płatności cyklicznych, klient powinien ponownie wykonać płatność z silnym uwierzytelnieniem. Zmiana kwoty obciążeń cyklicznych, a więc zmiana warunków umowy wymaga ponownego silnego uwierzytelnienia klienta (SCA)
Dokonanie silnej autoryzacji - wymagającej udziału klienta - jest dla banku potwierdzeniem akceptacji nowego cyklu obciążeń.
Należy używać preautoryzacji jeśli spodziewamy się, że kwota będzie zwrócona, lub docelowe obciążenie będzie tylko na część kwoty preautoryzacji.
Należy unikać preautoryzacji jeśli nie jest ona konieczna.
Preautoryzacja umożliwia blokadę środków z wykorzystaniem silnego uwierzytelnienia, bez jej pobierania.
W zależnosci od umowy z Elavon Visa/MasterCard mogą pobierać stałą, drobną opłatę za każdą preautoryzację (poza prowizją od wykonanej płatności).

link Problem kart nienadających się do płatności cyklicznych

Większość kart płatniczych nadaje się do jednorazowych płatności Internetowych oraz płatności cyklicznych (o ile ich właściciele nie zablokowali takiej możliwości w swoim banku i ustawili odpowiednie limity kwotowe). Istnieją jednak karty, którymi można dokonać jednorazowych płatności internetowych, ale nie nadają się one do płatności cyklicznych. Przykładami takich kart są karty Maestro.

W szczególnych przypadkach, jest więc możliwy scenariusz, w którym udaje się pomyślnie zapisać kartę dokonując pierwszej płatności z silnym uwierzytelnieniem (SCA), a przy próbie płatności cykliczynej (np. po pierwszym okresie rozliczeniowym) taka transakcja jest odrzucana przez bank - wydawcę karty.

Aby unikać takiej sytuacji, od razu po zapisaniu karty za pomocą płatności z parametrem cof=storing z silnym uwierzytelnieniem, można dokonać preautoryzacji z parameterem cof=recurring. Po udanej preautoryzacji (state=preauthorized) można ją wycofać, a kartę klienta uznać za nadajacą się do płatności cyklicznych.

Wszystkie płatności cykliczne i inicjowane przez sprzedawcę (MIT), czyli takie, w których nie jest już używany kod CVV/CVC i nie może być dokonane silne uwierzytelnienie klienta (brak udziału klienta w procesie transakcji), muszą być oznaczone parametrem cof=recurring lub cof=unscheduled.

Krok Działanie Opis
1 Płatność inicjująca z zapisaniem karty w profilu klienta Sprzedawca wywołuje płatność z parameterem cof=storing, na kwotę, która będzie równa cyklicznym obciążeniom lub 0 jednostek walutowych. Należy spodziewać się, że klient będzie musiał dokonać silnego uwierzytelnienia (3D-Secure).
POWODZENIE PŁATNOŚCI: karta obsługuje płatności internetowe, można przejść do kroku 2. Ta płatność nie powinna być wycofywana/zwracana. Po pomyślnej płatności, utworzony automatycznie w jej trakcie profil klienta cli_xxxxxxxxxx nadaje się do późniejszego użycia.
NIEPOWODZENIE PŁATNOŚCI: karta nie została zautoryzowana z silnym uwierzytelnieniem i nie może być użyta do kolejnych płatności cyklicznych 1,3.
2 Utworzenie subskrypcji
lub
Autoryzacja typu MIT
lub
Autoryzacja lub preautoryzacja testująca możliwość płatności typu MIT
Utworzenie subskrypcji (z automatyczną pierwszą płatnością) lub pierwsze żądanie obciążenia karty klienta inicjowane przez sprzedawcę z parametrem (w przypadku cykliczności realizowanej po stronie Sprzedawcy) lub przeprowadzenie autoryzacji (w przypadku gdy Sprzedawca chce tylko sprawdzić działanie karty, bez jej obciążania).
POWODZENIE: karta obsługuje płatności internetowe i cykliczne. Kolejne obciążenia są możliwe2.
NIEPOWODZENIE: karta nie obsługuje płatności cyklicznych, więc na pewno nie powiodą się kolejna próby obciążenia1.

1 - Jeżeli powodem odrzucenia jest nieobsługiwanie płatności internetowych/MOTO przez tę kartę lub zbyt niskie limity, to po zmianie tych ustawień przez posiadacza karty, może on ponowić próbę zarejestrowania karty.

2 - W przypadku gdy klient nie będzie posiadał środków pieniężnych na koncie/karcie lub ważność karty wygaśnie, płatności przestaną być możliwe.

3 - W przypadku gdy przyczyną odrzucenia autoryzacji będzie niepoprawny kod CVV/CVC (kod odrzucenia: 75, 82, N7) nie należy dokonywać więcej obciążeń tej karty! Takie odrzucenie może wynikać z użycia kradzionej karty (fraud). Następne obciążenia mogą zostać zaakceptowane przez bank ze względu na brak (niepoprawnego) CVV, ale odbywa się to na odpowiedzialność Sprzedawcy.

link Płatności cykliczne (recurring) i powtarzające się (one-click, rozszerzające)

Czym jest card on file?

Card on file jest usługą umożliwiającą zapisanie danych karty płatniczej w Espago - w celu dokonywania obciążeń klienta bez konieczności ponownego wprowadzania danych karty przez jej posiadacza. Określenie Card on file oraz parametr cof funkcjonuje w bramce Espago od lipca 2019r.

Aby skorzystać z card on file w Espago należy:

  • wykonać płatność z silnym uwierzytelnieniem SCA (3D-Secure) i wartością cof=storing (zapisanie karty w ramach card on file) w żądaniu API. Dane zostaną zapisane w Profilu Klienta, a w odpowiedzi zostanie przesłany jego unikalny identyfikator. Dokonanie pierwszej płatności w opisany powyżej sposób jest konieczne aby móc dokonywać kolejnych obciążeń.
  • Wywołanie kolejnych płatności przy użyciu odczytanego Profilu Klienta w modelu card on file. Z punktu widzenia acquirera i banku te płatności będą powiązane z płatnością inicjującą.

Funkcjonalność

Dane karty w Profilu Klienta można aktualizować, a profil - w razie potrzeby - usunąć żądaniem API. Card on file w Espago daje pełnię możliwości wykorzystania potencjału płatności przewidzianych przez organizacje kartowe, co opisane jest w dalszych częściach rozdziału. Obciążenia na podstawie zapisanych danych karty dzielą się na:

  • transakcje inicjowane przez sprzedawcę (Merchant Initiated Transaction) na podstaiwe umowy, np. płatności cykliczne, odroczone, wyrównanie salda;
  • transakcje inicjowane przez posiadacza karty (Cardholder Initiated Transactions) np. one-click.

Płatności inicjowane przez sprzedawcę (Merchant Initiated Transaction)

Po poprawnym przeprocesowaniu płatności inicjującej z wykorzystaniem silnego uwierzytelnienia (SCA), można dokonać kolejnych obciążeń w procesie inicjowanym przez Sprzedawcę - na podstawie umowy zawartej z posiadaczem karty. Przykłowe obciążenia tego typu to:

  • comiesięczna płatność abonamentowa za usługę lub członkostwo w klubie/siłowni;
  • wyrównanie salda po wykonanej usłudze zleconej przez klienta np. przejazd taksówką lub wypożyczenie samochodu na minuty.

Płatności inicjowane przez posiadacza karty

Płatności zapisaną w Espago kartą, inicjowane przez posiadacza karty, np. typu one-click należy wywoływać z parametrem client wskazującym klienta, dla którego dane karty zostały zapisane. Przy płatnościach typu CIT niezbędne będzie wykonanie procedury silnego uwierzytelnienia (SCA). Są to płatności, które następują w wyniku akcji dokonanej przez posiadacza karty, np.:

  • potwierdzenie zakupu w sklepie internetowym przyciskiem “Płacę”;
  • zakup usługi w aplikacji mobilnej.

link Parametr COF - wartości

Parametr cof przyjmuje wartości jest typu string.

Każdą płatność związaną z zapisaniem karty lub użyciem zapisanej karty i inicjowaną przez sprzedawcę należy oznaczać parametrem cof. W przypadku braku tego parametru, płatność z użyciem profilu klienta traktowana jest jako inicjowana przez klienta i wymaga silnej weryfikacji SCA (3-D Secure).

Płatność inicjująca

storing - powoduje zapisanie danych karty i zwraca identyfikator profilu klienta, który może być użyty dla przyszłych płatności. Płatność ta powinna opiewać na kwotę równą każdej kolejnej płatności cyklicznej lub w innych przypadkach - na dowolną kwotę.

Płatności inicjowane przez sprzedawcę (MIT)- zlecenia stałe (standing instructions)

recurring - płatności cykliczne o stałym interwale mniejszym niż rok, w okresie świadczenia usługi w sposób ciągły lub usług świadczonych cyklicznie;
unscheduled - płatności przy użyciu zapisanych danych karty, na stałą lub różną kwotę, która nie jest wykonywana zgodnie z określonym harmonogramem lub interwałem, np. wyrównanie salda za usługę świadczoną na żądanie (np. carsharing, czasowe wypożyczanie hulajnóg);

Płatności inicjowane przez sprzedawcę (MIT) - specyficzne dla branży (industry-specific)

delayed_charge - płatność uzupełniająca (odroczona) po wykonaniu usługi.
Przykładowe zastosowanie - w hotelach, żegludze, wypożyczalni pojazdów.

no-show - płatność na podstawie zawartego umowie uprawnienia sprzedawcy do obciążenia karty w przypadku, gdy z przyczyn leżących po stronie posiadacza karty usługa nie mogła być wykonana.
Przykładowe zastosowanie - niepojawienie się gościa w przypadku rezerwacji bezzwrotnej.

reauthorisation - płatność za zakup dokonany po pierwotnej autoryzacji, może odzwierciedlać różne, szczególne przypadki, np. rozszerzenie usługi ponad pierwotną kwotę autoryzacji.
Przykładowe zastosowanie:
* w eCommerce - przy podzielonej dostawie lub jej opóźnieniu - gdy pierwotna autoryzacja nastąpiła tylko na część kwoty odpowiadającej częściowej dostawie i konieczne jest obciążenia za kolejną część;
* przy przedłużeniu najmu pojazdu lub pobytu w hotelu;

resubmission - płatność za wykonaną usługę, ponowiona w związku z nieuzyskaniem autoryzacji podczas pierwszej próby obciążenia karty;

Subskrypcje Espago poll

link Działanie subskrypcji Espago

Subskrypcje Espago to mechanizm płatności cyklicznych, realizowanych w sposób automatyczny na podstawie zdefiniowanych przez Sprzedawcę planów: z określoną częstotliwością i stałą kwotą obciążenia. Automatyzacja subskrypcji jest realizowana po stronie Espago i zastępuje każdorazowe inicjowanie nowego obciążenia przez Sprzedawcę zapytaniem do API z parametrem cof=recurring.

Do stworzenia subskrypcji niezbędny jest obiekt klienta z przypisanymi danymi karty kredytowej. Łącząc plan z obiektem klienta tworzy się subskrypcje.

  1. Sprzedawca początkowo definiuje w systemie Espago plan (lub wiele planów), czyli schemat płatności cyklicznych określający okres oraz wysokość opłaty.
  2. Sprzedawca inicjuje płatność z silnym uwierzytelnieniem (SCA - 3D-Secure) i parametrem cof=storing, na kwotę odpowiadającą pojedynczemu obciążeniu w ramach planu. Jeśli płatność się powiedzie, Sprzedawca w odpowiedzi otrzumuje identyfikator profilu klienta.
  3. Po utworzeniu profilu klienta, Sprzedawca może uruchomić dla niego subskrypcję. W momencie utworzenia subskrypcji (o ile nie jest to subskrypcja opóźnionym startem) następuje pierwsza próba obciążenia. Jeśli obciążenie się powiedzie, subskrypcja zostaje uruchomiona.
  4. Następne obciążenie będzie miało miejsce po zdefiniowanym w planie okresie. Każda próba obciążenia generuje wysłanie do serwisu Sprzedawcy informacji zwrotnej (back-request) ze statusem płatności.

Informacje o płatnościach cyklicznych (stanach, dotychczasowych próbach obciążeń itd) są zbierane w postaci faktur. Dostępne są one tylko przy płatnościach cyklicznych realizowanych po stronie Espago.

link Konfiguracja

Po uzyskaniu dostępu do panelu merchanta należy wykonać następujące czynności:

  1. Przejść do zakładki
  2. Przejść do okna edycji serwisu wybierając przycisk “Edytuj”
  3. Ustawić adres url żądania zwrotnego (więcej na temat żądań zwrotnych w rozdziale “Back request”)
  4. Uzupełnić czasy powtarzania próby obciążenia nieudanych transakcji oraz określić status na wypadek wykorzystania limitów ponowień. W środowisku produkcyjnym możliwymi wartościami są: 1, 2, 3, 4 dni, a w środowisku testowym krótsze czast (np. liczone w minutach).



Możliwe stany po wyczerpaniu limitów ponownych obciążeń:

Stan Opis
Zatrzymaj subskrypcję Wyłącza subskrypcję uniemożliwiając generowanie kolejnych obciążeń według cyklu ustalonego w szczegółach planu. Status subskrypcji zmieni się na “inactive”.
Nic nie rób Mimo braku pozytywnego wyniku danego obciążenia generowane będą kolejne, zgodnie z planem.

link Plany

Plany definiują schemat płatności cyklicznych, zawierają informacje o wysokości i częstotliwości obciążeń. Na podstawie zdefiniowanych Planów następnie będzie można uruchamiać dla klientów subskrypcje.

Tworząc plan ustala się takie dane jak: typ okresu obciążenia (np. day, month), wartość okresu obciążenia (w przypadku typu okresu period=7 oraz period_unit=day uzyskujemy cykliczność obciążania co 7 dni) oraz kwota pojedyńczego obciążenia. Wszelkie dotyczące tworzenia planów znajdują się w poniższych podrozdziałach.

Utworzenie nowego planu następuje w wyniku wysłania żądania typu POST na adres https://sandbox.espago.com/api/plans umieszczając stosowne parametry.

Dostępne parametry HTTP

Parametr Opis Uwagi
period_unit Jednostka okresu Określa jednostkę, w której następuje rozliczenie, np: day, month.
period Wartość okresu Liczba całkowita. Wspólnie z parametrem period decyduje o częstotliwości obciążeń.
amount Kwota transakcji Liczba dziesiętna, np. 123.45
currency Waluta Symbol waluty zgodny z posiadanym MID
description Opis planu Powinien składać się z co najmniej 5 znaków.

Należy zauważyć, że istotne jest określenie parametrów “period” i “period_unit”, gdyż ich sumaryczne wartości odpowiadają za rzeczywistą częstotliwość obciążeń. Oto dopuszczalne wartości dla powyższych konfiguracji:

Wartość parametru 'period_unit' Dopuszczalne wartości parametru 'period' Uzyskany rezultat
day 1-366 Plan obciążający konto klienta co zadaną liczbę dni
month 1-12 Plan obciążający konto klienta co zadaną liczbę miesięcy

Przykładowe zapytanie o utworzenie planu:

curl -i https://sandbox.espago.com/api/plans -H \
'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
-d "description=opis planu" \
-d "period_unit=month" \
-d "period=1" \
-d "amount=50" \
-d "currency=pln"


require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
response = client.send(
  'api/plans',
  method: :post,
  body: {
    description: 'plan description',
    period_unit: 'month',
    period: 1,
    amount: 50,
    currency: 'pln'
  }
)

puts response.code
puts response.body


$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/plans');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "description=opis planu&period_unit=month&period=1&amount=50&currency=pln");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close ($ch);

{
  "id":"pl_77299uAqqIu4a6eQB",
  "description":"opis planu",
  "period":1,
  "period_unit":"month",
  "amount":"50.0",
  "currency":"pln",
  "created_at":1559739533
}


Pobranie danych utworzonego wcześniej planu następuje w wyniku wysłania żądania typu GET na adres https://sandbox.espago.com/api/plans/(:id)
(:id) - identyfikator planu, którego dane chcą Państwo pobrać

curl -i https://sandbox.espago.com/api/plans/ID \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD


require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
plan_id = 'pl_8a1W3P6xTXOZ4epTp'
response = client.send "api/plans/#{plan_id}", method: :get

puts response.code
puts response.body


$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/plans/ID');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close ($ch);

{
  "id":"pl_77299uAqqIu4a6eQB",
  "description":"opis planu",
  "period":1,
  "period_unit":"month",
  "amount":50.0,
  "currency":"pln",
  "created_at":1559739533
}


Celem usunięcia stworzonego wcześniej planu należy wysłać żądanie metodą DELETE na adres https://sandbox.espago.com/api/plans/(:id)
(:id) - identyfikator planu, którego dane chcą Państwo usunąć

curl -i https://sandbox.espago.com/api/plans/ID \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
-X DELETE 

require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
plan_id = 'pl_8a1FInbtEadoX0PER'
response = client.send "api/plans/#{plan_id}", method: :delete

puts response.code
puts response.body


$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/plans/ID');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');

curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close ($ch);

W odpowiedzi wysyłamy - Status: 204 NoContent

By dokonać zmiany ustawień planu należy wysłać żądanie metodą PUT na adres: https://sandbox.espago.com/api/plans/(:id)
(:id) - identyfikator modyfikowanego planu

Reszta paramterów i wartości jest identyczna, jak przy tworzeniu nowego planu

UWAGA
Modyfikacje planu nie dotyczą już istniejących subskrypcji - zmiany obejmą jedynie te utworzone po wysłaniu powyższego requestu! W związku z tym, dla utrzymania porządku sugerujemy nie korzystać z aktualizacji planu, a tworzyć nowe plany.

curl -i https://sandbox.espago.com/api/plans/ID \
-X PUT -u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
-d "description=Aktualzacja planu" \
-d "period_unit=month" \
-d "period=1" \
-d "amount=75" \
-d "currency=pln"


require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
plan_id = 'pl_8a1FInbtEadoX0PER'
response = client.send(
  "api/plans/#{plan_id}",
  method: :put,
  body: {
    description: 'updated plan description',
    period_unit: 'month',
    period: 1,
    amount: 75,
    currency: 'pln'
  }
)

puts response.code
puts response.body


$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/plans/ID');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "description=Aktualzacja planu&period_unit=month&period=1&amount=75&currency=pln");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');

curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close ($ch);

W odpowiedzi wysyłamy - Status: 204 No Content

Pobieranie listy dostępnych planów następuje w wyniku wysłania żądania metodą GET na adres: https://sandbox.espago.com/api/plans

curl -i https://sandbox.espago.com/api/plans \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD 


require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
response = client.send 'api/plans', method: :get

puts response.code
puts response.body


$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/plans');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close ($ch);

{
  "count":3,
  "plans":[
  {
    "id":"pl_772F0N8AqpLJ8tUhK",
    "description":"Karnet EXCLUSIVE PRO",
    "period":1,
    "period_unit":"month",
    "amount":119.0,
    "currency":"pln",
    "created_at":1559745412
  },
  {
    "id":"pl_772eAqoP50JRfV3Fo",
    "description":"Karnet PRO",
    "period":1,
    "period_unit":"month",
    "amount":79.0,
    "currency":"pln",
    "created_at":1559745395
  },
  {
    "id":"pl_772tYQqPm5QaD9ye9",
    "description":"Karnet NORMAL",
    "period":1,
    "period_unit":"month",
    "amount":50.0,
    "currency":"pln",
    "created_at":1559745382
  }]
}


link Subskrypcje

Subskrypcja (abonament) tworzony jest przez przypisanie planu do klienta.

Domyślnie subskrypcja działa od momentu jej uruchomienia (następuje jest wtedy pierwsze obciążenie) i kolene obciążaenia w ramach tej subskrypcji są wywoływane z okresem zdefiniowanym w danym planie. Godzina, o której następuje każda próba obciążenia w zaplanowanym dniu jest zbliżona do godziny utworzenia subskrypcji.

Subskrypcja jest zatrzymywana gdy wystąpi którykolwiek z przypadków:

  • pierwsza płatnosć się nie powiedzie (czyli subskrypcja nie jest w ogóle uruchamiana);
  • Sprzedawca wyśle żądanie zatrzymania subskrypcji;
  • nastąpi trzykrotna odmowa autoryzacji w ramach jednego cyklu (jeżeli zatrzymanie subskrypcji w takiej sytuacji zostało skonfigurowane w panelu www);
  • nastąpi odmowa autoryzacji przez bank - z powodu blokady karty przpisanej do profilu klienta*

W przypadku odmowy autoryzacji z kodami: 03, 04, 07, 12, 14, 15, 41, 43, 54, 57, 62, 78, 82, N7, 93, R0, R1, R3,B04, B14, B15, B41, B43, B54 subskrypcja jest od razu zatrzymywana, ponieważ karta zapisana w profilu klienta nie nadaje się już do użycia. W takim przypadku należy poprosić użytkownika o podanie nowej karty i uruchomić subksrypcję ponownie.

Istnieje również możliwość uruchomienia subskrypcji z opóźnionym startem, czyli z ustaloną datą pierwszego obciążenia - późniejszą niż wysłanie żądania tworzącego subskrypcję.

Utworzenie nowej subskrypcji następuje w wyniku wysłania żądania typu POST na adres https://sandbox.espago.com/api/subscriptions i wybrania klienta oraz właściwego planu.

Dostępne parametry HTTP

Parametr Opis Uwagi
client ID klienta Parametr wymagany
plan ID planu Parametr wymagany
channel Kanał płatności Parametr opcjonalny - domyślnie przyjmuje wartość kanału płatności serwisu. Wartości: elavon_cc, worldline_cc, polcard_cc.
start_time Moment uruchomienia subskrypcji Parametr opcjonalny. Wartość musi być znacznikiem czasu w formacie unix. Domyślnie (bez parametru start_time) subskrypcja jest uruchamiana w momencie wywołania żądania. Parametr wymaga wartości czasu unix z przedziału: od 59 minut do 1 roku od żądania API.
curl -i https://sandbox.espago.com/api/subscriptions \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
-d "client=client_id" \
-d "plan=plan_id"
require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
response = client.send(
  'api/subscriptions',
  method: :post,
  body: {
    client: 'cli_772YYE_98HM1DmAD',
    plan: 'pl_8a1trIGa-EMTQN1VI'
  }
)

puts response.code
puts response.body
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/subscriptions');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "client=client_id&plan=plan_id");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close ($ch);
W odpowiedzi poza informacją dotyczącą subskrypcji wysyłamy także dane pierwszego obciążenia (last_invoice).
{
  "id": "sub_i3CoQEnqX5IKve",
  "state": "active",
  "client": "cli_buoBpPrw6rU7iC",
  "plan": "pl_vGTGxa_Kf521Sdv",
  "created_at": 1373461486,
  "last_invoice": {
    "id": "in_MVt4vwsp7VvOTqa",
    "date": 1373461485,
    "client": "cli_buoBpPrw6rU7iC",
    "subscription": "sub_i3CoQEnqX5IKve",
    "amount": "7.00",
    "currency": "PLN",
    "paid": true,
    "issuer_response_code": "00",
    "attempts": 1,
    "next_payment_attempt": "null",
    "created_at": 1373461485
  }
}

Uwaga!
Jeżeli pierwsza płatność wykonywana przy tworzeniu subskrypcji się nie powiedzie to subskrypcja od razu wygasa - jest to zabezpieczenie przeciwko tworzeniu subskrypcji przy użyciu karty, która np. nie obsługuje transakcji internetowych/MOTO.
W takim przypadku w odpowiedzi na zapytanie tworzące subskrypcję (/api/subscriptions) obok id subskrypcji będzie informacja że jest nieaktywna: "state":"inactive".

Kolejne odpowiedzi

Poza utworzoną subskrypcją nastąpi utworzenie 1. faktury, która jest właściwą informacją o stanie transakcji. Informacje o kolejnych obciążeniach przychodzą w formie asynchronicznych back requestów na adres żądania zwrotnego (więcej informacji w dziale Back request) i są generowane są w momencie utworzenia nowej lub próby obciążenia już istniejącej. Przykładowy back request (więcej informacji w dziale Faktury):

{
  "id": "in_hS-KiS3N6YCzOhG",
  "date": 1371631155,
  "client": "cli_OU7k00vEMGi53C",
  "subscription": "sub_QyJzN4KdzNzvmZ",
  "amount": "7.00",
  "currency": "PLN",
  "paid": true,
  "attempts": 1,
  "next_payment_attempt": "null",
  "created_at": 1371500155
}

Back requesty są wysyłane do momentu otrzymania z aplikacji kodu 200 ‘Ok’ maksymalnie przez 24h z rosnącym interwałem.

Isnieje możliwość utworzenia subskrypcji, której start (pierwsze obciążenie) nastąpi w zadeklarowanym przez Sprzedawcę momencie. Aby uruchomić subskrypcję z opóźnionym startem należy w zapytaniu tworzącym subskrypcję przesłać parametr start_time z odpowiednią wartością (opis w tabelce powyżej).

  • Jest to opcja przydatna np. w celu realizacji początkowego darmowego okresu.
  • Po uruchomieniu subskrypcji z opóźnionym startem działa ona tak jak zwykła subskrypcja.
  • Możliwe jest zatrzymanie subskrypcji zanim nastąpi pierwsze wywołanie.

Subskrypcja z opóźnionym startem posiada pewne ograniczenia:

  • W momencie tworzenia subskrypcji nie następuje pierwsza próba płatności, a więc nie ma mechanizmu blokującego rozpoczęcie subskrypcji w przypadku takiego odrzucenia. Możliwe jest więc uruchomienie subskrypcji dla karty, której nie da się obciążyć, gdyż np. nie obsługuje płatności internetowych i/lub cyklicznych - Sprzedawca o tym fakcie dowie się w chwili próby pierwszego obciążenia.
  • Aby uniknąć powyższego problemu, Sprzedawca powinien upewnić się wcześniej czy karta obsługuje płatności cykliczne.
  • Należy sprawdzić datę ważności karty - musi być większa, niż data planowanego pierwszego pobrania. W przypadku gdy zpaisana karta utraci ważność zbyt wcześnie, warto zaproponować klientowi użycie innej karty, o dłuższym terminie ważności.
  • Moment planowego uruchomienia subskrypcji określony w parametrze start_time musi być późniejszy niż 59 minut licząc od chwili wysłania żądania do API Espago i wynosić maksymalnie 1 rok licząc od chwili wysłania żądania.

Pobranie danych utworzonej wcześniej subskrypcji następuje w wyniku wysłania żądania typu GET na adres https://sandbox.espago.com/api/subscriptions/(:id)
(:id) - identyfikator subskrypcji, której dane chcą Państwo pobrać

curl -i https://sandbox.espago.com/api/subscriptions/ID \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD
require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
subscription_id = 'sub_8a1xsjIpXYYlKFzF'
response = client.send "api/subscriptions/#{subscription_id}", method: :get

puts response.code
puts response.body
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/subscriptions/ID');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close ($ch);
{
  "id": "sub_i3CoQEnqX5IKve",
  "state": "active",
  "client": "cli_buoBpPrw6rU7iC",
  "plan": "pl_vGTGxa_Kf521Sdv",
  "created_at": 1373461486,
  "last_invoice": {
    "id": "in_MVt4vwsp7VvOTqa",
    "date": 1373461485,
    "client": "cli_buoBpPrw6rU7iC",
    "subscription": "sub_i3CoQEnqX5IKve",
    "amount": "7.00",
    "currency": "PLN",
    "paid": true,
    "issuer_response_code": "00",
    "attempts": 1,
    "next_payment_attempt": "null",
    "created_at": 1373461485
  }
}

Zatrzymanie istniejącej subskrypcji następuje w wyniku wysłania żądania typu DELETE na adres https://sandbox.espago.com/api/subscriptions/(:id)
(:id) - identyfikator subskrypcji, której dane chcą Państwo usunąć

curl -i https://sandbox.espago.com/api/subscriptions/ID \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
-X DELETE 
require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
subscription_id = 'sub_8a1FXEDVNMINvTOS'
response = client.send "api/subscriptions/#{subscription_id}", method: :delete

puts response.code
puts response.body
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/subscriptions/ID');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');

curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close ($ch);
W odpowiedzi wysyłamy - status: 204 No Content

Pobieranie listy aktywnych subskrypcji następuje w wyniku wysłania żądania metodą GET na adres: https://sandbox.espago.com/api/subscriptions. Możliwe jest wysłanie parametrów dodatkowych, lecz nie są one obowiązkowe.

Parametr Opis Wartość domyślna
page Numer strony 1 (pierwsza strona)
per Liczba subskrypcji na każdej stronie 25 (25 subskrypcji)
curl -i https://sandbox.espago.com/api/subscriptions \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
-d "page=2" \
-d "per=5"
require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
response = client.send(
  'api/subscriptions',
  method: :get,
  body: {
    page: 1,
    per: 5
  }
)

puts response.code
puts response.body
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/subscriptions');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "page=2&per=5");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close ($ch);

{
  "count": 1,
  "subscriptions": [
    {
      "id": "sub_i3CoQEnqX5IKve",
      "state": "active",
      "client": "cli_buoBpPrw6rU7iC",
      "plan": "pl_vGTGxa_Kf521Sdv",
      "created_at": 1373461486,
      "last_invoice": {
        "id": "in_9d7xIbhzLMkxTFm",
        "date": 1373463196,
        "client": "cli_buoBpPrw6rU7iC",
        "subscription": "sub_i3CoQEnqX5IKve",
        "amount": "7.00",
        "currency": "PLN",
        "paid": true,
        "issuer_response_code": "00",
        "attempts": 1,
        "next_payment_attempt": "null",
        "created_at": 1373463196,
      }
    }
  ]
}

Pobieranie listy aktywnych subskrypcji przypisanych do danego klienta następuje w wyniku wysłania żądania metodą GET na adres: https://sandbox.espago.com/api/clients/(:client_id)/subscriptions
(:client_id) - identyfikator klienta, którego dane subskrypcji chcą Państwo pobrać. Możliwe jest wysłanie parametrów dodatkowych, lecz nie są one obowiązkowe.

Parametr Opis Wartość domyślna
page Numer strony 1 (pierwsza strona)
per Liczba subskrypcji na każdej stronie 25 (25 subskrypcji)
curl -i https://sandbox.espago.com/api/clients/CLIENT_ID/subscriptions \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
-d "page=2" \
-d "per=5"
require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
client_id = 'cli_772YYE_98HM1DmAD'
response = client.send(
  "api/clients/#{client_id}/subscriptions",
  method: :get,
  body: {
    page: 1,
    per: 5
  }
)

puts response.code
puts response.body
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/clients/CLIENT_ID/subscriptions');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "page=2&per=5");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close ($ch);

{
  "count": 2,
  "subscriptions": [
    {
      "id": "sub_WbAUbaC_7KB79V",
      "state": "active",
      "client": "cli_buoBpPrw6rU7iC",
      "plan": "pl_vGTGxa_Kf521Sdv",
      "created_at": 1373463500,
      "last_invoice": {
        "id": "in_I3iEPUZFxUsLUR-",
        "date": 1373463498,
        "client": "cli_buoBpPrw6rU7iC",
        "subscription": "sub_WbAUbaC_7KB79V",
        "amount": "7.00",
        "currency": "PLN",
        "paid": true,
        "issuer_response_code": "00",
        "attempts": 1,
        "next_payment_attempt": "null",
        "created_at": 1373463498
      }
    },
    {
      "id": "sub_FMw5DlPzK0dW9V",
      "state": "active",
      "client": "cli_buoBpPrw6rU7iC",
      "plan": "pl_vGTGxa_Kf521Sdv",
      "created_at": 1373463506,
      "last_invoice": {
        "id": "in_WtlQMDFdUDpIdSq",
        "date": 1373463504,
        "client": "cli_buoBpPrw6rU7iC",
        "subscription": "sub_FMw5DlPzK0dW9V",
        "amount": "7.00",
        "currency": "PLN",
        "paid": true,
        "issuer_response_code": "00",
        "attempts": 1,
        "next_payment_attempt": "null",
        "created_at": 1373463504,
      }
    }
  ]
}

link Faktury

Faktura to obiekt systemowy związany z płatnością cykliczną i odpowiedzialny za przechowywanie stanu transakcji, liczbę dotychczasowych prób obciążeń oraz ewentualną datę kolejnej płatności na wypadek niepowodzenia ostatniej.

Wyświetlenie danych faktury danego klienta jest możliwe po wysłaniu żądania typu GET na adres: https://sandbox.espago.com/api/clients/(:client_id)/invoices
(:client_id) - identyfikator klienta

curl -i https://sandbox.espago.com/api/clients/CLIENT_ID/invoices/ \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD
require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
client_id = 'cli_772YYE_98HM1DmAD'
response = client.send "api/clients/#{client_id}/invoices", method: :get

puts response.code
puts response.body
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/clients/CLIENT_ID/invoices/');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close ($ch);

{
  "count":1,
  "invoices":[
    {
      "id":"in_7728vjvj-BdSK0B64",
      "date":1559903458,
      "client":"cli_772YYE_98HM1DmAD",
      "subscription":"sub_772pHbFAL2vs-z8g",
      "amount":"119.00",
      "currency":"pln",
      "paid":true,
      "issuer_response_code":"00",
      "attempts":1,
      "next_payment_attempt":null,
      "created_at":1559903458,
      "last_payment":"pay_772Nkgo8MS-25osp"
    }
  ]
}

Znaczenie pól w odpowiedzi:

Nazwa pola Znaczenie Dostępne wartości
Date Informacja o zleconej dacie obciążenia Data w formacie Unix time
Paid Informacja, czy faktura została opłacona True lub false
Attempts Liczba wykonanych prób zapłaty Wartość liczbowa
Next payment attempt Data wykonania kolejnej próby w przypadku negatywnej ostatniej odpowiedzi Data w formacie Unix time lub null w przypadku braku konieczności ponawiania

Istnieje możliwość wykonania dodatkowych prób pobrania płatności (poza limitem przewidzianym przez konfigurację). W tym celu należy wysłać request typu POST na adres: https://sandbox.espago.com/api/invoices/(:invoice_id)/pay
(:invoice_id) - identyfikator faktury

UWAGA
Wykonanie tego polecenia będzie skutkować zmniejszeniem liczby dodatkowych prób obciążeń wykonywanych automatycznie przez system!

curl -i https://sandbox.espago.com/api/invoices/(:invoice_id)/pay \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD
require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
invoice_id = 'in_7728vjvj-BdSK0B64'
response = client.send "api/invoices/#{invoice_id}/pay", method: :post

puts response.code
puts response.body
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/invoices/(:invoice_id)/pay');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close ($ch);
{
  "id": "in_MUL7PeIUTDwOHx8",
  "date": 1371805245,
  "client": "cli_N7hldWZqSoBLva",
  "subscription": "sub_occMPm6-_284b3",
  "amount": "7.00",
  "currency": "PLN",
  "paid": true,
  "attempts": 2,
  "next_payment_attempt": "null",
  "created_at": 1371805245,
    "last_payment":"pay_772Nkgo8MS-25osp"
}

Dla opłaconej wcześniej faktury wysyłana jest odpowiedź z kodem błędu 422 "Unprocessable Entity.

Wyświetlenie danych faktury jest możliwe po wysłaniu żądania typu GET na adres: https://sandbox.espago.com/api/invoices/(:id)
(:id) - identyfikator faktury

curl -i https://sandbox.espago.com/api/invoices/ID_FAKTURY \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD
require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
invoice_id = 'in_7728vjvj-BdSK0B64'
response = client.send "api/invoices/#{invoice_id}", method: :get

puts response.code
puts response.body
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/invoices/ID_FAKTURY');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close ($ch);
{
  "id":"in_7728vjvj-BdSK0B64",
  "date":1559903458,
  "client":"cli_772YYE_98HM1DmAD",
  "subscription":"sub_772pHbFAL2vs-z8g",
  "amount":"119.00",
  "currency":"pln",
  "paid":true,
  "issuer_response_code":"00",
  "attempts":1,
  "next_payment_attempt":null,
  "created_at":1559903458,
  "last_payment":"pay_772Nkgo8MS-25osp"
}

link Pozycje faktury

Pozycje faktury są informacją na temat jednej płatności dla danego cyklu subskrypcji - zawierają informacje na temat próby opłacenia danej faktury. Jeżeli się ona nie powiedzie powstanie kolejna pozycja faktury i próba ponownego obciążenia wg danej faktury oraz okresu ustawionego w konfiguracji powtarzania nieudanych obciążeń subskrypcji. Więcej o konfiguracji subskrypcji espago można znaleźć w dziale Subskrypcje Espago - konfiguracja.

Tworzenie nowej pozycji następuje w wyniku wysłania żądania typu POST na adres https://sandbox.espago.com/api/invoice_items

Dostępne parametry

Parametr Opis Wartość pola Obligatoryjność
amount Kwota transakcji Liczba dziesiętna, np. 123,45 Wymagany
currency Waluta Symbol waluty zgodny z posiadanym MID Wymagany
date Data obciążenia Data obciążenia w przyszłości w formacie unix time Wymagany
client ID klienta Identyfikator umożliwiający przypisanie transakcji do utworzonego klienta Wymagany
description Opis transakcji Powinien składać się z co najmniej 5 znaków. Opcjonalny
curl -i https://sandbox.espago.com/api/invoice_items \
-H 'Accept: application/vnd.espago.v3+json' \
-u app_id:password \
-d "currency=currency" \
-d "date=unix_time" \
-d "amount=100" \
-d "client=client_id" \
-d "description=Opis transakcji"
require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
response = client.send(
  "api/invoice_items",
  method: :post,
  body: {
    currency: 'pln',
    date: 1764363614,
    amount: 100,
    client: 'cli_772YYE_98HM1DmAD',
    description: 'Opis transakcji'
  }
)

puts response.code
puts response.body
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/invoice_items');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "currency=currency&date=unix_time&amount=100&client=client_id&description=Opis transakcji");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'app_id' . ':' . 'password');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
{
  "id": "ii_1sbC2i-UHMWJXZH",
  "client": "cli_xNKNXh-_kWu6Qi",
  "description": "Opis transakcji",
  "amount": "100.00",
  "currency": "PLN",
  "created_at": 1381755981
}

Pobranie informacji o pozycjach wchodzących w skład faktury jest możliwe po wysłaniu żądania typu GET na adres: https://sandbox.espago.com/api/invoices/(:invoice_id)/line_items
(:invoice_id) - identyfikator faktury

curl -i https://sandbox.espago.com/api/invoices/(:invoice_id)/line_items \
-H 'Accept: application/vnd.espago.v3+json' \
-u app_id:password
require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
invoice_id = 'in_7728vjvj-BdSK0B64'
response = client.send "api/invoices/#{invoice_id}/line_items", method: :get

puts response.code
puts response.body
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/invoices/:invoice_id/line_items');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

curl_setopt($ch, CURLOPT_USERPWD, 'app_id' . ':' . 'password');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);

{
  "count": 1,
  "invoice_items": [
    {
    "id": "ii_1KZ0VBahlukLI2X",
    "client": "cli_OU7k00vEMGi53C",
    "description": "Pozycja 1",
    "amount": "7.00",
    "currency": "PLN",
    "created_at": 1371631057
    }
  ]
}

Usunięcie istniejącej pozycji następuje w wyniku wysłania żądania typu DELETE na adres https://sandbox.espago.com/api/invoice_items/(:id)
(:id) - identyfikator pozycji

curl -i https://sandbox.espago.com/api/invoice_items/(:id) \
-X DELETE \
-H 'Accept: application/vnd.espago.v3+json' \
-u app_id:password
require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
invoice_id = 'in_7728vjvj-BdSK0B63'
response = client.send "api/invoices/#{invoice_id}", method: :delete

puts response.code
puts response.body
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/invoice_items/(:id)');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');

curl_setopt($ch, CURLOPT_USERPWD, 'app_id' . ':' . 'password');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
Status uzyskany w odpowiedzi to 204 "No content"

Informacje zwrotne (back request) receipt

link Konfiguracja

Bramka Espago wysyła asynchronicznie do serwisu Sprzedawcy 4 rodzaje informacji zwrotnych, oznaczonych parametrem subject wskazującym na rodzaj obiektu, którego dotyczy zdarzenie:

Wartość parametru subject Obiekt Zdarzenie Wymagane
payment płatność informacja o statusie płatności - po wykonaniu dowolnej płatności w APIv3.0 (przy płatności z 3D-Secure, żądanie jest wysyłany dopiero po weryfikacji i uzyskaniu odpowiedzi z banku) Tak
invoice faktura informacja o statusie faktury - po podjęciu próby płatności w ramach subskrypcji Tak, jeśli używane są Subskrypcje Espago
subscription subskrypcja informacja o statusie subskrypcji - gdy status subskrypcji się zmieni, np. gdy zostaje zdezaktywowana Tak, jeśli używane są Subskrypcje Espago
card karta informacja o utworzonym tokenie karty - po zapisaniu danych karty w Espago i utworzeniu tokenu karty - domyśnie opcja wyłączona, w razie potrzeby używania tego typu żądań należy skontaktować się z pomocą techniczną Espago. Nie

Informacje o zmianie statusu transakcji są wysyłane asynchronicznie na zdefiniowany przez Sprzedawcę adres żądania zwrotnego. Wysyłane żądania powinny wykorzystywać protokół HTTPS (port 443), ale możliwa też jest komunikacja na port HTTP (port 80). W środowisku testowym Sandbox dodatkowo serwer ma możliwość wysyłania informacji zwrotnych na porty 8002 i 8003.

UWAGA
W przypadku braku odpowiedzi “HTTP 200” z serwera Sprzedawcy, wysyłanie informacji jest ponawiane przez serwer Espago przez kolajne 24h - z rosnącym interwałem.



W panelu Sprzedawcy należy wykonać następujące czynności:
1. Przejść do zakładki Twoje strony:
2. Przejść do okna edycji serwisu klikając przycisk Edytuj.
3. Uzupełnić pole “URL żądania zwrotnego (application/json v. 3.0.)” - na ten adres wysyłane będą informacje.
4. Uzupełnić pola “Login BasicAuth (dla URL żądania zwrotnego)” oraz “Hasło BasicAuth (dla URL żądania zwrotnego)”. Za ich pomocą autoryzowanie będą żądania wysyłane z bramki Espago.

UWAGA
Walidacja loginu i hasła dla żądań zwrotnych nie jest wymagana, lecz jej stosowanie jest silnie zalecane ze względów bezpieczeństwa.

Za pomocą poniższego zapytania PUT można edytować ustawienia dotyczące żądań zwrotnych:

  • url, gdzie żądania ma zostać wysłane
  • login i hasło, którym chcemy uwierzytelniać żądanie w swoim systemie
curl -i https://sandbox.espago.com/api/back_request_settings \
-X PUT \
-H 'Accept: application/vnd.espago.v3+json' \
-u your_app_id:your_api_app_password \
-d "url=https://example.espago.com/" \
-d "login=MyLogin" \
-d "password=MyPassword"
kod HTTP 200
{}
kod HTTP 422
{
   "url": ["is invalid or not responding"]
}

link Informacja zwrotna przy płatności

Każda płatność w chwili uzyskania przez Espago odpowiedzi o autoryzacji, jej odmowie lub wystąpienia błędu przy próbie płatności, powoduje wysłanie informacji zwrotnej z bramki Espago do serwisu Sprzedawcy.

Jeśli mechanizm 3-D Secure spowoduje przekierowanie klienta do banku, informacje zwrotne są przesyłane po uwierzytelnieniu klienta i są one głównym źródłem informacji dla Sprzedawcy o statusie płatności. Jeśli autoryzacja nie zostanie dokonana w przeciągu 1,5 godziny od jej zainicjowania (klient porzuci płatność na etapie weryfikacji 3-D Secure), status płatności zmieni się na “resigned” i wtedy zostanie przesłana informacja zwrotna.

Przykładowa informacja zwrotna (back request):

{
  "subject": "payment",
  "id": "pay_772sMqGEogv63CSk",
  "description": "order_263",
  "channel": "elavon",
  "amount": "56.94",
  "currency": "PLN",
  "state": "executed",
  "client": "cli_7725o4SHuhgnHAVe",
  "created_at": 1560160387,
  "card": {
    "company": "VI",
    "last4": "4242",
    "year": 2030,
    "month": 1,
    "first_name": "Jan",
    "last_name": "Kowalski",
    "authorized": null,
    "created_at": 1560160386
  },
  "issuer_response_code": "00",
  "reversable": true,
  "transaction_id": "tr_772b9YYzb"
}
Parametr Uwagi Opis
subject Typ informacji
id ID płatności. Umożliwia m.in. późniejsze odszukanie płatności, sprawdzenie statusu, zwrot. Ma postać pay_xxxxxxxxxxxxxxxx i długość 18 lub 20 znaków.
description Opis płatności przesłany w zapytaniu na /api/charges.
channel Kanał płatności.
amount Kwota
currency Waluta
state Status płatności. Szczegółowo opisane w części “Możliwe stany płatności”
client ID klienta przy pomocy którego dokonano płatności. Dla płatności z paramtrem cof=storing jest to profil, który można wykorzystać do dalszych płatności wielokrotnych lub subkrypcji.
created_at Data utworzenia płatności, czas w systemie unix.
card obiekt Parametry dotyczące użytej karty.
issuer_response_code Kod odpowiedzi z banku.
tds_status_reason Kod zawierający przyczynę stanu autoryzacji 3-D Secure 2. Opisy tych kodów dostępne są w sekcji Do pobrania jako Kody statusu 3-D Secure.
transaction_id ID transakcji. Przydatne do wyszukiwania płatności w panelu udostępnianym przez Elavon, gdyż tylko to ID jest widoczne w raportach Elavon (nie ma tam ID klienta ani ID płatności). Transakcja jest to “operacja”. Domyślnie jedna płatność ma jedną transakcję (tj. wykonanie płatności), po zwróceniu części lub całości płatności zostaje przypisane tu ID transakcji zwracającej płatność.
redirect_url opcjonalny Adres URL do przekierowania klienta, jeśli karta klienta obsługuje 3-D Secure.
reversable opcjonalny Parametr reversable=true informuje o możliwości wycofania płatności przed rozliczeniem. Po rozliczeniu parametr przyjmuje wartość false i przestaje być widoczny we właściwościach płatności.
liability_shift Dostępny jedynie dla kanału worldline_cc Boolean. Parametr liability_shift=true informuje o przeniesieniu odpowiedzialności na instytucje wydającą kartę, w przypadku reklamacji związenej z oszustwem.
trace_id Dostępny jedynie dla kanału worldline_cc ID transakcji SCA, stanowiące dowód na jej przeprowadzenie. ID to jest przesyłane do banku, jako część danych autoryzacyjnych dla płatności typu MIT (płatności bez udziału posiadacza karty).

link Informacja zwrotna przy płatnościach cyklicznych

Przykład żądania zwrotnego z informacją o udanym obciążeniu (paid: true).

{
  "subject": "invoice",
  "id": "in_hS-KiS3N6YCzOhG",
  "date": 1371631155,
  "client": "cli_OU7k00vEMGi53C",
  "subscription": "sub_QyJzN4KdzNzvmZ",
  "amount": "7.00",
  "currency": "PLN",
  "paid": true,
  "issuer_response_code": "00",
  "attempts": 1,
  "next_payment_attempt": "null",
  "created_at": 1371500155,
  "last_payment": "pay_iq1yCYmgieM_ct"
}

W przypadku, gdy status subskrypcji się zmieni, ponieważ w Panelu Sprzedawcy została włączona opcja zatrzymania subskrypcji po nieudanych próbach - nastąpi żądanie zwrotne informujące o tym zdarzeniu:

{
  "subject": "subscription",
  "id": "sub_WQO0vEpk0-SrqM",
  "state": "inactive",
  "client": "cli_MNXfMFpu8_j3ax",
  "plan": "pl_dxT6xBEo__fbb7y",
  "created_at": 1457559667,
  "last_invoice": {
    "id": "in_CjUBitNf9UpWdoQ",
    "date": 1460461811,
    "client": "cli_MNXfMFpu8_j3ax",
    "subscription": "sub_WQO0vEpk0-SrqM",
    "amount": "55.00",
    "currency": "pln",
    "paid": false,
    "issuer_response_code": "00",
    "attempts": 1,
    "next_payment_attempt": "null",
    "created_at": 1460461811,
    "last_payment": "pay_iq1yCYmgieM_ct"
  }
}

link Informacja zwrotna przy tworzeniu tokenów

Istnieje możliwość włączenia wysyłania informacji zwrotnych z danymi tokenu z bramki Espago w momencie tworzenia tokenu dla karty. Dzięki temu, informacja o utworzonym dla karty tokenie, zostanie wysłana nie tylko w ramach odpowiedzi HTTP do przeglądarki klienta/urządzenia mobilnego klienta, ale również do serwera sprzedawcy..
W celu włączenia tej funkcji konieczny jest kontakt z Działem Wsparcia Technicznego (kontakt mailowy), Ta funkcja jest domyślnie nieaktywna.


Ważne
Aby informacja zwortna została wysłana, przy tworzeniu tokenu (żądanie POST na adres /api/tokens) konieczne jest dodanie parametru card[description] o długości 5-60 znaków. Musi być to unikalny identyfikator nadany przez system Sprzedawcę, który pozwoli w jego systemie przypisać utworzony token do odpowiedniego Klienta lub konkretnej, rozpoczętej płatności.

Przebieg tworzenia tokenu z włączonymi informacjami zwrotnymi:

  1. Z przeglądarki klienta (przy użyciu Espago JS) lub z aplikacji mobilnej wysyłane jest żądanie utworzenia tokenu. To żądanie zawiera m.in. dane karty oraz pole “card[description]”.
  2. Urządzenie klienta otrzymuje odpowiedź z bramki Espago potwierdzającą utworzenie tokenu. Odpowiedź zawiera m.in. ID tokenu, które w normalnym układzie urządzenie Klient przesyła do serwera Sprzedawcy.
  3. Bramka Espago wysyła asynchronicznie informację zwrotną do serwera Sprzedawcy, zawierającą m.in. ID tokenu oraz w części dotyczącym karty pole “description”, umożliwiające sprzedawcy powiązanie tokenu z klientem.
  4. Przy użyciu tokenu odebranego z Espago (lub oderanego od Klienta) serwis Sprzedawcy może dokonać płatności.
{
  "subject": "card",
  "id": "cc_7762MqOeLF1iVw7fD",
  "created_at": 1571170086,
  "used": false,
  "card": {
    "company": "VI",
    "last4": "4242",
    "year": 2020,
    "month": 2,
    "first_name": "Jan",
    "last_name": "Kowalski",
    "authorized": null,
    "description": "Client_1234567890",
    "created_at": 1571170086
  },
  "description": "Client_1234567890"
}

Zwroty undo

link Zwrot istniejącej płatności po rozliczeniu

W poniższym rozdziale opisane zostały zwroty istniejącej płatności po rozliczeniu. Jeżeli chcesz się dowiedzieć o wycofywaniu istniejącej płatności przed rozliczeniem przejdź tutaj.

Zwrot pieniędzy za transakcję, która została już rozliczona następuje w wyniku wysłania żądania typu POST na adres https://sandbox.espago.com/api/charges/(:id)/refund gdzie (:id) jest to identyfikator płatności, która ma zostać wycofana i zwrócona

Zwrócić można całą kwotę z transakcji lub część. Nie ma możliwości wycofania dokonanego zwrotu.
Płatność można zwrócić w czasie maksymalnie 12 miesięcy od jej wykonania.

W przypadku zwrotu części płatności możliwe jest wielokrotne zwracanie płatności do momentu zwrócenia całej kwoty pierwotnej płatności. Kwotę już zwróconą podaje parametr refunded_amount. Aby zwrócić całość płatności już częściowo zwróconej można zwrócić wyliczoną wartość (do zwrócenia= amount - refunded_amount) lub wywołać zapytanie bez parametru “amount”.

Dostępne parametry HTTP

Parametr Opis Obligatoryjność Wartość domyślna
amount kwota, która ma zostać zwrócona Opcjonalny Kwota ta musi być mniejsza bądź równa kwocie transakcji. Jeżeli nie zostanie określona w wysyłanym żądaniu, zwrócona zostanie cała kwota transakcji.

Istotne elementy odpowiedzi

Parametr Opis Uwagi
id id płatności Wartość niezmieniona, ID płatności której dotyczy zwrot.
state status płatności Po poprawnie wykonanym zwrocie (częściowym lub całkowitym) przyjmuje wartość “refunded”
refunded_amount kwota zwrócona Przy zwrocie całkowitym refunded_amount=amount. Przy częściowych zwrotach płatności, refunded_amount jest sumą dokonanych zwrotów.
transaction_id ID transakcji zwracającej Jest to ID transakcji (operacji) zwracającej płatność. Różni się od ID transakcji dokonującej płatność.

Przykładowe zapytanie

curl -i https://sandbox.espago.com/api/charges/(:id)/refund \
 -X POST \
 -H 'Accept: application/vnd.espago.v3+json' \
 -u app_id:password \
 -d "amount=n"
require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
payment_id = 'pay_315gfsdf234'
response = client.send(
  "api/charges/#{payment_id}/refund",
  method: :post,
  body: {
    amount: 100
  }
)

puts response.code
puts response.body
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/charges/(:id)/refund');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "amount=n");
curl_setopt($ch, CURLOPT_USERPWD, 'app_id' . ':' . 'password');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
{
  "id": "pay_COy6zH9fLj1d7K",
  "description": "Opis transakcji",
  "channel": "elavon",
  "amount": "49.99",
  "refunded_amount": "15.00",
  "currency": "pln",
  "state": "refunded",
  "client": "cli_xNKNXh-_kWu6Qi",
  "created_at": 1381823580,
  "card": {
    "company": "VI",
    "last4": "4242",
    "year": 2017,
    "month": 2,
    "first_name": "Jan",
    "last_name": "Kowalski",
    "authorized": true,
    "created_at": 1381755890
  },
  "issuer_response_code": "00",
  "transaction_id": "tn_AKZ71ysMF"
}

link Zwrot bez powołania się na płatność

W poniższym rozdziale opisane zostały zwroty bez wcześniejszej płatności ecommerce. Jeżeli chcesz się dowiedzieć o wycofywaniu istniejącej płatności przejdź tutaj.

Zwrot pieniędzy bez wcześniejszej transakcji ecommerce następuje w wyniku wysłania żądania typu POST na adres https://sandbox.espago.com/api/refunds.

Preferowanym sposobem zwrotu jest zwrot z powołaniem się na wcześniejszą transakcję. Zwroty bez transakcji ecommerce mogą się sprawdzić w sytuacji gdy oryginalna transakcja wykonana była na fizycznym terminalu płatniczym i bramka Espago nie ma jej danych.

Dostępne parametry HTTP

Parametr Opis Obligatoryjność
amount Kwota, która ma zostać zwrócona Wymagany
currency Trzyliterowy kod waluty w standardzie ISO 4217. Wskazana waluta musi odpowiadać tej, na umowie z agentem rozliczeniowym dla danego Serwisu. Wymagany
description Opis zwrotu musi składać się z ciągu o długości od 5 do 255 znaków. Wymagany
channel Kanał, którym ma być procesowany ten zwrot. Wspierane elavon_cc, elavon_eisop Wymagany
custom_order_id Identyfikator przekazywany w pliku rozliczeniowym Opcjonalny
eisop_token Obiekt eisop_token zawierający dane tokenu EISOP za którego pomocą ma zostać wykonany zwrot Warunkowy
card ID istniejącego w Espago tokenu karty, na który zostanie wykonany zwrot. Obowiązkowy jeśli nie podano client ani eisop_token Warunkowy
client ID istniejącego w Espago Profilu Klienta z zapisaną kartą. Obowiązkowy jeśli nie podano card ani eisop_token Warunkowy

Obiekt eisop_token

Parametr Opis Obligatoryjność
token Numer tokenu EISOP Wymagany
card_year Rok końca ważności karty klienta w formacie liczbowym YYYY Wymagany
card_month Miesiąc końca ważności karty klienta w formacie liczbowym MM Wymagany

Istotne elementy odpowiedzi

Parametr Opis Uwagi
id Identyfikator zwrotu
state Status zwrotu Po poprawnie wykonanym zwrocie przyjmuje wartość "refunded" lub "refund_executed". Inne wartości to np. "refund_rejected" i "failed"
refunded_amount Kwota zwrócona.
issuer_response_code Kod odrzucenia Kod wskazujący na powód odrzucenia próby zwrotu

Przykładowe zapytanie

curl -i https://sandbox.espago.com/api/refunds \
 -X POST \
 -H 'Content-Type: application/json' \
 -H 'Accept: application/vnd.espago.v3+json' \
 -u  ms_771eUTliRiZ:SeCreT_P@ssw0rD \
 -d '{ "amount": 10, "currency": "PLN", "channel": "elavon_eisop", "description": "docs test refund",  "eisop_token": { "token": "BEYOVBGIVPBX0006", "card_year": "2025", "card_month": "12" } }'
require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
payment_id = 'pay_315gfsdf234'
response = client.send(
  "api/charges/#{payment_id}/refund",
  method: :post,
  body: {
    amount: 10,
        currency: "PLN",
        description: "docs test refund",
        eisop_token: {
          token:  "BEYOVBGIVPBX0006",
            card_year: "2025", 
        card_month: "12"
      }
  }
)

puts response.code
puts response.body
{
  "id": "pay_COy6zH9fLj1d7K",
  "channel": "elavon_eisop",
  "refunded_amount": "10.0",
  "currency": "GBP",
  "state": "refunded",
  "created_at": 1381823580,
  "eisop_token": {
    "token": "xxx",
    "token_type": "xxx",
    "last4": "xxxx",
    "year": "YYYY",
    "month": "MM",
    "company": "CC"
  },
  "issuer_response_code": "XX",
  "transaction_id": "xxx"
}

Profil klienta accessibility_new

link Obiekt klienta

Profil klienta w Espago służy do przechowywania danych klienta, ze szczególnym uwzględnieniem danych karty. Profil klienta, który posiada kartę płatniczą zapisaną przy użyciu silnego uwierzytelnienia (SCA) można obciążać wiele razy korzystając z Płatności wielokrotnych lub Subskrypcji Espago.

Możliwe jest utworzenie profilu klienta bez danych karty (tylko z opisem, e-mailem) w celu późniejszego uzupełnienia danych karty.

link Atrybuty profilu klienta i karty

Profil klienta jest obiektem posiadającym zestaw parametrów. Są one zwracane zaraz po utworzeniu klienta, a także dostępne później przy odpytaniu o klienta lub jego płatnosci.

Opis i możliwe wartości parametrów karty w profilu klienta:

Parametr Wartość Opis
company VI, MC, MD Informacja o wystawcy karty: VI - Visa, MC - MasterCard, MD - Maestro, AX - American Express, DC - Diners Club, JC - JCB. UWAGA: najczęściej umowa z Elavon obejmuje tylko karty Visa i MasterCard, dlatego w większości przypadków wystarczające jest rozróżnianie wartości: VI, MC, MD.
authorized null, true, false Zwraca informację o ostatniej autoryzacji karty na żądanie, przyjmuje wartości logiczne.
null - autoryzacja nie była przeprowadzana
true - autoryzacja karty przebiegła pomyślnie i jest ona aktywna
false - autoryzacja karty przebiegła negatywnie
authorized_cvv_cvc null, true, false Parametr dostępny przy wykorzystaniu funkcji podwójnej autoryzacji. Zwraca informację o pierwszej autoryzacji karty, gdy kod CVV/CVC był użyty. Przyjmuje wartości logiczne takie jak parametr “authorized”.
issuer_response_code Kod odrzucenia Jeśli authorized=false, to ten parametr będzie zawierał kod odrzucenia przez bank (issuer_response_code)
created_at (numer) Czas w formacie uniksowym
sca_payment obiekt tablica z informacjami o transakcji inicjującej recurring (czyli pierwsza lub najnowsza płatnosć z cof=storing i 3-D Secure przy użyciu tego profilu klienta). Informuje o płatności, której ID będzie przesyłane do Banku przy płatnościach cyklicznych. Przykład: "sca_payment": { "id": "pay_aaaaaaaaaaaa", "amount": "19.00", "updated_at": 1605775020, "client": "cli_xxxxxxxxxxxxxxx" }

link Tworzenie nowego profilu

Profil klienta utworzony w Espago tą metodą (bez płatności z silnym uwierzytelnieniem, oznaczonej parametrem cof=storing) służy zapisaniu danych karty w Espago. Można go wykorzystać do płatności inicjowanych przez klienta (CIT). Dzięku temu, klient nie będzie musiał na nowo wprowadzać danych karty dokonując płatności. Należy jednak pamiętać, że każda inicjowana przez klienta płatność będzie uwierzytelniana w banku - może wystąpić konieczność zatwierdzenia płatności przez posiadacza karty (3D-Secure).


Wykorzystanie profilu utworzonego osobnym zapytaniem do płatności inicjowanych przez sprzedawcę (MIT)
Aby wykorzystać profil klienta do płatności inicjowanych przez sprzedawcę (np.: subskrypcje lub wyrównanie salda), należy dokonać płatności z udziałem posiadacza karty (SCA) z parametrem cof=storing. To spowoduje, że kolejne płatności będą mogły być już inicjowane przez sprzedawcę (MIT) przy zastosowaniu właściwych wartości parametru cof.



Profil klienta dla płatności inicjowanych przez sprzedawcę
Jeśli profil klienta ma być wykorzystywany do płatności inicjowanych przez sprzedawcę (MIT), sugerujemy pominięcie tworzenia profilu osobnym zapytaniem i skorzystanie ze scenariusza płatności wielokrotnych.


Utworzenie nowego klienta następuje w wyniku wysłania żądania typu POST na adres https://sandbox.espago.com/api/clients/

Dostępne parametry HTTP

Parametr Opis Komentarze Obligatoryjność
description Krótki opis klienta Powinno składać się z co najmniej 5 znaków. Pole opcjonalne
email E-mail klienta Uzupełnienie adresu klienta umożliwi włączenie automatycznych powiadomień z bramki Espago o zmianie statusu płatności. Pole opcjonalne.
Po wypełnieniu sprawdzamy format adresu mailowego.
card Parametr przekazujący ID tokenu do karty W tym parametrze należy podać ID wcześniej utworzonego tokenu do karty. Opcjonalny
curl -i https://sandbox.espago.com/api/clients \
-H "Accept: application/vnd.espago.v3+json" \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
-d "description=Jan Kowalski" \
-d "card=token_id"
require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
response = client.send(
  "api/clients",
  method: :post,
  body: {
    description: 'Jan Kowalski',
    card: 'token_id'
  }
)

puts response.code
puts response.body
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/clients');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "description=Jan Kowalski&card=token_id");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
{
  "email": "jan@kowalski.com",
  "id": "cli_Yzij0t46pV88oR",
  "created_at": 1381825758,
  "description": "Jan Kowalski",
  "card": {
    "company": "VI",
    "last4": "4242",
    "year": 2017,
    "month": 2,
    "first_name": "Jan",
    "last_name": "Kowalski",
    "authorized": true,
    "created_at": 1381825758,
  },
  "deleted": false
}


Zamiast podawać token karty można podać bezpośrednio jej dane, lecz ze względów bezpieczeństwa przekazywanie ich przy użyciu tokenów jest preferowanym rozwiązaniem. Przesyłanie kompletu danych w zapytaniu może być wykorzystane tylko do testów oraz w specyficznych zastosowaniach w środowisku produkcyjnym (prosimy o kontakt z Espago).

Dane karty można podać wg następującego schematu (wszystkie pola są obowiązkowe):

Parametr Opis Komentarze
card[first_name] Imię właściciela karty
card[last_name] Nazwisko właściciela karty
card[number] Numer karty klienta
card[verification_value] Kod CVV
card[year] Rok końca ważności karty klienta Zapisywane w formacie liczbowym YYYY
card[month] Miesiąc końca ważności karty klienta Zapisywane w formacie liczbowym MM; możliwe opcje 01-12

link Tworzenie tokenu do karty

Aby utworzyć token do karty klienta należy wysłać żądanie typu POST na podany adres https://sandbox.espago.com/api/tokens

curl -i https://sandbox.espago.com/api/tokens \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
-d "card[first_name]=Jan" \
-d "card[last_name]=Kowalski" \
-d "card[number]=4242424242424242" \
-d "card[verification_value]=123" \
-d "card[year]=2018" \
-d "card[month]=02"
require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
response = client.send(
  "api/tokens",
  method: :post,
  body: {
    card: {
      first_name: "Jan",
      last_name: "Kowalski",
      month: "02",
      number: "4242424242424242",
      verification_value: "123",
      year: "2030"
    }
  }
)

puts response.code
puts response.body
// Generated by curl-to-PHP: http://incarnate.github.io/curl-to-php/
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/tokens');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "card[first_name]=Jan&card[last_name]=Kowalski&card[number]=4242424242424242&card[verification_value]=123&card[year]=2018&card[month]=02");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
{
  "id": "cc_J_wDRKH6jmIEb_8",
  "created_at": 1550871516,
  "used": false,
  "card": {
    "company": "VI",
    "last4": "4242",
    "year": 2018,
    "month": 2,
    "first_name": "John",
    "last_name": "Kowalsky",
    "authorized": "null",
    "created_at": 1550871586
  }
}

Parametr used przyjmuje wartości logiczne true lub false. Jeżeli wartość wynosi false, oznacza to, że token nie został jeszcze użyty.

link Sprawdzanie informacji o tokenie

Sprawdzenie informacji o karcie, która została stokenizowana, pozwala na uzyskanie danych o:

  • kraju wystawcy karty
  • nazwy banku wystawcy karty
  • waluty karty
  • rodzaju karty

Aby korzystać z tej funkcji, wymagany jest kontakt z Espago w celu uruchomienia tej usługi.
W niektórych przypadkach sprawdzanie informacji o karcie może trwać dłużej niż 1s.

Aby wywołać metodę, należy wysłać żądanie typu POST na adres: https://sandbox.espago.com/api/tokens/(:id)/check_type

(:id) - identyfikator tokenu karty, dla której dane mają zostać sprawdzone.

curl -i https://sandbox.espago.com/api/tokens/cc_776Hzu24ArvnooVvq/check_type \
-X POST \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD
require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
token_id = 'cc_8a1IcKzD4NzD7httF'
response = client.send "api/tokens/#{token_id}/check_type", method: :post

puts response.code
puts response.body
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/tokens/cc_776Hzu24ArvnooVvq/check_type');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
{
    "id":"cc_776Hzu24ArvnooVvq",
    "created_at":1570612905,
    "used":false,
    "card":{
        "company":"VI",
        "last4":"4242",
        "year":2026,
        "month":2,
        "first_name":"Jan",
        "last_name":"Kowalski",
        "authorized":null,
        "card_type":"D",
        "country":"HKG",
        "currency":"HKD",
        "bank":"U",
        "created_at":1570612905
    }
}

Parametr Opis Uwagi
card_type Informacja o rodzaju karty C - karta kredytowa
D - karta debetowa
U - brak informacji
country Kraj wystawcy karty 3-literowy kod kraju w standardzie ISO 3166-1 alpha-3
U - brak informacji
currency Waluta karty 3-literowy kod waluty w formacie ISO 4217.
U - brak informacji
bank Nazwa banku Nazwa banku
U - brak informacji

link Modyfikacja profilu

Usunięcie istniejącego klienta następuje w wyniku wysłania żądania typu DELETE na dany adres https://sandbox.espago.com/api/clients/(:id)

(:id) - identyfikator klienta, którego dane chcą Państwo usunąć

curl -i https://sandbox.espago.com/api/clients/CLIENT_ID \
-X DELETE \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD
require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
client_id = 'cli_8a1IcKzD4NzD7httF'
response = client.send "api/clients/#{client_id}", method: :delete

puts response.code
puts response.body
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/clients/CLIENT_ID');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');

curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);

W odpowiedzi wysyłamy Status 204: no content

Aktualizacja danych utworzonego wcześniej klienta następuje w wyniku wysłania żądania typu PUT na adres https://sandbox.espago.com/api/clients/(:id)
gdzie (:id) - identyfikator aktualizowanego klienta (np. /api/clients/cli_xxxxxxxxx).

Parametry, które można modyfikować są takie same jak przy tworzeniu klienta, wszystkie są opcjonalne (konieczne jest podanie przynajmniej jednego modyfikowanego)

  • card=token_id - ID tokenu, jeśli aktualizowana jest karta
  • email [opcjonalnie]
  • description [opcjonalnie]


UWAGA
Podobnie jak przy tworzeniu klienta wymaganym rozwiązaniem przy aktualizacji karty jest użycie ID Tokenu (utworzonego przed wysłaniem żądania aktualizacji klienta). Jeżeli (Sprzedawca posiadajacy certyfikat PCI) aktualizacji ulega którakolwiek z danych dotyczących karty to należy podać wszystkie dane tej karty (nawet jeśli zmianie ulega tylko jedna część).
Po aktualizacji danych karty nie ma możliwości przywrócenia starej karty. Jeśli chcesz umożliwić podanie nowej karty tylko w przypadku gdy będzie działać, i dopiero wtedy usuwać starą kartę to zamiast aktualizacji karty rozważ utworzenie nowego profilu klienta i następnie usunięcie starego.

curl -i https://sandbox.espago.com/api/clients/ID_KLIENTA \
-X PUT \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
-d "description=Jan Kowalski" \
-d "email=client@example.com" \
-d "card[first_name]=Jan" \
-d "card[last_name]=Kowalski" \
-d "card[number]=4242424242424242" \
-d "card[verification_value]=123" \
-d "card[year]=2025" \
-d "card[month]=02"
require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
client_id = 'cli_772YYE_98HM1DmAD'
response = client.send(
  "api/clients/#{client_id}",
  method: :put,
  body: {
    description: 'Jan Kowalski',
    email: 'client@example.com',
    card: {
      first_name: 'Jan',
      last_name: 'Kowalski',
      number: 4242424242424242,
      verification_value: 123,
      year: 2025,
      month: 02
    }
  }
)

puts response.code
puts response.body
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/clients/ID_KLIENTA');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "description=Jan Kowalski&email=client@example.com&card[first_name]=Jan&card[last_name]=Kowalski&card[number]=4242424242424242&card[verification_value]=123&card[year]=2025&card[month]=02");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');

curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
{
  "email":"client@example.com",
  "id":"cli_772q8GcejiQfRl4z",
  "created_at":1560960175,
  "description":"Jan Kowalski",
  "card":{
    "company":"VI",
    "last4":"4242",
    "year":2025,
    "month":2,
    "first_name":"Jan",
    "last_name":"Kowalski",
    "authorized":null,
    "created_at":1561125908
  },
  "deleted":false
}

link Pobieranie danych profilu

Pobranie danych utworzonego wcześniej klienta następuje w wyniku wysłania żądania typu GET na adres https://sandbox.espago.com/api/clients/(:id)

(:id) - identyfikator klienta, którego dane chcą Państwo pobrać

curl -i https://sandbox.espago.com/api/clients/CLIENT_ID \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD
require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
client_id = 'cli_772YYE_98HM1DmAD'
response = client.send "api/clients/#{client_id}", method: :get

puts response.code
puts response.body
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/clients/CLIENT_ID');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);

{
  "email":"client@example.com",
  "id":"cli_772q8GcejiQfRl4z",
  "created_at":1560960175,
  "description":"Jan Kowalski",
  "card":{
    "company":"VI",
    "last4":"4242",
    "year":2022,
    "month":2,
    "first_name":"Jan",
    "last_name":"Kowalski",
    "authorized":true,
    "created_at":1561126879
    },
  "deleted":false",
  "sca_payment": {
    "payment_id": "pay_772bLKUDa1sdfsd",
    "amount": "0.00",
    "channel": "elavon",
    "updated_at": 1561126879,
    "client_id": "cli_772q8GcejiQfRl4z"
    }
}

Wyświetlenie określonej strony z określoną ilością klientów następuje w wyniku wysłania żądania typu GET na adres https://sandbox.espago.com/api/clients?page=1&per=10

Dostępne parametry HTTP

Parametr Opis Obligatoryjność Wartość domyślna
page Numer strony Opcjonalny 1 (pierwsza strona)
per Liczba obciążeń na każdej stronie Opcjonalny 25 (25 klientów)
curl -i https://sandbox.espago.com/api/clients \
-X GET \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
-d "page=2" \
-d "per=15"
require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
response = client.send(
  "api/clients",
  method: :get,
  body: {
    page: 1,
    per: 5
  }
)

puts response.code
puts response.body
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/clients');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "page=2&per=15");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
{
  "count":19,
  "clients":[
    {
      "email":"client@example.com",
      "id":"cli_772q8GcejiQfRl4z",
      "created_at":1560960175,
      "description":"Jan Kowalski",
      "card":{
        "company":"VI",
        "last4":"4242",
        "year":2022,
        "month":2,
        "first_name":"Jan",
        "last_name":"Kowalski",
        "authorized":true,
        "authorized_cvv_cvc":true,
        "issuer_response_code":"00",
        "created_at":1561126879
      },
      "deleted":false
    },
    {
      "email":"test@example.com",
      "id":"cli_772psATGSdMbS8NS",
      "created_at":1560960154,
      "description":"Jan Kowalski id:321",
      "card":{
        "company":null,
        "last4":null,
        "year":null,
        "month":null,
        "first_name":null,
        "last_name":null,
        "authorized":null,
        "created_at":null
      },
      "deleted":false
    },
    (. . .)
  ]
}

link Autoryzacja karty klienta na żądanie

Autoryzacja na żądanie służy do sprawdzenia, czy karta zapisana w profilu klienta nadaje się do obciążeń inicjowanych przez sprzedawcę (MIT). Sprawdzenie polega na zarezerwowaniu i natychmiastowym zwolnieniu środków w wysokości 1 jednostki walutowej (1 PLN, 1 EUR itd.).

  • Udana autoryzacja oznacza to, że karta obsługuje płatności inicjowane przez sprzedawcę, nie jest zablokowana i nie upłynął jej termin ważności.
  • Nieudana autoryzacja oznacza, że obciążenia inicjowane przez sprzedawcę również nie powiodą - wyjątkiem jest odmowa autoryzacji ze względu np. na chwilowy brak środków lub wyczerpanie limitu transakcji danego dnia. W celu ustalenia przyczyny odrzucenia należy poddać analizie parametr issuer_response_code otrzymany w odpowiedzi. Należy przy tym pamiętać, aby nie ponawiać autoryzacji w przypadku odmowy z kodami wskazanymi zabraniającymi ponownej autoryzacji.


Pierwsza autoryzacja karty w profilu klienta
Jeśli autoryzacja na żądanie jest pierwszą operacją wykonywaną przy pomocy karty zapisanej w profilu klienta (np. po aktualizacji profilu klienta z użyciem nowego tokenu z EspagoFrame):
- Użycie CVV: podczas tej autoryzacji będzie użyty kod CVV - zapisany u dostawcy usług płatniczych kod CVV może być użyty tylko raz, do pierwszej płatności. Wszystkie następne transakcje będą już wykonywane bez kodu CVV. Część kart może nie obsługiwać płatności bez kodu CVV i wtedy nie nadają się do płatności cyklicznych. Taka operacja może powodować sytuację w której autoryzacja się powiodła, a dalsze próby obciążania już nie;
- Soft decline: pierwsza autoryzacja nowej karty będzie widziana jako płatność inicjowana przez sprzedawcę, bez wcześniejszej silnej weryfikacji klienta, dlatego może zostać odrzucona z kodem 1A lub 65 - wymagane zastosowanie SCA;
Aby tego uniknąć, należy bezpośrednio po aktualizacji danych karty w profilu klienta dokonać płatności z silnym uwierzytelnieniem (SCA), z parametrem cof=storing.


Autoryzacja karty klienta na żądanie następuje w wyniku wysłania żądania typu POST na adres https://sandbox.espago.com/api/clients/(:id)/authorize

(:id) - identyfikator klienta, którego dane mają zostać zautoryzowane

curl -i https://sandbox.espago.com/api/clients/CLIENT_ID/authorize \
-X POST \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD
require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
client_id = 'cli_772YYE_98HM1DmAD'
response = client.send "api/clients/#{client_id}/authorize", method: :post

puts response.code
puts response.body
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/clients/CLIENT_ID/authorize');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);

{
  "email":"client@example.com",
  "id":"cli_772q8GcejiQfRl4z",
  "created_at":1560960175,
  "description":"Jan Kowalski",
  "card":{
    "company":"VI",
    "last4":"2239",
    "year":2025,
    "month":2,
    "first_name":"Jan",
    "last_name":"Kowalski",
    "authorized":true,
    "issuer_response_code":"00",
    "created_at":1561369769
  },
  "deleted":false
}

link Bezpieczna strona do tworzenia i aktualizacji karty klienta

Istnieje możliwość przekierowania Klienta na stronę Espago w celu utworzenia profilu klienta lub aktualizacji danych jego karty w tym profilu. Są to przydane opcje w sytuacji gdy z jakiegoś powodu Sprzedawca nie chce aby Klient podawał dane karty pozostając na stronie sprzedawcy (czyli przy wykorzystaniu Espago JS lub iFrame).

Dodatkowo przy użyciu parametrów “check” i “store” można zadeklarować sytuacje w jakich aktualizacja ma mieć miejsce, aby wykluczyć sytuację w której Klient nadpisuje działającą kartę nową, nie obsługującą płatnosci cyklicznych lub bez środków.

Aby stworzyć “client_card_page” - bezpieczną stronę, gdzie Klient może zostać przekierowany aby bezpiecznie przekazać dane karty - należy wysłać zapytanie POST na następujący adres API:
https://sandbox.espago.com/api/clients/card_page
a następnie przekierować klienta na adres podany w odpowiedzi.

Parametry HTTP

Parametr Wymagane Opis Komentarz
client ID klienta Powiniem być podany tylko w przypadku modyfikacji istniejącego już klienta
client[description] check Opis/nazwa klienta Musi zawierać przynamniej 5 znaków
client[email] check
(chyba, że przekazoano parametr email)
Adres e-mail Profilu Klienta Adres e-mail wymagany do uwierzytelnienia 3D Secure, na który dodatkowo zostanie wysłane powiadomienie o wyniku obciążenia
email check
(chyba, że przekazoano parametr client[email])
Adres e-mail klienta Adres e-mail wymagany do uwierzytelnienia 3D Secure, na który dodatkowo zostanie wysłane powiadomienie o wyniku obciążenia. Jeśli parametr jest użyty równocześnie z paramtrem client wskazującym na ID Profilu Klienta posiadającego już zapisany adres e-mail lub z parametrem client tworzącym nowy obiekt Profilu Klienta z adresem e-mail, to przesłany w żądaniu obciążenia parametr email ma pierwszeństwo.
skip_email Wskaźnik wyłączenia powiadomienia e-mail. Boolean Domyślna wartość: false. Pozwala wyłączyć powiadomienie wysyłane przez Espago w formie e-mail - nawet jeśli do płatności użyto Profilu Klienta z zapisanym adresem e-mail lub przekazano parametr email w żądaniu obciążenia. Uwaga: w przypadku wyłączenia powiadomienia wysyłanego przez Espago, obowiązek wysłania powiadomienia klientowi ciąży na Sprzedawcy.
store Informacja kiedy karta ma być zapisana Możliwe wartości:
all (domyślnie) - zapisuje każdą kartę podaną
ecommerce - zapisuje tylko gdy karta nadaje się do płatności internetowych
recurring - zapisuje gdy karta nadaje się do płatności cyklicznych
check Informacja jak testować kartę klienta Możliwe wartości:
nothing - nic
ecommerce - sprawdź czy karta nadaje się do płatności internetowych
recurring - sprawdź czy karta nadaje sie do płatności cyklicznych
positive_url Adres URL, na który klient ma być przekierowany po zapisaniu danych karty.
negative_url Adres URL, na który klient ma być przekierowany gdy zrezygnuje lub gdy wystąpi błąd.
title Krótki opis, w jakim celu ta karta jest podawana - wyświetlony zostanie na stronie. Przynajmniej 5 znaków


Jeżeli serwis ma włączoną opcję “automatycznej autoryzacji klienta podczas jego utworzenia” to “check” jest domyślnie ustawiony jako “recurring”. W przeciwnym wypadku jako “nothing”.


curl -i https://sandbox.espago.com/api/clients/card_page \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
-d "client[description]=Jan Kowalski id:321" \
-d "client[email]=test@example.com" \
-d "check=recurring" \
-d "store=recurring" \
-d "title=Card for future subscription for the radio ABC"
require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
response = client.send(
  "api/clients/card_page",
  method: :post,
  body: {
    client: {
      description: "Jan Kowalski id:321",
      email: "test@example.com"
    },
    check: "recurring",
    store: "recurring",
    title: "Card for future subscription for the radio ABC"
  }
)

puts response.code
puts response.body
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/clients/card_page');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "client[description]=Jan Kowalski id:321&client[email]=test@example.com&check=recurring&store=recurring&title=Card for future subscription for the radio ABC");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
{
  "id":"cpl_772AUdz2l2DMHCvz",
  "url":"https://sandbox.espago.com/client_card_page/cpl_772AUdz2l2DMHCvz",
  "client":"cli_772IYA6M52V4njJR",
  "store":"recurring",
  "check":"recurring",
  "title":"Card for future subscription for the radio ABC",
  "valid_to":1561459867,
  "created_at":1561373467,
  "used":false,
  "positive_url":null,
  "negative_url":null
}

Teraz można także używać profil klienta (cli_772IYA6M52V4njJR) tak jak normalnie.
Parametr URL zawiera url strony client_card_page dla tego klienta. Taki link jest ważny jedną godzinę i wygasa po zapisaniu karty. Po zapisaniu karty, na ostatnim ekrenie podany jest parametr finish-true, może śledzić ten adres URL w WebView w aplikacji mobilnej i zamknąć okno po utworzeniu karty.

link Sprawdzanie informacji o karcie klienta

Sprawdzenie informacji o karcie przypisanej do profilu klienta pozwala na uzyskanie danych o:

  • kraju wystawcy karty
  • nazwy banku wystawcy karty
  • waluty karty
  • rodzaju karty

Aby korzystać z tej funkcji, wymagany jest kontakt z Espago w celu uruchomienia tej usługi.
W niektórych przypadkach sprawdzanie informacji o karcie może trwać dłużej niż 1s.

Aby wywołać metodę, należy wysłać żądanie typu POST na adres: https://sandbox.espago.com/api/clients/(:id)/check_type

(:id) - identyfikator profilu klienta, którego dane mają zostać sprawdzone.

curl -i https://sandbox.espago.com/api/clients/cli_772IYA6M52V4njJR/check_type \
-X POST \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD
require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
client_id = 'cli_772YYE_98HM1DmAD'
response = client.send "api/clients/#{client_id}/check_type", method: :post

puts response.code
puts response.body
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/clients/cli_772IYA6M52V4njJR/check_type');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
{
  "email":"test@example.com",
  "id":"cli_772IYA6M52V4njJR",
  "created_at":1561373467,
  "description":"Jan Kowalski id:321",
  "card":{
    "company":"VI",
    "last4":"4242",
    "year":2026,
    "month":2,
    "first_name":"Jan",
    "last_name":"Kowalski",
    "card_type":"D",
    "country":"HKG",
    "currency":"HKD",
    "bank":"U",
    "created_at":1561373520
  },
  "deleted":false
}

Parametr Opis Uwagi
card_type Informacja o rodzaju karty C - karta kredytowa
D - karta debetowa
U - brak informacji
country Kraj wystawcy karty 3-literowy kod kraju w standardzie ISO 3166-1 alpha-3
U - brak informacji
currency Waluta karty 3-literowy kod waluty w formacie ISO 4217.
U - brak informacji
bank Nazwa banku Nazwa banku
U - brak informacji

Dosyłanie CVV vpn_key

link Po co dosyłać CVV

Kod CVV może być użyty tylko jeden raz i po pierwszej autoryzacji lub płatności jest usuwany z bramki Espago. Aby przy użyciu profilu klienta wykonać kolejną płatnosć z użyciem kodu CVV, należy pobrać od klienta kod CVV (przy uzyciu EspagoFrame lub skryptu Espago JS i utworzyć token dla CVV) i przesłać go jako jeden z parametrów płatności (obok ID klienta, kwoty itp).


Funkcja dosyłania CVV jest szczególnie pomocna jako dodatkowe uwierzytelnienie przy płatnościach wielokrotnych inicjowanych przez klienta (np. zakupy w sklepie, płatności w aplikacji mobilnej). Dosyłanie CVV dodatkowo zwiększa skuteczność płatności, gdyż umożliwia obciążanie kart, które nie działają bez kodu CVV (patrz: Problem kart nienadających się do płatności cyklicznych)

Przesłany kod CVV w formie tokenu może zostać użyty w ciągu 24h od jego utworzenia, ponieważ ta funkcja służy tylko realizacji na bieżąco kolejnych płatności, nie ma możliwości zapisania tokenów “na zapas”.

link Tworzenie tokenu CVV

Do utworzenia tokenu CVV można wykorzystać EspagoIFrame, w którym klient będzie mógł podać dane karty, a w tym przypadku - wyłącznie CVV. Następnie te dane zostaną przesłane do Espago, a skrypt zwórci do strony ID tokenu, który można użyć do płatności w trybie dosyłania CVV.

1. Wywołanie IFrame

Klient wywołuje IFrame przystosowany do generowania tokenów cvv, a następnie go wypełnia i przesyła do espago

<script src="https://js.espago.com/espago-1.3.js"></script>
 <script 
   async=""
   data-id="EspagoFrameScript"
   data-key="VrYVaA1CjmRooKh63YYv"
   data-live="false"
     data-cvv-only="true"
   data-button="Pay"
   src="https://js.espago.com/iframe.js">
 </script>

 <a id="pay_btn">Zapłać</a>
$('#pay_btn').click( () => {
  showEspagoFrame()
})

Odebranie tokenu

Po wywołaniu formularza i podaniu danych karty przez płatnika, skrypt wysyła je bezpośrednio do serwera Espago. W przypadku utworzenia tokenu, skrypt domyślnie szuka na stronie z której został wywołany formularza o identyfikatorze “espago_form” i dodaje w nim pole z tokenem.

Działanie to można zmienić, wskazując parametr data-target lub data-success w wywołaniu iframe, o czym wspomniano w tabeli poniżej.

<form id="espago_form">
  <input type="hidden" id="cvv_token" name="cvv_token" value="cvv_xxxxxx">
</form>

Wywołanie płatności

Wywołanie płatności wraz z dodanym parametrem cvv=cvv_token_id.

curl -i https://sandbox.espago.com/api/charges \
-H "Accept: application/vnd.espago.v3+json" \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
-d "amount=10" \
-d "currency=pln" \
-d "client=cli_772IYA6M52V4njJR" \
-d "description=Espago docs" \
-d "cvv=cv_772oAPNIwkEZlEIPo"

link Parametry ramki

Parametr Wymagany Wartości domyślne Informacje
async done “” Nie może mieć wartości innej niż domyślna
data-id done EspagoFrameScript Nie może mieć wartości innej niż domyślna
src done adres skryptu Nie może mieć wartości innej niż domyślna
data-key done String, Klucz publiczny Merchanta
data-cvv-only done String, jeśli ma wartość ‘true’, EspagoFrame działa w trybie tokenu CVV - tylko pole CVV jest wyświetlane.
data-live true String, Wskazuje czy formularz ma być wysyłany do środowiska produkcyjnego. Wartość ‘true’ oznacza wysyłanie danych na środowisko produkcyjne, wartość ‘false’ na środowisko testowe.
data-company String, wskazuje markę zapisanej karty, logo danej marki będzie wyświetlone obok pola CVV w sekcji informacji o zapisanej karcie. Dostępne: AX, DC, DI, JC, MC, MD, UP, VI.
data-last4 String, wskazuje ostatnie 4 cyfry z numeru zapisanej karty, będą one wyświetlone obok pola CVV w sekcji informacji o zapisanej karcie.
data-valid-to String, format: ‘MMRRRR’, wskazuje datę ważności zapisanej karty, będzie ona wyświetlone obok pola CVV w sekcji informacji o zapisanej karcie.
data-lang pl String, Język w jakim będzie wyświetlony formularz w standardzie ISO 639-1. Dostępne: da, de, en, et, fr, it, lt, lv, pl, ru, sv.
data-success function(data) {} Funkcja callback wywoływana w przypadku, gdy token zostanie wygenerowany. Uwaga, podanie funkcji callback wyłącza domyślne działanie skryptu - pole ‘cvv_token’ nie zostanie dołączone do formularza.
data - string, wygenerowany token z bramki Espago.
data-error function(data) {} Funkcja callback wywoływana w przypadku, gdy token nie zostanie wygenerowany.
data - string; kod błędu otrzymany z bramki Espago wraz z opisem.
data-onclose function() {} Funkcja wywoływana w przypadku, gdy użytkownik zamknie okno dialogowe (klikając “x” lub klawisz “Esc”).
data-target espago_form Nazwa formularza do którego zostanie dodane ukryte pole ‘card_token’ o wartości tokenu.
Uwaga - w przypadku gdy zostanie podany parametr ‘success_callback’ akcja ta nie wykona się. Token zostanie przekazany do tej funkcji.
data-title Dodaj swoją kartę (pl) Nagłówek wyświetlany na górze formularza.
Uwaga - domyślna wartość jest zależna od parametru języka ‘data-lang’
data-subtitle Tekst wyświetlany poniżej nagłówka i nazwy sklepu (pobranej automatycznie z API Espago)
data-button Zapisz (pl) Etykieta tekstowa wyświetlona na przycisku zatwierdzania formularza.
Uwaga - domyślna wartość jest zależna od parametru języka ‘data-lang’

link Płatność przy użyciu tokenu CVV

Płatność przy użyciu tokenu CVV odbywa się w taki sam sposób, co zwykła płatność, ale posiada dodatkowy parametr cvv, zawierający id tokenu cvv.

Przykładowe zapytanie

curl -i https://sandbox.espago.com/api/charges \
-H "Accept: application/vnd.espago.v3+json" \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
-d "amount=10" \
-d "currency=pln" \
-d "client=cli_772IYA6M52V4njJR" \
-d "description=Espago docs" \
-d "cvv=cv_772oAPNIwkEZlEIPo"
require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
response = client.send(
  "api/charges",
  method: :post,
  body: {
    amount: 10,
    currency: 'pln',
    client: 'cli_772YYE_98HM1DmAD',
    description: 'Espago docs',
    cvv: 'cv_772oAPNIwkEZlEIPo'
  }
)

puts response.code
puts response.body
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/charges');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "amount=10&currency=pln&client=cli_772IYA6M52V4njJR&description=Espago docs&cvv=cv_772oAPNIwkEZlEIPo");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);

link Wykorzystanie Espago.js do tworzenia tokenu CVV

W celu przyjęcia kodu CVV i utworzenia tokenu CVV należy użyć formularz wykorzystujący skrypt JS espago-1.3. Skrypt ten przesyła kod CVV bezpośrednio z formularza (przeglądarka klienta) do bramki Espago, uzyskuje token CVV i przesyła jego ID ( jako parametr “cvv_token” z wartością w postaci “cv_xxxxxxxx”) wraz z formularzem do strony sprzedawcy na adres zdefinowany w polu action.

Adres, pod którym dostępna jest aktualna wersja skryptu: https://js.espago.com/espago-1.3.js
Demo: https://github.com/espago/espago-1.3.js-demo

W skrypcie należy użyć klucza publicznego (Public Key) używanego także przy generowaniu tokenów z danymi kart.

<script src='https://js.espago.com/espago-1.3.js' type='text/javascript'></script>

<form action='cv_token.html' id='espago_new_cvv_form' method='POST'>
  <input id='espago_new_verification_value' type='text' value='712'>
  <span id='espago_new_verification_value_error'></span>
  <input type='submit' value='Create CVV token'>
</form>
var espago = new Espago({public_key: 'PfcMBQnqWjNF2ihkv9xs', custom: true, live: false})

$("#espago_new_cvv_form").submit(function(event){
  event.preventDefault()

  if (espago.validate_new_cvc()){
    $("#espago_new_verification_value_error").text("")
  } else {
    $("#espago_new_verification_value_error").text("Błędne dane!")
  }
  espago.create_new_cvv()
})

Espago Terminals payment

link Czym jest Espago Terminals

Espago Terminals umożliwia integrację fizycznych terminali płatniczych z systemem sprzedaży dostępnym przez przeglądarkę. Integracja polega na wysłaniu płatności na terminal przez request API i otrzymaniu przez system sprzedaży informacji o statusie transakcji. Umożliwia też realizację zwrotów inicjowanych w systemie sprzedaży.

Standardowa integracja może zostać rozszerzona o funkcjonalność, która umożliwia powiązanie ID transakcji z terminala z klientem w serwisie sprzedawcy i na tej podstawie ponowne obciążenie karty bez jej fizycznej obecności (o ile umożliwia to regulamin sprzedaży).

Wykorzystanie Espago Terminals jest spójne z API Espago (wykorzystywanym w e-commerce, e-invoicing i usługach recurringowych), ponieważ po dokonaniu płatności na terminalu i uzyskaniu od Espago Terminals profilu klienta wszelkie operacje wykonywane są w ten sam sposób w bramce Espago w oparciu o ten profil.

Do przeprowadzenia wdrożenia została przygotowana przez Espago symulacja fizycznego terminala, dzięki czemu partner integrujący nie potrzebuje dostępu do testowego fizycznego terminala jak i testowych kart płatniczych.

link Zakres stosowania Espago Terminals

Ze względu na charakter działania terminali płatniczych Espago Terminals posiada kilka ograniczeń technicznych:
1. Komputer (dalej zwany POS), z którego wysłana ma być płatność musi bezpośrednio znajdować się w tej samej sieci LAN z terminalem.
2. POS musi posiadać system Android (telefon lub tablet - min. wersja 7) lub Windows (minimum 7).
3. POS musi mieć zainstalowaną dedykowaną aplikację Espago Terminals (w dziale Do pobrania).
4. Espago Terminals współpracuje tylko z niektórymi agentami rozliczeniowymi (m.in. Worldline). Więcej informacji na ten temat można uzyskać pod adresem sprzedaz@espago.com.

Aplikacja Espago Terminals

Nasza aplikacja została stworzona w celach bezpieczeństwa transakcji, a bez niego nasze rozwiązanie nie będzie działać poprawnie. Służy ono do bezpośredniej komunikacji między naszym API, a terminalem płatniczym.

Poza instalacją aplikacji nie jest potrzebne żadne dodatkowe oprogranowanie. Aplikacja została stworzone w taki sposób, aby działała niezwłocznie po uruchomieniu urządzenia, lub w tle, kiedy inna aplikacja jest obecnie używana.

Aplikacja jest dostępna w dziale Do pobrania. link

link Integracja

Po uzyskaniu dostępu do konta od działu wsparcia należy się zalogować pod adresem https://terminals-beta.espago.com/users/sign_in. Po tym zaleca się zmianę hasła. Można tego dokonać w panelu zarządzania swoim kontem - znajduje się on pod przyciskiem sybolizującym “konto” w lewym dolnym rogu.

W następnym kroku należy przejść do zakładki “Services”. Tam będzie można odnaleźć swój serwis testowy.
W Espago Terminals każdy użytkownik może posiadać wiele serwisów, a do serwisów może należeć wiele terminali, jednak każdy serwis posiada oddzielny dostęp do API i nie mogą one wymieniać między sobą informacji czy współdzielić terminali.

Po wybraniu swojego serwisu należy kliknąć przycisk “Edit Service” oraz ustalić hasło dostępu do API - nie może ono być przekazywane osobom postronnym. Należy również podać back_request_url - parametr określający adres, na który zostanie wysłany back request z informacją o statusie transakcji po jej wykonaniu, jak i login i hasło basic auth mające służyć do autoryzacji back requestów.

Ostatnim krokiem jest konfiguracja terminali. Aby tego dokonać należy z poziomu serwisu wybrać “View Terminal” dla wybranego terminala, następnie “Edit Terminal”. Nazwa może być dowolna - wygodna dla integratora. Kluczowymi parametrami podstawowej konfiguracji jest adres IP sieci LAN oraz port, na którym nasłuchiwać będzie terminal. Na etapie integracji z środowiskiem testowym te parametry nie są istotne do poprawnego przeprowadzenia płatności.

Po tej konfiguracji można zacząć wysyłać requesty do bramki Espago Terminals według instrukcji w kolejnych rozdziałach. Espago udostępnia również narzędzie do podglądania zapytań wysyłanych do bramki. Dostępne one są w zakładce Api Requests.

Wirtualny Terminal

Mając na uwadze to, iż dostęp do Espago Terminals oraz integracja może nastąpić dużo wcześniej, niż dostępny będzie fizyczny terminal stworzyliśmy wirtualny terminal testowy wbudowany w nasze rozszerzenie. Wszystkie płatności wysyłane na środowisko testowe (https://terminals-sandbox.espago.com) będą obsługiwane przez niego.
Po poprawnym zapytaniu o płatność i przejściu w link rozszerzenie Espago Terminals do przeglądarki uruchomi nowe okno z terminalem wirtualnym, który przedstawia kluczowe informacje dla programisty, które wysłał na terminal. Na dole okna będzie możliwość wybrania odpowiedzi wysłanej na terminal.

Po poprawnej integracji oraz przejściu kilku testów zespół Espago uruchomi środowisko produkcyjne, za pomocą którego będzie można wysyłać płatności na fizyczne terminale.</ div>

link Aplikacje Espago Terminals

Do korzystania z oferowanych przez nas usług, konieczne jest zainstalowanie jednej z dedykowanych do tego celu aplikacji. Posłużą one jako pośrednik w komunikacji terminala płatniczego z naszym API. Aplikacje te dostępne są na komputery z systemem Windows oraz telefony z systemem Android. Wybraną przez nas aplikację można pobrać w dziale Do pobrania . Link

Instalator prowadzi nas przez cały proces instalacji, który zawiera tylko dwa kroki:
1. Wybór dla kogo zainstalować aplikację (aktualny użytkownik / wszyscy użytkownicy).
2. Ścieżka, pod którą aplikacja ma zostać zainstalowana.

Aplikacja po instalacji zostanie dodana do autostartu systemu, dzięki czemu, przy ponownym uruchomieniu komputera nie musimy jej ręcznie uruchamiać. Działa też ona całkowicie w tle, dlatego też przy starcie nie wyświetli nam się jej okno. Jeżeli chcemy wyświetlić okno aplikacji, należy na pasku zadań rozwinąć tray (zasobnik systemowy), a następnie kliknąć lewym przyciskiem na białą ikonę Espago Terminals. By uniknąć przypadkowe zamykanie aplikacji przyciskiem X zostało zmienione jego działanie, przez co próba zamknięcia aplikacji w ten sposób spowoduje jedynie jej minimalizację do tray'a.

Kliknięcie prawym przyciskiem w ikonę spowoduje wyświetlenie dodatkowych akcji.
* Force reload — wymusza restart połączenia aplikacji z chmurą Espago oraz terminalem płatniczym.
* Disable Virtual Terminal — wyłącza / włącza przechwytywanie wysyłanych płatności przez wirtualny terminal.
* Quit — wymusza całkowite zamknięcie aplikacji.

Zanim aplikacja będzie gotowa do pracy, musimy wejść w panel ustawień, klikając w zębatkę umieszczoną w prawym górnym rogu okna, a następnie podać jej następujące informacje:
* TID — ID terminala, którego chcemy połączyć.
* API login — login do API dla naszego serwisu.
* API password — hasło do API dla naszego serwisu.

Powyższe dane są potrzebne by połączyć się z chmurą Espago oraz terminalem. Bez nich aplikacja nie będzie działała poprawnie!

Dostęp do powyższych informacji mamy w panelu naszego serwisu. Należy pamiętać, że jeżeli nie mamy ustawionego hasła API, powinno się to zrobić, wchodząc w Service -> Edit Service -> Edit Passwords.

Aktualnie, tryb ten dostępny jest wyłącznie na aplikacje systemu Windows.
Powinno się z niego korzystać jedynie w celach deweloperskich, przy próbach połączenia się z naszym API.

W celach integracyjnych została dodana opcja, która przełącza aplikację w tryb Sandbox. Tryb ten zmienia środowisko, z którym komunikuje się aplikacja oraz terminal. By wspomniany włączyć tryb, należy w ustawieniach aplikacji ustawić przełącznik opisany jako “Run in sandbox mode” tak, by zaświecił się na żółto. W celu uniknięcia nieporozumień w jakim trybie działa aplikacja, w głównym widoku aplikacji pojawi się specjalny komunikat informujący, że tryb Sandbox jest włączony.

Trzeba pamiętać o sprawdzeniu danych serwisu oraz terminala, z którym próbujemy nawiązać komunikację, gdyż te mogą się różnić w zależności od środowiska.

Sterowanie statusem płatności

Tryb Sandbox pozwala na sterowanie statusem płatności za pomocą kwoty obciazenia:

  • wartość kwoty po przecinku równa 00 skutkuje statusem success (na przykład: 10.00)
  • wartość kwoty po przecinku różna od 00 skutkuje statusem failed (na przykład: 10.01)

Wiele użytkowników

Jeżeli na komputerze jest więcej niż jeden użytkownik, należy zmienić jego ustawienia logowania (dokumentacja microsoft). Należy wejść w ustawienia, wyszukać pozycję Opcje logowania, następnie upewnić się, że opcja “Użyj moich informacji logowania, aby automatycznie kończyć konfigurowanie mojego urządzenia po aktualizacji lub ponownym uruchomieniu” i upewnić się, że jest ona Wyłączona dla wszystkich użytkowników. Bez tego aplikacja nie będzie działać poprawnie.

link Działanie Espago Terminals

1. Request z danymi do wykonania transakcji

Wysłanie requestu do API Espago Terminals z danymi terminala oraz informacjami o transakcji na adres terminals.espago.com/api/charges.

{
  "amount": 12.00,
  "currency": "EUR",
  "description": "Payment #5656",
  "terminal": "1234567",
  "kind": "mobile"
}

2. Response

Po podaniu poprawnych danych Espago Terminals wyśle transakcję na terminal, a w odpowiedzi przekaże informację o utworzonej płatności.

{
  "payment_guid": "tp_4455rgT6Ve",
    "state": "sent"
}

W przypadku braku połączenia z terminalem lub niepoprawnymi danymi zostanie zwrócony odpowiedni komunikat.

3. Wysłanie płatności na terminal płatniczy

Po requeście API transakcja zostanie wysłana na terminal płatniczy. W tym momencie Klient dokonuje płatności kartą na terminalu w zwykły sposób, zgodnie z instrukcją użytkowania terminala.

4. Odpowiedź ze statusem transakcji

Po zakończeniu transakcji informacje dotyczące transakcji zostaną wysłane na adres podany jako back request.

{
  "payment": {
    "id": "tp_7d7z-noWFPW",
    "description": "Payment #5656",
    "state": "success",
    "amount": "12.00",
    "currency": "EUR"
  }
}

link Parametry obciązenia

Nowa płatność na terminalu następuje w wyniku wysłania żądania typu POST na adres https://terminals.espago.com/api/charges. Tak jak w przypadku standardowego API Espago zapytanie należy autoryzować za pomocą nagłówka Authorization z wartością Basic app_id:password.

Dostępne są następujące parametry:

Parametr Opis Wymagane Uwagi
terminal TID Tak Tid terminala, na który ma zostać wysłana płatność
description Opis transakcji Tak Musi składać się z 3 do 255 znaków. Powinien być stosowany do powiązania płatności z klientem serwisu.
amount Kwota transakcji Tak Dodatnia liczba dziesiętna, np. 123.45
currency Waluta Tak Trzyliterowy skrót zgodny z walutą przyjmowaną przez terminal
kind Typ transakcji Tak Musi zawierać string "mobile", inaczej płatność nie zostanie wysłana na terminal
fetch_client Obiekt klienta Nie Wartość true spowoduje przekazaniem obiektu klienta w back requeście

W odpowiedzi Espago Terminals prześle link do przekierowania komputera POS lub w przypadku niepoprawnego zapytania jego powód.

link Parametry back requestów

Po zakończonej płatości Espago Terminals wysyła informacje dotyczące jej statusu.
Przykładowa odpowiedź:

{
  "payment": {
    "id": "tp_7d7z-noWFPW",
    "description": "Order #55665",
    "state": "success",
    "amount": "12.99",
    "currency": "PLN"
  },
  "client": {
    "id": "cli_7d7Cm9pP61YyvOKZ",
    "card": {
      "full_name": "Myrna Cummings",
      "company": "VI",
      "last4": "0002",
      "year": "2024",
      "month": "12",
      "country_code": "pl"
    }
  }
}
Parametr Opis Uwagi
payment Dane dotyczące płatności
payment id Id płatności Nadawane przez Espago Terminals
payment description Opis płatności Nadawane przez merchanta przy tworzeniu płatności
payment state Status płatności Wartość inna niż success oznacza niepowodzenie
payment amount Kwota płatności
payment currency Waluta płatności
client Dane dotyczące klienta Zwracane tylko gdy fetch_client=true
client id Id profilu klienta w Espago
client card Dane karty przypisanej do profilu
reject_reason Powód odrzucenia płatności Parametr ten jest wysyłany tylko w przypadku niepowodzenia transakcji

link Płatność zakończona niepowodzeniem - parametr reject_reason

Parametr reject_reason zawiera ogólną infromację o odrzuceniu lub odmowie wykonania płatności z poziomu terminala płatniczego. Jest on dołączany do odpowiedzi tylko, gdy status płatności ma wartość failed. Zwracany razem z płatnościami w back requestach i poprzez API. Zawiera informacje o: nazwie, wiadomości i opisie błędu. Ma no charakter stricte informacyjny, mający pomóc zlokalizować ewentualny błąd.

{
    "payment": { 
        ...,
        "state": "failed"
        },
    "reject_reason": {
        "name": "declinedWrongPin",
        "message": "Authorization declined - Wrong PIN",
        "description": "Authorization failed, cardholder entered wrong PIN."
    }
}

link Status płatności

Espago Terminals zapisuje całą komunikację z terminalem oraz wszelkie potrzebne informacje o płatności, w tym jej status. Można się zapoznać z tymi informacjami w panelu na https://espago.terminals.com/manage, lecz w przypadku niejasności to informacja na ekranie terminala zawsze stanowi nadrzędne źródło informacji.

Możliwe stany płatności na terminalu:

Stan Opis
new Płatność utworzona w serwisie Espago Terminals, lecz link do niej przypisany nie został wykorystany
sent Płatność wysłana na terminal, oczekuje na zakończenie
success Płatność została wykonana, konto klienta obciążone.
failed Płatność zakończona niepowodzeniem.

link Płatności wielokrotne na terminalu

Wykonywanie płatności wielokrotnych w oparciu o pierwszą transakcję wykonaną na terminalu jest bardzo proste w implementacji, zwłaszcza gdy merchant posiada już integrację ze standardową bramką płatności Espago.

Aby uzyskać referencję transakcji po płatności przy jej tworzeniu poprzez request na endpoint /api/charges należy dodać parametr fetch_client i nadać mu wartość true. Wtedy gdy płatność zostanie udana w back requeście dostaniemy obiekt klienta z parametrem id.

{
  "payment": { ... },
  "client": {
    "id": "cli_7d7Cm9pP61YyvOKZ",
    "card": {
      "full_name": "Myrna Cummings",
      "company": "VI",
      "last4": "0002",
      "year": "2024",
      "month": "12",
      "country_code": "pl"
    }
  }
}

Po udanej płatności Espago Terminals tworzy profil klienta dla standardowej bramki Espago. ID oznacza ID profilu, który można podawać zamiast tokenu (client: ...) w parametrach tworzenia płatności i można go używać w taki sam sposób jak zwykły profil klienta utworzony przez zwykły request do bramki Espago.
Więcej na temat profilu klienta można przeczytać w rozdziale profil klienta.

link Wyciąganie profilu klienta po dokonanej płatności

Możliwe jest wyciągnięcie klienta po dokonaniej płatności ze statusem success, nawet jeżeli parametr fetch_client nie został ustawiony na wartość true. Zapytanie to może być szczególnie przydatne przydatne przy płatności która została wykonana na terminalu, ale z jakiegoś powodu nie udało się wyciągnąć z niej danych karty i utworzyć profilu klienta, a chcielibyśmy go uzyskać.
W tym celu należy wysłać standardowy request POST na endpoint /api/payment/fetch_client z parametrem

Przykładowe zapytanie

{
    "payment": "tp_3452342"
}

Przykładowa odpowiedź

{
    "client": {
        "id": "cli_83cSYFUwtQQ4Nd72",
        "card": {
            "full_name": "Gayle Erdman",
            "company": "VI",
            "last4": "0002",
            "year": "2025",
            "month": "12",
            "country_code": "pl"
        }
    },
    "status": "ok"
}

link Status terminala

Możliwe jest wyciągnięcie danych terminala oraz jego aktualnego statusu przez API.
W tym celu należy wysłać standardowy request POST na endpoint /api/terminal z parametrem terminal wskazującym na TID terminala.

Parametry connection oznaczają status połączenia terminala z chmurą poprzez aplikację natywną. W przypadku integracji przez rozszerzenie do przeglądarki należy je zignorować.

Przykładowe zapytanie

{
    "terminal": "238409245"
}

Przykładowa odpowiedź

{
    "tid": "238409245",
    "ip": "192.168.0.2",
    "port": "7784",
    "name": "recepcja-2",
    "updated_at": "1628548083",
    "connection": {
        "connected": true,
        "busy": false
    }
}

link Wyciąganie danych transakcji

Możliwe jest wyciągnięcie danych płatności oraz jego aktualnego statusu przez API.
W tym celu należy wysłać standardowy request POST na endpoint /api/payment z parametrem payment wskazującym na id płatności (tp_....).

Przykładowe zapytanie

{
    "payment": "tp_83cePB345fg"
}

Przykładowa odpowiedź

{
    "guid": "tp_83cePNfN04b",
    "description": "Order #345323",
    "state": "success",
    "amount": "15.99",
    "currency": "EUR"
}

link Zwrot płatności wykonanej na terminalu

Aby wykonać zwrot udanej transakcji należy wykonać zapytanie POST na https://terminals.espago.com/api/charges/(payment id)/refunds, a w body podać kwotę.
UWAGA: w celu oddania pełnej emulacji zwrotów, nieparzysta liczba groszy oznacza nieudaną transakcje na środowisku sandbox.

Przykładowe zapytanie:

/api/charges/tp_456xyz/refunds

{
  "amount": 5.99
}

Odpowiedź:

{
  "id": "tp_456xyz",
  "refunded_amount": "5.99",
  "state": "refunded"
}

Espago.js web

link Działanie Espago.js

UWAGA: opisane tu użycie Espago JS jest akceptowanym, ale starszym rozwiązaniem niż Espago iFrame. Dla nowych integracji zdecydowanie sugerujemy wykorzystanie rozwiązania iFrame dające więcej możliwości i będące ciągle rozwijane.

Celem uproszczenia integracji stworzyliśmy dla Państwa skrypt, który generuje utworzony token zwracając jego wartość w parametrze “card_token”.
Adres, pod którym można go znaleźć to https://js.espago.com/espago-1.3.js

Jeżeli formularz płatności ma być osadzony wewnątrz Państwa strony to użycie skryptu https://js.espago.com/espago-1.3.js (lub Espag iFrame) jest obowiązkowe. Skrypt musi być pobierany przez przeglądarkę klienta bezpośrednio z serwera Espago.

Dostępność skryptu js.espago.com (SLA) jest taka sama jak bramki Espago, dlatego nie ma potrzeby kopiowania i używania przez skryptu JS Espago ze swojego serwera. Na stronie do pobrania dostępny jest najnowszy przykładowy formularz wykorzystujący skrypt JS z biblioteką jQuery - przykład wykorzystuje bibliotekę jQuery, której sam skrypt Espago.JS nie wymaga do poprawnego działania. Możliwa jest więc implementacja również w “czystym” JavaScript. Przy wykorzystaniu skryptu https://js.espago.com/espago-1.3.js w formularzu pola zawierające dane kart (numer karty, data ważności, właściciel) nie może mieć parametru typu “name” - do działania skryptu wystarczy “id”. Aby uzyskać te dane można odczytać je z odpowiedzi bramki Espago przy tworzeniu profilu klienta (zapytanie /api/clients) lub płatności (zapytanie /api/charges).

1. Wypełnienie formularza

Klient wypełnia formularz swoimi danymi, a następnie klikając przycisk wywołuje akcję wytworzenia tokenu

<script src='https://js.espago.com/espago-1.3.js' type='text/javascript'></script>
<form action='/charge' id='espago_form' method='POST'>
  <input id='espago_card_number' type='text'>
  <input id='espago_first_name' type='text'>
  <input id='espago_last_name' type='text'>
  <input id='espago_month' type='text'>
  <input id='espago_year' type='text'>
  <input id='espago_verification_value' type='text'>
  <input type='submit' value='Pay'>
</form>

2. Odebranie tokenu

Funkcja `create_token()` to główna akcja skryptu komunikująca się z bramką. Na podstawie wcześniej określonego klucza publicznego merchant jest identyfikowany, a wszelkie przesłane dane karty wiązane z tokenem. Domyślnie funkcja espago.create_token() wykonuje akcję submit.

var espago = new Espago({public_key: 'PfcMBQnqWjNF2ihkv9xs', custom: true, live: false})

$("#espago_form").submit(function(event){
  event.preventDefault()
  if (!espago.validate_card_number()){
    alert("Błędne dane!")
  }

  if (!espago.validate_first_name()){
    alert("Błędne dane!")
  }

  if (!espago.validate_last_name()){
    alert("Błędne dane!")
  }

  if (!espago.validate_card_date()){
    alert("Błędne dane!")
  }

  if (!espago.validate_card_cvc()){
    alert("Błędne dane!")
  }

  espago.create_token()
})

3. Wywołanie płatności

Wywołanie zwykłej płatności z tokenem - czytaj więcej na temat płatności

link Parametry konstruktora Espago

Formularz zadziała poprawnie tylko w wyniku operacji na utworzonym wcześniej obiekcie espago. Na nim będą wywoływane wszystkie metody odpowiedzialne za komunikację oraz ewentualną walidację wprowadzonych danych. Utworzony obiekt musi zawierać klucz publiczny merchanta. Poniżej został zamieszczony przykładowy kod odpowiedzialny za jego utworzenie:

var espago = new Espago({public_key: 'klucz_publiczny:'});

Parametry

Parametr Obowiązkowy Wartości domyślne Znaczenie
public_key done Klucz publiczny Merchanta
live true Parametr, który wskazuje gdzie będą wysyłane dane do utworzenia tokenu.
Parametr ‘true’ oznacza wysyłanie danych na środowisko produkcyjne, parametr ‘false’ na środowisko testowe.
form #espago_form Nazwa formularza
card_number #espago_card_number ID Pola z numerem karty klienta
first_name #espago_first_name ID pola z imieniem właściciela karty
last_name #espago_last_name ID Pola z nazwiskie, właściciela karty
month #espago_month ID pola z miesiącem ważności karty
year #espago_year ID pola z rokiem ważności karty
cvc #espago_verification_value ID pola z numerem weryfikacyjnym karty
custom false Wartość ‘true’ pozwala na zdefiniowanie własnych parametrów success i error.
success function(data) {} Funkcja callback. Akcje w niej zawarte wykonują się w przypadku otrzymania pozytywnej odpowiedzi zwrotnej.
error function(data) {} Funkcja callback. Akcje w niej zawarte wykonują się w przypadku wystąpienia błędu podczas komunikacji z serwerem.
submit true Zatwierdzenie formularza i wysłanie danych.

link Tworzenie tokenu

Główna akcja skryptu komunikująca się z bramką. Na podstawie wcześniej określonego klucza publicznego merchant jest identyfikowany, a wszelkie przesłane dane karty wiązane z tokenem.

espago.create_token()

Domyślnie funkcja espago.create_token() wykonuje akcję submit. Możliwe jest jej wyłączenie poprzez zawarcie w niej dodatkowych argumentów funkcji zawartych poniżej (kolejno wyłączenie akcji submit oraz czynności na wypadek powodzenia i błędu):

espago.create_token({
  submit: false,
  success: (data) => { 
    alert("success")
  },
  error: (data) => { 
    alert("error");
  }
})

link Pola formularza

Domyślne ID pola Typ pola Znaczenie
espago_card_number text Numer karty klienta
espago_first_name text Imię klienta
espago_last_name text Nazwisko klienta
espago_month text Miesiąc wygaśnięcia karty
espago_year text Rok wygaśnięcia karty
espago_verification_value text Kod potwierdzenia

Poniżej przedstawione zostały funkcje walidacji pól formularza. W przykładowym kodzie tych funkcji zostały wprowadzone dane podlegające walidacji. W przypadku ich braku, domyślnym parametrem stają się wartości odpowiednich pól formularza.

validate_card_number()

Metoda umożliwiająca walidację numeru karty klienta. Przy wprowadzaniu numeru karty z dodatkowymi znakami nie będącymi cyframi, zostaną one zignorowane.

espago.validate_card_number('4242424242424242') //true
espago.validate_card_number('42 42 42 42 42 42 42 42') //true
espago.validate_card_number('42 42 42') //false
espago.validate_card_number() //domyślnym parametrem wartość pola 'espago_card_number' formularza

validate_first_name()

Metoda walidująca imię właściciela karty wprowadzane do formularza płatności.

espago.validate_first_name('Jan') //true
espago.validate_first_name('') //false
espago.validate_first_name() //domyślnym parametrem wartość pola 'espago_first_name' formularza

validate_last_name()

Metoda walidująca nazwisko właściciela karty wprowadzane do formularza płatności.

espago.validate_last_name('Kowalski') //true
espago.validate_last_name('') //false
espago.validate_last_name() //domyślnym parametrem wartość pola 'espago_last_name' formularza 

validate_card_date()

Metoda walidująca datę ważności karty wprowadzaną do formularza płatności.

espago.validate_card_date('02', '2017') //true
espago.validate_card_date(02, 2017) //true
espago.validate_card_date(2, 17) //false
espago.validate_card_date() //domyślnymi parametrami wartości pól 'espago_month' i 'espago_year' formularza

validate_card_cvc()

Metoda walidująca kod CVC karty wprowadzany do formularza płatności.

espago.validate_card_cvc('123') //true
espago.validate_card_cvc('12') //false
espago.validate_card_cvc('xyx') //false
espago.validate_card_cvc() //domyślnym parametrem wartość pola 'espago_verification_value' formularza

Google Pay™ payment

link Opis działania

Google Pay pozwala kupującym na dokonywanie szybkich płatności kartowych, bez konieczności podawania danych karty płatniczej.
Dane produktu kartowego są przechowywane bezpiecznie przez Google.

Są dwa sposoby integracji:
1. Skorzystanie ze strony hostowanych płatności – Bezpieczną Stronę Płatności Espago
2. Użycie API lub SDK Google Pay po stronie Sprzedawcy i przesłanie otrzymanego tokenu do Espago w żądaniu POST na adres /api/charges

link Strona hostowanych płatności

Google Pay może być obsługiwany w pełni przez Espago po przekierowaniu klienta na Bezpieczną Stronę Płatności Espago.

Aby włączyć tę funkcjonalność w serwisie Sprzedawcy należy skontakować się z Działem Wsparcia Espago.

Testowe płatności

W środowisku Sandbox kwota transakcij po przecinku określa scenariusz symulowanej płatności.

Kwota po przecinku Scenariusz płatności
n.00 zaakceptowana z kryptogramem, bez 3D Secure
n.01 zaakceptowana PAN_ONLY, 3D Secure Challenge
n.02 zaakceptowana PAN_ONLY, 3D Secure Frictionless
n.10 odrzucona z kryptogramem
n.11 odrzucona PAN_ONLY, 3D Secure Challenge
n.12 odrzucona PAN_ONLY, 3D Secure Frictionless
n.66 błędne gatewayMerchantId

Gdzie n oznacza liczbę naturalną.

link Integracja z API Google Pay



Sama integracja jest stosunkowo prosta:
1. Sprzedawca integruje się z API Google Pay.
2. Kupujący wybiera przycisk Google Pay w witrynie internetowej lub aplikacji mobilnej Sprzedawcy.
3. Kupujący dokonuje płatności, a Google Pay zwraca Sprzedawcy token płatności.
4. Sprzedawca zakodowuje otrzymany token za pomocą base64 i przesyła go do API Espago w żądaniu POST na adres /api/charges


Integracja strony internetowej z API Google Pay

Celem integracji strony internernetowej z API Google Pay, postępuj zgodnie z instrukcjami zawartymi w dokumentacji Google Pay API dla aplikacji internetowych, zapoznaj się ze wskazówkami dotyczącymi marki w aplikacji internetowej Google Pay oraz listą kontrolną integracji Google Pay w aplikacjach internetowych.



Integracja aplikacji na Androida z API Google Pay

Celem integracji aplikacji na Andorida z API Google Pay, postępuj zgodnie z instrukcjami zawartymi w dokumentacji dla deweloperów Google Pay na Androida, zapoznaj się ze wskazówkami dotyczącymi marki w aplikacji GooglePay na Androida oraz zapoznaj się z listą kontrolną integracji Google Pay na Androidzie.



Konfiguracja integracji

W kodzie wywołującym skrypt Sprzedawca musi wskazać bramkę płatności oraz ID Sprzedawcy, dla bramki Espago parametry przyjmują odpowiednio wartości:
gateway: 'espago',
gatewayMerchantId: '[app_id serwisu merchanta]'

Przykładowo:

const tokenizationSpecification = {
  type: 'PAYMENT_GATEWAY',
  parameters: {
    'gateway': 'espago',
    'gatewayMerchantId': 'ms_771eUTliRiZ'
  }
};

Obsługiwane sieci kart

Spośród kart dostępnych w Google Pay, Espago obsługuje wszystkie produkty organizacji kartowych Visa, Mastercard oraz JCB, co implikuje następującą konfigurację skryptu Google Pay.

const allowedCardNetworks = ["JCB", "MASTERCARD","VISA"];

link Przekazanie zaszyfrowanych danych płatności do Espago i obciążenie

Po uzyskaniu zaszyfrowanych danych płatności od Google Pay (paymentData), Sprzedawca musi zakodować je korzystając z algorytmu base64, następnie wysłać do bramki Espago jako wartość parametru googlepay.

Rozpoczęcie nowego obciążenia następuje w wyniku wysłania żądania typu POST na adres https://sandbox.espago.com/api/charges

Inicjowanie płatności odbywa się przy użyciu tych samych parametrów jak w przypadku parametrów obciążenia opisanych w rozdziale Płatność jednorazowa. Wyjątkiem jest nowy parametr googlepay oraz wartość parametru channel, która musi przyjąć wartość elavon_google_pay

Obecnie płatności Google Pay są dostępne jedynie dla integracji przez Elavon.




Dla płatności PAN_ONLY uwierzytelnienie 3D Secure jest inicjowane automatycznie, analogicznie do płatności kartowych.
W odpowiedzi z bramki Sprzedawca otrzyma adres url do przekierowania klienta (jako wartość parametru redirect_url).

link Generator payloadów Google Pay

Pod tym linkiem znajduje się formularz generujący tokeny Google Pay do użycia na środowisku sandbox.espago.com.

link Przykładowe obciążenie

{
  "amount": 10,
  "currency": "pln",
  "channel": "elavon_google_pay",
  "description": "Espago docs Google Pay",
  "google_pay": "eyJwcm90b2NvbFZlcnNpb24iOiJFQ3YyIiwic2lnbmVkTWVzc2FnZSI6IntcImVuY3J5cHRlZE1lc3NhZ2VcIjpcInY4bmhGYVJVWmYveERJakhFcnAvOEc2WmdyK2xCcCt2N2cyL0MveXl4UmNhbGcwTElKUmF1NUljblVpYnZMMUh1UkdETTV2dVNYQUNxUG0yaSt3cFBBL0lrSzZvWko4WlNVdFFEcXc1K0RPY002a2ZJYy9jeUVtdmpXTWhVTkdDZkJ2dUF5RU0xeGk3dzU4MjNoVmhQemVUSk12K2YyYjZwQTAvZGZRZkpSWURjRVp1bjFWWGFFalRDdWFRcUVlV0x6RW81MDlBd25nOFJjYmFRelNzQXcwd0U4dUZsVDliRlY3cVc5N2svS3RuYTluYUdHR29UdmVaS3lKdDF4SmQ0NkhTRlkyNkN4WmxLRkppaGFLN2d4OW94RGVqVEE2VGtHL2tDd05keUZUQk4wSGY3ZEZUaUpEVkRiUklZOUtlalpkRXJwWnlQbHFES1luMWJSRytPSldWNGszWVhldmp6QWZoTmpzMWZyQ0dpTE5GeUtWa1RMRFl1enhOQWZobkQvZHpINVkyYkZUSnRqYmhOUFpNL3VmdmJMWjNTN1dKOVpuWFkxS2dyRlpNRFBzQkRjb3hjZE1nVmtMcVptQjVSNFZhUndDdm96M2JtcDhUd2tiVG5Vb2lndE5hQ29pclJ2TT1cIixcImVwaGVtZXJhbFB1YmxpY0tleVwiOlwiQk9IcXNPME55Z3NNQThFcHpyaGIyWTV5SjR0V3hjeU8wUmhJdTMyMmIvc1B0VE5uU3Q4RGlNUlVEZWx1WU5rbUZMcFJoeTg3blVPTTlNbk5KcVBhS3JzPVwiLFwidGFnXCI6XCJySU5Nay9DVjFjQUQzYVgwc2JOOSt2UEdjb1g4RGdzTHE0R0hld2NEMEw4PVwifSIsInNpZ25hdHVyZSI6Ik1FVUNJUUQ4ZkhSWG5kWFVjd2FpczltTW9Hd0QwSm90MlYvby9vOU41cG9JemRTS0V3SWdjdWw5RGhoSVppVGN3N2RrWisxUGtQbDlJZjBwNG1qamg5OVQvVXZZQ0NBPSIsImludGVybWVkaWF0ZVNpZ25pbmdLZXkiOnsic2lnbmVkS2V5Ijoie1wia2V5RXhwaXJhdGlvblwiOlwiMTc0MjgxMDMxNzAwMFwiLFwia2V5VmFsdWVcIjpcIk1Ga3dFd1lIS29aSXpqMENBUVlJS29aSXpqMERBUWNEUWdBRWhtUzhlbWExdEFhQWtHWkVmMERKVllHM0d5T3FNenpxL2lZR3JLZHZGbWlOK2s2cGdOQWNoTzFXRlo1NUFtYzZwL1o4RU5CdlZ3MnRhai9EaDNDNGNnPT1cIn0iLCJzaWduYXR1cmVzIjpbIk1FUUNJQ012Vm9mUVpzVDFQSmZORHR4aHZwS1c4SHRWbFRKYXBwdkVFQjJMbURsdkFpQTBLZElCNVVjNmFsdTlXSmJpSHBGbWRyclFkaHZwZHV2YnlsN1JybGhSQXc9PSJdfX0="
}
curl -i https://sandbox.espago.com/api/charges \
 -H "Accept: application/vnd.espago.v3+json" \
 -u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
 -d "amount=10" \
 -d "currency=pln" \
 -d "channel=elavon_google_pay"\
 -d "description=Espago docs Google Pay"\
  -d "google_pay=eyJwcm90b2NvbFZlcnNpb24iOiJFQ3YyIiwic2lnbmVkTWVzc2FnZSI6IntcImVuY3J5cHRlZE1lc3NhZ2VcIjpcInY4bmhGYVJVWmYveERJakhFcnAvOEc2WmdyK2xCcCt2N2cyL0MveXl4UmNhbGcwTElKUmF1NUljblVpYnZMMUh1UkdETTV2dVNYQUNxUG0yaSt3cFBBL0lrSzZvWko4WlNVdFFEcXc1K0RPY002a2ZJYy9jeUVtdmpXTWhVTkdDZkJ2dUF5RU0xeGk3dzU4MjNoVmhQemVUSk12K2YyYjZwQTAvZGZRZkpSWURjRVp1bjFWWGFFalRDdWFRcUVlV0x6RW81MDlBd25nOFJjYmFRelNzQXcwd0U4dUZsVDliRlY3cVc5N2svS3RuYTluYUdHR29UdmVaS3lKdDF4SmQ0NkhTRlkyNkN4WmxLRkppaGFLN2d4OW94RGVqVEE2VGtHL2tDd05keUZUQk4wSGY3ZEZUaUpEVkRiUklZOUtlalpkRXJwWnlQbHFES1luMWJSRytPSldWNGszWVhldmp6QWZoTmpzMWZyQ0dpTE5GeUtWa1RMRFl1enhOQWZobkQvZHpINVkyYkZUSnRqYmhOUFpNL3VmdmJMWjNTN1dKOVpuWFkxS2dyRlpNRFBzQkRjb3hjZE1nVmtMcVptQjVSNFZhUndDdm96M2JtcDhUd2tiVG5Vb2lndE5hQ29pclJ2TT1cIixcImVwaGVtZXJhbFB1YmxpY0tleVwiOlwiQk9IcXNPME55Z3NNQThFcHpyaGIyWTV5SjR0V3hjeU8wUmhJdTMyMmIvc1B0VE5uU3Q4RGlNUlVEZWx1WU5rbUZMcFJoeTg3blVPTTlNbk5KcVBhS3JzPVwiLFwidGFnXCI6XCJySU5Nay9DVjFjQUQzYVgwc2JOOSt2UEdjb1g4RGdzTHE0R0hld2NEMEw4PVwifSIsInNpZ25hdHVyZSI6Ik1FVUNJUUQ4ZkhSWG5kWFVjd2FpczltTW9Hd0QwSm90MlYvby9vOU41cG9JemRTS0V3SWdjdWw5RGhoSVppVGN3N2RrWisxUGtQbDlJZjBwNG1qamg5OVQvVXZZQ0NBPSIsImludGVybWVkaWF0ZVNpZ25pbmdLZXkiOnsic2lnbmVkS2V5Ijoie1wia2V5RXhwaXJhdGlvblwiOlwiMTc0MjgxMDMxNzAwMFwiLFwia2V5VmFsdWVcIjpcIk1Ga3dFd1lIS29aSXpqMENBUVlJS29aSXpqMERBUWNEUWdBRWhtUzhlbWExdEFhQWtHWkVmMERKVllHM0d5T3FNenpxL2lZR3JLZHZGbWlOK2s2cGdOQWNoTzFXRlo1NUFtYzZwL1o4RU5CdlZ3MnRhai9EaDNDNGNnPT1cIn0iLCJzaWduYXR1cmVzIjpbIk1FUUNJQ012Vm9mUVpzVDFQSmZORHR4aHZwS1c4SHRWbFRKYXBwdkVFQjJMbURsdkFpQTBLZElCNVVjNmFsdTlXSmJpSHBGbWRyclFkaHZwZHV2YnlsN1JybGhSQXc9PSJdfX0="
require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new(user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD')
response = client.send(
  'api/charges',
  method: :post,
  body: {
    amount: 10,
    currency: 'pln',
    channel: 'elavon_google_pay',
    description: 'Espago docs Google Pay',
        google_pay: 'eyJwcm90b2NvbFZlcnNpb24iOiJFQ3YyIiwic2lnbmVkTWVzc2FnZSI6IntcImVuY3J5cHRlZE1lc3NhZ2VcIjpcInY4bmhGYVJVWmYveERJakhFcnAvOEc2WmdyK2xCcCt2N2cyL0MveXl4UmNhbGcwTElKUmF1NUljblVpYnZMMUh1UkdETTV2dVNYQUNxUG0yaSt3cFBBL0lrSzZvWko4WlNVdFFEcXc1K0RPY002a2ZJYy9jeUVtdmpXTWhVTkdDZkJ2dUF5RU0xeGk3dzU4MjNoVmhQemVUSk12K2YyYjZwQTAvZGZRZkpSWURjRVp1bjFWWGFFalRDdWFRcUVlV0x6RW81MDlBd25nOFJjYmFRelNzQXcwd0U4dUZsVDliRlY3cVc5N2svS3RuYTluYUdHR29UdmVaS3lKdDF4SmQ0NkhTRlkyNkN4WmxLRkppaGFLN2d4OW94RGVqVEE2VGtHL2tDd05keUZUQk4wSGY3ZEZUaUpEVkRiUklZOUtlalpkRXJwWnlQbHFES1luMWJSRytPSldWNGszWVhldmp6QWZoTmpzMWZyQ0dpTE5GeUtWa1RMRFl1enhOQWZobkQvZHpINVkyYkZUSnRqYmhOUFpNL3VmdmJMWjNTN1dKOVpuWFkxS2dyRlpNRFBzQkRjb3hjZE1nVmtMcVptQjVSNFZhUndDdm96M2JtcDhUd2tiVG5Vb2lndE5hQ29pclJ2TT1cIixcImVwaGVtZXJhbFB1YmxpY0tleVwiOlwiQk9IcXNPME55Z3NNQThFcHpyaGIyWTV5SjR0V3hjeU8wUmhJdTMyMmIvc1B0VE5uU3Q4RGlNUlVEZWx1WU5rbUZMcFJoeTg3blVPTTlNbk5KcVBhS3JzPVwiLFwidGFnXCI6XCJySU5Nay9DVjFjQUQzYVgwc2JOOSt2UEdjb1g4RGdzTHE0R0hld2NEMEw4PVwifSIsInNpZ25hdHVyZSI6Ik1FVUNJUUQ4ZkhSWG5kWFVjd2FpczltTW9Hd0QwSm90MlYvby9vOU41cG9JemRTS0V3SWdjdWw5RGhoSVppVGN3N2RrWisxUGtQbDlJZjBwNG1qamg5OVQvVXZZQ0NBPSIsImludGVybWVkaWF0ZVNpZ25pbmdLZXkiOnsic2lnbmVkS2V5Ijoie1wia2V5RXhwaXJhdGlvblwiOlwiMTc0MjgxMDMxNzAwMFwiLFwia2V5VmFsdWVcIjpcIk1Ga3dFd1lIS29aSXpqMENBUVlJS29aSXpqMERBUWNEUWdBRWhtUzhlbWExdEFhQWtHWkVmMERKVllHM0d5T3FNenpxL2lZR3JLZHZGbWlOK2s2cGdOQWNoTzFXRlo1NUFtYzZwL1o4RU5CdlZ3MnRhai9EaDNDNGNnPT1cIn0iLCJzaWduYXR1cmVzIjpbIk1FUUNJQ012Vm9mUVpzVDFQSmZORHR4aHZwS1c4SHRWbFRKYXBwdkVFQjJMbURsdkFpQTBLZElCNVVjNmFsdTlXSmJpSHBGbWRyclFkaHZwZHV2YnlsN1JybGhSQXc9PSJdfX0='
  }
)

puts response.body
{
  "id": "pay_8ffCLdBYBSzMk6HJ",
  "description": "Espago docs Google Pay",
  "channel": "elavon_google_pay",
  "amount": "10.00",
  "currency": "pln",
  "state": "executed",
  "client": "cli_8ffe5FGyhZceHb6q",
  "created_at": 1679651962,
  "card": {
    "company": "VI",
    "last4": "0006",
    "year": 2030,
    "month": 1,
    "created_at": 1679651962
  },
  "issuer_response_code": "00",
  "reversable": true,
  "transaction_id": "tr_8ffi3se3t"
}

Więcej na temat odpowiedzi z serwera znajdziesz tutaj.

{
  "id": "pay_8ffaeAEaCyzUY-D-",
  "description": "Espago docs Google Pay",
  "channel": "elavon_google_pay",
  "amount": "10.00",
  "currency": "pln",
  "state": "new",
  "client": "cli_8ffEpSsgrShInvKc",
  "created_at": 1679651893,
  "card": {
    "company": "VI",
    "last4": "0006",
    "year": 2030,
    "month": 1,
    "created_at": 1679651893
  },
  "issuer_response_code": "",
  "transaction_id": "tr_8fftqyPct",
  "redirect_url": "https://sandbox.espago.com/secure_web_page/pay_8ffaeAEaCyzUY-D-"
}

BLIK phonelink_ring

link Wprowadzenie

BLIK to polska platforma płatności mobilnych, która umożliwia wygodne i szybkie dokonywanie płatności w sklepach stacjonarnych i internetowych za pomocą 6-cyfrowego kodu.
Aby skorzystać z BLIK-a, potrzebna jest aplikacja mobilna banku, który obsługuje płatności BLIK.

Płatności BLIK są dostępne jedynie dla waluty PLN.


Istnieją 3 sposoby na wywołanie obciążenia BLIK:
1. Płatnność poprzez samodzielne przesłanie kodu BLIK do bramki Espago.
2. Płatność poprzez stronę eblik.pl
3. Płatność BLIK one-click, po wcześniejszym zarejestrowaniu aliasu one-click.

link Płatność BLIK charge by code

Sprzedawca musi stworzyć w obrębie swojej aplikacji formularz, poprzez który uzyska od płatnika numer BLIK - następnie przekazać go do bramki Espago poprzez żądanie typu POST na adres /api/charges.
Po wysłaniu żądania płatnikowi wyświetlana jest prośba o potwierdzenie transakcji BLIK w jego aplikacji bankowej, a płatność przechodzi w stan blik_decision.
Odpowiedź z ostatecznym stanem płatności jest wysyłana poprzez Back Request.


Rozpoczęcie nowego obciążenia następuje w wyniku wysłania żądania typu POST na adres https://sandbox.espago.com/api/charges Transakcje BLIK muszą zostać przeprowadzone kanałem płatności p24_blik

Dla płatności BLIK charge by code konieczne jest przesłanie parametru p24_regulation_accepted o wartości równej true, gdyż w tym przypadku płatnik zostanie przeniesiony bezpośrednio do banku.

Parametr Opis Format Obligatoryjność
channel Należy przekazać wartość p24_blik lub elavon_blik String Obowiązkowy
blik_code Kod BLIK (T6) wygenerowany w aplikacji bankowej płacącego String (6 znaków) Obowiązkowy w przypadku podania parametru alias_type
alias_type Przekazywany w momencie chęci utworzenia aliasu one-click String, dozwolone wartości: one_click Nieobowiązkowy
client ID Profilu Klienta (utworzony alias blik zostanie przypisany do Profilu Klienta) String Nieobowiązkowy
email E-mail osoby płacącej String Obowiązkowy (chyba, że przekazano parametr client z id klienta, który ma przypisany adres email)
return_url Adres, na który zostanie przekierowany klient po transakcji String Nieobowiązkowy, jeśli zawarto parametr blik_code. Obowiązkowy dla płatności eblik.pl
locale Język transakcji String, kod języku według standardu ISO 639-1. Dostępne wartości: bg, cs, de, en, es, fr, hr, hu, it, nl, pl, pt, se, sk. Nieobowiązkowy
p24_regulation_accepted Akceptacja regulaminu Przelewy24. Określa, czy płatnikowi zostanie wyświetlona zgoda po przekierowaniu na stronę P24. Domyśla wartość false - wyświetl . Boolean Nieobowiązkowy

W przypadku wysyłania wartości true dla parametru p24_regulation_accepted, na stronie Partnera musi znaleźć się zgoda o treści: „Oświadczam, że zapoznałem się z regulaminem i obowiązkiem informacyjnym serwisu Przelewy24”.
Pod słowami regulamin i obowiązek informacyjny musi być link do stron z tymi dokumentami. Checkbox nie może być odgórnie zaznaczony.

{
  "channel": "p24_blik",
  "blik_code": "777100",
  "amount": 10,
  "currency": "PLN",
  "description": "Espago docs P24 BLIK",
  "email": "example@example.com"
}
curl -i https://sandbox.espago.com/api/charges \
 -H "Accept: application/vnd.espago.v3+json" \
 -u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
 -d "channel=p24_blik" \
 -d "blik_code=777100" \
 -d "amount=10" \
 -d "currency=PLN" \
 -d "description=Espago docs P24 BLIK" \
 -d "email=example@example.com" \
require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param method_name [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new(user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD')
response = client.send(
  "api/charges",
  method: :post,
  body: {
    channel: 'p24_blik',
    blik_code: '777100',
    amount: 10,
    currency: 'PLN',
    description: 'Espago docs P24 BLIK',
    email: 'example@example.com'
  }
)

puts response.body
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/charges');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "channel=p24_blik&blik_code=7771000&amount=10&currency=PLN&description=Espago docs P24 Blik&email=example@example.com");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close ($ch);
{
  "id":"pay_901X97fmqW7-ZQqo",
  "description":"Espago docs P24 Blik",
  "channel":"p24_blik",
  "amount":"10.00",
  "currency":"PLN",
  "state":"blik_decision",
  "email":"example@example.com",
  "created_at":1684166626,
  "transaction_id":"p24_901E5Jsu2IlhzNE2"
}

link Płatność poprzez stronę eblik.pl

W przypadku niepodania parametru blik_code zostanie zwrócony stan płatności new oraz link do przekierowania na stronę eblik w której płatnik może podać kod BLIK. Opcja nie jest dostępna w przypadku tworzenia aliasu one_click . Po poprawnym przekierowaniu płatność przechodzi w stan blik_redirected.

Odpowiedź z ostatecznym stanem płatności jest wysyłana poprzez Back Request.

{
  "channel": "p24_blik",
  "amount": 10,
  "currency": "PLN",
  "description": "Espago docs P24 BLIK",
  "return_url": "https://espago.com",
  "email": "example@example.com"
}
curl -i https://sandbox.espago.com/api/charges \
 -H "Accept: application/vnd.espago.v3+json" \
 -u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
 -d "channel=p24_blik" \
 -d "amount=10" \
 -d "currency=PLN" \
 -d "description=Espago docs P24 BLIK" \
 -d "return_url=https://espago.com" \
 -d "email=example@example.com"
require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param method_name [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new(user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD')
response = client.send(
  "api/charges",
  method: :post,
  body: {
    channel: 'p24_blik',
    amount: 10,
    currency: 'PLN',
    description: 'Espago docs P24 BLIK',
    return_url: 'https://espago.com',
    email: 'example@example.com'
  }
)

puts response.body
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/charges');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "channel=p24_blik&amount=10&currency=PLN&description=Espago docs P24 Blik&return_url=https://espago.com&email=example@example.com");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close ($ch);
{
  "id":"pay_901oh54m1sFgJfHj",
  "description":"Espago docs P24 Blik",
  "channel":"p24_blik",
  "amount":"10.00",
  "currency":"PLN",
  "state":"new",
  "email":"example@example.com",
  "created_at": 1684166942,
  "transaction_id": "p24_901GMO87ibiWf8KZ",
  "redirect_url":"https://sandbox.espago.com/p24_eblik/pay_901oh54m1sFgJfHj"
}

link BLIK one-click

Płatności one-click pozwalają na dokonanie zakupu bez konieczności przepisywania kodu BLIK, jedynie poprzez potwierdzenie płatności, w aplikacji moblinej.


Rejestracja aliasu BLIK one-click następuje po zainicjowaniu obciążenia dla kanału p24_blik,
wykorzystując parametr alias_type=one_click.

Żądanie rejestracji aliasu zostanie przekazane do systemu BLIK, a klient otrzyma zaproszenie, w swojej aplikacji bankowej, do płatności bez kodu BLIK w sklepie Sprzedawcy.
Jeśli decyzja klienta będzie pozytywna alias zostanie zarejstrowany w systemie BLIK, a klient nie będzie proszony o kod BLIK podczas przyszłych płatności.

W zależności od wykorzystania Profilu Klienta w zapytaniu do API, możliwe są 3 scenariusze rejestracji aliasu one-click.

Profil klienta Rezultat
Nie Płatność jednorazowa oraz utworzenie Profilu Klienta z aliasem one-click, jeśli decyzja klienta będzie pozytywna.
Tak (bez aktywnego aliasu) Płatność jednorazowa oraz dodanie aliasu do Profilu Klienta, jeśli decyzja klienta będzie pozytywna.
Tak (z aktywnym aliasem) Płatność jednorazowa oraz rejestracja kolejnej aplikacji bankowej dla aliasu.


{
  "channel": "p24_blik",
  "blik_code": "777101",
  "amount": 21.04,
  "currency": "PLN",
  "description": "Espago docs P24 BLIK",
  "email": "example@example.com",
  "alias_type": "one_click"
}
curl -i https://sandbox.espago.com/api/charges \
 -H "Accept: application/vnd.espago.v3+json" \
 -u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
 -d "channel=p24_blik" \
 -d "blik_code=777101" \
 -d "amount=21.04" \
 -d "currency=PLN" \
 -d "description=Espago docs P24 BLIK" \
 -d "email=example@example.com"
 -d "alias_type=one_click"
require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param method_name [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new(user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD')
response = client.send(
  "api/charges",
  method: :post,
  body: {
    channel: 'p24_blik',
    blik_code: '777101',
    amount: 21.04,
    currency: 'PLN',
    description: 'Espago docs P24 BLIK',
    email: 'example@example.com',
    alias_type: 'one_click'
  }
)

puts response.body
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/charges');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "channel=p24_blik&blik_code=777101&amount=21.04&currency=PLN&description=Espago docs P24 Blik&email=example@example.com&alias_type=one_click");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close ($ch);
{
  "id":"pay_901D3j3SglzRigHQ",
  "description":"Espago docs P24 Blik",
  "channel":"p24_blik",
  "amount":"21.04",
  "currency":"PLN",
  "state":"blik_decision",
  "email":"example@example.com",
  "created_at":1684166626,
  "transaction_id":"p24_901E5maO86lhzNE2",
  "client":"cli_9015q7ioPP2EllAO"
}

Rozpoczęcie nowego obciążenia dla aliasu one-click następuje w wyniku wysłania żądania typu POST na adres https://sandbox.espago.com/api/charges Transakcje one-click muszą zostać przeprowadzone kanałem płatności p24_blik_alias


Dla płatności BLIK one-click alias, konieczne jest przesłanie parametru p24_regulation_accepted o wartości równej true, gdyż w tym przypadku płatnik zostanie przeniesiony bezpośrednio do banku.

Parametr Opis Format Obligatoryjność
channel Należy przekazać wartość p24_blik_alias String Obowiązkowy
alias_type Wskazuje, który typ aliasu ma zostać użyty String, dozwolone wartości: one_click Obowiązkowy
client Id profilu klienta String Obowiązkowy
email E-mail osoby płacącej String Obowiązkowy (chyba, że przekazano w parametrze client id klienta, który ma przypisany adres email)
locale Język transakcji String, kod języka według standardu ISO 639-1. Dostępne wartości: bg, cs, de, en, es, fr, hr, hu, it, nl, pl, pt, se, sk. Nieobowiązkowy
p24_regulation_accepted Akceptacja regulaminu Przelewy24. Określa, czy płatnikowi zostanie wyświetlona zgoda po przekierowaniu na stronę P24. Domyśla wartość false - wyświetl . Boolean Obowiązkowy

W przypadku wysyłania wartości true dla parametru p24_regulation_accepted, na stronie Partnera musi znaleźć się zgoda o treści: „Oświadczam, że zapoznałem się z regulaminem i obowiązkiem informacyjnym serwisu Przelewy24”.
Pod słowami regulamin i obowiązek informacyjny musi być link do stron z tymi dokumentami. Checkbox nie może być odgórnie zaznaczony.


{
  "channel": "p24_blik_alias",
  "alias_type": "one_click",
  "amount": 10,
  "currency": "PLN",
  "description": "Espago docs P24 BLIK",
  "client": "cli_8a2lAMfJiJRblhYR"
}
curl -i https://sandbox.espago.com/api/charges \
 -H "Accept: application/vnd.espago.v3+json" \
 -u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
 -d "channel=p24_blik_alias" \
 -d "alias_type=one_click" \
 -d "amount=10" \
 -d "currency=PLN" \
 -d "description=Espago docs P24 BLIK" \
 -d "client=cli_8a2lAMfJiJRblhYR"
require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param method_name [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new(user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD')
response = client.send(
  "api/charges",
  method: :post,
  body: {
    channel: 'p24_blik_alias',
    alias_type: 'one_click',
    amount: 10,
    currency: 'PLN',
    description: 'Espago docs P24 BLIK',
    client: 'cli_8a2lAMfJiJRblhYR'
  }
)

puts response.body
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/charges');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "channel=p24_blik_alias&alias_type=one_click&amount=10&currency=PLN&description=Espago docs P24 Blik&client=cli_8a2lAMfJiJRblhYR");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close ($ch);
{
  "id":"pay_9011PZTylAm-JEsM",
  "description":"Espago docs P24 Blik",
  "channel":"p24_blik_alias",
  "amount":"10.00",
  "currency":"PLN",
  "state":"blik_decision",
  "email":"example@example.com",
  "created_at":1684166626,
  "transaction_id":"p24_901E1z-JffNa-F4098",
  "client":"cli_8a2lAMfJiJRblhYR"
}

Profil Klienta może mieć zarejestrowany jeden aktywny alias one-click. Na jeden alias one-click może być zarejestrowanych wiele aplikacji bankowych płatnika. Po zarejestrowaniu drugiej aplikacji bankowej, API Espago będzie zwracać w odpowiedzi na request api/charges na kanale p24_blik_alias (dla danego Profilu Klienta) płatność ze statusem new oraz listę dostępnych aplikacji do wyboru:

"alternative_keys": [
    {
        "label": "TEST APP 032",
        "alias": "617987"
    },
    {
        "label": "TEST APP 028",
        "alias": "617986"
    }
]

Należy dokończyć płatność wysyłając zapytanie typu POST na endpoint api/charges/(:id)/blik_app_decision,
odsyłając w body parametr alias. Na przykład:

POST /api/charges/pay_8a1UC6bjMbhsBbYH/blik_app_decision

{
    "alias": "617987"
}

Aliasy te są zmienne i zbędne jest zapisywanie ich w celu późniejszych użyć.

{
  "alias": "617987"
}
curl -i https://sandbox.espago.com/api/charges/pay_8a1UC6bjMbhsBbYH/blik_app_decision \
 -H "Accept: application/vnd.espago.v3+json" \
 -u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
 -d "alias=617987"
require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param method_name [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new(user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD')
response = client.send(
  "api/charges",
  method: :post,
  body: {
    alias: '617987'
  }
)

puts response.body
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/charges');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "alias=617987");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close ($ch);
{
  "id":"pay_9011PZTylAm-JEsM",
  "description":"Espago docs P24 Blik",
  "channel":"p24_blik_alias",
  "amount":"10.00",
  "currency":"PLN",
  "state":"blik_decision",
  "email":"example@example.com",
  "created_at":1684166626,
  "transaction_id":"p24_901E1z-JffNa-F4098",
  "client":"cli_8a2lAMfJiJRblhYR"
}

Aby zobaczyć przypisane Aliasy BLIK do profilu klienta należy wykorzystać metodę pobierania danych profilu klienta.
Alias BLIK one-click widoczny jest jako parametr p24_blik_alias_one_click.

Przykładowe dane Profilu Klienta z zarejestrowanym aliasem one-click.

{
    "email": "example@example.com",
    "id": "cli_8a2lAMfJiJRblhYR",
    "created_at": 1665433136,
    "description":"Client with a BLIK alias",
    "card": {
        "company":"VI",
        "last4":"4242",
        "year":2022,
        "month":2,
        "first_name":"Jan",
        "last_name":"Kowalski",
        "authorized":true,
        "created_at":1561126879
    },
    "p24_blik_alias_one_click": {
        "kind": "one_click",
        "state": "registered",
        "email": "example@example.com",
        "expiration_date": 1728476779,
        "value": "27c798a90f9fbbb546c5c5cda71bacb87c8ee5a644c2f9ab384c5336ad50"
    },
    "deleted": false
}

Jeśli płatnik nie zaakceptuje rejestracji aliasu one-click, do jego profilu klienta zostanie przypisany nieaktywny alias ("state": "unregistered").

link Płatności testowe

Płatności BLIK w środowisku Sandbox są potwierdzane automatycznie. Odpowiedź z ostatecznym stanem płatności jest wysyłana poprzez Back Requestem, tak jak w przypadku środowiska produkcyjnego.

Kody do poprawnego procesowania płatności BLIK należy tworzyć wg wzoru 777xxx -
gdzie x oznaczaja dowolną cyfrę.
Kody BLIK są jednorazowe- należy je zmieniać dla kolejnych prób obciążenia testowego.


Środowisko sandbox zwróci konkretny kod błędu, gdy wykona się transakcję BLIK’iem odpowiednią kwotą:
- 288.00 — ALIAS_DECLINED
- 192.00 — TAS_DECLINED
- 144.00 — USER_DECLINED
- 216.00 — SEC_DECLINED
- 264.00 — SYSTEM_ERROR
- 360.00 — GENERAL_ERROR
- 120.00 — INSUFFICIENT_FUNDS
- 312.00 — TIMEOUT
- 96.00 — LIMIT_EXCEEDED
- 336.00 — USER_TIMEOUT
- 168.00 — ISSUER_DECLINED

W środowisku sandbox można potwierdzić alias one-click (status REGISTERED) poprzez rejestrację transakcji blikowej na kwotę kończącą się na 4 grosze, np. 21.04 PLN.

Zmiana statusu aliasu BLIK one-click na - UNREGISTERED, kwota płatności musi się kończyć na 33 grosze, np. 37.33 PLN.

Szybkie Przelewy account_balance

link Jak zlecać przelewy

Istnieje możliwość wykonania płatności przelewem bankowym, poprzez platformę Przelewy24. Aby rozpocząć płatność należy wysłać żądanie typu POST na adres /api/charges . W odpowiedzi zostanie zwrócony parametr redirect_url zawierający URL do przekierowania klienta do strony płatności Przelewy24. Po przekierowaniu płatność przejdzie w stan transfer_redirected. Ostateczny stan płatności zostanie wysłany asynchronicznie poprzez back request.

Rozpoczęcie nowego obciążenia następuje w wyniku wysłania żądania typu POST na adres https://sandbox.espago.com/api/charges Transakcje przelewowe muszą zostać przeprowadzone kanałem płatności p24_transfer

{
  "channel": "p24_transfer",
  "amount": 10,
  "currency": "PLN",
  "description": "Espago docs P24 Transfer",
  "email": "example@example.com",
  "return_url": "https://espago.com",
  "p24_regulation_accepted": true
}
curl -i https://sandbox.espago.com/api/charges \
 -H "Accept: application/vnd.espago.v3+json" \
 -u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
 -d "channel=p24_transfer" \
 -d "amount=10" \
 -d "currency=PLN" \
 -d "description=Espago docs P24 Transfer" \
 -d "email=example@example.com" \
 -d "return_url=https://espago.com" \
 -d "p24_regulation_accepted=true"
require 'net/http'
require 'uri'
require 'json'

class EspagoClient
  # @param user [String]
  # @param password [String]
  def initialize(user:, password:)
    @user = user
    @password = password
  end

  # @param path [String]
  # @param body [Hash, nil]
  # @param method [Symbol]
  # @return [Net::HTTPResponse]
  def send(path, body: nil, method: :get)
    uri = URI.join('https://sandbox.espago.com', path)
    request = request_class(method).new(uri)
    request.basic_auth(@user, @password)
    request['Accept'] = 'application/vnd.espago.v3+json'
    request['Content-Type'] = 'application/json'
    request.body = body.to_json if body

    Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end
  end

  private

  # @param method_name [Symbol]
  # @return [Class<Net::HTTPRequest>]
  def request_class(method_name)
    Net::HTTP.const_get(method_name.to_s.capitalize)
  end
end

client = EspagoClient.new(user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD')
response = client.send(
  "api/charges",
  method: :post,
  body: {
    channel: 'p24_transfer',
    amount: 10,
    currency: 'PLN',
    description: 'Espago docs P24 Transfer',
    email: 'example@example.com',
    return_url: 'https://espago.com',
    p24_regulation_accepted: true
  }
)

puts response.body
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/charges');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "channel=p24_transfer&amount=10&currency=PLN&description=Espago docs P24 Transfer&return_url=https://espago.com&email=example@example.com");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close ($ch);
{
  "id":"pay_901oh54m1sFgJfHj",
  "description":"Espago docs P24 Transfer",
  "channel":"p24_transfer",
  "amount":"10.00",
  "currency":"PLN",
  "state":"new",
  "email":"example@example.com",
  "created_at": 1684166942,
  "transaction_id": "p24_902rCZV7MGssIo61",
  "redirect_url":"https://sandbox.espago.com/payment_p24/pay_901oh54m1sFgJfHj"
}

Parametr Opis Format Obligatoryjność
channel Należy przekazać wartość p24_transfer String Obowiązkowy
amount Kwota transakcji Liczba dziesiętna, do 2 cyfr po przecinku. Przykładowo: 123.45. Obowiązkowy
description Opis transakcji String, od 5 do 99 znaków. Obowiązkowy
email E-mail osoby płacącej String Obowiązkowy (chyba, że przekazano parametr client z id klienta, który ma przypisany adres email)
return_url Adres, na który zostanie przekierowany klient po transakcji String Obowiązkowy
locale Język transakcji String, kod języka według standardu ISO 639-1. Dostępne wartości: bg, cs, de, en, es, fr, hr, hu, it, nl, pl, pt, se, sk. Nieobowiązkowy
p24_regulation_accepted Akceptacja regulaminu Przelewy24. Określa, czy płatnikowi zostanie wyświetlona zgoda po przekierowaniu na stronę P24. Domyśla wartość false - wyświetl . Boolean Nieobowiązkowy

W przypadku wysyłania wartości true dla parametru p24_regulation_accepted, na stronie Partnera musi znaleźć się zgoda o treści: „Oświadczam, że zapoznałem się z regulaminem i obowiązkiem informacyjnym serwisu Przelewy24”.
Pod słowami regulamin i obowiązek informacyjny musi być link do stron z tymi dokumentami. Checkbox nie może być odgórnie zaznaczony.

Apple Pay credit_card

link Strona hostowanych płatności

Apple Pay może być obsługiwany w pełni przez Espago po przekierowaniu klienta na Bezpieczną Stronę Płatności Espago.

Aby włączyć tę funkcjonalność w serwisie Sprzedawcy należy skontakować się z Działem Wsparcia Espago.

Testowe płatności

W środowisku Sandbox kwota transakcij po przecinku określa scenariusz symulowanej płatności.

Kwota po przecinku Scenariusz płatności
n.00 zaakceptowana
n.10 odrzucona
n.20 odrzucona ECI=7

Gdzie n oznacza liczbę naturalną.

link Generator payloadów Apple Pay

Pod tym linkiem znajduje się formularz generujący tokeny Apple Pay do użycia na środowisku sandbox.espago.com.

link Apple Pay w iFrame 3.0

Przycisk Apple Pay może być umieszczony na stronie sprzedawcy na dwa sposoby. Sprzedawca może zaimplementować na swojej stronie EspagoFrame, który wyświetli Secure Web Page z wieloma możliwymi sposobami płatności lub zostanie wyświetlony tylko przycisk Apple Pay na stronie sprzedawcy. Dzięki takiej implementacji, integracja sprzedawcy z Apple Pay jest dużo prostsza.

Onboarding

Żeby móc rozpocząć korzystanie z Apple Pay w iframe, należy przygotować swoją domenę do rejestracji w Apple Pay.

Plik weryfikujący domenę

Dla integracji Apple Pay przez iframe konieczne jest umieszczenie pliku weryfikującego domenę Domain Verification File.

Należy umieścić na swojej domenie pod ścieżką /.well-known/apple-developer-merchantid-domain-association.

Przykładowo, jeśli nasza domena to my_domain.com to plik powinien być dostępny do pobrania po żądaniu GET na adres https://my_domain.com/.well-known/apple-developer-merchantid-domain-association.

Pliki weryfikujące domenę dla środowiska sandbox i production są dostępne w sekcji Do pobrania.

Rejestracja domeny

Po udostępnieniu pliku weryfikacji domeny pod odpowiednią ścieżką należy skontaktować z działem wsparcia Espago, aby przeprowadzili rejestrację domeny w Apple Pay.

link Implementacja Apple Pay w iFrame v3.0

Kiedy zostanie zakończony proces onboardingu, sprzedawca może zaimplementować EspagoFrame zgodnie z dokumentacją Iframe v
3.0. Kiedy klient posiada portfel ApplePay z zapisaną kartą oraz korzysta z przeglądarki Safari, w EspagoFrame wyświetli mu się dodatkowy przycisk płatności za pomocą Apple Pay.

Po autoryzacji płatności za pomocą Apple Pay odpowiedź z iframe jest taka sama, jak w przypadku płatności kartą (zwracany jest status płatności i jej id). 

Więcej o implementacji iFrame 3.0 znajdziesz tutaj.

link Implementacja przycisku Apple Pay na stronie sprzedawcy

Aby na swojej stronie wyświetlić tylko przycisk ApplePay, bez konieczności wyświetlania innych metod płatności wewnątrz iframe, należy wywołać EspagoFrame w zmodyfikowany sposób.

1. Umiejscowienie elementu HTML dla przycisku Apple Pay

W kodzie strony należy przygotować element z wybranym ID, które w dalszym procesie integracji zostanei przekazany do metody open(). To w nim EspagoFrame wyświetli iframe, który będzie zawierał przycisk Apple Pay.
<body>
.
.
.
<div id="apple-pay-button"></div>
.
.
.
</body>

2. Implementacja zmodyfikowanego kodu z dokumentacji Iframe v3.0

Należy dodać kod analogicznie do implementacji iFrame 3.0, z tą różnicą, że zamiast wywołania metody open() po naciśnięciu przycisku „Zapłać”, należy wywołać ją bezpośrednio po metodzie init() z dodatkowymi parametrami kind: "applePayButton" oraz element:
 <script src="https://js.espago.com/espago-frame.js"></script>
 <script lang="text/javascript">
    const onPaymentResult = function (result) {
      console.log(`Transakcja ${result.payment_id} zakończona ze statusem: ${result.state}`);
    };
    const onError = function (errorMessage) {
     console.log("Coś poszło nie tak: " + errorMessage);
    };
    const onClose = function () {
     console.log("Modal closed.");
    };
    const espagoFrame = new EspagoFrame({
     key: "merchantPublicKey123",
     env: "sandbox",
     payment: "pay_123123123",
     token: "aa111a11-111-1aa1-aa11-a11aaa111111"
    })
    espagoFrame.init().then(() => {
     espagoFrame.open({
         kind: „applePayButton”,
         element: „apple-pay-button”
         onPaymentResult: onPaymentResult,
         onError: onError,
         onClose: onClose
     });
    });
</script>

3. Klient dokonuje płatności za pomocą Apple Pay

Kiedy klient posiada portfel ApplePay z zapisaną kartą oraz korzysta z przeglądarki Safari, w miejscu gdzie w kodzie strony jest wskazany w pierwszym kroku element, zostanie wyświetlony przycisk ApplePay wewnątrz EspagoFrame. Po naciśnięciu go i przejściu przez proces autoryzacji płatności za pomocą Apple Pay odpowiedź z iframe jest taka sama, jak w przypadku płatności kartą (zwracany jest status płatności i jej id).

4. Odpowiedź - informacja dla klienta

Sprzedawca postępuje tak samo, jak w przypadku integracji z czystym iframe 3.0. - musi wysłać zapytanie do Espago o pełną informację dot. statusu płatności, aby następnie odpowiednio obsłużyć proces podsumowania płatności na stronie.
Witamy na Espago docs!

W ramach naszej witryny stosujemy pliki cookies w celu świadczenia Państwu usług na najwyższym poziomie. Jeśli nie wyrażasz zgody, ustawienia dotyczące plików cookies możesz zmienić w swojej przeglądarce.

Zespół Espago