22
Oct

Using Paypal with Rails

posted by vdimos 79 comments rails

For our latest joint venture we need to implement some kind of payment gateway.
The requirements were simple:

  • We need it secure
  • We need it simple
  • We need it now

The project was a complete overhaul of a job posting site : www.freshwebjobs.com

The talented folks over at Extendio had done a very nice job reskinning the site, and they wanted us to update the codebase, add RoR hype ,some new hooks and features.

The first thing that you think of when doing RoR and e-Commerce is Shopify.
Shopify was created by jadedPixel. They extracted their accumulated e-shopping wisdom and gave the community Active Merchant. AM does a great job in abstracting payment gateway complexity and allowing you to use and switch different payment gateways.
Our first choice for a payment gateway was AuthorizeNet.
The whole RoR community seems to be using it, and their rates were quite acceptable.

The only problem is they work only with US-based companies.
Apparently most of the payment gateways supported by AM do.

After some research we stumbled upon “PayPal Website Payments Standard” (PPWPS). It is the simplest form of payment services offered by Paypal, allowing you to accept credit card and paypal payments.

Ok here is how it works:
The customer lands on your payment page. You can set up encrypted buttons with different amounts. The customer clicks on a button and is redirected to a paypal page where he can use his credit card or paypal login to issue the payment. After doing so he is redirected to your site (or wherever you specify) while an asynchronous notification system lets you know that you have received a payment.

Getting started

In order to get started with PPWPS we need to set up an Sandbox account.
Paypal is providing developers with a virtual sandbox where you can make transactions without real money changing hands.
Before you can use the sandbox you need to create a developer account and log into it.

After you created your developer account make sure you create two test accounts for the sandbox.
One should be a business account the other a simple client account.

When done try to log in at www.sandbox.paypal.com.

Ok we now have our developer account and two accounts for the sandbox.

Paypal requires you to be logged into your developer account when trying to access the sandbox.

As a tip log with one of your browsertabs into your developer account and since the session timeouts pretty quick use autoreload, to reload the index page every 5 minutes.

Initial Setup

First thing we need to make sure is our application is playing in test mode. Test mode means that instead of using the original paypal infrastructure all request are made to the sandbox.

In your config/environment.rb file add the following lines:

# Ensure the gateway is in test mode
 ActiveMerchant::Billing::Base.gateway_mode = :test
 ActiveMerchant::Billing::Base.integration_mode = :test
 ActiveMerchant::Billing::PaypalGateway.pem_file =
                 File.read(File.dirname(__FILE__) + '/../paypal/paypal_cert.pem')

The above code will make sure AM is in test mode. Also it will include the paypal certificate.

Certificates

To get the paypal certificate and setup your own, we will need to log into the sandbox with your business test account.

The paypal sandbox can be somehow slow. Patience young jedi, patience…

When logged go to your “Profile” – “Encrypted Payment Settings”. Here download the paypal public certificate and store it in a folder in your application. I created a paypal folder in the root folder of the application. If you use something else make sure you update the references in environment.rb and crypto42.rb later on.

We will need to create some certificates ourselfes. If you are on a linux box do something like this:

 penssl genrsa -out my-prvkey.pem 1024

then

openssl req -new -key my-prvkey.pem -x509 -days 365 -out my-pubcert.pem

In Ubuntu running the above without sudo throws some errors for me about beeing unable to use the random number generator. If you are not using Linux, consider using it :) .

The above should leave you with two files. my-prvkey.pem and my-pubcert.pem. Move both files into the paypal folder with the paypal public certificate.

Now return to your sandbox account and in “Your Public Certificates” upload your public certificate.
After you added it you will see it in the listing with a Cert ID. Keep this Cert ID for later use.

Lib, controller and the view

Lets get down and write some code.

Here is a snippet I got from the internet and changed it a bit to fit my needs:

module Crypto42
  class Button
    def initialize(data)
      my_cert_file = Dir.getwd + "/paypal/my-pubcert.pem"
      my_key_file = Dir.getwd + "/paypal/my-prvkey.pem"
      paypal_cert_file = Dir.getwd + "/paypal/paypal_cert.pem"

      IO.popen("/usr/bin/openssl smime -sign -signer #{my_cert_file} -inkey #{my_key_file} -outform der -nodetach -binary | /usr/bin/openssl smime -encrypt -des3 -binary -outform pem #{paypal_cert_file}", 'r+') do |pipe|
        data.each { |x,y| pipe << "#{x}=#{y}\n" }
        pipe.close_write
        @data = pipe.read
      end
    end

    def self.from_hash(hs)
      self.new hs
    end

    def get_encrypted_text
      return @data
    end

  end #end button
end #end module

Simple save the above piece of code into a file in your applications lib directory.
It basically calls the system openssl (make sure you have it installed) function to encrypt some data we pass in as argument.

We have following scenario for our site. The customer gets at some point to a page where we want to allow him to choose and buy between N distinguish options.
These options will be buttons linking to Paypal. Upon clicking them the customer will be able to use Paypal to do the purchase.

Paypal lets you create buttons like this through their webpage, but these buttons are fixed and cannot be used to carry extra variables like maybe an invoice number.

We want to create such buttons ourselfes everytime a user comes to our payment site.

Here is how our users controller would look like:

class UsersController < ApplicationController

  include ActiveMerchant::Billing::Integrations
  require 'crypto42'
  require 'money'

... Different user functions...

#place order is for a specific job
  def place_order

    @job = Job.find(params[:job_id])
    fetch_decrypted(@job)

    if @logged_user.credits > 0
      render(:action => "confirm_order")
      return
    else
      #place order will have our paypal buttons
      render(:action => "place_order")
      return
    end

  rescue ActiveRecord::RecordNotFound
    flash[:alert] = "Buying credits for fun?"
    redirect_to :action => "profile"
  end

...

private
  def fetch_decrypted(job = nil)

    # cert_id is the certificate if we see in paypal when we upload our own certificates
    # cmd _xclick need for buttons
    # item name is what the user will see at the paypal page
    # custom and invoice are passthrough vars which we will get back with the asunchronous
    # notification
    # no_note and no_shipping means the client want see these extra fields on the paypal payment
    # page
    # return is the url the user will be redirected to by paypal when the transaction is completed.
    decrypted = {
      "cert_id" => "cert id from your paypal business account",
      "cmd" => "_xclick",
      "business" => "name@yourpaypal.com",
      "item_name" => "FWJ - 1 Credit",
      "item_number" => "1",
      "custom" =>"something to pass to IPN",
      "amount" => "75",
      "currency_code" => "USD",
      "country" => "US",
      "no_note" => "1",
      "no_shipping" => "1",
    }

    if job
      decrypted.merge!("invoice" => "Another passthrough var", "return" => "http://www.freshwebjobs.com/users/done?job_id=#{job.id}")
    else
      decrypted.merge!("return" => "http://www.freshwebjobs.com/users/done")
    end

    @encrypted_basic = Crypto42::Button.from_hash(decrypted).get_encrypted_text


     @action_url = ENV['RAILS_ENV'] == "production" ? "https://www.paypal.com/uk/cgi-bin/webscr" : "https://www.sandbox.paypal.com/uk/cgi-bin/webscr"
end

Now we have our encrypted button code so we can use it like this in the view:

<form action="<%= @action_url %>" method="post">
          <input type="hidden" name="cmd" value="_s-xclick" />
          <input type="hidden" name="encrypted" value="<%= @encrypted_basic %>" />
          <input type="image" src="/images/btn_buynow_SM.jpg" name="submit" alt="3 credits">
</form>

@action_url is set by us depending on the mode.

IPN – Instant (?) Payment Notification

With all the above done, you should have a working payment site! Actually you could stop here and track the transactions via paypal. That would be rather weird though since the application would have no kind of automated feedback about the transactions.
That is where IPN, Paypals’ automated asynchronous event notification system, comes into play.
To set it up we need to enter the sandbox business account again, and go to “Profile” → “Instant Payment Notification Preferences”. Turn it on and set the URL to a URL of you application we are going to use to handle IPNs.

Update: As Mathias mentions in the comments, the IPN URL can be passed as a separate button parameter to Paypal instead of hardcoding it as mentioned above

Here is the code fragment to handle the IPNs, pretty much as it is in the AM source code:

  def ipn
    # Create a notify object we must
    notify = Paypal::Notification.new(request.raw_post)

    #we must make sure this transaction id is not allready completed
    if !Trans.count("*", :conditions => ["paypal_transaction_id = ?", notify.transaction_id]).zero?
       # do some logging here...
    end


    if notify.acknowledge
      begin
        if notify.complete?
           #transaction complete.. add your business logic here
        else
           #Reason to be suspicious
        end

      rescue => e
        #Houston we have a bug
      ensure
        #make sure we logged everything we must
      end
    else #transaction was not acknowledged
      # another reason to be suspicious
    end

    render :nothing => true
  end

Everytime a user pays us, Paypal will issue a request to the IPN url appending a bunch of usefull information. AM is used to acknowledge the request (to make sure noone is spoofing them) and if everything is ok we can add the credits to the user.

Moving into production mode

In order to move our site into production mode we must not forget following things:

  • Change :test to :production in environment.rb
  • Download the real Paypal certificate from your real business account.
  • Upload your own certificates to our account.
  • Change the values for Cert_id, business_name, and returnURL in your button code in the controller
  • Change the IPN URL in your business account profile.
  • Additionaly you can check the allow only encrypted payments in your profile, and check the other settings as well.

To do some basic testing in the real world you can temporarily change the charged amount, make a purchase then issue a refund through paypal.

Ok I think I have covered the basics. Next post will be about testing IPN with mock objects.

Comments (79)

Pin Mathias said on Oct 26, 10:31 AM:

There's also a small-ish Paypal gem which only includes four classes but works just as well, including sandbox mode.

As a side note: You don't need to configure a specific IPN-URL in your Paypal profile. It does need to have one configured, but you can include it in the commands you send to Paypal (parameter is notify_url). It will be stored for each transaction made, and will be used for each subsequent IPN notification (if there are any more) for this transaction. This makes testing a little bit easier.

Pin vdimos said on Oct 26, 03:09 PM:

Thanks for the tip Mathias. I updated the post.

Pin Paul said on Nov 15, 05:04 PM:

I've used your tutorial to get paypal ipn integration successfully working, thank you for sharing this information.

However, when the user is returned after the transaction they are logged out of my site. This is not happening every time though.

Do you know why this might be happening? I appreciate this is probably a paypal issue, but I just wondered if you might have come across it before or be able to point me in the right direction.

Pin vdimos said on Nov 20, 12:00 PM:

Hey Paul,
Glad you could use the information. We didn't have any issues like the ones you mention, but my first guess would be to check you are redirected to the same domain, and check the cookie with the session_id to see if it is correct.
Best of Luck

Pin alexey said on Jan 10, 11:30 AM:

Great tutorial Vdimos !

i was suggest to add:
./script/plugin install http://activemerchant.googlecode.com/svn/trunk/active_merchant

for some reason installing active_merchant *gem* isnt worked (require "activemerchant" works but ActiveMerchant::Billing::Base.gateway_mode = :test doesnt)

Only installing plugin is solved problem ;(

Pin vdimos said on Jan 10, 04:36 PM:

Hey Alexey! Hope the tutorial was of some help. In fact to install the activemerchant gem the syntax is sudo gem install activemerchant. Best of luck, cheers Vasilis..

Pin anton said on Jan 11, 05:46 PM:

The crypto42.rb brings in the line: @data = pipe.read
the message: Loading 'screen' into random state -Loading 'screen' into random state - done
unable to write 'random state'
I have Vista running. Has anybody an idea how to fix the problem?

Pin vdimos said on Jan 14, 04:37 PM:

Hey anton,
I am pretty sure it is the syscall to the openssl binary, since it uses the random number generator of the underlying OS (i think). Since I don't have Vista, I can't really say much more, except to try the syscall from the command line yourself. Please let us know if you worked the issue out, so I can update the post. Best of Luck, Vasilis

Pin GregFu said on Jan 15, 06:54 AM:

@alexy

make sure you:

require "active_merchant" # not the underscore

Pin Geoff said on Feb 05, 11:27 AM:

Thanks for the tutorial! It was very useful. I did run into one problem. When clicking on my button I would get the following error from PayPal:

"We were unable to decrypt the certificate id."

If you see this problem, it's likely one of 2 things:

1 - You got the certs between the sandbox and the live site mixed up somehow. (this didn't happen to me, but while I was looking for a solution I found that this was often given as a reason)

2 - There are newline characters in the encrypted string. My form (for some unkown reason) was getting formed like so:




To fix it I just added the following to my controller:
@encrypted_basic = @encrypted_basic.gsub("\n","")

Pin Geoff said on Feb 05, 01:57 PM:

My last post isn't entirely correct :-S
While remove the newline characters from the encrypted field was required to get rid of the "decrypt the certificate id" issue, I began to get "email address for the business is not present in the encrypted blob" which means that something is going wrong with the encryption.

All the help seems to point at (again) 1 of 2 things:
- Wrong keys/certificates (I've check and check again)
- Some problem with encryption.

My testing has led nowhere so far, though I think this and the previous spacing thing are related. I've tried both on my windows machine (running local) and a test server running linux. :-( I'll post here if I figure it out.

Pin Prateek said on Apr 21, 07:48 PM:

Thanks for the writeup. This was very very useful

Pin John said on May 01, 11:18 PM:

Useful tutorial. And is that vim? Nice color scheme. What is it?

Pin Zan said on May 03, 06:24 AM:

Thanks for the tutorial! I was puzzled over the encryption part til I came here =)

Pin JDJ said on Jun 02, 05:16 AM:

I'm still stuck on the "email address for the business is not present in the encrypted blob" error. What's weird is that everything works fine on my dev machine, but now I'm getting that error on the production server. Dev machine is OS X 10.5, production server is Ubuntu 6.06 (set up via Deprec). I think I've toggled everything needed for the production environment, but no love. Anyone have any ideas?

Pin Shankar said on Jun 05, 02:28 PM:

Thanks for this.

Pin Matt Colyer said on Jun 08, 11:53 PM:

In order to get around the certificate decode errors I had to strip all newlines out of the encrypted data.

If you take line 63:
@encrypted_basic = Crypto42::Button.from_hash(decrypted).get_encrypted_text

And add a gsub to the end
.get_encrypted_text.gsub("\n","")

It should work.

Pin Paul said on Jul 10, 05:12 PM:

I can confirm that OpenSSL 0.9.7a doesn't suffer from the encryption issues.

Pin JJ said on Nov 10, 03:54 PM:

I have empty @encrypted_basic, any ideas?

Pin MikeL said on Nov 14, 12:33 AM:

I was getting an InvalidAuthenticityToken error so I turned it off by added the following:

protect_from_forgery :except => [:ipn, :done ]

If there is a better work around for this issue?

Pin tommy said on Oct 27, 09:14 PM:

i also getting an InvalidAuthenticityToken error anybody can help me?

Pin insurance said on Nov 05, 06:23 AM:

Thanks for the tutorial! I was puzzled over the encryption part til I came here =)

Pin hot ugg boots said on Nov 19, 04:26 AM:

Mrs Brown went to visit one hot ugg sale of her friend and carried a small box with holes punched in the top." What's in your box?" Classic Cardy Ugg Boots asked the friend. "A cat," answered Mrs Brown. "You see I've been dreaming about mice at night and I'm so scared! This cat is to catch them." "But the mice are only Classic Short Ugg Boots imaginary," said the friend."So is the cat," whispered Mrs Brown.

Pin car insurance comparsion said on Dec 04, 06:36 AM:

Thanks for the tutorial! Thanks for the tips.

Pin mania virtual said on Dec 04, 07:23 PM:

Excellent article, thanks for sharing it.

Pin property in calabria said on Dec 06, 06:09 AM:

this is what I need, I am confused how to install it. codenya very long time. fortunately I found this website. thank you for the information how to install, very helpful at all.

Pin Technology said on Dec 06, 07:03 AM:

programming language is very much at all. I do not understand at all. thanks to this tutorial is very useful, thank you for sharing this tutorial. I want to use Paypal with Rails.

Pin Limousine NY said on Dec 07, 04:58 PM:

These kind of articles are always attractive and I am happy to find so many good point about using the Paypal with Rails, the coding is really very helpful. Thanks for sharing.

Pin long term treatment centers said on Dec 08, 09:08 AM:

I am just new to your blog and just spent about 1 hour and 30 minutes lurking and reading. I think I will frequent your blog from now on after going through some of your posts. I will definitely learn a lot from them.
Regards - Gerry

Pin Wilbert said on Dec 09, 07:57 PM:

Security is very important especially when dealing with e commerce. This is great to know about how some people are working in this field.

Pin vijay said on Dec 11, 09:13 AM:

The PayPal Ruby on Rails SDK eases the process of integrating PayPal's financial services into your application by providing a small footprint of three files: caller.rb, profile.rb, and utils.rb. The packages comes with web samples written for Ruby on Rails that illustrate how to use PayPal NVP Web Services API, including examples for Direct Credit Card Payment, Express Checkout, TransactionSearch, Refund, Void, and Capture.editorial articles

Pin Best Dating Guide said on Dec 11, 04:57 PM:

Great tutorial! Paypal is working on my country now and I'll just try it.

Pin grow taller 4 idiots said on Dec 11, 09:40 PM:

I have thought about this kind of approach, but never really taken action with the paypal system, but a nice overview, easy to follow etc. Will bookmark for future use, thanks for the information, new skills learning always appreciated !

John Vanton - Height Expert

Pin Baju said on Dec 16, 04:48 PM:

I've used your tutorial to get paypal ipn integration successfully working, thank you for sharing this information.

Pin thai silk said on Dec 17, 06:11 AM:

Stunning stuff..I was on the lookout for this for many days now. paypal already.

Pin اخبار مصر said on Dec 21, 03:27 PM:

Thank you for a very enlightening and informative post, it seems a shame that certain types use these posts for link building campaigns, and neglect to read....

Pin All About Photography said on Dec 25, 04:31 AM:

thanks for this article :) very interesting

Pin Beauty Secret said on Dec 25, 04:32 AM:

thanks for this article :) very interesting :)

Pin Fashion Magazine said on Dec 25, 05:22 AM:

like your article :) thanks

Pin memory power said on Dec 26, 12:05 PM:

this is one of the interesting posts i have read this month.cheers

Pin maca andina said on Dec 28, 01:33 AM:

Interesting article, i enjoy reading your blog
thanks

Pin membuat blog said on Dec 30, 02:15 AM:

This is a really old post. I saw the posting date after I read it..

Pin lower ab workouts said on Dec 30, 05:53 PM:

This article definitely will help a lot! Thank you very much!!

Pin nada said on Jan 02, 08:13 PM:

its a cool post
thanks for sharing

cheers
http://telecomandinternet.com

Pin resume writers said on Jan 03, 04:20 PM:

Thanks for this very enlightening article. Paypal is the best!

Pin nanuni kokoritu said on Jan 04, 02:35 PM:

Excelent blog,... nice post! Thanks

Pin Michael said on Jan 04, 04:38 PM:

I only use PayPal for my e-commerce sites. Maybe I'm just lazy, but it is so easy!

Pin freight forwarders USA said on Jan 06, 04:23 PM:

Paypal is so easy to use, I can't say enough good things about them, personally. Thanks for the post!

Pin farmville cheats said on Jan 08, 12:13 AM:

Thanks, this is really helpful. I'm pretty up to speed with Rails (it's so awesome!) but integrating PayPal has been a bit of a challenge.

Pin Shelton Smith said on Jan 08, 01:49 PM:

Good post….thanks for sharing.. very useful for me i will bookmark this for my future needed. thanks for a great source.

Thanks
Web development company india

Pin all natural candle said on Jan 08, 08:07 PM:

I use PayPal daily for my business and this is something that is very important to me. Thanks for talking about this issue mate.

Pin dell repair said on Jan 08, 08:10 PM:

Interesting post and I really like your take on the issue. I now have a clear idea on what this matter is all about. Security is indeed important for PayPal. Thank you so much.

Pin Dating Guide said on Jan 11, 01:34 AM:

Nice tip! Made me understand the process much better! Thank you.

Pin Quadrant vans said on Jan 11, 12:49 PM:

Would have thought Paypal would have made integration as simple as possible to encourage more people to use the payment gateway.

Pin casino said on Jan 11, 04:19 PM:

great information and thanks

Pin Steve said on Jan 11, 06:02 PM:

Great post. Really useful. Thanks.

Pin Gary said on Jan 12, 03:46 PM:

Hello,

I have implemented WPSI with PayPal.
It is working correctly, but when I pass the 'notify_url' for IPN, it gaves me,

(ActionController::InvalidAuthenticityToken) Error.

I am facing problem to pass the 'notify_url' with this decrypted values. Is there any way to pass it ?

Warm Regards,
Gary

Pin Baiju said on Jan 13, 09:33 AM:

Hello,

Good post.
I am also facing the same problem as Steve is facing.

I have setup the IPN in PayPal sandbox business account as 'http://192.168.1.150:3000/payments/ipn' but it is not sending data to my application.

It is showing FAILED in IPN History.

Any idea ?

Thank you,
Baiju

Pin New Gadgets said on Jan 17, 09:00 AM:

I'm need this script. I want to try to use it. Paypal is Great, I am very impressed with the performance of Paypal. Thank you for sharing knowledge.

Pin http://www.guiaprudenteonline.com.br/ said on Jan 19, 02:57 PM:

For me paypal is the best

Pin inearkopfhoerer said on Jan 19, 10:01 PM:

Yeah Paypal is quite usefull. But i find it even more impressive that people are constantly working to improve this genius payment system.

Thank your for the article.

Pin العاب said on Jan 27, 04:21 PM:

Thank you for your topic
The subject of bitter, sweet, beautiful, moon
Accept traffic
Gisele thanks from me to you
Mra thanks
To the meeting ..

Pin supra shoes said on Feb 08, 09:16 AM:

Thanks for sharing your good blog with us!

Pin دردشة said on Feb 10, 07:31 PM:

Thanks for sharing your good blog with us!

Pin fotografia ślubna katowice said on Feb 14, 06:18 PM:

Thanks for inspression. Extra stuff here.

Pin fotografia ślubna Bielsko said on Feb 14, 06:18 PM:

I agree with you i this case. Thanks

Pin Oriya Matrimony said on Feb 15, 08:16 AM:

Nice Articles, Thank you for sharing with us

Pin Bisnis Sampingan said on Feb 18, 03:53 PM:

Thanks for the information. This is useful for me since I'm thinking of creating an e-commerce web site.

Pin Sport said on Feb 19, 04:55 PM:

currently used paypal a lot if people. I want to try to use it to make use paypal. I will try and practice this tutorial, this is very useful. thank you for sharing.

Pin world of warcraft cataclysm said on Feb 19, 07:10 PM:

I thought Paypal is the best option for payment get way. It's very easy to integrate and activate

world of warcraft cataclysm

Pin منتديات said on Feb 23, 11:45 PM:

Nice Articles, Thank you for sharing with us

Pin car wraps said on Feb 27, 01:58 PM:

Thanks for the tip!!

Pin cheap florida vacations said on Feb 27, 02:00 PM:

Pay pal sucks, they rip people of all the time.

Pin fotograf slubny said on Mar 03, 10:24 PM:

i love this great place!

Pin psycholog online said on Mar 03, 10:24 PM:

cool place isnt it?

Pin Blog Comment Demon said on Mar 04, 02:17 PM:

Paypal really plays a major role all over the internet. Your post really helps a lot. I will check it back to read the tutorial carefully and try if this will work out fine. :)
Thanks!

Pin Unterwaesche Online Shop said on Mar 07, 12:24 PM:

I must admit that this post really interesting, thanks for the writing!

Pin Youtube to MP4 Converter said on Mar 10, 05:25 AM:

Excellent article, thanks for sharing it.

Pin Paul said on Mar 11, 01:51 AM:

Problem with email address for the business is not present in the encrypted blob. i have been spent more than 2 days, still can't find a solution. Anyonehwo can help me...
1. Log on the linux box and create a private key and my public certificate
private key
openssl genrsa -out app_key.pem 1024

My Public Certificate
openssl req -new -key app_key.pem -x509 -days 365 -out app_cert.pem

2. Upload my public certificate to Paypal sandbox and get the CERT_ID

3. Download Paypal public certificate: paypal_cert.pem

Now I have 3 files under the certs directory
• app_cert.pem
• app_key.pem
• paypal_cert.pem

In my controller, it calls the encrypt function

values = {
:business => "help.s_1260152087_biz@gmail.com",
:cmd => "_cart",
:upload => 1,
:currency_code => "AUD",
:handling_cart => @order_log.postage,
:return => return_paypal_url,
:notify_url => notify_return_url,
:cert_id => "STVF85MBT8XWS"
}
counter = 0
@orders = Order.find(:all,:conditions => { :order_log_id => order_log_id.to_i })
@orders.each do | order |
counter = counter + 1
RAILS_DEFAULT_LOGGER.info "item name[" + order.item_name + " |price[" + order.price.to_s + "]"
values.merge!({
"item_number_#{counter}" => counter,
"item_name_#{counter}" => order.item_name,
"amount_#{counter}" => order.price,
"quantity_#{counter}" => order.quantity
})
end
encrypted_string = encrypt_for_paypal(values.to_query)

===
class ShippingDetail < ActiveRecord::Base
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

end
===

Web Page = The value of the encrypted field is encrypted.

==
But the Paypal returns error "Email address for the business is not presented in the encrypted blob"

Please help me to resolve this proble.. Because of this problem, we cannot launch our web site.

Drop a comment: