Skip to content

Commit

Permalink
support refund
Browse files Browse the repository at this point in the history
  • Loading branch information
jimhj committed Jul 9, 2015
1 parent e450b0b commit 39e31c9
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 3 deletions.
2 changes: 1 addition & 1 deletion lib/wx_pay.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

module WxPay
class<< self
attr_accessor :appid, :mch_id, :key
attr_accessor :appid, :mch_id, :key, :apiclient_cert_file

def extra_rest_client_options=(options)
@rest_client_options = options
Expand Down
36 changes: 34 additions & 2 deletions lib/wx_pay/service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

module WxPay
module Service
GATEWAY_URL = 'https://api.mch.weixin.qq.com/pay'
GATEWAY_URL = 'https://api.mch.weixin.qq.com'

INVOKE_UNIFIEDORDER_REQUIRED_FIELDS = %i(body out_trade_no total_fee spbill_create_ip notify_url trade_type)
def self.invoke_unifiedorder(params)
Expand All @@ -15,7 +15,7 @@ def self.invoke_unifiedorder(params)

check_required_options(params, INVOKE_UNIFIEDORDER_REQUIRED_FIELDS)

r = invoke_remote("#{GATEWAY_URL}/unifiedorder", make_payload(params))
r = invoke_remote("#{GATEWAY_URL}/pay/unifiedorder", make_payload(params))

yield r if block_given?

Expand All @@ -38,6 +38,38 @@ def self.generate_app_pay_req(params)
params
end

INVOKE_REFUND_REQUIRED_FIELDS = %i(transaction_id out_trade_no out_refund_no total_fee refund_fee)
def self.invoke_refund(params)
params = {
appid: WxPay.appid,
mch_id: WxPay.mch_id,
nonce_str: SecureRandom.uuid.tr('-', ''),
op_user_id: WxPay.mch_id
}.merge(params)

check_required_options(params, INVOKE_REFUND_REQUIRED_FIELDS)

# 微信退款需要双向证书
# https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4
# https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3

p12_file = File.read WxPay.apiclient_cert_file
cert = OpenSSL::PKCS12.new(p12_file, WxPay.mch_id)

WxPay.extra_rest_client_options = {
ssl_client_cert: cert.certificate,
ssl_client_key: cert.key,
verify_ssl: OpenSSL::SSL::VERIFY_NONE
}

r = invoke_remote "#{GATEWAY_URL}/secapi/pay/refund", make_payload(params)

yield(r) if block_given?

r
end


private

def self.check_required_options(options, names)
Expand Down
47 changes: 47 additions & 0 deletions test/wx_pay/service_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
class ServiceTest < MiniTest::Test
def setup
WxPay.appid = 'xxxxxxxxxxxxxx'
WxPay.key = 'xxxxxxxxxxxxxxx'
WxPay.mch_id = 'xxxxxxxxxxxxxx'
WxPay.apiclient_cert_file = '/Users/jimmy/Workspace/shopshow-ultron/public/apiclient_cert.p12'

@params = {
transaction_id: '1217752501201407033233368018',
op_user_id: '10000100',
out_refund_no: '1415701182',
out_trade_no: '1415757673',
refund_fee: 1,
total_fee: 1
}
end

def test_invoke_refund
response_body = <<-EOF
<xml>
<return_code><![CDATA[SUCCESS]]></return_code>
<return_msg><![CDATA[OK]]></return_msg>
<appid><![CDATA[wx2421b1c4370ec43b]]></appid>
<mch_id><![CDATA[10000100]]></mch_id>
<nonce_str><![CDATA[NfsMFbUFpdbEhPXP]]></nonce_str>
<sign><![CDATA[B7274EB9F8925EB93100DD2085FA56C0]]></sign>
<result_code><![CDATA[SUCCESS]]></result_code>
<transaction_id><![CDATA[1008450740201411110005820873]]></transaction_id>
<out_trade_no><![CDATA[1415757673]]></out_trade_no>
<out_refund_no><![CDATA[1415701182]]></out_refund_no>
<refund_id><![CDATA[2008450740201411110000174436]]></refund_id>
<refund_channel><![CDATA[]]></refund_channel>
<refund_fee>1</refund_fee>
<coupon_refund_fee>0</coupon_refund_fee>
</xml>
EOF

FakeWeb.register_uri(
:post,
%r|https://api\.mch\.weixin\.qq\.com*|,
body: response_body
)

r = WxPay::Service.invoke_refund(@params)
assert_equal r.success?, true
end
end

0 comments on commit 39e31c9

Please sign in to comment.