iugu-api-sdk 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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: []