Przelewy24 - zakończenie transakcji?

Hej,

Próbuję podłączyć płatności przelewy24 z moją aplikacją (tak, niestety to nie ja wybrałam przelewy24 i nie jestem tu elastyczna :slight_smile: )
Postępuję zgodnie ze specyfikacją http://www.przelewy24.pl/files/cms/2/przelewy24_specyfikacja_3_2.pdf
Doszłam do momentu kiedy formularz wysyłany pod adres trnRegister zwraca poprawną wartość czyli:
error=0&token=…
…co powinno oznaczać, że nie ma błędów w wysyłanych danych (p24_sign).
Następnie, jeżeli decyduję się na bezpośrednią transkację trnDirect - ID i kwota się zgadzają, jestem przenoszona na odpowiednią stronę, płacę, mój bank mówi, że operacja została wykonana poprawnie… po czym przez długi czas mam okno
transakcja oczekuje na potwierdzenie,
żeby na koniec otrzymać
Opis błędu: Przekroczony czas na dokonanie transakcji ! (err102)

Owszem, nie potrafię poradzić sobie z punktem 5.4 Odbiór wyniku transakcji,
ustawiłam jako p24_url_return oraz p24_url_status jako ‘/result_payment’,
w routes.rb post ‘/result_payment’ => ‘payments#result’, as: ‘result_payment’,
w kontrolerze akcja result polega jedynie na
Payment.first.update(:p24_description => params[:p24_order_id]),
chciałam jedynie sprawdzić czy udaje mi się odebrać jakąś hm. Zwrotną akcję z przelewów :slight_smile: ale nijak sobie z tym nie radzę, nie udaje sie updatować, dopiero na koniec “błędnej transkacji” przenosi mnie na pożadaną stronę, ale już bez parametrów.

Czy jakaś dobra dusza pomogłaby z finalizacją transkacji :)?

Będę szalenie wdzięczna!

Hej,

Przechodziłem ostatnio przez implementację Przelewy24 i nie jest taka straszna jak Ci się wydaje :-). Po rejestracji transakcji musisz przekierować usera na stronę z płatnością (trnRequest) z odebranym tokenem, a po całej operacji musisz ją jeszcze zweryfikować.

Możesz użyć klineta: https://rubygems.org/gems/przelewy24_payment

2 Likes

Hej, dzięki za odpowiedź :)!
Mam pytanie - czy muszę koniecznie przechodzić przez rejestrację i zdobywanie tokenu? nie mogę bezpośrednio lecieć przez trnDirect?
Poza tym do tego momentu jeszcze jakoś sobie radziłam (a przynajmniej tak mi się wydawało :wink: ), bo przechodziłam przez cały proces płatności i… mam wrażenie, że problem polega na mojej “reakcji” na płatność. Poniźej wklejam kod z mojego kontrolera (bo rozumiem, że po wykonaniu płatności to wraca do miejsca wskazanego jako p24_url_return, tam pobieram dane wyznaczone przez przelewy (order_id, method, statement), po czym wysyłam pod /trnVerify kolejne dane i dopiero wtedy transkacja dochodzi do skutku?
W panelu przelewy24 mam informacje o dokonanym transakcjach ale sa oznaczone jako “Do wykrozystana” [w opisie: Do wykorzystania - Wykryto wpłatę ale wynik transakcji nie został odebrany przez sklep. Przyczyny:

  • transakcja w trakcie realizacji, Klient nie doszedł jeszcze do etapu przekazywania wyniku
  • wynik transakcji był wysłany do sklepu, ale nie został poprawnie przez sklep odebrany
  • wynik transakcji nie został wysłany do sklepu-Klient zbyt wcześnie zamknął przeglądarkę lub informacja o wpłacie pojawiła się po 15 minutach.]

def result

@payment = Payment.find_by_session_id(params[:p24_session_id])
if @payment && @payment.update_attributes(:p24_order_id => params[:p24_order_id],
                                                            :p24_method => params[:p24_method],
                                                            :p24_statement => params[:p24_statement])
  przelewy24_weryfikuj
else
  flash[:error] = 'Transaction not found'
  redirect_to cards_path
end

def przelewy24_weryfikuj

# verification script url
uri = URI.parse('https://secure.przelewy24.pl/trnVerify')

http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Post.new(uri.request_uri)
request.set_form_data(@payment.as_json)
http.use_ssl = true

# create new http object with ssl usage
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

# get the response from Przelewy24.pl
res = http.start {|http| http.request(request) }

case res
when Net::HTTPSuccess, Net::HTTPRedirection
  results = res.body.split("\r\n")

  if results[1] == "TRUE" || results[1] == "ERROR TEST"

    # check if transaction is not already used
    unless @payment.is_verified
      @payment.update_attribute(:is_verified, true)
      return
    else
      error_desc = t('transaction_already_used')
    end
  else
    error_desc = "#{results[2]} #{results[3]}"
  end
else
  error_desc = t('connection_error') 
end

Jcieslar trafiłam na Twojego gema z wielką radością w sercu, juz wcześniej :smiley:
Ale nie działał mi już testConnection
rake przelewy24_payment:test_connection
A ciężko mi uwierzyć, że to wina podanych przeze mnie danych, bo jak wysyłałam je wg dokumentacji 3.2 przelewów - uznawało md5(merchant_id|CRC) za poprawne :cry:

Krok z weryfikacja i redirectem używając tokena jest bardzo spoko i to moim zdaniem stanowi przewage Przelewy24 nad Transferuj, jednakże na początku może się wydawać dziwne :P. Odezwij się na priv z loginem na Skype, pokaże Ci jak to rozwiązałem u siebie.

A wysyłasz dane na poprawne środowisko sandbox/secure? Gdy masz
config.mode=:production
to zapytanie leci do https://secure.przelewy24.pl/testConnection, w przeciwnym wypadku do https://sandbox.przelewy24.pl/testConnection.

Przed chwilą przetestowałem rake przelewy24_payment:test_connection i zwrócił mi, dla poprawnych danych, error="0" oraz, gdy podałem błędne dane, error="1", errorMessage="Wrong CRC".

Dla potomnych, jeżeli ktoś trafi tutaj szukając pomocy :smile:
Faktycznie, @Wacaw - dziękuję, rzeczywiście wykonywałam test connection będąc w development ale uparcie wciskając dane ze środowiska secure :pensive:
Dzięki @jcieslar za gem!

Mimo wszystko postanowiłam zrobić to dalej bezgemowo (z ogromnym wsparciem @fizzlebubble, za które jestem hiper wdzięczna :wink: )

Wnioski i spostrzeżenia:
Ważne - SANDBOX wcale nie działa tak samo jak środowisko produkcyjne SECURE
Różnica polega na tym, że kiedy łączymy się z sandboxem - na adres wskazany w p24_url_return zwraca on POST-em dane takie jak order_id itp., które są konieczne do weryfikacji transakcji.
Efekt tego jest taki, że (tak jak jest to powiedziane w [specyfikacji][1]) - p24_url_status nie jest wymagany, weryfikację możemy przeprowadzić pod adresem wskazanym w p24_url_return bo dysponuje on koniecznymi do tego danymi

Inaczej jednak sprawa wygląda przy secure
Na adres p24_url_return użytkownik jest przenoszony po dokonaniu płatności, nie ważne czy jest ona poprawna czy nie. Jest to GET, a nie POST jak w przypadku sandboxa
Jeżeli ograniczymy się do tego adresu - nie zweryfikujemy jednak płatności ze swojej strony!
Aby to zrobić ustawienie parmetru p24_url_status wydaje się konieczne - to pod ten adres, POST-em zostaną wysłane dane zwrotne ze strony płatności, które my mamy przejąć, porównać z naszą “wizją płatności” - i odesłać na trnVerify - tylko wtedy płatność jest zatwierdzona! Oczywiście w pod tym adresem, po wysłaniu danych pod trnVerify dostaniemy zwrotnie informację o błędzie (lub jego braku) i możemy spokojnie ustawić dany Payment.update(:is_verified => true)
Jest to jednak już niezależne od uzytkownika, dzieje się “poza nim”. On wylądował pod adresem z p24_url_return i cała reszta go już “nie dotyczy”

Jeżeli gdzieś skłamałam w tym poście - proszę o zlinczowanie :wink:

Mam nadzieję, że komuś jeszcze kiedyś się przydadzą te spostrzeżenia :wink:
[1]: http://www.przelewy24.pl/files/cms/2/przelewy24_specyfikacja_3_2.pdf

2 Likes

Kolejną nieaktualną rzeczą w dokumentacji jest lista IP serwerów z których może przyjść request od Przelewy24. Poniżej aktualna lista

217.168.139.48 – 217.168.139.55
217.168.128.198 – 217.168.128.202
91.216.191.181 – 91.216.191.185

Hej,

Odświeżam trochę temat, zaczynam dopiero integrację z Przelewy24 i od razu problemy. Mianowicie, chcę sprawdzic połączenie i wywołuje z formularza metodą GET następujący link:

https://secure.przelewy24.pl/testConnection?p24_merchant_id=47922&p24_pos_id=47922&p24_sign=dlugi_kod

Dodam, że używam dobrego kodu CRC dla prawdziwego serwera, próbowałem też kodu z sandbox i z serwerem sandbox, próbowałem nawet kodu CRC z sandbox dla serwera live i odwrotnie - za każdym razem ten sam error: error=1&errorMessage=Wrong CRC.

jedyna możliwość jaką widze, to że źle generuje p24_sign, w moim przypadku robie to tak:
md5(“47922|kod_CRC_odpowiedni dla srodowiska”);

Czy coś robie nie tak? Prosze o pomoc…

Pozdrawiam,
drejas

Próbowałeś już może w ten sposób https://github.com/jcieslar/przelewy24_payment/blob/master/lib/przelewy24_payment.rb#L94

Hej,

Z tego
Digest::MD5.hexdigest(session.to_s + “|” + merchant.to_s + “|” + amount.to_s + “|” + currency.to_s + “|” + crc.to_s)

wynika, że powinienem polaczyc nie tylko p24_pos_id oraz klucz CRC ale tez pare innych pól

Z dokiumentacji technicznej Przelewy24:
p24_sign STRING(100) T to wartość funkcji MD5 z
połączonych ze sobą pól:
p24_pos_id oraz klucza
CRC. Łącznikiem pól jest
znak „|”.

p24_pos to ID sprzedawcy

ale ja chce tylko przetestowac polaczenie wiec po co mi amount, cuyrrency, session?

Pozdr,
Lukasz

bo to suma kontrolna a nie to co chcesz sobie wysłać

Sumę kontrolną p24_sign obliczamy wg poniższego wzoru:
p24_sign => to wartość funkcji MD5 z połączonych ze sobą pól: p24_session_id,
p24_merchant_id, p24_amount,p24_currency oraz klucza CRC. Łącznikiem pól jest znak „|”.

pozdr/.

Nie wiem czy testowałeś gem - tam jest możliwość przetestowania połączenia:

rake przelewy24_payment:test_connection
#kod https://github.com/jcieslar/przelewy24_payment/blob/master/lib/tasks/test_connection.rake

Gdzie faktycznie używane są tylko dwa parametry: https://github.com/jcieslar/przelewy24_payment/blob/master/lib/przelewy24_payment.rb#L152

Witam, jestem bardzo bardzo początkujący w RoR i przy implementacji Przelewów24 napotkałem mur nie do przeskoczenia. Do implementacji użyłem gem’a od @jcieslar, skonfigurowałem go i poprawnie przenosi mnie do strony z płatnością, jednakże po dokonaniu płatności otrzymuję błąd:

NoMethodError in PaymentsController#comeback
undefined method `force_encoding' for nil:NilClass

Oczywiście url_status oraz url_return prowadzą do akcji comeback w moim kontrolerze zgodnie z instrukcją implementacji gem’a
Osobiście upatrywałbym problemu w tym, że przelewy24 nie zwracają mi żadnych parametrów transakcji
W widoku moich płatności oczywiście posiadam

 <%= payment_button(@data) %>

Do rozpoczęcia transakcji.
Test connection przechodzę poprawnie bez żadnych błędów, oczywiście jestem w środowisku deweloperskim. To chyba wszystko co istotne.
Prawdopodobnie więc pogłubiłem się gdzieś w wysyłaniu lub odbieraniu danych, jednakże nie mam kompletnie pomysłu jak sobie z tym poradzić. Możliwe, że to jakaś pierdoła za którą będzie mi wstyd jak trochę się podszkolę jednak mimo wszystko w tym momencie uprzejmie proszę Was o pomoc.

Wygląda jakbyś dostał b.dziwną odpowiedź, lub API Przelewy24 się zmieniło.
Twój błąd rzuca ten fragment: https://github.com/jcieslar/przelewy24_payment/blob/master/lib/przelewy24_payment.rb#L167

Z tego co wiem API się nie zmieniło, nadal jest w wersji 3.2.
Tak wygląda mój kontroler płatności

class PaymentsController < ApplicationController
          include Przelewy24PaymentController


  def index
    @payments = Payment.all
  end



  def show

    @payment = Payment.find(params[:id])


        @data = { :session_id =>  @payment.session_id,
              :description => @payment.porada.title,
              :amount => @payment.porada.cena,
              :email => @payment.user.email,
              :country => 'PL',
              # adding this params, you overwrite your config settings so this param is optional
              :merchant_id => ‚XXXXX’,
              :pos_id => ‚XXXXX’,
              :api_version => '3.2',
              :crc_key => ‚XXXXXXXXXXX’,
              :currency => 'PLN',
              :country => 'PL',
              # :url_return => url_return,
              # :url_status => url_status,

              # other optional params
              # :language => pl/en/de/es/it
              # :method => method,
              # :client => 'Adam Nowak',
              # :address => 'Powstancow 22/2',
              # :zipcode => '53-456',
              # :city => 'Wroclaw',
              # :phone => '481321132123',
              # :time_limit => INT,
              # :wait_for_result => INT,
              # :channel => INT,
              # :shipping => INT,
              # :transfer_label => STRING(20)
              # :encoding => ISO-8859-2/UTF-8/Windows-1250

            }

  end



  def new
      @payment = Payment.new(:porada_id => params[:id])
  end

  def edit
  end

  def create
        @payment = Payment.new(payment_params)
    @payment.session_id = Przelewy24Payment.friendly_token[0,20] 
    @payment_porada = @payment.porada
        @user = current_user
        @payment.user_id = current_user.id
        @payment.user = current_user

    respond_to do |format|
      if @payment.save
        format.html { redirect_to @payment, notice: 'Payment was successfully created.' }
        format.json { render :show, status: :created, location: @payment }
      else
        format.html { render :new }
        format.json { render json: @payment.errors, status: :unprocessable_entity }
      end
    end
  end


  def update
    respond_to do |format|
      if @payment.update(payment_params)
        format.html { redirect_to @payment, notice: 'Payment was successfully updated.' }
        format.json { render :show, status: :ok, location: @payment }
      else
        format.html { render :edit }
        format.json { render json: @payment.errors, status: :unprocessable_entity }
      end
    end
  end


  def destroy
    @payment.destroy
    respond_to do |format|
      format.html { redirect_to payments_url, notice: 'Payment was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  def payment_success(payment_params)
    # payment_params returns hash with:
    # p24_merchant_id
    # p24_pos_id
    # p24_session_id
    # p24_order_id
    # p24_amount
    # p24_currency
    # p24_method
    # p24_sign
    # p24_karta
    # payment_id
    # e.g
    # payment = Payment.find_by_session_id(payment_params[:p24_session_id])
  end

  # after error payment this method will be trigger
  # so you can do whatever you want
  def payment_error(payment_params, code, description)
    # payment_params returns hash with:
    # p24_merchant_id
    # p24_pos_id
    # p24_session_id
    # p24_order_id
    # p24_amount
    # p24_currency
    # p24_method
    # p24_sign
    # p24_karta
    # payment_id
    #
    # code return error code
    # description return error description
  end

  # method to setup params to verify it final verifyciation
  # so you can do whatever you want
  def payment_verify(response_params)
    # e.g:
    # you must return hash with amount which was save in your db and your crc_key
    payment = Payment::Payment.where(session_id: response_params['p24_session_id']).first
    if payment
      { amount: payment.amount, crc_key: Przelewy24Payment.crc_key }
    else
      {}
    end
  end







  private




    # Use callbacks to share common setup or constraints between actions.
    def set_payment
      @payment = Payment.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def payment_params
      params.require(:payment).permit(:amount, :porada_id, :user_id)
    end
end

A tak plik z konfiguracją

Przelewy24Payment.setup do |config|
  config.merchant_id = 'XXXXX'
  config.pos_id = 'XXXXX'
  config.crc_key = 'XXXXXXXXXXXXXXXXXXXX'
  config.language = 'pl'
  config.currency = 'PLN'
  config.country = 'PL'
  config.mode = :development
  config.url_status = '/kam'
  config.url_return = '/kam'
  config.hostname = {
      :development => "http://127.0.0.1:3000",
      :production => "mydomain.pl",
      :staging => "staging.domain"
  }
end

get '/kam' => 'payments#comeback'

Może problem tkwi w tym, że url_status oraz return nie prowadzą bezprośrednio do payments/comeback, z uwagi na to, że ten ta ścieżka odpowiada za akcje show więc ruby szukało po prostu płatności z ID comeback.
Reasumując użytkownik w widoku show widzi wszystkie parametry płatności, klika payment_button i zostaje przenoszony poprawnie na strone przelewow 24 gdzie wszystkie dane typu id sprzedawcy, kwota, tytul są poprawne, jednakże po płatności w momencie gdy powinny zostać odebrane dane służące do weryfikacji nie otrzymuję niczego, przez co transakcja nie może dojść do skutku i w panelu sandboxa posiada status “do wykorzystania”
Prawdopodobnie pomieszałem coś z implementacją, jednak kompletnie nie wiem jak sobie z tym poradzić :confused:

Jeszcze wklej jakie parametry dostajesz po przekierowaniu z P24.

Właśnie problem tkwi w tym, że po dokonaniu płatności nie dostaję żadnych parametrów.

A ścieżka przekierowania jest po prostu “/kam” czy masz jakieś dodatkowe parametry GET?