wechat-ipay 2.0.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 +7 -0
- data/.github/workflows/code_quality.yml +35 -0
- data/.gitignore +6 -0
- data/.rspec +2 -0
- data/.rubocop.yml +21 -0
- data/.yardopts +3 -0
- data/CHANGELOG.md +15 -0
- data/Gemfile +15 -0
- data/README.md +92 -0
- data/Rakefile +19 -0
- data/lib/wechat-pay/direct.rb +371 -0
- data/lib/wechat-pay/ecommerce/applyment.rb +195 -0
- data/lib/wechat-pay/ecommerce/balance.rb +114 -0
- data/lib/wechat-pay/ecommerce/bill.rb +91 -0
- data/lib/wechat-pay/ecommerce/combine_order.rb +133 -0
- data/lib/wechat-pay/ecommerce/order.rb +135 -0
- data/lib/wechat-pay/ecommerce/profitsharing.rb +230 -0
- data/lib/wechat-pay/ecommerce/refund.rb +135 -0
- data/lib/wechat-pay/ecommerce/subsidies.rb +84 -0
- data/lib/wechat-pay/ecommerce/withdraw.rb +154 -0
- data/lib/wechat-pay/ecommerce.rb +93 -0
- data/lib/wechat-pay/helper.rb +33 -0
- data/lib/wechat-pay/sign.rb +245 -0
- data/lib/wechat-pay/version.rb +5 -0
- data/lib/wechat-pay.rb +44 -0
- data/wechat-ipay.gemspec +27 -0
- metadata +135 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 417cacf5d330314a773fe49fb898dc94194da17ae4486588e09813e1fdfcf547
|
4
|
+
data.tar.gz: '09fd147836791a7842536f0d598bcbb590fcf1d9fefdb9b94e55580e600086cc'
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9abaf1188c2a61716948e4139194aa62b3a79cba3a9eb75b05e70a15d72a0b25b631b93a7042adb89eb4ed2b479dd9cdd5f98c42b538b86a6a95b75882e09729
|
7
|
+
data.tar.gz: 5f36f28a6c57af14678d438bd13d05d9eb580aa1b594ba72f469545a885368a378e069a83c90e99bfe87edb4e1be3d8c90c2dbdee165c8a53fcc2790a18cf554
|
@@ -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
data/.rspec
ADDED
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
data/CHANGELOG.md
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# Next Release
|
2
|
+
|
3
|
+
## 1.1.0 (07/26/2021)
|
4
|
+
|
5
|
+
* Fix `Accept-Encoding` issue in wechat.
|
6
|
+
|
7
|
+
|
8
|
+
## 1.0.8 (05/26/2021)
|
9
|
+
|
10
|
+
* Add api `invoke_transactions_in_native` to `WechatPay::Ecommerce`
|
11
|
+
|
12
|
+
## 1.0.7 (05/16/2021)
|
13
|
+
|
14
|
+
* Change `WechatPay::Ecommerce.get_certificates` to `WechatPay::Ecommerce.certificates`
|
15
|
+
* 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
|
@@ -0,0 +1,371 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'wechat-pay/helper'
|
5
|
+
|
6
|
+
module WechatPay
|
7
|
+
# # 直连商户相关接口封装(常用的已有,待完善)
|
8
|
+
# 文档: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_1.shtml
|
9
|
+
module Direct
|
10
|
+
include WechatPayHelper
|
11
|
+
|
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)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
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)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
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
|
126
|
+
|
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
|
158
|
+
|
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)
|
179
|
+
out_trade_no = params.delete(:out_trade_no)
|
180
|
+
path = "/v3/pay/transactions/out-trade-no/#{out_trade_no}"
|
181
|
+
end
|
182
|
+
|
183
|
+
params = params.merge({
|
184
|
+
mchid: WechatPay.mch_id
|
185
|
+
})
|
186
|
+
|
187
|
+
method = 'GET'
|
188
|
+
query = build_query(params)
|
189
|
+
url = "#{path}?#{query}"
|
190
|
+
|
191
|
+
make_request(
|
192
|
+
method: method,
|
193
|
+
path: url,
|
194
|
+
extra_headers: {
|
195
|
+
'Content-Type' => 'application/x-www-form-urlencoded'
|
196
|
+
}
|
197
|
+
)
|
198
|
+
end
|
199
|
+
|
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
|
228
|
+
|
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
|
261
|
+
|
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
|
288
|
+
|
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
|
317
|
+
|
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
|
347
|
+
|
348
|
+
class << self
|
349
|
+
private
|
350
|
+
|
351
|
+
def direct_transactions_method_by_suffix(suffix, params)
|
352
|
+
url = "/v3/pay/transactions/#{suffix}"
|
353
|
+
method = 'POST'
|
354
|
+
|
355
|
+
params = {
|
356
|
+
mchid: WechatPay.mch_id,
|
357
|
+
appid: WechatPay.app_id
|
358
|
+
}.merge(params)
|
359
|
+
|
360
|
+
payload_json = params.to_json
|
361
|
+
|
362
|
+
make_request(
|
363
|
+
method: method,
|
364
|
+
path: url,
|
365
|
+
for_sign: payload_json,
|
366
|
+
payload: payload_json
|
367
|
+
)
|
368
|
+
end
|
369
|
+
end
|
370
|
+
end
|
371
|
+
end
|