Question

I am using this gem for payments in paypal https://github.com/tc/paypal_adaptive

I am very confused and disoriented with this gem. It has a poorly documented and is difficult for me to understand how to get the data from paypal on ipn response.

I hope this question will help more people having the same problem.

My steps are:

I send request to paypal from my orders_controller.rb with method preaproval_payment.

def preapproval_payment
preapproval_request = PaypalAdaptive::Request.new
data = {
  "returnUrl" => response_paypal_user_orders_url(current_user),
  "cancelUrl"=>  cancel_payment_gift_url(@gift),
  "requestEnvelope" => {"errorLanguage" => "en_US"},
  "senderEmail" => "gift_1342711309_per@gmail.com",
  "startingDate" => Time.now,
  "endingDate" => Time.now + (60*60*24) * 30,
  "currencyCode"=>"USD",
  "maxAmountPerPayment" => "@gift.price",
  "ipnNotificationUrl" => ipn_notification_url,
  "ip" => request.remote_ip
  }
    preapproval_response = preapproval_request.preapproval(data)
    puts data
  if preapproval_response.success?
    redirect_to preapproval_response.preapproval_paypal_payment_url
  else
    redirect_to gift_url(@gift), alert: t(".something_was_wrong")
  end
end

These are the data of my request in my log console from command puts data :

{"returnUrl"=>"http://localhost:3000/en/u/maserranocaceres/orders/response_paypal", "cancelUrl"=>"http://localhost:3000/en/gifts/gift-1/cancel_payment", "requestEnvelope"=>{"errorLanguage"=>"en_US"}, "senderEmail"=>"gift_1342711309_per@gmail.com", "startingDate"=>2012-07-29 13:05:49 +0200, "endingDate"=>2012-08-28 13:05:49 +0200, "currencyCode"=>"USD", "maxAmountPerPayment"=>9, "ipnNotificationUrl"=>"http://localhost:3000/ipn_notification?locale=en", "ip"=>"127.0.0.1"}

I redirect to paypal page, and I make the payment on paypal successfully :D.

When payment is completed successfully, I am directed to:

http://localhost:3000/en/u/maserranocaceres/orders/response_paypal

I have response_paypal action in orders_controller.rb. It is GET action and my code for this action is:

def response_paypal
  respond_to do |format|
       format.html { redirect_to user_orders_url(current_user), :alert => "works fine return url"}
    end
 end

Up to this point everything works fine.

Now what I need is to get the data I received from paypal and save my database a new order if payment is successfully processed.

For this purpose I make a file in lib/paypal_ipn.rb and I add to this file the content from https://github.com/tc/paypal_adaptive/blob/master/templates/paypal_ipn.rb

# Allow the metal piece to run in isolation
require(File.dirname(__FILE__) + "/../../config/environment") unless defined?(Rails)

class PaypalIpn
  def self.call(env)
    if env["PATH_INFO"] =~ /^\/paypal_ipn/
      request = Rack::Request.new(env)
      params = request.params
      ipn = PaypalAdaptive::IpnNotification.new
      ipn.send_back(env['rack.request.form_vars'])
      if ipn.verified?
        #mark transaction as completed in your DB
        output = "Verified."
      else
        output = "Not Verified."
      end

      [200, {"Content-Type" => "text/html"}, [output]]
    else
      [404, {"Content-Type" => "text/html"}, ["Not Found"]]
    end
  end

end

In my routes.rb I add:

match "/ipn_notification" => PaypalIpn

My 2 problems are:

a) I do not see that after making the payment this file to be fired and I can not see in my console data I get from paypal.

b) I want to send to paypal in my request, the id of object @gift for being able to recover later in paypal_ipn.rb and to save my database.

What am I doing wrong and how I can solve these problems?

Thank you

Was it helpful?

Solution

I haven't used that gem, but I've used PayPal IPN before. Here are some things you should check:

  1. Do you have your PayPal account set up to use IPN? You must enable this setting on the account for this to work.

  2. Have you verified that when you pass ipn_notification_url during the payment process, that it matches your "/ipn_notification" route?

  3. For this to work, PayPal must be able to communicate directly with the server that is running this app. This means that typically, unless you have a custom setup on your local machine with dynamic DNS or something, that you will need to actually deploy this code to a server in order for PayPal to be able to communicate with your app. In other words, if this is running on http://localhost:3000, this will not work.

To answer your second question, how to recover @gift in order to record the fact it was paid in your database, I'm not entirely sure how to do it with this gem, but I'll tell you how I do it using ActiveMerchant - it is probably quite similar.

  1. In your payment request to PayPal, you can pass in an invoice number. I believe the field is just called "invoice". Here you would pass the ID of the gift.

  2. When PayPal notifies your app via IPN that the order was paid for, it will pass the invoice number back to you. Retrieve the @gift using this invoice number and then you can do what you need with it.

Here are the relevant parts of my working PayPal code, using the ActiveMerchant gem: https://gist.github.com/3198178

Good luck!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top