Delivery status Failed notify_url IPN in ruby on r

2019-03-06 04:51发布

问题:

I get the following error:

2015-08-17T18:46:59.095260+00:00 heroku[router]: at=info method=POST path="/payment_notification" status=500

this is my model:

class Product < ActiveRecord::Base
def paypal_encrypted(return_url, notify_url, cancel_return, useremail) 
        values = { 
        :business => 'facilitatoremail@example.com',
           :cmd => '_xclick',
        :upload => 1,
        :return => return_url,
        :rm => 1,
        :notify_url => notify_url,
        :cancel_return => cancel_return,
        :custom => useremail,
        :cert_id => 'myid'
        }   
        values.merge!({ 
        "amount" => unit_price,
        "item_name" => name,
        "item_number" => id,
        "quantity" => '1'
        })

        encrypt_for_paypal(values)
    end



    has_many :payment_notifications
end

PAYPAL_CERT_PEM = File.read("#{Rails.root}/certs/paypal_cert.pem")
APP_CERT_PEM = File.read("#{Rails.root}/certs/app_cert.pem")
APP_KEY_PEM = File.read("#{Rails.root}/certs/app_key.pem")

def encrypt_for_paypal(values)
  signed = OpenSSL::PKCS7::sign(OpenSSL::X509::Certificate.new(APP_CERT_PEM), OpenSSL::PKey::RSA.new(APP_KEY_PEM, ''), values.map { |k, v| "#{k}=#{v}" }.join("\n"), [], OpenSSL::PKCS7::BINARY)
  OpenSSL::PKCS7::encrypt([OpenSSL::X509::Certificate.new(PAYPAL_CERT_PEM)], signed.to_der, OpenSSL::Cipher::Cipher::new("DES3"), OpenSSL::PKCS7::BINARY).to_s.gsub("\n", "")
end

My controller for the post is:

class PaymentNotificationController < ApplicationController
    protect_from_forgery :except => [:create]

  def create
    @payment = PaymentNotification.create!(params: params, product_id: 1, status: params[:payment_status], transaction_id: params[:txn_id], email: params[:custom] )
    render nothing: true

    if @payment.status == 'Completed'
      PaymentTransactions.success(@payment).deliver_now
    end

  end
end

My button:

<%= form_tag "https://www.sandbox.paypal.com/cgi-bin/webscr" do %>
  <%= hidden_field_tag :cmd, "_s-xclick" %>
  <%= hidden_field_tag :encrypted, @product.paypal_encrypted(root_url, payment_notification_index_url, root_url, :custom) %>
  <%= text_field_tag :custom %>
  <%= submit_tag 'checkout encrypted' %>
<% end %>

I'm not sure what I'm doing wrong here.

Paypal sends the POST but I get the error STATUS=500

All the payment proceed normally but I just want that paypal do a POST using notify_url.

I'm testing this in Heroku since testing locally will not work.

Also, if I use the return_url to make the post instead, it will work and return STATUS=200.

But I don't want to use this since the gap between the user doing the transaction and being redirected back to the return_url.

EDIT

after integrating Airbrake this is what I got in return

EDIT 2

I changed the data encoding for data sent from PayPal to UTF-8

When I tried again, the status was still 500 but I got the transaction saved in the database BUT paypal kept getting a failed attempt and kept retrying so instead of one record being saved I had multiple records

The error I'm getting now is this one:

Right now at least the transactions are saved but paypal seems to fail to recognized that.

SOLVED

Apparently, it was my mailer that wasn't configured in production.. I was just able to comment that part and push in heroku and tried again. It successfully went trough with a STATUS=200 and the error was solved in Airbrake.

Thank you all!

回答1:

Did you set your system encoding in PayPal account? It's somewhere under 'PayPal button encoding' in your profile, and you should set 'Send the data to me in the same encoding' to UTF-8.

As was discovered in comments, another error was due to misconfigured mailer. Note that #render call doesn't send data to client immediately, it just queues it until action ends.