mangopay 3.0.1 → 3.0.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.
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