Tommy Chheng

Icon

All Things Programming!

Paypal Adaptive Ruby Gem Released

I have been tinkering with the new Paypal Adaptive Payments API and created a simple ruby gem to interface with it. Still pretty new but I’m using it with little problems so far. Submit bug reports if found. See the code at github

Paypal Adaptive Payments API
The adaptive payments api gives you the opportunity to make preapproved payments, chained payments and parallel payments. The chained/parallel payments are great for commission-based apps or if you are trying to connect a buyer to multiple sellers with a single interface.

How to use with Rails:
Install:

sudo gem install paypal_adaptive

Setup your API info by adding a paypal_adaptive.yml to your config folder:


development:
  environment: "sandbox"
  username: "sandbox_username"
  password: "sandbox_password"
  signature: "sandbox_signature"
  application_id: "sandbox_app_id"

test:
  environment: "sandbox"
  username: "sandbox_username"
  password: "sandbox_password"
  signature: "sandbox_signature"
  application_id: "sandbox_app_id"

production:
  environment: "production"
  username: "my_production_username"
  password: "my_production_password"
  signature: "my_production_signature"
  application_id: "my_production_app_id"

Make the payment request:


pay_request = PaypalAdaptive::Request.new

data = {
"returnUrl" => "http://testserver.com/payments/completed_payment_request",
"requestEnvelope" => {"errorLanguage" => "en_US"},
"currencyCode"=>"USD",
"receiverList"=>{"receiver"=>
     [{"email"=>"testpp_1261697850_per@nextsprocket.com", "amount"=>"10.00"}]},
"cancelUrl"=>"http://testserver.com/payments/canceled_payment_request",
"actionType"=>"PAY",
"ipnNotificationUrl"=>"http://testserver.com/payments/ipn_notification"
}

pay_response = pay_request.pay(data)

if pay_response.success?
  redirect_to pay_response.approve_paypal_payment_url
else
  puts pay_response.errors.first['message']
  redirect_to failed_payment_url
end

Once the user goes to pay_response.approve_paypal_payment_url, they will be prompted to login to Paypal for payment.

Upon payment completion page, they will be redirected to http://testserver.com/payments/completed_payment_request.

They can also click cancel to go to http://testserver.com/payments/canceled_payment_request

The actual payment details will be sent to your server via “ipnNotificationUrl” You have to create a listener to receive POST messages from paypal. I added a Rails metal template in the templates folder which handles the callback.

Additionally, you can make calls to Paypal Adaptive’s other APIs:


payment_details, preapproval, preapproval_details,
cancel_preapproval, convert_currency, refund

Input is just a Hash just like the pay method. Refer to the Paypal Adaptive manual for more details.

Category: Programming, Ruby

Tagged: ,

  • bundacia
    This looks great. I am having one problem getting it to work though... I'm getting this error:

    /home/user/.rvm/rubies/ruby-1.9.2-head/lib/ruby/1.9.1/net/http.rb:677:in `connect': SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed (OpenSSL::SSL::SSLError)
    from /home/user/.rvm/rubies/ruby-1.9.2-head/lib/ruby/1.9.1/net/http.rb:677:in `connect'
    from /home/user/.rvm/rubies/ruby-1.9.2-head/lib/ruby/1.9.1/net/http.rb:637:in `do_start'
    from /home/user/.rvm/rubies/ruby-1.9.2-head/lib/ruby/1.9.1/net/http.rb:626:in `start'
    from /home/user/.rvm/rubies/ruby-1.9.2-head/lib/ruby/1.9.1/net/http.rb:1160:in `request'
    from /home/user/.rvm/rubies/ruby-1.9.2-head/lib/ruby/1.9.1/net/http.rb:970:in `post'
    from /home/user/.rvm/gems/ruby-1.9.2-head/gems/paypal_adaptive-0.1.0/lib/request.rb:79:in `call_api'
    from /home/user/.rvm/gems/ruby-1.9.2-head/gems/paypal_adaptive-0.1.0/lib/request.rb:31:in `pay'
    from ./test.rb:18:in `<main>'

    When rolling this stuff by hand without your gem the solution was to add this line:

    http.verify_mode = OpenSSL::SSL::VERIFY_NONE

    Where http is the Net::HTTP object. Is there a way to do the same thing using your gem, or is this something I've got misconfigured?

    Thanks.</main>
  • tommychheng
    This looks like a net::http error?

    If you are using Rails, you can try sticking http.verify_mode = OpenSSL::SSL::VERIFY_NONE into ssl.rb of config/initializers
  • bundacia
    Thanks for the reply. Actually, it looks like I can fix this by reopening the Net::HTTP class and tweaking the initialize method to it sets a ca_path for all new objects so it can find the right certificates. Here's what I did:

    class Net::HTTP
    alias :orig_initialize :initialize

    def initialize(*args)
    # Call the original init
    orig_initialize(*args)

    # Setup ssl cert path
    @ca_path = '/etc/ssl/certs'
    end
    end

    /etc/ssl/certs is where the certs live on Ubuntu. Don't know how common that is across platforms.
  • I am getting this error and used as the above example as stated above:

    undefined local variable or method `pp_response'

    please advice!

    Thank you for your time
  • tommychheng
    looks like a typo, it should be pay_response
  • Also can you fix it in github too ...http://github.com/tc/paypal_adaptive
  • tommychheng
    yes, i'll do it right now, thanks for catching it
  • Adam Eberlin
    looks great! good work!
  • JJ
    @Kevin you have to log in https://www.x.com/ and somewhere in profile you will find application_id. For production application_id you have to contact to paypal.
  • Kevin
    Hey Tommy... newbie question but I see the username/password/signature fields on my developer paypal screen but where do I find the application_id? Is that just an arbitrary name that I can pick or is it somewhere on developer.paypal.com?
  • tommychheng
    yes, sign up for an id at http://x.com
  • ncri
    Works fine now. But I'd require users to also be able to pay with credit card, without having a PP account, like it is possible with website payments standard checkout. Also I don't like the user to see how much money goes to which email address.

    So ideally I'd like PP Website Payments Standard checkout capability but diverting the payment to different paypal accounts in the background. I think this must be somehow possible.

    Any ideas are greatly appreciated.
  • tommychheng
    hi nico, you are right that paypal adaptive payments don't support credit card payments yet. It is scheduled in their roadmap. You can get a date from paypal to see how soon this is.
  • ncri
    Thanks for the info. Any references?

    Is your gem also supporting chained payments? That is more interesting for me, as I don't like payers to see all the receivers of the payment.
  • tommychheng
    There were a few posts on the http://x.com regarding CC payments coming in the near future.

    To do chained payments, just add a primary boolean flag:
    {"receiver"=> [{"email"=>"PRIMARY", "amount"=>"100.00", "primary" => true},
    {"email"=>"OTHER", "amount"=>"75.00", "primary" => false}]}
  • ncri
    Thanks!
  • ncri
    Hi. Looks good! Thx. Just trying it out.

    What do I need to put in application_id: "sandbox_app_id"?

    I didn't get one with my sandbox account and even googling doesn't reveal the answer...

    Nico


  • Do you have an example of how your gem does Parallel payments?
  • tommychheng
    Hey Matt,
    Just add two or more people to the receiverList to make it a parallel payment like:
    "receiverList"=>{"receiver"=>
    [{"email"=>"person1@chheng.com", "amount"=>"10.00"}, {"email"=>"person2@chheng.com", "amount"=>"20.00"}]},
  • guest2222222
    Hi Tommy,

    Above format is not working for me, getting an error message "This kind of unilateral payment is not allowed". I had provided API username, pass, signature. Do I missing something?

    Thanks
  • tommychheng
    hey, if you are getting a 'unilateral payment is not allowed', make sure the test email is a registered email in your sandbox account.
  • Coll !!!
blog comments powered by Disqus

Read Books on the Amazon Kindle 3