ralipay 0.0.1
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 +7 -0
- data/.gitignore +56 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +30 -0
- data/Rakefile +9 -0
- data/lib/ralipay/common.rb +73 -0
- data/lib/ralipay/service.rb +66 -0
- data/lib/ralipay/version.rb +3 -0
- data/lib/ralipay.rb +54 -0
- data/ralipay.gemspec +24 -0
- data/test/test_ralipay.rb +28 -0
- metadata +98 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 92c93ab20e355bf8784e72f991b4f591d05676e1
|
|
4
|
+
data.tar.gz: bbeb79dc378ec5ca941ba36d5986f6c5a47c0667
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 9d35832273a4bf5c129c95150ab22944425c6f6636f748df5fc839135181fff91d40ec9831f99d4db02242d4a82f5d0bb1cbf24fac7fc007f84b4b477daa4b9a
|
|
7
|
+
data.tar.gz: a0065daa00674ea782a3a71ad18cba8df30ee4625fa374ea5ca5082abc1f95bdd8983e657b68372656f13c6c88ea33df68f91e06a17232fa1a13df8669a85972
|
data/.gitignore
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
*.gem
|
|
2
|
+
*.rbc
|
|
3
|
+
.bundle
|
|
4
|
+
.config
|
|
5
|
+
.yardoc
|
|
6
|
+
Gemfile.lock
|
|
7
|
+
InstalledFiles
|
|
8
|
+
_yardoc
|
|
9
|
+
coverage
|
|
10
|
+
doc/
|
|
11
|
+
lib/bundler/man
|
|
12
|
+
pkg
|
|
13
|
+
rdoc
|
|
14
|
+
spec/reports
|
|
15
|
+
test/tmp
|
|
16
|
+
test/version_tmp
|
|
17
|
+
tmp
|
|
18
|
+
|
|
19
|
+
# Numerous always-ignore extensions
|
|
20
|
+
*.diff
|
|
21
|
+
*.err
|
|
22
|
+
*.orig
|
|
23
|
+
*.log
|
|
24
|
+
*.rej
|
|
25
|
+
*.swo
|
|
26
|
+
*.swp
|
|
27
|
+
*.vi
|
|
28
|
+
*~
|
|
29
|
+
*.sass-cache
|
|
30
|
+
|
|
31
|
+
# OS or Editor folders
|
|
32
|
+
.DS_Store
|
|
33
|
+
Thumbs.db
|
|
34
|
+
.cache
|
|
35
|
+
.project
|
|
36
|
+
.settings
|
|
37
|
+
.tmproj
|
|
38
|
+
*.esproj
|
|
39
|
+
nbproject
|
|
40
|
+
|
|
41
|
+
# Dreamweaver added files
|
|
42
|
+
_notes
|
|
43
|
+
dwsync.xml
|
|
44
|
+
|
|
45
|
+
# Komodo
|
|
46
|
+
*.komodoproject
|
|
47
|
+
.komodotools
|
|
48
|
+
|
|
49
|
+
# Folders to ignore
|
|
50
|
+
.hg
|
|
51
|
+
.svn
|
|
52
|
+
.CVS
|
|
53
|
+
intermediate
|
|
54
|
+
publish
|
|
55
|
+
.idea
|
|
56
|
+
*.png
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Copyright (c) 2013 RaymondChou
|
|
2
|
+
|
|
3
|
+
MIT License
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
+
a copy of this software and associated documentation files (the
|
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
11
|
+
the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be
|
|
14
|
+
included in all copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Ralipay
|
|
2
|
+
|
|
3
|
+
A ruby Gem for Alipay
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
Add this line to your application's Gemfile:
|
|
8
|
+
|
|
9
|
+
gem 'ralipay'
|
|
10
|
+
|
|
11
|
+
And then execute:
|
|
12
|
+
|
|
13
|
+
$ bundle
|
|
14
|
+
|
|
15
|
+
Or install it yourself as:
|
|
16
|
+
|
|
17
|
+
$ gem install ralipay
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
还没写
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
## Contributing
|
|
25
|
+
|
|
26
|
+
1. Fork it
|
|
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
|
data/Rakefile
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
module Ralipay::Common
|
|
2
|
+
|
|
3
|
+
require 'openssl'
|
|
4
|
+
require 'base64'
|
|
5
|
+
|
|
6
|
+
#生成签名结果
|
|
7
|
+
def self.build_sign(data_array)
|
|
8
|
+
#把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
|
|
9
|
+
for_sign_string = self.create_link_string(data_array)
|
|
10
|
+
#签名
|
|
11
|
+
if $global_configs[:secure_type] == 'RSA'
|
|
12
|
+
return self.rsa_sign(for_sign_string)
|
|
13
|
+
elsif $global_configs[:secure_type] == 'MD5'
|
|
14
|
+
return self.md5_sign(for_sign_string)
|
|
15
|
+
else
|
|
16
|
+
fail('------Unknown sign_type------')
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
#把数组所有元素,排序后按照“参数=参数值”的模式用“&”字符拼接成字符串
|
|
21
|
+
def self.create_link_string(hash)
|
|
22
|
+
result_string = ''
|
|
23
|
+
hash = hash.sort
|
|
24
|
+
hash.each{|key,value|
|
|
25
|
+
result_string += (key.to_s + '=' + value.to_s + '&')
|
|
26
|
+
}
|
|
27
|
+
#去掉末尾的&
|
|
28
|
+
result_string = result_string[0, result_string.length - 1]
|
|
29
|
+
return result_string
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
#RSA签名
|
|
33
|
+
def self.rsa_sign(for_sign_string)
|
|
34
|
+
#读取私钥文件
|
|
35
|
+
rsa_private_key_file = File.read($global_configs[:rsa_private_key_path])
|
|
36
|
+
#转换为openssl密钥
|
|
37
|
+
openssl_key = OpenSSL::PKey::RSA.new rsa_private_key_file
|
|
38
|
+
#使用openssl方法进行sha1签名digest(不能用sha256)
|
|
39
|
+
digest = OpenSSL::Digest::SHA1.new
|
|
40
|
+
signature = openssl_key.sign digest, for_sign_string
|
|
41
|
+
#base64编码
|
|
42
|
+
signature.gsub!("\n",'')
|
|
43
|
+
signature = Base64.encode64(signature)
|
|
44
|
+
signature.gsub!("\n",'')
|
|
45
|
+
return signature
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
#MD5签名
|
|
49
|
+
def self.md5_sign(for_sign_string)
|
|
50
|
+
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
#验签
|
|
54
|
+
def self.verify?(for_sign_string, signed_string)
|
|
55
|
+
#读取公钥文件
|
|
56
|
+
rsa_public_key_file = File.read($global_configs[:rsa_public_key_path])
|
|
57
|
+
openssl_public = OpenSSL::PKey::RSA.new rsa_public_key_file
|
|
58
|
+
digest = OpenSSL::Digest::SHA1.new
|
|
59
|
+
openssl_public.verify(digest, Base64.decode64(signed_string), for_sign_string)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
#除去数组中的空值和签名参数
|
|
63
|
+
def self.para_filter(paras = {})
|
|
64
|
+
new_paras = {}
|
|
65
|
+
paras.each{|key,value|
|
|
66
|
+
if key != :sign && key != :sign_type && value != '' && value != nil
|
|
67
|
+
new_paras[key] = value
|
|
68
|
+
end
|
|
69
|
+
}
|
|
70
|
+
return new_paras
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
require 'ralipay/common'
|
|
2
|
+
require 'uri'
|
|
3
|
+
require 'net/http'
|
|
4
|
+
require 'cgi'
|
|
5
|
+
require 'nokogiri'
|
|
6
|
+
|
|
7
|
+
include Ralipay::Common
|
|
8
|
+
|
|
9
|
+
class Service
|
|
10
|
+
|
|
11
|
+
@@gateway_pay_channel = 'https://mapi.alipay.com/cooperate/gateway.do?'
|
|
12
|
+
@@gateway_order = 'http://wappaygw.alipay.com/service/rest.htm?'
|
|
13
|
+
@@my_sign #签名结果
|
|
14
|
+
@@parameter #需要签名的hash
|
|
15
|
+
@@format #编码格式
|
|
16
|
+
@@req_data = '' #post请求数据
|
|
17
|
+
|
|
18
|
+
def initialize
|
|
19
|
+
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
#创建mobile_merchant_pay_channel接口
|
|
23
|
+
def mobile_merchant_pay_channel(parameter)
|
|
24
|
+
|
|
25
|
+
#除去数组中的空值和签名参数
|
|
26
|
+
@@parameter = Ralipay::Common::para_filter parameter
|
|
27
|
+
sort_array = @@parameter.sort
|
|
28
|
+
#生成签名
|
|
29
|
+
@@my_sign = Ralipay::Common::build_sign sort_array
|
|
30
|
+
#创建请求数据串
|
|
31
|
+
@@req_data = Ralipay::Common::create_link_string(@@parameter).to_s \
|
|
32
|
+
+ '&sign=' \
|
|
33
|
+
+ CGI::escape(@@my_sign) \
|
|
34
|
+
+ '&sign_type=' \
|
|
35
|
+
+ $sec_id
|
|
36
|
+
|
|
37
|
+
#请求支付宝接口
|
|
38
|
+
uri = URI.parse (@@gateway_pay_channel + @@req_data)
|
|
39
|
+
http = Net::HTTP.new uri.host, uri.port
|
|
40
|
+
http.use_ssl = true if uri.scheme == 'https'
|
|
41
|
+
path = uri.query.nil? ? uri.path : uri.path + '?' + uri.query
|
|
42
|
+
xml = http.get2(path).body
|
|
43
|
+
result = response_handle xml
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
#验签并反序列化Json数据
|
|
47
|
+
def response_handle xml
|
|
48
|
+
#解析xml
|
|
49
|
+
doc = Nokogiri::XML xml
|
|
50
|
+
json_result = doc.xpath('/alipay/response/alipay/result').text
|
|
51
|
+
ali_sign = doc.xpath('/alipay/sign').text
|
|
52
|
+
|
|
53
|
+
#转换待签名格式数据,因为此mapi接口统一都是用GBK编码的,所以要把默认UTF-8的编码转换成GBK,否则生成签名会不一致
|
|
54
|
+
for_sign_string = 'result=' + json_result
|
|
55
|
+
for_sign_string = for_sign_string.encode('GBK')
|
|
56
|
+
verify = Ralipay::Common::verify?(for_sign_string, ali_sign)
|
|
57
|
+
|
|
58
|
+
if verify == true
|
|
59
|
+
return json_result
|
|
60
|
+
else
|
|
61
|
+
fail('------verify fail------')
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
end
|
data/lib/ralipay.rb
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
module Ralipay
|
|
2
|
+
|
|
3
|
+
require 'ralipay/version'
|
|
4
|
+
require 'ralipay/common'
|
|
5
|
+
require 'ralipay/service'
|
|
6
|
+
|
|
7
|
+
include Ralipay::Common
|
|
8
|
+
|
|
9
|
+
class Payment
|
|
10
|
+
|
|
11
|
+
#传入参数,必须初始化
|
|
12
|
+
$global_configs = {
|
|
13
|
+
:secure_type => 'RSA',
|
|
14
|
+
:partner => '',
|
|
15
|
+
:seller_email => '',
|
|
16
|
+
:notify_url => '',
|
|
17
|
+
:call_back_url => '',
|
|
18
|
+
:merchant_url => '',
|
|
19
|
+
:subject => '',
|
|
20
|
+
:out_trade_no => '',
|
|
21
|
+
:total_fee => '',
|
|
22
|
+
:out_user => '',
|
|
23
|
+
:rsa_private_key_path => '',
|
|
24
|
+
:rsa_public_key_path => ''
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
#固定参数,无需修改
|
|
28
|
+
$service1 = 'alipay.wap.trade.create.direct'
|
|
29
|
+
$service2 = 'alipay.wap.auth.authAndExecute'
|
|
30
|
+
$format = 'xml'
|
|
31
|
+
$sec_id = '0001'
|
|
32
|
+
$input_charset = 'utf-8'
|
|
33
|
+
$input_charset_gbk = 'GBK'
|
|
34
|
+
$service_pay_channel = 'mobile.merchant.paychannel'
|
|
35
|
+
|
|
36
|
+
def initialize(configs)
|
|
37
|
+
#@todo 入参合法性验证
|
|
38
|
+
$global_configs = $global_configs.merge configs
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def generate_wap_pay_url
|
|
42
|
+
params = {
|
|
43
|
+
:_input_charset => $input_charset_gbk,
|
|
44
|
+
:sign_type => $sec_id,
|
|
45
|
+
:service => $service_pay_channel,
|
|
46
|
+
:partner => $global_configs[:partner],
|
|
47
|
+
:out_user => ''
|
|
48
|
+
}
|
|
49
|
+
Service.new.mobile_merchant_pay_channel params
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
end
|
data/ralipay.gemspec
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
require 'ralipay/version'
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |spec|
|
|
7
|
+
spec.name = "ralipay"
|
|
8
|
+
spec.version = Ralipay::VERSION
|
|
9
|
+
spec.authors = ["RaymondChou"]
|
|
10
|
+
spec.email = ["freezestart@gmail.com"]
|
|
11
|
+
spec.description = "A Gem for alipay,contains web payment and mobile payment"
|
|
12
|
+
spec.summary = "A Gem for alipay"
|
|
13
|
+
spec.homepage = "http://ledbk.com"
|
|
14
|
+
spec.license = "MIT"
|
|
15
|
+
|
|
16
|
+
spec.files = `git ls-files`.split($/)
|
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
19
|
+
spec.require_paths = ["lib"]
|
|
20
|
+
|
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
|
22
|
+
spec.add_development_dependency "rake"
|
|
23
|
+
spec.add_development_dependency "nokogiri"
|
|
24
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require 'test/unit'
|
|
2
|
+
require 'ralipay'
|
|
3
|
+
|
|
4
|
+
class TestRalipay < Test::Unit::TestCase
|
|
5
|
+
|
|
6
|
+
def test_generate_wap_pay_url
|
|
7
|
+
configs = {
|
|
8
|
+
:partner => '2088701817081672',
|
|
9
|
+
:rsa_private_key_path => '/Users/masonwoo/Desktop/rsa_private_key.pem',
|
|
10
|
+
:rsa_public_key_path => '/Users/masonwoo/Desktop/alipay_public_key.pem'
|
|
11
|
+
}
|
|
12
|
+
assert_equal "test",
|
|
13
|
+
Ralipay::Payment.new(configs).generate_wap_pay_url
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def test_para_filter
|
|
17
|
+
input_para = {:a => 'abc', :sign_type => 'abc', :c => '', :d => nil}
|
|
18
|
+
assert_equal ({:a => 'abc'}),
|
|
19
|
+
Ralipay::Common::para_filter(input_para)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def test_create_link_string
|
|
23
|
+
input_para = {:a => 'abc', :x => 'abcd', :s => '', :d => nil}
|
|
24
|
+
assert_equal 'a=abc&d=&s=&x=abcd',
|
|
25
|
+
Ralipay::Common::create_link_string(input_para)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: ralipay
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- RaymondChou
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2013-03-22 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: bundler
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ~>
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '1.3'
|
|
20
|
+
type: :development
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ~>
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '1.3'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: rake
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - '>='
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0'
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - '>='
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: nokogiri
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - '>='
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '0'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - '>='
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0'
|
|
55
|
+
description: A Gem for alipay,contains web payment and mobile payment
|
|
56
|
+
email:
|
|
57
|
+
- freezestart@gmail.com
|
|
58
|
+
executables: []
|
|
59
|
+
extensions: []
|
|
60
|
+
extra_rdoc_files: []
|
|
61
|
+
files:
|
|
62
|
+
- .gitignore
|
|
63
|
+
- Gemfile
|
|
64
|
+
- LICENSE.txt
|
|
65
|
+
- README.md
|
|
66
|
+
- Rakefile
|
|
67
|
+
- lib/ralipay.rb
|
|
68
|
+
- lib/ralipay/common.rb
|
|
69
|
+
- lib/ralipay/service.rb
|
|
70
|
+
- lib/ralipay/version.rb
|
|
71
|
+
- ralipay.gemspec
|
|
72
|
+
- test/test_ralipay.rb
|
|
73
|
+
homepage: http://ledbk.com
|
|
74
|
+
licenses:
|
|
75
|
+
- MIT
|
|
76
|
+
metadata: {}
|
|
77
|
+
post_install_message:
|
|
78
|
+
rdoc_options: []
|
|
79
|
+
require_paths:
|
|
80
|
+
- lib
|
|
81
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
82
|
+
requirements:
|
|
83
|
+
- - '>='
|
|
84
|
+
- !ruby/object:Gem::Version
|
|
85
|
+
version: '0'
|
|
86
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
87
|
+
requirements:
|
|
88
|
+
- - '>='
|
|
89
|
+
- !ruby/object:Gem::Version
|
|
90
|
+
version: '0'
|
|
91
|
+
requirements: []
|
|
92
|
+
rubyforge_project:
|
|
93
|
+
rubygems_version: 2.0.3
|
|
94
|
+
signing_key:
|
|
95
|
+
specification_version: 4
|
|
96
|
+
summary: A Gem for alipay
|
|
97
|
+
test_files:
|
|
98
|
+
- test/test_ralipay.rb
|