alipay-easysdk-ruby 1.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.
Files changed (30) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +213 -0
  3. data/Rakefile +4 -0
  4. data/examples/demo.rb +134 -0
  5. data/examples/demo_with_post.rb +239 -0
  6. data/lib/alipay/easysdk/kernel/alipay_constants.rb +46 -0
  7. data/lib/alipay/easysdk/kernel/config.rb +38 -0
  8. data/lib/alipay/easysdk/kernel/easy_sdk_kernel.rb +328 -0
  9. data/lib/alipay/easysdk/kernel/factory.rb +95 -0
  10. data/lib/alipay/easysdk/kernel/util/json_util.rb +30 -0
  11. data/lib/alipay/easysdk/kernel/util/response_checker.rb +28 -0
  12. data/lib/alipay/easysdk/kernel/util/sign_content_extractor.rb +50 -0
  13. data/lib/alipay/easysdk/kernel/util/signer.rb +125 -0
  14. data/lib/alipay/easysdk/payment/common/client.rb +190 -0
  15. data/lib/alipay/easysdk/payment/common/models/alipay_data_dataservice_bill_downloadurl_query_response.rb +13 -0
  16. data/lib/alipay/easysdk/payment/common/models/alipay_trade_cancel_response.rb +13 -0
  17. data/lib/alipay/easysdk/payment/common/models/alipay_trade_close_response.rb +13 -0
  18. data/lib/alipay/easysdk/payment/common/models/alipay_trade_create_response.rb +13 -0
  19. data/lib/alipay/easysdk/payment/common/models/alipay_trade_fastpay_refund_query_response.rb +13 -0
  20. data/lib/alipay/easysdk/payment/common/models/alipay_trade_query_response.rb +13 -0
  21. data/lib/alipay/easysdk/payment/common/models/alipay_trade_refund_response.rb +13 -0
  22. data/lib/alipay/easysdk/payment/common/models/base_response.rb +42 -0
  23. data/lib/alipay/easysdk/payment/page/client.rb +80 -0
  24. data/lib/alipay/easysdk/payment/page/models/alipay_trade_page_pay_response.rb +35 -0
  25. data/lib/alipay/easysdk/payment/wap/client.rb +88 -0
  26. data/lib/alipay/easysdk/payment/wap/models/alipay_trade_wap_pay_response.rb +35 -0
  27. data/lib/alipay/easysdk/version.rb +5 -0
  28. data/lib/alipay/easysdk.rb +33 -0
  29. data/sig/alipay/easysdk/ruby.rbs +8 -0
  30. metadata +130 -0
@@ -0,0 +1,190 @@
1
+ require 'net/http'
2
+ require 'uri'
3
+ require 'cgi'
4
+
5
+ require_relative '../../kernel/easy_sdk_kernel'
6
+ require_relative 'models/alipay_trade_create_response'
7
+ require_relative 'models/alipay_trade_query_response'
8
+ require_relative 'models/alipay_trade_refund_response'
9
+ require_relative 'models/alipay_trade_close_response'
10
+ require_relative 'models/alipay_trade_cancel_response'
11
+ require_relative 'models/alipay_trade_fastpay_refund_query_response'
12
+ require_relative 'models/alipay_data_dataservice_bill_downloadurl_query_response'
13
+
14
+ module Alipay
15
+ module EasySDK
16
+ module Payment
17
+ module Common
18
+ class Client
19
+ def initialize(kernel)
20
+ @kernel = kernel
21
+ end
22
+
23
+ def create(subject, out_trade_no, total_amount, buyer_id)
24
+ biz_params = {
25
+ 'subject' => subject,
26
+ 'out_trade_no' => out_trade_no,
27
+ 'total_amount' => total_amount,
28
+ 'buyer_id' => buyer_id
29
+ }
30
+ execute('alipay.trade.create', biz_params, {}, Models::AlipayTradeCreateResponse)
31
+ end
32
+
33
+ def query(out_trade_no)
34
+ biz_params = { 'out_trade_no' => out_trade_no }
35
+ execute('alipay.trade.query', biz_params, {}, Models::AlipayTradeQueryResponse)
36
+ end
37
+
38
+ def refund(out_trade_no, refund_amount)
39
+ biz_params = {
40
+ 'out_trade_no' => out_trade_no,
41
+ 'refund_amount' => refund_amount
42
+ }
43
+ execute('alipay.trade.refund', biz_params, {}, Models::AlipayTradeRefundResponse)
44
+ end
45
+
46
+ def close(out_trade_no)
47
+ biz_params = { 'out_trade_no' => out_trade_no }
48
+ execute('alipay.trade.close', biz_params, {}, Models::AlipayTradeCloseResponse)
49
+ end
50
+
51
+ def cancel(out_trade_no)
52
+ biz_params = { 'out_trade_no' => out_trade_no }
53
+ execute('alipay.trade.cancel', biz_params, {}, Models::AlipayTradeCancelResponse)
54
+ end
55
+
56
+ def query_refund(out_trade_no, out_request_no)
57
+ biz_params = {
58
+ 'out_trade_no' => out_trade_no,
59
+ 'out_request_no' => out_request_no
60
+ }
61
+ execute('alipay.trade.fastpay.refund.query', biz_params, {}, Models::AlipayTradeFastpayRefundQueryResponse)
62
+ end
63
+
64
+ def download_bill(bill_type, bill_date)
65
+ biz_params = {
66
+ 'bill_type' => bill_type,
67
+ 'bill_date' => bill_date
68
+ }
69
+ execute('alipay.data.dataservice.bill.downloadurl.query', biz_params, {}, Models::AlipayDataDataserviceBillDownloadurlQueryResponse)
70
+ end
71
+
72
+ def verify_notify(parameters)
73
+ if @kernel.is_cert_mode
74
+ @kernel.verify_params(parameters, @kernel.extract_alipay_public_key(@kernel.get_alipay_cert_sn('')))
75
+ else
76
+ @kernel.verify_params(parameters, @kernel.get_config('alipayPublicKey'))
77
+ end
78
+ end
79
+
80
+ def agent(app_auth_token)
81
+ @kernel.inject_text_param('app_auth_token', app_auth_token)
82
+ self
83
+ end
84
+
85
+ def auth(auth_token)
86
+ @kernel.inject_text_param('auth_token', auth_token)
87
+ self
88
+ end
89
+
90
+ def async_notify(url)
91
+ @kernel.inject_text_param('notify_url', url)
92
+ self
93
+ end
94
+
95
+ def route(test_url)
96
+ @kernel.inject_text_param('ws_service_url', test_url)
97
+ self
98
+ end
99
+
100
+ def optional(key, value)
101
+ @kernel.inject_biz_param(key, value)
102
+ self
103
+ end
104
+
105
+ def batch_optional(optional_args)
106
+ optional_args.each do |key, value|
107
+ @kernel.inject_biz_param(key, value)
108
+ end
109
+ self
110
+ end
111
+
112
+ private
113
+
114
+ def execute(api_method, biz_params, text_params, response_class)
115
+ system_params = base_system_params(api_method)
116
+
117
+ sign = @kernel.sign(system_params, biz_params, text_params, @kernel.get_config('merchantPrivateKey'))
118
+
119
+ text_query = (@kernel.text_params || {}).dup
120
+ query_params = { 'sign' => sign }.merge(system_params)
121
+ query_params.merge!(text_query) unless text_query.empty?
122
+
123
+ uri = build_gateway_uri(query_params)
124
+ request = Net::HTTP::Post.new(uri.request_uri)
125
+ request['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8'
126
+ request.body = @kernel.to_url_encoded_request_body(biz_params)
127
+
128
+ response = perform_http_request(uri, request)
129
+
130
+ resp_map = @kernel.read_as_json(response, api_method)
131
+
132
+ unless verify_response(resp_map)
133
+ raise '验签失败,请检查支付宝公钥设置是否正确。'
134
+ end
135
+
136
+ map = @kernel.to_resp_model(resp_map)
137
+ response_class.from_map(map)
138
+ ensure
139
+ clear_optional_params
140
+ end
141
+
142
+ def base_system_params(method)
143
+ {
144
+ 'method' => method,
145
+ 'app_id' => @kernel.get_config('appId'),
146
+ 'timestamp' => @kernel.get_timestamp,
147
+ 'format' => 'json',
148
+ 'version' => '1.0',
149
+ 'alipay_sdk' => @kernel.get_sdk_version,
150
+ 'charset' => 'UTF-8',
151
+ 'sign_type' => @kernel.get_config('signType'),
152
+ 'app_cert_sn' => @kernel.get_merchant_cert_sn,
153
+ 'alipay_root_cert_sn' => @kernel.get_alipay_root_cert_sn
154
+ }.compact
155
+ end
156
+
157
+ def build_gateway_uri(query_params)
158
+ host = @kernel.get_config('gatewayHost').to_s.sub(%r{/gateway\.do$}, '')
159
+ scheme = @kernel.get_config('protocol') || 'https'
160
+ uri = URI("#{scheme}://#{host}/gateway.do")
161
+ uri.query = URI.encode_www_form(query_params.sort.to_h)
162
+ uri
163
+ end
164
+
165
+ def perform_http_request(uri, request)
166
+ http = Net::HTTP.new(uri.host, uri.port)
167
+ http.use_ssl = uri.scheme == 'https'
168
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE if http.use_ssl?
169
+ http.open_timeout = 15
170
+ http.read_timeout = 15
171
+ http.request(request)
172
+ end
173
+
174
+ def verify_response(resp_map)
175
+ if @kernel.is_cert_mode
176
+ @kernel.verify(resp_map, @kernel.extract_alipay_public_key(@kernel.get_alipay_cert_sn(resp_map)))
177
+ else
178
+ @kernel.verify(resp_map, @kernel.get_config('alipayPublicKey'))
179
+ end
180
+ end
181
+
182
+ def clear_optional_params
183
+ @kernel.optional_text_params.clear if @kernel.optional_text_params
184
+ @kernel.optional_biz_params.clear if @kernel.optional_biz_params
185
+ end
186
+ end
187
+ end
188
+ end
189
+ end
190
+ end
@@ -0,0 +1,13 @@
1
+ require_relative 'base_response'
2
+
3
+ module Alipay
4
+ module EasySDK
5
+ module Payment
6
+ module Common
7
+ module Models
8
+ class AlipayDataDataserviceBillDownloadurlQueryResponse < BaseResponse; end
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ require_relative 'base_response'
2
+
3
+ module Alipay
4
+ module EasySDK
5
+ module Payment
6
+ module Common
7
+ module Models
8
+ class AlipayTradeCancelResponse < BaseResponse; end
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ require_relative 'base_response'
2
+
3
+ module Alipay
4
+ module EasySDK
5
+ module Payment
6
+ module Common
7
+ module Models
8
+ class AlipayTradeCloseResponse < BaseResponse; end
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ require_relative 'base_response'
2
+
3
+ module Alipay
4
+ module EasySDK
5
+ module Payment
6
+ module Common
7
+ module Models
8
+ class AlipayTradeCreateResponse < BaseResponse; end
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ require_relative 'base_response'
2
+
3
+ module Alipay
4
+ module EasySDK
5
+ module Payment
6
+ module Common
7
+ module Models
8
+ class AlipayTradeFastpayRefundQueryResponse < BaseResponse; end
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ require_relative 'base_response'
2
+
3
+ module Alipay
4
+ module EasySDK
5
+ module Payment
6
+ module Common
7
+ module Models
8
+ class AlipayTradeQueryResponse < BaseResponse; end
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ require_relative 'base_response'
2
+
3
+ module Alipay
4
+ module EasySDK
5
+ module Payment
6
+ module Common
7
+ module Models
8
+ class AlipayTradeRefundResponse < BaseResponse; end
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,42 @@
1
+ module Alipay
2
+ module EasySDK
3
+ module Payment
4
+ module Common
5
+ module Models
6
+ class BaseResponse
7
+ attr_accessor :body
8
+
9
+ def self.from_map(map = {})
10
+ new.tap do |instance|
11
+ map.each do |key, value|
12
+ method_name = key.to_s
13
+ method_name = method_name.gsub(/[^a-zA-Z0-9_]/, '_')
14
+ unless instance.respond_to?(method_name)
15
+ instance.singleton_class.class_eval do
16
+ attr_accessor method_name
17
+ end
18
+ end
19
+ instance.public_send("#{method_name}=", value)
20
+ end
21
+ end
22
+ end
23
+
24
+ def success?
25
+ respond_to?('code') ? public_send('code') == '10000' : false
26
+ end
27
+
28
+ def error_message
29
+ if respond_to?('sub_msg') && public_send('sub_msg')
30
+ public_send('sub_msg')
31
+ elsif respond_to?('msg')
32
+ public_send('msg')
33
+ else
34
+ nil
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,80 @@
1
+ require_relative '../../kernel/easy_sdk_kernel'
2
+ require_relative 'models/alipay_trade_page_pay_response'
3
+
4
+ module Alipay
5
+ module EasySDK
6
+ module Payment
7
+ module Page
8
+ class Client
9
+ def initialize(kernel)
10
+ @kernel = kernel
11
+ end
12
+
13
+ def pay(subject, out_trade_no, total_amount, return_url)
14
+ system_params = {
15
+ 'method' => 'alipay.trade.page.pay',
16
+ 'app_id' => @kernel.get_config('appId'),
17
+ 'timestamp' => @kernel.get_timestamp,
18
+ 'format' => 'json',
19
+ 'version' => '1.0',
20
+ 'alipay_sdk' => @kernel.get_sdk_version,
21
+ 'charset' => 'UTF-8',
22
+ 'sign_type' => @kernel.get_config('signType'),
23
+ 'app_cert_sn' => @kernel.get_merchant_cert_sn,
24
+ 'alipay_root_cert_sn' => @kernel.get_alipay_root_cert_sn
25
+ }
26
+ biz_params = {
27
+ 'subject' => subject,
28
+ 'out_trade_no' => out_trade_no,
29
+ 'total_amount' => total_amount,
30
+ 'product_code' => 'FAST_INSTANT_TRADE_PAY'
31
+ }
32
+ text_params = {
33
+ 'return_url' => return_url
34
+ }
35
+
36
+ sign = @kernel.sign(system_params, biz_params, text_params, @kernel.get_config('merchantPrivateKey'))
37
+
38
+ response = {
39
+ 'body' => @kernel.generate_page('POST', system_params, biz_params, text_params, sign)
40
+ }
41
+
42
+ Models::AlipayTradePagePayResponse.from_map(response)
43
+ end
44
+
45
+ def agent(app_auth_token)
46
+ @kernel.inject_text_param('app_auth_token', app_auth_token)
47
+ self
48
+ end
49
+
50
+ def auth(auth_token)
51
+ @kernel.inject_text_param('auth_token', auth_token)
52
+ self
53
+ end
54
+
55
+ def async_notify(url)
56
+ @kernel.inject_text_param('notify_url', url)
57
+ self
58
+ end
59
+
60
+ def route(test_url)
61
+ @kernel.inject_text_param('ws_service_url', test_url)
62
+ self
63
+ end
64
+
65
+ def optional(key, value)
66
+ @kernel.inject_biz_param(key, value)
67
+ self
68
+ end
69
+
70
+ def batch_optional(optional_args)
71
+ optional_args.each do |key, value|
72
+ @kernel.inject_biz_param(key, value)
73
+ end
74
+ self
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,35 @@
1
+ module Alipay
2
+ module EasySDK
3
+ module Payment
4
+ module Page
5
+ module Models
6
+ class AlipayTradePagePayResponse
7
+ attr_accessor :body
8
+
9
+ def self.from_map(response)
10
+ new.tap do |instance|
11
+ instance.body = response['body']
12
+ end
13
+ end
14
+
15
+ def success?
16
+ !body.nil? && !body.to_s.empty?
17
+ end
18
+
19
+ def form
20
+ body
21
+ end
22
+
23
+ def error_message
24
+ nil
25
+ end
26
+
27
+ def to_s
28
+ body || ''
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,88 @@
1
+ require_relative '../../kernel/easy_sdk_kernel'
2
+ require_relative 'models/alipay_trade_wap_pay_response'
3
+
4
+ module Alipay
5
+ module EasySDK
6
+ module Payment
7
+ module Wap
8
+ class Client
9
+ def initialize(kernel)
10
+ @kernel = kernel
11
+ end
12
+
13
+ # 完全复制PHP版本的pay方法
14
+ def pay(subject, out_trade_no, total_amount, quit_url, return_url)
15
+ system_params = {
16
+ "method" => "alipay.trade.wap.pay",
17
+ "app_id" => @kernel.get_config("appId"),
18
+ "timestamp" => @kernel.get_timestamp(),
19
+ "format" => "json",
20
+ "version" => "1.0",
21
+ "alipay_sdk" => @kernel.get_sdk_version(),
22
+ "charset" => "UTF-8",
23
+ "sign_type" => @kernel.get_config("signType"),
24
+ "app_cert_sn" => @kernel.get_merchant_cert_sn(),
25
+ "alipay_root_cert_sn" => @kernel.get_alipay_root_cert_sn()
26
+ }
27
+ biz_params = {
28
+ "subject" => subject,
29
+ "out_trade_no" => out_trade_no,
30
+ "total_amount" => total_amount,
31
+ "quit_url" => quit_url,
32
+ "product_code" => "QUICK_WAP_WAY"
33
+ }
34
+ text_params = {
35
+ "return_url" => return_url
36
+ }
37
+
38
+ # 完全按照PHP版本的逻辑:先设置所有参数,再生成签名,最后生成页面
39
+ sign = @kernel.sign(system_params, biz_params, text_params, @kernel.get_config("merchantPrivateKey"))
40
+
41
+ response = {
42
+ "body" => @kernel.generate_page("POST", system_params, biz_params, text_params, sign)
43
+ }
44
+ return Alipay::EasySDK::Payment::Wap::Models::AlipayTradeWapPayResponse.from_map(response)
45
+ end
46
+
47
+ # ISV代商户代用,指定appAuthToken
48
+ def agent(app_auth_token)
49
+ @kernel.inject_text_param("app_auth_token", app_auth_token)
50
+ return self
51
+ end
52
+
53
+ # 用户授权调用,指定authToken
54
+ def auth(auth_token)
55
+ @kernel.inject_text_param("auth_token", auth_token)
56
+ return self
57
+ end
58
+
59
+ # 设置异步通知回调地址
60
+ def async_notify(url)
61
+ @kernel.inject_text_param("notify_url", url)
62
+ return self
63
+ end
64
+
65
+ # 将本次调用强制路由到后端系统的测试地址上
66
+ def route(test_url)
67
+ @kernel.inject_text_param("ws_service_url", test_url)
68
+ return self
69
+ end
70
+
71
+ # 设置API入参中没有的其他可选业务请求参数
72
+ def optional(key, value)
73
+ @kernel.inject_biz_param(key, value)
74
+ return self
75
+ end
76
+
77
+ # 批量设置可选参数
78
+ def batch_optional(optional_args)
79
+ optional_args.each do |key, value|
80
+ @kernel.inject_biz_param(key, value)
81
+ end
82
+ return self
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,35 @@
1
+ module Alipay
2
+ module EasySDK
3
+ module Payment
4
+ module Wap
5
+ module Models
6
+ class AlipayTradeWapPayResponse
7
+ attr_accessor :body, :code, :sub_code
8
+
9
+ def self.from_map(response)
10
+ new.tap do |instance|
11
+ instance.body = response['body']
12
+ end
13
+ end
14
+
15
+ def success?
16
+ !body.nil? && !body.to_s.empty?
17
+ end
18
+
19
+ def form
20
+ body
21
+ end
22
+
23
+ def error_message
24
+ nil
25
+ end
26
+
27
+ def to_s
28
+ body || ''
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,5 @@
1
+ module Alipay
2
+ module EasySDK
3
+ VERSION = '1.0.0'
4
+ end
5
+ end
@@ -0,0 +1,33 @@
1
+ require_relative 'easysdk/version'
2
+ require_relative 'easysdk/kernel/factory'
3
+ require_relative 'easysdk/kernel/util/response_checker'
4
+
5
+ module Alipay
6
+ module EasySDK
7
+ class Error < StandardError; end
8
+
9
+ class << self
10
+ def config(options = {})
11
+ Kernel::Factory.config(options)
12
+ end
13
+
14
+ alias configure config
15
+
16
+ def payment
17
+ Kernel::Factory.payment
18
+ end
19
+
20
+ def wap
21
+ payment.wap
22
+ end
23
+
24
+ def page
25
+ payment.page
26
+ end
27
+
28
+ def common
29
+ payment.common
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,8 @@
1
+ module Alipay
2
+ module Easysdk
3
+ module Ruby
4
+ VERSION: String
5
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
6
+ end
7
+ end
8
+ end