alipay-easysdk-ruby 1.0.1 → 1.0.3
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/CHANGELOG.md +20 -0
- data/lib/alipay/easysdk/kernel/alipay_constants.rb +20 -22
- data/lib/alipay/easysdk/kernel/cert_environment.rb +35 -0
- data/lib/alipay/easysdk/kernel/config.rb +96 -25
- data/lib/alipay/easysdk/kernel/easy_sdk_kernel.rb +104 -71
- data/lib/alipay/easysdk/kernel/factory.rb +33 -11
- data/lib/alipay/easysdk/kernel/util/aes.rb +75 -0
- data/lib/alipay/easysdk/kernel/util/ant_certification_util.rb +63 -0
- data/lib/alipay/easysdk/kernel/util/json_util.rb +50 -8
- data/lib/alipay/easysdk/kernel/util/page_util.rb +34 -0
- data/lib/alipay/easysdk/kernel/util/response_checker.rb +6 -1
- data/lib/alipay/easysdk/kernel/util/signer.rb +15 -5
- data/lib/alipay/easysdk/payment/app/client.rb +75 -0
- data/lib/alipay/easysdk/payment/app/models/alipay_trade_app_pay_response.rb +19 -0
- data/lib/alipay/easysdk/payment/common/client.rb +59 -7
- data/lib/alipay/easysdk/payment/common/models/base_response.rb +0 -14
- data/lib/alipay/easysdk/payment/page/client.rb +1 -1
- data/lib/alipay/easysdk/payment/page/models/alipay_trade_page_pay_response.rb +1 -17
- data/lib/alipay/easysdk/payment/wap/client.rb +1 -1
- data/lib/alipay/easysdk/payment/wap/models/alipay_trade_wap_pay_response.rb +1 -17
- data/lib/alipay/easysdk/version.rb +1 -1
- data/lib/alipay/easysdk.rb +4 -0
- metadata +9 -4
- data/examples/demo.rb +0 -133
- data/examples/demo_with_post.rb +0 -239
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
require 'openssl'
|
|
2
|
+
require 'base64'
|
|
3
|
+
|
|
4
|
+
module Alipay
|
|
5
|
+
module EasySDK
|
|
6
|
+
module Kernel
|
|
7
|
+
module Util
|
|
8
|
+
class AES
|
|
9
|
+
def aes_encrypt(plain_text, key)
|
|
10
|
+
raise encryption_error(plain_text, key) if key.to_s.empty?
|
|
11
|
+
|
|
12
|
+
secret_key = Base64.decode64(key)
|
|
13
|
+
padded = add_pkcs7_padding(plain_text.to_s)
|
|
14
|
+
|
|
15
|
+
cipher = OpenSSL::Cipher.new('AES-128-CBC')
|
|
16
|
+
cipher.encrypt
|
|
17
|
+
cipher.key = secret_key
|
|
18
|
+
cipher.iv = "\0" * 16
|
|
19
|
+
cipher.padding = 0
|
|
20
|
+
|
|
21
|
+
encrypted = cipher.update(padded) + cipher.final
|
|
22
|
+
Base64.strict_encode64(encrypted)
|
|
23
|
+
rescue StandardError => e
|
|
24
|
+
raise StandardError, "AES加密失败,plainText=#{plain_text},keySize=#{key.to_s.length}。#{e.message}"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def aes_decrypt(cipher_text, key)
|
|
28
|
+
raise decryption_error(cipher_text, key) if key.to_s.empty?
|
|
29
|
+
|
|
30
|
+
secret_key = Base64.decode64(key)
|
|
31
|
+
encrypted = Base64.decode64(cipher_text)
|
|
32
|
+
|
|
33
|
+
decipher = OpenSSL::Cipher.new('AES-128-CBC')
|
|
34
|
+
decipher.decrypt
|
|
35
|
+
decipher.key = secret_key
|
|
36
|
+
decipher.iv = "\0" * 16
|
|
37
|
+
decipher.padding = 0
|
|
38
|
+
|
|
39
|
+
decrypted = decipher.update(encrypted) + decipher.final
|
|
40
|
+
strip_pkcs7_padding(decrypted)
|
|
41
|
+
rescue StandardError => e
|
|
42
|
+
raise StandardError, "AES解密失败,cipherText=#{cipher_text},keySize=#{key.to_s.length}。#{e.message}"
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
def add_pkcs7_padding(source)
|
|
48
|
+
str = source.to_s.strip
|
|
49
|
+
block = 16
|
|
50
|
+
pad = block - (str.bytesize % block)
|
|
51
|
+
pad = block if pad.zero?
|
|
52
|
+
str + (pad.chr * pad)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def strip_pkcs7_padding(source)
|
|
56
|
+
return source if source.nil? || source.empty?
|
|
57
|
+
|
|
58
|
+
char = source[-1]
|
|
59
|
+
num = char.ord
|
|
60
|
+
return source if num == 62
|
|
61
|
+
source[0...-num]
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def encryption_error(plain_text, key)
|
|
65
|
+
StandardError.new("AES加密失败,plainText=#{plain_text},AES密钥为空。")
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def decryption_error(cipher_text, key)
|
|
69
|
+
StandardError.new("AES解密失败,cipherText=#{cipher_text},AES密钥为空。")
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
require 'openssl'
|
|
2
|
+
require 'digest/md5'
|
|
3
|
+
|
|
4
|
+
module Alipay
|
|
5
|
+
module EasySDK
|
|
6
|
+
module Kernel
|
|
7
|
+
module Util
|
|
8
|
+
class AntCertificationUtil
|
|
9
|
+
SUPPORTED_SIGNATURES = %w[sha1WithRSAEncryption sha256WithRSAEncryption].freeze
|
|
10
|
+
|
|
11
|
+
def cert_sn(cert_path)
|
|
12
|
+
cert = load_certificate(cert_path)
|
|
13
|
+
signature_digest(cert.issuer.to_a, cert.serial)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def public_key(cert_path)
|
|
17
|
+
cert = load_certificate(cert_path)
|
|
18
|
+
key_pem = cert.public_key.to_pem
|
|
19
|
+
key_pem.gsub(/-----BEGIN PUBLIC KEY-----/, '')
|
|
20
|
+
.gsub(/-----END PUBLIC KEY-----/, '')
|
|
21
|
+
.gsub(/\s+/, '')
|
|
22
|
+
.strip
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def root_cert_sn(cert_path)
|
|
26
|
+
certs = load_cert_chain(cert_path)
|
|
27
|
+
sns = certs.each_with_object([]) do |cert, acc|
|
|
28
|
+
next unless SUPPORTED_SIGNATURES.include?(cert.signature_algorithm)
|
|
29
|
+
|
|
30
|
+
acc << signature_digest(cert.issuer.to_a, cert.serial)
|
|
31
|
+
end
|
|
32
|
+
sns.join('_')
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
def load_certificate(path)
|
|
38
|
+
raise ArgumentError, '证书路径不能为空' if path.nil? || path.to_s.strip.empty?
|
|
39
|
+
|
|
40
|
+
OpenSSL::X509::Certificate.new(File.read(path))
|
|
41
|
+
rescue Errno::ENOENT => e
|
|
42
|
+
raise RuntimeError, "无法读取证书文件: #{path} - #{e.message}"
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def load_cert_chain(path)
|
|
46
|
+
pem = File.read(path)
|
|
47
|
+
pem.split(/(?=-----BEGIN CERTIFICATE-----)/)
|
|
48
|
+
.reject(&:empty?)
|
|
49
|
+
.map { |chunk| OpenSSL::X509::Certificate.new(chunk) }
|
|
50
|
+
rescue Errno::ENOENT => e
|
|
51
|
+
raise RuntimeError, "无法读取证书链文件: #{path} - #{e.message}"
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def signature_digest(issuer_array, serial)
|
|
55
|
+
issuer_str = issuer_array.reverse.map { |name, data, _| "#{name}=#{data}" }.join(',')
|
|
56
|
+
serial_str = serial.to_i.to_s
|
|
57
|
+
Digest::MD5.hexdigest("#{issuer_str}#{serial_str}")
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -7,14 +7,9 @@ module Alipay
|
|
|
7
7
|
class JsonUtil
|
|
8
8
|
# 完全复制PHP版本的toJsonString方法
|
|
9
9
|
def to_json_string(obj)
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
when String
|
|
14
|
-
obj
|
|
15
|
-
else
|
|
16
|
-
obj.to_s
|
|
17
|
-
end
|
|
10
|
+
return {} if obj.nil?
|
|
11
|
+
raise ArgumentError, 'to_json_string expects a Hash' unless obj.is_a?(Hash)
|
|
12
|
+
convert_map(obj)
|
|
18
13
|
end
|
|
19
14
|
|
|
20
15
|
def self.from_json_string(json_string)
|
|
@@ -23,6 +18,53 @@ module Alipay
|
|
|
23
18
|
rescue JSON::ParserError
|
|
24
19
|
json_string
|
|
25
20
|
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def convert_map(hash)
|
|
25
|
+
return hash unless hash.is_a?(Hash)
|
|
26
|
+
|
|
27
|
+
hash.each_with_object({}) do |(key, value), result|
|
|
28
|
+
result[underscore_key(key)] = convert_value(value)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def convert_value(value)
|
|
33
|
+
case value
|
|
34
|
+
when Hash
|
|
35
|
+
convert_map(value)
|
|
36
|
+
when Array
|
|
37
|
+
value.map { |item| convert_value(item) }
|
|
38
|
+
else
|
|
39
|
+
convert_object(value)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def convert_object(value)
|
|
44
|
+
return value if primitive?(value)
|
|
45
|
+
|
|
46
|
+
if value.respond_to?(:to_h)
|
|
47
|
+
convert_map(value.to_h)
|
|
48
|
+
elsif value.respond_to?(:to_hash)
|
|
49
|
+
convert_map(value.to_hash)
|
|
50
|
+
else
|
|
51
|
+
value
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def underscore_key(key)
|
|
56
|
+
str = key.to_s
|
|
57
|
+
underscored = str.gsub(/([A-Z]+)/) { "_#{$1.downcase}" }
|
|
58
|
+
underscored.gsub(/__+/, '_').sub(/^_/, '')
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def primitive?(value)
|
|
62
|
+
value.is_a?(String) ||
|
|
63
|
+
value.is_a?(Numeric) ||
|
|
64
|
+
value == true ||
|
|
65
|
+
value == false ||
|
|
66
|
+
value.nil?
|
|
67
|
+
end
|
|
26
68
|
end
|
|
27
69
|
end
|
|
28
70
|
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
module Alipay
|
|
2
|
+
module EasySDK
|
|
3
|
+
module Kernel
|
|
4
|
+
module Util
|
|
5
|
+
class PageUtil
|
|
6
|
+
def build_form(action_url, parameters)
|
|
7
|
+
charset = Alipay::EasySDK::Kernel::AlipayConstants::DEFAULT_CHARSET
|
|
8
|
+
form = "<form id='alipaysubmit' name='alipaysubmit' action='#{action_url}?charset=#{charset}' method='POST'>"
|
|
9
|
+
params_enum(parameters).each do |key, val|
|
|
10
|
+
next if check_empty(val)
|
|
11
|
+
|
|
12
|
+
escaped = val.to_s.gsub("'", "'")
|
|
13
|
+
form += "<input type='hidden' name='#{key}' value='#{escaped}'/>"
|
|
14
|
+
end
|
|
15
|
+
form += "<input type='submit' value='ok' style='display:none;'></form>"
|
|
16
|
+
form += "<script>document.forms['alipaysubmit'].submit();</script>"
|
|
17
|
+
form
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def params_enum(parameters)
|
|
23
|
+
return [] if parameters.nil?
|
|
24
|
+
parameters.to_a
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def check_empty(value)
|
|
28
|
+
!value || value.to_s.strip == ''
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -7,7 +7,12 @@ module Alipay
|
|
|
7
7
|
return true if response.respond_to?(:code) && response.code.to_s == '10000'
|
|
8
8
|
|
|
9
9
|
code_blank = !response.respond_to?(:code) || blank?(response.code)
|
|
10
|
-
|
|
10
|
+
sub_code_value = if response.respond_to?(:subCode)
|
|
11
|
+
response.subCode
|
|
12
|
+
elsif response.respond_to?(:sub_code)
|
|
13
|
+
response.sub_code
|
|
14
|
+
end
|
|
15
|
+
sub_code_blank = blank?(sub_code_value)
|
|
11
16
|
|
|
12
17
|
code_blank && sub_code_blank
|
|
13
18
|
end
|
|
@@ -49,7 +49,7 @@ module Alipay
|
|
|
49
49
|
# 调用openssl内置方法验签,完全模仿PHP的openssl_verify
|
|
50
50
|
public_key = OpenSSL::PKey::RSA.new(res)
|
|
51
51
|
digest = OpenSSL::Digest::SHA256.new
|
|
52
|
-
decoded_sign = Base64.decode64(sign)
|
|
52
|
+
decoded_sign = Base64.decode64(sign.to_s)
|
|
53
53
|
|
|
54
54
|
result = public_key.verify(digest, decoded_sign, content)
|
|
55
55
|
return result
|
|
@@ -59,14 +59,16 @@ module Alipay
|
|
|
59
59
|
end
|
|
60
60
|
|
|
61
61
|
def verify_params(parameters, public_key)
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
normalized = stringify_keys(parameters)
|
|
63
|
+
sign = normalized['sign'] || ''
|
|
64
|
+
content = get_sign_content(normalized)
|
|
65
|
+
verify(content, sign, public_key)
|
|
65
66
|
end
|
|
66
67
|
|
|
67
68
|
def get_sign_content(params)
|
|
69
|
+
normalized = stringify_keys(params)
|
|
68
70
|
# 模拟PHP的ksort
|
|
69
|
-
sorted_params =
|
|
71
|
+
sorted_params = normalized.sort.to_h
|
|
70
72
|
|
|
71
73
|
# 移除sign和sign_type字段
|
|
72
74
|
sorted_params.delete('sign')
|
|
@@ -89,6 +91,14 @@ module Alipay
|
|
|
89
91
|
|
|
90
92
|
private
|
|
91
93
|
|
|
94
|
+
def stringify_keys(hash)
|
|
95
|
+
return {} if hash.nil?
|
|
96
|
+
|
|
97
|
+
hash.each_with_object({}) do |(key, value), acc|
|
|
98
|
+
acc[key.to_s] = value
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
92
102
|
# 完全复制PHP的wordwrap函数
|
|
93
103
|
def wordwrap(str, width = 75, break_str = "\n", cut = false)
|
|
94
104
|
if str.nil? || str.empty?
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
require_relative '../../kernel/easy_sdk_kernel'
|
|
2
|
+
require_relative 'models/alipay_trade_app_pay_response'
|
|
3
|
+
|
|
4
|
+
module Alipay
|
|
5
|
+
module EasySDK
|
|
6
|
+
module Payment
|
|
7
|
+
module App
|
|
8
|
+
class Client
|
|
9
|
+
def initialize(kernel)
|
|
10
|
+
@kernel = kernel
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def pay(subject, out_trade_no, total_amount)
|
|
14
|
+
system_params = {
|
|
15
|
+
'method' => 'alipay.trade.app.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
|
+
}
|
|
31
|
+
text_params = {}
|
|
32
|
+
|
|
33
|
+
sign = @kernel.sign(system_params, biz_params, text_params, @kernel.get_config('merchantPrivateKey'))
|
|
34
|
+
response = {
|
|
35
|
+
Alipay::EasySDK::Kernel::AlipayConstants::BODY_FIELD => @kernel.generate_order_string(system_params, biz_params, text_params, sign)
|
|
36
|
+
}
|
|
37
|
+
Models::AlipayTradeAppPayResponse.from_map(response)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def agent(app_auth_token)
|
|
41
|
+
@kernel.inject_text_param('app_auth_token', app_auth_token)
|
|
42
|
+
self
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def auth(auth_token)
|
|
46
|
+
@kernel.inject_text_param('auth_token', auth_token)
|
|
47
|
+
self
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def async_notify(url)
|
|
51
|
+
@kernel.inject_text_param('notify_url', url)
|
|
52
|
+
self
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def route(test_url)
|
|
56
|
+
@kernel.inject_text_param('ws_service_url', test_url)
|
|
57
|
+
self
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def optional(key, value)
|
|
61
|
+
@kernel.inject_biz_param(key, value)
|
|
62
|
+
self
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def batch_optional(optional_args)
|
|
66
|
+
optional_args.each do |opt_key, opt_value|
|
|
67
|
+
@kernel.inject_biz_param(opt_key, opt_value)
|
|
68
|
+
end
|
|
69
|
+
self
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Alipay
|
|
2
|
+
module EasySDK
|
|
3
|
+
module Payment
|
|
4
|
+
module App
|
|
5
|
+
module Models
|
|
6
|
+
class AlipayTradeAppPayResponse
|
|
7
|
+
attr_accessor :body
|
|
8
|
+
|
|
9
|
+
def self.from_map(response)
|
|
10
|
+
new.tap do |instance|
|
|
11
|
+
instance.body = response[Alipay::EasySDK::Kernel::AlipayConstants::BODY_FIELD]
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
require 'net/http'
|
|
2
2
|
require 'uri'
|
|
3
3
|
require 'cgi'
|
|
4
|
+
require 'openssl'
|
|
4
5
|
|
|
5
6
|
require_relative '../../kernel/easy_sdk_kernel'
|
|
6
7
|
require_relative 'models/alipay_trade_create_response'
|
|
@@ -16,6 +17,27 @@ module Alipay
|
|
|
16
17
|
module Payment
|
|
17
18
|
module Common
|
|
18
19
|
class Client
|
|
20
|
+
class TeaError < StandardError
|
|
21
|
+
attr_reader :data, :code
|
|
22
|
+
|
|
23
|
+
def initialize(data = {}, message = '', code = nil, cause = nil)
|
|
24
|
+
super(message)
|
|
25
|
+
@data = data
|
|
26
|
+
@code = code
|
|
27
|
+
set_backtrace(cause.backtrace) if cause
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
class TeaUnableRetryError < StandardError
|
|
32
|
+
attr_reader :last_request, :last_exception
|
|
33
|
+
|
|
34
|
+
def initialize(last_request, last_exception)
|
|
35
|
+
super(last_exception&.message)
|
|
36
|
+
@last_request = last_request
|
|
37
|
+
@last_exception = last_exception
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
19
41
|
def initialize(kernel)
|
|
20
42
|
@kernel = kernel
|
|
21
43
|
end
|
|
@@ -71,7 +93,7 @@ module Alipay
|
|
|
71
93
|
|
|
72
94
|
def verify_notify(parameters)
|
|
73
95
|
if @kernel.is_cert_mode
|
|
74
|
-
@kernel.verify_params(parameters, @kernel.extract_alipay_public_key(
|
|
96
|
+
@kernel.verify_params(parameters, @kernel.extract_alipay_public_key(''))
|
|
75
97
|
else
|
|
76
98
|
@kernel.verify_params(parameters, @kernel.get_config('alipayPublicKey'))
|
|
77
99
|
end
|
|
@@ -117,7 +139,7 @@ module Alipay
|
|
|
117
139
|
sign = @kernel.sign(system_params, biz_params, text_params, @kernel.get_config('merchantPrivateKey'))
|
|
118
140
|
|
|
119
141
|
text_query = (@kernel.text_params || {}).dup
|
|
120
|
-
query_params = {
|
|
142
|
+
query_params = { Alipay::EasySDK::Kernel::AlipayConstants::SIGN_FIELD => sign }.merge(system_params)
|
|
121
143
|
query_params.merge!(text_query) unless text_query.empty?
|
|
122
144
|
|
|
123
145
|
uri = build_gateway_uri(query_params)
|
|
@@ -130,11 +152,15 @@ module Alipay
|
|
|
130
152
|
resp_map = @kernel.read_as_json(response, api_method)
|
|
131
153
|
|
|
132
154
|
unless verify_response(resp_map)
|
|
133
|
-
raise '验签失败,请检查支付宝公钥设置是否正确。'
|
|
155
|
+
raise TeaError.new({}, '验签失败,请检查支付宝公钥设置是否正确。')
|
|
134
156
|
end
|
|
135
157
|
|
|
136
158
|
map = @kernel.to_resp_model(resp_map)
|
|
137
159
|
response_class.from_map(map)
|
|
160
|
+
rescue TeaError => e
|
|
161
|
+
raise e
|
|
162
|
+
rescue StandardError => e
|
|
163
|
+
raise TeaError.new({}, e.message, nil, e)
|
|
138
164
|
ensure
|
|
139
165
|
clear_optional_params
|
|
140
166
|
end
|
|
@@ -155,17 +181,17 @@ module Alipay
|
|
|
155
181
|
end
|
|
156
182
|
|
|
157
183
|
def build_gateway_uri(query_params)
|
|
158
|
-
host = @kernel.get_config(
|
|
159
|
-
scheme = @kernel.get_config(
|
|
184
|
+
host = @kernel.get_config(Alipay::EasySDK::Kernel::AlipayConstants::HOST_CONFIG_KEY).to_s.sub(%r{/gateway\.do$}, '')
|
|
185
|
+
scheme = @kernel.get_config(Alipay::EasySDK::Kernel::AlipayConstants::PROTOCOL_CONFIG_KEY) || 'https'
|
|
160
186
|
uri = URI("#{scheme}://#{host}/gateway.do")
|
|
161
187
|
uri.query = URI.encode_www_form(query_params.sort.to_h)
|
|
162
188
|
uri
|
|
163
189
|
end
|
|
164
190
|
|
|
165
191
|
def perform_http_request(uri, request)
|
|
166
|
-
http =
|
|
192
|
+
http = build_http_client(uri)
|
|
167
193
|
http.use_ssl = uri.scheme == 'https'
|
|
168
|
-
http.verify_mode = OpenSSL::SSL::VERIFY_NONE if http.use_ssl?
|
|
194
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE if http.use_ssl? && ignore_ssl?
|
|
169
195
|
http.open_timeout = 15
|
|
170
196
|
http.read_timeout = 15
|
|
171
197
|
http.request(request)
|
|
@@ -183,6 +209,32 @@ module Alipay
|
|
|
183
209
|
@kernel.optional_text_params.clear if @kernel.optional_text_params
|
|
184
210
|
@kernel.optional_biz_params.clear if @kernel.optional_biz_params
|
|
185
211
|
end
|
|
212
|
+
|
|
213
|
+
def build_http_client(uri)
|
|
214
|
+
proxy_settings = http_proxy_settings
|
|
215
|
+
if proxy_settings
|
|
216
|
+
Net::HTTP.new(uri.host, uri.port, *proxy_settings)
|
|
217
|
+
else
|
|
218
|
+
Net::HTTP.new(uri.host, uri.port)
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
def http_proxy_settings
|
|
223
|
+
raw_proxy = @kernel.get_config('httpProxy')
|
|
224
|
+
return nil if raw_proxy.nil? || raw_proxy.to_s.strip.empty?
|
|
225
|
+
|
|
226
|
+
proxy_uri = raw_proxy =~ %r{^https?://} ? URI(raw_proxy) : URI("http://#{raw_proxy}")
|
|
227
|
+
[proxy_uri.host, proxy_uri.port, proxy_uri.user, proxy_uri.password]
|
|
228
|
+
rescue URI::InvalidURIError
|
|
229
|
+
nil
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
def ignore_ssl?
|
|
233
|
+
value = @kernel.get_config('ignoreSSL')
|
|
234
|
+
return false if value.nil?
|
|
235
|
+
|
|
236
|
+
value == true || value.to_s.strip.downcase == 'true'
|
|
237
|
+
end
|
|
186
238
|
end
|
|
187
239
|
end
|
|
188
240
|
end
|
|
@@ -20,20 +20,6 @@ module Alipay
|
|
|
20
20
|
end
|
|
21
21
|
end
|
|
22
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
23
|
end
|
|
38
24
|
end
|
|
39
25
|
end
|
|
@@ -36,7 +36,7 @@ module Alipay
|
|
|
36
36
|
sign = @kernel.sign(system_params, biz_params, text_params, @kernel.get_config('merchantPrivateKey'))
|
|
37
37
|
|
|
38
38
|
response = {
|
|
39
|
-
|
|
39
|
+
Alipay::EasySDK::Kernel::AlipayConstants::BODY_FIELD => @kernel.generate_page('POST', system_params, biz_params, text_params, sign),
|
|
40
40
|
'payment_url' => @kernel.generate_payment_url(system_params, biz_params, text_params, sign)
|
|
41
41
|
}
|
|
42
42
|
|
|
@@ -8,26 +8,10 @@ module Alipay
|
|
|
8
8
|
|
|
9
9
|
def self.from_map(response)
|
|
10
10
|
new.tap do |instance|
|
|
11
|
-
instance.body = response[
|
|
11
|
+
instance.body = response[Alipay::EasySDK::Kernel::AlipayConstants::BODY_FIELD]
|
|
12
12
|
instance.payment_url = response['payment_url']
|
|
13
13
|
end
|
|
14
14
|
end
|
|
15
|
-
|
|
16
|
-
def success?
|
|
17
|
-
!body.nil? && !body.to_s.empty?
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def form
|
|
21
|
-
body
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def error_message
|
|
25
|
-
nil
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def to_s
|
|
29
|
-
body || ''
|
|
30
|
-
end
|
|
31
15
|
end
|
|
32
16
|
end
|
|
33
17
|
end
|
|
@@ -39,7 +39,7 @@ module Alipay
|
|
|
39
39
|
sign = @kernel.sign(system_params, biz_params, text_params, @kernel.get_config("merchantPrivateKey"))
|
|
40
40
|
|
|
41
41
|
response = {
|
|
42
|
-
|
|
42
|
+
Alipay::EasySDK::Kernel::AlipayConstants::BODY_FIELD => @kernel.generate_page("POST", system_params, biz_params, text_params, sign),
|
|
43
43
|
"payment_url" => @kernel.generate_payment_url(system_params, biz_params, text_params, sign)
|
|
44
44
|
}
|
|
45
45
|
return Alipay::EasySDK::Payment::Wap::Models::AlipayTradeWapPayResponse.from_map(response)
|
|
@@ -8,26 +8,10 @@ module Alipay
|
|
|
8
8
|
|
|
9
9
|
def self.from_map(response)
|
|
10
10
|
new.tap do |instance|
|
|
11
|
-
instance.body = response[
|
|
11
|
+
instance.body = response[Alipay::EasySDK::Kernel::AlipayConstants::BODY_FIELD]
|
|
12
12
|
instance.payment_url = response['payment_url']
|
|
13
13
|
end
|
|
14
14
|
end
|
|
15
|
-
|
|
16
|
-
def success?
|
|
17
|
-
!body.nil? && !body.to_s.empty?
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def form
|
|
21
|
-
body
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def error_message
|
|
25
|
-
nil
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def to_s
|
|
29
|
-
body || ''
|
|
30
|
-
end
|
|
31
15
|
end
|
|
32
16
|
end
|
|
33
17
|
end
|