smallroomsoftware.com

PayPal Website Payments Pro

Posted on December 05, 2006

I was pleased to discover the other day that PayPal are now offering their Website Payments Pro service outside of the US. This is the top-end of their merchant solutions and allows you to collect credit-card details and process them via a web-service without the customer needing to register with PayPal or be transferred onto a PayPal managed website. This is exactly what we need and PayPal should provide a more reliable service than the other smaller processing companies (like Protx who I've used and have not been too impressed with).

It's hard to see why anyone would choose WorldPay over PayPal WPP. WorldPay (really just Royal Bank of Scotland) are far more expensive, don't offer a web-service and had an awful admin interface last time I looked.

I've been using ActiveMerchant to access the PayPal API from Ruby. Unfortunately I'm going to have to upgrade it a bit to deal with Switch/Maestro cards. I'm always upgrading/fixing things to deal with Switch cards!

Update! 15/Jan/07:

A chap from PayPal emailed me to tell me that WPP in the UK uses a different API (a simpler REST-like API rather than SOAP). So the following instructions are really only relevant to the US service. PayPal have integration instructions for UK clients here.

There's not a lot of documentation for ActiveMerchant (actually, there is none) but it seems quite easy to get the hang of. To get started using it with PayPal WPP you should grab a PayPal developer account and check out [Website Payments Pro documentation] on the 'integration center'. I followed the instructions on a few people's blogs for getting hold of API certificates and they all turned out to be out of the date. PayPal's step-by-step guide is much better. One this that might catch you out is that, when creating your sandbox merchant account, you should specify that you are in the US rather than the UK or anywhere else, otherwise you won't be able to enable the account for the payment pro feature. (see update above)

Once you've downloaded the test API certificate, you add it to your project. I saved mine as config/paypal_test.pem. Then you add something like:

ActiveMerchant::Billing::Base.gateway_mode = :test
ActiveMerchant::Billing::PaypalGateway.pem_file =
    File.read( File.dirname(__FILE__) + '/../paypal_test.pem' )

... to your config/environments/development.rb file.

Using the direct payment API is fairly easy. It's something like this:

creditcard = ActiveMerchant::Billing::CreditCard.new({
    :number => '4242424242424242',
    :month => 8,
    :year => 2007,
    :first_name => 'Joe',
    :last_name => 'Smith',
    :type => 'visa',
    :verification_value => '000'
  })

address = {
  :address1 => 12 My Street',
  :address2 => 'Somewhere',
  :city => 'London',
  :state => 'London',
  :zip => '123ABC',
  :country => 'GB',
  :phone => '01234 567890'
}

gateway = ActiveMerchant::Billing::Base.gateway(:paypal).new(
    :login => 'my_api_login',
    :password => 'MY_API_PASSWORD'
  )

# preauthorize $10
response = gateway.authorize(1000, creditcard,
    :ip => 'xx.xx.xx.xx', :address => @address)

But to adhere to PayPals terms you have to offer the 'PayPal Express Checkout' option on your site which means, for your customer, a trip to PayPal's site and back. This is how you redirect a user to PayPal for express checkout:

response = paypal_gateway.setup_express_purchase(
  1000,
  :order_id => @cart.id,
  :return_url => url_for(:action => 'paypal_success'),
  :cancel_return_url => url_for(:action => 'paypal_cancel'),
  :description => "description of what customer is buying"
)
if response.success?
  url = ActiveMerchant::Billing::PaypalGateway.redirect_url_for(response.params['token'])
  redirect_to url
end

And when the customer has chosen their paypal payment method they return to your site:

def paypal_success
  response = paypal_gateway.get_express_details(params[:token])
  if response.success?
    @cart = Cart.find(response.params['invoice_id'])
    # Now show some kind of confirmation screen
    # After user clicks 'Confirm payment' execute something like
    # this to secure the funds:
    response = paypal_gateway.purchase(1000, nil, :express => true,
      :token => params[:token], :payer_id => params[:payer_id])
  end
end
Comments
  1. jrileyDecember 09, 2006 @ 04:57 AM
    Hey Tom, I'm doing some Rails development and starting out with ActiveMerchant. Ran across your site and could not help but notice the name. :) Do you happen to have an example with Authorize.Net rather than PayPal?
  2. tomDecember 09, 2006 @ 10:35 AM
    I'm UK based so I've never been in a position to use Authorize.Net. Just flicking through the AM Authorize.Net gateway code, it looks pretty straightforward. Create gateway with your authorize.net login and password and make a call to purchase as above. Alternatively make a call to 'authorize' and another to 'capture' later on when want to clear the funds. Good luck!
  3. JodiDecember 14, 2006 @ 04:05 PM
    Thanx for the writeup Tom. However I cannot find a reference that Paypal Pro is offered outside the USA. The following says that it's currently offered in "US Only" http://www.paypal.com/cgi-bin/webscr?cmd=_merchant-outside Plus you had to trick out the sandbox with a US country selection. I'm in Canada and would love if it were so. What is your reference? I don't doubt you have the sandbox running trick-out, but have you run an app in production taking real-live payments? thanx for your thoughts. Jodi
  4. tomDecember 14, 2006 @ 05:45 PM
    I've been looking at PayPal's UK site: https://www.paypal.com/uk/cgi-bin/webscr?cmd=_merchant-outside I may have been hasty in 'outside of the US'. Looks like it might only be available in the US and UK at the moment. I imagine that other countries will follow though. Especially once google checkout goes global. Yeah, I haven't managed to get the sandbox working for a UK merchant. Maybe the sandbox isn't quite in sync with their public infrastructure. I don't have real payments going through yet (that's at least a few weeks off). Though I'm confident it will work for us I do still need to give PayPal a ring and query a few things. tom
  5. spiderJanuary 05, 2007 @ 11:48 PM
    Tom, thnks! You article help me too much!
  6. AJJanuary 09, 2007 @ 01:44 PM
    Googled across your post. Yes, not available in Australia at least. We've been requesting this for 18 months now but I suspect it was to deferred in order to sell Verisign's Payflow. Bring on google pay!!
  7. BarryFebruary 08, 2007 @ 12:13 AM
    Thanks for the tutorial! ActiveMerchant is definitely under documented, your article filled in some of the gaps. One small issue: In the paypal express checkout paypal\_success handler where you use paypal_gateway\.purchase you have: > :payer\_id => params[:payer\_id] It should be: > :payer\_id => params[:PayerID]
  8. IngoJune 11, 2007 @ 08:18 PM
    Tanks, this is great! The thing is when I try to authorize a payment using the above code, I get an error 'Please enter a complete shipping address'. Do I need to provide it as an additional option? Since I could not find documentation I tried a couple (:shipping_address, :ship_to_address, etc) but so ar none of them worked. Thanks for any hint! Ingo
  9. AnandJune 16, 2007 @ 02:25 PM
    Many thanks. I used PaypalExpressGateway::setup_purchase method. I get the following error when I call that method. "Security header is not valid" Any idea how to fix it?
  10. Matti KotsalainenOctober 12, 2007 @ 09:17 AM
    Hi! I'm also trying to integrate with Paypal UK. In you January update you wrote that Paypal UK doesn't work with the SOAP-interface used by Active Merchant, instead they seem to only support name=value get requests. Does this mean that I can't use for Active Merchant? thanks. matti
  11. JDGNovember 02, 2007 @ 07:31 PM
    Just a heads up - when using the express checkout, payer_id is now params[:PayerID].
  12. Cody FauserJanuary 17, 2008 @ 03:07 PM
    Matti, ActiveMerchant supports Website Payments Pro UK with the PayflowUkGateway for credit card payments and the PayflowExpressUkGateway for PayPal Express payments in the UK. The APIs are the same, but you'll be using your PayPal Manager credentials when constructing the gateways.
  13. Melvin RamJanuary 19, 2008 @ 11:31 AM
    RE: response = gateway.authorize(1000, creditcard, :ip => 'xx.xx.xx.xx', :address => @address) How would you save this into your database so you could retrieve this authorization and capture the funds at a later time?
  14. eladMay 20, 2008 @ 06:26 PM
    Marshal.dump(@address) into an attribute.
Hosting by site5.com