ralipay 0.0.3 → 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.
- checksums.yaml +4 -4
- data/README.md +117 -8
- data/lib/ralipay/version.rb +1 -1
- data/lib/ralipay.rb +87 -16
- data/test/test_ralipay.rb +3 -3
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ffa7224be52da431a62dbbd7fe48e6cc9e5f5da0
|
|
4
|
+
data.tar.gz: d2227107e9fb55aae21e5c0bf7872e4332c29384
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7773a0a08db868eb09b0cbcb39b50b5fe87f943f4e8430522ff34165c6a646d7ac793c6798ea52522c7f7dcaa3876640ba51834d7a177040b48eec96fd889d7e
|
|
7
|
+
data.tar.gz: 722d39bf8d156a24aa6a9fa612be63f129a40e879baf3605cada4797c76e84371660d66234497a157c97406374bb5ac519a4b75194cc9e780792ac01acd82250
|
data/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Ralipay
|
|
2
2
|
|
|
3
|
-
A ruby Gem for Alipay
|
|
3
|
+
A ruby Gem for Alipay, contains web payment and mobile client payment
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -16,15 +16,124 @@ Or install it yourself as:
|
|
|
16
16
|
|
|
17
17
|
$ gem install ralipay
|
|
18
18
|
|
|
19
|
+
## API
|
|
20
|
+
|
|
21
|
+
Ralipay::WapPayment.new
|
|
22
|
+
|
|
23
|
+
Ralipay::WapPayment.generate_pay_url
|
|
24
|
+
|
|
25
|
+
Ralipay::WapPayment.callback_verify?
|
|
26
|
+
|
|
27
|
+
Ralipay::WapPayment.callback_verify
|
|
28
|
+
|
|
29
|
+
Ralipay::WapPayment.notify_verify?
|
|
30
|
+
|
|
31
|
+
Ralipay::WapPayment.notify_verify
|
|
32
|
+
|
|
33
|
+
Ralipay::ClientPayment.notify_verify?
|
|
34
|
+
|
|
35
|
+
Ralipay::ClientPayment.notify_verify
|
|
36
|
+
|
|
37
|
+
Ralipay::ClientPayment.callback_verify?
|
|
38
|
+
|
|
39
|
+
Ralipay::Common::build_sign
|
|
40
|
+
|
|
41
|
+
Ralipay::Common::create_link_string
|
|
42
|
+
|
|
43
|
+
Ralipay::Common::rsa_sign
|
|
44
|
+
|
|
45
|
+
Ralipay::Common::md5_sign
|
|
46
|
+
|
|
47
|
+
Ralipay::Common::verify?
|
|
48
|
+
|
|
49
|
+
Ralipay::Common::para_filter
|
|
50
|
+
|
|
51
|
+
Ralipay::Common::decrypt
|
|
52
|
+
|
|
53
|
+
|
|
19
54
|
## Usage
|
|
20
55
|
|
|
21
|
-
|
|
56
|
+
### 准备
|
|
57
|
+
|
|
58
|
+
- 申请你的支付宝商户服务
|
|
59
|
+
|
|
60
|
+
- 取调用支付宝支付接口的账户信息
|
|
61
|
+
|
|
62
|
+
- 并使用openssl工具生成好公钥与私钥(建议使用RSA加密方式)
|
|
63
|
+
|
|
64
|
+
### 生成一个商品的WAP支付地址
|
|
65
|
+
|
|
66
|
+
准备好参数:configs(hash symbol)
|
|
67
|
+
|
|
68
|
+
configs = {
|
|
69
|
+
:partner => '0000000000000', #商户id partner_id
|
|
70
|
+
:seller_email => 'service@iiseeuu.com', #商户email
|
|
71
|
+
:rsa_private_key_path => '/Users/ZhouYT/Desktop/rsa_private_key.pem', #私钥绝对路径
|
|
72
|
+
:rsa_public_key_path => '/Users/ZhouYT/Desktop/alipay_public_key.pem', #公钥绝对路径
|
|
73
|
+
:subject => '测试商品', #商品名称
|
|
74
|
+
:out_trade_no => '1222222233', #外部交易号,不能重复
|
|
75
|
+
:total_fee => '0.01', #交易价格
|
|
76
|
+
:notify_url => 'http://xx.xx.xx.xx/xx/xx', #服务器异步回调通知接口地址
|
|
77
|
+
:merchant_url => 'http://xx.xx.xx.xx/xx/xx', #商品展示地址
|
|
78
|
+
:call_back_url => 'http://xx.xx.xx.xx/xx/xx' #支付成功同步回调跳转地址
|
|
79
|
+
}
|
|
80
|
+
获取url
|
|
81
|
+
|
|
82
|
+
url = Ralipay::WapPayment.new(configs).generate_pay_url
|
|
83
|
+
|
|
84
|
+
将当前页面redirect到该url上
|
|
85
|
+
|
|
86
|
+
### wap支付同步回调页面callback_url(get方法)
|
|
87
|
+
|
|
88
|
+
同样需要上面的configs(hash symbol),在new的时候只需要配置公钥和私钥就可以了
|
|
89
|
+
|
|
90
|
+
准备好当前页面获取到的get请求获取到的所有参数与值,用hash symbol形式传入
|
|
91
|
+
|
|
92
|
+
Ralipay::WapPayment.new(configs).callback_verify?(gets)
|
|
93
|
+
|
|
94
|
+
callback_verify? 方法只返回bool
|
|
95
|
+
|
|
96
|
+
callback_verify 方法返回支付状态,并安全的返回回调参数hash,失败返回false
|
|
97
|
+
|
|
98
|
+
返回的hash内容:
|
|
99
|
+
|
|
100
|
+
:trade_no
|
|
101
|
+
:out_trade_no
|
|
102
|
+
|
|
103
|
+
### wap支付异步回调接口notify_url(post方法)
|
|
104
|
+
|
|
105
|
+
同样需要上面的configs(hash symbol),在new的时候只需要配置公钥和私钥就可以了
|
|
106
|
+
|
|
107
|
+
准备好当前页面获取到的post请求获取到的所有参数与值,用hash symbol形式传入
|
|
108
|
+
|
|
109
|
+
Ralipay::WapPayment.new(configs).notify_verify?(posts)
|
|
110
|
+
|
|
111
|
+
异步回调验证,支付宝主动通知,前端POST xml方式获得参数,该方法只返回bool
|
|
112
|
+
|
|
113
|
+
成功请自行向支付宝打印纯文本success
|
|
114
|
+
|
|
115
|
+
如验签失败或未输出success支付宝会24小时根据策略重发总共7次,需考虑重复通知的情况
|
|
116
|
+
|
|
117
|
+
notify_verify? 方法只返回bool
|
|
118
|
+
|
|
119
|
+
notify_verify 方法返回支付状态,并安全的返回回调参数hash,失败返回false
|
|
120
|
+
|
|
121
|
+
### 客户端sdk支付异步回调通知接口notify_url(post方法)
|
|
122
|
+
|
|
123
|
+
同样需要上面的configs(hash symbol),在new的时候只需要配置公钥和私钥就可以了
|
|
124
|
+
|
|
125
|
+
准备好当前页面获取到的post请求获取到的所有参数与值,用hash symbol形式传入
|
|
126
|
+
|
|
127
|
+
Ralipay::ClientPayment.new(configs).notify_verify?(posts)
|
|
128
|
+
|
|
129
|
+
此方法与wap支付一致,内部处理有所不同
|
|
130
|
+
|
|
131
|
+
### 客户端sdk支付同步验证callback_url(post方法)
|
|
132
|
+
|
|
133
|
+
客户端callback回调之后POST请求服务器callback_url
|
|
22
134
|
|
|
135
|
+
前端处理时在验签通过就给客户端返回2,不通过就返回1
|
|
23
136
|
|
|
24
|
-
|
|
137
|
+
Ralipay::ClientPayment.new(configs).callback_verify?(posts)
|
|
25
138
|
|
|
26
|
-
|
|
27
|
-
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
28
|
-
3. Commit your changes (`git commit -am 'Add some feature'`)
|
|
29
|
-
4. Push to the branch (`git push origin my-new-feature`)
|
|
30
|
-
5. Create new Pull Request
|
|
139
|
+
该方法可以不使用
|
data/lib/ralipay/version.rb
CHANGED
data/lib/ralipay.rb
CHANGED
|
@@ -7,13 +7,12 @@ module Ralipay
|
|
|
7
7
|
require 'json'
|
|
8
8
|
require 'date'
|
|
9
9
|
require 'nokogiri'
|
|
10
|
+
require 'cgi'
|
|
10
11
|
|
|
11
12
|
include Ralipay::Common
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
#传入参数,必须初始化
|
|
16
|
-
$global_configs = {
|
|
14
|
+
#初始化参数
|
|
15
|
+
$global_configs = {
|
|
17
16
|
:secure_type => 'RSA',
|
|
18
17
|
:partner => '',
|
|
19
18
|
:seller_email => '',
|
|
@@ -26,17 +25,20 @@ module Ralipay
|
|
|
26
25
|
:out_user => '',
|
|
27
26
|
:rsa_private_key_path => '',
|
|
28
27
|
:rsa_public_key_path => ''
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
#固定参数,无需修改
|
|
31
|
+
$service1 = 'alipay.wap.trade.create.direct'
|
|
32
|
+
$service2 = 'alipay.wap.auth.authAndExecute'
|
|
33
|
+
$format = 'xml'
|
|
34
|
+
$sec_id = '0001'
|
|
35
|
+
$input_charset = 'utf-8'
|
|
36
|
+
$input_charset_gbk = 'GBK'
|
|
37
|
+
$service_pay_channel = 'mobile.merchant.paychannel'
|
|
38
|
+
$v = '2.0'
|
|
39
|
+
|
|
40
|
+
#wap支付类
|
|
41
|
+
class WapPayment
|
|
40
42
|
|
|
41
43
|
def initialize(configs)
|
|
42
44
|
#@todo 入参合法性验证
|
|
@@ -44,7 +46,7 @@ module Ralipay
|
|
|
44
46
|
end
|
|
45
47
|
|
|
46
48
|
#生成wap支付地址
|
|
47
|
-
def
|
|
49
|
+
def generate_pay_url
|
|
48
50
|
params = {
|
|
49
51
|
:_input_charset => $input_charset_gbk,
|
|
50
52
|
:sign_type => $sec_id,
|
|
@@ -170,4 +172,73 @@ module Ralipay
|
|
|
170
172
|
|
|
171
173
|
end
|
|
172
174
|
|
|
175
|
+
#手机SDK客户端支付类,与wap流程不同,且只允许RSA验签
|
|
176
|
+
class ClientPayment
|
|
177
|
+
|
|
178
|
+
def initialize(configs)
|
|
179
|
+
#@todo 入参合法性验证
|
|
180
|
+
$global_configs = $global_configs.merge configs
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
#异步回调验证,支付宝主动通知,前端POST xml方式获得参数,该方法只返回bool
|
|
184
|
+
#成功请自行向支付宝打印纯文本success
|
|
185
|
+
#如验签失败或未输出success支付宝会24小时根据策略重发总共7次,需考虑重复通知的情况
|
|
186
|
+
def notify_verify? posts
|
|
187
|
+
notify_data = 'notify_data=' + posts[:notify_data].to_s
|
|
188
|
+
sign = posts[:sign]
|
|
189
|
+
#验签名
|
|
190
|
+
verify = Ralipay::Common::verify?(notify_data, sign)
|
|
191
|
+
|
|
192
|
+
if verify
|
|
193
|
+
#解密并解析返回参数的xml
|
|
194
|
+
xml = posts[:notify_data]
|
|
195
|
+
doc = Nokogiri::XML xml
|
|
196
|
+
status = doc.xpath('/notify/trade_status').text
|
|
197
|
+
#获得可信的交易状态
|
|
198
|
+
status == 'TRADE_FINISHED' ? true : false
|
|
199
|
+
else
|
|
200
|
+
false
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
#异步回调验证,支付宝主动通知,前端POST xml方式获得参数,该方法返回支付状态,并安全的返回回调参数hash,失败返回false
|
|
205
|
+
#成功请自行向支付宝打印纯文本success
|
|
206
|
+
#如验签失败或未输出success支付宝会24小时根据策略重发总共7次,需考虑重复通知的情况
|
|
207
|
+
def notify_verify posts
|
|
208
|
+
notify_data = 'notify_data=' + posts[:notify_data].to_s
|
|
209
|
+
sign = posts[:sign]
|
|
210
|
+
#验签名
|
|
211
|
+
verify = Ralipay::Common::verify?(notify_data, sign)
|
|
212
|
+
|
|
213
|
+
if verify
|
|
214
|
+
#解密并解析返回参数的xml
|
|
215
|
+
xml = posts[:notify_data]
|
|
216
|
+
doc = Nokogiri::XML xml
|
|
217
|
+
status = doc.xpath('/notify/trade_status').text
|
|
218
|
+
#获得可信的交易状态
|
|
219
|
+
if status == 'TRADE_FINISHED'
|
|
220
|
+
{
|
|
221
|
+
:out_trade_no => doc.xpath('/notify/out_trade_no').text,
|
|
222
|
+
:subject => doc.xpath('/notify/subject').text,
|
|
223
|
+
:price => doc.xpath('/notify/price').text,
|
|
224
|
+
:trade_no => doc.xpath('/notify/trade_no').text
|
|
225
|
+
}
|
|
226
|
+
else
|
|
227
|
+
false
|
|
228
|
+
end
|
|
229
|
+
else
|
|
230
|
+
false
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
#客户端callback回调之后POST请求服务器callback_url,传入hash symbol,该方法只返回bool
|
|
235
|
+
#前端在验签通过就给客户端返回2,不通过就返回1
|
|
236
|
+
def callback_verify? posts
|
|
237
|
+
sign = CGI::unescape posts[:sign]
|
|
238
|
+
content = CGI::unescape posts[:content]
|
|
239
|
+
Ralipay::Common::verify?(content, sign)
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
end
|
|
243
|
+
|
|
173
244
|
end
|
data/test/test_ralipay.rb
CHANGED
|
@@ -17,7 +17,7 @@ class TestRalipay < Test::Unit::TestCase
|
|
|
17
17
|
:call_back_url => 'http://www.iiseeuu.com'
|
|
18
18
|
}
|
|
19
19
|
assert_equal "需要手动访问url进行测试",
|
|
20
|
-
Ralipay::
|
|
20
|
+
Ralipay::WapPayment.new(configs).generate_pay_url
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
def test_callback_verify
|
|
@@ -43,7 +43,7 @@ class TestRalipay < Test::Unit::TestCase
|
|
|
43
43
|
:sign_type => '0001'
|
|
44
44
|
}
|
|
45
45
|
assert_equal true,
|
|
46
|
-
Ralipay::
|
|
46
|
+
Ralipay::WapPayment.new(configs).callback_verify?(gets)
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
def test_notify_verify
|
|
@@ -67,7 +67,7 @@ class TestRalipay < Test::Unit::TestCase
|
|
|
67
67
|
:notify_data => 'Ych9Cg/zaLHsqaBePwoFtxAE7vX0ZvslWCLFTP1AdsxQgvrEcwflAFdbhIHgqsy8AZdRGp7rNeP1Bpn9v+feNlHD96RQit4p1/JHTAOfdoNmQsRaDvBNH9xUlCANXC4zTFDxCZEJN79ppSAzhOu1iMAdUOzim+ZAacxpkMfM4c+YSkpXrEK7kt3Lw4FpkJwwkRAUlYNtrlva94Qo6RZDmo4UpDlUyS1GkqIOihnwxzE4rDO84txzVWtdGDD+Il5ev7nVwnbcsaJzbhl7jgkg8+KzcoIibrn8QJy/xsSckwXZ2pq9Q2d+ufOd/zqpeUvTaD9nNbaH0UYZXDzKPnS91au6zk/2Nqe1d+TsNBeU7muQTM719y7btzfq6tRjs2eNdOfinIYK/MC0lypYtakHrIxpxqyKe1UlpyIVwUauKBkzmJP03x4FJOC7jsbVxI7N2Um/7qlAYCIzLog+SvjW3RX7dhjXAG72qJ93yrTySMJE4yvHEhSFfc2EgjepMzVlCNLwlENrvzkTiqs6rdrKmReKLr2D4QETC5qPL+v3S1iEdlPN4z0KKxp1RWzdwNfLtOceas+lx8oNM2AiQ4O0Y8+YDI/NX7xjckPzwPsEfNWYnwfLYb3MkbmIfhRVozQtsVI4VfxLX35bSQLVtKPdAM4foUIZFh0+HGM+qiSNtZQ2BWjmOUFvIdNyrxMzrRF2+BnuoP+lCkOvQdOnWNoBFpD8aUQrD48AJHQTeyf63bSeJ5Vdif/LPpeJjL+FkP/k+h6mcvigIo1ZcOoF9S2Gg20EgXZWggqR7RLnkroCaNbn/86gZsDQvtwn855n3PRQxosw8a/0F5uFIt/oD5zI7TDFv+p3q9SO3+GYaOwd6OHK3hS11kx2EpzYWw9PaFoANsER9r9buKvQDfcJDkxeN79qmP2zuznVq9OM5X9wDFy2WiFfyYl/swuvZN5e9Q2c0MXj9aeA2H464Am+iFOv1lBWGOlxyVsTQuFjRzRg4FIOp8cv0qOtI/UQPWGbGAy4qys7+sJN/wkboLpdWKLhwgPzto9TM0jN5GZMeA35+2wGcuPAe/SNqhvWM9r8xeCniuSDjesHWWN5bkiYzB4cb0n+E72Yh5WmwJw87ySuXAQWgONxnzgjX0LAGiinoBoufBqmpi/f8vAV3sJFEzkGZxFLSO1Us1ldSi16IqnPTdNtaQAe0N+QYnALM10rmsuGp4/jJatFWFMnmi06AMLcC31who0SD/xItGl6riSkX0yDqWQJzCvZUrrZJoqXJ7XBZoCQscL3Ug2RCKrGba/Ekc10EQINiX99XzYUPVK8xKxO4WW/7T00rZ8B1YjnUaBdWKGdmWmv0itnLx6rK8NWBw=='
|
|
68
68
|
}
|
|
69
69
|
assert_equal true,
|
|
70
|
-
Ralipay::
|
|
70
|
+
Ralipay::WapPayment.new(configs).notify_verify?(posts)
|
|
71
71
|
end
|
|
72
72
|
|
|
73
73
|
def test_para_filter
|