ActiveMerchant 很好很强大,但是网上介绍的都是信用卡支付的方式,对于国内这种类Paypal的支付方式很少。
这种支付方式在ActiveMerchant中称之为integration模式,可能是由于编写起来并不难,介绍它的文档很少,我编写的时候是完全按照paypal的代码写的。
http://code.google.com/p/activemerchant/issues/detail?id=114
是我提交的Patch,以支付宝为例,在使用前需要指定 ActiveMerchant::Billing::Integrations::Alipay::KEY和Alipay::ACCOUNT,具体这两个值放在哪里,根据个人喜好,直接放在插件中,或者放在environment.rb中,或者放在lib文件夹下require进来都可以。
使用的时候,需要在页面中使用下面这样的代码(参见 http://activemerchant.rubyforge.org/classes/ActiveMerchant/Billing/Integrations/ActionViewHelper.html)
<% payment_service_for 1000, '[email protected]', :amount => 50.00, :currency => 'CAD', :service => :paypal, :html => { :id => 'payment-form' } do |service| %> <% service.customer :first_name => 'Cody', :last_name => 'Fauser', :phone => '(555)555-5555', :email => '[email protected]' %> <% service.billing_address :city => 'Ottawa', :address1 => '21 Snowy Brook Lane', :address2 => 'Apt. 36', :state => 'ON', :country => 'CA', :zip => 'K1J1E5' %> <% service.invoice '#1000' %> <% service.shipping '0.00' %> <% service.tax '0.00' %> <% service.notify_url url_for(:only_path => false, :action => 'notify') %> <% service.return_url url_for(:only_path => false, :action => 'done') %> <% service.cancel_return_url 'http://mystore.com' %> <% service.sign %> <% end %>
helper.rb中的工作也很重要,
mapping :tax, 'tax_no'
说明 service.tax '0.00' 会生成 这样一个表单字段。
mapping :customer, :email => 'c_email', :address => 'c_address'
说明 service.customer :email => '[email protected]', :address => '上海' 会生成
和
两个字段。
对于不会用于生成Hash签名,基本不会变的字段,可以在helper的intialize方法中生成
def initialize(order, account, options = {}) super add_field('bank_type', 0) end => ''
service.sign方法,是我为生成签名添加的。在这个方法里最后使用 add_field 'sign', sign把hash值填入到表单里。(好像只有国内的支付接口需要计算hash值)
# in lib/active_merchant/billing/integrations/tenpay.rb def sign add_field('sign', Digest::MD5.hexdigest("cmdno=#{cmdno}&date=#{date}&bargainor_id=#{account}" + "&transaction_id=#{transaction_id}&sp_billno=#{order}&total_fee=#{amount}" + "&fee_type=#{currency}&return_url=#{return_url}&attach=#{attach}&key=#{KEY}")) end
返回方式有两种,notify和return。可以理解为异步和同步方式,一般notify方法还需要acknowlege,也就是通知对方收到。目前支付宝的notify模式尚未支持,若要使用需要参照paypal的实现。这里先看return模式。
Return类只需要两个方法 success? 和 message,使用的时候也很简单
def OrderController < ApplicationController include ActiveMerchant::Billing::Integrations def alipay_return r = Alipay::Return.new(request.query_string) unless @result = r.success? logger.warn(r.message) end end