-
PayPal Recurring Billing with ActiveMerchant in Ruby on Rails
Posted on February 20th, 2009 42 commentsActiveMerchant is great and PayPal is easy to use. A lot of us already have a PayPal account for EBay. It works great in auctions where you pay once. However, ActiveMerchant currently does not support PayPal recurring billing. One requirement of a recent project is to be able to charge for a monthly or yearly subscription plan with PayPal. Therefore, I did some googling and found that Jon Baker has already extended ActiveMerchant to add this functionality using PayPal’s Name-Value Pair (NVP) API. However, as Cody Fauser pointed out, the NVP API was taken out from ActiveMerchant, so I had to implement that with PayPal’s SOAP API.
First, download this file and put it in vendor/plugins/active_merchant/lib/active_merchant/billing/gateways/.Use the GitHub from now because maintaining a separate file download is too troublesome. Alternatively, there’s a fork on GitHub at http://github.com/rayvinly/active_merchant/.In your controller, after a user selects one of your subscription plan, the form goes to the checkout action:
def checkout response = gateway.setup_agreement(:description => description, :return_url => return_url, :cancel_return_url => cancel_return_url) redirect_to gateway.redirect_url_for(response.token) end
This redirects the user to PayPal so he can login and read the description you provided. After he confirms, he is redirected back to your application’s return_url, which I set it to be the complete action below. If he cancels, he is redirected back to the cancel_return_url. You can set cancel_return_url to be the plan selection page where he can choose a different plan.
If he confirms, here’s the complete action:
def complete token = params[:token] response = gateway.create_profile(token, :description => description, :start_date => start_date, :frequency => frequency_in_months, :amount => amount_in_dollars, :auto_bill_outstanding => true) # Save this profile_id in your transactions table. This is used to cancel/modify the plan in the future. profile_id = response.params["profile_id"] if response.success? flash[:notice] = "Your PayPal account was successfully set up for the <strong>#{description}</strong> payment plan." redirect_to login_path else flash.now[:notice] = "There was a problem setting up your PayPal account for the <strong>#{description}</strong> payment plan" render cancel_url end end
I default the frequency to be in months and turn on auto_bill_outstanding because that is what I need, but you can look at the file you downloaded and the PayPal documentation to see what other options are available. In particular, read these two PDFs:
If the user wants to cancel the payment plan, a cancel action would look like:
def cancel response = gateway.cancel_profile(paypal_profile_id, :note => 'Payment plan was canceled by user') flash[:notice] = 'You have successfully canceled your membership' end
paypal_profile_id is the profile_id you saved in the complete action from above. Keeping this profile_id is very handy.
That’s it. Enjoy making money!
UPDATE 2009-02-04
I updated the extension to include a credit_card hash. You will probably capture the credit card details submitted by the user in a form as in params[:credit_card], but I will just create a hash to show as an example. To make recurring payment with a credit card, just pass nil for the token (this is required, because PayPal would use the token in preference to the credit card). Pass the credit_card hash as follows:
credit_card = Hash.new credit_card[:type] = 'Visa' credit_card[:number] = '1234567812345678' credit_card[:exp_month] = '07' credit_card[:exp_year] = '2016' credit_card[:cvv2] = '123' credit_card[:card_owner] = 'John Doe' response = gateway.create_profile(nil, :credit_card => credit_card, :description => description, :start_date => start_date, :frequency => frequency, :amount => amount, :auto_bill_outstanding => true)
However, I got the famous DPRP is disabled for this merchant error message when I tested it. I did a little googling but I haven’t found the cause. There may just be something that you have to turn on in your PayPal developer account. I also read that it works for newer accounts only. But since I don’t have a need for this, I didn’t look further. If you guys know, please let me know. I will try to update the extension as soon as possible to make it work with a credit card.



Recent Comments