mangopay 3.0.1 → 3.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/README.md +43 -14
  4. data/lib/mangopay.rb +43 -34
  5. data/lib/mangopay/authorization_token.rb +76 -0
  6. data/lib/mangopay/bank_account.rb +14 -7
  7. data/lib/mangopay/client.rb +11 -17
  8. data/lib/mangopay/errors.rb +22 -2
  9. data/lib/mangopay/http_calls.rb +24 -2
  10. data/lib/mangopay/legal_user.rb +1 -1
  11. data/lib/mangopay/natural_user.rb +1 -1
  12. data/lib/mangopay/payin.rb +2 -2
  13. data/lib/mangopay/payout.rb +1 -1
  14. data/lib/mangopay/resource.rb +1 -1
  15. data/lib/mangopay/transaction.rb +17 -2
  16. data/lib/mangopay/version.rb +1 -1
  17. data/spec/lib/mangopay/authorization_token_spec.rb +72 -0
  18. data/spec/lib/mangopay/bank_account_spec.rb +25 -26
  19. data/spec/lib/mangopay/card_registration_spec.rb +40 -16
  20. data/spec/lib/mangopay/client_spec.rb +14 -9
  21. data/spec/lib/mangopay/configuration_spec.rb +20 -0
  22. data/spec/lib/mangopay/fetch_filters_spec.rb +65 -0
  23. data/spec/lib/mangopay/payin_card_direct_spec.rb +70 -0
  24. data/spec/lib/mangopay/payin_card_web_spec.rb +53 -0
  25. data/spec/lib/mangopay/payout_bankwire_spec.rb +56 -0
  26. data/spec/lib/mangopay/shared_resources.rb +123 -82
  27. data/spec/lib/mangopay/transaction_spec.rb +48 -2
  28. data/spec/lib/mangopay/transfer_spec.rb +51 -15
  29. data/spec/lib/mangopay/user_spec.rb +1 -0
  30. data/spec/lib/mangopay/wallet_spec.rb +31 -32
  31. data/spec/spec_helper.rb +11 -4
  32. data/spec/tmp/.keep +0 -0
  33. metadata +17 -8
  34. data/spec/lib/mangopay/card_spec.rb +0 -35
  35. data/spec/lib/mangopay/payin_spec.rb +0 -34
  36. data/spec/lib/mangopay/payout_spec.rb +0 -34
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 67c10c6356d088795e976707bb179e568a7f5368
4
- data.tar.gz: dcd3cd6d68b8012d37752e00d6f6edf15b1b8223
3
+ metadata.gz: fae2d9875515d0ac49e200836b8741894d6009eb
4
+ data.tar.gz: 754c2abd123306ef475b1fa0ef89f37725e8b0ad
5
5
  SHA512:
6
- metadata.gz: 841c0922c44245dfe8505dc25756fb3f82621b2823e4993a0ccd3c19248972068102508491ef391c19b6918de7b504746de71d0d61998635552d854628e4aa8c
7
- data.tar.gz: 4497c0d2305ac47148712956bcf071f56b69ce2c73e2ca287296c42404cf020967372130b4b92e9ae13d4d82b05663e5c06da50f595e01c43333374b1dae2815
6
+ metadata.gz: f3c10e1d1fc80d4650a48662204b90c3d83d7af10c3be4fa4be9bb88caf9e0062e0622956488b15ad72d38ed55d8942af55187ba8b41de8cc249d65cab2eec43
7
+ data.tar.gz: 0c15e721136d89ed3ac62152c24673e6d7b74e1cf6219ef8c40b73196ec44fef34c0b20be043c8dbec47eebc5e5aecddd95f4f022c4a2e2a99a3ed58e6b53ec3
data/.gitignore CHANGED
@@ -8,9 +8,9 @@ lib/bundler/man
8
8
  pkg
9
9
  rdoc
10
10
  spec/reports
11
+ spec/tmp/*.tmp
11
12
  test/tmp
12
13
  test/version_tmp
13
- tmp
14
14
  tags
15
15
 
16
16
  # YARD artifacts
data/README.md CHANGED
@@ -1,37 +1,66 @@
1
1
  # MangoPay2 Ruby SDK
2
2
 
3
3
  The gem for interacting with the version 2 of the MangoPay API.
4
- See the [API documentation]() for more details on the API.
4
+ See the [API documentation](http://docs.mangopay.com/api-references/)
5
+ for more details on the API.
5
6
 
6
7
  Tested on the following versions of Ruby: 1.9.2, 1.9.3, 2.0.0
7
8
 
8
- ## Code Status
9
- [![Build Status]()]()
10
- [![Code Climate]()]()
11
- [![Dependency Status]()]()
12
-
13
9
  ## NEWS
14
10
 
15
- ### Version 3.0.0
11
+ ### Version 3.*
16
12
  ** BREAKING CHANGES **
17
- This version of the gem is targeting the MangoPay API Version 2.
13
+ This version (3.*) of the gem is targeting the MangoPay API Version 2.
18
14
  It has a brand new structure to make the api calls easier to use
15
+ and is not backward compatible with 2.* series.
19
16
 
20
17
  ## Usage
21
18
 
22
19
  ### Install
23
- * Install the gem by either running ```gem install mangopay``` or by adding it to your Gemfile ```gem 'mangopay'```
20
+ * Install the gem by either running ```gem install mangopay```
21
+ or by adding it to your Gemfile ```gem 'mangopay'```
22
+
23
+ * The Rails users will be happy to know that there is a new generator script
24
+ that will help you configure your access to the MangoPay API version 2.
25
+ Simply run ``rails generate mangopay:install CLIENT_ID CLIENT_NAME CLIENT_EMAIL``
26
+ where CLIENT_ID is the id you will use to connect to the api
27
+ and CLIENT_NAME is a full name that will be use to identify all communications
28
+ between you and the MangoPay Team.
24
29
 
25
- * The Rails users will be happy to know that there is a new generator script that will help you configure your access to the MangoPay API version 2.
26
- Simply run ``rails generate mangopay:install CLIENT_ID CLIENT_NAME`` where CLIENT_ID is the id you will use to connect to the api and CLIENT_NAME is a full name that will be use to identify all communications between you and the MangoPay Team.
30
+ * Otherwise, call ```MangoPay.configure``` in your script as shown in the snippet below.
27
31
 
28
32
  ### Examples
29
33
 
34
+ ```ruby
35
+ require 'mangopay'
36
+
37
+ # configuration (not required if Rails generator fired as above)
38
+ MangoPay.configure do |c|
39
+ c.preproduction = true
40
+ c.client_id = 'YOUR_CLIENT_ID'
41
+ c.client_passphrase = 'YOUR_CLIENT_PASSWORD'
42
+ end
43
+
44
+ # get some user by id
45
+ john = MangoPay::User.fetch(john_id) # => {FirstName"=>"John", "LastName"=>"Doe", ...}
46
+
47
+ # update some of his data
48
+ MangoPay::NaturalUser.update(john_id, {'LastName' => 'CHANGED'}) # => {FirstName"=>"John", "LastName"=>"CHANGED", ...}
49
+
50
+ # get all users (with pagination)
51
+ pagination = {'page' => 1, 'per_page' => 8} # get 1st page, 8 items per page
52
+ users = MangoPay::User.fetch(pagination) # => [{...}, ...]: list of 8 users data hashes
53
+ pagination # => {"page"=>1, "per_page"=>8, "total_pages"=>748, "total_items"=>5978}
54
+
55
+ # get John's bank accounts
56
+ accounts = MangoPay::BankAccount.fetch(john_id) # => [{...}, ...]: list of accounts data hashes (10 per page by default)
57
+ ```
30
58
 
31
59
  ### Tests
32
60
  Make sure that you have run: ```bundle install```
33
61
  Then you just have to run rspec ```rspec``` to run all the test suite.
34
- Feel free to report any test failure by creating an issue on the [Gem's Github](https://github.com/MangoPay/mangopay2-ruby-sdk/issues)
62
+ Feel free to report any test failure by creating an issue
63
+ on the [Gem's Github](https://github.com/MangoPay/mangopay2-ruby-sdk/issues)
35
64
 
36
65
  ## Contributing
37
66
 
@@ -61,7 +90,7 @@ Syntax:
61
90
  * a = b and not a=b.
62
91
  * Follow the conventions you see used in the source already.
63
92
 
64
- A contribution can also be as simple as a +1 on issues tickets to show us what you would like to see in this gem.
93
+ A contribution can also be as simple as a +1 on issues tickets to show us
94
+ what you would like to see in this gem.
65
95
 
66
96
  That's it for now. Good Hacking...
67
- >>>>>>> dev
data/lib/mangopay.rb CHANGED
@@ -2,13 +2,13 @@ require 'net/http'
2
2
  require 'cgi/util'
3
3
  require 'multi_json'
4
4
 
5
- # Version
5
+ # helpers
6
6
  require 'mangopay/version'
7
-
8
- # JSON
9
7
  require 'mangopay/json'
8
+ require 'mangopay/errors'
9
+ require 'mangopay/authorization_token'
10
10
 
11
- # Resources
11
+ # resources
12
12
  require 'mangopay/http_calls'
13
13
  require 'mangopay/resource'
14
14
  require 'mangopay/client'
@@ -24,13 +24,12 @@ require 'mangopay/bank_account'
24
24
  require 'mangopay/card_registration'
25
25
  require 'mangopay/card'
26
26
 
27
- # Errors
28
- require 'mangopay/errors'
29
-
30
27
  module MangoPay
31
28
 
32
29
  class Configuration
33
- attr_accessor :root_url, :client_id, :client_passphrase, :preproduction
30
+ attr_accessor :preproduction, :root_url,
31
+ :client_id, :client_passphrase,
32
+ :temp_dir
34
33
 
35
34
  def preproduction
36
35
  @preproduction || false
@@ -54,17 +53,46 @@ module MangoPay
54
53
  URI(configuration.root_url + url)
55
54
  end
56
55
 
57
- def self.request(method, url, params={}, headers={})
56
+ #
57
+ # - +method+: HTTP method; lowercase symbol, e.g. :get, :post etc.
58
+ # - +url+: the part after Configuration#root_url
59
+ # - +params+: hash; entity data for creation, update etc.; will dump it by JSON and assign to Net::HTTPRequest#body
60
+ # - +filters+: hash; pagination params etc.; will encode it by URI and assign to URI#query
61
+ # - +headers+: hash; request_headers by default
62
+ # - +before_request_proc+: optional proc; will call it passing the Net::HTTPRequest instance just before Net::HTTPRequest#request
63
+ #
64
+ # Raises MangoPay::ResponseError if response code != 200.
65
+ #
66
+ def self.request(method, url, params={}, filters={}, headers = request_headers, before_request_proc = nil)
58
67
  uri = api_uri(url)
68
+ uri.query = URI.encode_www_form(filters) unless filters.empty?
59
69
 
60
70
  res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
61
- request = Net::HTTP::const_get(method.capitalize).new(uri.request_uri, request_headers)
62
- request.body = MangoPay::JSON.dump(params)
63
- http.request request
71
+ req = Net::HTTP::const_get(method.capitalize).new(uri.request_uri, headers)
72
+ req.body = MangoPay::JSON.dump(params)
73
+ before_request_proc.call(req) if before_request_proc
74
+ http.request req
64
75
  end
65
- MangoPay::JSON.load(res.body)
76
+
77
+ # decode json data
78
+ begin
79
+ data = MangoPay::JSON.load(res.body)
80
+ rescue MultiJson::LoadError
81
+ data = {}
82
+ end
83
+
84
+ raise MangoPay::ResponseError.new(uri, res.code, data) unless res.is_a? Net::HTTPOK
85
+
86
+ # copy pagination info if any
87
+ ['x-number-of-pages', 'x-number-of-items'].each { |k|
88
+ filters[k.gsub('x-number-of-', 'total_')] = res[k].to_i if res[k]
89
+ }
90
+
91
+ data
66
92
  end
67
93
 
94
+ private
95
+
68
96
  def self.user_agent
69
97
  @uname ||= get_uname
70
98
 
@@ -83,30 +111,11 @@ module MangoPay
83
111
  'uname lookup failed'
84
112
  end
85
113
 
86
- def self.get_oauth_token
87
- if @auth_timestamp.nil? || @auth_timestamp <= Time.now || @auth_token.nil?
88
- uri = api_uri('/api/oauth/token')
89
- res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
90
- req = Net::HTTP::Post.new(uri.request_uri)
91
- req.basic_auth configuration.client_id, configuration.client_passphrase
92
- req.body = 'grant_type=client_credentials'
93
- http.request req
94
- end
95
- @auth_token = MangoPay::JSON.load(res.body)
96
- @auth_timestamp = Time.now + @auth_token['expires_in'].to_i
97
- end
98
- @auth_token
99
- end
100
-
101
- def self.oauth_token
102
- oauth = get_oauth_token
103
- "#{oauth['token_type']} #{oauth['access_token']}"
104
- end
105
-
106
114
  def self.request_headers
115
+ auth_token = MangoPay::AuthorizationToken::Manager.get_token
107
116
  headers = {
108
117
  'user_agent' => "MangoPay V1 RubyBindings/#{MangoPay::VERSION}",
109
- 'Authorization' => oauth_token,
118
+ 'Authorization' => "#{auth_token['token_type']} #{auth_token['access_token']}",
110
119
  'Content-Type' => 'application/json'
111
120
  }
112
121
  begin
@@ -0,0 +1,76 @@
1
+ module MangoPay
2
+ module AuthorizationToken
3
+
4
+ class Manager
5
+
6
+ class << self
7
+ def storage
8
+ @@storage ||= StaticStorage.new
9
+ end
10
+ def storage= (storage)
11
+ @@storage = storage
12
+ end
13
+ end
14
+
15
+ def self.get_token
16
+ token = storage.get
17
+ if token.nil? || token['timestamp'].nil? || token['timestamp'] <= Time.now
18
+ token = MangoPay.request(:post, '/api/oauth/token', {}, {}, {}, Proc.new do |req|
19
+ cfg = MangoPay.configuration
20
+ req.basic_auth cfg.client_id, cfg.client_passphrase
21
+ req.body = 'grant_type=client_credentials'
22
+ end)
23
+ token['timestamp'] = Time.now + token['expires_in'].to_i
24
+ storage.store token
25
+ end
26
+ token
27
+ end
28
+ end
29
+
30
+ class StaticStorage
31
+ def get
32
+ @@token ||= nil
33
+ end
34
+ def store(token)
35
+ @@token = token
36
+ end
37
+ end
38
+
39
+ class FileStorage
40
+ require 'yaml'
41
+ @temp_dir
42
+
43
+ def initialize(temp_dir = nil)
44
+ @temp_dir = temp_dir || MangoPay.configuration.temp_dir
45
+ if !@temp_dir
46
+ raise "Path to temporary folder is not defined"
47
+ end
48
+ end
49
+
50
+ def get
51
+ begin
52
+ f = File.open(file_path, File::RDONLY)
53
+ f.flock(File::LOCK_SH)
54
+ txt = f.read
55
+ f.close
56
+ YAML.load(txt) || nil
57
+ rescue Errno::ENOENT
58
+ nil
59
+ end
60
+ end
61
+
62
+ def store(token)
63
+ File.open(file_path, File::RDWR|File::CREAT, 0644) do |f|
64
+ f.flock(File::LOCK_EX)
65
+ f.truncate(0)
66
+ f.rewind
67
+ f.puts(YAML.dump(token))
68
+ end
69
+ end
70
+
71
+ def file_path
72
+ File.join(@temp_dir, "MangoPay.AuthorizationToken.FileStore.tmp")
73
+ end
74
+ end
75
+ end
76
+ end
@@ -3,18 +3,25 @@ module MangoPay
3
3
  include MangoPay::HTTPCalls::Create
4
4
  include MangoPay::HTTPCalls::Fetch
5
5
 
6
- def self.fetch(*ids)
7
- url = ids.length == 1 ? url(ids[0]) : url(ids[0], ids[1])
8
- MangoPay.request(:get, url)
6
+ # Fetches:
7
+ # - list of bank accounts belonging to the given +user_id+
8
+ # - or single bank account belonging to the given +user_id+ with the given +bank_account_id+.
9
+ #
10
+ # In case of list query, optional +filters+ is a hash accepting pagination params
11
+ # (+page+, +per_page+; see MangoPay::HTTPCalls::Fetch::ClassMethods#fetch)
12
+ #
13
+ def self.fetch(user_id, bank_account_id_or_filters={})
14
+ bank_account_id, filters = MangoPay::HTTPCalls::Fetch.parse_id_or_filters(bank_account_id_or_filters)
15
+ MangoPay.request(:get, url(user_id, bank_account_id), {}, filters)
9
16
  end
10
17
 
11
18
  private
12
19
 
13
- def self.url(*id)
14
- if id.length == 1
15
- "/v2/#{MangoPay.configuration.client_id}/users/#{CGI.escape(id[0])}/bankaccounts"
20
+ def self.url(user_id, bank_account_id = nil)
21
+ if bank_account_id
22
+ "/v2/#{MangoPay.configuration.client_id}/users/#{CGI.escape(user_id.to_s)}/bankaccounts/#{CGI.escape(bank_account_id.to_s)}"
16
23
  else
17
- "/v2/#{MangoPay.configuration.client_id}/users/#{CGI.escape(id[0])}/bankaccounts/#{CGI.escape(id[1])}"
24
+ "/v2/#{MangoPay.configuration.client_id}/users/#{CGI.escape(user_id.to_s)}/bankaccounts"
18
25
  end
19
26
  end
20
27
  end
@@ -1,17 +1,11 @@
1
- module MangoPay
2
- class Client < Resource
3
-
4
- def self.create(params)
5
- uri = URI(MangoPay.configuration.root_url + '/api/clients/')
6
- res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
7
- request = Net::HTTP::Post.new(uri.request_uri, {
8
- 'user_agent' => "MangoPay V1 RubyBindings/#{MangoPay::VERSION}",
9
- 'Content-Type' => 'application/json'
10
- })
11
- request.body = MangoPay::JSON.dump(params)
12
- http.request request
13
- end
14
- MangoPay::JSON.load(res.body)
15
- end
16
- end
17
- end
1
+ module MangoPay
2
+ class Client < Resource
3
+
4
+ def self.create(params)
5
+ MangoPay.request(:post, '/api/clients/', params, {}, {
6
+ 'user_agent' => "MangoPay V1 RubyBindings/#{MangoPay::VERSION}",
7
+ 'Content-Type' => 'application/json'
8
+ })
9
+ end
10
+ end
11
+ end
@@ -1,4 +1,24 @@
1
1
  module MangoPay
2
- class Errors
3
- end
2
+
3
+ # Generic error superclass for MangoPay specific errors.
4
+ # Currently never instantiated directly.
5
+ # Currently only single subclass used.
6
+ class Error < StandardError
7
+ end
8
+
9
+ # Thrown from any MangoPay API call whenever
10
+ # it returns response with HTTP code != 200.
11
+ class ResponseError < Error
12
+
13
+ attr_reader :request_url, :code, :details
14
+
15
+ def initialize(request_url, code, details)
16
+ @request_url, @code, @details = request_url, code, details
17
+ super(message) if message
18
+ end
19
+
20
+ def message; @details['Message']; end
21
+ def type; @details['Type']; end
22
+ def errors; @details['errors']; end
23
+ end
4
24
  end
@@ -28,14 +28,36 @@ module MangoPay
28
28
 
29
29
  module Fetch
30
30
  module ClassMethods
31
- def fetch(id = nil, filters = {})
32
- response = MangoPay.request(:get, url(id), filters)
31
+
32
+ # - Fetching single entity by +id+:
33
+ #
34
+ # MangoPay::User.fetch("user-id") # => {"FirstName"=>"Mango", "LastName"=>"Pay", ...}
35
+ #
36
+ # - Fetching multiple entities with _optional_ +filters+ hash,
37
+ # including _pagination_ params
38
+ # (+page+, +per_page+; see http://docs.mangopay.com/api-references/pagination/):
39
+ #
40
+ # MangoPay::User.fetch() # => [{...}, ...]: list of user data hashes (10 per page by default)
41
+ # MangoPay::User.fetch({'page' => 2, 'per_page' => 3}) # => list of 3 hashes from 2nd page
42
+ #
43
+ # - For paginated queries the +filters+ param will be supplemented by +total_pages+ and +total_items+ info:
44
+ #
45
+ # MangoPay::User.fetch(filter = {'page' => 2, 'per_page' => 3})
46
+ # filter # => {"page"=>2, "per_page"=>3, "total_pages"=>1969, "total_items"=>5905}
47
+ #
48
+ def fetch(id_or_filters = nil)
49
+ id, filters = MangoPay::HTTPCalls::Fetch.parse_id_or_filters(id_or_filters)
50
+ response = MangoPay.request(:get, url(id), {}, filters)
33
51
  end
34
52
  end
35
53
 
36
54
  def self.included(base)
37
55
  base.extend(ClassMethods)
38
56
  end
57
+
58
+ def self.parse_id_or_filters(id_or_filters = nil)
59
+ id_or_filters.is_a?(Hash) ? [nil, id_or_filters] : [id_or_filters, {}]
60
+ end
39
61
  end
40
62
 
41
63
  module Refund
@@ -5,7 +5,7 @@ module MangoPay
5
5
 
6
6
  def self.url(id = nil)
7
7
  if id
8
- "/v2/#{MangoPay.configuration.client_id}/users/legal/#{CGI.escape(id)}"
8
+ "/v2/#{MangoPay.configuration.client_id}/users/legal/#{CGI.escape(id.to_s)}"
9
9
  else
10
10
  "/v2/#{MangoPay.configuration.client_id}/users/legal"
11
11
  end