-
Notifications
You must be signed in to change notification settings - Fork 75
Alipay (支付宝)
I have built an Demo to use alipay.
Source code is here
First define your api key, account and email in config/environment.rb
. (If you haven’t them, you can get them here: https://www.alipay.com/himalayas/practicality_customer.htm)
ActiveMerchant::Billing::Integrations::Alipay::KEY
ActiveMerchant::Billing::Integrations::Alipay::ACCOUNT
ActiveMerchant::Billing::Integrations::Alipay::EMAIL
Alipay has three payment service:
1. create_direct_pay_by_user 即时到账
2. create_partner_trade_by_buyer 担保交易
3. trade_create_by_buyer 标准双接口
1. CREATE_DIRECT_PAY_BY_USER 即时到账
<% payment_service_for 'payment code', ActiveMerchant::Billing::Integrations::Alipay::ACCOUNT,
:service => :alipay,
:html => { :id => 'payment-form', :method => :get } do |service| %>
<% service.total_fee 0.02 %>
<% service.seller :email => ActiveMerchant::Billing::Integrations::Alipay::EMAIL %>
<% service.notify_url url_for(:only_path => false, :action => 'notify') %>
<% service.return_url url_for(:only_path => false, :action => 'done') %>
<% service.show_url url_for(:only_path => false, :action => 'show') %>
<% service.body 'payment body' %>
<% service.charset "utf-8" %>
<% service.service ActiveMerchant::Billing::Integrations::Alipay::Helper::CREATE_DIRECT_PAY_BY_USER %>
<% service.payment_type 1 %>
<% service.subject 'payment subject' %>
<% service.sign %>
<% end %>
<%= button_to_function "Submit", "document.getElementById('payment-form').submit()" %>
payment code is the out_trade_no, it must be unique.
total_fee is the total fee of order.
payment subject is the subject of the payment.
payment body is the body of the payment.
For rails3 project, you have to remove the snowman tag, use
<%= button_to_function "Submit", "document.getElementById('payment-form').firstChild.remove();document.getElementById('payment-form').submit()" %>
instead
2. CREATE_PARTNER_TRADE_BY_BUYER 担保交易
<% payment_service_for 'payment code', ActiveMerchant::Billing::Integrations::Alipay::ACCOUNT,
:service => :alipay,
:html => { :id => 'payment-form', :method => :get } do |service| %>
<% service.discount -0.01 %>
<% service.price 0.01 %>
<% service.quantity 2 %>
<% service.seller :email => ActiveMerchant::Billing::Integrations::Alipay::EMAIL %>
<%# service.buyer :id => 'buyer_id' %>
<% service.notify_url url_for(:only_path => false, :action => 'notify') %>
<% service.return_url url_for(:only_path => false, :action => 'done') %>
<% service.show_url url_for(:only_path => false, :action => 'show') %>
<% service.body 'payment body' %>
<% service.charset "utf-8" %>
<% service.service ActiveMerchant::Billing::Integrations::Alipay::Helper::CREATE_PARTNER_TRADE_BY_BUYER %>
<% service.payment_type 1 %>
<% service.subject 'payment subject' %>
<% service.agent ActiveMerchant::Billing::Integrations::Alipay::ACCOUNT %>
<% service.logistics :type => 'EXPRESS', :fee => 0.10, :payment => 'BUYER_PAY' %>
<% service.receive :name => '黄志敏', :address => '上海市静安中华大厦1808室', :zip => 'xxxxxx', :phone => 'xxxxxxxxxxx', :mobile => 'xxxxxxxxxxx' %>
<% service.sign %>
<% end %>
<%= button_to_function "Submit", "document.getElementById('payment-form').submit();" %>
logistics defines how to send the goods.
receive defines where the goods send to.
3. TRADE_CREATE_BY_BUYER 标准双接口
<% payment_service_for 'payment code', ActiveMerchant::Billing::Integrations::Alipay::ACCOUNT,
:service => :alipay,
:html => { :id => 'payment-form', :method => :get } do |service| %>
<% service.discount -0.01 %>
<% service.price 0.01 %>
<% service.quantity 2 %>
<% service.seller :email => ActiveMerchant::Billing::Integrations::Alipay::EMAIL %>
<% service.notify_url url_for(:only_path => false, :action => 'notify') %>
<% service.return_url url_for(:only_path => false, :action => 'done') %>
<% service.show_url url_for(:only_path => false, :action => 'show') %>
<% service.body 'payment body' %>
<% service.charset "utf-8" %>
<% service.service ActiveMerchant::Billing::Integrations::Alipay::Helper::TRADE_CREATE_BY_BUYER %>
<% service.payment_type 1 %>
<% service.subject 'payment subject' %>
<% service.logistics :type => 'EXPRESS', :fee => 0.10, :payment => 'BUYER_PAY' %>
<% service.receive :name => '黄志敏', :address => '上海市静安中华大厦1808室', :zip => 'xxxxxx', :phone => 'xxxxxxxxxxx', :mobile => 'xxxxxxxxxxx' %>
<% service.sign %>
<% end %>
<%= button_to_function "Submit", "document.getElementById('payment-form').submit();" %>
notification = ActiveMerchant::Billing::Integrations::Alipay::Notification.new(request.raw_post)
AlipayTxn.create(:notify_id => notification.notify_id,
:total_fee => notification.total_fee,
:status => notification.trade_status,
:trade_no => notification.trade_no,
:received_at => notification.notify_time)
notification.acknowledge
case notification.status
when "WAIT_BUYER_PAY"
@order.pend_payment!
when "WAIT_SELLER_SEND_GOODS"
@order.pend_shipment!
when "WAIT_BUYER_CONFIRM_GOODS"
@order.confirm_shipment!
when "TRADE_FINISHED"
@order.pay!
else
@order.fail_payment!
end
def done
r = ActiveMerchant::Billing::Integrations::Alipay::Return.new(request.query_string)
unless @result = r.success?
logger.warn(r.message)
end
end
for helper
CREATE_DIRECT_PAY_BY_USER = 'create_direct_pay_by_user'
CREATE_PARTNER_TRADE_BY_BUYER = 'create_partner_trade_by_buyer'
TRADE_CREATE_BY_BUYER = 'trade_create_by_buyer'
###################################################
# common
###################################################
mapping :account, 'partner'
mapping :order, 'out_trade_no'
mapping :seller, :email => 'seller_email',
:id => 'seller_id'
mapping :buyer, :email => 'buyer_email',
:id => 'buyer_id'
mapping :notify_url, 'notify_url'
mapping :return_url, 'return_url'
mapping :show_url, 'show_url'
mapping :body, 'body'
mapping :subject, 'subject'
mapping :charset, '_input_charset'
mapping :service, 'service'
mapping :payment_type, 'payment_type'
#################################################
# create direct pay by user
#################################################
mapping :total_fee, 'total_fee'
mapping :paymethod, 'paymethod'
mapping :defaultbank, 'defaultbank'
mapping :royalty, :type => 'royalty_type',
:parameters => 'royalty_parameters'
mapping :it_b_pay, 'it_b_pay'
#################################################
# create partner trade by buyer and trade create by user
#################################################
mapping :price, 'price'
mapping :quantity, 'quantity'
mapping :discount, 'discount'
['', '_1', '_2', '_3'].each do |postfix|
self.class_eval <<-EOF
mapping :logistics#{postfix}, :type => 'logistics_type#{postfix}',
:fee => 'logistics_fee#{postfix}',
:payment => 'logistics_payment#{postfix}'
EOF
end
mapping :receive, :name => 'receive_name',
:address => 'receive_address',
:zip => 'receive_zip',
:phone => 'receive_phone',
:mobile => 'receive_mobile'
mapping :t_b_pay, 't_b_pay'
mapping :t_s_send_1, 't_s_send_1'
mapping :t_s_send_2, 't_s_send_2'
#################################################
# create partner trade by buyer
#################################################
mapping :agent, 'agent'
mapping :buyer_msg, 'buyer_msg'
for notification
['notify_type', 'notify_id', 'out_trade_no', 'trade_no', 'payment_type', 'subject', 'body',
'seller_email', 'seller_id', 'buyer_email', 'buyer_id', 'logistics_type', 'logistics_payment',
'receive_name', 'receive_address', 'receive_zip', 'receive_phone', 'receive_mobile'].each do |param|
self.class_eval <<-EOF
def #{param}
params['#{param}']
end
EOF
end
['price', 'discount', 'quantity', 'total_fee', 'coupon_discount', 'logistics_fee'].each do |param|
self.class_eval <<-EOF
def #{param}
params['#{param}']
end
EOF
end
['trade_status', 'refund_status', 'logistics_status'].each do |param|
self.class_eval <<-EOF
def #{param}
params['#{param}']
end
EOF
end
['notify_time', 'gmt_create', 'gmt_payment', 'gmt_close', 'gmt_refund', 'gmt_send_goods', 'gmt_logistics_modify'].each do |param|
self.class_eval <<-EOF
def #{param}
Time.parse params['#{param}']
end
EOF
end
['use_coupon', 'is_total_fee_adjust'].each do |param|
self.class_eval <<-EOF
def #{param}?
'T' == params['#{param}']
end
EOF
end