Paypal Adaptive似乎是解决这个问题的方法,这是我找到的一些文档,希望对您有所帮助。
PayPal 自适应 Rails 3
像往常一样,PayPal 文档非常混乱和杂乱无章,因此我想我会记录我是如何设法让 PayPal Adaptive 在市场风格的网站上工作的。
警告!
请使用这篇文章作为有关 paypal API 如何与您的 rails 应用程序连接的指南。正如 Jamesw 在下面的评论中指出的那样,我没有创造出一种足够的方式来记录每笔交易的所有细节。毫无疑问,这是法律要求的。所以也许在读完这篇文章后看看他的评论。希望你能找到一种方法来做到这一点
设置
经过一番搜索,我发现现在最好使用的 gem 是paypal_adaptive。ActiveMerchant 目前不支持 PayPal Adaptive(有一个 gem 可以添加它,但似乎没有维护。)
# Gemfile
gem 'paypal_adaptive'
这个怎么运作
PayPal Adaptive 相对简单,但杂乱无章的文档让人望而生畏。简而言之,这就是我的做法:
- 在您的配置文件夹中创建 paypal_adaptive.yml 并添加您的详细信息
- 创建一个资源来处理付款——我创建了一个“采购”资源(模型:采购)
- 当用户单击购买按钮时,它会调用我在 PurchasesController 中称为“购买”的操作
- 在“购买”操作中,我首先创建一个新的购买项目 (Purchase.new),然后添加一些详细信息,如 user_id、product_id、amount 等。
- 然后我在我新创建的 Purchase 对象 (purchase.pay) 上调用一个名为“pay”的模型方法
- 在我的购买模型中,我定义了“支付”方法,在其中我最终通过创建请求类 (PaypalAdaptive::Request.new) 来使用 paypal_adaptive gem
- 我将要发送到 PayPal 的所有必要数据添加到哈希中,然后调用 Request.pay 方法,传入该数据哈希。这会向 PayPal 发起 API 调用,然后 PayPal 会回复此请求成功的确认信息
- 如果 API 调用成功,我会将用户重定向到 PayPal 以登录并确认付款
- 用户付款后,PayPal 会向您指定的 IPN 地址发送一个 IPN(即时付款通知)——我将其路由到我的 PurchasesController 中的一个方法
- 在这种方法中,我找到了 Purchase 对象并将其标记为已付款(purchase.paid = true),然后就完成了!
paypal_adaptive.yml
转到此处创建一个沙盒帐户(您将需要它)。登录后转到“创建预配置帐户”。创建两个帐户——一个买家和一个卖家。如果您使用链式或并行付款(由多人分摊的付款),请创建更多帐户。
单击左侧面板中的 Api Credentials。
现在使用这些凭据填写您的 paypal_adaptive.yml(也使用我在下面提供的 application_id - 这是 www.x.com 提供的测试 application_id
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"
创建控制器操作来处理购买请求
在这里,您只需要支付的金额和您希望这笔钱去往的电子邮件列表。所以写下你的逻辑来解决这个问题,然后打电话给 PayPal 来设置购买。
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 呼叫
我将我的 IPN 呼叫从 PayPal 路由到此方法:
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
不幸的是,如果您在本地主机上,PayPal 无法向您发送 IPN,因此在测试整个过程时会出现问题。Ryan Bates 的解决方案是使用 curl 来模拟 IPN 请求。但是,正如您在上面的代码中看到的,我们向 PayPal 发出另一个请求,确认 IPN 是真实的。因此,即使 curl 发送假 IPN,我们也会遇到问题。我现在要去寻找解决方案,但是如果您有任何想法,请发表评论。