Paypal Adaptive seems to be suitable for this, here are some docs I found hope this helps.
Adaptive PayPal with rails 3
As usual, the PayPal documentation is rather messy and disorganized, and therefore I thought that the Id document, how I managed to get PayPal Adaptive to work on a website on the market.
Attention!
Please use this post as a guide on how the paypal API connects to your rail application. As Jamesw notes in the comments below, I did not create an adequate way to record all the details of each transaction; which is undoubtedly required by law. Therefore, perhaps take a look at his comment after reading this. Hope you can find a way to do this.
Customization
After some searching, I found that the best gem to use now is paypal_adaptive . ActiveMerchant currently does not support Adaptive PayPal (there is a stone built into it, but it does not seem to be supported.)
# Gemfile gem 'paypal_adaptive'
How it works
PayPal Adaptive is relatively simple, but dirty documentation can seem complicated. Simply put, this is how I did it:
- create paypal_adaptive.yml in your config folder and add your details.
- create a resource for processing payments. I created the "Shopping" resource (model: purchase).
- when the user clicks the buy button, he triggers an action that I called "buy" in my PurchaseController
- in the buy action, first create a new Purchase item (Purchase.new), and then add some details, such as user_id, product_id, quantity, etc.
- Then I call a model method called โpayโ for my newly created Purchase object (purchase.pay).
- In my purchase model, I define a โpaymentโ method and within it. Finally, I use the paypal_adaptive gem, creating its Request class (PaypalAdaptive :: Request.new)
- I add all the necessary data that I want to send to PayPal in a hash, and then call the Request.pay method, passing this data hash. This makes an API call to PayPal, which then responds with confirmation of the success of this request.
- If the API call completes successfully, I redirect the user to PayPal to log in and confirm the payment.
- After the user makes the payment, PayPal sends an IPN (immediate payment notification) to the IPN address you specified, which I sent to the method in my PurchasesController
- In this method, I find the Purchase object and mark it as paid (purchase.paid = true), and then executed it!
paypal_adaptive.yml
Go here to create an account for the sandbox (you'll need one). After logging in, go to "Create a Preconfigured Account". Create two accounts - one buyer and one seller. If you are using chained or parallel payments (payments shared between several people), create a few more accounts.
Click on Api Credentials in the left sidebar.
Now fill in your paypal_adaptive.yml using these credentials (also use the application_id application that I provide below) - this is the application_id application for testing provided by www.x.com
development: environment: "sandbox" username: "platts_xxxxxxxx_biz_api1.gmail.com" password: "xxxxxxxxxxxx" signature: "xxxxxxx" application_id: "APP-80W284485P519543T" test: environment: "sandbox" username: "platts_xxxxxxxx_biz_api1.gmail.com" password: "xxxxxxxx" signature: "xxxxxxxx" application_id: "APP-80W284485P519543T" production: environment: "production" username: "my_production_username" password: "my_production_password" signature: "my_production_signature" application_id: "my_production_app_id"
Create a controller action to process a purchase request
Here you really need the amount of money you need to pay, and a list of emails for which you want to receive this money. So write your logic to complete this work, and then call PayPal to set up your purchase.
pay_request = PaypalAdaptive::Request.new data = { "returnUrl" => return_url, "requestEnvelope" => {"errorLanguage" => "en_US"}, "currencyCode" => "USD", "receiverList" => { "receiver" => [ {"email" => "platts_xxxxxxxx_biz@gmail.com", "amount"=> amount} ]}, "cancelUrl" => cancel_url, "actionType" => "PAY", "ipnNotificationUrl" => ipn_url } #To do chained payments, just add a primary boolean flag:{"receiver"=> [{"email"=>"PRIMARY", "amount"=>"100.00", "primary" => true}, {"email"=>"OTHER", "amount"=>"75.00", "primary" => false}]} pay_response = pay_request.pay(data) if pay_response.success? # Send user to paypal redirect_to pay_response.approve_paypal_payment_url else puts pay_response.errors.first['message'] redirect_to "/", notice: "Something went wrong. Please contact support." end
IPN call processing
I will direct my IPN call from PayPal to this method:
def ipn_notification ipn = PaypalAdaptive::IpnNotification.new ipn.send_back(request.raw_post) if ipn.verified? logger.info "IT WORKED" else logger.info "IT DIDNT WORK" end render nothing: true end
Unfortunately, if you are on a local hosting, PayPal cannot send you an IPN, and therefore there is a problem with testing the whole process. Ryan Bates' solution is to use curl to simulate an IPN request. However, as you can see in the above code, we make another request at PayPal, confirming that the IPN is real. Thus, even with a twist sending a fake IPN, we run into problems. I'm going to look for solutions now, but please comment if you have any ideas.