iugu-api-sdk 1.0.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 943c240d25ddab2e8f8c606db2ec3a613e993c7dfe2f2439ec2a89b8433c54c0
4
+ data.tar.gz: 7390024da6406da9aef317ec3e4cf2f1e900f40d319fd26f70bc6219ab2a6b1d
5
+ SHA512:
6
+ metadata.gz: d9f279d88ed74e2ca4244bdda904c2c56dcf60ae414b461cd63b74a76bd85e0e01fdf459be811d046f7d9d74d0de25b0b3c71adcefcd78970a9a9044eddcc47b
7
+ data.tar.gz: d98433865a1bbdb3709b147c5ec04dd43e96677716901dc0468d231bf329920e677855824fb52396609dcca8495a89931ff738b768e244daaee155f5ae5f7141
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+
5
+ begin
6
+ require "rspec/core/rake_task"
7
+ RSpec::Core::RakeTask.new(:spec)
8
+
9
+ task default: :spec
10
+ rescue LoadError
11
+ end
@@ -0,0 +1,207 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Iugu
4
+ class Account < APIResource
5
+ # POST /marketplace/create_account
6
+ #
7
+ # Creates a account
8
+ #
9
+ # @param [Hash] attributes the values to create an account
10
+ # @option attributes [String] :name The name of an account
11
+ # @option attributes [Integer] :commission_percent The commission_percent
12
+ # of an account
13
+
14
+ def self.create(attributes)
15
+ Iugu::Factory.create_from_response(
16
+ object_type,
17
+ APIRequest.request(
18
+ "POST",
19
+ "#{Iugu.base_uri}marketplace/create_account",
20
+ attributes
21
+ )
22
+ )
23
+ end
24
+
25
+ # POST /accounts/:account_id/request_verification
26
+ #
27
+ # Verify a account
28
+ #
29
+ # @param [Hash] attributes the values to verify an account, divided into two
30
+ # hashes, [data] and [file]
31
+ # @option attributes[data] [String] :price_range the price range is the max value
32
+ # of sale, possible values ['Até R$ 100,00', 'Entre R$ 100,00 e R$ 500,00',
33
+ # 'Mais que R$ 500,00']
34
+ # @option attributes[data] [Boolean] :physical_products the physical products
35
+ # defines if the account sells physical product, possible values
36
+ # [true, false]
37
+ # @option attributes[data] [String] :business_type the business type of an account
38
+ # @option attributes[data] [String] :person_type the person type of an account,
39
+ # possible values ['Pessoa Física', 'Pessoa Jurídica']
40
+ # @option attributes[data] [Boolean] :automatic_transfer the automatic transfer
41
+ # defines automatic withdraws, possible values [true, false]
42
+ # (recommended that be true)
43
+ # @option attributes[data] [String] :cnpj the cnpj of an account if person_type is
44
+ # Pessoa Jurídica
45
+ # @option attributes[data] [String] :company_name the company name if person_type
46
+ # is Pessoa Jurídica
47
+ # @option attributes[data] [String] :cpf the cpf of an account if person_type is
48
+ # Pessoa Física
49
+ # @option attributes[data] [String] :name the name of an account if person_type
50
+ # is Pessoa Física
51
+ # @option attributes[data] [String] :address the address of an account
52
+ # @option attributes[data] [String] :cep the cep of an account
53
+ # @option attributes[data] [String] :city the city of an account
54
+ # @option attributes[data] [String] :state the state of an account
55
+ # @option attributes[data] [String] :telephone the telephone of an account
56
+ # @option attributes[data] [String] :resp_name the responsible name if
57
+ # person_type is Pessoa Jurídica
58
+ # @option attributes[data] [String] :resp_cpf the responsible cpf if
59
+ # person_type is Pessoa Jurídica
60
+ # @option attributes[data] [String] :bank the bank that will be used to withdraw,
61
+ # possible values ['Itaú','Bradesco','Caixa Econômica','Banco do Brasil',
62
+ # 'Santander']
63
+ # @option attributes[data] [String] :bank_ag the bank ag is the number of the
64
+ # bank agency of an account
65
+ # @option attributes[data] [String] :account_type the account_type is the type of
66
+ # an bank account, possible values ['Corrente', 'Poupança']
67
+ # @option attributes[data] [String] :bank_cc the bank cc is the number of the
68
+ # bank account of an account
69
+ # @option attributes[file] [File] :id the id is the file with RG
70
+ # @option attributes[file] [File] :cpf the cpf is the file with CPF
71
+ # @option attributes[file] [File] :activity the activity is a document proving the
72
+ # activity of the company
73
+ # @param [String] account_id the account_id of an account
74
+ # @param [String] user_token the user_token of an account
75
+
76
+ def self.verify(attributes, account_id, user_token)
77
+ Iugu::Factory.create_from_response(
78
+ object_type,
79
+ APIRequest.request(
80
+ "POST",
81
+ "#{url(account_id)}/request_verification",
82
+ attributes,
83
+ user_token
84
+ )
85
+ )
86
+ end
87
+
88
+ # GET /accounts/:account_id
89
+ #
90
+ # Searchs a account
91
+ #
92
+ # @param [String] account_id the account_id of an account
93
+ # @param [String] user_token the user_token of an account
94
+
95
+ def self.fetch(account_id, user_token)
96
+ Iugu::Factory.create_from_response(
97
+ object_type,
98
+ APIRequest.request(
99
+ "GET",
100
+ "#{url(account_id)}",
101
+ {},
102
+ user_token
103
+ )
104
+ )
105
+ end
106
+
107
+ # Configures a account
108
+ # POST /accounts/configuration
109
+
110
+ def self.configuration(attributes, api_token)
111
+ Iugu::Factory.create_from_response(
112
+ object_type,
113
+ APIRequest.request(
114
+ "POST",
115
+ "#{url}/configuration",
116
+ attributes,
117
+ api_token
118
+ )
119
+ )
120
+ end
121
+
122
+ # POST /accounts/transfers
123
+ #
124
+ # Transfers an amount to another account
125
+ #
126
+ # @param [Hash] attributes the values to make a transfer of an account
127
+ # @option attributes[receiver_id] [String] receiver_id the account_id of account with will receive
128
+ # @option attributes[amount_cents] [String] amount_cents the value in cents that will be transferred
129
+ # @param [String] api_token live_api_token of the account sending the money
130
+
131
+ def self.transfer(attributes, api_token)
132
+ Iugu::Factory.create_from_response(
133
+ object_type,
134
+ APIRequest.request(
135
+ "POST",
136
+ "#{Iugu.base_uri}transfers",
137
+ attributes,
138
+ api_token
139
+ )
140
+ )
141
+ end
142
+
143
+ # POST /accounts/:account_id/request_withdraw
144
+ #
145
+ # Withdraw a value of an account
146
+ #
147
+ # @param [Hash] attributes the values to make a withdrawal of an account
148
+ # @option attributes [Float] :amount the amount defines the value of
149
+ # withdrawal
150
+ # @param [String] account_id the account_id of an account
151
+ # @param [String] user_token the user_token of an account
152
+
153
+ def self.withdraw(attributes, account_id, user_token)
154
+ Iugu::Factory.create_from_response(
155
+ object_type,
156
+ APIRequest.request(
157
+ "POST",
158
+ "#{url(account_id)}/request_withdraw",
159
+ attributes,
160
+ user_token
161
+ )
162
+ )
163
+ end
164
+
165
+ # POST /bank_verification
166
+ #
167
+ # Update a bank account
168
+ #
169
+ # @param [Hash] attributes the values to update an bank account
170
+ # @option attributes [Integer] :agency The number of agency
171
+ # @option attributes [Integer] :account The number of account
172
+ # @option attributes [String] :account_type The type of account
173
+ # @option attributes [Integer] :bank The number of the bank account
174
+ # @option attributes [file] :document Documento for comprove the data of bank account
175
+ # @param [String] user_token of the account
176
+
177
+ def self.bank(attributes, user_token)
178
+ Iugu::Factory.create_from_response(
179
+ object_type,
180
+ APIRequest.request(
181
+ "POST",
182
+ "#{Iugu.base_uri}bank_verification",
183
+ attributes,
184
+ user_token
185
+ )
186
+ )
187
+ end
188
+
189
+ # GET /bank_verification
190
+ #
191
+ # List bank accounts
192
+ #
193
+ # @param [String] user_token of the account
194
+
195
+ def self.banks(user_token)
196
+ Iugu::Factory.create_from_response(
197
+ object_type,
198
+ APIRequest.request(
199
+ "GET",
200
+ "#{Iugu.base_uri}bank_verification",
201
+ {},
202
+ user_token
203
+ )
204
+ )
205
+ end
206
+ end
207
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Iugu
4
+ class APIChildResource
5
+ @parent_keys = {}
6
+ @fabricator = nil
7
+
8
+ def initialize(parent_keys = {}, fabricator)
9
+ @parent_keys = parent_keys
10
+ @fabricator = fabricator
11
+ end
12
+
13
+ def create(attributes = {})
14
+ @fabricator.send "create", merge_params(attributes), token
15
+ end
16
+
17
+ def search(options = {})
18
+ @fabricator.send "search", merge_params(options)
19
+ end
20
+
21
+ def fetch(options = nil)
22
+ @fabricator.send "fetch", merge_params({ id: options })
23
+ end
24
+
25
+ private
26
+ def merge_params(attributes)
27
+ @parent_keys.merge attributes
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Iugu
4
+ module APICreate
5
+ module ClassMethods
6
+ def create(attributes = {}, token = nil)
7
+ Iugu::Factory.create_from_response(
8
+ object_type,
9
+ APIRequest.request("POST", url(attributes), attributes, token)
10
+ )
11
+ rescue Iugu::RequestWithErrors => e
12
+ obj = new
13
+ obj.set_attributes attributes, true
14
+ obj.errors = e.errors
15
+ obj
16
+ end
17
+ end
18
+
19
+ def self.included(base)
20
+ base.extend(ClassMethods)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Iugu
4
+ module APIDelete
5
+ def delete
6
+ APIRequest.request("DELETE", self.class.url(attributes))
7
+ self.errors = nil
8
+ true
9
+ rescue Iugu::RequestWithErrors => e
10
+ self.errors = e.errors
11
+ false
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Iugu
4
+ module APIFetch
5
+ def refresh(token = nil)
6
+ copy Iugu::Factory.create_from_response(
7
+ self.class.object_type, APIRequest.request("GET", self.class.url(self.id), {}, token)
8
+ )
9
+ self.errors = nil
10
+ true
11
+ rescue Iugu::RequestWithErrors => e
12
+ self.errors = e.errors
13
+ false
14
+ end
15
+
16
+ module ClassMethods
17
+ def fetch(options = nil, token = nil)
18
+ Iugu::Factory.create_from_response(
19
+ self.object_type, APIRequest.request("GET", self.url(options), {}, token)
20
+ )
21
+ end
22
+ end
23
+
24
+ def self.included(base)
25
+ base.extend(ClassMethods)
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rest_client"
4
+ require "base64"
5
+ require "json"
6
+
7
+ module Iugu
8
+ class APIRequest
9
+ def self.request(method, url, data = {}, authorization_token = nil)
10
+ Iugu::Utils.auth_from_env if Iugu.api_key.nil?
11
+ raise Iugu::AuthenticationException, "Chave de API não configurada. Utilize Iugu.api_key = ... para configurar." if Iugu.api_key.nil?
12
+ handle_response send_request method, url, data, authorization_token
13
+ end
14
+
15
+ def self.send_request(method, url, data, authorization_token)
16
+ RestClient::Request.execute build_request(method, url, data, authorization_token)
17
+ rescue RestClient::ResourceNotFound
18
+ raise ObjectNotFound
19
+ rescue RestClient::UnprocessableEntity => e
20
+ raise RequestWithErrors, JSON.parse(e.response)["errors"]
21
+ rescue RestClient::BadRequest => e
22
+ raise RequestWithErrors, JSON.parse(e.response)["errors"]
23
+ end
24
+
25
+ def self.build_request(method, url, data, authorization_token)
26
+ data = data.to_json unless data[:multipart]
27
+ {
28
+ verify_ssl: true,
29
+ headers: default_headers(authorization_token),
30
+ method: method,
31
+ payload: data,
32
+ url: url,
33
+ timeout: 30
34
+ }
35
+ end
36
+
37
+ def self.handle_response(response)
38
+ response_json = JSON.parse(response.body)
39
+ raise ObjectNotFound if response_json.is_a?(Hash) && response_json["errors"] == "Not Found"
40
+
41
+ if response_json.is_a?(Hash) && response_json["errors"] && response_json["errors"].length.positive?
42
+ raise RequestWithErrors,
43
+ response_json["errors"]
44
+ end
45
+
46
+ response_json
47
+ rescue JSON::ParserError
48
+ raise RequestFailed
49
+ end
50
+
51
+ def self.default_headers(authorization_token)
52
+ token = authorization_token || Iugu.api_key
53
+ {
54
+ authorization: "Basic " + Base64.strict_encode64(token + ":"),
55
+ accept: "application/json",
56
+ accept_charset: "utf-8",
57
+ user_agent: "Iugu RubyLibrary",
58
+ accept_language: "pt-br;q=0.9,pt-BR",
59
+ content_type: "application/json; charset=utf-8"
60
+ }
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Iugu
4
+ class APIResource < Iugu::Object
5
+ def self.url(options = nil)
6
+ endpoint_url + relative_url(options)
7
+ end
8
+
9
+ def is_new?
10
+ @attributes["id"].nil?
11
+ end
12
+
13
+ def self.object_type
14
+ Iugu::Utils.underscore name.to_s.split("::")[-1]
15
+ end
16
+
17
+ def self.endpoint_url
18
+ "#{Iugu.base_uri}#{self.object_base_uri}"
19
+ end
20
+
21
+ def self.relative_url(options = "")
22
+ id = case options
23
+ when Hash
24
+ options[:id] || options["id"]
25
+ when Iugu::APIResource
26
+ options.id
27
+ else
28
+ options
29
+ end
30
+ id ? "/#{id}" : ""
31
+ end
32
+
33
+ def self.object_base_uri
34
+ pluralized_models = ["account", "customer", "payment_method", "invoice", "subscription", "plan"]
35
+ if pluralized_models.include? self.object_type
36
+ "#{self.object_type}s"
37
+ else
38
+ object_type
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Iugu
4
+ module APISave
5
+ def save
6
+ method = is_new? ? "POST" : "PUT"
7
+ copy Iugu::Factory.create_from_response(self.class.object_type,
8
+ APIRequest.request(method,
9
+ self.class.url(attributes),
10
+ modified_attributes))
11
+ self.errors = nil
12
+ true
13
+ rescue Iugu::RequestWithErrors => e
14
+ self.errors = e.errors
15
+ false
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Iugu
4
+ module APICreate
5
+ module ClassMethods
6
+ def search(options = {})
7
+ Iugu::Factory.create_from_response object_type, APIRequest.request("GET", url(options), options)
8
+ end
9
+ end
10
+
11
+ def self.included(base)
12
+ base.extend(ClassMethods)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Iugu
4
+ class Charge < APIResource
5
+ include Iugu::APICreate
6
+
7
+ def success
8
+ @attributes["success"] || false
9
+ end
10
+
11
+ def invoice
12
+ return false unless @attributes["invoice_id"]
13
+
14
+ Invoice.fetch @attributes["invoice_id"]
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Iugu
4
+ class Customer < APIResource
5
+ include Iugu::APIFetch
6
+ include Iugu::APICreate
7
+ include Iugu::APISave
8
+ include Iugu::APIDelete
9
+
10
+ def payment_methods
11
+ APIChildResource.new({ customer_id: id }, Iugu::PaymentMethod)
12
+ end
13
+
14
+ def invoices
15
+ APIChildResource.new({ customer_id: id }, Iugu::Invoice)
16
+ end
17
+
18
+ def default_payment_method
19
+ return false unless @attributes["default_payment_method_id"]
20
+
21
+ PaymentMethod.fetch({ id: @attributes["default_payment_method_id"], customer_id: id })
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Iugu
4
+ class Factory
5
+ def self.create_from_response(object_type, response, errors = nil)
6
+ if response.nil?
7
+ obj = Iugu.const_get(Iugu::Utils.camelize(object_type)).new
8
+ obj.errors = errors if errors
9
+ obj
10
+ elsif response.is_a?(Array)
11
+ results = []
12
+ response.each do |i|
13
+ results.push Iugu.const_get(Iugu::Utils.camelize(object_type)).new i
14
+ end
15
+ Iugu::SearchResult.new results, results.count
16
+ elsif response["items"] && response["totalItems"]
17
+ results = []
18
+ response["items"].each do |v|
19
+ results.push create_from_response(object_type, v)
20
+ end
21
+ Iugu::SearchResult.new results, response["totalItems"]
22
+ else
23
+ Iugu.const_get(Iugu::Utils.camelize(object_type)).new response
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Iugu
4
+ class Invoice < APIResource
5
+ include Iugu::APIFetch
6
+ include Iugu::APICreate
7
+ include Iugu::APISave
8
+ include Iugu::APIDelete
9
+
10
+ def customer
11
+ return false unless @attributes["customer_id"]
12
+
13
+ Customer.fetch @attributes["customer_id"]
14
+ end
15
+
16
+ def cancel
17
+ copy Iugu::Factory.create_from_response(self.class.object_type,
18
+ APIRequest.request("PUT",
19
+ "#{self.class.url(id)}/cancel"))
20
+ self.errors = nil
21
+ true
22
+ rescue Iugu::RequestWithErrors => e
23
+ self.errors = e.errors
24
+ false
25
+ end
26
+
27
+ def capture
28
+ copy Iugu::Factory.create_from_response(self.class.object_type,
29
+ APIRequest.request("POST",
30
+ "#{self.class.url(id)}/capture"))
31
+ self.errors = nil
32
+ true
33
+ rescue Iugu::RequestWithErrors => e
34
+ self.errors = e.errors
35
+ false
36
+ end
37
+
38
+ def refund
39
+ copy Iugu::Factory.create_from_response(self.class.object_type,
40
+ APIRequest.request("POST",
41
+ "#{self.class.url(id)}/refund"))
42
+ self.errors = nil
43
+ true
44
+ rescue Iugu::RequestWithErrors => e
45
+ self.errors = e.errors
46
+ false
47
+ end
48
+
49
+ def duplicate(attributes = {})
50
+ copy Iugu::Factory.create_from_response(self.class.object_type,
51
+ APIRequest.request("POST",
52
+ "#{self.class.url(id)}/duplicate",
53
+ attributes))
54
+ self.errors = nil
55
+ true
56
+ rescue Iugu::RequestWithErrors => e
57
+ self.errors = e.errors
58
+ false
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "set"
4
+
5
+ module Iugu
6
+ class Object
7
+ attr_accessor :errors
8
+
9
+ undef :id if method_defined?(:id)
10
+
11
+ def initialize(attributes = {})
12
+ @unsaved_attributes = Set.new
13
+ set_attributes attributes
14
+ end
15
+
16
+ def add_accessor(name)
17
+ singleton_class.class_eval do
18
+ define_method(name.to_s) { attributes[name.to_s] }
19
+ unless name.to_s == "id"
20
+ define_method("#{name}=") do |value|
21
+ attributes[name.to_s] = value
22
+ unsaved_attributes.add name.to_s
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ def method_missing(name, *args)
29
+ return super unless name.to_s.end_with? "="
30
+ return super if name.to_s.start_with? "id"
31
+
32
+ add_accessor(name.to_s[0...-1])
33
+ send(name, args[0])
34
+ end
35
+
36
+ attr_reader :unsaved_attributes, :attributes
37
+
38
+ def modified_attributes
39
+ Iugu::Utils.intersect @unsaved_attributes, @attributes
40
+ end
41
+
42
+ def copy(object)
43
+ @unsaved_attributes = Set.new
44
+ @attributes = {}
45
+ set_attributes object.attributes
46
+ end
47
+
48
+ def set_attributes(attributes, unsaved = false)
49
+ @attributes = Iugu::Utils.stringify_keys(attributes)
50
+ @attributes.each do |k, _v|
51
+ add_accessor(k)
52
+ end
53
+ @unsaved_attributes = @attributes.keys.to_set if unsaved
54
+ end
55
+
56
+ protected
57
+ def metaclass
58
+ class << self; self; end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Iugu
4
+ class PaymentMethod < APIResource
5
+ include Iugu::APIFetch
6
+ include Iugu::APICreate
7
+ include Iugu::APISave
8
+ include Iugu::APIDelete
9
+
10
+ def self.url(options = {})
11
+ customer_id = options[:customer_id] || options["customer_id"]
12
+ id = options[:id] || options["id"]
13
+ raise StandardError, "Missing Customer ID" unless customer_id
14
+
15
+ "#{Customer.url customer_id}/#{object_base_uri}" + relative_url(id)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Iugu
4
+ class PaymentToken < APIResource
5
+ include Iugu::APICreate
6
+ end
7
+ end
data/lib/iugu/plan.rb ADDED
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Iugu
4
+ class Plan < APIResource
5
+ include Iugu::APIFetch
6
+ include Iugu::APICreate
7
+ include Iugu::APISave
8
+ include Iugu::APIDelete
9
+
10
+ def self.fetch_by_identifier(identifier)
11
+ Iugu::Factory.create_from_response(object_type,
12
+ APIRequest.request("GET",
13
+ "#{url}/identifier/#{identifier}"))
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Iugu
4
+ class SearchResult
5
+ def initialize(results, total_results)
6
+ @results = results
7
+ @total = total_results
8
+ end
9
+
10
+ attr_reader :total, :results
11
+ end
12
+ end
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Iugu
4
+ class Subscription < APIResource
5
+ include Iugu::APIFetch
6
+ include Iugu::APICreate
7
+ include Iugu::APISave
8
+ include Iugu::APIDelete
9
+
10
+ def add_credits(quantity)
11
+ copy Iugu::Factory.create_from_response(self.class.object_type,
12
+ APIRequest.request("PUT",
13
+ "#{self.class.url(id)}/add_credits",
14
+ { quantity: quantity }))
15
+ self.errors = nil
16
+ true
17
+ rescue Iugu::RequestWithErrors => e
18
+ self.errors = e.errors
19
+ false
20
+ end
21
+
22
+ def remove_credits(quantity)
23
+ copy Iugu::Factory.create_from_response(self.class.object_type,
24
+ APIRequest.request("PUT",
25
+ "#{self.class.url(id)}/remove_credits",
26
+ { quantity: quantity }))
27
+ self.errors = nil
28
+ true
29
+ rescue Iugu::RequestWithErrors => e
30
+ self.errors = e.errors
31
+ false
32
+ end
33
+
34
+ def suspend
35
+ copy Iugu::Factory.create_from_response(self.class.object_type,
36
+ APIRequest.request("POST",
37
+ "#{self.class.url(id)}/suspend"))
38
+ self.errors = nil
39
+ true
40
+ rescue Iugu::RequestWithErrors => e
41
+ self.errors = e.errors
42
+ false
43
+ end
44
+
45
+ def activate
46
+ copy Iugu::Factory.create_from_response(self.class.object_type,
47
+ APIRequest.request("POST",
48
+ "#{self.class.url(id)}/activate"))
49
+ self.errors = nil
50
+ true
51
+ rescue Iugu::RequestWithErrors => e
52
+ self.errors = e.errors
53
+ false
54
+ end
55
+
56
+ def change_plan(plan_identifier, options = {})
57
+ options[:plan_identifier] = plan_identifier
58
+ copy Iugu::Factory.create_from_response(self.class.object_type,
59
+ APIRequest.request("POST",
60
+ "#{self.class.url(id)}/change_plan",
61
+ options))
62
+ self.errors = nil
63
+ true
64
+ rescue Iugu::RequestWithErrors => e
65
+ self.errors = e.errors
66
+ false
67
+ end
68
+
69
+ def change_plan_simulation(plan_identifier, options = {})
70
+ options[:plan_identifier] = plan_identifier
71
+ Iugu::Factory.create_from_response(self.class.object_type,
72
+ APIRequest.request("GET",
73
+ "#{self.class.url(id)}/change_plan_simulation",
74
+ options))
75
+ end
76
+
77
+ def customer
78
+ return false unless @attributes["customer_id"]
79
+
80
+ Customer.fetch @attributes["customer_id"]
81
+ end
82
+ end
83
+ end
data/lib/iugu/utils.rb ADDED
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Iugu
4
+ class Utils
5
+ def self.auth_from_env
6
+ api_key = ENV["IUGU_API_KEY"]
7
+ Iugu.api_key = api_key if api_key
8
+ end
9
+
10
+ def self.intersect(array, another_hash)
11
+ keys_intersection = array & another_hash.keys
12
+ intersection = {}
13
+ keys_intersection.each { |k| intersection[k] = another_hash[k] }
14
+ intersection
15
+ end
16
+
17
+ def self.underscore(string)
18
+ string.gsub(/::/, "/")
19
+ .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
20
+ .gsub(/([a-z\d])([A-Z])/, '\1_\2')
21
+ .tr("-", "_")
22
+ .downcase
23
+ end
24
+
25
+ def self.camelize(string)
26
+ string.to_s.gsub(%r{/(.?)}) do
27
+ "::#{Regexp.last_match(1).upcase}"
28
+ end.gsub(/(?:^|_)(.)/) { Regexp.last_match(1).upcase }
29
+ end
30
+
31
+ def self.stringify_keys(hash)
32
+ new_hash = {}
33
+ hash.each do |key, value|
34
+ new_hash[key.to_s] = if value.is_a? Hash
35
+ stringify_keys(value)
36
+ else
37
+ value
38
+ end
39
+ end
40
+ new_hash
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Iugu
4
+ VERSION = "1.0.0"
5
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "iugu"
data/lib/iugu.rb ADDED
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "iugu/version"
4
+ require_relative "iugu/utils"
5
+ require_relative "iugu/api_request"
6
+ require_relative "iugu/object"
7
+ require_relative "iugu/api_resource"
8
+ require_relative "iugu/api_child_resource"
9
+ require_relative "iugu/factory"
10
+ require_relative "iugu/search_result"
11
+ require_relative "iugu/api_fetch"
12
+ require_relative "iugu/api_create"
13
+ require_relative "iugu/api_save"
14
+ require_relative "iugu/api_delete"
15
+ require_relative "iugu/api_search"
16
+ require_relative "iugu/customer"
17
+ require_relative "iugu/payment_method"
18
+ require_relative "iugu/payment_token"
19
+ require_relative "iugu/invoice"
20
+ require_relative "iugu/subscription"
21
+ require_relative "iugu/charge"
22
+ require_relative "iugu/plan"
23
+ require_relative "iugu/account"
24
+
25
+ module Iugu
26
+ class AuthenticationException < StandardError
27
+ end
28
+
29
+ class RequestFailed < StandardError
30
+ end
31
+
32
+ class ObjectNotFound < StandardError
33
+ end
34
+
35
+ class RequestWithErrors < StandardError
36
+ attr_accessor :errors
37
+
38
+ def initialize(errors)
39
+ @errors = errors
40
+ end
41
+ end
42
+
43
+ class << self
44
+ attr_accessor :api_key
45
+ end
46
+
47
+ @api_version = "v1"
48
+ @endpoint = "https://api.iugu.com"
49
+
50
+ def self.base_uri
51
+ "#{@endpoint}/#{@api_version}/"
52
+ end
53
+ end
metadata ADDED
@@ -0,0 +1,247 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: iugu-api-sdk
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Marcelo Paez Sequeira
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-05-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rest-client
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.3'
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: 2.3.0
37
+ type: :development
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - "~>"
42
+ - !ruby/object:Gem::Version
43
+ version: '2.3'
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 2.3.0
47
+ - !ruby/object:Gem::Dependency
48
+ name: byebug
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '11.1'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '11.1'
61
+ - !ruby/object:Gem::Dependency
62
+ name: rake
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '13.0'
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: 10.0.0
71
+ type: :development
72
+ prerelease: false
73
+ version_requirements: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - "~>"
76
+ - !ruby/object:Gem::Version
77
+ version: '13.0'
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: 10.0.0
81
+ - !ruby/object:Gem::Dependency
82
+ name: rspec
83
+ requirement: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - "~>"
86
+ - !ruby/object:Gem::Version
87
+ version: '3.11'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - "~>"
93
+ - !ruby/object:Gem::Version
94
+ version: '3.11'
95
+ - !ruby/object:Gem::Dependency
96
+ name: rubocop
97
+ requirement: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - "~>"
100
+ - !ruby/object:Gem::Version
101
+ version: '1.30'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - "~>"
107
+ - !ruby/object:Gem::Version
108
+ version: '1.30'
109
+ - !ruby/object:Gem::Dependency
110
+ name: rubocop-packaging
111
+ requirement: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - "~>"
114
+ - !ruby/object:Gem::Version
115
+ version: '0.5'
116
+ type: :development
117
+ prerelease: false
118
+ version_requirements: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - "~>"
121
+ - !ruby/object:Gem::Version
122
+ version: '0.5'
123
+ - !ruby/object:Gem::Dependency
124
+ name: rubocop-performance
125
+ requirement: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - "~>"
128
+ - !ruby/object:Gem::Version
129
+ version: '1.14'
130
+ type: :development
131
+ prerelease: false
132
+ version_requirements: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - "~>"
135
+ - !ruby/object:Gem::Version
136
+ version: '1.14'
137
+ - !ruby/object:Gem::Dependency
138
+ name: rubocop-rake
139
+ requirement: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - "~>"
142
+ - !ruby/object:Gem::Version
143
+ version: '0.6'
144
+ type: :development
145
+ prerelease: false
146
+ version_requirements: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - "~>"
149
+ - !ruby/object:Gem::Version
150
+ version: '0.6'
151
+ - !ruby/object:Gem::Dependency
152
+ name: rubocop-rspec
153
+ requirement: !ruby/object:Gem::Requirement
154
+ requirements:
155
+ - - "~>"
156
+ - !ruby/object:Gem::Version
157
+ version: '2.11'
158
+ type: :development
159
+ prerelease: false
160
+ version_requirements: !ruby/object:Gem::Requirement
161
+ requirements:
162
+ - - "~>"
163
+ - !ruby/object:Gem::Version
164
+ version: '2.11'
165
+ - !ruby/object:Gem::Dependency
166
+ name: vcr
167
+ requirement: !ruby/object:Gem::Requirement
168
+ requirements:
169
+ - - "~>"
170
+ - !ruby/object:Gem::Version
171
+ version: '6.1'
172
+ type: :development
173
+ prerelease: false
174
+ version_requirements: !ruby/object:Gem::Requirement
175
+ requirements:
176
+ - - "~>"
177
+ - !ruby/object:Gem::Version
178
+ version: '6.1'
179
+ - !ruby/object:Gem::Dependency
180
+ name: webmock
181
+ requirement: !ruby/object:Gem::Requirement
182
+ requirements:
183
+ - - "~>"
184
+ - !ruby/object:Gem::Version
185
+ version: '3.14'
186
+ type: :development
187
+ prerelease: false
188
+ version_requirements: !ruby/object:Gem::Requirement
189
+ requirements:
190
+ - - "~>"
191
+ - !ruby/object:Gem::Version
192
+ version: '3.14'
193
+ description:
194
+ email:
195
+ - marcelo@iugu.com
196
+ executables: []
197
+ extensions: []
198
+ extra_rdoc_files: []
199
+ files:
200
+ - Rakefile
201
+ - lib/iugu-api-sdk.rb
202
+ - lib/iugu.rb
203
+ - lib/iugu/account.rb
204
+ - lib/iugu/api_child_resource.rb
205
+ - lib/iugu/api_create.rb
206
+ - lib/iugu/api_delete.rb
207
+ - lib/iugu/api_fetch.rb
208
+ - lib/iugu/api_request.rb
209
+ - lib/iugu/api_resource.rb
210
+ - lib/iugu/api_save.rb
211
+ - lib/iugu/api_search.rb
212
+ - lib/iugu/charge.rb
213
+ - lib/iugu/customer.rb
214
+ - lib/iugu/factory.rb
215
+ - lib/iugu/invoice.rb
216
+ - lib/iugu/object.rb
217
+ - lib/iugu/payment_method.rb
218
+ - lib/iugu/payment_token.rb
219
+ - lib/iugu/plan.rb
220
+ - lib/iugu/search_result.rb
221
+ - lib/iugu/subscription.rb
222
+ - lib/iugu/utils.rb
223
+ - lib/iugu/version.rb
224
+ homepage: https://iugu.com
225
+ licenses:
226
+ - MIT
227
+ metadata: {}
228
+ post_install_message:
229
+ rdoc_options: []
230
+ require_paths:
231
+ - lib
232
+ required_ruby_version: !ruby/object:Gem::Requirement
233
+ requirements:
234
+ - - ">="
235
+ - !ruby/object:Gem::Version
236
+ version: '0'
237
+ required_rubygems_version: !ruby/object:Gem::Requirement
238
+ requirements:
239
+ - - ">="
240
+ - !ruby/object:Gem::Version
241
+ version: '0'
242
+ requirements: []
243
+ rubygems_version: 3.3.7
244
+ signing_key:
245
+ specification_version: 4
246
+ summary: Iugu API
247
+ test_files: []