Opłacanie transakcji kartami płatniczymi cieszy się coraz większą popularnością na rynku e-commerce

Ten tutorial pozwoli zarówno zrozumieć mechanizm działania tego rodzaju płatności jak i pomoże w poprawnym wdrożeniu ich na własnej stronie. Ta metoda może również posłużyć do zapisania karty klienta, poprzez wygenerowanie tokenu, który będzie później wiązał kartę kredytową z kontem sprzedawcy i umożliwiał płatności bez potrzeby ponownego wprowadzania danych.

Mechanizm płatności kartą przez zintegrowaną bramkę

  1. W pierwszej kolejności należy dodać możliwość wyboru metody płatności kartą swoim klientom, poprzez np. wyświetlenie dodatkowego przycisku "Szybka płatność kartą" np.

    Na tym etapie przyjmujemy, że sklep powinien już dysponować danymi klienta takimi jak nazwisko oraz email i danymi płatności - kwotą i walutą zamówienia.
  2. Następnie po kliknięciu zapłać, w tle generowany jest link transakcji, pod który zostanie przekierowany klient (automatycznie lub po kliknięciu przycisku).
    Tą metodę można również wykorzystać do automatycznego wysyłania linków transakcji klientom, którzy nie odwiedzają naszego sklepu, a jedynie mają uiścić opłatę.
  3. Tpay.com udostępnia gotowe biblioteki programistyczne w języku PHP, które obsługują proces generowania transakcji automatycznie i nie wymagają dużego nakładu pracy deweloperów. Wystarczy tylko dostosować gotowe pliki do swoich potrzeb.
  4. W panelu transakcyjnym Tpay, klient wprowadzi swoje dane karty i zatwierdzi płatność.
  5. Po udanej płatności klient zostanie przekierowany do strony sukcesu w sklepie. W przypadku niepowodzenia należy umożliwić klientowi ponowną zapłatę poprzez przekierowanie pod ten sam link ze strony niepowodzenia lub poprzez wygenerowanie nowego. Z raz wygenerowanego linku można korzystać tak długo, aż transakcja nie zostanie poprawnie opłacona.
  6. Powiadomienie o wpłacie zostanie wysłane na adres wynikowy sklepu, skonfigurowany w ustawieniach konta sprzedawcy.

 Techniczne wyjaśnienie płatności kartą na stronie sklepu

  1. Wykonanie transakcji kartą odbywa się poprzez wysłanie zapytania przez API. Do rozpoczęcia integracji będą potrzebne dane dostępowe takie jak klucz, hasło i kod weryfikacyjny, które należy wygenerować zgodnie z instrukcją.
  2. Drugi krok to wywołanie metody register_sale, służącej do przesłania potrzebnych danych do serwera Tpay.
    Do wygenerowania transakcji i wykonania przekierowania, zalecamy posłużyć się gotową biblioteką PHP tak jak w tym przykładzie. Wspomniany przykład wykona przekierowanie do panelu transakcyjnego Tpay, wystarczy uzupełnić w nim przekazanie kwoty, waluty i danych klienta w zależności od swojego rozwiązania - np. pobrać z bazy danych.

    Przykład wykonania tej metody znajduje się w serwisie github w bibliotece PHP tpay-com, a także można wykonać testowe wywołanie klikając "Try" w dokumentacji.
    Minimalny zestaw parametrów, jakie należy wysłać w tej metodzie to:
    {
      "name": "john doe",
      "email": "[email protected]",
      "desc": "payment for order xyz",
      "amount": 10.99,
      "api_password": "XtCns9OAue8zSFJ",
      "sign": "25bd2eb0bd6e6ad2c570bcf9ecb2156b35d31dff",
      "currency": 985
    }​

    Dodatkowy parametr "onetimer" decyduje o zapamiętaniu karty płatniczej. Jeżeli metoda ta nie ma posłużyć do zapamiętania karty płatniczej, należy zawsze przesyłać w niej parametr "onetimer".
    Zapamiętanie karty można wykorzystać do wdrożenia płatności rekurencyjnych. Zapamiętany token będzie zwrócony w parametrze "cli_auth", w powiadomieniu systemowym.

  3. Wynik zapytania zwraca parametr "sale_auth", będący wygenerowanym identyfikatorem transakcji, pod który należy przekierować płatnika.
  4. Po udanym zatwierdzeniu płatności przez klienta, na adres wynikowy serwera (zdefiniowany w ustawieniach konta) zostanie wysłane asynchroniczne powiadomienie o wpłacie, tak samo jak w przypadku transferów bankowych.
    Przeczytaj dokumentację opisującą powiadomienia transakcji kartowych. W serwisie github.com udostępniliśmy gotowy przykład automatycznie weryfikujący powiadomienie i zwracający jego zwalidowaną zawartość.
  5. Adres URL, na który zostanie przekierowany płatnik po zatwierdzeniu płatności można zdefiniować statycznie w ustawieniach konta sprzedawcy lub przesyłać dynamicznie w odpowiednich parametrach.

Przykład wdrożenia w oparciu o biblioteki PHP Tpay

  1. Pobierz biblioteki Tpay z serwisu Github.com
  2. Stwórz plik (np. w folderze examples) rozszerzający klasę PaymentCardForms, w którego konstruktorze podaj swoje dane dostępowe do API kart płatniczych:
    <?php
    
    namespace tpayLibs\examples;
    
    use tpayLibs\src\_class_tpay\PaymentForms\PaymentCardForms;
    use tpayLibs\src\_class_tpay\Utilities\TException;
    
    include_once 'config.php';
    include_once 'loader.php';
    
    class CardBasic extends PaymentCardForms
    {
        public function __construct()
        {
            $this->cardApiKey = 'bda5eda723bf1ae71a82e90a249803d3f852248d';
            $this->cardApiPass = 'IhZVgraNcZoWPLgA';
            $this->cardKeyRSA = 'LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0NCk1JR2ZNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0R05BRENCaVFLQmdRQ2NLRTVZNU1Wemd5a1Z5ODNMS1NTTFlEMEVrU2xadTRVZm1STS8NCmM5L0NtMENuVDM2ekU0L2dMRzBSYzQwODRHNmIzU3l5NVpvZ1kwQXFOVU5vUEptUUZGVyswdXJacU8yNFRCQkxCcU10TTVYSllDaVQNCmVpNkx3RUIyNnpPOFZocW9SK0tiRS92K1l1YlFhNGQ0cWtHU0IzeHBhSUJncllrT2o0aFJDOXk0WXdJREFRQUINCi0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQ';
            $this->cardVerificationCode = '6680181602d396e640cb091ea5418171';
            $this->cardHashAlg = 'sha1';
            parent::__construct();
        }
    }​
  3. Dodaj funkcję wykonującą zapytanie do serwera Tpay i przekierowanie do panelu transakcyjnego:
    public function getRedirectTransaction()
    {
        try {
            $config = [
                'name' => 'John Doe',
                'email' => '[email protected]',
                'desc' => 'Transaction description',
            ];
            $this
                ->setAmount(123.00)
                ->setCurrency(985)
                ->setReturnUrls('https://shop.com/success', 'https://shop.com/error');
            $transaction =  $this->registerSale($config['name'], $config['email'], $config['desc']);
            if (isset($transaction['sale_auth']) === false) {
                throw new TException('Error generating transaction: ' . $transaction['err_desc']);
            }
            $transactionId = $transaction['sale_auth'];
            header("Location: https://secure.tpay.com/cards/?sale_auth=$transactionId");
        } catch (TException $e) {
            echo 'Unable to generate transaction. Reason: ' . $e->getMessage();
        }
    }

    Niektóre dane należy pobrać z bazy danych (kwotę, walutę itp.), w tym przykładzie wprowadziliśmy dane przykładowe.

  4. Wykonanie funkcji MakeCardPayment() zwróci wynik, zawierający parametr "sale_auth", na który wykonane zostaje przekierowanie klienta.
    Przykładowy zestaw parametrów zwracany przez API:
    $transaction = [
      'result' => '1',
      'sale_auth' => 't59c28295aeb071b0cf6471b24f727f6456998de',
    ];​
  5. Cały plik można wykonać dodając poza klasą linijkę:
    (new CardBasic())->getRedirectTransaction();
  6. Pamiętaj, że powiadomienie o poprawnym opłaceniu zostanie wysłane do Twojego sklepu, dopiero po finalizacji transakcji.
    W celu odebrania takiego powiadomienia, utwórz plik CardNotification.php, rozszerzający klasę CardNotificationHandler. W panelu odbiorcy płatności należy podać adres URL prowadzący do tego pliku zgodnie z dokumentacją.
    Dodaj konstruktor nowej klasy:
    <?php
    
    namespace tpayLibs\examples;
    
    use tpayLibs\src\_class_tpay\Notifications\CardNotificationHandler;
    
    include_once 'config.php';
    include_once 'loader.php';
    
    class CardNotification extends CardNotificationHandler
    {
        public function __construct()
        {
            $this->cardApiKey = 'bda5eda723bf1ae71a82e90a249803d3f852248d';
            $this->cardApiPass = 'IhZVgraNcZoWPLgA';
            $this->cardKeyRSA = 'LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0NCk1JR2ZNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0R05BRENCaVFLQmdRQ2NLRTVZNU1Wemd5a1Z5ODNMS1NTTFlEMEVrU2xadTRVZm1STS8NCmM5L0NtMENuVDM2ekU0L2dMRzBSYzQwODRHNmIzU3l5NVpvZ1kwQXFOVU5vUEptUUZGVyswdXJacU8yNFRCQkxCcU10TTVYSllDaVQNCmVpNkx3RUIyNnpPOFZocW9SK0tiRS92K1l1YlFhNGQ0cWtHU0IzeHBhSUJncllrT2o0aFJDOXk0WXdJREFRQUINCi0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQ';
            $this->cardVerificationCode = '6680181602d396e640cb091ea5418171';
            $this->cardHashAlg = 'sha1';
            parent::__construct();
        }
    
    }​
  7. Następnie dodaj wywołanie funkcji sprawdzającej powiadomienie systemowe (wbudowanej w bibliotekę Tpay) oraz funkcję getOrderDetailsFromDatabase, która zwróci kwotę i walutę zamówienia zapisane w sklepie, na potrzeby walidacji powiadomienia:
    private function getTpayNotification()
    {
        //Jeżeli chcesz wyłączyć sprawdzanie adresu IP serwera Tpay, wykonaj tą komendę:
        $this->disableValidationServerIP();
        //Jeżeli korzystasz z proxy, wykonaj tą komendę aby sprawdzić adres IP w tablicy HTTP_X_FORWARDED_FOR:
        $this->enableForwardedIPValidation();
    
        $notification =  $this->handleNotification();
        //Pobierz szczegóły zamówienia z bazy danych sklepu
        $shopOrderData = $this->getOrderDetailsFromDatabase($notification['order_id']);
        //Sprawdź poprawność podpisu powiadomienia
        $this
            ->setAmount($shopOrderData['amount'])
            ->setCurrency($shopOrderData['currency'])
            ->setOrderID($notification['order_id']);
        $this->validateCardSign($notification['sign'], $notification['sale_auth'],
            $notification['card'], $notification['date'], $notification['status']);
    
        return $notification;
    }​
    private function getOrderDetailsFromDatabase($orderId)
    {
        //Zaprogramuj pobranie szczegółów zamówienia z bazy sklepu w oparciu o OrderId
        //Przykładowe dane na potrzeby przykładu
        return [
            'amount' => 123.00,
            'currency' => 985,
        ];
    }
  8. Dodaj funkcję sterującą klasą init() oraz własną funkcję setOrderAsConfirmed(), która w oparciu o zwrócone dane oznaczy zamówienie jako opłacone oraz zapisze przydatne dane - np. token klienta do ponownego użytku (cli_auth) oraz tytuł transakcji (sale_auth).
    public function init()
    {
        $notification = $this->getTpayNotification();
        if (isset($notification['status']) && $notification['status'] === 'correct') {
            $this->setOrderAsConfirmed($notification);
        }
    }​

    Zmienna $notification będzie zawierała tablicę danych, opisanych w dokumentacji.

  9. Dodaj wywołanie nowo stworzonej klasy na jej końcu:
    (new CardNotification())->init();​