ralipay 0.0.1 → 0.0.2
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/README.md +1 -1
- data/lib/ralipay/common.rb +34 -8
- data/lib/ralipay/service.rb +71 -2
- data/lib/ralipay/version.rb +1 -1
- data/lib/ralipay.rb +60 -1
- data/test/test_ralipay.rb +10 -3
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 710a49c3f404fbad754bdb8800b408e8ab417199
|
|
4
|
+
data.tar.gz: 8306eff1acdc996510683b6b0afe6f388c9885b7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f981cf1358eed4aa939fb8eff7b5e42252a4f8458707ad924ddf425e2656fe5654be812dcd1521d0bc2ed33237d77ccfef34351c62970b65289be727a5d772c3
|
|
7
|
+
data.tar.gz: a72fa9c8608615c04268b2148e1bdc0df2c60f97878cd3e5eea07a69141324ba421c138cfc33eec4646573062476b4feb8f93383b5a0f07a5a1d99fad93b5fd0
|
data/README.md
CHANGED
data/lib/ralipay/common.rb
CHANGED
|
@@ -4,7 +4,7 @@ module Ralipay::Common
|
|
|
4
4
|
require 'base64'
|
|
5
5
|
|
|
6
6
|
#生成签名结果
|
|
7
|
-
def self.build_sign
|
|
7
|
+
def self.build_sign data_array
|
|
8
8
|
#把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
|
|
9
9
|
for_sign_string = self.create_link_string(data_array)
|
|
10
10
|
#签名
|
|
@@ -18,7 +18,7 @@ module Ralipay::Common
|
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
#把数组所有元素,排序后按照“参数=参数值”的模式用“&”字符拼接成字符串
|
|
21
|
-
def self.create_link_string
|
|
21
|
+
def self.create_link_string hash
|
|
22
22
|
result_string = ''
|
|
23
23
|
hash = hash.sort
|
|
24
24
|
hash.each{|key,value|
|
|
@@ -30,7 +30,7 @@ module Ralipay::Common
|
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
#RSA签名
|
|
33
|
-
def self.rsa_sign
|
|
33
|
+
def self.rsa_sign for_sign_string
|
|
34
34
|
#读取私钥文件
|
|
35
35
|
rsa_private_key_file = File.read($global_configs[:rsa_private_key_path])
|
|
36
36
|
#转换为openssl密钥
|
|
@@ -39,9 +39,7 @@ module Ralipay::Common
|
|
|
39
39
|
digest = OpenSSL::Digest::SHA1.new
|
|
40
40
|
signature = openssl_key.sign digest, for_sign_string
|
|
41
41
|
#base64编码
|
|
42
|
-
signature.gsub!("\n",'')
|
|
43
42
|
signature = Base64.encode64(signature)
|
|
44
|
-
signature.gsub!("\n",'')
|
|
45
43
|
return signature
|
|
46
44
|
end
|
|
47
45
|
|
|
@@ -51,23 +49,51 @@ module Ralipay::Common
|
|
|
51
49
|
end
|
|
52
50
|
|
|
53
51
|
#验签
|
|
54
|
-
def self.verify?
|
|
52
|
+
def self.verify? for_sign_string, signed_string
|
|
55
53
|
#读取公钥文件
|
|
56
54
|
rsa_public_key_file = File.read($global_configs[:rsa_public_key_path])
|
|
55
|
+
#转换为RSA对象
|
|
57
56
|
openssl_public = OpenSSL::PKey::RSA.new rsa_public_key_file
|
|
57
|
+
#生成SHA1密钥串
|
|
58
58
|
digest = OpenSSL::Digest::SHA1.new
|
|
59
|
+
#openssl验证签名
|
|
59
60
|
openssl_public.verify(digest, Base64.decode64(signed_string), for_sign_string)
|
|
60
61
|
end
|
|
61
62
|
|
|
62
63
|
#除去数组中的空值和签名参数
|
|
63
|
-
def self.para_filter
|
|
64
|
+
def self.para_filter paras = {}
|
|
64
65
|
new_paras = {}
|
|
65
66
|
paras.each{|key,value|
|
|
66
|
-
if key != :sign && key != :sign_type && value != '' && value != nil
|
|
67
|
+
if key != :sign && key != :sign_type && key != 'sign' && key != 'sign_type' && value != '' && value != nil
|
|
67
68
|
new_paras[key] = value
|
|
68
69
|
end
|
|
69
70
|
}
|
|
70
71
|
return new_paras
|
|
71
72
|
end
|
|
72
73
|
|
|
74
|
+
#解密用商户私钥,解密前,需要用base64将内容还原成二进制,按128位拆开解密
|
|
75
|
+
def self.decrypt crypt_string
|
|
76
|
+
#读取私钥文件
|
|
77
|
+
rsa_private_key_file = File.read($global_configs[:rsa_private_key_path])
|
|
78
|
+
#转换为openssl密钥
|
|
79
|
+
openssl_key = OpenSSL::PKey::RSA.new rsa_private_key_file
|
|
80
|
+
#密文经过base64解码
|
|
81
|
+
crypt_string = Base64.decode64(crypt_string)
|
|
82
|
+
|
|
83
|
+
#声明明文字符串变量
|
|
84
|
+
result = ''
|
|
85
|
+
#循环按照128位解密
|
|
86
|
+
i = 0
|
|
87
|
+
while i < (crypt_string.length.to_f/128) do
|
|
88
|
+
for_decrypt_string = crypt_string[i * 128,128]
|
|
89
|
+
#p for_decrypt_string
|
|
90
|
+
#拆分开长度为128的字符串片段通过私钥进行解密
|
|
91
|
+
origin_data = openssl_key.private_decrypt for_decrypt_string
|
|
92
|
+
result = result + origin_data
|
|
93
|
+
i += 1
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
return result
|
|
97
|
+
end
|
|
98
|
+
|
|
73
99
|
end
|
data/lib/ralipay/service.rb
CHANGED
|
@@ -20,7 +20,7 @@ class Service
|
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
#创建mobile_merchant_pay_channel接口
|
|
23
|
-
def mobile_merchant_pay_channel
|
|
23
|
+
def mobile_merchant_pay_channel parameter
|
|
24
24
|
|
|
25
25
|
#除去数组中的空值和签名参数
|
|
26
26
|
@@parameter = Ralipay::Common::para_filter parameter
|
|
@@ -55,7 +55,7 @@ class Service
|
|
|
55
55
|
for_sign_string = for_sign_string.encode('GBK')
|
|
56
56
|
verify = Ralipay::Common::verify?(for_sign_string, ali_sign)
|
|
57
57
|
|
|
58
|
-
if verify
|
|
58
|
+
if verify
|
|
59
59
|
return json_result
|
|
60
60
|
else
|
|
61
61
|
fail('------verify fail------')
|
|
@@ -63,4 +63,73 @@ class Service
|
|
|
63
63
|
|
|
64
64
|
end
|
|
65
65
|
|
|
66
|
+
#创建alipay.wap.trade.create.direct接口
|
|
67
|
+
def alipay_wap_trade_create_direct parameter
|
|
68
|
+
#除去数组中的空值和签名参数
|
|
69
|
+
@@parameter = Ralipay::Common::para_filter parameter
|
|
70
|
+
sort_array = @@parameter.sort
|
|
71
|
+
#生成签名
|
|
72
|
+
@@my_sign = Ralipay::Common::build_sign sort_array
|
|
73
|
+
#创建POST请求数据串
|
|
74
|
+
@@req_data = Ralipay::Common::create_link_string(@@parameter).to_s \
|
|
75
|
+
+ '&sign=' \
|
|
76
|
+
+ CGI::escape(@@my_sign)
|
|
77
|
+
#请求支付宝接口
|
|
78
|
+
uri = URI.parse (@@gateway_order)
|
|
79
|
+
http = Net::HTTP.new uri.host, uri.port
|
|
80
|
+
request = Net::HTTP::Post.new(uri.request_uri)
|
|
81
|
+
request.set_body_internal(@@req_data)
|
|
82
|
+
response = http.request(request)
|
|
83
|
+
|
|
84
|
+
#解析token
|
|
85
|
+
token = parse_token response.body
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def parse_token string
|
|
89
|
+
#返回的数据已转义,反转义之
|
|
90
|
+
unescaped_string = CGI::unescape string
|
|
91
|
+
#用&拆开
|
|
92
|
+
unescaped_string = unescaped_string.split('&')
|
|
93
|
+
data_hash = {}
|
|
94
|
+
unescaped_string.each{|str|
|
|
95
|
+
kv_array = str.split('=',2)
|
|
96
|
+
data_hash[kv_array[0]] = kv_array[1]
|
|
97
|
+
}
|
|
98
|
+
#私钥解密
|
|
99
|
+
data_hash['res_data'] = Ralipay::Common::decrypt data_hash['res_data']
|
|
100
|
+
#获取返回的RSA签名
|
|
101
|
+
sign = data_hash['sign']
|
|
102
|
+
#去sign,准备验签
|
|
103
|
+
data_hash = Ralipay::Common::para_filter data_hash
|
|
104
|
+
data_hash.sort
|
|
105
|
+
link_string = Ralipay::Common::create_link_string(data_hash)
|
|
106
|
+
|
|
107
|
+
#验签
|
|
108
|
+
verify = Ralipay::Common::verify?(link_string, sign)
|
|
109
|
+
|
|
110
|
+
if verify
|
|
111
|
+
#解析token
|
|
112
|
+
doc = Nokogiri::XML data_hash['res_data']
|
|
113
|
+
token = doc.xpath('/direct_trade_create_res/request_token').text
|
|
114
|
+
return token
|
|
115
|
+
else
|
|
116
|
+
fail('------verify fail------')
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
#调用alipay_Wap_Auth_AuthAndExecute接口
|
|
121
|
+
def alipay_wap_auth_and_execute parameter
|
|
122
|
+
#除去数组中的空值和签名参数
|
|
123
|
+
@@parameter = Ralipay::Common::para_filter parameter
|
|
124
|
+
sort_array = @@parameter.sort
|
|
125
|
+
#生成签名
|
|
126
|
+
@@my_sign = Ralipay::Common::build_sign sort_array
|
|
127
|
+
#生成跳转链接
|
|
128
|
+
redirect_url = @@gateway_order \
|
|
129
|
+
+ Ralipay::Common::create_link_string(@@parameter) \
|
|
130
|
+
+ '&sign=' \
|
|
131
|
+
+ CGI::escape(@@my_sign)
|
|
132
|
+
return redirect_url
|
|
133
|
+
end
|
|
134
|
+
|
|
66
135
|
end
|
data/lib/ralipay/version.rb
CHANGED
data/lib/ralipay.rb
CHANGED
|
@@ -3,6 +3,8 @@ module Ralipay
|
|
|
3
3
|
require 'ralipay/version'
|
|
4
4
|
require 'ralipay/common'
|
|
5
5
|
require 'ralipay/service'
|
|
6
|
+
require 'json'
|
|
7
|
+
require 'date'
|
|
6
8
|
|
|
7
9
|
include Ralipay::Common
|
|
8
10
|
|
|
@@ -32,6 +34,7 @@ module Ralipay
|
|
|
32
34
|
$input_charset = 'utf-8'
|
|
33
35
|
$input_charset_gbk = 'GBK'
|
|
34
36
|
$service_pay_channel = 'mobile.merchant.paychannel'
|
|
37
|
+
$v = '2.0'
|
|
35
38
|
|
|
36
39
|
def initialize(configs)
|
|
37
40
|
#@todo 入参合法性验证
|
|
@@ -46,7 +49,63 @@ module Ralipay
|
|
|
46
49
|
:partner => $global_configs[:partner],
|
|
47
50
|
:out_user => ''
|
|
48
51
|
}
|
|
49
|
-
Service.new.mobile_merchant_pay_channel params
|
|
52
|
+
result = Service.new.mobile_merchant_pay_channel params
|
|
53
|
+
|
|
54
|
+
begin
|
|
55
|
+
json = JSON.parse result
|
|
56
|
+
rescue SignOrVerifyError
|
|
57
|
+
#验签异常,可能为证书错误,参数初始化错误
|
|
58
|
+
fail('------SignOrVerifyError------')
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
#参数及验签正常,继续生成请求支付请求页面url
|
|
62
|
+
#构造请求参数
|
|
63
|
+
req_hash = {
|
|
64
|
+
:req_data => '<direct_trade_create_req><subject>' \
|
|
65
|
+
+ $global_configs[:subject] \
|
|
66
|
+
+ '</subject><out_trade_no>' \
|
|
67
|
+
+ $global_configs[:out_trade_no] \
|
|
68
|
+
+ '</out_trade_no><total_fee>' \
|
|
69
|
+
+ $global_configs[:total_fee] \
|
|
70
|
+
+ "</total_fee><seller_account_name>" \
|
|
71
|
+
+ $global_configs[:seller_email] \
|
|
72
|
+
+ "</seller_account_name><notify_url>" \
|
|
73
|
+
+ $global_configs[:notify_url] \
|
|
74
|
+
+ "</notify_url><out_user>" \
|
|
75
|
+
+ $global_configs[:out_user] \
|
|
76
|
+
+ "</out_user><merchant_url>" \
|
|
77
|
+
+ $global_configs[:merchant_url] \
|
|
78
|
+
+ "</merchant_url><cashier_code>" \
|
|
79
|
+
+ "</cashier_code><call_back_url>" \
|
|
80
|
+
+ $global_configs[:call_back_url] \
|
|
81
|
+
+ "</call_back_url></direct_trade_create_req>",
|
|
82
|
+
:service => $service1,
|
|
83
|
+
:sec_id => $sec_id,
|
|
84
|
+
:partner => $global_configs[:partner],
|
|
85
|
+
:req_id => DateTime.parse(Time.now.to_s).strftime('%Y%m%d%H%M%S').to_s,
|
|
86
|
+
:format => $format,
|
|
87
|
+
:v => $v
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
#获取token
|
|
91
|
+
token = Service.new.alipay_wap_trade_create_direct(req_hash)
|
|
92
|
+
|
|
93
|
+
#构造要请求的参数数组,无需改动
|
|
94
|
+
req_hash = {
|
|
95
|
+
:req_data => "<auth_and_execute_req><request_token>" \
|
|
96
|
+
+ token \
|
|
97
|
+
+ "</request_token></auth_and_execute_req>",
|
|
98
|
+
:service => $service2,
|
|
99
|
+
:sec_id => $sec_id,
|
|
100
|
+
:partner => $global_configs[:partner],
|
|
101
|
+
:call_back_url => $global_configs[:call_back_url],
|
|
102
|
+
:format => $format,
|
|
103
|
+
:v => $v
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
#调用alipay_Wap_Auth_AuthAndExecute接口方法,生成支付地址
|
|
107
|
+
wap_pay_url = Service.new.alipay_wap_auth_and_execute(req_hash)
|
|
108
|
+
return wap_pay_url
|
|
50
109
|
end
|
|
51
110
|
|
|
52
111
|
end
|
data/test/test_ralipay.rb
CHANGED
|
@@ -6,10 +6,17 @@ class TestRalipay < Test::Unit::TestCase
|
|
|
6
6
|
def test_generate_wap_pay_url
|
|
7
7
|
configs = {
|
|
8
8
|
:partner => '2088701817081672',
|
|
9
|
-
:
|
|
10
|
-
:
|
|
9
|
+
:seller_email => 'service@iiseeuu.com',
|
|
10
|
+
:rsa_private_key_path => '/Users/ZhouYT/Desktop/rsa_private_key.pem',
|
|
11
|
+
:rsa_public_key_path => '/Users/ZhouYT/Desktop/alipay_public_key.pem',
|
|
12
|
+
:subject => '测试商品',
|
|
13
|
+
:out_trade_no => '1222222232',
|
|
14
|
+
:total_fee => '1',
|
|
15
|
+
:notify_url => 'http://www.iiseeuu.com',
|
|
16
|
+
:merchant_url => 'http://www.iiseeuu.com',
|
|
17
|
+
:call_back_url => 'http://www.iiseeuu.com'
|
|
11
18
|
}
|
|
12
|
-
assert_equal "
|
|
19
|
+
assert_equal "需要手动访问url进行测试",
|
|
13
20
|
Ralipay::Payment.new(configs).generate_wap_pay_url
|
|
14
21
|
end
|
|
15
22
|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ralipay
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- RaymondChou
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2013-03-
|
|
11
|
+
date: 2013-03-23 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|