Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

add tenpay rspec test. #308

  • Loading branch information...
commit 5139aeff920c0aa7cb8504ffbab5efa8c3812ec0 1 parent 63f0215
@saberma saberma authored
View
65 app/controllers/shop/order_controller.rb
@@ -1,10 +1,10 @@
#encoding: utf-8
class Shop::OrderController < Shop::AppController
include Admin::ShopsHelper
- skip_before_filter :password_protected , only: [:notify, :done]
- skip_before_filter :must_has_theme , only: [:notify, :done]
- skip_before_filter :check_shop_avaliable , only: [:notify, :done]
- skip_before_filter :check_shop_access_enabled, only: [:notify, :done]
+ skip_before_filter :password_protected , only: [:notify, :done, :tenpay_notify, :tenpay_done]
+ skip_before_filter :must_has_theme , only: [:notify, :done, :tenpay_notify, :tenpay_done]
+ skip_before_filter :check_shop_avaliable , only: [:notify, :done, :tenpay_notify, :tenpay_done]
+ skip_before_filter :check_shop_access_enabled, only: [:notify, :done, :tenpay_notify, :tenpay_done]
layout 'shop/checkout'
@@ -137,26 +137,51 @@ def commit
begin 'from pay gateway'
- def notify # 此action只供支付网关(支付宝)服务器的外部通知接口使用,通知我们订单支付状态(notify_url)
- notification = ActiveMerchant::Billing::Integrations::Alipay::Notification.new(request.raw_post)
- @order = Order.find_by_token(notification.out_trade_no)
- if @order and notification.acknowledge(@order.payment.key) and valid?(notification, @order.payment.partner)
- @order.pay!(notification.total_fee) if notification.complete? and @order.financial_status_pending? # 要支持重复请求
- render text: "success"
- else
- render text: "fail"
+ begin '支付宝'
+
+ def notify # 此action只供支付网关(支付宝)服务器的外部通知接口使用,通知我们订单支付状态(notify_url)
+ notification = ActiveMerchant::Billing::Integrations::Alipay::Notification.new(request.raw_post)
+ @order = Order.find_by_token(notification.out_trade_no)
+ if @order and notification.acknowledge(@order.payment.key) and valid?(notification, @order.payment.partner)
+ @order.pay!(notification.total_fee) if notification.complete? and @order.financial_status_pending? # 要支持重复请求
+ render text: "success"
+ else
+ render text: "fail"
+ end
end
+
+ def done # 支付后从浏览器前台直接返回(return_url)
+ pay_return = ActiveMerchant::Billing::Integrations::Alipay::Return.new(request.query_string)
+ @order = Order.find_by_token(pay_return.order)
+ @_resources = { shop: @order.shop } # checkout.haml中expose的shop
+ if @order
+ @order.pay!(pay_return.amount) if @order.financial_status_pending? # 要支持重复请求
+ else
+ raise pay_return.message
+ end
+ end
+
end
- def done # 支付后从浏览器前台直接返回(return_url)
- pay_return = ActiveMerchant::Billing::Integrations::Alipay::Return.new(request.query_string)
- @order = Order.find_by_token(pay_return.order)
- @_resources = { shop: @order.shop } # checkout.haml中expose的shop
- if @order
- @order.pay!(pay_return.amount) if @order.financial_status_pending? # 要支持重复请求
- else
- raise pay_return.message
+ begin '财付通'
+
+ def tenpay_notify # 此action只供支付网关(财付通)服务器的外部通知接口使用,通知我们订单支付状态(return_url)
+ notification = ActiveMerchant::Billing::Integrations::Tenpay::Return.new(request.raw_post)
+ @order = Order.find_by_token(notification.order)
+ if @order and notification.success?(@order.payment.key, @order.payment.partner)
+ @order.pay!(notification.total_fee) if @order.financial_status_pending? # 要支持重复请求
+ render
+ else
+ render text: "fail"
+ end
end
+
+ def tenpay_done # 支付后从浏览器前台直接返回(show_url)
+ @order = Order.find_by_token(params[:token])
+ @_resources = { shop: @order.shop } # checkout.haml中expose的shop
+ render action: :done
+ end
+
end
end
View
5 app/views/shop/order/_confirm_pay_2.html.haml
@@ -5,11 +5,10 @@
- payment_service_for order.token, payment.partner, service: :tenpay, html: { id: 'payment-form', method: :get } do |service|
- service.cmdno 1
- service.date Date.today.to_s(:number)
- -# service.amount (order.total_price*100).to_i # 以分为单位
- - service.amount 1 # 以分为单位
+ - service.amount (order.total_price*100).to_i # 以分为单位
- service.transaction_id "#{payment.partner}#{Date.today.to_s(:number)}#{order.number.to_s.rjust(10, '0')}"
- service.currency '1' # 人民币
- - service.return_url done_order_url
+ - service.return_url tenpay_notify_order_url
- service.charset "utf-8"
- service.spbill_create_ip request.remote_ip
- service.description '商品付款'
View
9 app/views/shop/order/tenpay_notify.html.erb
@@ -0,0 +1,9 @@
+<html>
+<head>
+<meta name="TENCENT_ONLINE_PAYMENT" content="China TENCENT">
+ <script language="javascript">
+ window.location.href='<%= tenpay_done_order_url(@order) %>';
+ </script>
+</head>
+<body></body>
+</html>
View
2  config/routes.rb
@@ -63,6 +63,8 @@
match '/orders/:shop_id/:token/commit' , to: 'order#commit' , as: :commit_order
post '/orders/notify' , to: 'order#notify' , as: :notify_order
get '/orders/done' , to: 'order#done' , as: :done_order
+ post '/orders/tenpay_notify' , to: 'order#tenpay_notify' , as: :tenpay_notify_order
+ get '/orders/tenpay_done/:token' , to: 'order#tenpay_done' , as: :tenpay_done_order
post '/orders/:shop_id/:token/update_total_price' , to: 'order#update_total_price', as: :update_order_total_price
post '/carts/:shop_id/:cart_token/update_tax_price', to: 'order#update_tax_price' , as: :update_order_tax_price
get '/carts/:shop_id/:cart_token/get_address' , to: 'order#get_address' , as: :get_address
View
166 spec/controllers/shop/order_controller_spec.rb
@@ -120,86 +120,143 @@
end
- context '#notify' do # 支付宝从后台发送通过
+ context 'alipay' do # 支付宝
- before do
- post :commit, shop_id: shop.id, token: order.token, order: { shipping_rate: '普通快递-10.0', payment_id: payment_alipay.id }
- order.reload
- controller.stub!(:valid?) { true } # 向支付宝校验notification的合法性
- end
+ context '#notify' do # 支付宝从后台发送通过
- context 'trade status is TRADE_FINISHED' do # 交易完成
+ before do
+ post :commit, shop_id: shop.id, token: order.token, order: { shipping_rate: '普通快递-10.0', payment_id: payment_alipay.id }
+ order.reload
+ controller.stub!(:valid?) { true } # 向支付宝校验notification的合法性
+ end
- let(:attrs) { { out_trade_no: order.token, notify_id: '123456', trade_status: 'TRADE_FINISHED', total_fee: order.total_price } }
+ context 'trade status is TRADE_FINISHED' do # 交易完成
- it 'should change order financial_status to paid' do
- order.financial_status_pending?.should be_true
- expect do
+ let(:attrs) { { out_trade_no: order.token, notify_id: '123456', trade_status: 'TRADE_FINISHED', total_fee: order.total_price } }
+
+ it 'should change order financial_status to paid' do
+ order.financial_status_pending?.should be_true
+ expect do
+ post :notify, attrs.merge(sign_type: 'md5', sign: sign(attrs, order.payment.key))
+ response.body.should eql 'success'
+ order.reload.financial_status_paid?.should be_true
+ end.should change(OrderTransaction, :count).by(1)
+ order.transactions.first.amount.should eql order.total_price
+ end
+
+ it 'should be retry' do # 要支持重复请求
+ order.reload
+ order.financial_status = :abandoned
+ order.save
post :notify, attrs.merge(sign_type: 'md5', sign: sign(attrs, order.payment.key))
response.body.should eql 'success'
- order.reload.financial_status_paid?.should be_true
- end.should change(OrderTransaction, :count).by(1)
- order.transactions.first.amount.should eql order.total_price
+ post :notify, attrs.merge(sign_type: 'md5', sign: sign(attrs, order.payment.key))
+ response.body.should eql 'success'
+ order.reload.financial_status.to_sym.should eql :abandoned # 不能再次被修改为paid
+ end
+
end
- it 'should be retry' do # 要支持重复请求
- order.reload
- order.financial_status = :abandoned
- order.save
- post :notify, attrs.merge(sign_type: 'md5', sign: sign(attrs, order.payment.key))
- response.body.should eql 'success'
- post :notify, attrs.merge(sign_type: 'md5', sign: sign(attrs, order.payment.key))
- response.body.should eql 'success'
- order.reload.financial_status.to_sym.should eql :abandoned # 不能再次被修改为paid
+ context 'trade status is WAIT_BUYER_PAY' do # 等待顾客付款
+
+ let(:attrs) { { out_trade_no: order.token, notify_id: '123456', trade_status: 'WAIT_BUYER_PAY', total_fee: order.total_price } }
+
+ it 'should remain order financial status' do
+ order.financial_status_pending?.should be_true
+ post :notify, attrs.merge(sign_type: 'md5', sign: sign(attrs, order.payment.key))
+ response.body.should eql 'success'
+ order.reload.financial_status_pending?.should be_true
+ end
+
end
end
- context 'trade status is WAIT_BUYER_PAY' do # 等待顾客付款
+ context '#done' do # 支付宝直接跳转回商店(支付成功后才会返回)
+
+ before do
+ order.financial_status = 'pending'
+ order.payment = payment_alipay
+ order.save
+ end
+
+ context 'trade status is TRADE_SUCCESS' do # 交易完成
- let(:attrs) { { out_trade_no: order.token, notify_id: '123456', trade_status: 'WAIT_BUYER_PAY', total_fee: order.total_price } }
+ let(:attrs) { { out_trade_no: order.token, trade_status: 'TRADE_SUCCESS', total_fee: order.total_price } }
+
+ it 'should change order financial_status to paid' do
+ expect do
+ get :done, attrs.merge(sign_type: 'md5', sign: sign(attrs, order.payment.key))
+ response.should be_success
+ end.should change(OrderTransaction, :count)
+ order.reload.financial_status_paid?.should be_true
+ end
+
+ it 'should be retry' do # 要支持重复请求
+ order.financial_status = :abandoned
+ order.save
+ get :done, attrs.merge(sign_type: 'md5', sign: sign(attrs, order.payment.key))
+ response.should be_success
+ expect do
+ get :done, attrs.merge(sign_type: 'md5', sign: sign(attrs, order.payment.key))
+ response.should be_success
+ end.should_not change(OrderTransaction, :count)
+ order.reload.financial_status.to_sym.should eql :abandoned # 不能再次被修改为paid
+ end
- it 'should remain order financial status' do
- order.financial_status_pending?.should be_true
- post :notify, attrs.merge(sign_type: 'md5', sign: sign(attrs, order.payment.key))
- response.body.should eql 'success'
- order.reload.financial_status_pending?.should be_true
end
end
end
- context '#done' do # 支付宝直接跳转回商店(支付成功后才会返回)
+ context 'tenpay' do # 财付通
+
+ let(:date) { Date.today.to_s(:number) }
+
+ let(:transaction_id) { "#{order.payment.partner}#{date}0000000001" }
+
+ let(:attrs) { { cmdno: '1', pay_result: '0', date: Date.today.to_s(:number), transaction_id: transaction_id, sp_billno: order.token, total_fee: (order.total_price*100).to_i, fee_type: '1', attach: 'ShopQi' } }
before do
- order.financial_status = 'pending'
- order.payment = payment_alipay
- order.save
+ post :commit, shop_id: shop.id, token: order.token, order: { shipping_rate: '普通快递-10.0', payment_id: payment_alipay.id }
+ order.reload
end
- context 'trade status is TRADE_SUCCESS' do # 交易完成
+ context '#notify' do # 财付通从后台发送通过
+
+ context 'trade status is TRADE_FINISHED' do # 交易完成
+
+ it 'should change order financial_status to paid' do
+ order.financial_status_pending?.should be_true
+ expect do
+ post :tenpay_notify, attrs.merge(bargainor_id: order.payment.partner, sign: tenpay_sign(attrs, order.payment.key))
+ response.body.should_not eql 'fail'
+ order.reload.financial_status_paid?.should be_true
+ end.should change(OrderTransaction, :count).by(1)
+ order.transactions.first.amount.should eql order.total_price
+ end
+
+ it 'should be retry' do # 要支持重复请求
+ order.reload
+ order.financial_status = :abandoned
+ order.save
+ post :tenpay_notify, attrs.merge(bargainor_id: order.payment.partner, sign: tenpay_sign(attrs, order.payment.key))
+ response.body.should_not eql 'fail'
+ post :tenpay_notify, attrs.merge(bargainor_id: order.payment.partner, sign: tenpay_sign(attrs, order.payment.key))
+ response.body.should_not eql 'fail'
+ order.reload.financial_status.to_sym.should eql :abandoned # 不能再次被修改为paid
+ end
- let(:attrs) { { out_trade_no: order.token, trade_status: 'TRADE_SUCCESS', total_fee: order.total_price } }
-
- it 'should change order financial_status to paid' do
- expect do
- get :done, attrs.merge(sign_type: 'md5', sign: sign(attrs, order.payment.key))
- response.should be_success
- end.should change(OrderTransaction, :count)
- order.reload.financial_status_paid?.should be_true
end
- it 'should be retry' do # 要支持重复请求
- order.financial_status = :abandoned
- order.save
- get :done, attrs.merge(sign_type: 'md5', sign: sign(attrs, order.payment.key))
+ end
+
+ context '#done' do # 财付通直接跳转回商店(支付成功后才会返回)
+
+ it 'should change order financial_status to paid' do
+ get :tenpay_done, attrs.merge(token: order.token, sign: sign(attrs, order.payment.key))
response.should be_success
- expect do
- get :done, attrs.merge(sign_type: 'md5', sign: sign(attrs, order.payment.key))
- response.should be_success
- end.should_not change(OrderTransaction, :count)
- order.reload.financial_status.to_sym.should eql :abandoned # 不能再次被修改为paid
end
end
@@ -207,3 +264,8 @@
end
end
+
+def tenpay_sign(attrs, key) # 财付通传递url参数时的加密字符串
+ md5_string = attrs.map {|s| "#{s[0]}=#{s[1]}"}
+ Digest::MD5.hexdigest(md5_string.join("&") + "&key=#{key}")
+end
Please sign in to comment.
Something went wrong with that request. Please try again.