alipay 0.6.0.beta1 → 0.6.0.beta2

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.
@@ -0,0 +1,15 @@
1
+ require 'digest/md5'
2
+
3
+ module Alipay
4
+ module Sign
5
+ class MD5
6
+ def self.sign(key, string)
7
+ Digest::MD5.hexdigest("#{string}#{key}")
8
+ end
9
+
10
+ def self.verify?(key, string, sign)
11
+ sign == sign(key, string)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,18 @@
1
+ require 'openssl'
2
+ require 'base64'
3
+
4
+ module Alipay
5
+ module Sign
6
+ class RSA
7
+ def self.sign(key, string)
8
+ rsa = OpenSSL::PKey::RSA.new(key)
9
+ Base64.encode64(rsa.sign('sha1', string))
10
+ end
11
+
12
+ def self.verify?(key, string, sign)
13
+ rsa = OpenSSL::PKey::RSA.new(key)
14
+ rsa.verify('sha1', Base64.decode64(sign), string)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -1,3 +1,3 @@
1
1
  module Alipay
2
- VERSION = "0.6.0.beta1"
2
+ VERSION = "0.6.0.beta2"
3
3
  end
@@ -0,0 +1,13 @@
1
+ module Alipay
2
+ module Wap
3
+ module Notify
4
+ def self.verify?(params, options = {})
5
+ params = Utils.stringify_keys(params)
6
+ pid = options[:pid] || Alipay.pid
7
+ notify_id = params['notify_data'].scan(/\<notify_id\>(.*)\<\/notify_id\>/).flatten.first
8
+
9
+ Sign.verify?(params, options) && ::Alipay::Notify.verify_notify_id?(pid, notify_id)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,73 @@
1
+ module Alipay
2
+ module Wap
3
+ module Service
4
+ GATEWAY_URL = 'https://wappaygw.alipay.com/service/rest.htm'
5
+
6
+ TRADE_CREATE_DIRECT_TOKEN_REQUIRED_PARAMS = %w( req_data )
7
+ REQ_DATA_REQUIRED_PARAMS = %w( subject out_trade_no total_fee call_back_url )
8
+ def self.trade_create_direct_token(params, options = {})
9
+ params = Utils.stringify_keys(params)
10
+ Alipay::Service.check_required_params(params, TRADE_CREATE_DIRECT_TOKEN_REQUIRED_PARAMS)
11
+
12
+ req_data = Utils.stringify_keys(params.delete('req_data'))
13
+ Alipay::Service.check_required_params(req_data, REQ_DATA_REQUIRED_PARAMS)
14
+
15
+ req_data = {
16
+ 'seller_account_name' => options[:seller_email] || Alipay.seller_email
17
+ }.merge(req_data)
18
+
19
+ xml = req_data.map {|k, v| "<#{k}>#{v.encode(:xml => :text)}</#{k}>" }.join
20
+ req_data_xml = "<direct_trade_create_req>#{xml}</direct_trade_create_req>"
21
+
22
+ # About req_id: http://club.alipay.com/read-htm-tid-10078020-fpage-2.html
23
+ params = {
24
+ 'service' => 'alipay.wap.trade.create.direct',
25
+ 'req_data' => req_data_xml,
26
+ 'partner' => options[:pid] || Alipay.pid,
27
+ 'req_id' => Time.now.strftime('%Y%m%d%H%M%s'),
28
+ 'format' => 'xml',
29
+ 'v' => '2.0'
30
+ }.merge(params)
31
+
32
+ xml = Net::HTTP.get(request_uri(params, options))
33
+ CGI.unescape(xml).scan(/\<request_token\>(.*)\<\/request_token\>/).flatten.first
34
+ end
35
+
36
+ AUTH_AND_EXECUTE_REQUIRED_PARAMS = %w( request_token )
37
+
38
+ def self.auth_and_execute_url(params, options = {})
39
+ params = Utils.stringify_keys(params)
40
+ Alipay::Service.check_required_params(params, AUTH_AND_EXECUTE_REQUIRED_PARAMS)
41
+
42
+ req_data_xml = "<auth_and_execute_req><request_token>#{params.delete('request_token')}</request_token></auth_and_execute_req>"
43
+
44
+ params = {
45
+ 'service' => 'alipay.wap.auth.authAndExecute',
46
+ 'req_data' => req_data_xml,
47
+ 'partner' => options[:pid] || Alipay.pid,
48
+ 'format' => 'xml',
49
+ 'v' => '2.0'
50
+ }.merge(params)
51
+
52
+ request_uri(params, options).to_s
53
+ end
54
+
55
+ def self.request_uri(params, options = {})
56
+ uri = URI(GATEWAY_URL)
57
+ uri.query = URI.encode_www_form(sign_params(params, options))
58
+ uri
59
+ end
60
+
61
+ SIGN_TYPE_TO_SEC_ID = {
62
+ 'MD5' => 'MD5',
63
+ 'RSA' => '0001'
64
+ }
65
+
66
+ def self.sign_params(params, options = {})
67
+ sign_type = (options[:sign_type] ||= Alipay.sign_type)
68
+ params = params.merge('sec_id' => SIGN_TYPE_TO_SEC_ID[sign_type])
69
+ params.merge('sign' => Alipay::Sign.generate(params, options))
70
+ end
71
+ end
72
+ end
73
+ end
@@ -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[:pid] || 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
+ raise ArgumentError, "[Alipay] Invalid sec_id, allow value: 'MD5', '0001'"
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
@@ -2,25 +2,28 @@ require 'test_helper'
2
2
 
3
3
  class Alipay::NotifyTest < Minitest::Test
4
4
  def setup
5
- @options = {
5
+ @params = {
6
6
  :notify_id => '1234',
7
- :sign_type => 'MD5'
8
7
  }
9
- @sign_options = @options.merge(:sign => Alipay::Sign.generate(@options))
8
+ @unsign_params = @params.merge(:sign_type => 'MD5', :sign => 'xxxx')
9
+ @sign_params = @params.merge(
10
+ :sign_type => 'MD5',
11
+ :sign => '22fc7e38e5acdfede396aa463870d111'
12
+ )
10
13
  end
11
14
 
12
15
  def test_unsign_notify
13
16
  FakeWeb.register_uri(:get, "https://mapi.alipay.com/gateway.do?service=notify_verify&partner=#{Alipay.pid}&notify_id=1234", :body => "true")
14
- assert !Alipay::Notify.verify?(@options)
17
+ assert !Alipay::Notify.verify?(@unsign_params)
15
18
  end
16
19
 
17
20
  def test_verify_notify_when_true
18
21
  FakeWeb.register_uri(:get, "https://mapi.alipay.com/gateway.do?service=notify_verify&partner=#{Alipay.pid}&notify_id=1234", :body => "true")
19
- assert Alipay::Notify.verify?(@sign_options)
22
+ assert Alipay::Notify.verify?(@sign_params)
20
23
  end
21
24
 
22
25
  def test_verify_notify_when_false
23
26
  FakeWeb.register_uri(:get, "https://mapi.alipay.com/gateway.do?service=notify_verify&partner=#{Alipay.pid}&notify_id=1234", :body => "false")
24
- assert !Alipay::Notify.verify?(@sign_options)
27
+ assert !Alipay::Notify.verify?(@sign_params)
25
28
  end
26
29
  end
@@ -38,7 +38,7 @@ class Alipay::ServiceTest < Minitest::Test
38
38
  assert_equal 'https://mapi.alipay.com/gateway.do?service=create_direct_pay_by_user&_input_charset=utf-8&partner=1000000000000000&seller_email=admin%40example.com&payment_type=1&out_trade_no=1&subject=test&price=0.01&quantity=1&sign_type=MD5&sign=51c7f60e85eaff5136600d1942b2744c', Alipay::Service.create_direct_pay_by_user_url(options)
39
39
  end
40
40
 
41
- def test_generate_create_refund_url
41
+ def test_refund_fastpay_by_platform_pwd_url
42
42
  data = [{
43
43
  :trade_no => '1',
44
44
  :amount => '0.01',
@@ -50,10 +50,10 @@ class Alipay::ServiceTest < Minitest::Test
50
50
  :notify_url => '/some_url',
51
51
  :refund_date => '2015-01-01 00:00:00'
52
52
  }
53
- assert_equal "https://mapi.alipay.com/gateway.do?service=refund_fastpay_by_platform_pwd&_input_charset=utf-8&partner=1000000000000000&seller_email=admin%40example.com&refund_date=2015-01-01+00%3A00%3A00&batch_num=1&detail_data=1%5E0.01%5Etest&batch_no=123456789&notify_url=%2Fsome_url&sign_type=MD5&sign=3f5be5655b513334460a511e74a9ae57", Alipay::Service.create_refund_url(options)
53
+ assert_equal "https://mapi.alipay.com/gateway.do?service=refund_fastpay_by_platform_pwd&_input_charset=utf-8&partner=1000000000000000&seller_email=admin%40example.com&refund_date=2015-01-01+00%3A00%3A00&batch_num=1&detail_data=1%5E0.01%5Etest&batch_no=123456789&notify_url=%2Fsome_url&sign_type=MD5&sign=3f5be5655b513334460a511e74a9ae57", Alipay::Service.refund_fastpay_by_platform_pwd_url(options)
54
54
  end
55
55
 
56
- def test_generate_create_forex_single_refund_url
56
+ def test_forex_refund_url
57
57
  options = {
58
58
  :out_return_no => '1',
59
59
  :out_trade_no => '12345678980',
@@ -62,10 +62,10 @@ class Alipay::ServiceTest < Minitest::Test
62
62
  :reason => 'reason',
63
63
  :gmt_return => '2015-01-01 00:00:00'
64
64
  }
65
- assert_equal 'https://mapi.alipay.com/gateway.do?service=forex_refund&partner=1000000000000000&_input_charset=utf-8&gmt_return=2015-01-01+00%3A00%3A00&out_return_no=1&out_trade_no=12345678980&return_amount=0.01&currency=USD&reason=reason&sign_type=MD5&sign=123c50e884e560801fee8b73f1ac6172', Alipay::Service.create_forex_single_refund_url(options)
65
+ assert_equal 'https://mapi.alipay.com/gateway.do?service=forex_refund&partner=1000000000000000&_input_charset=utf-8&gmt_return=2015-01-01+00%3A00%3A00&out_return_no=1&out_trade_no=12345678980&return_amount=0.01&currency=USD&reason=reason&sign_type=MD5&sign=123c50e884e560801fee8b73f1ac6172', Alipay::Service.forex_refund_url(options)
66
66
  end
67
67
 
68
- def test_generate_create_forex_trade
68
+ def test_generate_create_forex_trade_url
69
69
  options = {
70
70
  :notify_url => 'https://example.com/notify',
71
71
  :subject => 'test',
@@ -73,7 +73,7 @@ class Alipay::ServiceTest < Minitest::Test
73
73
  :currency => 'EUR',
74
74
  :total_fee => '0.01',
75
75
  }
76
- assert_equal 'https://mapi.alipay.com/gateway.do?service=create_forex_trade&_input_charset=utf-8&partner=1000000000000000&seller_email=admin%40example.com&notify_url=https%3A%2F%2Fexample.com%2Fnotify&subject=test&out_trade_no=1&currency=EUR&total_fee=0.01&sign_type=MD5&sign=495a0e610134aa33f6ce021f8b8c6c8d', Alipay::Service.create_forex_trade(options)
76
+ assert_equal 'https://mapi.alipay.com/gateway.do?service=create_forex_trade&_input_charset=utf-8&partner=1000000000000000&seller_email=admin%40example.com&notify_url=https%3A%2F%2Fexample.com%2Fnotify&subject=test&out_trade_no=1&currency=EUR&total_fee=0.01&sign_type=MD5&sign=495a0e610134aa33f6ce021f8b8c6c8d', Alipay::Service.create_forex_trade_url(options)
77
77
  end
78
78
 
79
79
  def test_close_trade
@@ -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
@@ -7,21 +7,23 @@ class Alipay::SignTest < Minitest::Test
7
7
  :partner => '123'
8
8
  }
9
9
  @md5_sign = 'bbd13b52823b576291595f472ebcfbc2'
10
+
11
+ @key_2 = '20000000000000000000000000000000'
12
+ @md5_sign_2 = '6d581af270c023fdaaca6880491e9bf7'
10
13
  end
11
14
 
12
15
  def test_generate_sign
13
16
  assert_equal @md5_sign, Alipay::Sign.generate(@params)
14
- end
15
-
16
- def test_generate_md5_sign
17
- assert_equal @md5_sign, Alipay::Sign.generate_md5(Alipay.key, @params)
17
+ assert_equal @md5_sign_2, Alipay::Sign.generate(@params, {:key => @key_2})
18
18
  end
19
19
 
20
20
  def test_verify_sign
21
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})
22
23
  end
23
24
 
24
- def test_verify_sign_when_fails
25
+ def test_verify_fail_when_sign_not_true
25
26
  assert !Alipay::Sign.verify?(@params.merge(:danger => 'danger', :sign_type => 'MD5', :sign => @md5_sign))
27
+ assert !Alipay::Sign.verify?(@params.merge(:sign_type => 'MD5', :sign => 'danger'))
26
28
  end
27
29
  end
@@ -1,6 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
- class Alipay::Notify::WapTest < Minitest::Test
3
+ class Alipay::Wap::NotifyTest < Minitest::Test
4
4
  def setup
5
5
  @notify_id = 'notify_id_test'
6
6
 
@@ -17,16 +17,16 @@ class Alipay::Notify::WapTest < Minitest::Test
17
17
 
18
18
  def test_unsign_notify
19
19
  FakeWeb.register_uri(:get, "https://mapi.alipay.com/gateway.do?service=notify_verify&partner=#{Alipay.pid}&notify_id=#{@notify_id}", :body => "true")
20
- assert !Alipay::Notify::Wap.verify?(@notify_params)
20
+ assert !Alipay::Wap::Notify.verify?(@notify_params)
21
21
  end
22
22
 
23
23
  def test_verify_notify_when_true
24
24
  FakeWeb.register_uri(:get, "https://mapi.alipay.com/gateway.do?service=notify_verify&partner=#{Alipay.pid}&notify_id=#{@notify_id}", :body => "true")
25
- assert Alipay::Notify::Wap.verify?(@sign_params)
25
+ assert Alipay::Wap::Notify.verify?(@sign_params)
26
26
  end
27
27
 
28
28
  def test_verify_notify_when_false
29
29
  FakeWeb.register_uri(:get, "https://mapi.alipay.com/gateway.do?service=notify_verify&partner=#{Alipay.pid}&notify_id=#{@notify_id}", :body => "false")
30
- assert !Alipay::Notify::Wap.verify?(@sign_params)
30
+ assert !Alipay::Wap::Notify.verify?(@sign_params)
31
31
  end
32
32
  end
@@ -1,6 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
- class Alipay::Service::WapTest < Minitest::Test
3
+ class Alipay::Wap::ServiceTest < Minitest::Test
4
4
  def test_trade_create_direct_token
5
5
  token = 'REQUEST_TOKEN'
6
6
  body = <<-EOS
@@ -23,7 +23,7 @@ class Alipay::Service::WapTest < Minitest::Test
23
23
  :body => body
24
24
  )
25
25
 
26
- assert_equal token, Alipay::Service::Wap.trade_create_direct_token(
26
+ assert_equal token, Alipay::Wap::Service.trade_create_direct_token(
27
27
  :req_data => {
28
28
  :out_trade_no => '1',
29
29
  :subject => 'subject',
@@ -34,7 +34,7 @@ class Alipay::Service::WapTest < Minitest::Test
34
34
  end
35
35
 
36
36
  def test_auth_and_execute_url
37
- options = { :request_token => 'token_test' }
38
- assert_equal 'https://wappaygw.alipay.com/service/rest.htm?service=alipay.wap.auth.authAndExecute&req_data=%3Cauth_and_execute_req%3E%3Crequest_token%3Etoken_test%3C%2Frequest_token%3E%3C%2Fauth_and_execute_req%3E&partner=1000000000000000&format=xml&v=2.0&sec_id=MD5&sign=3efe60d4a9b7960ba599da6764c959df', Alipay::Service::Wap.auth_and_execute_url(options)
37
+ params = { :request_token => 'token_test' }
38
+ assert_equal 'https://wappaygw.alipay.com/service/rest.htm?service=alipay.wap.auth.authAndExecute&req_data=%3Cauth_and_execute_req%3E%3Crequest_token%3Etoken_test%3C%2Frequest_token%3E%3C%2Fauth_and_execute_req%3E&partner=1000000000000000&format=xml&v=2.0&sec_id=MD5&sign=3efe60d4a9b7960ba599da6764c959df', Alipay::Wap::Service.auth_and_execute_url(params)
39
39
  end
40
40
  end
@@ -1,6 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
- class Alipay::Sign::WapTest < Minitest::Test
3
+ class Alipay::Wap::SignTest < Minitest::Test
4
4
  def setup
5
5
  @params = {
6
6
  :v => '1.0',
@@ -12,6 +12,6 @@ class Alipay::Sign::WapTest < Minitest::Test
12
12
  end
13
13
 
14
14
  def test_verify_sign
15
- assert Alipay::Sign::Wap.verify?(@params.merge(:sign => @sign, :whatever => 'x'))
15
+ assert Alipay::Wap::Sign.verify?(@params.merge(:sign => @sign, :whatever => 'x'))
16
16
  end
17
17
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: alipay
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0.beta1
4
+ version: 0.6.0.beta2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rei
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-26 00:00:00.000000000 Z
11
+ date: 2015-04-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -74,6 +74,7 @@ extensions: []
74
74
  extra_rdoc_files: []
75
75
  files:
76
76
  - ".gitignore"
77
+ - ".travis.yml"
77
78
  - CHANGELOG.md
78
79
  - Gemfile
79
80
  - LICENSE.txt
@@ -82,20 +83,24 @@ files:
82
83
  - alipay.gemspec
83
84
  - lib/alipay.rb
84
85
  - lib/alipay/notify.rb
85
- - lib/alipay/notify/wap.rb
86
86
  - lib/alipay/service.rb
87
- - lib/alipay/service/wap.rb
88
87
  - lib/alipay/sign.rb
89
- - lib/alipay/sign/wap.rb
88
+ - lib/alipay/sign/dsa.rb
89
+ - lib/alipay/sign/md5.rb
90
+ - lib/alipay/sign/rsa.rb
90
91
  - lib/alipay/utils.rb
91
92
  - lib/alipay/version.rb
92
- - test/alipay/notify/wap_test.rb
93
+ - lib/alipay/wap/notify.rb
94
+ - lib/alipay/wap/service.rb
95
+ - lib/alipay/wap/sign.rb
93
96
  - test/alipay/notify_test.rb
94
- - test/alipay/service/wap_test.rb
95
97
  - test/alipay/service_test.rb
96
- - test/alipay/sign/wap_test.rb
98
+ - test/alipay/sign/md5_test.rb
97
99
  - test/alipay/sign_test.rb
98
100
  - test/alipay/utils_test.rb
101
+ - test/alipay/wap/notify_test.rb
102
+ - test/alipay/wap/service_test.rb
103
+ - test/alipay/wap/sign_test.rb
99
104
  - test/alipay_test.rb
100
105
  - test/test_helper.rb
101
106
  homepage: https://github.com/chloerei/alipay
@@ -123,12 +128,13 @@ signing_key:
123
128
  specification_version: 4
124
129
  summary: An unofficial simple alipay gem
125
130
  test_files:
126
- - test/alipay/notify/wap_test.rb
127
131
  - test/alipay/notify_test.rb
128
- - test/alipay/service/wap_test.rb
129
132
  - test/alipay/service_test.rb
130
- - test/alipay/sign/wap_test.rb
133
+ - test/alipay/sign/md5_test.rb
131
134
  - test/alipay/sign_test.rb
132
135
  - test/alipay/utils_test.rb
136
+ - test/alipay/wap/notify_test.rb
137
+ - test/alipay/wap/service_test.rb
138
+ - test/alipay/wap/sign_test.rb
133
139
  - test/alipay_test.rb
134
140
  - test/test_helper.rb