Paypal and Rails


#1

Hello everyone,

I am looking for a way to pass off a simple payment to paypal using our
own interface. I understand that this requires making full use of
Paypal’s API since we won’t be using their shopping cart or anything. I
found the article by Pranav Bihari on his site and in the Wiki on using
SOAP4R and the paypal WSDL file to interface with paypal web services,
but I guess maybe I’m too new to ruby to understand his “simple” script.
I figured what we are doing is very simple and I just can’t figure out
how to do it though simply.

What we have is a user logged into our system. We will provide them a
secure page to enter billing info for an order whose total is already
calculated and ready to send to paypal. Basically all we need is to post
the users info that paypal requires for credit card payments and no
account, and our total, to paypal and have it bill them for that.

Can anyone point me in the right direction on this? Thanks ahead of
time.


#2

Bryan C. wrote:

Hello everyone,

I am looking for a way to pass off a simple payment to paypal using our
own interface. I understand that this requires making full use of
Paypal’s API since we won’t be using their shopping cart or anything. I
found the article by Pranav Bihari on his site and in the Wiki on using
SOAP4R and the paypal WSDL file to interface with paypal web services,
but I guess maybe I’m too new to ruby to understand his “simple” script.
I figured what we are doing is very simple and I just can’t figure out
how to do it though simply.

What we have is a user logged into our system. We will provide them a
secure page to enter billing info for an order whose total is already
calculated and ready to send to paypal. Basically all we need is to post
the users info that paypal requires for credit card payments and no
account, and our total, to paypal and have it bill them for that.

Can anyone point me in the right direction on this? Thanks ahead of
time.

You might look into Paypal Website Pro. This is a relatively new
offering from Paypal, which I think allows the functionality you are
looking for.


#3

Lon B. wrote:

Bryan C. wrote:

Hello everyone,

I am looking for a way to pass off a simple payment to paypal using our
own interface. I understand that this requires making full use of
Paypal’s API since we won’t be using their shopping cart or anything. I
found the article by Pranav Bihari on his site and in the Wiki on using
SOAP4R and the paypal WSDL file to interface with paypal web services,
but I guess maybe I’m too new to ruby to understand his “simple” script.
I figured what we are doing is very simple and I just can’t figure out
how to do it though simply.

What we have is a user logged into our system. We will provide them a
secure page to enter billing info for an order whose total is already
calculated and ready to send to paypal. Basically all we need is to post
the users info that paypal requires for credit card payments and no
account, and our total, to paypal and have it bill them for that.

Can anyone point me in the right direction on this? Thanks ahead of
time.

You might look into Paypal Website Pro. This is a relatively new
offering from Paypal, which I think allows the functionality you are
looking for.

Thanks for the heads up. The Direct Paypment system of Website Payment
Pro seems great, but unfortunately still requires full branding with
paypal as an option for our users. We want to avoid an external shopping
cart at all costs and just use paypal for CC processing as we can’t do
that in house. We looked into other places that do CC authorization and
processing but paypal still seems cheaper and more friendly in the long
run.


#4

Mufaddal K. wrote:

Hi,

This is just a hunch. Does Paypal provide a jar that has all the API
that you need to use? If yes, could you use that jar via jruby?

-Mufaddal.

Mufaddal - they offer full SDK kits for Java, PHP, or ASP as well as
WSDL files for use with SOAP. I was curious if anyone could point me to
an easy-walkthrough of using maybe SOAP4R with WSDL files to get some
actual ruby methods setup to use within our app.


#5

Hi,

This is just a hunch. Does Paypal provide a jar that has all the API
that you need to use? If yes, could you use that jar via jruby?

-Mufaddal.


#6

I’m not super familiar with Paypal (yet :wink: does Paypal for Ruby
(http://dist.leetsoft.com/api/paypal/) accomplish what you need?

Rob K.


#7

The PayPal gem is built around PayPal’s IPN, or Instant Payment
Notification
system.

Basically you send the user to PayPal by pre-filling a form directed at
their server. The user pays and when they do PayPal sends an HTTP GET to
a
URL you define in the PayPal setup.

You confirm that the details are legit and if so, you’ve got a payment
made…

It’s PayPal’s old school setup, predating the soap-y crap they’re
pushing
these days.


#8

HH wrote:

The PayPal gem is built around PayPal’s IPN, or Instant Payment Notification
system.

Basically you send the user to PayPal by pre-filling a form directed at
their server. The user pays and when they do PayPal sends an HTTP GET to a
URL you define in the PayPal setup.

I’m using this in production at the moment, and it works fine. Obviously
you have to put users through a Paypal branded checkout, but aside from
that it’s all good.

Cheers,

Tom


#9

Tom T. wrote:

HH wrote:

The PayPal gem is built around PayPal’s IPN, or Instant Payment Notification
system.

Basically you send the user to PayPal by pre-filling a form directed at
their server. The user pays and when they do PayPal sends an HTTP GET to a
URL you define in the PayPal setup.

I’m using this in production at the moment, and it works fine. Obviously
you have to put users through a Paypal branded checkout, but aside from
that it’s all good.

Cheers,

Tom

Tom,

Could you point me to the example or directions you used to set this up?
I currently have a paypal account and just need to be able to verify
that a customer has put through a payment in order for them to access
certain content on my site. Any and all help (and step by steps for this
newbie) are greatly appreciated. Thanks in advance.

Sincerely,

Robert D.


#10

Could you point me to the example or directions you used to set this up?
I currently have a paypal account and just need to be able to verify
that a customer has put through a payment in order for them to access
certain content on my site. Any and all help (and step by steps for this
newbie) are greatly appreciated. Thanks in advance.

Sincerely,

Robert D.

Hi Robert - I basically use the example from the leetsoft paypal
library. Here’s some of my controller that processes the paypal ipn
response. It certainly doesn’t handle all cases, but does seem to get
the job done. I look up user records via their sha1 user id that is set
on the paypal submission form I’ve setup. This allows someone to make a
payment from paypal that doesn’t match the email address I have on file
for them.

Heres some of the controller:

def paypal_ipn

notify = Paypal::Notification.new(request.raw_post)

acknowleged = false
if notify.acknowledge
acknowledged = true
end

if acknowledged

logger.info "item_id: #{notify.item_id}" #1000
logger.info "complete?: #{notify.complete?}" #true
logger.info "status: #{notify.status}" #Completed
logger.info "transaction_id: #{notify.transaction_id}" #8fx...
logger.info "type: #{notify.type}" #subscr_signup, subscr_payment, 

subscr_cancel
logger.info “invoice: #{notify.invoice}” #9348
logger.info “notice amt: #{notify.amount}”

logger.info "subscr_id: #{@params[:subscr_id]}" # 

S-5C507750HS1209630
paid_user = User.find(:first, :conditions => [“sha1(‘somesalt’ + id)
= ?”, notify.invoice.split("_")[0] ])

if !paid_user.nil?
  case notify.type
    when "subscr_payment"
      if notify.complete?
        logger.info "got a signup for #{paid_user.id}"
        logger.info "amount: #{notify.amount}"
        logger.info "gross: #{notify.gross}"
        logger.info "fee: #{notify.fee}"

        case notify.item_id
          when "basic_monthly"
            if notify.amount == Money.us_dollar(200)
              logger.info "updating member to 1 and subscr_id to 

#{@params[:subscr_id]}"
paid_user.update_attributes(“member” => 1, “subscr_id”
=> @params[:subscr_id], “subscription_type” => “basic_monthly”,
“subscribed_on” => Time.now)
end
else
# we have an error - don’t do anything…
logger.error “unknown item id ‘#{notify.item_id}’”
end
end # end case notify.item_id
when “subscr_cancel”
logger.info “processing a cancellation…”
begin
user = User.find_by_subscr_id(@params[:subscr_id])
user.update_attributes(“member” => 0, “subscr_id” => nil,
“cancelled_on” => Time.now)
rescue
logger.error $!
end
when “web_accept”
logger.info “got web_accept”
if notify.complete?
case notify.item_id
when “basic_yearly”
if notify.amount == Money.us_dollar(1200)
logger.info “processing a yearl subscription for
#{paid_user.id}”
paid_user.update_attributes(“member” => 1,
“subscription_type” => “basic_yearly”, “subscribed_on” => Time.now)
end
else
logger.info “unknown item id ‘#{notify.item_id}’”
end
end
else
logger.info “unknown type ‘#{notify.type}’”
end # end case notify.type
else
logger.info “unable to find user #{notify.invoice.split(’_’)[0]}”
end
end

render :nothing => true
end

And here’s some of the form that makes a post to paypal:

Good luck -

Dave
http://www.favoriterun.com


#11

What you’re looking for is this:
http://www.elctech.com/products_ruby_paypal.shtml

It does the full API connection to PayPal from Ruby on Rails.

A couple of issues that I found:

  • I couldn’t get the initial step to work where you download the new
    API stuff from PayPal. Thankfully, the package already has the files
    included. I used these and was able to make transactions with no
    problem.
  • I believe you’ll need to update the SOAP stuff in Ruby, I’m not sure
    if the update is needed when running in production as I didn’t get that
    far (I wanted to process AUD currency - see below)
  • The login and password temporary names in the README are actually
    called something else.
  • The API only processes payments in USD, so if you’re wanting to use
    any other currency your out of luck.
  • The “docs” and other info around the place suck, so this adds to the
    difficulty level.
  • This whole thing is far from “simple”, but is a nice solution if you
    can get it working.
  • Use “ruby -d script/server” when running the connection to PayPal and
    you’ll see the SOAP response from PayPal. It includes the error
    messages in the XML string, handy for debugging.
  • I didn’t get as far as parsing the response for error strings, but I
    don’t think it would be that difficult.

Yes it works, and yes I’ve got it working previously. If you need help
let me know, but this should be enough to get you started.

Cheers,
Dan
http://www.gogogadget.com.au


#12

Dave and Dan,

Thank you both. I am sure that with your input I will get things up and
going asap! I will let you know how it goes.

  • Rob

#13

On Nov 22, 2006, at 8:24 PM, donut donut wrote:

make a
acknowleged = false
logger.info “type: #{notify.type}” #subscr_signup,

#{paid_user.id}"
else

record the purchase in the database. Is there anything wrong with
this?

Also, if the user checks the order status before the IPN comes in
(if IPN
takes a few minutes for some reason), I can’t even tell the user that
the order is pending. This is pretty bad. How do you guys get around
this?

I describe how to do exactly this in my Rails e-commerce book:
http://www.agilewebdevelopment.com/rails-ecommerce

The short version is that you have your order form submit to an
action in your app that creates the transaction and renders a view
with the paypal form filled out and submitted automatically via
javascript. This form can then be populated with an invoice number
that you can verify at IPN time. You would also have a transaction
in pending state for a customer to be able to see immediately.


#14

On 11/22/06, Benjamin C. removed_email_address@domain.invalid wrote:

hate to counter plug, but there’s also the small pdf only title
'Payment Processing with Paypal and Ruby ’ from Joe Fair.
http://pragmaticprogrammer.com/titles/jfpaypal/index.html

I haven’t read either yet, so can’t really advise, only state the
obvious :slight_smile:


Chris M.
Web D.
Open Source & Web Standards Advocate
http://www.chriscodes.com/


#15

Hi,
I create an order record with a status of in progress, if the IPN comes
back
I update the status to paid. If it doesn’t I now have a record of orders
that were abandoned.

Your invoice numbers don’t have to be in sequence for paypal to work.

Regards,
John


#16

Dave wrote:

Hi Robert - I basically use the example from the leetsoft paypal
library. Here’s some of my controller that processes the paypal ipn
response. It certainly doesn’t handle all cases, but does seem to get
the job done. I look up user records via their sha1 user id that is set
on the paypal submission form I’ve setup. This allows someone to make a
payment from paypal that doesn’t match the email address I have on file
for them.

Heres some of the controller:

def paypal_ipn

notify = Paypal::Notification.new(request.raw_post)

acknowleged = false
if notify.acknowledge
acknowledged = true
end

if acknowledged

logger.info "item_id: #{notify.item_id}" #1000
logger.info "complete?: #{notify.complete?}" #true
logger.info "status: #{notify.status}" #Completed
logger.info "transaction_id: #{notify.transaction_id}" #8fx...
logger.info "type: #{notify.type}" #subscr_signup, subscr_payment, 

subscr_cancel
logger.info “invoice: #{notify.invoice}” #9348
logger.info “notice amt: #{notify.amount}”

logger.info "subscr_id: #{@params[:subscr_id]}" # 

S-5C507750HS1209630
paid_user = User.find(:first, :conditions => [“sha1(‘somesalt’ + id)
= ?”, notify.invoice.split("_")[0] ])

if !paid_user.nil?
  case notify.type
    when "web_accept"
      logger.info "got web_accept"
      if notify.complete?
        case notify.item_id
          when "basic_yearly"
            if notify.amount == Money.us_dollar(1200)
              logger.info "processing a yearl subscription for 

#{paid_user.id}"
paid_user.update_attributes(“member” => 1,
“subscription_type” => “basic_yearly”, “subscribed_on” => Time.now)
end
else
logger.info “unknown item id ‘#{notify.item_id}’”
end
end
else
logger.info “unknown type ‘#{notify.type}’”
end # end case notify.type
else
logger.info “unable to find user #{notify.invoice.split(’_’)[0]}”
end
end

render :nothing => true
end

I want to run this by you guys who have implemented PayPal payment.

One of the issues I’m facing in using PayPal with Rails is that my
website does not know if the user has pressed the PayPal button(in this
case a Buy-Now button) to make a purchase because the user gets
redirected to paypal once the button is clicked. I can’t pre-generate
an invoice number to stick in the button because the user may decide not
to make a purchase. So when the IPN comes in, I don’t really have an
invoice number to verify with. I do the normal verification such as
checking notify.acknowledge and payment_status, etc, and then just
record the purchase in the database. Is there anything wrong with this?

Also, if the user checks the order status before the IPN comes in(if IPN
takes a few minutes for some reason), I can’t even tell the user that
the order is pending. This is pretty bad. How do you guys get around
this?


#17

On Nov 22, 2006, at 10:59 PM, Chris M. wrote:

that you can verify at IPN time. You would also have a transaction
in pending state for a customer to be able to see immediately.

hate to counter plug, but there’s also the small pdf only title
'Payment Processing with Paypal and Ruby ’ from Joe Fair.
http://pragmaticprogrammer.com/titles/jfpaypal/index.html

I haven’t read either yet, so can’t really advise, only state the
obvious :slight_smile:

Heh, good point. :slight_smile:


#18

Sorry for the late reply.

Another option is to use something similar to IPN called PDT. When
the user gets done and PayPal redirects them to your web site PayPal
puts a hidden field in the redirect. This field has a token that you
can use to directly query PayPal before you build the response page.
You can save the results of the query, too.

hate to counter plug, but there’s also the small pdf only title
'Payment Processing with Paypal and Ruby ’ from Joe Fair.
http://pragmaticprogrammer.com/titles/jfpaypal/index.html

Yes, but he’s not as responsive in monitoring the mailing lists. :wink:

Joe


“For a new software system, the requirements will not be completely
known until after the users have used it.” Humphrey’s Requirements
Uncertainty Principle.


#19

Bothari wrote:

Sorry for the late reply.

Another option is to use something similar to IPN called PDT. When
the user gets done and PayPal redirects them to your web site PayPal
puts a hidden field in the redirect. This field has a token that you
can use to directly query PayPal before you build the response page.
You can save the results of the query, too.

According to the PayPal documentation, you are not guaranteed to
received a PDT due to various reasons. Actually, I’m not sure why PDT
exists…


#20

Is there a reason for not opting for the “Website Payments
Standardhttps://www.paypal.com/cgi-bin/webscr?cmd=_wp-standard-overview-outside
option rather than “Website Payments
Prohttps://www.paypal.com/cgi-bin/webscr?cmd=_wp-pro-overview-outside”.
The transaction fees don’t seem to be any higher plus you wouldn’t have
to
go through an API based integration?