finix 0.13 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- ODNmZGZiNzc0NGE2NWI5NTlmMzUyZDA4NWIxZmFjZjdmM2Q2ODFmZg==
5
- data.tar.gz: !binary |-
6
- MGVjZWQ5NDgwNTBhZmFlNGJjODZiZjZhM2M4YTBiYmY3ODk3NDI3NQ==
2
+ SHA256:
3
+ metadata.gz: ade5c9e0c2bd58f5ac07581952654d5b50aeed67606a423dafa3639c183f5298
4
+ data.tar.gz: 444938eed6284a21381bb13558b3c8ec5111361f583f216a13b9b038ac4448da
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- NDQ3MzBjOTQ0ZDg5OTRlZGIxYmJjYWY0OWMzYmM3MmU4NjZkYzJkZWU2MDIz
10
- OTNhNWZlOTg2MzkyZTA4OWZjNDhiZTk4ZGEzMzEzN2RjMGM0MzAzZGM2Zjhi
11
- MGU4YjRmMWQwYzE3ZDhhMWIxZmE5ZTU1ZjkwYzBkMGQ2MTRlYjU=
12
- data.tar.gz: !binary |-
13
- YjFkOGQ5M2E3NzMxYjg1ZDg4NjZjYmJhNmJmNjFjOWMzZTRmNGUxMWQyMjBk
14
- NWI2ZWE3MDcyMThhYzVlNWMwM2UyY2FiZGJhZDdjODBkNjliZWQxNWFmMjkz
15
- MGFjNjczYTI0ODVkYWU0OWU4ZGUzNzA2ZmRhNWY2ZjljYThhNTI=
6
+ metadata.gz: 9ce96db67f73345494dcd2407cdd4e493d9d73fdf533875516e85d3edfc99740b539540bfedf961aec5cd9dd222bd4f990bcd225d6e55c3ccf96ae52f5df3435
7
+ data.tar.gz: bf1d770c30b5e7a4d7795d2f37e8c4a8a1814cf957603a2ce18adcff43727e3779ad3bd378e5b4a494cfcb965494c879ea730cc197d48bc6f480cfa22692e3c0
@@ -0,0 +1,22 @@
1
+ version: 2.1
2
+ jobs:
3
+ rspec_tests:
4
+ working_directory: ~/workspace
5
+ docker:
6
+ - image: circleci/ruby:2.7
7
+ steps:
8
+ - checkout
9
+ - restore_cache:
10
+ keys:
11
+ - v1-dep-{{checksum "Gemfile.lock"}}
12
+ - run: 'bundle check --path=vendor/bundle || bundle install --path=vendor/bundle --jobs=4 --retry=3'
13
+ - save_cache:
14
+ key: v1-dep-{{checksum "Gemfile.lock"}}
15
+ paths:
16
+ - vendor/bundle
17
+ - ~/.bundle
18
+ - run: bundle exec rspec --format documentation
19
+ workflows:
20
+ test:
21
+ jobs:
22
+ - rspec_tests
data/.gitignore CHANGED
@@ -1,4 +1,11 @@
1
1
  Gemfile.lock
2
2
  .idea/
3
3
  *.gem
4
- .report/
4
+ .report/
5
+
6
+ *ignore*
7
+ .vcr/
8
+ *.iml
9
+ .byebug_history
10
+ .DS_Store
11
+ .env
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
@@ -1 +1 @@
1
- ruby-1.9.3
1
+ ruby-2.7
data/Gemfile CHANGED
@@ -1,10 +1,9 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gem 'rake', '~> 10.4.2'
3
+ gem 'rake', '~> 13.0.1'
4
4
 
5
5
  group :test do
6
- gem 'minitest', '~> 5.10.1'
7
- gem 'minitest-reporters', '~> 1.1.13'
6
+ gem 'rspec', '~> 3.5.0'
8
7
  end
9
8
 
10
- gemspec
9
+ gemspec
data/README.md CHANGED
@@ -3,4 +3,37 @@
3
3
  [![CircleCI](https://circleci.com/gh/finix-payments/processing-ruby.svg?style=svg&circle-token=326db95733638463152e926a1016ec0383e554d2)](https://circleci.com/gh/finix-payments/processing-ruby)
4
4
 
5
5
  ## Getting Started
6
- `gem install finix`
6
+ Add this line to your application's Gemfile:
7
+
8
+ gem 'finix'
9
+
10
+ Then execute:
11
+
12
+ $ bundle
13
+
14
+ Or install it yourself as:
15
+
16
+ $ gem install finix
17
+
18
+ ## Contributing
19
+
20
+ 1. Fork it
21
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
22
+ 3. Write your code **and unit tests**
23
+ 4. Ensure all tests still pass (`bundle exec rspec`)
24
+ 5. Commit your changes (`git commit -am 'Add some feature'`)
25
+ 6. Push to the branch (`git push origin my-new-feature`)
26
+ 7. Create new pull request
27
+
28
+
29
+ ### Tests
30
+
31
+ To run all tests:
32
+
33
+ $ bundle exec rspec
34
+
35
+
36
+ To run a specific test:
37
+
38
+ $ bundle exec rspec ./spec/finix/resources/application_spec.rb
39
+
data/Rakefile CHANGED
@@ -1,9 +1,5 @@
1
1
  require 'rake'
2
2
  require 'bundler/gem_tasks'
3
3
  require 'rake/testtask'
4
-
5
- desc 'Run test suite'
6
- Rake::TestTask.new do |t|
7
- # t.test_files = FileList['test/**/test_*.rb']
8
- t.pattern ='test/**/test_*.rb'
9
- end
4
+ require 'rspec/core/rake_task'
5
+ require 'logger'
@@ -5,7 +5,7 @@ require 'finix/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = 'finix'
8
- spec.required_ruby_version = '>= 1.9'
8
+ spec.required_ruby_version = '>= 2.0'
9
9
  spec.version = Finix::VERSION
10
10
  spec.authors = ['finix-payments']
11
11
  spec.email = ['support@finixpayments.com']
@@ -22,15 +22,6 @@ Gem::Specification.new do |spec|
22
22
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
23
23
  spec.require_paths = ['lib']
24
24
 
25
- spec.add_dependency('faraday', '~> 0.10.0')
26
- spec.add_dependency('faraday_middleware', '~> 0.10.1')
27
-
28
- if RUBY_VERSION >= '2.0'
29
- spec.add_dependency('json', '~> 2.0.2')
30
- spec.add_dependency('addressable', '~> 2.5.0')
31
- else
32
- spec.add_dependency('public_suffix', '~> 1.4.6')
33
- spec.add_dependency('json', '~> 1.8')
34
- spec.add_dependency('addressable', '~> 2.3')
35
- end
25
+ spec.add_dependency('faraday', '~> 1.1.0')
26
+ spec.add_dependency('faraday_middleware', '~> 1.0.0')
36
27
  end
@@ -1,6 +1,6 @@
1
- require 'finix/version' unless defined? Finix::VERSION
2
- require 'finix/client'
3
- require 'finix/error'
1
+ require_relative 'finix/version' unless defined? Finix::VERSION
2
+ require_relative 'finix/client'
3
+ require_relative 'finix/errors'
4
4
 
5
5
  module Finix
6
6
 
@@ -8,15 +8,15 @@ module Finix
8
8
  @config = {:root_url => 'https://localhost/processing'}
9
9
  @hypermedia_registry = {}
10
10
  @errors_registry = {
11
- :unknown => Finix::ResourceErrors,
12
- 400 => Finix::BadRequest,
13
- 401 => Finix::Unauthorized,
14
- 402 => Finix::UpstreamProcessorError,
15
- 403 => Finix::Forbidden,
16
- 404 => Finix::NotFound,
17
- 405 => Finix::MethodNotAllowed,
18
- 422 => Finix::UnprocessableEntity,
19
- 500 => Finix::InternalServerError
11
+ :unknown => Errors,
12
+ 400 => BadRequest,
13
+ 401 => Unauthorized,
14
+ 402 => PaymentRequired,
15
+ 403 => Forbidden,
16
+ 404 => NotFound,
17
+ 405 => MethodNotAllowed,
18
+ 422 => UnprocessableEntity,
19
+ 500 => InternalServerError
20
20
  }
21
21
 
22
22
  class << self
@@ -35,7 +35,7 @@ module Finix
35
35
  @config[:user] = @config[:user].strip unless @config[:user].nil?
36
36
  @config[:password] = @config[:password].strip unless @config[:password].nil?
37
37
 
38
- @client = Finix::Client.new @config
38
+ @client = Client.new @config
39
39
  end
40
40
 
41
41
  def split_the_href(href)
@@ -43,12 +43,14 @@ module Finix
43
43
  end
44
44
 
45
45
  def get_href(cls)
46
- href = Finix.hypermedia_registry.key(cls)
47
- href = Finix.hypermedia_registry.key(cls.superclass) if href.nil?
48
- if href.nil? # support wrapper module
49
- mod = cls.name.split('::').first
50
- scls = cls.superclass.superclass.name.split('::').last
51
- href = Finix.hypermedia_registry.key(self.instance_eval "#{mod}::#{scls}")
46
+ href = (not cls.nil? and not cls.hypermedia_types.nil?) ? cls.hypermedia_types.last : hypermedia_registry.key(cls)
47
+
48
+ sps = cls
49
+ while href.nil?
50
+ sps = sps.superclass
51
+ break if sps.nil?
52
+ clss = Finix::Utils.eval_class cls, sps
53
+ href = hypermedia_registry.key(clss)
52
54
  end
53
55
  href
54
56
  end
@@ -56,11 +58,17 @@ module Finix
56
58
  def from_hypermedia_registry(href, attributes={})
57
59
  split_uri = split_the_href(href)
58
60
  split_uri.reverse!.each do |resource|
59
- cls = Finix.hypermedia_registry[resource]
60
- cls = cls.send :hypermedia_subtype, attributes if not cls.nil? and cls.respond_to?(:hypermedia_subtype)
61
+ cls = find_resource_cls(resource, attributes)
61
62
  return cls unless cls.nil?
62
63
  end
63
- Finix::Utils.eval_class self, 'UnknownResource'
64
+ Finix::Utils.eval_class self, UnknownResource
65
+ end
66
+
67
+ def find_resource_cls(resource, attributes={})
68
+ cls = hypermedia_registry[resource]
69
+ # cls = hypermedia_registry["__stub__#{resource}"] if cls.nil?
70
+ cls = cls.send :hypermedia_subtype, attributes if not cls.nil? and cls.respond_to?(:hypermedia_subtype)
71
+ cls
64
72
  end
65
73
 
66
74
  def get(*args, &block)
@@ -8,7 +8,7 @@ require 'finix/response/finix_error_middleware'
8
8
  module Finix
9
9
  class Client
10
10
 
11
- DEFAULTS = {
11
+ DEFAULT_CONFIG = {
12
12
  :logging_level => 'WARN',
13
13
  :connection_timeout => 60,
14
14
  :read_timeout => 60,
@@ -21,7 +21,7 @@ module Finix
21
21
  attr_accessor :config
22
22
 
23
23
  def initialize(options={})
24
- @config = DEFAULTS.merge options
24
+ @config = DEFAULT_CONFIG.merge options
25
25
  build_conn
26
26
  end
27
27
 
@@ -0,0 +1,47 @@
1
+ require_relative 'hal_resource'
2
+ module Finix
3
+
4
+ class Errors < ::StandardError
5
+ include Finix::HalResource
6
+ attr_reader :code
7
+ attr_reader :total
8
+
9
+ def initialize(response=nil)
10
+ @code = response[:status].to_i
11
+ @total = response[:body]['total'].to_i
12
+
13
+ load_page_from_response! response
14
+ @attributes['errors'] = @attributes.delete 'items'
15
+ @attributes.delete 'page'
16
+ end
17
+
18
+ def to_s
19
+ "#{@errors}"
20
+ end
21
+
22
+ end
23
+
24
+ class BadRequest < Errors
25
+ end
26
+
27
+ class Unauthorized < Errors
28
+ end
29
+
30
+ class PaymentRequired < Errors
31
+ end
32
+
33
+ class Forbidden < Errors
34
+ end
35
+
36
+ class NotFound < Errors
37
+ end
38
+
39
+ class MethodNotAllowed < Errors
40
+ end
41
+
42
+ class UnprocessableEntity < Errors
43
+ end
44
+
45
+ class InternalServerError < Errors
46
+ end
47
+ end
@@ -5,21 +5,49 @@ module Finix
5
5
  attr_accessor :attributes
6
6
 
7
7
  def method_missing(method, *args, &block)
8
- if @attributes.has_key?(method.to_s)
9
- return @attributes[method.to_s]
8
+ attributes = [@attributes]
9
+ attributes << @attributes['page'] unless @attributes['page'].nil?
10
+ attributes.each do |attrs|
11
+ if attrs.has_key?(method.to_s)
12
+ return attrs[method.to_s]
13
+ end
14
+ end
15
+
16
+ if @attributes.empty? or (@attributes.has_key?('page') and not @attributes.has_key?('items'))
17
+ self.refresh if self.respond_to? :refresh
18
+ return self.send :method_missing, method, *args, &block
10
19
  end
11
20
 
12
21
  case method.to_s
13
- when /(.+)=$/
22
+ when /(.+)=$/ # support setting
14
23
  attr = method.to_s.chop
15
- @attributes[attr] = args[0]
24
+ @attributes[attr] = args.slice(0)
16
25
  else
17
- if @hyperlinks.has_key? "#{method}"
18
- value = @hyperlinks["#{method}"]
19
- result = value.call
20
- return result
21
- end
26
+ @hyperlinks.send :method_missing, method, *args, &block
22
27
  end
23
28
  end
29
+
30
+ def load_page_from_response!(response)
31
+ body = Finix::Utils.indifferent_read_access response.body
32
+
33
+ hash_class = Finix::Utils.eval_class(self, IndifferentHash)
34
+ @hyperlinks = hash_class.new
35
+ links = body.delete('_links')
36
+ links.each { |key, link| @hyperlinks[key.to_sym] = link[:href] } unless links.nil?
37
+
38
+ page = body.delete('page')
39
+ @attributes = {'items' => [], 'page' => hash_class.new(page)} # clear attributes
40
+ if body.has_key? '_embedded'
41
+ resource_name, resources = body.delete('_embedded').first
42
+ @resource_class = Finix.from_hypermedia_registry resource_name
43
+ @attributes['items'] = resources.map do |attrs|
44
+ cls = Finix.from_hypermedia_registry resource_name, attrs
45
+ cls.construct_from_response attrs
46
+ end
47
+ end
48
+
49
+ @attributes.merge! body
50
+ end
24
51
  end
25
52
  end
53
+
@@ -0,0 +1,25 @@
1
+ module Finix
2
+ class IndifferentHash < ::Hash
3
+
4
+ def initialize(*args)
5
+ original_hash = args.slice!(0) || {}
6
+ self.merge!(original_hash)
7
+ end
8
+
9
+ def method_missing(method, *args, &block)
10
+ if self.has_key? "#{method}"
11
+ value = self["#{method}"]
12
+ return value.call(*args) if value.respond_to? :call
13
+ return value
14
+ end
15
+ end
16
+
17
+ def count(*args)
18
+ if self.has_key? 'count'
19
+ raise Exception.new 'Unsupported block_given exception' if block_given?
20
+ return self.send :method_missing, :count, *args
21
+ end
22
+ super(*args)
23
+ end
24
+ end
25
+ end
@@ -1,80 +1,203 @@
1
1
  require 'cgi'
2
+ require 'ostruct'
2
3
  require_relative 'hal_resource'
4
+ require_relative 'indifferent_hash'
3
5
 
4
6
  module Finix
5
7
  class Pagination
6
8
 
7
- include Enumerable
9
+ include ::Enumerable
8
10
  include HalResource
9
11
 
10
12
  attr_accessor :resource_class
13
+ attr_reader :attributes
14
+ attr_reader :hyperlinks
11
15
 
12
- def initialize(href, opts={})
13
- @hyperlinks = {}
14
- @attributes = {}
16
+ def initialize(*args)
17
+ opts = args.slice!(0) || {}
18
+ href = opts.delete(:href)
15
19
 
20
+ @hyperlinks = Finix::Utils.eval_class(self, IndifferentHash).new
16
21
  @hyperlinks[:self] = href
22
+ @attributes = {}
17
23
  @resource_class = nil
24
+ extract_opts opts
25
+ end
26
+
27
+ def init!(*args)
28
+ opts = args.slice(0) || {}
29
+ extract_opts opts
30
+ self
18
31
  end
19
32
 
20
33
  def each
21
34
  return enum_for :each unless block_given?
22
- current
35
+ fetch :first
23
36
  loop do
24
37
  items.each { |item| yield item }
25
38
  fetch :next
26
39
  end
27
40
  end
28
41
 
29
- def current
30
- refresh unless items
31
- items
42
+ def count(*args)
43
+ refresh # always refresh to get last items
44
+
45
+ cnt = (block_given?) ? super(*args) : self.send(:method_missing, :count, args)
46
+ cnt = 0 if cnt.nil?
47
+ cnt
32
48
  end
33
49
 
34
- def fetch(scope) # :next, :last, :first, :prev, :self
35
- scope = scope.to_s.to_sym
36
- if @hyperlinks[scope]
37
- load_from @hyperlinks[scope]
50
+ def fetch(scope = nil) # :next, :last, :first, :prev, :self
51
+ opts = {}
52
+ if scope.is_a? Hash
53
+ opts = Finix::Utils.indifferent_read_access scope
54
+ scope = nil
55
+ end
56
+
57
+ scope = :self if scope.nil?
58
+ scope = scope.to_s.to_sym unless scope.nil?
59
+
60
+ href = @hyperlinks[scope]
61
+ unless href
62
+ if scope == :first
63
+ @attributes['page']['offset'] = 0 unless @attributes['page']['offset'].nil?
64
+ href = @hyperlinks[:self]
65
+ href = href[/[^\?]+/]
66
+ end
67
+ end
68
+
69
+ if href
70
+ load_from href, opts
38
71
  return self.items
39
72
  end
40
73
 
41
74
  raise StopIteration
42
75
  end
43
76
 
77
+ alias retrieve fetch
78
+
44
79
  def refresh
45
- fetch :self
80
+ fetch
81
+ self
46
82
  end
47
83
 
84
+ alias load! refresh
85
+ alias retrieve refresh
86
+
48
87
  def create(attrs={})
49
- attrs = attrs.attributes if attrs.is_a?(Finix::Resource)
88
+ attrs = attrs.attributes if attrs.is_a?(Resource)
50
89
  attrs = Finix::Utils.indifferent_read_access attrs
90
+
51
91
  href = @hyperlinks[:self]
52
92
  @resource_class = Finix.from_hypermedia_registry href, attrs
53
- @resource_class.new(attrs, href).save
93
+
94
+ attrs[:href] = href
95
+ @resource_class.new(attrs).save
96
+ end
97
+
98
+ def next_page
99
+ fetch :next
100
+ self
101
+ end
102
+
103
+ def previous_page
104
+ fetch :prev
105
+ self
106
+ end
107
+
108
+ def last_page
109
+ fetch :last
110
+ self
111
+ end
112
+
113
+ def first_page
114
+ fetch :first
115
+ self
116
+ end
117
+
118
+ def total
119
+ # refresh unless loaded
120
+ self.page.count
121
+ end
122
+
123
+ def num_pages
124
+ num = total / limit
125
+ num += 1 if total % limit > 0
126
+ num
127
+ end
128
+
129
+ def loaded
130
+ not self.items.nil?
54
131
  end
55
132
 
56
133
  private
57
134
 
58
- def load_from(url, params = {})
59
- params ||= {}
135
+ # def current_page
136
+ # (offset / limit) + 1
137
+ # end
138
+
139
+ def extract_opts(opts={})
140
+ opts = Finix::Utils.indifferent_read_access opts
141
+ limit = opts.delete('limit')
142
+ offset = opts.delete('offset')
143
+ @attributes['page'] = @attributes['page'] || {}
144
+ @attributes['page']['limit'] = limit unless limit.nil?
145
+ @attributes['page']['offset'] = offset unless offset.nil?
146
+ @attributes.merge! opts unless opts.empty?
147
+
148
+ if not limit.nil? or not offset.nil? # reset @hyperlinks
149
+ @hyperlinks.reject! {|k, v| k.to_s != 'self'}
150
+ parsed_url = URI.parse(@hyperlinks[:self])
151
+ parsed_url.query = nil
152
+ @hyperlinks[:self] = parsed_url.to_s
153
+ end
154
+ end
60
155
 
61
- response = Finix.get url, params
62
- body = Finix::Utils.indifferent_read_access response.body
156
+ def load_from(url, opts = {})
157
+ parsed_url = URI.parse(url)
63
158
 
64
- links = body.delete('_links')
65
- links.each { |key, link| @hyperlinks[key.to_sym] = link[:href] }
159
+ params = {}
160
+ params.merge! @attributes['page'] if @attributes.has_key? 'page'
161
+ params.merge! parse_query(parsed_url.query)
162
+ parsed_url.query = nil # remove query
66
163
 
67
- @attributes = {} # clear attributes
68
- if body.has_key? '_embedded'
69
- resource_name, resources = body.delete('_embedded').first
70
- @resource_class = Finix.from_hypermedia_registry resource_name
71
- @attributes['items'] = resources.map do |attrs|
72
- cls = Finix.from_hypermedia_registry resource_name, attrs
73
- cls.construct_from_response attrs
74
- end
75
- @attributes['page'] = body.delete('page')
164
+ # params page
165
+ opts ||= {}
166
+ page = opts.delete('page')
167
+ unless page.nil?
168
+ page = Finix::Utils.indifferent_read_access page
169
+ params.merge! page unless page.nil?
76
170
  end
171
+
172
+ params.merge! opts unless opts.empty?
173
+ params.delete('count') # remove count from previous query
174
+
175
+ response = Finix.get parsed_url.to_s, params
176
+ load_page_from_response! response
77
177
  end
78
178
 
179
+ # Stolen from Mongrel, with some small modifications:
180
+ # Parses a query string by breaking it up at the '&'
181
+ # and ';' characters. You can also use this to parse
182
+ # cookies by changing the characters used in the second
183
+ # parameter (which defaults to '&;').
184
+ def parse_query(qs, d = nil)
185
+ params = {}
186
+ (qs || '').split(d ? /[#{d}] */n : /[&;] */n).each do |p|
187
+ k, v = p.split('=', 2).map { |x| CGI::unescape(x) }
188
+ if (cur = params[k])
189
+ if cur.class == Array
190
+ params[k] << v
191
+ else
192
+ params[k] = [cur, v]
193
+ end
194
+ else
195
+ params[k] = v
196
+ end
197
+ end
198
+
199
+ params
200
+ end
79
201
  end
80
- end
202
+ end
203
+
@@ -8,6 +8,9 @@ require 'finix/resources/identity'
8
8
  require 'finix/resources/processor'
9
9
  require 'finix/resources/token'
10
10
  require 'finix/resources/merchant'
11
+ require 'finix/resources/merchant_profile'
12
+ require 'finix/resources/risk_profile'
13
+ require 'finix/resources/fee_profile'
11
14
  require 'finix/resources/payment_instrument'
12
15
  require 'finix/resources/payment_card'
13
16
  require 'finix/resources/bank_account'
@@ -18,4 +21,5 @@ require 'finix/resources/verification'
18
21
  require 'finix/resources/dispute'
19
22
  require 'finix/resources/evidence'
20
23
  require 'finix/resources/refund'
21
- require 'finix/resources/settlement'
24
+ require 'finix/resources/settlement'
25
+ require 'finix/resources/error'
@@ -14,6 +14,7 @@ module Finix
14
14
  attrs = attrs.attributes if attrs.is_a?(Finix::Resource)
15
15
  self.processors.create(attrs)
16
16
  end
17
+ alias enable_processor create_processor
17
18
 
18
19
  def create_token(attrs={})
19
20
  attrs = attrs.attributes if attrs.is_a?(Finix::Resource)
@@ -11,6 +11,9 @@ module Finix
11
11
  end
12
12
 
13
13
  def capture(attrs={})
14
+ if attrs['capture_amount'].nil?
15
+ attrs['capture_amount'] = self.amount
16
+ end
14
17
  self.attributes = self.attributes.merge attrs
15
18
  self.save
16
19
  end
@@ -0,0 +1,12 @@
1
+ module Finix
2
+ class Error < ::StandardError
3
+ include Finix::Resource
4
+ include Finix::HypermediaRegistry
5
+
6
+ define_hypermedia_types [:errors]
7
+
8
+ def message
9
+ @attributes['message']
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,8 @@
1
+ module Finix
2
+ class FeeProfile
3
+ include Finix::Resource
4
+ include Finix::HypermediaRegistry
5
+
6
+ define_hypermedia_types [:fee_profiles]
7
+ end
8
+ end
@@ -11,7 +11,7 @@ module Finix
11
11
  def define_hypermedia_types(types)
12
12
  @hypermedia_types = types.map! do |t|
13
13
  t.to_s
14
- end.sort!.freeze
14
+ end.sort!
15
15
 
16
16
  @hypermedia_types.each do |type|
17
17
  Finix.hypermedia_registry[type] = self
@@ -23,4 +23,4 @@ module Finix
23
23
 
24
24
  end
25
25
 
26
- end
26
+ end
@@ -0,0 +1,8 @@
1
+ module Finix
2
+ class MerchantProfile
3
+ include Finix::Resource
4
+ include Finix::HypermediaRegistry
5
+
6
+ define_hypermedia_types [:merchant_profiles]
7
+ end
8
+ end
@@ -10,13 +10,11 @@ module Finix
10
10
  def hypermedia_subtype(response)
11
11
  unless response.nil?
12
12
  type = response['instrument_type'] || response['type']
13
- name = self.name.sub! 'PaymentInstrument', 'PaymentCard'
14
13
  if type == 'PAYMENT_CARD'
15
- name = self.name.sub! 'PaymentInstrument', 'PaymentCard'
14
+ name = self.name.sub 'PaymentInstrument', 'PaymentCard'
16
15
  elsif type == 'BANK_ACCOUNT'
17
- name = self.name.sub! 'PaymentInstrument', 'BankAccount'
16
+ name = self.name.sub 'PaymentInstrument', 'BankAccount'
18
17
  end
19
-
20
18
  return self.instance_eval name unless name.nil?
21
19
  end
22
20
  self
@@ -1,29 +1,35 @@
1
- require File.expand_path('../../pagination', __FILE__)
2
- require File.expand_path('../../utils', __FILE__)
3
- require File.expand_path('../../hal_resource', __FILE__)
4
- require 'addressable/template'
1
+ require_relative '../utils'
2
+ require_relative '../hal_resource'
3
+ require_relative '../pagination'
4
+ require_relative '../indifferent_hash'
5
5
 
6
6
  module Finix
7
-
8
7
  module Resource
9
-
10
8
  include HalResource
11
9
 
12
- def initialize(attributes = {}, href = nil)
13
- @attributes = Utils.indifferent_read_access attributes
10
+ def initialize(*args)
11
+ opts = args.slice!(0) || {}
12
+ href = opts.delete(:href)
13
+ @attributes = Finix::Utils.indifferent_read_access opts
14
14
 
15
- @hyperlinks = {}
15
+ @hyperlinks = Finix::Utils.eval_class(self, IndifferentHash).new
16
16
  @hyperlinks[:self] = href if href =~ URI::regexp
17
17
  end
18
18
 
19
+ alias links hyperlinks
20
+
19
21
  def hydrate(links)
20
22
  links.each do |key, link|
21
23
  property = key.sub(/.*?\./, '')
22
24
 
25
+ href = link[:href]
23
26
  if property == 'self'
24
- @hyperlinks[:self] = link[:href]
27
+ @hyperlinks[:self] = href
25
28
  else
26
- @hyperlinks[property] = Finix::Utils.callable(Finix::Utils.eval_class(self, 'Pagination').new link[:href], {})
29
+ split_uri = Finix.split_the_href(href).reverse!
30
+ cls = Finix.find_resource_cls split_uri[0]
31
+ cls = cls.nil? ? Finix.from_hypermedia_registry(href) : Finix::Utils.eval_class(self, Pagination)
32
+ @hyperlinks[property] = Finix::Utils.callable(cls.new :href => href)
27
33
  end
28
34
  end
29
35
  end
@@ -96,9 +102,9 @@ module Finix
96
102
 
97
103
  module ClassMethods
98
104
 
105
+ # this is class method, not callable from instance
99
106
  def construct_from_response(payload)
100
107
  payload = Finix::Utils.indifferent_read_access payload
101
-
102
108
  links = payload.delete('_links') || {}
103
109
  instance = self.new payload
104
110
  instance.hydrate(links)
@@ -107,17 +113,22 @@ module Finix
107
113
 
108
114
  def fetch(*arguments)
109
115
  if arguments.nil? or arguments.empty? or arguments[0].nil? or arguments[0].to_s.empty?
110
- href = Finix.hypermedia_registry.key(self)
111
- return Finix::Utils.eval_class(self, 'Pagination').new href
116
+ href = Finix.get_href self
117
+ # href = Finix.hypermedia_registry.key(self)
118
+ return Finix::Utils.eval_class(self, Pagination).new :href => href
112
119
  end
113
120
 
114
121
  options = arguments.slice!(0) or {}
115
122
  if options.is_a? String and options =~ URI::regexp
116
123
  href = options
117
124
  else
118
- href = Finix.hypermedia_registry.key(self) or Finix.hypermedia_registry.key(self.class)
119
- id = options if options.is_a? String
120
- id = options.delete(:id) if options.is_a? Hash
125
+ href = Finix.get_href(self) or Finix.get_href(self.class)
126
+ if options.is_a? Hash
127
+ options = Finix::Utils.indifferent_read_access options
128
+ id = options.delete('id')
129
+ elsif options.is_a? String
130
+ id = options
131
+ end
121
132
  href = "#{href}/#{id}" unless id.nil?
122
133
  end
123
134
 
@@ -125,9 +136,25 @@ module Finix
125
136
  construct_from_response response.body
126
137
  end
127
138
 
139
+ def pagination(*args)
140
+ href = Finix.get_href self
141
+ # href = Finix.hypermedia_registry.key(self)
142
+ opts = args.slice!(0) || {}
143
+ opts[:href] = href
144
+ Finix::Utils.eval_class(self, Pagination).new opts
145
+ end
146
+
128
147
  alias find fetch
129
- alias retrieve fetch
130
- end
131
148
 
149
+ def retrieve(*args)
150
+ pager_or_resource = fetch *args
151
+
152
+ if pager_or_resource.is_a? Pagination
153
+ pager_or_resource.load! unless pager_or_resource.loaded
154
+ end
155
+
156
+ pager_or_resource
157
+ end
158
+ end
132
159
  end
133
160
  end
@@ -0,0 +1,8 @@
1
+ module Finix
2
+ class RiskProfile
3
+ include Finix::Resource
4
+ include Finix::HypermediaRegistry
5
+
6
+ define_hypermedia_types [:risk_profiles]
7
+ end
8
+ end
@@ -3,10 +3,11 @@ module Finix
3
3
  include Finix::Resource
4
4
  include Finix::HypermediaRegistry
5
5
 
6
- define_hypermedia_types [:transfers]
6
+ define_hypermedia_types [:transfers, :funding_transfers, :fees]
7
7
 
8
- def reverse(refund_amount=0)
9
- self.reversals.create :refund_amount => refund_amount
8
+ def reverse(args=0)
9
+ atts = args.is_a?(Hash) ? {}.merge(args) : {:refund_amount => args}
10
+ self.reversals.create atts
10
11
  end
11
12
  end
12
13
  end
@@ -1,4 +1,7 @@
1
1
  module Finix
2
+ # Your User is equivalent to an API Key and is used to authenticate when
3
+ # performing operations on the Finix API.
4
+
2
5
  class User
3
6
  include Finix::Resource
4
7
  include Finix::HypermediaRegistry
@@ -1,17 +1,15 @@
1
1
  require 'faraday'
2
- require 'finix/error'
2
+ require_relative '../errors'
3
3
 
4
4
  module Faraday
5
5
 
6
6
  class Response::RaiseApiError < Response::Middleware
7
-
8
7
  def on_complete(response)
9
8
  status_code = response[:status].to_i
10
9
  error_class = Finix.errors_registry[status_code]
11
- raise Finix.errors_registry[:unknown].new(response) if error_class.nil? and status_code >= 400
12
- raise error_class.new(response) if error_class
10
+ raise Finix.errors_registry[:unknown].new response if error_class.nil? and status_code >= 400
11
+ raise error_class.new response if error_class
13
12
  end
14
-
15
13
  end
16
14
 
17
15
  end
@@ -1,8 +1,9 @@
1
1
  module Finix
2
2
  module Utils
3
- def eval_class(slf, name)
4
- mod = slf.class.name.split("::").first unless slf.kind_of? Class or slf.kind_of? Module
5
- mod = slf.name.split("::").first if mod.nil?
3
+ def eval_class(slf, cls)
4
+ mod = slf.class.name.sub(/::.*/, '') unless slf.kind_of? Class or slf.kind_of? Module
5
+ mod = slf.name.sub(/::.*/, '') if mod.nil?
6
+ name = demodulize cls.name
6
7
  self.instance_eval "#{mod}::#{name}"
7
8
  end
8
9
 
@@ -39,6 +40,10 @@ module Finix
39
40
  indifferent
40
41
  end
41
42
 
43
+ def demodulize(class_name_in_module)
44
+ class_name_in_module.to_s.sub(/^.*::/, '')
45
+ end
46
+
42
47
  extend self
43
48
  end
44
49
  end
@@ -1,3 +1,3 @@
1
1
  module Finix
2
- VERSION = '0.13'
2
+ VERSION = '1.0.1'
3
3
  end
metadata CHANGED
@@ -1,85 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: finix
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.13'
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - finix-payments
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-12-11 00:00:00.000000000 Z
11
+ date: 2021-01-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.10.0
19
+ version: 1.1.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.10.0
26
+ version: 1.1.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: faraday_middleware
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ~>
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.10.1
33
+ version: 1.0.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ~>
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 0.10.1
41
- - !ruby/object:Gem::Dependency
42
- name: public_suffix
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ~>
46
- - !ruby/object:Gem::Version
47
- version: 1.4.6
48
- type: :runtime
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ~>
53
- - !ruby/object:Gem::Version
54
- version: 1.4.6
55
- - !ruby/object:Gem::Dependency
56
- name: json
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ~>
60
- - !ruby/object:Gem::Version
61
- version: '1.8'
62
- type: :runtime
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ~>
67
- - !ruby/object:Gem::Version
68
- version: '1.8'
69
- - !ruby/object:Gem::Dependency
70
- name: addressable
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ~>
74
- - !ruby/object:Gem::Version
75
- version: '2.3'
76
- type: :runtime
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ~>
81
- - !ruby/object:Gem::Version
82
- version: '2.3'
40
+ version: 1.0.0
83
41
  description: Finix Ruby Client
84
42
  email:
85
43
  - support@finixpayments.com
@@ -87,34 +45,40 @@ executables: []
87
45
  extensions: []
88
46
  extra_rdoc_files: []
89
47
  files:
90
- - .gitignore
91
- - .ruby-gemset
92
- - .ruby-version
48
+ - ".circleci/config.yml"
49
+ - ".gitignore"
50
+ - ".rspec"
51
+ - ".ruby-gemset"
52
+ - ".ruby-version"
93
53
  - Gemfile
94
54
  - LICENSE.txt
95
55
  - README.md
96
56
  - Rakefile
97
- - circle.yml
98
57
  - finix.gemspec
99
58
  - lib/finix.rb
100
59
  - lib/finix/client.rb
101
- - lib/finix/error.rb
60
+ - lib/finix/errors.rb
102
61
  - lib/finix/hal_resource.rb
62
+ - lib/finix/indifferent_hash.rb
103
63
  - lib/finix/pagination.rb
104
64
  - lib/finix/resources.rb
105
65
  - lib/finix/resources/application.rb
106
66
  - lib/finix/resources/authorization.rb
107
67
  - lib/finix/resources/bank_account.rb
108
68
  - lib/finix/resources/dispute.rb
69
+ - lib/finix/resources/error.rb
109
70
  - lib/finix/resources/evidence.rb
71
+ - lib/finix/resources/fee_profile.rb
110
72
  - lib/finix/resources/hypermedia.rb
111
73
  - lib/finix/resources/identity.rb
112
74
  - lib/finix/resources/merchant.rb
75
+ - lib/finix/resources/merchant_profile.rb
113
76
  - lib/finix/resources/payment_card.rb
114
77
  - lib/finix/resources/payment_instrument.rb
115
78
  - lib/finix/resources/processor.rb
116
79
  - lib/finix/resources/refund.rb
117
80
  - lib/finix/resources/resource.rb
81
+ - lib/finix/resources/risk_profile.rb
118
82
  - lib/finix/resources/settlement.rb
119
83
  - lib/finix/resources/token.rb
120
84
  - lib/finix/resources/transfer.rb
@@ -136,17 +100,17 @@ require_paths:
136
100
  - lib
137
101
  required_ruby_version: !ruby/object:Gem::Requirement
138
102
  requirements:
139
- - - ! '>='
103
+ - - ">="
140
104
  - !ruby/object:Gem::Version
141
- version: '1.9'
105
+ version: '2.0'
142
106
  required_rubygems_version: !ruby/object:Gem::Requirement
143
107
  requirements:
144
- - - ! '>='
108
+ - - ">="
145
109
  - !ruby/object:Gem::Version
146
110
  version: '0'
147
111
  requirements: []
148
112
  rubyforge_project:
149
- rubygems_version: 2.4.8
113
+ rubygems_version: 2.7.10
150
114
  signing_key:
151
115
  specification_version: 4
152
116
  summary: Finix Ruby Client
data/circle.yml DELETED
@@ -1,32 +0,0 @@
1
- machine:
2
- ruby:
3
- version: 1.9.3
4
-
5
- environment:
6
- RUBY_VERSIONS: 1.9.3,2.0.0,2.1.10,2.2.5,2.2.6,2.3.1,2.3.3,2.4.0-preview3
7
- PROCESSING_URL: https://api-staging.finix.io/
8
-
9
- dependencies:
10
- override:
11
- - rvm get head
12
- - rvm install $RUBY_VERSIONS
13
- - rvm $RUBY_VERSIONS --verbose do gem install bundler
14
- - rvm $RUBY_VERSIONS --verbose do bundle install
15
-
16
- test:
17
- override:
18
- - rvm $RUBY_VERSIONS --verbose do bundle exec rake test
19
-
20
- post:
21
- - cp -Rf .report/ $CIRCLE_ARTIFACTS
22
-
23
- deployment:
24
- release:
25
- tag: /v[0-9]+(\.[0-9]+)*/
26
- owner: finix-payments
27
- commands:
28
- - |
29
- curl -u ${rubygems_user}:${rubygems_password} https://rubygems.org/api/v1/api_key.yaml > ~/.gem/credentials
30
- - chmod 0600 ~/.gem/credentials
31
- - gem build *.gemspec
32
- - gem push *.gem
@@ -1,47 +0,0 @@
1
- module Finix
2
-
3
- class ResourceErrors < ::StandardError
4
- attr_reader :response
5
- attr_reader :errors
6
- attr_reader :code
7
-
8
- def initialize(response=nil)
9
- @response = response
10
- @errors = []
11
- unless response.nil?
12
- @code = response[:status].to_i
13
- @response[:body]['_embedded']['errors'].each { |error| @errors.push Utils.eval_class(self, 'ResourceError').new error}
14
- end
15
- end
16
-
17
- def to_s
18
- "#{@errors}"
19
- end
20
-
21
- def inspect
22
- to_s
23
- end
24
- end
25
-
26
- class ResourceError < ::StandardError
27
- attr_reader :attributes
28
-
29
- def initialize(error = {})
30
- @attributes = {}
31
- @attributes = @attributes.merge error
32
- end
33
-
34
- def to_s
35
- "#{self.class.name.split('::').last || ''} #{@attributes}"
36
- end
37
- end
38
-
39
- class BadRequest < ResourceErrors; end
40
- class Unauthorized < ResourceErrors; end
41
- class UpstreamProcessorError < ResourceErrors; end
42
- class Forbidden < ResourceErrors; end
43
- class NotFound < ResourceErrors; end
44
- class MethodNotAllowed < ResourceErrors; end
45
- class UnprocessableEntity < ResourceErrors; end
46
- class InternalServerError < ResourceErrors; end
47
- end