Integracja z Payu – Wysyłanie zamówień

By | May 15, 2016

Integracja systemu płatności PayU i ASP.NET MVC jest naprawdę prosta. Z ich dokumentacją i podstawową wiedzą na temat klienta REST API można rozpocząć wysyłanie zamówień w jeden wieczór. A dziś pokażę Wam jak wygląda to w moim projekcie.

W tym poście pokryję tylko temat tworzenia nowych zamówień, wysyłania ich do API PayU i otrzymania linku do płatności. Dalszą obsługę zamówienia zostawiam sobie na trochę później, bo już wiem jak to zrobić, więc odkładam to na chwilę, gdy będę cierpiał na naprawdę duży brak czasu. A w tym czasie zajmę się SignalR, z którym zacząłem tydzień temu i który będzie wymagał ode mnie więcej niż kilka chwil.

Zacznijmy od momentu, w którym nowe zamówienie trafia na drogę, do PayU.

Jako, że będę chciał dodać jeszcze przynajmniej jednego operatora płatności w przyszłości, to będę musiał zrobić drobny refaktoring, ale w tej chwili najważniejsze jest to, że przekazujemy zamówienie do zupełnie innego kontrolera. W finalnej wersji widzę to w ten sposób, że zamówienie opłacane gotówką przy odbiorze będzie lądowało bezpośrednio na stronie potwierdzającej zamówienie i informującej o jego statusie, zmianach itd. Z kolei zamówienie opłacane kartą, PayU, DotPayem lub innymi metodami płatności, ma znaleźć się  na takiej samej stronie, ale nieco okrężną drogą.

W tym wypadku jest to prosty kontroler PayU, z dwoma metodami akcji.

Pierwsza z nich zwraca bardzo prosty póki co widok, druga jest ładowana AJAXem i zwraca URL, pod który należy przekierować klienta, by znalazł się na stronie płatności. Istotne jest to, że pojawia się tu po raz pierwszy klasa klienta PayU, która jak łatwo się domyśleć wysyła szczegóły naszego zamówienia do API allegro i zwraca nam URL w stringu. W przyszłości będzie robić jeszcze kilka rzeczy i do tego będzie potrzebna jej rozbudowa i refaktoring, ale tym zajmę się w przyszłości. Potrzebne dla klienta PayU dane wyciągam prostą lambdą z View Modelu. Mógłbym co prawda wysłać sam View Model, ale cały klient PayU jest umieszczony w oddzielnym projekcie i gdy się już uporam z nadaniem mu pełnej funkcjonalności, to chciałbym mieć możliwość przeniesienia go do jakiegokolwiek innego projektu, wprowadzenie zależności od przychodzącego View Modelu by mi to uniemożliwiło, dlatego też na potrzeby klienta PayU musiałem stworzyć oddzielne klasy DTO.

A klient PayU w bardzo wczesnej wersji wygląda następująco.

Póki co wszystko mieści się w jednej klasie i kilku oddzielnych obiektach. Do samego procesu tworzenia nowego zamówienia muszę dodać jeszcze returnUrl, który będzie adresem, na który będę kierował klienta po dokonaniu płatności (wspomniane wcześniej podsumowanie), ale ze względu na to, że jeszcze nie skończyłem tego ostatniego etapu obsługi zamówień, to do klienta PayU funkcjonalność taka trafi dopiero za jakiś czas. Będę też musiał przekazać do API PayU dane kupującego, by oszczędzić klientowi wypełniania formularzy na stronie płatności. Klient PayU wymaga jeszcze wiele czułości.

Przejdźmy do tego co właściwie mamy. Klient otrzymuje obiekt ze szczegółami zamówienia. Jeśli nie uzyskaliśmy danych autoryzacyjnych, to przeprowadzana jest autoryzacja. Póki co opieram się o dane testowe z dokumentacji, ale w przyszłości będę musiał przygotować plik konfiguracyjny, lub tabelę w bazie, gdzie będę trzymał tego typu informacje. O problemie na jaki natrafiłem podczas składania zamówienia możecie przeczytać tutaj.
Do API PayU musimy przekazać JSONa, który będzie zawierał kilka pól opisujących nasze zamówienie, kwotę do zapłaty i kilka innych informacji, który na dzień dzisiejszy nie uzupełniałem, bo odpowiedni funkcjonalności jeszcze nie powstały (np. notifyUrl). Póki co przesyłam do API PayU dane w postaci StringContent, który tworzę przy wykorzystaniu lambdy wygrzebującej szczegóły z otrzymanego DTO i używającej String Buildera, by poskładać wszystko do kupy (uwaga na linię sb.Length -= 1, usunięcie tego przecinka jest niezbędne do poprawnego działania). Rozwiązanie może nie jest zbyt eleganckie, ale pozwala na dodawanie nowych rzeczy i zmiany w bardzo sprawny sposób, więc podejrzewam, że zostanę przy takiej konstrukcji do momentu, kiedy zajmę się ostatecznymi szlifami nad całą funkcjonalnością, którą zaplanowałem dla tego elementu.

Póki co klient PayU nie wygląda pięknie i potrzeba mu sporo pracy. Niestety brakuje mi jeszcze kilku elementów w innych miejscach projektu, a czasu ostatnio mam jak na lekarstwo, więc powyższy kod będzie musiał pozostać w takiej formie, aż skończę pracę nad kilkoma innymi funkcjonalnościami, zepnę wszystko w całość i trochę posprzątam, podzielę na mniejsze kawałki, dodam inne mniej lub bardziej istotne informacje, a usunę inne. Gdzieś w międzyczasie będę musiał wcisnąć sprawdzanie statusu płatności dla dodanych zamówień, by integracja działała w dwie strony. Mam tylko nadzieję, że wyrobię się z tym w trakcie trwania konkursu (chociaż wiem, że do końca maja, to ja na pewno nie skończę całego projektu).

Linki: