qonto 0.1.0

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,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7f24ba0d4ac1660f45b44441bbc3b43ed68b2343
4
+ data.tar.gz: 7512617e196450d36f421dd38f84f5d1017cbbf6
5
+ SHA512:
6
+ metadata.gz: 7c57c3fd514dc333f9a5196e6cf5ccfa91e10039b506dbf3a02cd95dc293b77e18d0890809aa667c17cb355f2e477df5d18d610ca150a2d9093ecf7364d57382
7
+ data.tar.gz: 16aacda3639335db6c7e750e7acb8a89a085687e7c0d609d6f8b9e846efdddea40666d6e18098effee6eed1f7ee32dac166c9c9fd770c2ca3ef8d0069a337539
@@ -0,0 +1,50 @@
1
+ version: 2
2
+ jobs:
3
+ build-latest: &common-build
4
+ working_directory: ~/qonto-api-ruby
5
+ docker:
6
+ - image: circleci/ruby:2.4.1-node
7
+ steps:
8
+ - checkout
9
+
10
+ - type: cache-restore
11
+ name: Restore bundle cache
12
+ keys:
13
+ - bump-bundle-{{ checksum "qonto-api.gemspec" }}
14
+ # fallback to using the latest cache if no exact match is found
15
+ - bump-bundle-
16
+
17
+ - run:
18
+ name: Bundle Install
19
+ command: bundle install --path vendor/bundle
20
+
21
+ - type: cache-save
22
+ name: Store bundle cache
23
+ key: bump-bundle-{{ checksum "qonto-api.gemspec" }}
24
+ paths:
25
+ - vendor/bundle
26
+
27
+ - run:
28
+ name: Run tests
29
+ command: bundle exec rspec
30
+ build-2-3:
31
+ <<: *common-build
32
+ docker:
33
+ - image: circleci/ruby:2.3.4-node
34
+ build-2-2:
35
+ <<: *common-build
36
+ docker:
37
+ - image: circleci/ruby:2.2.7-node
38
+ build-2-1:
39
+ <<: *common-build
40
+ docker:
41
+ - image: circleci/ruby:2.1.10-node
42
+
43
+ workflows:
44
+ version: 2
45
+ build:
46
+ jobs:
47
+ - build-latest
48
+ - build-2-3
49
+ - build-2-2
50
+ - build-2-1
@@ -0,0 +1,7 @@
1
+ /.bundle/
2
+ /Gemfile.lock
3
+ /coverage/
4
+ /doc/
5
+ /spec/reports/
6
+ /tmp/
7
+ .DS_Store
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1 @@
1
+ 2.4.1
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/LICENCE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2017- Sébastien Charrier
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,72 @@
1
+ # Qonto API Ruby Client
2
+
3
+ The Qonto API Ruby client provides convenient access to the Qonto API from applications written in Ruby language.
4
+ It is currently up to date with the `v1` version. Qonto API documentation is avaible at https://api-doc.qonto.eu.
5
+
6
+ This project is not affiliated with the Qonto company in any way.
7
+
8
+ ## Installation
9
+
10
+ Add this line to your application's Gemfile:
11
+
12
+ gem 'qonto'
13
+
14
+ And then execute:
15
+
16
+ $ bundle
17
+
18
+ Or install it yourself as:
19
+
20
+ $ gem install qonto
21
+
22
+ ## Requirements
23
+
24
+ * Ruby 2.1+.
25
+
26
+ ## Usage
27
+
28
+ The library needs to be configured with your account's secret key and organization
29
+ slug which are available in your organization dashboard on http://qonto.eu.
30
+
31
+ require 'qonto'
32
+
33
+ # Initialize your client
34
+ client = Qonto::Client.new(slug: 'your-organization-slug', secret_key: 'your-secret-key')
35
+
36
+ You can retrieve your organization bank accounts by calling `get_organization`:
37
+
38
+ # Retrieve your organization object
39
+ organization = client.get_organization
40
+ bank_account = organization.bank_accounts.first
41
+
42
+ # Balance is available for each bank account
43
+ puts "Balance: #{bank_account.balance} €"
44
+
45
+ You can list transactions for a given bank account by calling `list_transactions`:
46
+
47
+ # Paginate through the transactions
48
+ transactions = client.list_transactions(
49
+ bank_account: bank_account,
50
+ per_page: 10,
51
+ current_page: 2
52
+ )
53
+
54
+ transactions.each do |transaction|
55
+ puts " #{transaction.side}: #{transaction.amount} #{transaction.currency} - #{transaction.label}"
56
+ end
57
+
58
+ If a request returns an error, the client raises a `Qonto::Error`. This can be simply
59
+ handled by a `begin/rescue` block:
60
+
61
+ begin
62
+ organization = client.get_organization
63
+ puts "Balance: #{organization.bank_accounts.first.balance} €"
64
+ rescue Qonto::Error => e
65
+ puts "Oops: #{e.to_s}"
66
+ end
67
+
68
+ ## Development
69
+
70
+ After checking out the repo, run `bundle install` to install dependencies. Then, run `rake spec` to run the tests.
71
+
72
+ To install this gem onto your local machine, run `bundle exec rake install`.
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
@@ -0,0 +1,5 @@
1
+ module Qonto
2
+ end
3
+
4
+ require 'qonto/version'
5
+ require 'qonto/client'
@@ -0,0 +1,7 @@
1
+ module Qonto
2
+ module Actions
3
+ end
4
+ end
5
+
6
+ require_relative 'actions/organization'
7
+ require_relative 'actions/transactions'
@@ -0,0 +1,26 @@
1
+ module Qonto
2
+ module Actions
3
+ module Organization
4
+ def get_organization
5
+ response = get("/organizations/#{slug}")
6
+ modelize_organization(response.parsed_response['organization'])
7
+ end
8
+
9
+ private
10
+
11
+ def modelize_organization(organization)
12
+ if !organization['bank_accounts'].nil?
13
+ organization['bank_accounts'] = modelize_bank_accounts(organization['bank_accounts'])
14
+ end
15
+
16
+ Qonto::Model::Organization.new(organization)
17
+ end
18
+
19
+ def modelize_bank_accounts(bank_accounts)
20
+ bank_accounts.map do |bank_account|
21
+ Qonto::Model::BankAccount.new(bank_account)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,31 @@
1
+ module Qonto
2
+ module Actions
3
+ module Transactions
4
+ def list_transactions(bank_account:, current_page: nil, per_page: nil)
5
+ query = prepare_query_string(bank_account, current_page, per_page)
6
+ response = get("/transactions?#{query}")
7
+
8
+ modelize_transactions(response.parsed_response['transactions'])
9
+ end
10
+
11
+ private
12
+
13
+ def prepare_query_string(bank_account, current_page, per_page)
14
+ {
15
+ slug: bank_account.slug,
16
+ iban: bank_account.iban,
17
+ current_page: current_page,
18
+ per_page: per_page
19
+ }.delete_if { |key, value| value.nil? }
20
+ .map { |(key, value)| "#{key}=#{value}" }
21
+ .join('&')
22
+ end
23
+
24
+ def modelize_transactions(transactions)
25
+ transactions.map do |transaction|
26
+ Qonto::Model::Transaction.new(transaction)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,72 @@
1
+ require 'httparty'
2
+ require 'qonto/actions'
3
+ require 'qonto/error'
4
+ require 'qonto/model'
5
+
6
+ module Qonto
7
+ class Client
8
+ include Qonto::Actions::Organization
9
+ include Qonto::Actions::Transactions
10
+
11
+ API_VERSION = '1'.freeze
12
+ BASE_URL = 'https://thirdparty.qonto.eu/v'.freeze
13
+ USER_AGENT = "qonto-api-ruby/#{VERSION}".freeze
14
+
15
+ def initialize(slug:, secret_key:)
16
+ @slug = slug
17
+ @secret_key = secret_key
18
+ end
19
+
20
+ def base_url
21
+ "#{BASE_URL}#{API_VERSION}"
22
+ end
23
+
24
+ def get(path)
25
+ execute :get, path
26
+ end
27
+
28
+ private
29
+
30
+ attr_reader :slug, :secret_key
31
+
32
+ def execute(method, path)
33
+ begin
34
+ response = request(method, path)
35
+ rescue *Error::NET_HTTP_ERRORS => err
36
+ raise ConnectionError.new, err.message
37
+ end
38
+
39
+ case response.code
40
+ when 200..299
41
+ response
42
+ when 400
43
+ raise BadRequestError.new(response)
44
+ when 401
45
+ raise AuthenticationError.new(response)
46
+ when 404
47
+ raise NotFoundError.new(response)
48
+ when 400..499
49
+ raise ResponseError.new(response)
50
+ when 500
51
+ raise InternalServerError.new(response)
52
+ when 500..599
53
+ raise ServerError.new(response)
54
+ end
55
+ end
56
+
57
+ def request(method, path)
58
+ HTTParty.send(method, base_url + path, base_options)
59
+ end
60
+
61
+ def base_options
62
+ {
63
+ format: :json,
64
+ headers: {
65
+ 'Accept' => 'application/json',
66
+ 'Authorization' => "#{slug}:#{secret_key}",
67
+ 'User-Agent' => USER_AGENT
68
+ }
69
+ }
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,82 @@
1
+ module Qonto
2
+ class Error < StandardError
3
+ NET_HTTP_ERRORS = [
4
+ EOFError,
5
+ Errno::ECONNABORTED,
6
+ Errno::ECONNREFUSED,
7
+ Errno::ECONNRESET,
8
+ Errno::EHOSTUNREACH,
9
+ Errno::EINVAL,
10
+ Errno::ENETUNREACH,
11
+ Net::HTTPBadResponse,
12
+ Net::HTTPHeaderSyntaxError,
13
+ Net::ProtocolError,
14
+ Net::OpenTimeout,
15
+ Net::ReadTimeout,
16
+ SocketError,
17
+ Zlib::GzipFile::Error,
18
+ OpenSSL::SSL::SSLError
19
+ ]
20
+
21
+ attr_reader :http_response
22
+
23
+ def initialize(response = nil)
24
+ @http_response = response
25
+ super(build_error_message)
26
+ end
27
+
28
+ def http_request
29
+ http_response.request
30
+ end
31
+
32
+ private
33
+
34
+ def build_error_message
35
+ return nil if http_response.nil?
36
+
37
+ message = "#{http_request_method} "
38
+ message << "#{http_request.path} : "
39
+ message << "#{http_response.code} - "
40
+ message << response_message unless response_message.nil?
41
+ message
42
+ end
43
+
44
+ def http_request_method
45
+ http_request.http_method.name.split('::').last.upcase
46
+ end
47
+
48
+ def response_message
49
+ content_type = http_response.headers['Content-Type']
50
+ if content_type && content_type.start_with?('application/json')
51
+ http_response.parsed_response['message']
52
+ else
53
+ net_http_response = http_response.response
54
+ "#{net_http_response.code} #{net_http_response.message}"
55
+ end
56
+ end
57
+ end
58
+
59
+ # Raised on errors in the 400-499 range
60
+ class ResponseError < Error; end
61
+
62
+ # Raised when the API returns a 400 HTTP status code
63
+ class BadRequestError < ResponseError; end
64
+
65
+ # Raised when the API returns a 401 HTTP status code
66
+ class AuthenticationError < ResponseError; end
67
+
68
+ # Raised when the API returns a 402 HTTP status code
69
+ class PaymentRequiredError < ResponseError; end
70
+
71
+ # Raised when the API returns a 404 HTTP status code
72
+ class NotFoundError < ResponseError; end
73
+
74
+ # Raised on errors in the 500-599 range
75
+ class ServerError < Error; end
76
+
77
+ # Raised when the API returns a 500 HTTP status code
78
+ class InternalServerError < ServerError; end
79
+
80
+ # Raised when we can't establish a connection to the API or if reading the reponse times out
81
+ class ConnectionError < Error; end
82
+ end
@@ -0,0 +1,16 @@
1
+ module Qonto
2
+ module Model
3
+ class Base
4
+ def initialize(attributes = {})
5
+ attributes.each do |key, value|
6
+ m = "#{key}=".to_sym
7
+ send(m, value) if respond_to?(m)
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
13
+
14
+ require_relative 'model/bank_account'
15
+ require_relative 'model/organization'
16
+ require_relative 'model/transaction'
@@ -0,0 +1,12 @@
1
+ module Qonto
2
+ module Model
3
+ class BankAccount < Base
4
+ attr_accessor :slug
5
+ attr_accessor :iban
6
+ attr_accessor :bic
7
+ attr_accessor :current
8
+ attr_accessor :balance
9
+ attr_accessor :balance_cents
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,8 @@
1
+ module Qonto
2
+ module Model
3
+ class Organization < Base
4
+ attr_accessor :slug
5
+ attr_accessor :bank_accounts
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,16 @@
1
+ module Qonto
2
+ module Model
3
+ class Transaction < Base
4
+ attr_accessor :amount
5
+ attr_accessor :amount_cents
6
+ attr_accessor :local_amount
7
+ attr_accessor :local_amount_cents
8
+ attr_accessor :side
9
+ attr_accessor :operation_type
10
+ attr_accessor :currency
11
+ attr_accessor :local_currency
12
+ attr_accessor :settled_at
13
+ attr_accessor :label
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,3 @@
1
+ module Qonto
2
+ VERSION = '0.1.0'.freeze
3
+ end
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'qonto/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'qonto'
8
+ spec.version = Qonto::VERSION
9
+ spec.authors = ['Sébastien Charrier']
10
+ spec.email = ['scharrier@gmail.com']
11
+ spec.licenses = ['MIT']
12
+
13
+ spec.summary = 'A Ruby client for the Qonto Api.'
14
+ spec.homepage = 'https://github.com/scharrier/qonto-ruby'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.require_paths = ['lib']
18
+ spec.required_ruby_version = '>= 2.1.0'
19
+
20
+ spec.add_runtime_dependency 'httparty', '~> 0'
21
+
22
+ spec.add_development_dependency 'rake', '~> 12'
23
+ spec.add_development_dependency 'rspec', '~> 3'
24
+ spec.add_development_dependency 'webmock', '~> 3'
25
+ end
metadata ADDED
@@ -0,0 +1,120 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: qonto
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Sébastien Charrier
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-09-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: httparty
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '12'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '12'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: webmock
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3'
69
+ description:
70
+ email:
71
+ - scharrier@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".circleci/config.yml"
77
+ - ".gitignore"
78
+ - ".rspec"
79
+ - ".ruby-version"
80
+ - Gemfile
81
+ - LICENCE
82
+ - README.md
83
+ - Rakefile
84
+ - lib/qonto.rb
85
+ - lib/qonto/actions.rb
86
+ - lib/qonto/actions/organization.rb
87
+ - lib/qonto/actions/transactions.rb
88
+ - lib/qonto/client.rb
89
+ - lib/qonto/error.rb
90
+ - lib/qonto/model.rb
91
+ - lib/qonto/model/bank_account.rb
92
+ - lib/qonto/model/organization.rb
93
+ - lib/qonto/model/transaction.rb
94
+ - lib/qonto/version.rb
95
+ - qonto.gemspec
96
+ homepage: https://github.com/scharrier/qonto-ruby
97
+ licenses:
98
+ - MIT
99
+ metadata: {}
100
+ post_install_message:
101
+ rdoc_options: []
102
+ require_paths:
103
+ - lib
104
+ required_ruby_version: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ version: 2.1.0
109
+ required_rubygems_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ requirements: []
115
+ rubyforge_project:
116
+ rubygems_version: 2.6.11
117
+ signing_key:
118
+ specification_version: 4
119
+ summary: A Ruby client for the Qonto Api.
120
+ test_files: []