Commit 1fa6ade437289662de34647f24a1910df7dcff3b
1 parent
48419b64
Exists in
master
first functional version
Showing
12 changed files
with
115 additions
and
62 deletions
Show diff stats
README.md
... | ... | @@ -30,14 +30,47 @@ $ bundle |
30 | 30 | ### Config |
31 | 31 | |
32 | 32 | ```ruby |
33 | +# required | |
33 | 34 | WxPay.appid = 'YOUR_APPID' |
34 | 35 | WxPay.key = 'YOUR_KEY' |
35 | 36 | WxPay.mch_id = 'YOUR_MCH_ID' |
37 | + | |
38 | +# optional | |
39 | +WxPay.extra_rest_client_options = {timeout: 2, open_timeout: 3} | |
36 | 40 | ``` |
37 | 41 | |
38 | 42 | ### APIs |
39 | 43 | |
40 | -**PLACEHOLDER** | |
44 | +**Check official document for detailed request params and return fields** | |
45 | + | |
46 | +#### unifiedorder | |
47 | + | |
48 | +```ruby | |
49 | +# required fields | |
50 | +params = { | |
51 | +body: '测试商品', | |
52 | +out_trade_no: 'test003', | |
53 | +total_fee: 1, | |
54 | +spbill_create_ip: '127.0.0.1', | |
55 | +notify_url: 'http://making.dev', | |
56 | +trade_type: 'JSAPI' | |
57 | +} | |
58 | + | |
59 | +# Return a WxPay::Result instance(subclass of Hash) contains parsed result | |
60 | +r = WxPay::Service.invoke_unifiedorder params | |
61 | +# => {"return_code"=>"SUCCESS", | |
62 | +# "return_msg"=>"OK", | |
63 | +# "appid"=>"YOUR APPID", | |
64 | +# "mch_id"=>"YOUR MCH_ID", | |
65 | +# "nonce_str"=>"8RN7YfTZ3OUgWX5e", | |
66 | +# "sign"=>"623AE90C9679729DDD7407DC7A1151B2", | |
67 | +# "result_code"=>"SUCCESS", | |
68 | +# "prepay_id"=>"wx2014111104255143b7605afb0314593866", | |
69 | +# "trade_type"=>"JSAPI"} | |
70 | + | |
71 | +# Return true if both return_code and result_code equal SUCCESS | |
72 | +r.success? # => true | |
73 | +``` | |
41 | 74 | |
42 | 75 | ## Contributing |
43 | 76 | ... | ... |
lib/wx_pay.rb
lib/wx_pay/notify.rb
... | ... | @@ -1,18 +0,0 @@ |
1 | -module WxPay | |
2 | - module Notify | |
3 | - GATEWAY = 'https://gw.tenpay.com/gateway/simpleverifynotifyid.xml' | |
4 | - SUCCESS_STR = '<retcode>0</retcode>' | |
5 | - | |
6 | - def self.verify?(params) | |
7 | - return false unless Sign.verify?(params) | |
8 | - | |
9 | - params = { | |
10 | - 'input_charset' => 'UTF-8', | |
11 | - 'partner' => WxPay.appid, | |
12 | - 'notify_id' => CGI.escape(params[:notify_id].to_s) | |
13 | - } | |
14 | - | |
15 | - open("#{GATEWAY}?#{Utils.make_query_string(params)}").read.include?(SUCCESS_STR) | |
16 | - end | |
17 | - end | |
18 | -end |
... | ... | @@ -0,0 +1,19 @@ |
1 | +module WxPay | |
2 | + class Result < ::Hash | |
3 | + SUCCESS_FLAG = 'SUCCESS'.freeze | |
4 | + | |
5 | + def initialize(result) | |
6 | + super | |
7 | + | |
8 | + if result['xml'].class == Hash | |
9 | + result['xml'].each_pair do |k, v| | |
10 | + self[k] = v | |
11 | + end | |
12 | + end | |
13 | + end | |
14 | + | |
15 | + def success? | |
16 | + self['return_code'] == SUCCESS_FLAG && self['result_code'] == SUCCESS_FLAG | |
17 | + end | |
18 | + end | |
19 | +end | ... | ... |
lib/wx_pay/service.rb
... | ... | @@ -8,14 +8,18 @@ module WxPay |
8 | 8 | INVOKE_UNIFIEDORDER_REQUIRED_FIELDS = %i(body out_trade_no total_fee spbill_create_ip notify_url trade_type) |
9 | 9 | def self.invoke_unifiedorder(params) |
10 | 10 | params = { |
11 | - app_id: WxPay.appid, | |
11 | + appid: WxPay.appid, | |
12 | 12 | mch_id: WxPay.mch_id, |
13 | 13 | nonce_str: SecureRandom.uuid.tr('-', ''), |
14 | 14 | }.merge(params) |
15 | 15 | |
16 | 16 | check_required_options(params, INVOKE_UNIFIEDORDER_REQUIRED_FIELDS) |
17 | 17 | |
18 | - WxPay::Utils.invoke_remote("#{GATEWAY_URL}/unifiedorder", WxPay::Utils.make_payload(params)) | |
18 | + r = invoke_remote("#{GATEWAY_URL}/unifiedorder", make_payload(params)) | |
19 | + | |
20 | + yield r if block_given? | |
21 | + | |
22 | + r | |
19 | 23 | end |
20 | 24 | |
21 | 25 | private |
... | ... | @@ -25,5 +29,26 @@ module WxPay |
25 | 29 | warn("WxPay Warn: missing required option: #{name}") unless options.has_key?(name) |
26 | 30 | end |
27 | 31 | end |
32 | + | |
33 | + def self.make_payload(params) | |
34 | + "<xml>#{params.map { |k, v| "<#{k}>#{v}</#{k}>" }.join}<sign>#{WxPay::Sign.generate(params)}</sign></xml>" | |
35 | + end | |
36 | + | |
37 | + def self.invoke_remote(url, payload) | |
38 | + r = RestClient::Request.execute( | |
39 | + { | |
40 | + method: :post, | |
41 | + url: url, | |
42 | + payload: payload, | |
43 | + headers: { content_type: 'application/xml' } | |
44 | + }.merge(WxPay.extra_rest_client_options) | |
45 | + ) | |
46 | + | |
47 | + if r | |
48 | + WxPay::Result.new Hash.from_xml(r) | |
49 | + else | |
50 | + nil | |
51 | + end | |
52 | + end | |
28 | 53 | end |
29 | 54 | end | ... | ... |
lib/wx_pay/sign.rb
... | ... | @@ -11,8 +11,8 @@ module WxPay |
11 | 11 | end |
12 | 12 | |
13 | 13 | def self.verify?(params) |
14 | - params = Utils.stringify_keys(params) | |
15 | - sign = params.delete('sign') | |
14 | + params = params.dup | |
15 | + sign = params.delete('sign') || params.delete(:sign) | |
16 | 16 | |
17 | 17 | generate(params) == sign |
18 | 18 | end | ... | ... |
lib/wx_pay/utils.rb
... | ... | @@ -1,27 +0,0 @@ |
1 | -module WxPay | |
2 | - module Utils | |
3 | - def self.stringify_keys(hash) | |
4 | - new_hash = {} | |
5 | - hash.each do |key, value| | |
6 | - new_hash[(key.to_s rescue key) || key] = value | |
7 | - end | |
8 | - new_hash | |
9 | - end | |
10 | - | |
11 | - def self.make_payload(params) | |
12 | - "<xml>#{params.map {|k, v| "<#{k}>#{v}</#{k}>"}.join}<sign>#{WxPay::Sign.generate(params)}</sign></xml>" | |
13 | - end | |
14 | - | |
15 | - def self.invoke_remote(url, payload) | |
16 | - Hash.from_xml( | |
17 | - RestClient::Request.execute( | |
18 | - { | |
19 | - method: :post, | |
20 | - url: url, | |
21 | - payload: payload, | |
22 | - headers: {content_type: 'application/xml'} | |
23 | - }.merge(WxPay.extra_rest_client_options)) | |
24 | - ) | |
25 | - end | |
26 | - end | |
27 | -end |
lib/wx_pay/version.rb
test/test_helper.rb
... | ... | @@ -0,0 +1,29 @@ |
1 | +require 'test_helper' | |
2 | + | |
3 | +class WxPay::ResultTest < MiniTest::Test | |
4 | + def test_success_method_with_true | |
5 | + r = WxPay::Result.new( | |
6 | + Hash.from_xml( | |
7 | + <<-XML | |
8 | + <xml> | |
9 | + <return_code>SUCCESS</return_code> | |
10 | + <result_code>SUCCESS</result_code> | |
11 | + </xml> | |
12 | + XML | |
13 | + )) | |
14 | + | |
15 | + assert_equal r.success?, true | |
16 | + end | |
17 | + | |
18 | + def test_success_method_with_false | |
19 | + r = WxPay::Result.new( | |
20 | + Hash.from_xml( | |
21 | + <<-XML | |
22 | + <xml> | |
23 | + </xml> | |
24 | + XML | |
25 | + )) | |
26 | + | |
27 | + assert_equal r.success?, false | |
28 | + end | |
29 | +end | ... | ... |
test/wx_pay/sign_test.rb
test/wx_pay/utils_test.rb