yl_alipay 0.15.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 +7 -0
- data/.gitignore +18 -0
- data/.travis.yml +5 -0
- data/CHANGELOG.md +101 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +810 -0
- data/Rakefile +9 -0
- data/alipay.gemspec +25 -0
- data/lib/alipay/app/service.rb +57 -0
- data/lib/alipay/app/sign.rb +36 -0
- data/lib/alipay/mobile/service.rb +27 -0
- data/lib/alipay/mobile/sign.rb +9 -0
- data/lib/alipay/notify.rb +19 -0
- data/lib/alipay/service.rb +239 -0
- data/lib/alipay/sign/dsa.rb +13 -0
- data/lib/alipay/sign/md5.rb +15 -0
- data/lib/alipay/sign/rsa.rb +18 -0
- data/lib/alipay/sign/rsa2.rb +18 -0
- data/lib/alipay/sign.rb +54 -0
- data/lib/alipay/utils.rb +19 -0
- data/lib/alipay/version.rb +3 -0
- data/lib/alipay/wap/notify.rb +13 -0
- data/lib/alipay/wap/service.rb +84 -0
- data/lib/alipay/wap/sign.rb +37 -0
- data/lib/alipay.rb +31 -0
- data/lib/yl_alipay.rb +1 -0
- data/test/alipay/app/service_test.rb +32 -0
- data/test/alipay/app/sign_test.rb +37 -0
- data/test/alipay/mobile/service_test.rb +16 -0
- data/test/alipay/mobile/sign_test.rb +7 -0
- data/test/alipay/notify_test.rb +35 -0
- data/test/alipay/service_test.rb +265 -0
- data/test/alipay/sign/md5_test.rb +20 -0
- data/test/alipay/sign/rsa2_test.rb +22 -0
- data/test/alipay/sign/rsa_test.rb +20 -0
- data/test/alipay/sign_test.rb +30 -0
- data/test/alipay/utils_test.rb +12 -0
- data/test/alipay/wap/notify_test.rb +38 -0
- data/test/alipay/wap/service_test.rb +67 -0
- data/test/alipay/wap/sign_test.rb +19 -0
- data/test/alipay_test.rb +11 -0
- data/test/test_helper.rb +34 -0
- data/yl_alipay.gemspec +25 -0
- metadata +159 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
module Alipay
|
|
2
|
+
module Wap
|
|
3
|
+
module Sign
|
|
4
|
+
ALIPAY_RSA_PUBLIC_KEY = <<-EOF
|
|
5
|
+
-----BEGIN PUBLIC KEY-----
|
|
6
|
+
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCQwpCPC4oB+clYNBkKQx3gfyFl
|
|
7
|
+
Ut3cpRr5oErt OypLKh6j1UmTDSpfsac29h1kC0HIvLmxWbPuoxcsKDlclgRPeWn
|
|
8
|
+
IxrpSF9k5Fu6SRy3+AOdIKrDO SHQ7VwUsNih2OnPbztMSMplGnQCBa1iec2r+38
|
|
9
|
+
Udmh5Ua2xg6IEfk493VQIDAQAB
|
|
10
|
+
-----END PUBLIC KEY-----
|
|
11
|
+
EOF
|
|
12
|
+
|
|
13
|
+
def self.verify?(params, options = {})
|
|
14
|
+
params = Utils.stringify_keys(params)
|
|
15
|
+
sign = params.delete('sign')
|
|
16
|
+
string = params_to_string(params)
|
|
17
|
+
|
|
18
|
+
case params['sec_id']
|
|
19
|
+
when 'MD5'
|
|
20
|
+
key = options[:key] || Alipay.key
|
|
21
|
+
::Alipay::Sign::MD5.verify?(key, string, sign)
|
|
22
|
+
when '0001' # RSA
|
|
23
|
+
::Alipay::Sign::RSA.verify?(ALIPAY_RSA_PUBLIC_KEY, string, sign)
|
|
24
|
+
else
|
|
25
|
+
false
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
SORTED_VERIFY_PARAMS = %w( service v sec_id notify_data )
|
|
30
|
+
def self.params_to_string(params)
|
|
31
|
+
SORTED_VERIFY_PARAMS.map do |key|
|
|
32
|
+
"#{key}=#{params[key]}"
|
|
33
|
+
end.join('&')
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
data/lib/alipay.rb
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
require 'net/http'
|
|
2
|
+
require 'cgi'
|
|
3
|
+
require 'alipay/version'
|
|
4
|
+
require 'alipay/utils'
|
|
5
|
+
require 'alipay/sign'
|
|
6
|
+
require 'alipay/sign/md5'
|
|
7
|
+
require 'alipay/sign/rsa'
|
|
8
|
+
require 'alipay/sign/rsa2'
|
|
9
|
+
require 'alipay/sign/dsa'
|
|
10
|
+
require 'alipay/service'
|
|
11
|
+
require 'alipay/notify'
|
|
12
|
+
require 'alipay/wap/service'
|
|
13
|
+
require 'alipay/wap/notify'
|
|
14
|
+
require 'alipay/wap/sign'
|
|
15
|
+
require 'alipay/mobile/service'
|
|
16
|
+
require 'alipay/mobile/sign'
|
|
17
|
+
require 'alipay/app/service'
|
|
18
|
+
require 'alipay/app/sign'
|
|
19
|
+
|
|
20
|
+
module Alipay
|
|
21
|
+
@debug_mode = true
|
|
22
|
+
@sign_type = 'MD5'
|
|
23
|
+
|
|
24
|
+
class << self
|
|
25
|
+
attr_accessor :pid, :key, :sign_type, :debug_mode
|
|
26
|
+
|
|
27
|
+
def debug_mode?
|
|
28
|
+
!!@debug_mode
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
data/lib/yl_alipay.rb
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require 'alipay'
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class Alipay::Mobile::ServiceTest < Minitest::Test
|
|
4
|
+
def setup
|
|
5
|
+
@params = {
|
|
6
|
+
app_id: '2016000000000000',
|
|
7
|
+
biz_content: {
|
|
8
|
+
timeout_express: "30m",
|
|
9
|
+
seller_id: "",
|
|
10
|
+
product_code: "QUICK_MSECURITY_PAY",
|
|
11
|
+
total_amount: "0.01",
|
|
12
|
+
subject: "1",
|
|
13
|
+
body: "测试数据",
|
|
14
|
+
out_trade_no: "10000000"
|
|
15
|
+
}.to_json,
|
|
16
|
+
charset: 'utf-8',
|
|
17
|
+
format: 'json',
|
|
18
|
+
method: 'alipay.trade.app.pay',
|
|
19
|
+
notify_url: 'http://example.com/notify',
|
|
20
|
+
timestamp: '2016-08-25 20:26:31',
|
|
21
|
+
version: '1.0'
|
|
22
|
+
}
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def test_alipay_trade_app_pay_with_rsa
|
|
26
|
+
assert_equal 'app_id=2016000000000000&biz_content=%7B%22timeout_express%22%3A%2230m%22%2C%22seller_id%22%3A%22%22%2C%22product_code%22%3A%22QUICK_MSECURITY_PAY%22%2C%22total_amount%22%3A%220.01%22%2C%22subject%22%3A%221%22%2C%22body%22%3A%22%E6%B5%8B%E8%AF%95%E6%95%B0%E6%8D%AE%22%2C%22out_trade_no%22%3A%2210000000%22%7D&charset=utf-8&format=json&method=alipay.trade.app.pay¬ify_url=http%3A%2F%2Fexample.com%2Fnotify&sign=Cvie7tAzUCH1JF7gVM2jMuEJ2%2FdHGWQesyl4MyV6MWnTeGzWhB4fgCJ%2B7EbdurHfiOVRpnGZkYc6twoWP53P2S6K4fp%2BazUJLVBgpSFy9ufn9Sf4BLpWMeOOEt5ufWdoWxWALhTbeEZnZReTDR1S%2FEXKw%2FTdjMWc3Q0kcG4ARzQ%3D&sign_type=RSA×tamp=2016-08-25%2020%3A26%3A31&version=1.0', Alipay::App::Service.alipay_trade_app_pay(@params, sign_type: 'RSA' , key: TEST_RSA_PRIVATE_KEY)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def test_alipay_trade_app_pay_with_rsa2
|
|
30
|
+
assert_equal 'app_id=2016000000000000&biz_content=%7B%22timeout_express%22%3A%2230m%22%2C%22seller_id%22%3A%22%22%2C%22product_code%22%3A%22QUICK_MSECURITY_PAY%22%2C%22total_amount%22%3A%220.01%22%2C%22subject%22%3A%221%22%2C%22body%22%3A%22%E6%B5%8B%E8%AF%95%E6%95%B0%E6%8D%AE%22%2C%22out_trade_no%22%3A%2210000000%22%7D&charset=utf-8&format=json&method=alipay.trade.app.pay¬ify_url=http%3A%2F%2Fexample.com%2Fnotify&sign=fRBLfmUFXDRWW%2BtWD7BQlv8uymKU7Ky8TQKLF%2FnGkUsdCXnZ0MbqLFXAoE4Il6464n9YKncJhG50aDZ4s4HxpMMCku55so99nPkf3Uoksmje5Z5zSZusxnUHl5o7zf21%2BIOOf5mJzA%2Fp4BGZqFK00CoM07Ye9tSV%2Fid1hT8MbxA%3D&sign_type=RSA2×tamp=2016-08-25%2020%3A26%3A31&version=1.0', Alipay::App::Service.alipay_trade_app_pay(@params, sign_type: 'RSA2' , key: TEST_RSA_PRIVATE_KEY)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
require 'base64'
|
|
3
|
+
|
|
4
|
+
class Alipay::App::SignTest < Minitest::Test
|
|
5
|
+
def setup
|
|
6
|
+
@params = {
|
|
7
|
+
biz_content: {:name=>'顺道'}.to_json,
|
|
8
|
+
out_trade_no: 'MEM1234567',
|
|
9
|
+
total_amount: '0.01'
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def test_params_to_sorted_string
|
|
15
|
+
assert_equal 'a=2&b=1', Alipay::App::Sign.params_to_sorted_string(b: 1, a: 2)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def test_params_to_encoded_string
|
|
19
|
+
assert_equal 'biz_content=%7B%22name%22%3A%22%E9%A1%BA%E9%81%93%22%7D&out_trade_no=MEM1234567&total_amount=0.01', Alipay::App::Sign.params_to_encoded_string(@params)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def test_verify_with_rsa2
|
|
23
|
+
sign = 'c1R7jXEzg/gMzCEwqBcrYf1EliSQEVyC2JaCt9AUkRqpxIQGeRAjA18gid3/ubFQn0vWC8ajNB0veyy7g7wlbi/gM/6S3qZpkLP5n+vgLG5v84IHVIHeQIf7a/U3olW2fFg9IonEr8ohIMYZD5IB89j+supMvtyPHhWHVal2N9k='
|
|
24
|
+
assert Alipay::App::Sign.verify?(@params.merge(sign: sign, sign_type: 'RSA2'),
|
|
25
|
+
sign_type: :rsa2,
|
|
26
|
+
key: TEST_RSA_PUBLIC_KEY
|
|
27
|
+
)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def test_verify_with_rsa
|
|
31
|
+
sign = 'l+vXVjKLNqtCMAHDgaLdWZaUkjyKEfp85K3GzRx7HJnxdxHhF4MHh2AJdnzLdnp653BnGtPs8SBC/25D2edZdho0+6q+d8RJw0ZiDmZAg7WRP5rq7nB1/SBaH6hLgp8HXL6Uqwo42Rik3I4Ecw9u7uK1spt/Ph4vzZJBq5QMc9I='
|
|
32
|
+
assert Alipay::App::Sign.verify?(@params.merge(sign: sign, sign_type: 'RSA'),
|
|
33
|
+
sign_type: :rsa,
|
|
34
|
+
key: TEST_RSA_PUBLIC_KEY
|
|
35
|
+
)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class Alipay::Mobile::ServiceTest < Minitest::Test
|
|
4
|
+
def test_mobile_securitypay_pay_string
|
|
5
|
+
assert_equal %q(service="mobile.securitypay.pay"&_input_charset="utf-8"&partner="1000000000000000"&seller_id="1000000000000000"&payment_type="1"&out_trade_no="1"¬ify_url="/some_url"&subject="subject"&total_fee="0.01"&body="test"&sign="if1qjK4qnT7eQ5fw%2BBddHhO1LY6iuPY9Xmhkx81YKuCdceKWBdv798j%2BrxF9ZAhNW4Y3TMURm%2BXpgxhOh8lj8vorFup%2BMJ6fe2rXRWgxFhK9B8xuP2XH%2F3878g6d8Jq2D2gINTgDDL7%2BB5%2FIWWlwInas40cQTsVngG8mWkzB788%3D"&sign_type="RSA"), Alipay::Mobile::Service.mobile_securitypay_pay_string({
|
|
6
|
+
out_trade_no: '1',
|
|
7
|
+
notify_url: '/some_url',
|
|
8
|
+
subject: 'subject',
|
|
9
|
+
total_fee: '0.01',
|
|
10
|
+
body: 'test'
|
|
11
|
+
}, {
|
|
12
|
+
sign_type: 'RSA',
|
|
13
|
+
key: TEST_RSA_PRIVATE_KEY
|
|
14
|
+
})
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class Alipay::NotifyTest < Minitest::Test
|
|
4
|
+
def setup
|
|
5
|
+
@params = {
|
|
6
|
+
notify_id: '1234',
|
|
7
|
+
}
|
|
8
|
+
@unsign_params = @params.merge(sign_type: 'MD5', sign: 'xxxx')
|
|
9
|
+
@sign_params = @params.merge(
|
|
10
|
+
sign_type: 'MD5',
|
|
11
|
+
sign: '22fc7e38e5acdfede396aa463870d111'
|
|
12
|
+
)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def test_unsign_notify
|
|
16
|
+
stub_request(
|
|
17
|
+
:get, "https://mapi.alipay.com/gateway.do?service=notify_verify&partner=#{Alipay.pid}¬ify_id=1234"
|
|
18
|
+
).to_return(body: "true")
|
|
19
|
+
assert !Alipay::Notify.verify?(@unsign_params)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def test_verify_notify_when_true
|
|
23
|
+
stub_request(
|
|
24
|
+
:get, "https://mapi.alipay.com/gateway.do?service=notify_verify&partner=#{Alipay.pid}¬ify_id=1234"
|
|
25
|
+
).to_return(body: "true")
|
|
26
|
+
assert Alipay::Notify.verify?(@sign_params)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def test_verify_notify_when_false
|
|
30
|
+
stub_request(
|
|
31
|
+
:get, "https://mapi.alipay.com/gateway.do?service=notify_verify&partner=#{Alipay.pid}¬ify_id=1234"
|
|
32
|
+
).to_return(body: "false")
|
|
33
|
+
assert !Alipay::Notify.verify?(@sign_params)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class Alipay::ServiceTest < Minitest::Test
|
|
4
|
+
def test_generate_create_partner_trade_by_buyer_url
|
|
5
|
+
options = {
|
|
6
|
+
out_trade_no: '1',
|
|
7
|
+
subject: 'test',
|
|
8
|
+
logistics_type: 'POST',
|
|
9
|
+
logistics_fee: '0',
|
|
10
|
+
logistics_payment: 'SELLER_PAY',
|
|
11
|
+
price: '0.01',
|
|
12
|
+
quantity: 1
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
assert_equal 'https://mapi.alipay.com/gateway.do?service=create_partner_trade_by_buyer&_input_charset=utf-8&partner=1000000000000000&seller_id=1000000000000000&payment_type=1&out_trade_no=1&subject=test&logistics_type=POST&logistics_fee=0&logistics_payment=SELLER_PAY&price=0.01&quantity=1&sign_type=MD5&sign=b5d30863b44acd8514a49b0320fb2aa2', Alipay::Service.create_partner_trade_by_buyer_url(options)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def test_generate_trade_create_by_buyer_url
|
|
19
|
+
options = {
|
|
20
|
+
out_trade_no: '1',
|
|
21
|
+
subject: 'test',
|
|
22
|
+
logistics_type: 'POST',
|
|
23
|
+
logistics_fee: '0',
|
|
24
|
+
logistics_payment: 'SELLER_PAY',
|
|
25
|
+
price: '0.01',
|
|
26
|
+
quantity: 1
|
|
27
|
+
}
|
|
28
|
+
assert_equal 'https://mapi.alipay.com/gateway.do?service=trade_create_by_buyer&_input_charset=utf-8&partner=1000000000000000&seller_id=1000000000000000&payment_type=1&out_trade_no=1&subject=test&logistics_type=POST&logistics_fee=0&logistics_payment=SELLER_PAY&price=0.01&quantity=1&sign_type=MD5&sign=2d296368fea70a127da939558c970bab', Alipay::Service.trade_create_by_buyer_url(options)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def test_generate_create_direct_pay_by_user_url
|
|
32
|
+
options = {
|
|
33
|
+
out_trade_no: '1',
|
|
34
|
+
subject: 'test',
|
|
35
|
+
price: '0.01',
|
|
36
|
+
quantity: 1
|
|
37
|
+
}
|
|
38
|
+
assert_equal 'https://mapi.alipay.com/gateway.do?service=create_direct_pay_by_user&_input_charset=utf-8&partner=1000000000000000&seller_id=1000000000000000&payment_type=1&out_trade_no=1&subject=test&price=0.01&quantity=1&sign_type=MD5&sign=682ad02280fca7d4c0fd22678fdddeef', Alipay::Service.create_direct_pay_by_user_url(options)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def test_generate_create_direct_pay_by_user_wap_url
|
|
42
|
+
options = {
|
|
43
|
+
out_trade_no: '1',
|
|
44
|
+
subject: 'test',
|
|
45
|
+
total_fee: '0.01'
|
|
46
|
+
}
|
|
47
|
+
assert_equal 'https://mapi.alipay.com/gateway.do?service=alipay.wap.create.direct.pay.by.user&_input_charset=utf-8&partner=1000000000000000&seller_id=1000000000000000&payment_type=1&out_trade_no=1&subject=test&total_fee=0.01&sign_type=MD5&sign=6530de6e3cba153cd4ca7edc48b91f96', Alipay::Service.create_direct_pay_by_user_wap_url(options)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def test_refund_fastpay_by_platform_pwd_url
|
|
51
|
+
data = [{
|
|
52
|
+
trade_no: '1',
|
|
53
|
+
amount: '0.01',
|
|
54
|
+
reason: 'test'
|
|
55
|
+
}]
|
|
56
|
+
options = {
|
|
57
|
+
batch_no: '123456789',
|
|
58
|
+
data: data,
|
|
59
|
+
notify_url: '/some_url',
|
|
60
|
+
refund_date: '2015-01-01 00:00:00'
|
|
61
|
+
}
|
|
62
|
+
assert_equal 'https://mapi.alipay.com/gateway.do?service=refund_fastpay_by_platform_pwd&_input_charset=utf-8&partner=1000000000000000&seller_user_id=1000000000000000&refund_date=2015-01-01+00%3A00%3A00&batch_num=1&detail_data=1%5E0.01%5Etest&batch_no=123456789¬ify_url=%2Fsome_url&sign_type=MD5&sign=def57a58e1ac21f70c45e41bd3697368', Alipay::Service.refund_fastpay_by_platform_pwd_url(options)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def test_forex_refund_url
|
|
66
|
+
options = {
|
|
67
|
+
out_return_no: '1',
|
|
68
|
+
out_trade_no: '12345678980',
|
|
69
|
+
return_amount: '0.01',
|
|
70
|
+
currency: 'USD',
|
|
71
|
+
reason: 'reason',
|
|
72
|
+
gmt_return: '20150101000000'
|
|
73
|
+
}
|
|
74
|
+
assert_equal 'https://mapi.alipay.com/gateway.do?service=forex_refund&partner=1000000000000000&_input_charset=utf-8&gmt_return=20150101000000&out_return_no=1&out_trade_no=12345678980&return_amount=0.01¤cy=USD&reason=reason&sign_type=MD5&sign=c9681fff5505fe993d1b2b8141308d0d', Alipay::Service.forex_refund_url(options)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def test_generate_create_forex_trade_url
|
|
78
|
+
options = {
|
|
79
|
+
notify_url: 'https://example.com/notify',
|
|
80
|
+
subject: 'test',
|
|
81
|
+
out_trade_no: '1',
|
|
82
|
+
currency: 'EUR',
|
|
83
|
+
total_fee: '0.01',
|
|
84
|
+
}
|
|
85
|
+
assert_equal 'https://mapi.alipay.com/gateway.do?service=create_forex_trade&_input_charset=utf-8&partner=1000000000000000¬ify_url=https%3A%2F%2Fexample.com%2Fnotify&subject=test&out_trade_no=1¤cy=EUR&total_fee=0.01&sign_type=MD5&sign=f24fd4d76acabf860263a40805138380', Alipay::Service.create_forex_trade_url(options)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def test_close_trade
|
|
89
|
+
response_body = <<-EOF
|
|
90
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
91
|
+
<alipay>
|
|
92
|
+
<is_success>T</is_success>
|
|
93
|
+
</alipay>
|
|
94
|
+
EOF
|
|
95
|
+
stub_request(
|
|
96
|
+
:get,
|
|
97
|
+
%r|https://mapi\.alipay\.com/gateway\.do.*|
|
|
98
|
+
).to_return(body: response_body)
|
|
99
|
+
|
|
100
|
+
assert_equal response_body, Alipay::Service.close_trade(
|
|
101
|
+
out_order_no: '1'
|
|
102
|
+
)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def test_single_trade_query
|
|
106
|
+
response_body = <<-EOF
|
|
107
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
108
|
+
<alipay>
|
|
109
|
+
<is_success>T</is_success>
|
|
110
|
+
<request>
|
|
111
|
+
<param name="trade_no">20150123123123</param>
|
|
112
|
+
<param name="_input_charset">utf-8</param>
|
|
113
|
+
<param name="service">single_trade_query</param>
|
|
114
|
+
<param name="partner">PARTNER</param>
|
|
115
|
+
</request>
|
|
116
|
+
<response>
|
|
117
|
+
<trade>
|
|
118
|
+
<additional_trade_status>DAEMON_CONFIRM_CLOSE</additional_trade_status>
|
|
119
|
+
<buyer_email>buyer@example.com</buyer_email>
|
|
120
|
+
<buyer_id>BUYER_ID</buyer_id>
|
|
121
|
+
<discount>0.00</discount>
|
|
122
|
+
<flag_trade_locked>0</flag_trade_locked>
|
|
123
|
+
<gmt_close>2015-01-20 02:37:00</gmt_close>
|
|
124
|
+
<gmt_create>2015-01-20 02:17:00</gmt_create>
|
|
125
|
+
<gmt_last_modified_time>2015-01-20 02:37:00</gmt_last_modified_time>
|
|
126
|
+
<is_total_fee_adjust>F</is_total_fee_adjust>
|
|
127
|
+
<operator_role>B</operator_role>
|
|
128
|
+
<out_trade_no>1</out_trade_no>
|
|
129
|
+
<payment_type>1</payment_type>
|
|
130
|
+
<price>640.00</price>
|
|
131
|
+
<quantity>1</quantity>
|
|
132
|
+
<seller_email>seller@example.com</seller_email>
|
|
133
|
+
<seller_id>SELLER_ID</seller_id>
|
|
134
|
+
<subject>ORDER SUBJECT</subject>
|
|
135
|
+
<to_buyer_fee>0.00</to_buyer_fee>
|
|
136
|
+
<to_seller_fee>0.00</to_seller_fee>
|
|
137
|
+
<total_fee>640.00</total_fee>
|
|
138
|
+
<trade_no>TRADE_NO</trade_no>
|
|
139
|
+
<trade_status>TRADE_CLOSED</trade_status>
|
|
140
|
+
<use_coupon>F</use_coupon>
|
|
141
|
+
</trade></response>
|
|
142
|
+
<sign>SIGN</sign>
|
|
143
|
+
<sign_type>MD5</sign_type>
|
|
144
|
+
</alipay>
|
|
145
|
+
EOF
|
|
146
|
+
stub_request(
|
|
147
|
+
:get,
|
|
148
|
+
%r|https://mapi\.alipay\.com/gateway\.do.*|
|
|
149
|
+
).to_return(body: response_body)
|
|
150
|
+
|
|
151
|
+
assert_equal response_body, Alipay::Service.single_trade_query(
|
|
152
|
+
out_trade_no: '1'
|
|
153
|
+
)
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def test_should_send_goods_confirm_by_platform
|
|
157
|
+
body = <<-EOF
|
|
158
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
159
|
+
<alipay>
|
|
160
|
+
<is_success>T</is_success>
|
|
161
|
+
</alipay>
|
|
162
|
+
EOF
|
|
163
|
+
stub_request(
|
|
164
|
+
:get,
|
|
165
|
+
%r|https://mapi\.alipay\.com/gateway\.do.*|
|
|
166
|
+
).to_return(body: body)
|
|
167
|
+
|
|
168
|
+
assert_equal body, Alipay::Service.send_goods_confirm_by_platform(
|
|
169
|
+
trade_no: 'trade_no',
|
|
170
|
+
logistics_name: 'example.com',
|
|
171
|
+
transport_type: 'DIRECT'
|
|
172
|
+
)
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def test_account_page_query
|
|
176
|
+
body = <<-EOF
|
|
177
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
178
|
+
<alipay>
|
|
179
|
+
<is_success>T</is_success>
|
|
180
|
+
<request>
|
|
181
|
+
<param name="sign">sign_data</param>
|
|
182
|
+
<param name="_input_charset">utf-8</param>
|
|
183
|
+
<param name="gmt_end_time">2015-10-26 06:20:29</param>
|
|
184
|
+
<param name="sign_type">MD5</param>
|
|
185
|
+
<param name="service">account.page.query</param>
|
|
186
|
+
<param name="partner">2088123123</param>
|
|
187
|
+
<param name="page_no">1</param>
|
|
188
|
+
<param name="gmt_start_time">2015-10-25 06:20:29</param>
|
|
189
|
+
</request>
|
|
190
|
+
<response>
|
|
191
|
+
<account_page_query_result>
|
|
192
|
+
<account_log_list>
|
|
193
|
+
<AccountQueryAccountLogVO>
|
|
194
|
+
<balance>1234</balance>
|
|
195
|
+
<buyer_account>2088123123</buyer_account>
|
|
196
|
+
<currency>123</currency>
|
|
197
|
+
<deposit_bank_no>20151025123123</deposit_bank_no>
|
|
198
|
+
<goods_title>商品名称</goods_title>
|
|
199
|
+
<income>100.00</income>
|
|
200
|
+
<iw_account_log_id>12345678910</iw_account_log_id>
|
|
201
|
+
<memo> </memo>
|
|
202
|
+
<merchant_out_order_no>1234567</merchant_out_order_no>
|
|
203
|
+
<outcome>0.00</outcome>
|
|
204
|
+
<partner_id>2088123123</partner_id>
|
|
205
|
+
<rate>0.015</rate>
|
|
206
|
+
<seller_account>2088123123123</seller_account>
|
|
207
|
+
<seller_fullname>xxxx有限公司</seller_fullname>
|
|
208
|
+
<service_fee>0.00</service_fee>
|
|
209
|
+
<service_fee_ratio> </service_fee_ratio>
|
|
210
|
+
<sign_product_name>快捷手机安全支付</sign_product_name>
|
|
211
|
+
<sub_trans_code_msg>快速支付,支付给个人,支付宝帐户全额</sub_trans_code_msg>
|
|
212
|
+
<total_fee>100.00</total_fee>
|
|
213
|
+
<trade_no>20151025123123</trade_no>
|
|
214
|
+
<trade_refund_amount>0.00</trade_refund_amount>
|
|
215
|
+
<trans_code_msg>在线支付</trans_code_msg>
|
|
216
|
+
<trans_date>2015-10-25 06:33:07</trans_date>
|
|
217
|
+
</AccountQueryAccountLogVO>
|
|
218
|
+
</account_log_list>
|
|
219
|
+
<has_next_page>F</has_next_page>
|
|
220
|
+
<page_no>1</page_no>
|
|
221
|
+
<page_size>5000</page_size>
|
|
222
|
+
</account_page_query_result>
|
|
223
|
+
</response>
|
|
224
|
+
<sign>sign_data</sign>
|
|
225
|
+
<sign_type>MD5</sign_type>
|
|
226
|
+
</alipay>
|
|
227
|
+
EOF
|
|
228
|
+
stub_request(
|
|
229
|
+
:get, %r|https://mapi\.alipay\.com/gateway\.do.*|
|
|
230
|
+
).to_return(:body => body)
|
|
231
|
+
assert_equal body, Alipay::Service.account_page_query(
|
|
232
|
+
page_no: 1,
|
|
233
|
+
gmt_start_time: (Time.now - 1).strftime('%Y-%m-%d %H:%M:%S'),
|
|
234
|
+
gmt_end_time: Time.now.strftime('%Y-%m-%d %H:%M:%S')
|
|
235
|
+
)
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
def test_create_forex_trade_wap_url
|
|
239
|
+
options = {
|
|
240
|
+
out_trade_no: '20150401000-0001',
|
|
241
|
+
subject: 'Order Name',
|
|
242
|
+
merchant_url: 'http://example.com/itemback',
|
|
243
|
+
total_fee: '10.00', #or rmb_fee, only one
|
|
244
|
+
currency: 'USD',
|
|
245
|
+
return_url: 'https://example.com/orders/20150401000-0001',
|
|
246
|
+
notify_url: 'https://example.com/orders/20150401000-0001/notify'
|
|
247
|
+
}
|
|
248
|
+
assert_equal 'https://mapi.alipay.com/gateway.do?service=create_forex_trade_wap&_input_charset=utf-8&partner=1000000000000000&seller_id=1000000000000000&out_trade_no=20150401000-0001&subject=Order+Name&merchant_url=http%3A%2F%2Fexample.com%2Fitemback&total_fee=10.00¤cy=USD&return_url=https%3A%2F%2Fexample.com%2Forders%2F20150401000-0001¬ify_url=https%3A%2F%2Fexample.com%2Forders%2F20150401000-0001%2Fnotify&sign_type=MD5&sign=f15d9e3d885c12f1a994048342c07bef', Alipay::Service.create_forex_trade_wap_url(options)
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
def test_batch_trans_notify_url
|
|
252
|
+
options = {
|
|
253
|
+
notify_url: 'https://example.com/orders/20150401000-0001/notify',
|
|
254
|
+
account_name: '毛毛',
|
|
255
|
+
detail_data: '0315006^testture0002@126.com^常炜买家^1000.00^hello',
|
|
256
|
+
batch_no: '20080107001',
|
|
257
|
+
batch_num: 1,
|
|
258
|
+
batch_fee: 1000.00,
|
|
259
|
+
email: 'biz_932@alitest.com',
|
|
260
|
+
pay_date: '20080107'
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
assert_equal 'https://mapi.alipay.com/gateway.do?service=batch_trans_notify&_input_charset=utf-8&partner=1000000000000000&pay_date=20080107¬ify_url=https%3A%2F%2Fexample.com%2Forders%2F20150401000-0001%2Fnotify&account_name=%E6%AF%9B%E6%AF%9B&detail_data=0315006%5Etestture0002%40126.com%5E%E5%B8%B8%E7%82%9C%E4%B9%B0%E5%AE%B6%5E1000.00%5Ehello&batch_no=20080107001&batch_num=1&batch_fee=1000.0&email=biz_932%40alitest.com&sign_type=MD5&sign=59c611607daafd1337e96b22404bd521', Alipay::Service.batch_trans_notify_url(options)
|
|
264
|
+
end
|
|
265
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class Alipay::Sign::MD5Test < Minitest::Test
|
|
4
|
+
def setup
|
|
5
|
+
@string = "partner=123&service=test"
|
|
6
|
+
@sign = 'bbd13b52823b576291595f472ebcfbc2'
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def test_sign
|
|
10
|
+
assert_equal @sign, Alipay::Sign::MD5.sign(Alipay.key, @string)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def test_verify
|
|
14
|
+
assert Alipay::Sign::MD5.verify?(Alipay.key, @string, @sign)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def test_verify_fail_when_sign_not_true
|
|
18
|
+
assert !Alipay::Sign::MD5.verify?(Alipay.key, "danger#{@string}", @sign)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class Alipay::Sign::RSA2Test < Minitest::Test
|
|
4
|
+
def setup
|
|
5
|
+
@string = "partner=123&service=test"
|
|
6
|
+
@rsa2_pkey = OpenSSL::PKey::RSA.new(2048)
|
|
7
|
+
@rsa2_public_key = @rsa2_pkey.public_key.export
|
|
8
|
+
@sign = Base64.strict_encode64(@rsa2_pkey.sign('sha256', @string))
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def test_sign
|
|
12
|
+
assert_equal @sign, Alipay::Sign::RSA2.sign(@rsa2_pkey, @string)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def test_verify
|
|
16
|
+
assert Alipay::Sign::RSA2.verify?(@rsa2_public_key, @string, @sign)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def test_verify_fail_when_sign_not_true
|
|
20
|
+
assert !Alipay::Sign::RSA2.verify?(@rsa2_public_key, "danger#{@string}", @sign)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class Alipay::Sign::RSATest < Minitest::Test
|
|
4
|
+
def setup
|
|
5
|
+
@string = "partner=123&service=test"
|
|
6
|
+
@sign = "TaVXdP/0ia5NxIv9T76v6vGOrtgoaFrwnchKIWP9PQeX1UkUVxaq6ejDFmXFrFR+Plk+E/XzfV2DYJSVt0Am0qJRSgeg+PuvK+yWGCGm9GJgUJlS4Eyta3g+8DWwRWTjUyh5yzlf9JoSnbNjYpBolnMRD7B/u1JLkTMJuMx2TVM="
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def test_sign
|
|
10
|
+
assert_equal @sign, Alipay::Sign::RSA.sign(TEST_RSA_PRIVATE_KEY, @string)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def test_verify
|
|
14
|
+
assert Alipay::Sign::RSA.verify?(TEST_RSA_PUBLIC_KEY, @string, @sign)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def test_verify_fail_when_sign_not_true
|
|
18
|
+
assert !Alipay::Sign::RSA.verify?(TEST_RSA_PUBLIC_KEY, "danger#{@string}", @sign)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class Alipay::SignTest < Minitest::Test
|
|
4
|
+
def setup
|
|
5
|
+
@params = {
|
|
6
|
+
service: 'test',
|
|
7
|
+
partner: '123'
|
|
8
|
+
}
|
|
9
|
+
@md5_sign = 'bbd13b52823b576291595f472ebcfbc2'
|
|
10
|
+
|
|
11
|
+
@key_2 = '20000000000000000000000000000000'
|
|
12
|
+
@md5_sign_2 = '6d581af270c023fdaaca6880491e9bf7'
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def test_generate_sign
|
|
16
|
+
assert_equal @md5_sign, Alipay::Sign.generate(@params)
|
|
17
|
+
assert_equal @md5_sign_2, Alipay::Sign.generate(@params, {key: @key_2})
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def test_verify_sign
|
|
21
|
+
assert Alipay::Sign.verify?(@params.merge(sign_type: 'MD5', sign: @md5_sign))
|
|
22
|
+
assert Alipay::Sign.verify?(@params.merge(sign_type: 'MD5', sign: @md5_sign_2), {key: @key_2})
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def test_verify_fail_when_sign_not_true
|
|
26
|
+
assert !Alipay::Sign.verify?(@params)
|
|
27
|
+
assert !Alipay::Sign.verify?(@params.merge(danger: 'danger', sign_type: 'MD5', sign: @md5_sign))
|
|
28
|
+
assert !Alipay::Sign.verify?(@params.merge(sign_type: 'MD5', sign: 'danger'))
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class Alipay::UtilsTest < Minitest::Test
|
|
4
|
+
def test_stringify_keys
|
|
5
|
+
hash = { 'a' => 1, :b => 2 }
|
|
6
|
+
assert_equal({ 'a' => 1, 'b' => 2 }.sort, Alipay::Utils.stringify_keys(hash).sort)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def test_generate_batch_no
|
|
10
|
+
assert_equal(24, Alipay::Utils.generate_batch_no.size)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class Alipay::Wap::NotifyTest < Minitest::Test
|
|
4
|
+
def setup
|
|
5
|
+
@notify_id = 'notify_id_test'
|
|
6
|
+
|
|
7
|
+
@notify_params = {
|
|
8
|
+
service: 'alipay.wap.trade.create.direct',
|
|
9
|
+
v: '1.0',
|
|
10
|
+
sec_id: 'MD5',
|
|
11
|
+
notify_data: "<notify><notify_id>#{@notify_id}</notify_id><other_key>other_value</other_key></notify>"
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
query = [ :service, :v, :sec_id, :notify_data ].map {|key| "#{key}=#{@notify_params[key]}"}.join('&')
|
|
15
|
+
@sign_params = @notify_params.merge(sign: Digest::MD5.hexdigest("#{query}#{Alipay.key}"))
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def test_unsign_notify
|
|
19
|
+
stub_request(
|
|
20
|
+
:get, "https://mapi.alipay.com/gateway.do?service=notify_verify&partner=#{Alipay.pid}¬ify_id=#{@notify_id}"
|
|
21
|
+
).to_return(body: "true")
|
|
22
|
+
assert !Alipay::Wap::Notify.verify?(@notify_params)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def test_verify_notify_when_true
|
|
26
|
+
stub_request(
|
|
27
|
+
:get, "https://mapi.alipay.com/gateway.do?service=notify_verify&partner=#{Alipay.pid}¬ify_id=#{@notify_id}"
|
|
28
|
+
).to_return(body: "true")
|
|
29
|
+
assert Alipay::Wap::Notify.verify?(@sign_params)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def test_verify_notify_when_false
|
|
33
|
+
stub_request(
|
|
34
|
+
:get, "https://mapi.alipay.com/gateway.do?service=notify_verify&partner=#{Alipay.pid}¬ify_id=#{@notify_id}"
|
|
35
|
+
).to_return(body: "false")
|
|
36
|
+
assert !Alipay::Wap::Notify.verify?(@sign_params)
|
|
37
|
+
end
|
|
38
|
+
end
|