最近花了一周时间搞定了 https://writings.io/ 的自助支付功能,做的过程中感觉 Ruby 社区关于支付宝的资源不多,所以写了一篇文章抛砖引玉。
支付宝 API 向导(Ruby 版) http://chloerei.com/2013/08/01/alipay-payment-in-ruby/
同时开源一个支付宝接口的 gem https://github.com/chloerei/alipay
做这个 gem 的原因是发现已有的 gem 不够好:
activemerchant_patch_for_china 依赖 activemerchant,实现得很复杂
ralipay 功能较全,但是代码中有一些不好的地方,比如全局变量太多。
另外还参考了 alipay_dualfun 和 china_pay,觉得包装有些多。
所以我还是自己写了一个 gem,代码更少,没有依赖,可以用于所有 Ruby Web 项目;直接面对支付宝接口,不加过多的包装。
比如,生成担保交易地址只是一个方法
Alipay::Service.create_partner_trade_by_buyer_url(
:out_trade_no => 'YOUR_ORDER_ID',
:subject => 'YOUR_ORDER_SUBJECCT',
...
)
我向之前提到的几个 gem 的作者致敬,因为不参考他们的代码我遇到很多问题都解决不了。
欢迎贡献代码,像即时到帐接口我没有权限访问,测试不了,所以还没写进去。
或者捐助我,让我更积极维护这个 gem https://me.alipay.com/chloerei
再搭一个广告,writings.io 现在可以自助付费了:https://writings.io/billing ,也欢迎继续联系我个人购买:[email protected]。
之前我也准备做一个支付宝付款的事情,然后我看这里:https://b.alipay.com/order/productSet.htm ,发现即时到帐需要执照。 不知道你的 gem,是不是支持担保交易和即时到帐两种情况的?
申请不到即时到帐的话,用担保交易就好了,双功能不能控制用户用什么方式支付,还是要处理担保交易一样的流程。
还有,其实 gem 要做的事情不多:生成 url、发货、校验通知,其余都是取决于自己的业务代码。
china_pay 做了很多封装,本来是想支持多种支付渠道的,比如财付通,快钱什么的。
其实生成跳转的 url 还是相对容易的,比较麻烦的是处理支付宝的异步通知,要校验什么的。
我觉得理想的情况是,支付 gem 应该是个 engine,把这些细节都搞定,大家只要写业务代码就行了,跟 devise 那样。
@Rei 我也仔细看过支付宝的流程,其实前面那个支付提交还是很简单的,当时想用 ruby 搞定也不会太费事;不过那个支付成功之后支付宝回调通知的时候还有一个到支付宝的验证过程,貌似复杂些,而且现有的 gem 中貌似也没有这部分,不知道你做了没有
#10 楼 @donnior 是指这个吗? https://github.com/chloerei/alipay/blob/master/lib/alipay/notify.rb 我看回调和异步消息的参数应该一样的。校验回调先用签名检查,再访问 notify_query 接口检查。
它校验的签名是回调参数,不是接口返回值。
我给拆成两个方法了 https://github.com/chloerei/alipay/blob/master/lib/alipay/sign.rb#L13
也许我应该在 Notify.verify? 里面也调用 Sign.verify?
@Rei 需要请教一个问题:如何确认通知(同步和异步)确实来自于支付宝,而非第三方伪造? 我看支付包文档上说是通过校验 notify_id,不过具体代码如何来写比较合适呢?
先校验签名,然后 GET 一个地址,看返回内容是不是 true
module Alipay
class Notify
def self.verify?(params)
if Sign.verify?(params)
params = Utils.symbolize_keys(params)
open("https://mapi.alipay.com/gateway.do?service=notify_verify&partner=#{Alipay.pid}¬ify_id=#{CGI.escape params[:notify_id].to_s}").read == 'true'
else
false
end
end
end
end
更新,更正了校验地址
#21 楼 @happypeter 奥,我发现这个地址跟文档看的不一样,忘了是哪里抄的。
正确的应该是
"https://mapi.alipay.com/gateway.do?service=notify_verify&partner=#{Alipay.pid}¬ify_id=#{CGI.escape params[:notify_id].to_s}"
#23 楼 @small_fish__ 没有利益吧。我做的时候也想,为什么要帮别的公司写工具包啊,应该是这些公司的责任。后来想到写出来对 Ruby 社区有好处,还是坚持下来了。
➜ ~ ruby -v
ruby 2.0.0p247 (2013-06-27 revision 41674) [i686-linux]
➜ ~ rvm list
rvm rubies
ruby-1.9.3-p448 [ i686 ]
=* ruby-2.0.0-p247 [ i686 ]
# => - current
# =* - current && default
# * - default
➜ ~ rvm gemset list
gemsets for ruby-2.0.0-p247 (found in /home/rasefon/.rvm/gems/ruby-2.0.0-p247)
(default)
global
=> r2
➜ ~ gem install alipay
Successfully installed alipay-0.0.1
1 gem installed
➜ ~ irb
2.0.0p247 :001 > require 'alipay'
LoadError: cannot load such file -- alipay
from /home/rasefon/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:51:in `require'
from /home/rasefon/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:51:in `require'
from (irb):1
from /home/rasefon/.rvm/rubies/ruby-2.0.0-p247/bin/irb:13:in `<main>'
2.0.0p247 :002 >
#34 楼 @Rei 有些 gem 也有不能加载的现象比如 win32-process,大部分可以用。 这是我的结果: ➜ ~ gem list | grep alipay alipay (0.0.1) ➜ ~ irb 2.0.0p247 :001 > require 'nokogiri' => true 2.0.0p247 :002 > puts $LOAD_PATH /home/rasefon/.rvm/gems/ruby-2.0.0-p247@r2/gems/mini_portile-0.5.1/lib /home/rasefon/.rvm/gems/ruby-2.0.0-p247@r2/gems/nokogiri-1.6.0/lib /home/rasefon/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0 /home/rasefon/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/i686-linux /home/rasefon/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby /home/rasefon/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/vendor_ruby/2.0.0 /home/rasefon/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/vendor_ruby/2.0.0/i686-linux /home/rasefon/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/vendor_ruby /home/rasefon/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0 /home/rasefon/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/i686-linux => nil 2.0.0p247 :003 > ^C
你好,我自己在网上下载了支付宝接口,我想先测试一下能不能通过支付宝接口进行简单的付款交易,是不是要注册企业账号,或者说个人账号。可是我看条件说注册个人账号要有自己的已发布网站。我没有个人网站。是不是就不能测试了,就只有注册企业账号来测试这个支付宝交易功能了是吗。
#44 楼 @Rei 嗯。那如果注册了企业账号,直接用下载的 Demo 就可以测试成功吗。需要把 Demo 发布到外网去吗。也就是上线。你可以发一份 Demo 给我吗。~~(>_<)~~ 我邮箱 [email protected].先谢谢了
看了下源码,感觉主要用来生成请求 url 的,另外 GATEWAY_URL 似乎不可配置,比如想改成测试环境 url https://openapi.alipaydev.com/gateway.do请指点 @rei ,谢谢!
#54 楼 @wikimo 你可以看这个项目 https://github.com/chloerei/alipay-demo,用的是担保交易接口,但是流程差不多。