1. Wprowadzenie

Dokument zawiera informacje na temat RESTful API bramki płatności imoje.

2. Statusy transakcji

Status Opis
new Nowa, nieobsłużona transakcja
authorized Autoryzacja transakcji
pending Oczekiwanie na status
submitted Wysłana do realizacji
rejected Transakcja odrzucona
settled Transakcja zrealizowana
error Błąd w transakcji
canceled Transakcja anulowana

3. Metody autoryzacji

Bramka pozwala na autoryzację metodą Basic Auth lub metodą OAuth. Zalecaną metodą jest autoryzacja OAuth.

3.1. Basic Auth

Aby dokonać autoryzacji za pomocą metody Basic Auth w żądaniu do serwera należy w nagłówkach zapytania umieścić dane autoryzacyjne (login i hasło):

Accept: application/json
Content-Type: application/json
Authorization: Basic
Y2YzzjRjZ2ctM2I3NC00ZGEaLWIwNzAtMjlkYjRhZjM1ZjVhqjM5M2RkZDBkLTBlZWItNDYxNC02Z1ExLTAxMz
B9NjEzZTI2NQ==

Kody odpowiedzi:

Kod HTTP Znaczenie
200 Autoryzacja poprawna
401 Nieautoryzowany dostęp, żądanie zasobu, który wymaga uwierzytelnienia
500 Błąd serwera

3.2. OAuth

Aby dokonać autoryzacji za pomocą metody OAuth należy w nagłówkach żądania do serwera umieścić dane autoryzacyjne:

Accept: application/json
Content-Type: application/json
Authorization: Bearer ad8y3hdoashco8fh49fhiahfb237f8hoihsd0f2hfikljf023h8

Kody odpowiedzi HTTP:

Kod HTTP Znaczenie
200 Autoryzacja poprawna
401 Nieautoryzowany dostęp, żądanie zasobu, który wymaga uwierzytelnienia
500 Błąd serwera

Do góry

4. Metody RESTful API

Base URL: https://api.imoje.pl/v1/merchant

Każdy poprawny adres składa się z trzech części:

  • adresu bazowego zapytania (https://api.imoje.pl/v1),
  • identyfikatora akceptanta (/merchant/{identyfikator akceptanta}),
  • funkcji jednoznacznie określającej zakres danych, których dotyczy zapytanie ( np. /transaction lub /services).

Każde zapytanie do serwera powinno zawierać dane autoryzacyjne w nagłówkach (Basic Auth lub OAuth).

Endpoint Zastosowanie Metody
/{merchantId}/transaction Tworzenie nowej transakcji POST
/{merchantId}/transaction/{transactionId} Pobieranie danych transakcji GET
/{merchantId}/services Zwraca informacje o usługach akceptanta GET
/{merchantId}/services/{serviceId} Zwraca informacje o usłudze akceptanta o określonym serviceId oraz możliwych metodach płatności. GET
/{merchantId}/settings/ips Pobierz zaufane adresy IP GET
/{merchantId}/settings/ips Ustaw zaufane adresy IP PUT
/{merchantId}/stats/transactions/count Zwraca liczbę wszystkich transakcji GET
/{merchantId}/stats/transactions/count/
{serviceId}
Zwraca liczbę wszystkich transakcji usługi określonej przez serviceId GET
/{merchantId}/stats/transactions/states Zwraca liczbę transakcji grupowane po statusach transakcji GET
/{merchantId}/stats/transactions/states/
{serviceId}
Zwraca liczbę transakcji transakcji usługi określonej przez serviceId GET

gdzie:

  • merchantId – identyfikator akceptanta w systemie
  • accessToken – token autoryzacyjny,
  • serviceId – identyfikator sklepu z którym związane są określone metody realizacji transakcji (UUID v4),
  • state – status transakcji,
  • cid – identyfikator klienta/płatnika nadany przez akceptanta,
  • transactionId – unikalny identyfikator transakcji (UUID v4).

Do góry

5. Tworzenie nowej transakcji przez API

W celu utworzenia nowego zamówienia należy za pomocą metody POST przesłać komunikat na endpoint API https://api.imoje.pl/v1/merchant/{merchantId}/transaction zawierający informacje o nowym zamówieniu.

5.1. HTTP Request dla płatności PBL

Przykładowy adres na który należy wysłać żądanie POST

https://api.imoje.pl/v1/merchant/6yt3gjtm9p7b8h9xsdqz/transaction

Nagłówki zapytania

Accept: application/json
Authorization: Basic sMkJhaYusOksa87Hbagt+8salsnsJjayPmznx
Content-Length: 895
Content-Type: application/json

Payload zapytania

{
 "type": "sale",
 "serviceId": "62f574ed-d4ad-4a7e-9981-89ed7284aaba",
 "amount": 100,
 "currency": "PLN",
 "title": "",
 "orderId": "123123123",
 "paymentMethod": "ing",
 "paymentMethodCode": "ing",
 "successReturnUrl": "https://domain.com/success",
 "failureReturnUrl": "https://domain.com/failure",
 "customer": {
   "firstName": "Jan",
   "lastName": "Kowalski",
   "cid": "123",
   "company": "",
   "phone": "",
   "email": "jan.kowalski@example.com"
  },
 "billing": {
   "firstName": "Jan",
   "lastName": "Kowalski",
   "company": "Company",
   "street": "Street",
   "city": "City",
   "region": "Region",
   "postalCode": "",
   "countryCodeAlpha2": "PL"
  },
 "shipping": {
   "firstName": "Jan",
   "lastName": "Kowalski",
   "company": "Company",
   "street": "Street",
   "city": "City",
   "region": "Region",
   "postalCode": "",
   "countryCodeAlpha2": "PL"
  }
}

Parametry payload

Parametr Typ Parametr wymagany Opis
type string WYMAGANE Typ transakcji. Dopuszczalne wartości: sale, refund.
serviceId string(36) WYMAGANE Identyfikator usługi akceptanta jako UUID v4.
amount integer WYMAGANE Kwota transakcji w najmniejszej jednostce waluty np. grosze.
currency string(3) WYMAGANE Waluta transakcji.
orderID string(100) WYMAGANE Numer zamówienia akceptanta.
title string(255) NIE Tytuł zamówienia.
paymentMethod string WYMAGANE Metoda realizacji zamówienia. Dopuszczalne są wartości: pbl, card, blik, ing, twisto.
paymentMethodCode string WYMAGANE Oznaczenie kanału płatności. Szczegóły opisane są w punkcie 5.2.
successReturnUrl string(300) WYMAGANE Adres powrotu z zewnętrznej strony obsługującej płatność w przypadku dokonania płatności z powodzeniem.
failureReturnUrl string(300) WYMAGANE Adres powrotu z zewnętrznej strony obsługującej płatność w przypadku wystąpienia błędu płatności.
customer object WYMAGANE Dane klienta.
billing object NIE Dane płatnika.
shipping object NIE Dane dot. dostawy.

Jeżeli w zapytaniu wystąpi parametr customer, billing, lub shipping konieczne jest dostarczenie parametrów:

customer

Parametr Typ Parametr wymagany Opis
firstName string(100) WYMAGANE Imię klienta.
lastName string(100) WYMAGANE Nazwisko klienta.
cid string(100) NIE Identyfikator klienta.
company string(200) NIE Nazwa firmy.
phone string(20) NIE Numer telefonu.
email string(200) WYMAGANE Adres email.

billing

Parametr Typ Parametr wymagany Opis
firstName string(100) WYMAGANE Imię klienta.
lastName string(100) WYMAGANE Nazwisko klienta.
company string(200) NIE Nazwa firmy.
street string(200) NIE Ulica.
city string(100) NIE Miasto.
region string(100) NIE  
postalCode string(30) NIE Kod pocztowy.
countryCodeAlpha2 string(20) NIE Kod kraju Alpha2.

shipping

Parametr Typ Parametr wymagany Opis
firstName string(100) WYMAGANE Imię klienta.
lastName string(100) WYMAGANE Nazwisko klienta.
company string(200) NIE Nazwa firmy.
street string(200) NIE Ulica.
city string(100) NIE Miasto.
region string(100) NIE  
postalCode string(30) NIE Kod pocztowy.
countryCodeAlpha2 string(2) NIE Kod kraju Alpha2.

5.2. Metody i kanały realizacji transakcji

Transakcje można realizować następującymi metodami:

Nazwa Wartość parametru paymentMethod Wartość parametru paymentMethodCode
Przelewy online. pbl Tabela poniżej (punkt 5.2.1)
Płatność kart. card ecom3ds
Płatność BLIK. blik blik
Płać z ING. ing ing
Płatność Twisto. twisto twisto

5.2.1. Przelew online Pay By Link

Przelewy Pay By Link można realizować za pomocą następujących usług banków:

Wartość parametru Nazwa usługi
neo NeoBank
mtransfer mTransfer - mBank
bzwbk BZWBK - Przelew24
pekao24 Pekao24Przelew - Bank Pekao
inteligo Płacę z Inteligo
ipko Płać z iPKO
getin Płacę z Getin Bank
noble Płacę z Noble Bank
ideabank Płacę z Idea Bank - IdeaBank
creditagricole Credit Agricole e-przelew
tmobile Płacę z T-mobile Usługi Bankowe dostarczane przez Alior Bank
eurobank Płacę z Eurobankiem
alior Płacę z Alior Bankiem
pbs Płacę z PBS
millennium Millennium - płatności internetowe
deutchebank db Transfer
raiffeisenpolbank R-Przelew
citi Przelew z Citi Handlowego
bos Płać z BOŚ
bnpparibas Płacę z BGŻ BNP Paribas
orange Płacę z Orange
pocztowy Pocztowy24
plusbank Płacę z Plus Bank
bs Bank Spółdzielczy
bspb Bank Spółdzielczy w Brodnicy
nest nestPrzelew
envelo Envelo Bank

5.3. HTTP Response

Odpowiedź serwera

W przypadku wykonania poprawnego zapytania rejestrującego nowe zamówienie serwer odpowie statusem HTTP 200 oraz informacją o nowo utworzonej transakcji:

{
 "transaction": {
 "id": "f115d23d-a943-4585-a3d7-09f6c417200d",
 "status": "new",
 "source": "api",
 "created": 1501188304,
 "modified": 1501188304,
 "notificationUrl": "https://notification_url",
 "serviceId": "63f574ed-d4ad-407e-9981-39ed7584a7b7",
 "amount": 100,
 "currency": "PLN",
 "title": "",
 "orderId": "123123123",
 "paymentMethod": "ing",
 "paymentMethodCode": "ing",
 "successReturnUrl": "https://domain.com/success",
 "failureReturnUrl": "https://domain.com/failure",
 "customer": {
   "firstName": "Jan",
   "lastName": "Kowalski",
   "cid": "123",
   "company": "",
   "phone": "",
   "email": "jan.kowalski@example.com"
  },
 "billing": {
   "firstName": "Jan",
   "lastName": "Kowalski",
   "company": "Company",
   "street": "Street",
   "city": "City",
   "region": "Region",
   "postalCode": "",
   "countryCodeAlpha2": "PL"
  },
 "shipping": {
   "firstName": "Jan",
   "lastName": "Kowalski",
   "company": "Company",
   "street": "Street",
   "city": "City",
   "region": "Regino",
   "postalCode": "",
   "countryCodeAlpha2": "PL"
   }
 },
 "action": {
   "type": "redirect",
   "url": "https://eblik.pl/blikweb/transaction/transaction_init/submit",
   "method": "POST",
   "contentType": "application/x-www-form-urlencoded",
   "contentBodyRaw":
"Type=Ipay2&MerchantID=7510&Currency=PLN&Amount=100&CustomParam=z9bfzsr7a&Descriptio
n=z9bfzsr7a%7CTest+transaction%7C%7Cg2a.com%2F&ControlData=2224807C0459BBE508011756
21EF717EE725F428575E40508A46006BC24C7F96"
  }
}

W odpowiedzi otrzymujemy dwa obiekty: transaction oraz action.

Obiekt transaction jest identyczny z wysłanym w zapytaniu rejestrującym zamówienie i zawiera kilka dodatkowych parametrów:

Parametr Typ Opis
id string Identyfikator transakcji w formacie UUID v4. Unikalny dla każdego zamówienia.
status string Status zamówienia.
source string Źródło zamówienia. Może posiadać wartości: api lub web.
created integer Data utworzenia zamówienia w formacie UNIX TIMESTAMP czasu UTC.
modified integer Data ostatniej zmiany statusu transakcji w formacji UNIX TIMESTAMP czasu UTC.

Drugim dodatkowym obiektem jest action. Obiekt ten wystąpi tylko w przypadku konieczności przekierowania płatnika na zewnętrzną stronę jak to ma miejsce w przypadku płatności Pay-By-Link. Obiekt ten zawiera dodatkowe pola których znaczenie jest opisane poniżej:

Parametr Typ Opis
type string Typ akcji.
url string W przypadku konieczności wykonania przekierowania płatnika na inną stronę (np. banku) adres URL.
method string Metoda POST lub GET.
contentType string Pozycja w nagłówku zapytania do banku określająca typ payloadu.
contentBodyRaw string Payload zapytania.

Statusy HTTP

Kod HTTP Znaczenie
200 Zapytanie wykonane poprawnie. Utworzono transakcję.
400 Błędne żądanie, niepoprawny payload żądania.
401 Nieautoryzowany dostęp. Żądanie zasobu, który wymaga uwierzytelnienia.
403 Brak uprawnień do wykonania żądania.
404 Nieznany zasób.
422 Payload jest poprawny ale nie zawiera wymaganaych parametrów.
500 Błąd serwera.
503 System niedostępny.

400

Przyczyny wystąpienia kodu odpowiedzi 400 oraz treść odpowiedzi może być następująca:

  • payload to niepoprawny JSON i nie mógł być przetworzony przez serwer:
{
 "apiErrorResponse": {
   "status": 400,
   "message": "Bad Request"
  }
}

422

  • payload żądania zwiera poprawny string JSON jednak nie zawiera wszystkich wymaganych parametrów:
{
 "apiErrorResponse": {
 "message": "Incorrect Payload",
 "code": "TRX-ERROR-120001",
 "instance": {
   "type": "sale",
   "serviceId": "63f574ed-d4ad-407e-9981-39ed7584a7b7",
   "amount": 0.03,
   "currency": "PLN",
   "title": "",
   "orderId": "123123",
   "paymentMethod": "ing",
   "paymentMethodCode": "ing",
   "customer": {
      "firstName": "",
      "lastName": "",
      "cid": "",
      "company": null,
      "phone": "",
      "email": ""
   }
 },
 "errors": [
   {
      "property": "instance.customer.firstName",
      "message": "does not meet minimum length of 1"
   },
   {
      "property": "instance.customer.lastName",
      "message": "does not meet minimum length of 1"
   },
   {
      "property": "instance.customer.cid",
      "message": "does not match pattern "^[\\w\\s-#.\\\\/]{1,100}$""
   },
   {
      "property": "instance.customer.cid",
      "message": "does not meet minimum length of 1"
      }
    ],
  }
}

gdzie:

  • status – kod HTTP odpowiedzi,
  • message – opis błędu,
  • code – kod błędu walidacji treści żądania,
  • instance – zawiera treść zapytania wysłana do serwera iMoje,
  • errors – zawiera listę błędów, które wystąpiły podczas walidacji treści zapytania.

Do góry

6. Notyfikacje

Aby poprawnie skonfigurować wysyłkę notyfikacji odnośnie transakcji do sklepu, należy wprowadzić url prowadzacy do weryfikacji w panelu administracyjnym imoje (zakładka Sklepy, później należy wybrać sklep w którym wykonywana jest integracja, kliknąć w Szczegóły. W otworzonej stronie przejść do sekcji Dane do integracji i zedytować pole Adres notyfikacji)

W momencie zmiany statusu transakcji serwery imoje wysyłają powiadomienia na wskazany przez akceptanta adres URL. Wymagane jest by serwer akceptanta (np. sklep) odpowiedział statusem 200 OK, który będzie oznaczał poprawne odebranie i przetworzenie notyfikacji przez serwer akceptanta. Notyfikacje wysyłane są w następującym cyklu:

  • 5 razy co 5 minut, następnie,
  • 5 razy co 60 minut, następnie,
  • 5 razy co 180 minut, następnie,
  • 5 razy co 360 minut.

icon

Jeśli notyfikacja nie zostanie odebrana serwery imoje zaprzestają powtórzeń wysyłki notyfikacji.

6.1. Zawartość BODY notyfikacji

Notyfikacje wysyłane są jako obiekt JSON metodą POST i mają następującą postać:

{
 "transaction": {
   "id": "f115d23d-a943-4585-a3d7-09f6c417200d",
   "type": "sale",
   "status": "settled",
   "source": "api",
   "created": 1483381278,
   "modified": 1483382521,
   "notificationUrl": "https://notification_url",
   "serviceId": "63f574ed-d4ad-407e-9981-39ed7584a7b7",
   "amount": 100,
   "currency": "PLN",
   "title": "Tytul",
   "orderId": "123123123",
   "paymentMethod": "ing",
   "paymentMethodCode": "ing",
   "customer": {
      "firstName": "Jan",
      "lastName": "Kowalski",
      "cid": "123",
      "company": "",
      "phone": "",
      "email": "jan.kowalski@example.com"
   },
   "billing": {
      "firstName": "Jan",
      "lastName": "Kowalski",
      "company": "Company",
      "street": "Street",
      "city": "City",
      "region": "Region",
      "postalCode": "",
      "countryCodeAlpha2": "PL"
   },
   "shipping": {
      "firstName": "Jan",
      "lastName": "Kowalski",
      "company": "Company",
      "street": "Street",
      "city": "City",
      "region": "Region",
      "postalCode": "",
      "countryCodeAlpha2": "PL"
    }
  }
}

6.2. Zawartość nagłówków notyfikacji

Dodatkowo w nagłówkach HTTP umieszczane są następujące parametry:

Content-Type: application/json; charset=UTF-8
X-Imoje-Signature: merchantid=6yt3gjtm9p7b8h9xsdqz;serviceid=63f574ed-d4ad-407e-9981-
39ed7584a7b7;signature=5e2ac79f4f02d368cdd6eaee17d2089dec13577c1d6e3364d6fc123c85029
e82;alg=sha256

gdzie:

  • merchantid – identyfikator akceptanta w imoje,
  • service – identyfikator usługi akceptanta w imoje,
  • signature – podpis notyfikacji,
  • alg – algorytm funkcji skrótu (możliwe wartości: sha256).

 

icon

Weryfikacja podpisu notyfikacji jest krytycznym elementem uwierzytelnienia informacji przesyłanych w pakiecie notyfikacji.

6.3. Metoda weryfikacji podpisu notyfikacji

Nagłówek zawierający podpis notyfikacji ma postać:

X-Imoje-Signature: merchantid=[...];serviceid=[...];signature=[...];alg=[...]

Aby uwierzytelnić pochodzenie oraz zweryfikować integralność wiadomości powiadomienia należy wykonać następujące czynności:

  1. Z nagłówków pakietu przychodzącego na adres notyfikacji należy pobrać zawartość X-ImojeSignature,
  2. Następnie należy pobrać wartość parametru signature oraz alg,
  3. W zależności od algorytmu funkcji skrótu określonego w parametrze alg należy obliczyć odpowiednią funkcją skrót:
    string incoming_signature = x_imoje_signature[signature]
    string body = notification_body
    string own_signature = hash(body + private_key, alg)
  4. Obliczoną wartość own_signature należy porównać z wartością incoming_signature, która została pobrana z nagłówka,
  5. Jeżeli wartości own_signature i incoming_signature są identyczne oznacza to, że wiadomość notyfikacji jest poprawna i pochodzi z zaufanego źródła.

icon

Zmiany statusów transakcji w należy dokonywać tylko gdy weryfikacja podpisu przebiegła poprawnie.

 

Przykład weryfikacji podpisu notyfikacji

  1. W nagłówku otrzymujemy sygnaturę imoje:
    X-Imoje-Signature: merchantid=6yt3gjtm9p7b8h9xsdqz;serviceid=63f574ed-d4ad-407e-9981-
    39ed7584a7b7;signature=8cddb407c5f1a46604660cf18e5670e68c6e384f9c8c4aa39b3af18c
    3c4bba1f;alg=sha256
  2. W treści pakietu notyfikacji otrzymujemy JSON:
    {
     "transaction": {
       "id": "f115d23d-a943-4585-a3d7-09f6c417200d",
       "type": "sale"
       "status": "settled",
       "source": "api",
       "created": 1483381278,
       "modified": 1483382521,
       "notificationUrl": "https://notification_url",
       "serviceId": "63f574ed-d4ad-407e-9981-39ed7584a7b7",
       "amount": 1.03,
       "currency": "PLN",
       "title": "Tytul",
       "orderId": "123123123",
       "paymentMethod": "ing",
       "paymentMethodCode": "ing",
       "customer": {
          "firstName": "Jan",
          "lastName": "Kowalski",
          "cid": "123",
          "company": "",
          "phone": "",
          "email": "jan.kowalski@example.com"
       },
       "billing": {
          "firstName": "Jan",
          "lastName": "Kowalski",
          "company": "Company",
          "street": "Street",
          "city": "City",
          "region": "Region",
          "postalCode": "",
          "countryCodeAlpha2": "PL"
       },
       "shipping": {
          "firstName": "Jan",
          "lastName": "Kowalski",
          "company": "Company",
          "street": "Street",
          "city": "City",
          "region": "Region",
          "postalCode": "",
          "countryCodeAlpha2": "PL"
        }
      }
    }
  3. Obliczamy sygnaturę:

    private_key: 25d19e0b0b4ec0ba989c94ddabc161d468d6ae1f05f0c7d4cf38a915bd68326d

    own_signature = sha256(body + private_key)

    own_signature: 8cddb407c5f1a46604660cf18e5670e68c6e384f9c8c4aa39b3af18c3c4bba1f

  4. Porównujemy sygnaturę obliczoną z otrzymaną w nagłówku notyfikacji:
    let body = "{...}";
    let headerSignature =
    "8cddb407c5f1a46604660cf18e5670e68c6e384f9c8c4aa39b3af18c3c4bba1f";
    let privateKey =
    "25d19e0b0b4ec0ba989c94ddabc161d468d6ae1f05f0c7d4cf38a915bd68326d";
    let mySignature = crypto.createHash("sha256").update(body + privateKey).digest("hex");
    if (mySignature === headerSignature) {
     // Notyfikacja zweryfikowana poprawnie. Przetwarzaj dalej.
    } else {
     // Notyfikacja zweryfikowana negatywnie. Ignoruj notyfikację.
    }

Do góry

7. Pobieranie danych transakcji

Aby pobrać dane zamówienia należy wysłać żądanie GET na adres https://api.imoje.pl/v1/merchant/{merchantId}/transaction/{transactionId}.

Na przykład:

https://api.imoje.pl/v1/merchant/6yt3gjtm9p7b8h9xsdqz/transactions/f115d23d-a943-4585-a3d7-09f6c417200d

W odpowiedzi otrzymamy:

{
 "transaction": {
   "id": "f115d23d-a943-4585-a3d7-09f6c417200d",
   "type": "sale",
   "status": "pending",
   "source": "api",
   "created": 1483381278,
   "modified": 1483382515,
   "notificationUrl": "https://notification_url",
   "serviceId": "63f574ed-d4ad-407e-9981-39ed7584a7b7",
   "amount": 1.03,
   "currency": "PLN",
   "title": "",
   "orderId": "123123123",
   "paymentMethod": "ing",
   "paymentMethodCode": "ing",
   "customer": {
      "firstName": "Jan",
      "lastName": "Kowalski",
      "cid": "123",
      "company": "",
      "phone": "",
      "email": "jan.kowalski@example.com"
   },
   "billing": {
      "firstName": "Jan",
      "lastName": "Kowalski",
      "company": "Company",
      "street": "Street",
      "city": "City",
      "region": "Region",
      "postalCode": "",
      "countryCodeAlpha2": "PL"
   },
   "shipping": {
      "firstName": "Jan",
      "lastName": "Kowalski",
      "company": "Company",
      "street": "Street",
      "city": "City",
      "region": "Region",
      "postalCode": "",
      "countryCodeAlpha2": "PL"
    }
  }
}

Do góry

8. Pozostałe funkcje API

8.1. Pobieranie danych o usługach akceptanta

Wysyłając żądanie GET na adres https://api.imoje.pl/v1/merchant/{merchantId}/service otrzymamy dokument JSON zawierający informacje o wszystkich usługach akceptanta

W odpowiedzi otrzymamy:

[
  {
   "service": {
     "id": "63f574ed-d4ad-407e-9981-39ed7584a7b7",
     "created": 1483381278,
     "isActive": true,
     "paymentMethods": [
       {
         "paymentMethod": "ing",
         "paymentMethodCode": "ing",
         "isActive": true,
         "isOnline": true,
         "description": "24h/7",
         "currency": "PLN",
         "transactionLimits": {
            "minTransaction": {
             "type": "number",
             "value": 0
            },
            "maxTransaction": {
             "type": "number",
             "value": 99999999
            }
          }
       },
       {
         "paymentMethod": "pbl",
         "paymentMethodCode": "creditagricole",
         "isActive": true,
         "isOnline": false,
         "description": "03:00-24:00",
         "currency": "PLN",
         "transactionLimits": {
            "minTransaction": {
             "type": "number",
             "value": 0
            },
            "maxTransaction": {
             "type": "number",
             "value": 99999999
            }
          }
        },
         ...
       ]
     }
   },
   {
   "service": {
     ...
    }
  }
]

8.2. Pobieranie danych o usłudze akceptanta

Wysyłając żądanie GET na adres https://api.imoje.pl/v1/merchant/{merchantId}/services/{serviceId} otrzymamy dokument JSON zawierający informacje o określonej przez serviceId usłudze akceptanta.

W odpowiedzi otrzymamy:

{
 "service": {
 "id": "63f574ed-d4ad-407e-9981-39ed7584a7b7",
 "created": 1483381278,
 "isActive": true,
 "paymentMethods": [
   {
     "paymentMethod": "ing",
     "paymentMethodCode": "ing",
     "isActive": true,
     "isOnline": true,
     "description": "24h/7",
     "currency": "PLN",
     "transactionLimits": {
       "minTransaction": {
        "type": "number",
        "value": 0
       },
       "maxTransaction": {
        "type": "number",
        "value": 99999999
       }
     }
   },
   {
     "paymentMethod": "pbl",
     "paymentMethodCode": "creditagricole",
     "isActive": true,
     "isOnline": false,
     "description": "03:00-24:00",
     "currency": "PLN",
     "transactionLimits": {
       "minTransaction": {
        "type": "number",
        "value": 0
       },
       "maxTransaction": {
        "type": "number",
        "value": 99999999
       }
     }
   },
   ...
   ]
  }
}

8.3. Pobieranie zaufanych adresów IP

System umożliwia konfigurację bezpiecznych adresów IP z których możliwa jest komunikacja z API imoje. Domyślnie lista jest pusta, co oznacza, że obsługiwane będą zapytania z każdego adresu IP.

Listę zaufanych adresów IP można otrzymać wysyłając żądanie GET na adres https://api.imoje.pl/v1/merchant/{merchantId}/settings/ips.

W odpowiedzi otrzymamy dokument JSON:

{
 "trustedIps": ["127.0.0.1","10.10.10.10",...]
}

lub dla pustej listy:

{
 "trustedIps": null
}

8.4. Ustawianie zaufanych adresów IP

Wysyłając żądanie PUT na adres https://api.imoje.pl/v1/merchant/{merchantId}/settings/ips możemy skonfigurować listę zaufanych adresów IP.

Payload zapytania powinien zawierać listę adresów w postaci:

{
 "trustedIps": ["127.0.0.1","10.10.10.10"]
}

8.5. Pobieranie danych statystycznych

8.5.1. Liczba zarejestrowanych transakcji

Wysyłając żądanie GET na adres https://api.imoje.pl/v1/merchant/{merchantId}/stats/transactions/count otrzymamy dokument JSON zawierający informację o liczbie wszystkich zarejestrowanych transakcji.

W odpowiedzi otrzymamy:

{
 "count": 23
}

8.5.2. Liczba zarejestrowanych transakcji dla usługi

Wysyłając żądanie GET na adres https://api.imoje.pl/v1/merchant/{merchantId}/stats/transactions/count/{serviceId} otrzymamy dokument JSON zawierający informację o liczbie wszystkich zarejestrowanych transakcji dla określonej przez serviceId usługi.

W odpowiedzi otrzymamy:

{
 "count": 23
}

8.5.3. Liczba transakcji - grupowane po statusie

Wysyłając żądanie GET na adres https://api.imoje.pl/v1/merchant/{merchantId}/stats/transactions/states otrzymamy dokument JSON zawierający informację o liczbie transakcji w określonym statusie.

W odpowiedzi otrzymamy:

{
 "new": 12,
 "authorized": 1,
 "pending": 0,
 "submitted": 22,
 "rejected": 2312,
 "settled": 21234,
 "refunded": 2
}

8.5.4. Liczba transakcji usługi - grupowane po statusie

Wysyłając żądanie GET na adres https://api.imoje.pl/v1/merchant/{merchantId}/stats/transactions/states/{serviceId} otrzymamy dokument JSON zawierający informację o liczbie transakcji w określonym statusie dla określonej przez serviceId usługi.

W odpowiedzi otrzymamy:

{
 "new": 1,
 "authorized": 1,
 "pending": 0,
 "submitted": 3,
 "rejected": 123,
 "settled": 762,
 "refunded": 0
}

Do góry

9. Minimalne wartości kwot transakcji, zwrotów

Dla każdej metody płatności obowiązują następujące limity:

Metoda płatności Minimalna kwota płatności (PLN)
Przelewy online Pay-By-Link 1
Płatność za pomocą BLIK 0.01
Płatność kartą 0.01

Poniżej tego progu dana metoda płatności nie jest dostępna.

Do góry

10. Twisto

icon

Twisto dla sklepów w trybie testowym nie jest dostępne. Symulację można dokonać jedynie w integracji z bramką płatności - do formularza należy dodać parametr twistoData z wartością {"status":"accepted-verification required","transaction_id":"sandbox"}

Aby rozpocząć płatność Twisto należy przygotować zebrane dane (punkt 10.3) z koszyka.

Podczas płatności, należy wykonać następujące kroki:

  1. zaimportować bibliotekę JavaScript i ustawić klucz publiczny, którego pobranie zostało opisane w punkcie 10.1:
     var _twisto_config = {
     public_key: 'live_pk_gs8fcj9p2mbasxhlyte236hrupm5lubqaj7qzwh7kfuihoekud',
     script: 'https://api.twisto.pl/v2/lib/twisto.js'
     };
     (function (e, g, a) {
     function h(a) {
     return function () {
     b._.push([a, arguments])
     }
     }
     var f = ["check"], b = e || {}, c = document.createElement(a);
     a = document.getElementsByTagName(a)[0];
     b._ = [];
     for (var d = 0; d < f.length; d++) {
     b[f[d]] = h(f[d]);
     }
     this[g] = b;
     c.type = "text/javascript";
     c.async = !0;
     c.src = e.script;
     a.parentNode.insertBefore(c, a);
     delete e.script
     }).call(window, _twisto_config, "Twisto", "script");
    
  2. wywołać funkcję Twisto.check z argumentami:
    • data (string) – zaszyfrowane dane płatności (10.3) w formie ciągu znaków zakodowane w base64,
    • success (function) – przeprowadzenie dalszych czynności po poprawnej lub niepoprwanej odpowiedzi aplikacji Twisto,
    • error (function) – przeprowadzenie dalszych czynności w momencie gdy pojawił się problem podczas przesyłania danych,
    • options (object)[opcjonalne] – zawartość tego obiektu musi być funkcją, a dostępna funkcja to:
      • processingStarted (function) – wywołane po poprawnym ropoczęciu procesowania.

Przykładowe wywołanie funkcji:

Twisto.check("{data}", function (response) {
      //success
    }, function (response) {
      //error
    }, {
          "processingStarted": function () {
      //processingStarted
    }
  }
);

Przykładowa poprawna odpowiedź aplikacji Twisto:

{
 "transaction_id": "1ad5mzbc9hsynjbkp8dlsqt7",
 "status": "accepted"
}

 

Opis statusów:

Status Opis
accepted zamówienie zostało pozytywnie ocenione przez system, można kontynuować płatność
accepted-verificationrequired wymagana jest dodatkowa weryfikacja płatnika
rejected zamówienie zostało odrzucone przez system

gdzie:

  • accepted – należy wysłać standardowe zapytanie do api imoje (punkt 5) z zamówieniem i dodać parametr twistoTransactionId z wartością otrzymanego parametru transaction_id,
  • accepted-verification-required – aby przeprowadzić zamówienie dalej należy wykonać procedury opisane w punkcie 10.5,
  • rejected – status ten oznacza że Twisto odrzuciło zapytanie i należy pozwolić płatnikowi wybrać inną metodę płatności

icon

W przypadku integracji z bramką płatności otrzymaną odpowiedź należy dołączyć do formularza z parametrem twistoData.

10.1. Pobranie kluczy

Klucze niezbędne do przeprowadzenia poprawnej transakcji za pomocą Twisto należy pobrać wysyłając żądanie metodą GET na adres:

https://paywall.imoje.pl/check/methods

nagłówki które muszą się znaleźć w zapytaniu:

Content-Type: application/json
X-Imoje-Signature: merchantid={merchantid};serviceid={serviceid};signature={signature};alg=sha256

gdzie:

  • merchantid – identyfikator klienta,
  • serviceid – identyfikator sklepu,
  • signature – zahashowany metodą sha256 klucz sklepu.

Przykład wygenerowanej sygnatury:

hash('sha256',{servicekey});

gdzie:

  • servicekey – klucz sklepu.

 

Zawartość przykładowej odpowiedzi:

{
 "status": "ok",
 "data": {
   "twisto": {
      "enable": true,
      "pk": "live_pk_ayog9acnonq70j1xcn63n5ttmvsfur54sd9lcelez9feycuub3",
      "sk": "live_sk_7fd1dbbfc0c63995f71960ec6cxzhf14e6be526637aad581ff82b16170b049a5",
      "timeout": 10000
     }
  }
}

gdzie:

  • enable – true jeżeli metoda płatności Twisto jest włączona dla tego sklepu, false jeżeli nie,
  • pk – to klucz publiczny Twisto,
  • sk – to klucz prywatny Twisto.

10.2. Biblioteka PHP

Biblioteka PHP wspomagająca proces przygotowania danych płatności znajdują się na stronie internetowej:

https://github.com/TwistoPayments/Twisto.php

10.3. Struktura danych, które są przekazywane do systemu Twisto

10.3.1 Przygotowanie danych z użyciem biblioteki PHP

icon

Ważne jest, aby ustawić poprawny adres api $twisto->setApiUrl('http://api.twisto.pl/v2/')

define('TWISTO_PUBLIC_KEY', 'live_pk_v22d67vm1fdec1xp3loxsban99gnpa022xes7u56kq6ahohz1t');
define('TWISTO_SECRET_KEY',
'live_sk_8d4442659363x7s28c1f5d58da43c38c7b6ed886663cc87c41046cd729fce7c7');
$twisto = new Twisto\Twisto();
$twisto->setApiUrl('http://api.twisto.pl/v2/');
$twisto->setPublicKey(TWISTO_PUBLIC_KEY);
$twisto->setSecretKey(TWISTO_SECRET_KEY);
$customer = new Twisto\Customer('johndoe@example.com', 'John Doe');
$order_items = array(
 new Twisto\Item(
   Twisto\Item::TYPE_DEFAULT, // typ
   'Coca Cola 1 litr', // nazwa
   530, // product_id (product ID - musi być unikalny dla zamówienia)
   6, // ilość
   156, // price_vat (cena brutto przedmiotu pomnożona przez ilość)
   23 // procent vat
  ),
 new Twisto\Item(
   Twisto\Item::TYPE_DEFAULT, // typ
   'Rowerek dziecięcy', // nazwa
   942, // product_id (product ID - musi być unikalny dla zamówienia)
   1, // ilosc
   285.31, // price_vat (cena brutto przedmiotu pomnożona przez ilość)
   23 // procent vat
 ),
 new Twisto\Item(
   Twisto\Item::TYPE_SHIPMENT, // typ
   'Kurier', // nazwa
   'shipment', // product_id (product ID - musi być unikalny dla zamówienia)
   1, // ilość
   119, // price_vat (cena brutto przedmiotu pomnożona przez ilość)
   23 // procent vat
 ),
 /*
 * Przedmiot jako płatność (Twisto) jest również wymagana
 */
 new Twisto\Item(
 Twisto\Item::TYPE_PAYMENT, // typ
 'Twisto', // nazwa
 'payment', // product_id (product ID - musi być unikalny dla zamówienia)
 1, // ilość
 0, // price_vat (cena brutto przedmiotu pomnożona przez ilość)
 23 // procent vat
 ),
 new Twisto\Item(
   Twisto\Item::TYPE_ROUND, // typ
   'Zaokraglenie', // nazwa
   'round', // product_id (product ID - musi być unikalny dla zamówienia)
   1, // ilość
   -0.31, // price_vat (cena brutto przedmiotu pomnożona przez ilość)
   0 // procent vat
 ),
);
$order = new Twisto\Order(
 new DateTime(), // date_created
 new Twisto\Address( // billing_address
   'John Doe',
   'Polna 5',
   'Warszawa',
   '00001',
   'PL',
   '+48500500500'),
 new Twisto\Address( // delivery_address
   'John Doe',
   'Polna 2',
   'Warszawa',
   '00001',
   'PL',
   '+48500500500'),
 560, // total_price_vat
 $order_items // items
);
$previous_orders = array(
 new Twisto\Order(
   new DateTime("2012-07-08 11:14:15.638276"),
    $order->billing_address,
    $order->delivery_address,
    $order->total_price_vat,
    $order_items
  )
);
// utworzenie danych które zostaną wysłane do Twisto przez javascript
$payload = $twisto->getCheckPayload($customer, $order, $previous_orders);

10.3.2 Przygotowanie danych bez biblioteki PHP

Struktura zamówienia:

{
 "random_nonce": {random_nonce},
 "customer": {customer},
 "order": {order},
 "previous_orders": {previous_orders}
}

gdzie:

  • random_nonce – unikalny, złożony z losowych alfanumerycznych znaków identyfikator,
  • customer – sekcja zgodna z opisem w punkcie 10.3.3,
  • order – sekcja zgodna z opisem w punkcie 10.3.3,
  • previous_orders – tablica wcześniejszych zamówień, gdzie każde pojedyńcze zamówienie ma strukturę opisaną w sekcji 10.3.3 (Order).

 

icon

Dane te powinny być w formacie json oraz należy je zaszyfrować zgodnie z opisem w punkcie 10.4. Przykład przygotowania danych wraz z szyfrowaniem został przedstawiony w punkcie 10.6.

10.3.3 Struktura parametrów potrzebnych do złożenia zamówienia w Twisto

 

Customer

Nazwa Wymagane Typ Maksymalna długość Opis Przykład
email Tak String 254 Adres email płatnika "johndoe@example.com"
name Nie String 255 Nazwa "Jan Kowalski"
facebook_id Nie String 50 Identyfikator Facebook "123456789"
company_id Nie String 15 NIP "1234567890"
vat_id Nie String 15 REGON "123456789"

Order

Nazwa Wymagane Typ Maksymalna długość Opis Przykład
date_created Tak String   Data i czas generowania zamówienia - ISO 8601 "2013-07- 22T14:57:18+00:00"
billing_address Tak Address   Adres rozliczeniowy  
delivery_address Tak Address   Adres dostawy  
total_price_vat Tak Number 8.2 Koszt przedmiotu z uwzględnieniem podatku VAT 1432.23
items Tak Item[]   Zawartość koszyka  

Address

Nazwa Wymagane Typ Maksymalna długość Opis Przykład
name Tak String 100 Imię i nazwisko "Jan Kowalski"
street Tak String 100 Ulica "Warszawska 1/5"
city Tak String 100 Miasto "Warszawa"
zipcode Tak String 5 Kod pocztowy "00001"
phone_number Tak String 20 Numer telefonu  
country Tak String 2 Kod kraju ISO 3166-1 alpha-2 "PL"
type Nie Number     1

Item

Nazwa Wymagane Typ Maksymalna długość Opis Przykład
type Tak Number   Typ produktu: 0 - produkt,
1 - wysyłka,
2 - płatność,
4 - zniżka,
32 - zaokrąglenie
0
name Tak String 255 Nazwa przedmiotu "Koszulka"
product_id Tak String 255 ID produktu (musi być unikalny dla zamówienia) "1000"
quantity Tak Number   Ilość 2
price_vat Tak Number   Koszt przedmiotu z uwzględnieniem podatku VAT 406.07
vat Tak Number   Procent podatku VAT 23
ean_code Nie String 13 Kod EAN  
isbn_code Nie String 13 Kod ISBN  
issn_code Nie String 8 Kod ISSN  
heureka_category Nie Number   Kod kategorii w systemie Heureka  

10.4. Szyfrowanie danych

10.4.1 AES + HMAC

Zawartość zapytania należy zaszyfrować za pomocą AES-128-CBC i podpisać metodą HMAC-SHA256. Szyfrowanie powinno przebiegać w następujący sposób:

  1. wygenerować kryptograficznie losowy wektor iv,
  2. usunąć pierwsze 8 znaków z prywatnego klucza. Następnie przekonwertować ciąg danych z kodu szesnastkowego na kod binarny. Z uzyskanego ciągu znaków, należy użyć pierwszych szesnaście znaków jako klucz dla szyfru. Resztę danych użyć jako salt,
  3. użyć klucza oraz wektora iv aby uzyskać cipher,
  4. przekonwertować dane do UTF-8 i skompresować otrzymany ciąg znaków używając biblioteki zlib,
  5. dodać długość łańcucha znaków jako unsigned long int w kolejności bajtów sieciowych i zastosować dopełnienie do wynikowego łańcucha,
  6. zaszyfrować tekst i razem z wektorami iv i digest przekonwertować do Base64.

Przykład:

// inicjalizacja zmiennej
$iv = openssl_random_pseudo_bytes(16);

// klucz prywatny Twisto
$secret_key = 'live_sk_a3daex196gc40c4f8oa8a8as9ccx218415aa13fcsdso2ad9h0jaeed6490lld20';

// pobranie klucza i soli
$bin_key = pack("H*", substr($secret_key, 8));
$aes_key = substr($bin_key, 0, 16);
$salt = substr($bin_key, 16, 16);

// kompresja danych
$gz_data = gzcompress($data, 9);
$data = pack("N", strlen($gz_data)) . $gz_data;

// sprawdzenie sumy
$digest = hash_hmac('sha256', $data . $iv, $salt, true);

// szyfrowanie AES
$encrypted = openssl_encrypt($data, 'aes-128-cbc', $aes_key, true, $iv);
$result = base64_encode($iv . $digest . $encrypted);

gdzie:

  • $data – dane zamówienia w formacie json.

10.4.2 SecretBox

Istnieje drugi sposób na zaszyfrowanie danych z wykorzystaniem biblioteki Sodium:

  1. usunąć pierwsze 8 znaków z prywatnego klucza. Następnie przekonwertować ciąg danych z kodu szesnastkowego na kod binarny. Z uzyskanego ciągu znaków, należy użyć pierwszych szesnaście znaków jako klucz dla szyfru,
  2. stworzyć losowy, alfanumerczyny ciąg znaków dalej nazywany identyfikatorem używając bezpieczenego generatora. Identyfikator dla każdego zamówienia musi być inny. Generator musi być bezpieczny do użytku kryptograficznego, więc zdecydowanie zalecamy użycie generatora dostarczonego przez bibliotekę Sodium,
  3. wykonać szyfrowanie za pomocą biblioteki Sodium.

10.4.3. Przykład z użyciem biblioteki PHP

W przypadku wykorzystania biblioteki PHP szyfrowanie danych odbywa się w ramach funkcji getCheckPayload w klasie Twisto.

10.5. Weryfikacja płatnika

W przypadku gdy status w odpowiedzi Twisto (punkt 10.5) jest accepted-verification-required należy przeprowadzić dodatkową weryfikację polegającą na wprowadzeniu kodu autoryzacyjnego.

icon

W przypadku integracji z bramką płatności dodatkowa weryfikacja przeprowadzana jest na bramce płatności.

Wysyłając każde zapytanie do api Twisto należy dodać poniższe nagłówki:

Accept: application/json
Content-Type: application/json
Authorization: {publickey},{secretkey}

gdzie:

  • publickey i secretkey to otrzymane klucze (punkt 10.1) rozdzielone przecinkiem.

10.5.1. Wysłanie kodu autoryzacyjnego do platnika

Należy wysłać żądanie metodą POST (z nagłówkami opisanymi w sekcji 10.4) z pustym payloadem na adres

https://api.twisto.pl/v2/check/{transaction_id}/verification/send/

gdzie:

  • transaction_id to identyfikator płatności otrzymany w punkcie 10.

Możliwe odpowiedzi:

message_id HTTP status message Opis
0 200 Verification code has been sent kod został poprawnie wysłany
1 400 Resend requested too early żądanie ponownego wysłania kodu weryfikacyjnego zostało wysłane zbyt wcześnie
2 400 Resends exceeded osiągnięto limit możliwości wysyłki kodów
3 400 Cannot verify transaction nie można zweryfikować transakcji

Przykładowa odpowiedź:

{
 "message_id": 0,
 "message": "Verification code has been sent"
}

10.5.2. Weryfikacja kodu

Otrzymany od płatnika kod należy wysłać metodą POST na adres

https://api.twisto.pl/v2/check/{transaction_id}/verification/

wraz z payload:

{
 "code": {code}
}

gdzie:

  • transaction_id – identyfikator płatności Twisto,
  • code – kod autoryzacyjny podany przez użytkownika.

Możliwe odpowiedzi:

message_id HTTP status message Opis Status końcowy
0 200 Successful verification weryfikacja przebiegła prawidłowo tak
1 400 Verification code does not match przesłany kod jest niepoprawny. Można poprosić użytkownika o wprowadzenie raz jeszcze kodu nie
2 400 Transaction has expired transakcja wygasła tak
3 400 Maximum tries exceeded limit ilości prób potwierdzenia kodu został osiągnięty tak
4 400 Cannot verify transaction nie można zweryfikować transakcji tak

W momencie gdy został zwrócony status końcowy nie należy prosić płatnika o wprowadzenie kodu raz jeszcze.

Przykładowa odpowiedź:

{
 "message_id": 0,
 "message": "Successful verification"
}

W przypadku poprawnej weryfikacji należy kontynuować zgodnie z opisem w punkcie 10 dla statusu accepted.

10.6. Kompletny przykład przygotowania danych wraz z szyfrowaniem bez biblioteki PHP

$random_nonce = uniqid('', true);
$customer = [
   "email" => "johndoe@example.com",
   "name" => "John Doe",
];
$order = [
   "date_created" => "2018-08-21T16:40:18+00:00",
   "billing_address" => [
     "name" => "John Doe",
     "street" => "Polna 5",
     "city" => "Warszawa",
     "zipcode" => "00001",
     "country" => "PL",
     "phone_number" => "500500500",
   ],
   "delivery_address" => [
     "name" => "John Doe",
     "street" => "Polna 2",
     "city" => "Warszawa",
     "zipcode" => "00001",
     "country" => "PL",
     "phone_number" => "500500500",
   ],
   "total_price_vat" => "100",
   "items" => [
      [
        "type" => "0",
        "name" => "Koszulka",
        "product_id" => "123",
        "quantity" => "1",
        "price_vat" => "100",
        "vat" => "23",
      ],
   ],
];
$data = json_encode([
   "random_nonce" => $random_nonce,
   "customer" => $customer,
   "order" => $order,
]);
$gz_data = gzcompress($data, 9);
$data = pack("N", strlen($gz_data)) . $gz_data;
$secret_key = 'live_sk_a3daex196gc40c4f8oa8a8as9ccx218415aa13fcsdso2ad9h0jaeed6490lld20';
$bin_key = pack("H*", substr($secret_key, 8));
$aes_key = substr($bin_key, 0, 16);
$salt = substr($bin_key, 16, 16);
$iv = openssl_random_pseudo_bytes(16);
$encrypted = openssl_encrypt($data, 'aes-128-cbc', $aes_key, true, $iv);
$digest = hash_hmac('sha256', $data . $iv, $salt, true);
$data = base64_encode($iv . $digest . $encrypted);

 

Do góry

11. Dane kontaktowe, wsparcie techniczne

Adres e-mail: kontakt.tech@imoje.pl
Telefon: 48 32 319 35 70
WWW: https://www.imoje.pl

 

Do góry