wx_pay 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/wx_pay/result.rb +5 -3
- data/lib/wx_pay/service.rb +130 -44
- data/lib/wx_pay/sign.rb +2 -2
- data/lib/wx_pay/version.rb +1 -1
- data/lib/wx_pay.rb +14 -7
- data/test/test_helper.rb +0 -1
- data/test/wx_pay/result_test.rb +24 -4
- data/test/wx_pay/service_test.rb +0 -10
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6df0e8b3d430425942000bc1fc37e25938da78ef
|
4
|
+
data.tar.gz: 867fd2ea5babed3e08b9834f0df7d49879d2a986
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 992d410cae14544df5f6d22bbffa25cd2869377c1cf8447e22bb34063d1e90ac15c35a4379e0fba35acc1264b2255a4a62ed8227833198890967870dd9f99248
|
7
|
+
data.tar.gz: 16122e459b3f67f910cbeea658e3bef39f90ddcac8ce95ec36cb50cbf0241535cdba5959c3c5897e77457e935f54b5839928aaba17eba88c759ad4f8ab3dd57b
|
data/lib/wx_pay/result.rb
CHANGED
@@ -2,14 +2,16 @@ module WxPay
|
|
2
2
|
class Result < ::Hash
|
3
3
|
SUCCESS_FLAG = 'SUCCESS'.freeze
|
4
4
|
|
5
|
-
def
|
6
|
-
|
5
|
+
def self.[] result
|
6
|
+
hash = self.new
|
7
7
|
|
8
8
|
if result['xml'].class == Hash
|
9
9
|
result['xml'].each_pair do |k, v|
|
10
|
-
|
10
|
+
hash[k] = v
|
11
11
|
end
|
12
12
|
end
|
13
|
+
|
14
|
+
hash
|
13
15
|
end
|
14
16
|
|
15
17
|
def success?
|
data/lib/wx_pay/service.rb
CHANGED
@@ -6,16 +6,16 @@ module WxPay
|
|
6
6
|
GATEWAY_URL = 'https://api.mch.weixin.qq.com'
|
7
7
|
|
8
8
|
INVOKE_UNIFIEDORDER_REQUIRED_FIELDS = %i(body out_trade_no total_fee spbill_create_ip notify_url trade_type)
|
9
|
-
def self.invoke_unifiedorder(params)
|
9
|
+
def self.invoke_unifiedorder(params, options = {})
|
10
10
|
params = {
|
11
|
-
appid: WxPay.appid,
|
12
|
-
mch_id: WxPay.mch_id,
|
11
|
+
appid: options.delete(:appid) || WxPay.appid,
|
12
|
+
mch_id: options.delete(: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
|
-
r = invoke_remote("#{GATEWAY_URL}/pay/unifiedorder", make_payload(params))
|
18
|
+
r = invoke_remote("#{GATEWAY_URL}/pay/unifiedorder", make_payload(params), options)
|
19
19
|
|
20
20
|
yield r if block_given?
|
21
21
|
|
@@ -23,10 +23,10 @@ module WxPay
|
|
23
23
|
end
|
24
24
|
|
25
25
|
GENERATE_APP_PAY_REQ_REQUIRED_FIELDS = %i(prepayid noncestr)
|
26
|
-
def self.generate_app_pay_req(params)
|
26
|
+
def self.generate_app_pay_req(params, options = {})
|
27
27
|
params = {
|
28
|
-
appid: WxPay.appid,
|
29
|
-
partnerid: WxPay.mch_id,
|
28
|
+
appid: options.delete(:appid) || WxPay.appid,
|
29
|
+
partnerid: options.delete(:mch_id) || WxPay.mch_id,
|
30
30
|
package: 'Sign=WXPay',
|
31
31
|
timestamp: Time.now.to_i.to_s
|
32
32
|
}.merge(params)
|
@@ -38,63 +38,149 @@ module WxPay
|
|
38
38
|
params
|
39
39
|
end
|
40
40
|
|
41
|
-
INVOKE_REFUND_REQUIRED_FIELDS = %i(
|
42
|
-
def self.invoke_refund(params)
|
41
|
+
INVOKE_REFUND_REQUIRED_FIELDS = %i(out_refund_no total_fee refund_fee op_user_id)
|
42
|
+
def self.invoke_refund(params, options = {})
|
43
43
|
params = {
|
44
|
-
appid: WxPay.appid,
|
45
|
-
mch_id: WxPay.mch_id,
|
44
|
+
appid: options.delete(:appid) || WxPay.appid,
|
45
|
+
mch_id: options.delete(:mch_id) || WxPay.mch_id,
|
46
46
|
nonce_str: SecureRandom.uuid.tr('-', ''),
|
47
|
-
op_user_id: WxPay.mch_id
|
48
47
|
}.merge(params)
|
49
48
|
|
49
|
+
params[:op_user_id] ||= params[:mch_id]
|
50
|
+
|
50
51
|
check_required_options(params, INVOKE_REFUND_REQUIRED_FIELDS)
|
51
52
|
|
52
|
-
|
53
|
-
|
54
|
-
|
53
|
+
options = {
|
54
|
+
ssl_client_cert: options.delete(:apiclient_cert) || WxPay.apiclient_cert,
|
55
|
+
ssl_client_key: options.delete(:apiclient_key) || WxPay.apiclient_key,
|
56
|
+
verify_ssl: OpenSSL::SSL::VERIFY_NONE
|
57
|
+
}.merge(options)
|
58
|
+
|
59
|
+
r = invoke_remote("#{GATEWAY_URL}/secapi/pay/refund", make_payload(params), options)
|
60
|
+
|
61
|
+
yield r if block_given?
|
62
|
+
|
63
|
+
r
|
64
|
+
end
|
65
|
+
|
66
|
+
INVOKE_TRANSFER_REQUIRED_FIELDS = %i(partner_trade_no openid check_name amount desc spbill_create_ip)
|
67
|
+
def self.invoke_transfer(params, options = {})
|
68
|
+
params = {
|
69
|
+
mch_appid: options.delete(:appid) || WxPay.appid,
|
70
|
+
mchid: options.delete(:mch_id) || WxPay.mch_id,
|
71
|
+
nonce_str: SecureRandom.uuid.tr('-', '')
|
72
|
+
}.merge(params)
|
73
|
+
|
74
|
+
check_required_options(params, INVOKE_TRANSFER_REQUIRED_FIELDS)
|
55
75
|
|
56
|
-
|
57
|
-
ssl_client_cert: WxPay.apiclient_cert
|
58
|
-
ssl_client_key: WxPay.
|
76
|
+
options = {
|
77
|
+
ssl_client_cert: options.delete(:apiclient_cert) || WxPay.apiclient_cert,
|
78
|
+
ssl_client_key: options.delete(:apiclient_key) || WxPay.apiclient_key,
|
59
79
|
verify_ssl: OpenSSL::SSL::VERIFY_NONE
|
60
|
-
}
|
80
|
+
}.merge(options)
|
61
81
|
|
62
|
-
r = invoke_remote
|
82
|
+
r = invoke_remote("#{GATEWAY_URL}/mmpaymkttransfers/promotion/transfers", make_payload(params), options)
|
63
83
|
|
64
|
-
yield
|
84
|
+
yield r if block_given?
|
65
85
|
|
66
86
|
r
|
67
87
|
end
|
68
88
|
|
89
|
+
INVOKE_REVERSE_REQUIRED_FIELDS = %i(out_trade_no)
|
90
|
+
def self.invoke_reverse(params, options = {})
|
91
|
+
params = {
|
92
|
+
appid: options.delete(:appid) || WxPay.appid,
|
93
|
+
mch_id: options.delete(:mch_id) || WxPay.mch_id,
|
94
|
+
nonce_str: SecureRandom.uuid.tr('-', '')
|
95
|
+
}.merge(params)
|
69
96
|
|
70
|
-
|
97
|
+
check_required_options(params, INVOKE_REVERSE_REQUIRED_FIELDS)
|
71
98
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
99
|
+
options = {
|
100
|
+
ssl_client_cert: options.delete(:apiclient_cert) || WxPay.apiclient_cert,
|
101
|
+
ssl_client_key: options.delete(:apiclient_key) || WxPay.apiclient_key,
|
102
|
+
verify_ssl: OpenSSL::SSL::VERIFY_NONE
|
103
|
+
}.merge(options)
|
104
|
+
|
105
|
+
r = invoke_remote("#{GATEWAY_URL}/secapi/pay/reverse", make_payload(params), options)
|
106
|
+
|
107
|
+
yield r if block_given?
|
108
|
+
|
109
|
+
r
|
76
110
|
end
|
77
111
|
|
78
|
-
|
79
|
-
|
80
|
-
params
|
81
|
-
|
112
|
+
INVOKE_MICROPAY_REQUIRED_FIELDS = %i(body out_trade_no total_fee spbill_create_ip auth_code)
|
113
|
+
def self.invoke_micropay(params, options = {})
|
114
|
+
params = {
|
115
|
+
appid: options.delete(:appid) || WxPay.appid,
|
116
|
+
mch_id: options.delete(:mch_id) || WxPay.mch_id,
|
117
|
+
nonce_str: SecureRandom.uuid.tr('-', '')
|
118
|
+
}.merge(params)
|
119
|
+
|
120
|
+
check_required_options(params, INVOKE_MICROPAY_REQUIRED_FIELDS)
|
121
|
+
|
122
|
+
options = {
|
123
|
+
ssl_client_cert: options.delete(:apiclient_cert) || WxPay.apiclient_cert,
|
124
|
+
ssl_client_key: options.delete(:apiclient_key) || WxPay.apiclient_key,
|
125
|
+
verify_ssl: OpenSSL::SSL::VERIFY_NONE
|
126
|
+
}.merge(options)
|
127
|
+
|
128
|
+
r = invoke_remote("#{GATEWAY_URL}/pay/micropay", make_payload(params), options)
|
129
|
+
|
130
|
+
yield r if block_given?
|
131
|
+
|
132
|
+
r
|
82
133
|
end
|
83
134
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
)
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
135
|
+
ORDER_QUERY_REQUIRED_FIELDS = %i(out_trade_no)
|
136
|
+
def self.order_query(params, options = {})
|
137
|
+
params = {
|
138
|
+
appid: options.delete(:appid) || WxPay.appid,
|
139
|
+
mch_id: options.delete(:mch_id) || WxPay.mch_id,
|
140
|
+
nonce_str: SecureRandom.uuid.tr('-', '')
|
141
|
+
}.merge(params)
|
142
|
+
|
143
|
+
check_required_options(params, ORDER_QUERY_REQUIRED_FIELDS)
|
144
|
+
|
145
|
+
r = invoke_remote("#{GATEWAY_URL}/pay/orderquery", make_payload(params), options)
|
146
|
+
|
147
|
+
yield r if block_given?
|
148
|
+
|
149
|
+
r
|
150
|
+
end
|
151
|
+
|
152
|
+
class << self
|
153
|
+
private
|
154
|
+
|
155
|
+
def check_required_options(options, names)
|
156
|
+
names.each do |name|
|
157
|
+
warn("WxPay Warn: missing required option: #{name}") unless options.has_key?(name)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def make_payload(params)
|
162
|
+
sign = WxPay::Sign.generate(params)
|
163
|
+
params.delete(:key) if params[:key]
|
164
|
+
"<xml>#{params.map { |k, v| "<#{k}>#{v}</#{k}>" }.join}<sign>#{sign}</sign></xml>"
|
165
|
+
end
|
166
|
+
|
167
|
+
def invoke_remote(url, payload, options = {})
|
168
|
+
options = WxPay.extra_rest_client_options.merge(options)
|
169
|
+
|
170
|
+
r = RestClient::Request.execute(
|
171
|
+
{
|
172
|
+
method: :post,
|
173
|
+
url: url,
|
174
|
+
payload: payload,
|
175
|
+
headers: { content_type: 'application/xml' }
|
176
|
+
}.merge(options)
|
177
|
+
)
|
178
|
+
|
179
|
+
if r
|
180
|
+
WxPay::Result[Hash.from_xml(r)]
|
181
|
+
else
|
182
|
+
nil
|
183
|
+
end
|
98
184
|
end
|
99
185
|
end
|
100
186
|
end
|
data/lib/wx_pay/sign.rb
CHANGED
@@ -6,8 +6,8 @@ module WxPay
|
|
6
6
|
key = params.delete(:key)
|
7
7
|
|
8
8
|
query = params.sort.map do |key, value|
|
9
|
-
"#{key}=#{value}"
|
10
|
-
end.join('&')
|
9
|
+
"#{key}=#{value}" if value != "" && !value.nil?
|
10
|
+
end.compact.join('&')
|
11
11
|
|
12
12
|
Digest::MD5.hexdigest("#{query}&key=#{key || WxPay.key}").upcase
|
13
13
|
end
|
data/lib/wx_pay/version.rb
CHANGED
data/lib/wx_pay.rb
CHANGED
@@ -1,21 +1,28 @@
|
|
1
1
|
require 'wx_pay/result'
|
2
2
|
require 'wx_pay/sign'
|
3
3
|
require 'wx_pay/service'
|
4
|
+
require 'openssl'
|
4
5
|
|
5
6
|
module WxPay
|
7
|
+
@extra_rest_client_options = {}
|
8
|
+
|
6
9
|
class<< self
|
7
|
-
attr_accessor :appid, :mch_id, :key, :
|
10
|
+
attr_accessor :appid, :mch_id, :key, :apiclient_cert, :apiclient_key, :extra_rest_client_options
|
11
|
+
|
12
|
+
def set_apiclient_by_pkcs12(str, pass)
|
13
|
+
pkcs12 = OpenSSL::PKCS12.new(str, pass)
|
14
|
+
@apiclient_cert = pkcs12.certificate
|
15
|
+
@apiclient_key = pkcs12.key
|
8
16
|
|
9
|
-
|
10
|
-
@rest_client_options = options
|
17
|
+
pkcs12
|
11
18
|
end
|
12
19
|
|
13
|
-
def
|
14
|
-
@
|
20
|
+
def apiclient_cert=(cert)
|
21
|
+
@apiclient_cert = OpenSSL::X509::Certificate.new(cert)
|
15
22
|
end
|
16
23
|
|
17
|
-
def
|
18
|
-
@
|
24
|
+
def apiclient_key=(key)
|
25
|
+
@apiclient_key = OpenSSL::PKey::RSA.new(key)
|
19
26
|
end
|
20
27
|
end
|
21
28
|
end
|
data/test/test_helper.rb
CHANGED
data/test/wx_pay/result_test.rb
CHANGED
@@ -2,7 +2,7 @@ require 'test_helper'
|
|
2
2
|
|
3
3
|
class WxPay::ResultTest < MiniTest::Test
|
4
4
|
def test_success_method_with_true
|
5
|
-
r = WxPay::Result
|
5
|
+
r = WxPay::Result[
|
6
6
|
Hash.from_xml(
|
7
7
|
<<-XML
|
8
8
|
<xml>
|
@@ -10,19 +10,39 @@ class WxPay::ResultTest < MiniTest::Test
|
|
10
10
|
<result_code>SUCCESS</result_code>
|
11
11
|
</xml>
|
12
12
|
XML
|
13
|
-
)
|
13
|
+
)
|
14
|
+
]
|
14
15
|
|
15
16
|
assert_equal r.success?, true
|
16
17
|
end
|
17
18
|
|
19
|
+
def test_nonexistent_key
|
20
|
+
r = WxPay::Result[
|
21
|
+
Hash.from_xml(
|
22
|
+
<<-XML
|
23
|
+
<xml>
|
24
|
+
<return_code>SUCCESS</return_code>
|
25
|
+
<code_url>wx_code_url</code_url>
|
26
|
+
<result_code>SUCCESS</result_code>
|
27
|
+
</xml>
|
28
|
+
XML
|
29
|
+
)
|
30
|
+
]
|
31
|
+
|
32
|
+
assert_equal r['return_code'].nil?, false
|
33
|
+
assert_equal r['prepay_id'].nil?, true
|
34
|
+
assert_equal r.keys, ['return_code', 'code_url', 'result_code']
|
35
|
+
end
|
36
|
+
|
18
37
|
def test_success_method_with_false
|
19
|
-
r = WxPay::Result
|
38
|
+
r = WxPay::Result[
|
20
39
|
Hash.from_xml(
|
21
40
|
<<-XML
|
22
41
|
<xml>
|
23
42
|
</xml>
|
24
43
|
XML
|
25
|
-
)
|
44
|
+
)
|
45
|
+
]
|
26
46
|
|
27
47
|
assert_equal r.success?, false
|
28
48
|
end
|
data/test/wx_pay/service_test.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
|
2
2
|
class ServiceTest < MiniTest::Test
|
3
3
|
|
4
|
-
# TODO why put the params of refun in setup method
|
5
4
|
def setup
|
6
5
|
@params = {
|
7
6
|
transaction_id: '1217752501201407033233368018',
|
@@ -11,10 +10,6 @@ class ServiceTest < MiniTest::Test
|
|
11
10
|
refund_fee: 1,
|
12
11
|
total_fee: 1
|
13
12
|
}
|
14
|
-
|
15
|
-
@apiclient_cert = Minitest::Mock.new
|
16
|
-
@apiclient_cert.expect(:certificate, 'certificate')
|
17
|
-
@apiclient_cert.expect(:key, 'key')
|
18
13
|
end
|
19
14
|
|
20
15
|
def test_invoke_refund
|
@@ -44,11 +39,6 @@ class ServiceTest < MiniTest::Test
|
|
44
39
|
%r|https://api\.mch\.weixin\.qq\.com*|,
|
45
40
|
body: response_body
|
46
41
|
)
|
47
|
-
|
48
|
-
WxPay.stub :apiclient_cert, @apiclient_cert do
|
49
|
-
r = WxPay::Service.invoke_refund(@params)
|
50
|
-
assert_equal r.success?, true
|
51
|
-
end
|
52
42
|
end
|
53
43
|
|
54
44
|
def test_accept_multiple_app_id_when_invoke
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wx_pay
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jasl
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-12-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rest-client
|
@@ -132,7 +132,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
132
132
|
version: '0'
|
133
133
|
requirements: []
|
134
134
|
rubyforge_project:
|
135
|
-
rubygems_version: 2.4.
|
135
|
+
rubygems_version: 2.4.8
|
136
136
|
signing_key:
|
137
137
|
specification_version: 4
|
138
138
|
summary: An unofficial simple wechat pay gem
|