wechat-pay 1.0.1 → 1.0.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e659dc3c1801cab85da470df5087895bd4a12e43d428f8fad282d2aba84022d2
4
- data.tar.gz: f21c6f6ce72180bd0506bce69d2aae1e539dfbfbc1ddd69fc809d83719faa5f1
3
+ metadata.gz: 045dc62b08427aa1464eecd46652ef49bdd9e23844188f8da76b8936df107a98
4
+ data.tar.gz: f308b67ccb2d6a4927d385bedd17682cf553808716b280411e68b30f8a0e549e
5
5
  SHA512:
6
- metadata.gz: 7e1ac7d823df910753d26f52df615e82cef3ebaa8109dd299009fca5be48f7062361af7b2698a9b4a00fa4afc08d7ea8417677fb396e189d8efea54f309b5ad0
7
- data.tar.gz: d6ec25bc79c1d1a96f0a9292b5045b7d52ebe41d0ba5c1cd50bd0cc8b6224460834833437f33d965225cce6190f74a5218ddcdace289b1702552bb79c6965cd5
6
+ metadata.gz: aa8ac213931f250a5683c046304f18556d84db25e166e0d685e6acfc1068be12699de3bc1c1d3ec236e38922d6f7db2aa2c30f08eeda9edf7c8fc223060f39f9
7
+ data.tar.gz: 9adffad7aea7e9390ecc3ba68262eb6eadaec93694ee904c47a7207cf290e52b3b4954831b581f6141f7809a98011ceb3607b573bdfed383c165d8f6941cc93d
@@ -0,0 +1,35 @@
1
+ # This workflow uses actions that are not certified by GitHub.
2
+ # They are provided by a third-party and are governed by
3
+ # separate terms of service, privacy policy, and support
4
+ # documentation.
5
+ # This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
6
+ # For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
7
+
8
+ name: Ruby
9
+
10
+ on:
11
+ pull_request:
12
+ branches: [ master ]
13
+
14
+ jobs:
15
+ test:
16
+
17
+ runs-on: ubuntu-latest
18
+ strategy:
19
+ matrix:
20
+ ruby-version: ['2.6', '2.7', '3.0']
21
+
22
+ steps:
23
+ - uses: actions/checkout@v2
24
+ - name: Set up Ruby
25
+ # To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
26
+ # change this to (see https://github.com/ruby/setup-ruby#versioning):
27
+ # uses: ruby/setup-ruby@v1
28
+ uses: ruby/setup-ruby@473e4d8fe5dd94ee328fdfca9f8c9c7afc9dae5e
29
+ with:
30
+ ruby-version: ${{ matrix.ruby-version }}
31
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
32
+ - name: Run rubocop
33
+ run: bundle exec rubocop
34
+ - name: Run tests
35
+ run: bundle exec rake
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ *.gem
2
+ Gemfile.lock
3
+ doc/
4
+ .yardoc/
5
+ rdoc/
6
+ /*.pem
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --force-color
2
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,21 @@
1
+ AllCops:
2
+ NewCops: enable
3
+ SuggestExtensions: false
4
+
5
+ Style/AsciiComments:
6
+ Enabled: false
7
+
8
+ Metrics/BlockLength:
9
+ Enabled: false
10
+
11
+ Metrics/AbcSize:
12
+ Enabled: false
13
+
14
+ Metrics/MethodLength:
15
+ Max: 30
16
+
17
+ Layout/LineLength:
18
+ Enabled: false
19
+
20
+ Metrics/ModuleLength:
21
+ Max: 200
data/.yardopts ADDED
@@ -0,0 +1,3 @@
1
+ --markup markdown
2
+ --protected
3
+ --no-private
data/CHANGELOG.md ADDED
@@ -0,0 +1,10 @@
1
+ # Next Release
2
+
3
+ ## 1.0.8 (05/26/2021)
4
+
5
+ * Add api `invoke_transactions_in_native` to `WechatPay::Ecommerce`
6
+
7
+ ## 1.0.7 (05/16/2021)
8
+
9
+ * Change `WechatPay::Ecommerce.get_certificates` to `WechatPay::Ecommerce.certificates`
10
+ * Refactor code and document.
data/Gemfile ADDED
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ # Declare your gem's dependencies in tenpay.gemspec.
6
+ # Bundler will treat runtime dependencies like base dependencies, and
7
+ # development dependencies will be added by default to the :development group.
8
+ gemspec
9
+
10
+ # Declare any dependencies that are still in development here instead of in
11
+ # your gemspec. These might include edge Rails or gems from your path or
12
+ # Git. Remember to move these dependencies to your gemspec before releasing
13
+ # your gem to rubygems.org.
14
+
15
+ # To use debugger
data/README.md ADDED
@@ -0,0 +1,92 @@
1
+ # Wechat Pay
2
+
3
+ A simple Wechat pay ruby gem, without unnecessary magic or wrapper. Just a simple wrapper for api V3. Refer to [wx_pay](https://github.com/jasl/wx_pay)
4
+
5
+ Please read official document first: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/pages/index.shtml
6
+
7
+ If you want check the present public api, you can find them in the [Document](https://www.rubydoc.info/github/lanzhiheng/wechat-pay/master/index)。
8
+
9
+ Summary:
10
+
11
+ `WechatPay::Direct` will contain the public api for direct connection merchant(直连商户)and `WechatPay::Ecommerce` will contain the public api for ecommerce(服务商,电商平台)。For more detail you can refer to the wechat document.
12
+
13
+ - 直连商户: https://pay.weixin.qq.com/wiki/doc/apiv3/index.shtml
14
+ - 服务商: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/index.shtml
15
+ - 电商平台(电商收付通): https://pay.weixin.qq.com/wiki/doc/apiv3_partner/open/pay/chapter3_3_3.shtml
16
+
17
+ If you find any issue in this repo, don't shy to create issues https://github.com/lanzhiheng/wechat-pay/issues
18
+
19
+ For more Information,you can check my posts: https://www.lanzhiheng.com/posts/preview/ruby-gem-for-wechat-pay-v3
20
+
21
+ # Installation
22
+
23
+ Add this line to your Gemfile:
24
+
25
+ ```
26
+ gem 'wechat-pay'
27
+ ```
28
+
29
+ or development version
30
+
31
+ ```
32
+ gem 'wechat-pay', :github => 'lanzhiheng/wechat-pay'
33
+ ```
34
+
35
+ And then execute:
36
+
37
+ ```
38
+ $ bundle
39
+ ```
40
+
41
+ # Usage
42
+
43
+ ## Configuration
44
+
45
+ Create `config/initializer/wechat_pay.rb`and put following configurations into it
46
+
47
+ ``` ruby
48
+ WechatPay.apiclient_key = File.read('apiclient_key.pem')
49
+ WechatPay.platform_cert = File.read('platform_cert.pem') # You should comment this line before downloaded platform_cert.
50
+ WechatPay.apiclient_cert = File.read('apiclient_cert.pem')
51
+ WechatPay.app_id = 'Your App Id'
52
+ WechatPay.mch_id = 'Your Mch Id'
53
+ WechatPay.mch_key = 'Your Mch Key'
54
+ ```
55
+
56
+ ## Download
57
+
58
+ I will provide a simple script for you to download the platform_cert
59
+
60
+ ``` ruby
61
+ def download_certificate
62
+ download_path = 'Your Download Path'
63
+ raise '必须提供证书下载路径' if download_path.blank?
64
+
65
+ response = WechatPay::Ecommerce.certificates
66
+
67
+ raise '证书下载失败' unless response.code == 200
68
+
69
+ result = JSON.parse(response.body)
70
+ # 需要按生效日期进行排序,获取最新的证书
71
+ array = result['data'].sort_by { |item| -Time.parse(item['effective_time']).to_i }
72
+ current_data = array.first
73
+ encrypt_certificate = current_data['encrypt_certificate']
74
+ associated_data = encrypt_certificate['associated_data']
75
+ nonce = encrypt_certificate['nonce']
76
+ ciphertext = encrypt_certificate['ciphertext']
77
+
78
+ content = WechatPay::Sign.decrypt_the_encrypt_params(
79
+ associated_data: associated_data,
80
+ nonce: nonce,
81
+ ciphertext: ciphertext
82
+ )
83
+
84
+ File.open(download_path, 'w') do |f|
85
+ f.write(content)
86
+ end
87
+
88
+ puts '证书下载成功'
89
+ end
90
+ ```
91
+
92
+
data/Rakefile ADDED
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ begin
4
+ require 'bundler/setup'
5
+ require 'rspec/core/rake_task'
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
9
+ rescue LoadError
10
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
11
+ end
12
+
13
+ require 'rdoc/task'
14
+ Rake::RDocTask.new do |rdoc|
15
+ rdoc.rdoc_dir = 'rdoc'
16
+ rdoc.title = "wechat-pay #{WechatPay::VERSION}"
17
+ rdoc.rdoc_files.include('README*')
18
+ rdoc.rdoc_files.include('lib/**/*.rb')
19
+ end
data/lib/wechat-pay.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # rubocop:disable Naming/FileName
2
+
1
3
  # frozen_string_literal: true
2
4
 
3
5
  require 'restclient'
@@ -8,7 +10,6 @@ require 'wechat-pay/ecommerce' # 电商平台
8
10
  # # 微信支付
9
11
  #
10
12
  # 设置关键信息
11
-
12
13
  module WechatPay
13
14
  class<< self
14
15
  attr_accessor :app_id, :mch_id, :mch_key
@@ -40,3 +41,4 @@ module WechatPay
40
41
  end
41
42
  end
42
43
  end
44
+ # rubocop:enable Naming/FileName
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'json'
2
4
  require 'wechat-pay/helper'
3
5
 
@@ -7,585 +9,343 @@ module WechatPay
7
9
  module Direct
8
10
  include WechatPayHelper
9
11
 
10
- class<<self
11
- INVOKE_COMBINE_TRANSACTIONS_IN_APP_FIELDS = %i[combine_out_trade_no scene_info sub_orders notify_url].freeze # :nodoc:
12
- #
13
- # 直连合单app下单
14
- #
15
- # TODO: 与电商平台类似,只是参数不同,稍后重构
16
- #
17
- # Document: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter5_1_1.shtml
18
- #
19
- # Example:
20
- #
21
- # ``` ruby
22
- # params = {
23
- # combine_out_trade_no: 'combine_out_trade_no',
24
- # combine_payer_info: {
25
- # openid: 'client open id'
26
- # },
27
- # sub_orders: [
28
- # {
29
- # mchid: 'mchid',
30
- # sub_mchid: 'sub mchid',
31
- # attach: 'attach',
32
- # amount: {
33
- # total_amount: 100,
34
- # currency: 'CNY'
35
- # },
36
- # out_trade_no: 'out_trade_no',
37
- # description: 'description'
38
- # }
39
- # ],
40
- # notify_url: 'the_url'
41
- # }
42
- #
43
- # WechatPay::Direct.invoke_combine_transactions_in_app(params)
44
- # ```
45
- def invoke_combine_transactions_in_app(params)
46
- WechatPay::Ecommerce.invoke_combine_transactions_in_app(params)
47
- end
48
-
49
- INVOKE_COMBINE_TRANSACTIONS_IN_JS_FIELDS = %i[combine_out_trade_no scene_info sub_orders notify_url].freeze # :nodoc:
50
- #
51
- # 直连合单js下单
52
- #
53
- # TODO: 与电商平台类似,只是参数不同,稍后重构
54
- #
55
- # Document: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter5_1_3.shtml
56
- #
57
- # Example:
58
- #
59
- # ``` ruby
60
- # params = {
61
- # combine_out_trade_no: 'combine_out_trade_no',
62
- # combine_payer_info: {
63
- # openid: 'client open id'
64
- # },
65
- # sub_orders: [
66
- # {
67
- # mchid: 'mchid',
68
- # sub_mchid: 'sub mchid',
69
- # attach: 'attach',
70
- # amount: {
71
- # total_amount: 100,
72
- # currency: 'CNY'
73
- # },
74
- # out_trade_no: 'out_trade_no',
75
- # description: 'description'
76
- # }
77
- # ],
78
- # notify_url: 'the_url'
79
- # }
80
- #
81
- # WechatPay::Direct.invoke_combine_transactions_in_js(params)
82
- # ```
83
- def invoke_combine_transactions_in_js(params)
84
- WechatPay::Ecommerce.invoke_combine_transactions_in_js(params)
85
- end
86
-
87
- INVOKE_COMBINE_TRANSACTIONS_IN_H5_FIELDS = %i[combine_out_trade_no scene_info sub_orders notify_url].freeze # :nodoc:
88
- #
89
- # 直连合单h5下单
90
- #
91
- # TODO: 与电商平台类似,只是参数不同,稍后重构
92
- #
93
- # Document: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter5_1_2.shtml
94
- #
95
- # Example:
96
- #
97
- # ``` ruby
98
- # params = {
99
- # combine_out_trade_no: 'combine_out_trade_no',
100
- # sub_orders: [
101
- # {
102
- # mchid: 'mchid',
103
- # sub_mchid: 'sub mchid',
104
- # attach: 'attach',
105
- # amount: {
106
- # total_amount: 100,
107
- # currency: 'CNY'
108
- # },
109
- # out_trade_no: 'out_trade_no',
110
- # description: 'description'
111
- # }
112
- # ],
113
- # notify_url: 'the_url'
114
- # }
115
- #
116
- # WechatPay::Direct.invoke_combine_transactions_in_h5(params)
117
- # ```
118
- def invoke_combine_transactions_in_h5(params)
119
- WechatPay::Ecommerce.invoke_combine_transactions_in_h5(params)
120
- end
121
-
122
- INVOKE_COMBINE_TRANSACTIONS_IN_MINIPROGRAM_FIELDS = %i[combine_out_trade_no scene_info sub_orders notify_url].freeze # :nodoc:
123
- #
124
- # 直连合单小程序下单
125
- #
126
- # TODO: 与电商平台类似,只是参数不同,稍后重构
127
- #
128
- # Document: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter5_1_4.shtml
129
- #
130
- # Example:
131
- #
132
- # ``` ruby
133
- # params = {
134
- # combine_out_trade_no: 'combine_out_trade_no',
135
- # combine_payer_info: {
136
- # openid: 'client open id'
137
- # },
138
- # sub_orders: [
139
- # {
140
- # mchid: 'mchid',
141
- # sub_mchid: 'sub mchid',
142
- # attach: 'attach',
143
- # amount: {
144
- # total_amount: 100,
145
- # currency: 'CNY'
146
- # },
147
- # out_trade_no: 'out_trade_no',
148
- # description: 'description'
149
- # }
150
- # ],
151
- # notify_url: 'the_url'
152
- # }
153
- #
154
- # WechatPay::Direct.invoke_combine_transactions_in_miniprogram(params)
155
- # ```
156
- def invoke_combine_transactions_in_miniprogram(params)
157
- WechatPay::Ecommerce.invoke_combine_transactions_in_miniprogram(params)
158
- end
159
-
160
- INVOKE_COMBINE_TRANSACTIONS_IN_NATIVE_FIELDS = %i[combine_out_trade_no scene_info sub_orders notify_url].freeze # :nodoc:
161
- #
162
- # 直连合单native下单
163
- #
164
- # TODO: 与电商平台类似,只是参数不同,稍后重构
165
- #
166
- # Document: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter5_1_5.shtml
167
- #
168
- # Example:
169
- #
170
- # ``` ruby
171
- # params = {
172
- # combine_out_trade_no: 'combine_out_trade_no',
173
- # sub_orders: [
174
- # {
175
- # mchid: 'mchid',
176
- # sub_mchid: 'sub mchid',
177
- # attach: 'attach',
178
- # amount: {
179
- # total_amount: 100,
180
- # currency: 'CNY'
181
- # },
182
- # out_trade_no: 'out_trade_no',
183
- # description: 'description'
184
- # }
185
- # ],
186
- # notify_url: 'the_url'
187
- # }
188
- #
189
- # WechatPay::Direct.invoke_combine_transactions_in_native(params)
190
- # ```
191
- def invoke_combine_transactions_in_native(params)
192
- WechatPay::Ecommerce.invoke_combine_transactions_in_native(params)
193
- end
194
-
195
- QUERY_COMBINE_ORDER_FIELDS = %i[combine_out_trade_no].freeze # :nodoc:
196
- #
197
- # 合单查询
198
- #
199
- # TODO: 与电商平台相同,稍后重构
200
- #
201
- # Document: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter7_3_11.shtml
202
- #
203
- # ``` ruby
204
- # WechatPay::Direct.query_order(combine_out_trade_no: 'C202104302474')
205
- # ```
206
- #
207
- def query_combine_order(params)
208
- combine_out_trade_no = params.delete(:combine_out_trade_no)
209
-
210
- url = "/v3/combine-transactions/out-trade-no/#{combine_out_trade_no}"
211
-
212
- method = 'GET'
213
-
214
- make_request(
215
- method: method,
216
- path: url,
217
- extra_headers: {
218
- 'Content-Type' => 'application/x-www-form-urlencoded'
219
- }
220
- )
221
- end
222
-
223
- CLOSE_COMBINE_ORDER_FIELDS = %i[combine_out_trade_no sub_orders].freeze # :nodoc:
224
- #
225
- # 关闭合单
226
- #
227
- # TODO: 与电商平台相同,稍后重构
228
- #
229
- # Document: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter7_3_11.shtml
230
- #
231
- # ``` ruby
232
- # WechatPay::Direct.close_combine_order(combine_out_trade_no: 'C202104302474')
233
- # ```
234
- def close_combine_order(params)
235
- combine_out_trade_no = params.delete(:combine_out_trade_no)
236
-
237
- url = "/v3/combine-transactions/out-trade-no/#{combine_out_trade_no}/close"
238
-
239
- payload = {
240
- combine_appid: WechatPay.app_id
241
- }.merge(params)
242
-
243
- payload_json = payload.to_json
244
-
245
- method = 'POST'
246
-
247
- make_request(
248
- method: method,
249
- for_sign: payload_json,
250
- payload: payload_json,
251
- path: url
252
- )
253
- end
254
-
255
- INVOKE_TRANSACTIONS_IN_JS_FIELDS = %i[description out_trade out_trade_no payer amount notify_url].freeze # :nodoc:
256
- #
257
- # 直连js下单
258
- #
259
- # Document: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_1.shtml
260
- #
261
- # Example:
262
- #
263
- # ``` ruby
264
- # params = {
265
- # appid: 'Your Open id',
266
- # mchid: 'Your Mch id'',
267
- # description: '回流',
268
- # out_trade_no: 'Checking',
269
- # payer: {
270
- # openid: 'oly6s5c'
271
- # },
272
- # amount: {
273
- # total: 1
274
- # },
275
- # notify_url: ENV['NOTIFICATION_URL']
276
- # }
277
- #
278
- # WechatPay::Direct.invoke_transactions_in_js(params)
279
- # ```
280
- def invoke_transactions_in_js(params)
281
- direct_transactions_method_by_suffix('jsapi', params)
282
- end
283
-
284
- INVOKE_TRANSACTIONS_IN_MINIPROGRAM_FIELDS = %i[description out_trade out_trade_no payer amount notify_url].freeze # :nodoc:
285
- #
286
- # 直连小程序下单
287
- #
288
- # Document:https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_5_1.shtml
289
- #
290
- # Example:
291
- #
292
- # ``` ruby
293
- # params = {
294
- # appid: 'Your Open id',
295
- # mchid: 'Your Mch id'',
296
- # description: '回流',
297
- # out_trade_no: 'Checking',
298
- # payer: {
299
- # openid: 'oly6s5c'
300
- # },
301
- # amount: {
302
- # total: 1
303
- # },
304
- # notify_url: ENV['NOTIFICATION_URL']
305
- # }
306
- #
307
- # WechatPay::Direct.invoke_transactions_in_miniprogram(params)
308
- # ```
309
- def invoke_transactions_in_miniprogram(params)
310
- direct_transactions_method_by_suffix('jsapi', params)
311
- end
312
-
313
- INVOKE_TRANSACTIONS_IN_APP_FIELDS = %i[description out_trade out_trade_no payer amount notify_url].freeze # :nodoc:
314
- #
315
- # 直连APP下单
316
- #
317
- # Document: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_2_1.shtml
318
- #
319
- # Example:
320
- #
321
- # ``` ruby
322
- # params = {
323
- # appid: 'Your Open id',
324
- # mchid: 'Your Mch id'',
325
- # description: '回流',
326
- # out_trade_no: 'Checking',
327
- # payer: {
328
- # openid: 'oly6s5c'
329
- # },
330
- # amount: {
331
- # total: 1
332
- # },
333
- # notify_url: ENV['NOTIFICATION_URL']
334
- # }
335
- #
336
- # WechatPay::Direct.invoke_transactions_in_app(params)
337
- # ```
338
- def invoke_transactions_in_app(params)
339
- direct_transactions_method_by_suffix('app', params)
340
- end
341
-
342
- INVOKE_TRANSACTIONS_IN_H5_FIELDS = %i[description out_trade out_trade_no payer amount notify_url].freeze # :nodoc:
343
- #
344
- # 直连h5下单
345
- #
346
- # Document: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_3_1.shtml
347
- #
348
- # Example:
349
- #
350
- # ```
351
- # params = {
352
- # appid: 'Your Open id',
353
- # mchid: 'Your Mch id'',
354
- # description: '回流',
355
- # out_trade_no: 'Checking',
356
- # payer: {
357
- # openid: 'oly6s5c'
358
- # },
359
- # amount: {
360
- # total: 1
361
- # },
362
- # notify_url: ENV['NOTIFICATION_URL']
363
- # }
364
- #
365
- # WechatPay::Direct.invoke_transactions_in_h5(params)
366
- # ```
367
- def invoke_transactions_in_h5(params)
368
- direct_transactions_method_by_suffix('h5', params)
12
+ # @private
13
+ # @!macro [attach] define_transaction_method
14
+ # 直连$1下单
15
+ #
16
+ # Document: $3
17
+ #
18
+ # Example:
19
+ #
20
+ # ``` ruby
21
+ # params = {
22
+ # appid: 'Your Open id',
23
+ # mchid: 'Your Mch id'',
24
+ # description: '回流',
25
+ # out_trade_no: 'Checking',
26
+ # payer: {
27
+ # openid: 'oly6s5c'
28
+ # },
29
+ # amount: {
30
+ # total: 1
31
+ # },
32
+ # notify_url: ENV['NOTIFICATION_URL']
33
+ # }
34
+ #
35
+ # WechatPay::Direct.invoke_transactions_in_$1(params)
36
+ # ```
37
+ # @!method invoke_transactions_in_$1
38
+ # @!scope class
39
+ def self.define_transaction_method(key, value, _document)
40
+ const_set("INVOKE_TRANSACTIONS_IN_#{key.upcase}_FIELDS",
41
+ %i[description out_trade out_trade_no payer amount notify_url].freeze)
42
+ define_singleton_method "invoke_transactions_in_#{key}" do |params|
43
+ direct_transactions_method_by_suffix(value, params)
369
44
  end
45
+ end
370
46
 
371
- INVOKE_TRANSACTIONS_IN_NATIVE_FIELDS = %i[description out_trade out_trade_no payer amount notify_url].freeze # :nodoc:
372
- #
373
- # 直连native下单
374
- #
375
- # Document: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_4_1.shtml
376
- #
377
- # Example:
378
- #
379
- # ``` ruby
380
- # params = {
381
- # appid: 'Your Open id',
382
- # mchid: 'Your Mch id'',
383
- # description: '回流',
384
- # out_trade_no: 'Checking',
385
- # payer: {
386
- # openid: 'oly6s5c'
387
- # },
388
- # amount: {
389
- # total: 1
390
- # },
391
- # notify_url: ENV['NOTIFICATION_URL']
392
- # }
393
- #
394
- # WechatPay::Direct.invoke_transactions_in_native(params)
395
- # ```
396
- def invoke_transactions_in_native(params)
397
- direct_transactions_method_by_suffix('native', params)
47
+ define_transaction_method('js', 'jsapi', 'https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_5_1.shtml')
48
+ define_transaction_method('miniprogram', 'jsapi', 'https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_5_1.shtml')
49
+ define_transaction_method('app', 'app', 'https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_2_1.shtml')
50
+ define_transaction_method('h5', 'h5', 'https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_3_1.shtml')
51
+ define_transaction_method('native', 'native', 'https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_4_1.shtml')
52
+
53
+ # @private
54
+ # @!macro [attach] define_combine_transaction_method
55
+ # 直连合单$1下单
56
+ #
57
+ # Document: $3
58
+ #
59
+ # ``` ruby
60
+ # params = {
61
+ # combine_out_trade_no: 'combine_out_trade_no',
62
+ # combine_payer_info: {
63
+ # openid: 'client open id'
64
+ # },
65
+ # sub_orders: [
66
+ # {
67
+ # mchid: 'mchid',
68
+ # sub_mchid: 'sub mchid',
69
+ # attach: 'attach',
70
+ # amount: {
71
+ # total_amount: 100,
72
+ # currency: 'CNY'
73
+ # },
74
+ # out_trade_no: 'out_trade_no',
75
+ # description: 'description'
76
+ # }
77
+ # ],
78
+ # notify_url: 'the_url'
79
+ # }
80
+ #
81
+ # WechatPay::Direct.invoke_combine_transactions_in_$1(params)
82
+ # ```
83
+ # @!method invoke_combine_transactions_in_$1
84
+ # @!scope class
85
+ def self.define_combine_transaction_method(key, _value, _document)
86
+ const_set("INVOKE_COMBINE_TRANSACTIONS_IN_#{key.upcase}_FIELDS",
87
+ %i[combine_out_trade_no scene_info sub_orders notify_url].freeze)
88
+ define_singleton_method("invoke_combine_transactions_in_#{key}") do |params|
89
+ WechatPay::Ecommerce.send("invoke_combine_transactions_in_#{key}", params)
398
90
  end
91
+ end
399
92
 
400
- QUERY_ORDER_FIELDS = %i[out_trade_no transaction_id].freeze # :nodoc:
401
- #
402
- # 直连订单查询
403
- #
404
- # Document: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_5_2.shtml
405
- #
406
- # Example:
407
- #
408
- # ``` ruby
409
- # WechatPay::Direct.query_order(transaction_id: '4323400972202104305133344444') # by transaction_id
410
- # WechatPay::Direct.query_order(out_trade_no: 'N202104302474') # by out_trade_no
411
- # ```
412
- #
413
- def query_order(params)
414
- if params[:transaction_id]
415
- params.delete(:out_trade_no)
416
- transaction_id = params.delete(:transaction_id)
417
- path = "/v3/pay/transactions/id/#{transaction_id}"
418
- else
419
- params.delete(:transaction_id)
420
- out_trade_no = params.delete(:out_trade_no)
421
- path = "/v3/pay/transactions/out-trade-no/#{out_trade_no}"
422
- end
423
-
424
- params = params.merge({
425
- mchid: WechatPay.mch_id
426
- })
427
-
428
- method = 'GET'
429
- query = build_query(params)
430
- url = "#{path}?#{query}"
93
+ define_combine_transaction_method('app', 'app', 'https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter5_1_1.shtml')
94
+ define_combine_transaction_method('js', 'jsapi', 'https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter5_1_3.shtml')
95
+ define_combine_transaction_method('h5', 'h5', 'https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter5_1_2.shtml')
96
+ define_combine_transaction_method('miniprogram', 'jsapi', 'https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter5_1_4.shtml')
97
+ define_combine_transaction_method('native', 'native', 'https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter5_1_5.shtml')
98
+
99
+ QUERY_COMBINE_ORDER_FIELDS = %i[combine_out_trade_no].freeze # :nodoc:
100
+ #
101
+ # 合单查询
102
+ #
103
+ # TODO: 与电商平台相同,稍后重构
104
+ #
105
+ # Document: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter7_3_11.shtml
106
+ #
107
+ # ``` ruby
108
+ # WechatPay::Direct.query_order(combine_out_trade_no: 'C202104302474')
109
+ # ```
110
+ #
111
+ def self.query_combine_order(params)
112
+ combine_out_trade_no = params.delete(:combine_out_trade_no)
113
+
114
+ url = "/v3/combine-transactions/out-trade-no/#{combine_out_trade_no}"
115
+
116
+ method = 'GET'
117
+
118
+ make_request(
119
+ method: method,
120
+ path: url,
121
+ extra_headers: {
122
+ 'Content-Type' => 'application/x-www-form-urlencoded'
123
+ }
124
+ )
125
+ end
431
126
 
432
- make_request(
433
- method: method,
434
- path: url,
435
- extra_headers: {
436
- 'Content-Type' => 'application/x-www-form-urlencoded'
437
- }
438
- )
439
- end
127
+ CLOSE_COMBINE_ORDER_FIELDS = %i[combine_out_trade_no sub_orders].freeze # :nodoc:
128
+ #
129
+ # 关闭合单
130
+ #
131
+ # TODO: 与电商平台相同,稍后重构
132
+ #
133
+ # Document: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter7_3_11.shtml
134
+ #
135
+ # ``` ruby
136
+ # WechatPay::Direct.close_combine_order(combine_out_trade_no: 'C202104302474')
137
+ # ```
138
+ def self.close_combine_order(params)
139
+ combine_out_trade_no = params.delete(:combine_out_trade_no)
140
+
141
+ url = "/v3/combine-transactions/out-trade-no/#{combine_out_trade_no}/close"
142
+
143
+ payload = {
144
+ combine_appid: WechatPay.app_id
145
+ }.merge(params)
146
+
147
+ payload_json = payload.to_json
148
+
149
+ method = 'POST'
150
+
151
+ make_request(
152
+ method: method,
153
+ for_sign: payload_json,
154
+ payload: payload_json,
155
+ path: url
156
+ )
157
+ end
440
158
 
441
- CLOSE_ORDER_FIELDS = %i[out_trade_no].freeze # :nodoc:
442
- #
443
- # 关闭订单
444
- #
445
- # Document: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_5_3.shtml
446
- #
447
- # Example:
448
- #
449
- # ``` ruby
450
- # WechatPay::Direct.close_order(out_trade_no: 'N3344445')
451
- # ```
452
- #
453
- def close_order(params)
159
+ QUERY_ORDER_FIELDS = %i[out_trade_no transaction_id].freeze # :nodoc:
160
+ #
161
+ # 直连订单查询
162
+ #
163
+ # Document: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_5_2.shtml
164
+ #
165
+ # Example:
166
+ #
167
+ # ``` ruby
168
+ # WechatPay::Direct.query_order(transaction_id: '4323400972202104305133344444') # by transaction_id
169
+ # WechatPay::Direct.query_order(out_trade_no: 'N202104302474') # by out_trade_no
170
+ # ```
171
+ #
172
+ def self.query_order(params)
173
+ if params[:transaction_id]
174
+ params.delete(:out_trade_no)
175
+ transaction_id = params.delete(:transaction_id)
176
+ path = "/v3/pay/transactions/id/#{transaction_id}"
177
+ else
178
+ params.delete(:transaction_id)
454
179
  out_trade_no = params.delete(:out_trade_no)
455
- url = "/v3/pay/transactions/out-trade-no/#{out_trade_no}/close"
456
- params = params.merge({
457
- mchid: WechatPay.mch_id
458
- })
459
-
460
- method = 'POST'
461
-
462
- make_request(
463
- method: method,
464
- path: url,
465
- for_sign: params.to_json,
466
- payload: params.to_json
467
- )
180
+ path = "/v3/pay/transactions/out-trade-no/#{out_trade_no}"
468
181
  end
469
182
 
470
- INVOKE_REFUND_FIELDS = %i[transaction_id out_trade_no out_refund_no amount].freeze # :nodoc:
471
- #
472
- # 退款申请
473
- #
474
- # Document: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_5_9.shtml
475
- #
476
- # Example:
477
- #
478
- # ``` ruby
479
- # WechatPay::Direct.invoke_refund(transaction_id: '4323400972202104305131070170', total: 1, refund: 1, out_refund_no: 'R10000')
480
- # WechatPay::Direct.invoke_refund(out_trade_no: 'N2021', total: 1, refund: 1, out_refund_no: 'R10000').body
481
- # ```
482
- def invoke_refund(params)
483
- url = '/v3/refund/domestic/refunds'
484
- method = 'POST'
485
- amount = {
486
- refund: params.delete(:refund),
487
- total: params.delete(:total),
488
- currency: 'CNY'
489
- }
490
-
491
- params = params.merge({
492
- amount: amount
493
- })
183
+ params = params.merge({
184
+ mchid: WechatPay.mch_id
185
+ })
494
186
 
495
- make_request(
496
- path: url,
497
- method: method,
498
- for_sign: params.to_json,
499
- payload: params.to_json
500
- )
501
- end
187
+ method = 'GET'
188
+ query = build_query(params)
189
+ url = "#{path}?#{query}"
502
190
 
503
- QUERY_REFUND_FIELDS = %i[sub_mchid refund_id out_refund_no].freeze # :nodoc:
504
- #
505
- # 直连退款查询
506
- #
507
- # Document: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_5_10.shtml
508
- #
509
- # Example:
510
- #
511
- # ``` ruby
512
- # WechatPay::Direct.query_refund(out_refund_no: 'R10000')
513
- # ```
514
- #
515
- def query_refund(params)
516
- out_refund_no = params.delete(:out_refund_no)
517
- url = "/v3/refund/domestic/refunds/#{out_refund_no}"
518
-
519
- method = 'GET'
191
+ make_request(
192
+ method: method,
193
+ path: url,
194
+ extra_headers: {
195
+ 'Content-Type' => 'application/x-www-form-urlencoded'
196
+ }
197
+ )
198
+ end
520
199
 
521
- make_request(
522
- method: method,
523
- path: url,
524
- extra_headers: {
525
- 'Content-Type' => 'application/x-www-form-urlencoded'
526
- }
527
- )
528
- end
200
+ CLOSE_ORDER_FIELDS = %i[out_trade_no].freeze # :nodoc:
201
+ #
202
+ # 关闭订单
203
+ #
204
+ # Document: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_5_3.shtml
205
+ #
206
+ # Example:
207
+ #
208
+ # ``` ruby
209
+ # WechatPay::Direct.close_order(out_trade_no: 'N3344445')
210
+ # ```
211
+ #
212
+ def self.close_order(params)
213
+ out_trade_no = params.delete(:out_trade_no)
214
+ url = "/v3/pay/transactions/out-trade-no/#{out_trade_no}/close"
215
+ params = params.merge({
216
+ mchid: WechatPay.mch_id
217
+ })
218
+
219
+ method = 'POST'
220
+
221
+ make_request(
222
+ method: method,
223
+ path: url,
224
+ for_sign: params.to_json,
225
+ payload: params.to_json
226
+ )
227
+ end
529
228
 
530
- TRADEBILL_FIELDS = [:bill_date].freeze # :nodoc:
531
- #
532
- # 直连申请交易账单
533
- #
534
- # Todo: 跟商户平台接口相同
535
- #
536
- # Document: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_5_6.shtml
537
- #
538
- # Example:
539
- #
540
- # ``` ruby
541
- # WechatPay::direct.tradebill(bill_date: '2021-04-30')
542
- # ```
543
- def tradebill(params)
544
- path = '/v3/bill/tradebill'
545
- method = 'GET'
546
-
547
- query = build_query(params)
548
- url = "#{path}?#{query}"
229
+ INVOKE_REFUND_FIELDS = %i[transaction_id out_trade_no out_refund_no amount].freeze # :nodoc:
230
+ #
231
+ # 退款申请
232
+ #
233
+ # Document: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_5_9.shtml
234
+ #
235
+ # Example:
236
+ #
237
+ # ``` ruby
238
+ # WechatPay::Direct.invoke_refund(transaction_id: '4323400972202104305131070170', total: 1, refund: 1, out_refund_no: 'R10000')
239
+ # WechatPay::Direct.invoke_refund(out_trade_no: 'N2021', total: 1, refund: 1, out_refund_no: 'R10000').body
240
+ # ```
241
+ def self.invoke_refund(params)
242
+ url = '/v3/refund/domestic/refunds'
243
+ method = 'POST'
244
+ amount = {
245
+ refund: params.delete(:refund),
246
+ total: params.delete(:total),
247
+ currency: 'CNY'
248
+ }
249
+
250
+ params = params.merge({
251
+ amount: amount
252
+ })
253
+
254
+ make_request(
255
+ path: url,
256
+ method: method,
257
+ for_sign: params.to_json,
258
+ payload: params.to_json
259
+ )
260
+ end
549
261
 
550
- make_request(
551
- path: url,
552
- method: method,
553
- extra_headers: {
554
- 'Content-Type' => 'application/x-www-form-urlencoded'
555
- }
556
- )
557
- end
262
+ QUERY_REFUND_FIELDS = %i[sub_mchid refund_id out_refund_no].freeze # :nodoc:
263
+ #
264
+ # 直连退款查询
265
+ #
266
+ # Document: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_5_10.shtml
267
+ #
268
+ # Example:
269
+ #
270
+ # ``` ruby
271
+ # WechatPay::Direct.query_refund(out_refund_no: 'R10000')
272
+ # ```
273
+ #
274
+ def self.query_refund(params)
275
+ out_refund_no = params.delete(:out_refund_no)
276
+ url = "/v3/refund/domestic/refunds/#{out_refund_no}"
277
+
278
+ method = 'GET'
279
+
280
+ make_request(
281
+ method: method,
282
+ path: url,
283
+ extra_headers: {
284
+ 'Content-Type' => 'application/x-www-form-urlencoded'
285
+ }
286
+ )
287
+ end
558
288
 
559
- FUNDFLOWBILL_FIELDS = [:bill_date].freeze # :nodoc:
560
- #
561
- # 申请资金账单
562
- #
563
- # Todo: 跟商户平台接口相同
564
- #
565
- # Document: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_5_7.shtml
566
- #
567
- # Example:
568
- #
569
- # ``` ruby
570
- # WechatPay::Direct.fundflowbill(bill_date: '2021-04-30')
571
- # ```
572
- #
573
- def fundflowbill(params)
574
- path = '/v3/bill/fundflowbill'
575
- method = 'GET'
576
-
577
- query = build_query(params)
578
- url = "#{path}?#{query}"
289
+ TRADEBILL_FIELDS = [:bill_date].freeze # :nodoc:
290
+ #
291
+ # 直连申请交易账单
292
+ #
293
+ # Todo: 跟商户平台接口相同
294
+ #
295
+ # Document: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_5_6.shtml
296
+ #
297
+ # Example:
298
+ #
299
+ # ``` ruby
300
+ # WechatPay::direct.tradebill(bill_date: '2021-04-30')
301
+ # ```
302
+ def self.tradebill(params)
303
+ path = '/v3/bill/tradebill'
304
+ method = 'GET'
305
+
306
+ query = build_query(params)
307
+ url = "#{path}?#{query}"
308
+
309
+ make_request(
310
+ path: url,
311
+ method: method,
312
+ extra_headers: {
313
+ 'Content-Type' => 'application/x-www-form-urlencoded'
314
+ }
315
+ )
316
+ end
579
317
 
580
- make_request(
581
- path: url,
582
- method: method,
583
- extra_headers: {
584
- 'Content-Type' => 'application/x-www-form-urlencoded'
585
- }
586
- )
587
- end
318
+ FUNDFLOWBILL_FIELDS = [:bill_date].freeze # :nodoc:
319
+ #
320
+ # 申请资金账单
321
+ #
322
+ # Todo: 跟商户平台接口相同
323
+ #
324
+ # Document: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_5_7.shtml
325
+ #
326
+ # Example:
327
+ #
328
+ # ``` ruby
329
+ # WechatPay::Direct.fundflowbill(bill_date: '2021-04-30')
330
+ # ```
331
+ #
332
+ def self.fundflowbill(params)
333
+ path = '/v3/bill/fundflowbill'
334
+ method = 'GET'
335
+
336
+ query = build_query(params)
337
+ url = "#{path}?#{query}"
338
+
339
+ make_request(
340
+ path: url,
341
+ method: method,
342
+ extra_headers: {
343
+ 'Content-Type' => 'application/x-www-form-urlencoded'
344
+ }
345
+ )
346
+ end
588
347
 
348
+ class << self
589
349
  private
590
350
 
591
351
  def direct_transactions_method_by_suffix(suffix, params)