Płatności z wykorzystaniem rails-api

Cześć!

Piszę backend oparty o gem rails-api, a frontend jest napisany w AngularJS (któs inny już to ogarnia). Cała aplikacja tak naprawdę to frontend, ja dostarczam tylko api (komunikacja odbywa się via JSON), zapisuję, pobieram, wyszukuję dane z bazy danych. Wszystko jasne, na razie śmiga tak jak planowaliśmy.

Do zaimplementowania mamy teraz zrobienie płatności z wykorzystaniem PayU. I… nie wiem za bardzo od której strony to ugryźć. Jak rozumiem ten temat nie powinien być mocno skomplikowany, gdyby była to ‘standardowa’ aplikacja napisana w RoR, znalazłem odpowiedni gem do tego

Jednak jak ogarnąć temat, gdy piszę tylko api? Szukałem informacji na ten temat, jednak nie mogłem na razie nic konkretnego znaleźć. Nasuwa mi się sporo pytań związanych z tym tematem. Ktoś może ma jakieś sugestie, porady, lub widział już podobne rozwiązanie?

1 Like

A z którym elementem integracji masz problem? W backendzie możesz zaimplementować akcję, która będzie zwracała obiekt transaction do zbudowania przycisku zapłać a raporty to już sam backend.

Przydałoby się więcej szczegółów.

Wystawiam tylko api, więc nie będę mógł zbudować tego przycisku.

W tej chwili wydaje mi się, że powinienem poinstruować człowieka, który pisze frontend, by zamieścił ten przycisk z odpowiednimi parametrami, które mu wyślę JSONem. Później poleci płatność i przy powrocie dostanę już z frontendu jakąś odpowiedź odnośnie operacji. Dobrze kombinuję?

Czy właśnie wszystko będzie w backendzie? Dostanę info, że mam wykonać płatność i wszystko mam obsłużyć w railsach i użyć jakiegoś ‘redirect_to’ ?

Tak, we frontendzie budujesz przycisk z przekazanych jsonem wartości. To jest po prostu formularz z ukrytymi polami. Status płatności to już kwestia wyłącznie backendu. W payu ustawiasz adres raportów, na które będą wysyłane informacje z payu, że dana transakcja zmieniła swój status. Ale i tak musisz sam odpytać jaki jest obecnie status. To się dzieje osobnym kanałem.

Użytkownik po wykonaniu płatności jest przekierowywany z powrotem do strony, ale to nic jeszcze nie znaczy. Frontend nie może Ci przekazać czy płatność została zrealizowana czy nie. Musisz sam o to odpytać payu.

Jeszcze jedna sprawa ciekawa. Tego przycisku tak naprawdę nie możemy zbudować we frontendzie, mamy tylko na końcu rejestracji jeden przycik ‘Zapisz i zapłać’. Dostaje potem tylko dane z jakiegoś tam formularza i dopiero po poprawnym ich zapisaniu powinienem zacząć wykonywać płatności.

Jak rozumiem muszę po prostu wysłać dane pod transaction.new_url metodą POST i użyć do tego Net::HTTP?

Czy lepszym rozwiązaniem i może nawet jedynym jest jednak rozbicie tego na dwie akcje i zrobienie jakiegoś widoku po zapisaniu danych z komunikatem ‘Brawo, dane zostały zapisane!’ oraz przyciskiem ‘Zapłać’, który już (tak jak to chyba jest w założeniu od początku) wyśle po prostu ten formularz do PayU?

Dzięki za pomoc!

Wysłanie posta przez net http nie zadziała, bo to nie aplikacja ma tworzyć płatność, tylko musisz przekierować użytkownika na stronę płatności i on już wszystko robi. To musi się zadziać po stronie frontendu.

Jest taka możliwość, że po zapisaniu formularza możesz zrobić redirect do strony payu. Trzebaby wtedy zbudować cały url składający się z transaction.new_url i do niego dokleić wszystkie parametry. Tylko takie rozwiązanie korzysta z metody GET, która nie jest za bardzo zalecana przez payu.

Najprostszym rozwiązaniem będzie rozbicie tej akcji na 2 części, zarejestrowanie się a potem wyświetlenie formularza z przyciskiem “Zapłać”. Druga opcja to po zarejestrowaniu generujesz nową stronę ze zbudowanym normalnie formularzem płatności i dodajesz kod javascript, który automatycznie klika przycisk submit.

Dzięki! Dogadaliśmy się z resztą zespołu i będziemy próbować w ten sposób :slight_smile:

Cześć niestety wciąż jeszcze nie działa to w 100%. Temat już wydawało się, że będzie rozwiązany i zrobiliśmy to w ten sposób, że zapisują się dane z formularza rejestracji, zwracam JSONem wszystkie potrzebne dane do PayU i we frontendzie po prostu tworzony jest formularz i automatycznie wysyłany. Problem jest tylko taki, że wyskakuje od razu kod błędu 209, a oznacza on ponoć zły numer pos_id lub pos_auth_key. Mimo tego komunikatu nie mogę się z tym zgodzić, te wartości są podane dobrze, co widać na załączniku niżej. Napisałem z tym problemem do PayU i na razie czekam na odpowiedź, ktoś może też zetknął się z podobnym dziwactwem?

Masz włączony sandbox, czy pracujesz na wersji “produkcyjnej” PayU na kanale testowym?

To wersja produkcyjna na kanale testowym, ale przy sandboxie sprawa wyglądała identycznie.

Spróbuj zrobić zwykły najprostszy formularz ręcznie i zobacz czy działa. Może jeszcze nie aktywowali konta.

Problem wynikał ze złego typu sklepu. Powinien być ‘Płatności’, nie ‘Checkout’. Nie dotyczałem tego nigdzie, może przeoczyłem, ale zanim support do mnie odpisał z wyjaśnieniem, to trochę się naszukałem ocb :slight_smile:

Płatności robiłem 1 raz, wszystko już gra i wygląda na to, że działa. Dzięki za pomoc i dzięki Ronin za mega przydatny gemik :slight_smile:

Odkopuję. Postanowiłem jako ćwiczenie napisać sklep internetowy (yup, newb alert;) i doszedłem do punktu, w którym chciałbym zintegrować płatności internetowe. Gem Ronina wyglądał kusząco prosto, ale niestety odbijam się od ściany ze wspomnianym tu błędem 209. Korzystam z danych testowego POS od PayU, kod (próbuję na razie najprostszą metodą):

controller:

def payment
  pos = Payu::Pos.new :pos_id => '145227', :pos_auth_key => '13a980d4f851f3d9a1cfc792fb1f5e50', :key1 => 'xxxxxxxx', :key2 => 'xxxxxxxx', :add_signature => true
  @transaction = pos.new_transaction(:first_name => 'John', :last_name => 'Doe', :email => 'john.doe@example.org', :client_ip => '1.2.3.4', :amount => 10000, desc: 'sth')
end

widok (HAML):

= form_tag(@transaction.new_url) do
  = payu_hidden_fields(@transaction)
  = submit_tag 'Pay'

Wydaje mi się, że setup jest okej, ale najwyraźniej nie bardzo. Będę wdzięczny za jakieś wskazówki co dalej.

Rozwiązałeś już ten problem? Tak jak pisałem wyżej musisz mieć typ sklepu w PayU jako ‘Płatności’, a nie jako ‘Checkout’. Sprawdź jak to wygląda u CIebie :slight_smile: