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
Hosting by site5.com