wechat-pay 1.0.1 → 1.0.8
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/.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 +10 -0
- data/Gemfile +15 -0
- data/README.md +92 -0
- data/Rakefile +19 -0
- data/lib/wechat-pay.rb +3 -1
- data/lib/wechat-pay/direct.rb +322 -562
- data/lib/wechat-pay/ecommerce.rb +61 -63
- data/lib/wechat-pay/ecommerce/applyment.rb +177 -178
- data/lib/wechat-pay/ecommerce/balance.rb +100 -101
- data/lib/wechat-pay/ecommerce/bill.rb +1 -0
- data/lib/wechat-pay/ecommerce/combine_order.rb +102 -233
- data/lib/wechat-pay/ecommerce/order.rb +102 -173
- data/lib/wechat-pay/ecommerce/profitsharing.rb +1 -0
- data/lib/wechat-pay/ecommerce/refund.rb +118 -119
- data/lib/wechat-pay/ecommerce/subsidies.rb +68 -69
- data/lib/wechat-pay/ecommerce/withdraw.rb +133 -134
- data/lib/wechat-pay/version.rb +1 -1
- data/wechat-pay.gemspec +27 -0
- metadata +40 -18
- data/lib/set_base_envrionment.rb +0 -8
@@ -1,186 +1,115 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module WechatPay
|
4
|
+
# 订单相关
|
4
5
|
module Ecommerce
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
# 小程序下单
|
37
|
-
#
|
38
|
-
# Document: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter7_2_3.shtml
|
39
|
-
#
|
40
|
-
# Example:
|
41
|
-
#
|
42
|
-
# ```
|
43
|
-
# params = {
|
44
|
-
# description: 'pay',
|
45
|
-
# out_trade_no: 'Order Number',
|
46
|
-
# payer: {
|
47
|
-
# sp_openid: 'wechat open id'
|
48
|
-
# },
|
49
|
-
# amount: {
|
50
|
-
# total: 10
|
51
|
-
# },
|
52
|
-
# sub_mchid: 'Your sub mchid',
|
53
|
-
# notify_url: 'the url'
|
54
|
-
# }
|
55
|
-
#
|
56
|
-
# WechatPay::Ecommerce.invoke_transactions_in_miniprogram(params)
|
57
|
-
# ```
|
58
|
-
def invoke_transactions_in_miniprogram(params)
|
59
|
-
transactions_method_by_suffix('jsapi', params)
|
60
|
-
end
|
61
|
-
|
62
|
-
INVOKE_TRANSACTIONS_IN_APP_FIELDS = %i[sub_mchid description out_trade_no notify_url amount].freeze # :nodoc:
|
63
|
-
#
|
64
|
-
# App下单
|
65
|
-
#
|
66
|
-
# https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter7_2_1.shtml
|
67
|
-
#
|
68
|
-
# Example:
|
69
|
-
#
|
70
|
-
# ```
|
71
|
-
# params = {
|
72
|
-
# description: 'pay',
|
73
|
-
# out_trade_no: 'Order Number',
|
74
|
-
# payer: {
|
75
|
-
# sp_openid: 'wechat open id'
|
76
|
-
# },
|
77
|
-
# amount: {
|
78
|
-
# total: 10
|
79
|
-
# },
|
80
|
-
# sub_mchid: 'Your sub mchid',
|
81
|
-
# notify_url: 'the url'
|
82
|
-
# }
|
83
|
-
#
|
84
|
-
# WechatPay::Ecommerce.invoke_transactions_in_miniprogram(params)
|
85
|
-
# ```
|
86
|
-
def invoke_transactions_in_app(params)
|
87
|
-
transactions_method_by_suffix('app', params)
|
88
|
-
end
|
89
|
-
|
90
|
-
INVOKE_TRANSACTIONS_IN_H5_FIELDS = %i[sub_mchid description out_trade_no notify_url amount].freeze # :nodoc:
|
91
|
-
#
|
92
|
-
# h5下单
|
93
|
-
#
|
94
|
-
# Document: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter7_2_4.shtml
|
95
|
-
#
|
96
|
-
# Example:
|
97
|
-
#
|
98
|
-
# ``` ruby
|
99
|
-
# params = {
|
100
|
-
# description: 'pay',
|
101
|
-
# out_trade_no: 'Order Number',
|
102
|
-
# payer: {
|
103
|
-
# sp_openid: 'wechat open id'
|
104
|
-
# },
|
105
|
-
# amount: {
|
106
|
-
# total: 10
|
107
|
-
# },
|
108
|
-
# sub_mchid: 'Your sub mchid',
|
109
|
-
# notify_url: 'the url'
|
110
|
-
# }
|
111
|
-
#
|
112
|
-
# WechatPay::Ecommerce.invoke_transactions_in_h5(params)
|
113
|
-
# ```
|
114
|
-
def invoke_transactions_in_h5(params)
|
115
|
-
transactions_method_by_suffix('h5', params)
|
116
|
-
end
|
117
|
-
|
118
|
-
QUERY_ORDER_FIELDS = %i[sub_mchid out_trade_no transaction_id].freeze # :nodoc:
|
119
|
-
#
|
120
|
-
# 订单查询
|
121
|
-
#
|
122
|
-
# Document: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter7_2_5.shtml
|
123
|
-
#
|
124
|
-
# ``` ruby
|
125
|
-
# WechatPay::Ecommerce.query_order(sub_mchid: '16000008', transaction_id: '4323400972202104305133344444') # by transaction_id
|
126
|
-
# WechatPay::Ecommerce.query_order(sub_mchid: '16000008', out_trade_no: 'N202104302474') # by out_trade_no
|
127
|
-
# ```
|
128
|
-
#
|
129
|
-
def query_order(params)
|
130
|
-
if params[:transaction_id]
|
131
|
-
params.delete(:out_trade_no)
|
132
|
-
transaction_id = params.delete(:transaction_id)
|
133
|
-
path = "/v3/pay/partner/transactions/id/#{transaction_id}"
|
134
|
-
else
|
135
|
-
params.delete(:transaction_id)
|
136
|
-
out_trade_no = params.delete(:out_trade_no)
|
137
|
-
path = "/v3/pay/partner/transactions/out-trade-no/#{out_trade_no}"
|
138
|
-
end
|
139
|
-
|
140
|
-
params = params.merge({
|
141
|
-
sp_mchid: WechatPay.mch_id
|
142
|
-
})
|
143
|
-
|
144
|
-
method = 'GET'
|
145
|
-
query = build_query(params)
|
146
|
-
url = "#{path}?#{query}"
|
147
|
-
|
148
|
-
make_request(
|
149
|
-
method: method,
|
150
|
-
path: url,
|
151
|
-
extra_headers: {
|
152
|
-
'Content-Type' => 'application/x-www-form-urlencoded'
|
153
|
-
}
|
154
|
-
)
|
6
|
+
# @private
|
7
|
+
# @!macro [attach] define_transaction_method
|
8
|
+
# $1下单
|
9
|
+
#
|
10
|
+
# Document: $3
|
11
|
+
#
|
12
|
+
# Example:
|
13
|
+
#
|
14
|
+
# ```
|
15
|
+
# params = {
|
16
|
+
# description: 'pay',
|
17
|
+
# out_trade_no: 'Order Number',
|
18
|
+
# payer: {
|
19
|
+
# sp_openid: 'wechat open id'
|
20
|
+
# },
|
21
|
+
# amount: {
|
22
|
+
# total: 10
|
23
|
+
# },
|
24
|
+
# sub_mchid: 'Your sub mchid',
|
25
|
+
# notify_url: 'the url'
|
26
|
+
# }
|
27
|
+
#
|
28
|
+
# WechatPay::Ecommerce.invoke_transactions_in_$1(params)
|
29
|
+
# ```
|
30
|
+
# @!method invoke_transactions_in_$1
|
31
|
+
# @!scope class
|
32
|
+
def self.define_transaction_method(key, value, _document)
|
33
|
+
const_set("INVOKE_TRANSACTIONS_IN_#{key.upcase}_FIELDS",
|
34
|
+
%i[sub_mchid description out_trade_no notify_url amount].freeze)
|
35
|
+
define_singleton_method("invoke_transactions_in_#{key}") do |params|
|
36
|
+
transactions_method_by_suffix(value, params)
|
155
37
|
end
|
38
|
+
end
|
156
39
|
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
40
|
+
define_transaction_method('native', 'native', 'document missing')
|
41
|
+
define_transaction_method('js', 'jsapi', 'https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter7_2_2.shtml')
|
42
|
+
define_transaction_method('app', 'app', 'https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter7_2_1.shtml')
|
43
|
+
define_transaction_method('h5', 'h5', 'https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter7_2_4.shtml')
|
44
|
+
define_transaction_method('miniprogram', 'jsapi', 'https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter7_2_3.shtml')
|
45
|
+
|
46
|
+
QUERY_ORDER_FIELDS = %i[sub_mchid out_trade_no transaction_id].freeze # :nodoc:
|
47
|
+
#
|
48
|
+
# 订单查询
|
49
|
+
#
|
50
|
+
# Document: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter7_2_5.shtml
|
51
|
+
#
|
52
|
+
# ``` ruby
|
53
|
+
# WechatPay::Ecommerce.query_order(sub_mchid: '16000008', transaction_id: '4323400972202104305133344444') # by transaction_id
|
54
|
+
# WechatPay::Ecommerce.query_order(sub_mchid: '16000008', out_trade_no: 'N202104302474') # by out_trade_no
|
55
|
+
# ```
|
56
|
+
#
|
57
|
+
def self.query_order(params)
|
58
|
+
if params[:transaction_id]
|
59
|
+
params.delete(:out_trade_no)
|
60
|
+
transaction_id = params.delete(:transaction_id)
|
61
|
+
path = "/v3/pay/partner/transactions/id/#{transaction_id}"
|
62
|
+
else
|
63
|
+
params.delete(:transaction_id)
|
168
64
|
out_trade_no = params.delete(:out_trade_no)
|
169
|
-
|
170
|
-
|
171
|
-
sp_mchid: WechatPay.mch_id
|
172
|
-
})
|
65
|
+
path = "/v3/pay/partner/transactions/out-trade-no/#{out_trade_no}"
|
66
|
+
end
|
173
67
|
|
174
|
-
|
68
|
+
params = params.merge({
|
69
|
+
sp_mchid: WechatPay.mch_id
|
70
|
+
})
|
71
|
+
|
72
|
+
method = 'GET'
|
73
|
+
query = build_query(params)
|
74
|
+
url = "#{path}?#{query}"
|
75
|
+
|
76
|
+
make_request(
|
77
|
+
method: method,
|
78
|
+
path: url,
|
79
|
+
extra_headers: {
|
80
|
+
'Content-Type' => 'application/x-www-form-urlencoded'
|
81
|
+
}
|
82
|
+
)
|
83
|
+
end
|
175
84
|
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
85
|
+
CLOSE_ORDER_FIELDS = %i[sub_mchid out_trade_no].freeze # :nodoc:
|
86
|
+
#
|
87
|
+
# 关闭订单
|
88
|
+
#
|
89
|
+
# Document: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter7_2_6.shtml
|
90
|
+
#
|
91
|
+
# ``` ruby
|
92
|
+
# WechatPay::Ecommerce.close_order(sub_mchid: '16000008', out_trade_no: 'N3344445')
|
93
|
+
# ```
|
94
|
+
#
|
95
|
+
def self.close_order(params)
|
96
|
+
out_trade_no = params.delete(:out_trade_no)
|
97
|
+
url = "/v3/pay/partner/transactions/out-trade-no/#{out_trade_no}/close"
|
98
|
+
params = params.merge({
|
99
|
+
sp_mchid: WechatPay.mch_id
|
100
|
+
})
|
101
|
+
|
102
|
+
method = 'POST'
|
103
|
+
|
104
|
+
make_request(
|
105
|
+
method: method,
|
106
|
+
path: url,
|
107
|
+
for_sign: params.to_json,
|
108
|
+
payload: params.to_json
|
109
|
+
)
|
110
|
+
end
|
183
111
|
|
112
|
+
class << self
|
184
113
|
private
|
185
114
|
|
186
115
|
def transactions_method_by_suffix(suffix, params)
|
@@ -1,136 +1,135 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module WechatPay
|
4
|
+
# 退款相关
|
4
5
|
module Ecommerce
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
}
|
6
|
+
INVOKE_REFUND_FIELDS = %i[sub_mchid out_trade_no total refund out_refund_no].freeze # :nodoc:
|
7
|
+
#
|
8
|
+
# 退款申请
|
9
|
+
#
|
10
|
+
# Document: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter7_6_1.shtml
|
11
|
+
#
|
12
|
+
# Example:
|
13
|
+
#
|
14
|
+
# ``` ruby
|
15
|
+
# WechatPay::Ecommerce.invoke_refund(sub_mchid: '1600000', transaction_id: '4323400972202104305131070170', total: 1, refund: 1, description: '退款', out_refund_no: 'R10000') # by transaction_id
|
16
|
+
# WechatPay::Ecommerce.invoke_refund(sub_mchid: '1608977559', total: 1, refund: 1, description: '退款', out_trade_no: 'N202104302474', out_refund_no: 'R10000') # by out_trade_no
|
17
|
+
# ```
|
18
|
+
def self.invoke_refund(params)
|
19
|
+
url = '/v3/ecommerce/refunds/apply'
|
20
|
+
method = 'POST'
|
21
|
+
amount = {
|
22
|
+
refund: params.delete(:refund),
|
23
|
+
total: params.delete(:total),
|
24
|
+
currency: 'CNY'
|
25
|
+
}
|
26
26
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
27
|
+
params = params.merge({
|
28
|
+
amount: amount,
|
29
|
+
sp_appid: WechatPay.app_id
|
30
|
+
})
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
32
|
+
make_request(
|
33
|
+
path: url,
|
34
|
+
method: method,
|
35
|
+
for_sign: params.to_json,
|
36
|
+
payload: params.to_json
|
37
|
+
)
|
38
|
+
end
|
39
39
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
40
|
+
QUERY_REFUND_FIELDS = %i[sub_mchid refund_id out_refund_no].freeze # :nodoc:
|
41
|
+
#
|
42
|
+
# 退款查询
|
43
|
+
#
|
44
|
+
# Document: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter7_6_2.shtml
|
45
|
+
#
|
46
|
+
# Example:
|
47
|
+
#
|
48
|
+
# ``` ruby
|
49
|
+
# WechatPay::Ecommerce.query_refund(sub_mchid: '16000000', out_refund_no: 'N202104302474') # 注意这里的out_refund_no用的是商户订单号,微信文档有误
|
50
|
+
# WechatPay::Ecommerce.query_refund(sub_mchid: '16000000', refund_id: '420000103020210508005624628') # 注意这里的refund_id用的是微信交易单号transaction_id,微信文档有误
|
51
|
+
# ```
|
52
|
+
#
|
53
|
+
def self.query_refund(params)
|
54
|
+
if params[:refund_id]
|
55
|
+
params.delete(:out_refund_no)
|
56
|
+
refund_id = params.delete(:refund_id)
|
57
|
+
path = "/v3/pay/partner/transactions/id/#{refund_id}"
|
58
|
+
else
|
59
|
+
params.delete(:refund_id)
|
60
|
+
out_refund_no = params.delete(:out_refund_no)
|
61
|
+
path = "/v3/pay/partner/transactions/out-trade-no/#{out_refund_no}"
|
62
|
+
end
|
63
63
|
|
64
|
-
|
65
|
-
|
66
|
-
|
64
|
+
params = params.merge({
|
65
|
+
sp_mchid: WechatPay.mch_id
|
66
|
+
})
|
67
67
|
|
68
|
-
|
69
|
-
|
70
|
-
|
68
|
+
method = 'GET'
|
69
|
+
query = build_query(params)
|
70
|
+
url = "#{path}?#{query}"
|
71
71
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
72
|
+
make_request(
|
73
|
+
method: method,
|
74
|
+
path: url,
|
75
|
+
extra_headers: {
|
76
|
+
'Content-Type' => 'application/x-www-form-urlencoded'
|
77
|
+
}
|
78
|
+
)
|
79
|
+
end
|
80
80
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
81
|
+
RETURN_ADVANCE_REFUND_FIELDS = %i[refund_id sub_mchid].freeze # :nodoc:
|
82
|
+
#
|
83
|
+
# 垫付退款回补
|
84
|
+
#
|
85
|
+
# Document: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter7_6_4.shtml
|
86
|
+
#
|
87
|
+
# Example:
|
88
|
+
#
|
89
|
+
# ``` ruby
|
90
|
+
# WechatPay::Ecommerce.return_advance_refund(refund_id: '50300908092021043008398036516', sub_mchid: '160000')
|
91
|
+
# ```
|
92
|
+
#
|
93
|
+
def self.return_advance_refund(params)
|
94
|
+
refund_id = params.delete(:refund_id)
|
95
|
+
url = "/v3/ecommerce/refunds/#{refund_id}/return-advance"
|
96
|
+
method = 'POST'
|
97
97
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
98
|
+
make_request(
|
99
|
+
path: url,
|
100
|
+
method: method,
|
101
|
+
for_sign: params.to_json,
|
102
|
+
payload: params.to_json
|
103
|
+
)
|
104
|
+
end
|
105
105
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
106
|
+
QUERY_RETURN_ADVANCE_REFUND_FIELDS = %i[sub_mchid refund_id].freeze # :nodoc:
|
107
|
+
#
|
108
|
+
# 退款查询
|
109
|
+
#
|
110
|
+
# Document: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter7_6_2.shtml
|
111
|
+
#
|
112
|
+
# Example:
|
113
|
+
#
|
114
|
+
# ``` ruby
|
115
|
+
# WechatPay::Ecommerce.query_refund(sub_mchid: '16000000', out_refund_no: 'N202104302474') # 注意这里的out_refund_no用的是商户订单号,微信文档有误
|
116
|
+
# WechatPay::Ecommerce.query_refund(sub_mchid: '16000000', refund_id: '420000103020210508005624628') # 注意这里的refund_id用的是微信交易单号transaction_id,微信文档有误
|
117
|
+
# ```
|
118
|
+
#
|
119
|
+
def self.query_return_advance_refund(params)
|
120
|
+
refund_id = params.delete(:refund_id)
|
121
|
+
path = "/v3/ecommerce/refunds/#{refund_id}/return-advance"
|
122
|
+
method = 'GET'
|
123
|
+
query = build_query(params)
|
124
|
+
url = "#{path}?#{query}"
|
125
125
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
end
|
126
|
+
make_request(
|
127
|
+
method: method,
|
128
|
+
path: url,
|
129
|
+
extra_headers: {
|
130
|
+
'Content-Type' => 'application/x-www-form-urlencoded'
|
131
|
+
}
|
132
|
+
)
|
134
133
|
end
|
135
134
|
end
|
136
135
|
end
|