iugu 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 +15 -0
- data/.gitignore +56 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/iugu.gemspec +24 -0
- data/lib/iugu.rb +49 -0
- data/lib/iugu/api_child_resource.rb +29 -0
- data/lib/iugu/api_create.rb +18 -0
- data/lib/iugu/api_delete.rb +12 -0
- data/lib/iugu/api_fetch.rb +13 -0
- data/lib/iugu/api_request.rb +60 -0
- data/lib/iugu/api_resource.rb +47 -0
- data/lib/iugu/api_save.rb +12 -0
- data/lib/iugu/api_search.rb +13 -0
- data/lib/iugu/charge.rb +10 -0
- data/lib/iugu/customer.rb +21 -0
- data/lib/iugu/factory.rb +25 -0
- data/lib/iugu/invoice.rb +31 -0
- data/lib/iugu/object.rb +62 -0
- data/lib/iugu/payment_method.rb +15 -0
- data/lib/iugu/payment_token.rb +5 -0
- data/lib/iugu/search_result.rb +16 -0
- data/lib/iugu/subscription.rb +40 -0
- data/lib/iugu/utils.rb +39 -0
- data/lib/iugu/version.rb +3 -0
- data/test/lib/iugu/customer_test.rb +76 -0
- data/test/lib/iugu/version_test.rb +7 -0
- data/test/test_helper.rb +3 -0
- metadata +118 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
NGM3Mjc3MTEwMTE2OWFlNmI0MWM5ZmU3NDY0Yzg3NGE5ODIyZmU2YQ==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
ZGIyMzk0OTI3NGM1NjFhYmFlYTcxNDFkMjY2NGUwNTMwN2E0MWUyMA==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
ZmJhZGI5ZjU0NDgzODlkZWEzY2QwODcyZjYxMTgzZmQ3YTkyZmYyZjlkZjRl
|
10
|
+
YmRmNGZiMzkyOGJlMDZkMDhjNTYyYTI0NzIzOTk3ZDdmNzEzOGU4OTgwM2M3
|
11
|
+
ZTE1NjY2ZWY4NDY3MDYxNDJkNzg4ZTIyM2M4YjBmMWJhMzQxMTQ=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
MzczY2U4OWI4MTIyNDAzZDhkODc5NzA5NTVhNWRlYTI4ZjY2MjUzYjM5ZDc4
|
14
|
+
M2UyN2ExMzM5OTgzM2FkNzI5OTAzMjUxMzg4MWRlMTJmYjE3MjM0NzFlYjIx
|
15
|
+
OGRjNDJiNTVjZDk5ZjU3YmU1NzBiMGZkN2RlNzU3YzNkMjk3ZjM=
|
data/.gitignore
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
|
19
|
+
*.gem
|
20
|
+
.bundle
|
21
|
+
Gemfile.lock
|
22
|
+
pkg/*
|
23
|
+
.bundle
|
24
|
+
db/*.sqlite3
|
25
|
+
log/*.log
|
26
|
+
tmp/
|
27
|
+
.sass-cache/
|
28
|
+
coverage/
|
29
|
+
*~
|
30
|
+
*.lock
|
31
|
+
*.DS_Store
|
32
|
+
*.out
|
33
|
+
*.swp
|
34
|
+
.sass-cache/
|
35
|
+
.sass-cache/*
|
36
|
+
.sass-cache/**
|
37
|
+
tmp/
|
38
|
+
tmp/*/*
|
39
|
+
tmp/**
|
40
|
+
*/*.swp
|
41
|
+
db/schema.rb
|
42
|
+
public/system/*
|
43
|
+
public/system/**
|
44
|
+
log/*/*
|
45
|
+
log/**
|
46
|
+
**/log
|
47
|
+
*/*/log
|
48
|
+
*/*/*/log
|
49
|
+
spec/dummy/log/*/*
|
50
|
+
spec/dummy/log/**
|
51
|
+
spec/dummy/tmp/
|
52
|
+
spec/dummy/tmp/*/*
|
53
|
+
spec/dummy/tmp/**
|
54
|
+
*.sqlite3
|
55
|
+
public/assets/**
|
56
|
+
sandbox/public/assets/**
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 TODO: Write your name
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# Iugu::Ruby
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'iugu-ruby'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install iugu-ruby
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it ( http://github.com/<my-github-username>/iugu-ruby/fork )
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/iugu.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'iugu/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "iugu"
|
8
|
+
spec.version = Iugu::VERSION
|
9
|
+
spec.authors = ["Marcelo Paez Sequeira"]
|
10
|
+
spec.email = ["marcelo@iugu.com"]
|
11
|
+
spec.summary = %q{Iugu API}
|
12
|
+
spec.homepage = "https://iugu.com"
|
13
|
+
spec.license = "MIT"
|
14
|
+
|
15
|
+
spec.files = `git ls-files`.split($/)
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
|
20
|
+
spec.add_dependency "rest-client"
|
21
|
+
|
22
|
+
spec.add_development_dependency "bundler", "~> 1.5"
|
23
|
+
spec.add_development_dependency "rake"
|
24
|
+
end
|
data/lib/iugu.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require_relative "iugu/version"
|
2
|
+
require_relative "iugu/utils"
|
3
|
+
require_relative "iugu/api_request"
|
4
|
+
require_relative "iugu/object"
|
5
|
+
require_relative "iugu/api_resource"
|
6
|
+
require_relative "iugu/api_child_resource"
|
7
|
+
require_relative "iugu/factory"
|
8
|
+
require_relative "iugu/search_result"
|
9
|
+
require_relative "iugu/api_fetch"
|
10
|
+
require_relative "iugu/api_create"
|
11
|
+
require_relative "iugu/api_save"
|
12
|
+
require_relative "iugu/api_delete"
|
13
|
+
require_relative "iugu/api_search"
|
14
|
+
require_relative "iugu/customer"
|
15
|
+
require_relative "iugu/payment_method"
|
16
|
+
require_relative "iugu/payment_token"
|
17
|
+
require_relative "iugu/invoice"
|
18
|
+
require_relative "iugu/subscription"
|
19
|
+
require_relative "iugu/charge"
|
20
|
+
|
21
|
+
module Iugu
|
22
|
+
class AuthenticationException < StandardError
|
23
|
+
end
|
24
|
+
|
25
|
+
class RequestFailed < StandardError
|
26
|
+
end
|
27
|
+
|
28
|
+
class ObjectNotFound < StandardError
|
29
|
+
end
|
30
|
+
|
31
|
+
class RequestWithErrors < StandardError
|
32
|
+
attr_accessor :errors
|
33
|
+
|
34
|
+
def initialize(errors)
|
35
|
+
@errors = errors
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class << self
|
40
|
+
attr_accessor :api_key
|
41
|
+
end
|
42
|
+
|
43
|
+
@api_version = 'v1'
|
44
|
+
@endpoint = 'https://api.iugu.com'
|
45
|
+
|
46
|
+
def self.base_uri
|
47
|
+
"#{@endpoint}/#{@api_version}/"
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Iugu
|
2
|
+
class APIChildResource
|
3
|
+
@parent_keys = {}
|
4
|
+
@fabricator = nil
|
5
|
+
|
6
|
+
def initialize(parent_keys = {}, fabricator)
|
7
|
+
@parent_keys = parent_keys
|
8
|
+
@fabricator = fabricator
|
9
|
+
end
|
10
|
+
|
11
|
+
def create(attributes = {})
|
12
|
+
@fabricator.send "create", merge_params(attributes)
|
13
|
+
end
|
14
|
+
|
15
|
+
def search(options = {})
|
16
|
+
@fabricator.send "search", merge_params(options)
|
17
|
+
end
|
18
|
+
|
19
|
+
def fetch(options = nil)
|
20
|
+
@fabricator.send "fetch", merge_params({ id: options })
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def merge_params(attributes)
|
26
|
+
@parent_keys.merge attributes
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Iugu
|
2
|
+
module APICreate
|
3
|
+
module ClassMethods
|
4
|
+
def create(attributes = {})
|
5
|
+
Iugu::Factory.create_from_response self.object_type, APIRequest.request("POST", self.url(attributes), attributes)
|
6
|
+
rescue Iugu::RequestWithErrors => ex
|
7
|
+
obj = self.new
|
8
|
+
obj.set_attributes attributes, true
|
9
|
+
obj.errors = ex.errors
|
10
|
+
obj
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.included(base)
|
15
|
+
base.extend(ClassMethods)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Iugu
|
2
|
+
module APIFetch
|
3
|
+
module ClassMethods
|
4
|
+
def fetch(options = nil)
|
5
|
+
Iugu::Factory.create_from_response self.object_type, APIRequest.request("GET", self.url(options))
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.included(base)
|
10
|
+
base.extend(ClassMethods)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
#encoding: UTF-8
|
2
|
+
|
3
|
+
require 'rest_client'
|
4
|
+
require "base64"
|
5
|
+
require "json"
|
6
|
+
|
7
|
+
module Iugu
|
8
|
+
class APIRequest
|
9
|
+
|
10
|
+
def self.request(method, url, data = {})
|
11
|
+
Iugu::Utils.auth_from_env if Iugu.api_key.nil?
|
12
|
+
raise Iugu::AuthenticationException, "Chave de API não configurada. Utilize Iugu.api_key = ... para configurar." if Iugu.api_key.nil?
|
13
|
+
handle_response self.send_request method, url, data
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def self.send_request(method, url, data)
|
19
|
+
RestClient::Request.execute build_request(method, url, data)
|
20
|
+
rescue RestClient::ResourceNotFound
|
21
|
+
raise ObjectNotFound
|
22
|
+
rescue RestClient::UnprocessableEntity => ex
|
23
|
+
raise RequestWithErrors.new JSON.parse(ex.response)['errors']
|
24
|
+
rescue RestClient::BadRequest => ex
|
25
|
+
raise RequestWithErrors.new JSON.parse(ex.response)['errors']
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.build_request(method, url, data)
|
29
|
+
{
|
30
|
+
verify_ssl: true,
|
31
|
+
headers: default_headers,
|
32
|
+
method: method,
|
33
|
+
payload: data.to_json,
|
34
|
+
url: url
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.handle_response(response)
|
39
|
+
response_json = JSON.parse(response.body)
|
40
|
+
raise ObjectNotFound if response_json.is_a?(Hash) && response_json['errors'] == "Not Found"
|
41
|
+
raise RequestWithErrors, response_json['errors'] if response_json.is_a?(Hash) && response_json['errors'] && response_json['errors'].count > 0
|
42
|
+
response_json
|
43
|
+
rescue JSON::ParserError
|
44
|
+
raise RequestFailed
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.default_headers
|
48
|
+
{
|
49
|
+
authorization: 'Basic ' + Base64.encode64(Iugu.api_key + ":"),
|
50
|
+
accept: 'application/json',
|
51
|
+
accept_charset: 'utf-8',
|
52
|
+
user_agent: 'Iugu RubyLibrary',
|
53
|
+
accept_language: 'pt-br;q=0.9,pt-BR',
|
54
|
+
#content_type: 'application/x-www-form-urlencoded; charset=utf-8'
|
55
|
+
content_type: 'application/json; charset=utf-8'
|
56
|
+
}
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Iugu
|
2
|
+
class APIResource < Iugu::Object
|
3
|
+
def self.url(options = nil)
|
4
|
+
endpoint_url + self.relative_url(options)
|
5
|
+
end
|
6
|
+
|
7
|
+
def is_new?
|
8
|
+
@attributes['id'].nil?
|
9
|
+
end
|
10
|
+
|
11
|
+
protected
|
12
|
+
|
13
|
+
def self.object_type
|
14
|
+
Iugu::Utils.underscore self.name.to_s.split('::')[-1]
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.endpoint_url
|
18
|
+
Iugu.base_uri + object_base_uri
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.relative_url(options = "")
|
22
|
+
if options.is_a?(Hash)
|
23
|
+
id = options[:id] || options["id"]
|
24
|
+
elsif options.is_a?(Iugu::APIResource)
|
25
|
+
id = options.id
|
26
|
+
else
|
27
|
+
id = options
|
28
|
+
end
|
29
|
+
id ? "/#{id}" : ""
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.object_base_uri
|
33
|
+
if self.object_type == "customer"
|
34
|
+
object_type = self.object_type + "s"
|
35
|
+
elsif self.object_type == "payment_method"
|
36
|
+
object_type = self.object_type + "s"
|
37
|
+
elsif self.object_type == "invoice"
|
38
|
+
object_type = self.object_type + "s"
|
39
|
+
elsif self.object_type == "subscription"
|
40
|
+
object_type = self.object_type + "s"
|
41
|
+
else
|
42
|
+
object_type = self.object_type
|
43
|
+
end
|
44
|
+
object_type
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Iugu
|
2
|
+
module APISave
|
3
|
+
def save
|
4
|
+
copy Iugu::Factory.create_from_response(self.class.object_type, APIRequest.request(is_new? ? "POST" : "PUT", self.class.url(self.attributes), modified_attributes))
|
5
|
+
self.errors = nil
|
6
|
+
true
|
7
|
+
rescue Iugu::RequestWithErrors => ex
|
8
|
+
self.errors = ex.errors
|
9
|
+
false
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Iugu
|
2
|
+
module APICreate
|
3
|
+
module ClassMethods
|
4
|
+
def search(options = {})
|
5
|
+
Iugu::Factory.create_from_response self.object_type, APIRequest.request("GET", self.url(options), options)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.included(base)
|
10
|
+
base.extend(ClassMethods)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/iugu/charge.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
module Iugu
|
2
|
+
class Customer < APIResource
|
3
|
+
include Iugu::APIFetch
|
4
|
+
include Iugu::APICreate
|
5
|
+
include Iugu::APISave
|
6
|
+
include Iugu::APIDelete
|
7
|
+
|
8
|
+
def payment_methods
|
9
|
+
APIChildResource.new({ customer_id: self.id }, Iugu::PaymentMethod)
|
10
|
+
end
|
11
|
+
|
12
|
+
def invoices
|
13
|
+
APIChildResource.new({ customer_id: self.id }, Iugu::Invoice)
|
14
|
+
end
|
15
|
+
|
16
|
+
def default_payment_method
|
17
|
+
return false unless @attributes['default_payment_method_id']
|
18
|
+
PaymentMethod.fetch({ id: @attributes['default_payment_method_id'], customer_id: self.id })
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/iugu/factory.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
module Iugu
|
2
|
+
class Factory
|
3
|
+
def self.create_from_response(object_type, response, errors = nil)
|
4
|
+
if response.nil?
|
5
|
+
obj = Iugu.const_get(Iugu::Utils.camelize(object_type)).new
|
6
|
+
obj.errors = errors if errors
|
7
|
+
obj
|
8
|
+
elsif response.is_a?(Array)
|
9
|
+
results = []
|
10
|
+
response.each do |i|
|
11
|
+
results.push Iugu.const_get(Iugu::Utils.camelize(object_type)).new i
|
12
|
+
end
|
13
|
+
Iugu::SearchResult.new results, results.count
|
14
|
+
elsif response['items'] && response['totalItems']
|
15
|
+
results = []
|
16
|
+
response['items'].each do |v|
|
17
|
+
results.push self.create_from_response(object_type, v)
|
18
|
+
end
|
19
|
+
Iugu::SearchResult.new results, response['totalItems']
|
20
|
+
else
|
21
|
+
Iugu.const_get(Iugu::Utils.camelize(object_type)).new response
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/iugu/invoice.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
module Iugu
|
2
|
+
class Invoice < APIResource
|
3
|
+
include Iugu::APIFetch
|
4
|
+
include Iugu::APICreate
|
5
|
+
include Iugu::APISave
|
6
|
+
include Iugu::APIDelete
|
7
|
+
|
8
|
+
def customer
|
9
|
+
return false unless @attributes["customer_id"]
|
10
|
+
Customer.fetch @attributes["customer_id"]
|
11
|
+
end
|
12
|
+
|
13
|
+
def cancel
|
14
|
+
copy Iugu::Factory.create_from_response(self.class.object_type, APIRequest.request("PUT", "#{self.class.url(self.id)}/cancel"))
|
15
|
+
self.errors = nil
|
16
|
+
true
|
17
|
+
rescue Iugu::RequestWithErrors => ex
|
18
|
+
self.errors = ex.errors
|
19
|
+
false
|
20
|
+
end
|
21
|
+
|
22
|
+
def refund
|
23
|
+
copy Iugu::Factory.create_from_response(self.class.object_type, APIRequest.request("POST", "#{self.class.url(self.id)}/refund"))
|
24
|
+
self.errors = nil
|
25
|
+
true
|
26
|
+
rescue Iugu::RequestWithErrors => ex
|
27
|
+
self.errors = ex.errors
|
28
|
+
false
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/iugu/object.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
3
|
+
module Iugu
|
4
|
+
class Object
|
5
|
+
|
6
|
+
attr_accessor :errors
|
7
|
+
|
8
|
+
undef :id if method_defined?(:id)
|
9
|
+
|
10
|
+
def initialize(attributes = {})
|
11
|
+
@unsaved_attributes = Set.new
|
12
|
+
set_attributes attributes
|
13
|
+
end
|
14
|
+
|
15
|
+
def add_accessor(name)
|
16
|
+
metaclass.instance_eval do
|
17
|
+
define_method(name.to_s) { @attributes[name.to_s] }
|
18
|
+
define_method(name.to_s + "=") do |value|
|
19
|
+
@attributes[name.to_s] = value
|
20
|
+
@unsaved_attributes.add name.to_s
|
21
|
+
end unless name.to_s == 'id'
|
22
|
+
end
|
23
|
+
self.class.__send__ :attr_accessor, name.to_sym
|
24
|
+
end
|
25
|
+
|
26
|
+
def method_missing(name, *args)
|
27
|
+
return super unless name.to_s.end_with? '='
|
28
|
+
return super if name.to_s.start_with? 'id'
|
29
|
+
add_accessor(name.to_s[0...-1])
|
30
|
+
return send(name, args[0])
|
31
|
+
end
|
32
|
+
|
33
|
+
def attributes
|
34
|
+
@attributes
|
35
|
+
end
|
36
|
+
|
37
|
+
def modified_attributes
|
38
|
+
Iugu::Utils.intersect @unsaved_attributes, @attributes
|
39
|
+
end
|
40
|
+
|
41
|
+
def copy(object)
|
42
|
+
@unsaved_attributes = Set.new
|
43
|
+
@attributes = {}
|
44
|
+
set_attributes object.attributes
|
45
|
+
end
|
46
|
+
|
47
|
+
def set_attributes(attributes, unsaved = false)
|
48
|
+
@attributes = Iugu::Utils.stringify_keys(attributes)
|
49
|
+
@attributes.each do |k, v|
|
50
|
+
add_accessor(k)
|
51
|
+
end
|
52
|
+
@unsaved_attributes = @attributes.keys.to_set if unsaved
|
53
|
+
end
|
54
|
+
|
55
|
+
protected
|
56
|
+
|
57
|
+
def metaclass
|
58
|
+
class << self; self; end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Iugu
|
2
|
+
class PaymentMethod < APIResource
|
3
|
+
include Iugu::APIFetch
|
4
|
+
include Iugu::APICreate
|
5
|
+
include Iugu::APISave
|
6
|
+
include Iugu::APIDelete
|
7
|
+
|
8
|
+
def self.url(options = {})
|
9
|
+
customer_id = options[:customer_id] || options["customer_id"]
|
10
|
+
id = options[:id] || options["id"]
|
11
|
+
raise StandardError, "Missing Customer ID" unless customer_id
|
12
|
+
"#{Customer.url customer_id}/#{self.object_base_uri}" + self.relative_url(id)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Iugu
|
2
|
+
class Subscription < APIResource
|
3
|
+
include Iugu::APIFetch
|
4
|
+
include Iugu::APICreate
|
5
|
+
include Iugu::APISave
|
6
|
+
include Iugu::APIDelete
|
7
|
+
|
8
|
+
def suspend
|
9
|
+
copy Iugu::Factory.create_from_response(self.class.object_type, APIRequest.request("POST", "#{self.class.url(self.id)}/suspend"))
|
10
|
+
self.errors = nil
|
11
|
+
true
|
12
|
+
rescue Iugu::RequestWithErrors => ex
|
13
|
+
self.errors = ex.errors
|
14
|
+
false
|
15
|
+
end
|
16
|
+
|
17
|
+
def activate
|
18
|
+
copy Iugu::Factory.create_from_response(self.class.object_type, APIRequest.request("POST", "#{self.class.url(self.id)}/activate"))
|
19
|
+
self.errors = nil
|
20
|
+
true
|
21
|
+
rescue Iugu::RequestWithErrors => ex
|
22
|
+
self.errors = ex.errors
|
23
|
+
false
|
24
|
+
end
|
25
|
+
|
26
|
+
def change_plan(plan_identifier)
|
27
|
+
copy Iugu::Factory.create_from_response(self.class.object_type, APIRequest.request("POST", "#{self.class.url(self.id)}/change_plan/#{plan_identifier}"))
|
28
|
+
self.errors = nil
|
29
|
+
true
|
30
|
+
rescue Iugu::RequestWithErrors => ex
|
31
|
+
self.errors = ex.errors
|
32
|
+
false
|
33
|
+
end
|
34
|
+
|
35
|
+
def customer
|
36
|
+
return false unless @attributes['customer_id']
|
37
|
+
Customer.fetch @attributes['customer_id']
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/iugu/utils.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
module Iugu
|
2
|
+
class Utils
|
3
|
+
def self.auth_from_env
|
4
|
+
api_key = ENV['IUGU_API_KEY']
|
5
|
+
Iugu.api_key = api_key if api_key
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.intersect(array, another_hash)
|
9
|
+
keys_intersection = array & another_hash.keys
|
10
|
+
intersection = {}
|
11
|
+
keys_intersection.each {|k| intersection[k] = another_hash[k]}
|
12
|
+
intersection
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.underscore(string)
|
16
|
+
string.gsub(/::/, '/').
|
17
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
18
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
19
|
+
tr("-", "_").
|
20
|
+
downcase
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.camelize(string)
|
24
|
+
string.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.stringify_keys(hash)
|
28
|
+
new_hash = {}
|
29
|
+
hash.each do |key, value|
|
30
|
+
if value.is_a? Hash
|
31
|
+
new_hash[key.to_s] = stringify_keys(value)
|
32
|
+
else
|
33
|
+
new_hash[key.to_s] = value
|
34
|
+
end
|
35
|
+
end
|
36
|
+
new_hash
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/iugu/version.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
require_relative '../../test_helper'
|
2
|
+
|
3
|
+
describe Iugu::Customer do
|
4
|
+
it "must be defined" do
|
5
|
+
Iugu::Customer.wont_be_nil
|
6
|
+
end
|
7
|
+
|
8
|
+
=begin
|
9
|
+
|
10
|
+
describe "fetching customers" do
|
11
|
+
describe "using a correct customer id" do
|
12
|
+
before do
|
13
|
+
@customer = Iugu::Customer.create({ email: "teste@teste.com", name: "Nome do Cliente" })
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should return a customer object" do
|
17
|
+
@customer.name = "NEW NAME"
|
18
|
+
assert @customer.save
|
19
|
+
end
|
20
|
+
|
21
|
+
after do
|
22
|
+
@customer.delete
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "fetching customers" do
|
28
|
+
describe "using a correct customer id" do
|
29
|
+
before do
|
30
|
+
@customer = Iugu::Customer.create({ email: "teste@teste.com", name: "Nome do Cliente" })
|
31
|
+
@fetched_customer = Iugu::Customer.fetch @customer.id
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should return a customer object" do
|
35
|
+
assert @fetched_customer.is_a? Iugu::Customer
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should have an id" do
|
39
|
+
assert @fetched_customer.id && @fetched_customer.id.length > 0
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "using a wrong customer id" do
|
44
|
+
it "should raise not found exception" do
|
45
|
+
proc { @fetched_customer = Iugu::Customer.fetch "BLABLABLA" }.must_raise Iugu::ObjectNotFound
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "creating customers" do
|
51
|
+
before do
|
52
|
+
@customer = Iugu::Customer.create({ email: "teste@teste.com", name: "Nome do Cliente" })
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "using correct data" do
|
56
|
+
it "should return a customer object" do
|
57
|
+
assert @customer.is_a? Iugu::Customer
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should have an id" do
|
61
|
+
assert @customer.id && @customer.id.length > 0
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "deleting customers" do
|
67
|
+
before do
|
68
|
+
@customer = Iugu::Customer.create({ email: "teste@teste.com", name: "Nome do Cliente" })
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should return true" do
|
72
|
+
assert @customer.delete
|
73
|
+
end
|
74
|
+
end
|
75
|
+
=end
|
76
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: iugu
|
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: 2014-01-16 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: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ! '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.5'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.5'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ! '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description:
|
56
|
+
email:
|
57
|
+
- marcelo@iugu.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- .gitignore
|
63
|
+
- Gemfile
|
64
|
+
- LICENSE.txt
|
65
|
+
- README.md
|
66
|
+
- Rakefile
|
67
|
+
- iugu.gemspec
|
68
|
+
- lib/iugu.rb
|
69
|
+
- lib/iugu/api_child_resource.rb
|
70
|
+
- lib/iugu/api_create.rb
|
71
|
+
- lib/iugu/api_delete.rb
|
72
|
+
- lib/iugu/api_fetch.rb
|
73
|
+
- lib/iugu/api_request.rb
|
74
|
+
- lib/iugu/api_resource.rb
|
75
|
+
- lib/iugu/api_save.rb
|
76
|
+
- lib/iugu/api_search.rb
|
77
|
+
- lib/iugu/charge.rb
|
78
|
+
- lib/iugu/customer.rb
|
79
|
+
- lib/iugu/factory.rb
|
80
|
+
- lib/iugu/invoice.rb
|
81
|
+
- lib/iugu/object.rb
|
82
|
+
- lib/iugu/payment_method.rb
|
83
|
+
- lib/iugu/payment_token.rb
|
84
|
+
- lib/iugu/search_result.rb
|
85
|
+
- lib/iugu/subscription.rb
|
86
|
+
- lib/iugu/utils.rb
|
87
|
+
- lib/iugu/version.rb
|
88
|
+
- test/lib/iugu/customer_test.rb
|
89
|
+
- test/lib/iugu/version_test.rb
|
90
|
+
- test/test_helper.rb
|
91
|
+
homepage: https://iugu.com
|
92
|
+
licenses:
|
93
|
+
- MIT
|
94
|
+
metadata: {}
|
95
|
+
post_install_message:
|
96
|
+
rdoc_options: []
|
97
|
+
require_paths:
|
98
|
+
- lib
|
99
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ! '>='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
105
|
+
requirements:
|
106
|
+
- - ! '>='
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '0'
|
109
|
+
requirements: []
|
110
|
+
rubyforge_project:
|
111
|
+
rubygems_version: 2.2.0
|
112
|
+
signing_key:
|
113
|
+
specification_version: 4
|
114
|
+
summary: Iugu API
|
115
|
+
test_files:
|
116
|
+
- test/lib/iugu/customer_test.rb
|
117
|
+
- test/lib/iugu/version_test.rb
|
118
|
+
- test/test_helper.rb
|