garbanzo 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.travis.yml +3 -0
- data/Gemfile +4 -0
- data/LICENSE +278 -0
- data/README.md +122 -0
- data/Rakefile +9 -0
- data/bin/console +7 -0
- data/bin/setup +7 -0
- data/garbanzo.gemspec +31 -0
- data/lib/garbanzo.rb +43 -0
- data/lib/garbanzo/address.rb +35 -0
- data/lib/garbanzo/ast.rb +9 -0
- data/lib/garbanzo/ast/base.rb +33 -0
- data/lib/garbanzo/ast/cancel.rb +19 -0
- data/lib/garbanzo/ast/create.rb +30 -0
- data/lib/garbanzo/ast/status.rb +19 -0
- data/lib/garbanzo/ast/update.rb +30 -0
- data/lib/garbanzo/connection.rb +11 -0
- data/lib/garbanzo/credentials.rb +23 -0
- data/lib/garbanzo/credit_card.rb +36 -0
- data/lib/garbanzo/duration.rb +21 -0
- data/lib/garbanzo/interval.rb +45 -0
- data/lib/garbanzo/parameters.rb +10 -0
- data/lib/garbanzo/parser.rb +21 -0
- data/lib/garbanzo/request.rb +33 -0
- data/lib/garbanzo/response.rb +25 -0
- data/lib/garbanzo/subscription.rb +54 -0
- data/lib/garbanzo/subscription/base.rb +46 -0
- data/lib/garbanzo/subscription/cancel.rb +11 -0
- data/lib/garbanzo/subscription/create.rb +16 -0
- data/lib/garbanzo/subscription/status.rb +21 -0
- data/lib/garbanzo/subscription/update.rb +16 -0
- data/lib/garbanzo/version.rb +3 -0
- metadata +231 -0
data/bin/setup
ADDED
data/garbanzo.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
lib = File.expand_path('../lib', __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require 'garbanzo/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = 'garbanzo'
|
7
|
+
spec.version = Garbanzo::VERSION
|
8
|
+
spec.authors = ['Corin Schedler']
|
9
|
+
spec.email = ['corin@dubdromic.com']
|
10
|
+
|
11
|
+
spec.summary = 'A small library for interacting with Authorize ARB'
|
12
|
+
spec.description = 'A small library for interacting with Authorize ARB'
|
13
|
+
spec.homepage = 'https://github.com/dubdromic/garbanzo'
|
14
|
+
spec.license = 'GPLv2'
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
17
|
+
spec.require_paths = ['lib']
|
18
|
+
|
19
|
+
spec.add_dependency 'active_attr'
|
20
|
+
spec.add_dependency 'nokogiri'
|
21
|
+
spec.add_dependency 'gyoku', '~> 1.0'
|
22
|
+
spec.add_dependency 'faraday'
|
23
|
+
|
24
|
+
spec.add_development_dependency 'bundler', '~> 1.9'
|
25
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
26
|
+
spec.add_development_dependency 'pry'
|
27
|
+
spec.add_development_dependency 'minitest', '~> 5.0'
|
28
|
+
spec.add_development_dependency 'minitest-color'
|
29
|
+
spec.add_development_dependency 'credit_card_validator'
|
30
|
+
spec.add_development_dependency 'webmock'
|
31
|
+
end
|
data/lib/garbanzo.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'garbanzo/version'
|
2
|
+
require 'pry'
|
3
|
+
require 'active_attr'
|
4
|
+
|
5
|
+
# Garbanzo - A small Ruby library for interacting with Authorize.Net ARB
|
6
|
+
# Copyright (c) 2015 Corin Schedler
|
7
|
+
#
|
8
|
+
# This program is free software; you can redistribute it and/or modify
|
9
|
+
# it under the terms of the GNU General Public License as published by
|
10
|
+
# the Free Software Foundation; either version 2 of the License, or
|
11
|
+
# (at your option) any later version.
|
12
|
+
#
|
13
|
+
# This program is distributed in the hope that it will be useful,
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16
|
+
# GNU General Public License for more details.
|
17
|
+
#
|
18
|
+
# You should have received a copy of the GNU General Public License along
|
19
|
+
# with this program; if not, write to the Free Software Foundation, Inc.,
|
20
|
+
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
21
|
+
|
22
|
+
module Garbanzo
|
23
|
+
require 'garbanzo/connection'
|
24
|
+
require 'garbanzo/parser'
|
25
|
+
require 'garbanzo/request'
|
26
|
+
require 'garbanzo/response'
|
27
|
+
require 'garbanzo/ast'
|
28
|
+
require 'garbanzo/parameters'
|
29
|
+
require 'garbanzo/subscription'
|
30
|
+
|
31
|
+
TEST_HOST = 'https://apitest.authorize.net'
|
32
|
+
LIVE_HOST = 'https://api2.authorize.net'
|
33
|
+
API_URI = '/xml/v1/request.api'
|
34
|
+
|
35
|
+
class << self
|
36
|
+
attr_accessor :connection
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.configure
|
40
|
+
self.connection ||= Connection.new
|
41
|
+
yield connection
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Garbanzo
|
2
|
+
class Address
|
3
|
+
ATTRIBUTES = [
|
4
|
+
:first_name,
|
5
|
+
:last_name,
|
6
|
+
:company,
|
7
|
+
:address1,
|
8
|
+
:address2,
|
9
|
+
:city,
|
10
|
+
:state,
|
11
|
+
:zip,
|
12
|
+
:country
|
13
|
+
]
|
14
|
+
|
15
|
+
attr_accessor *ATTRIBUTES
|
16
|
+
|
17
|
+
def initialize(options = {})
|
18
|
+
options.each do |attribute, value|
|
19
|
+
public_send("#{attribute}=", value)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def valid?
|
24
|
+
first_name.to_s != '' && last_name.to_s != ''
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_h
|
28
|
+
ATTRIBUTES.reduce({}) do |hash, attribute|
|
29
|
+
value = public_send(attribute)
|
30
|
+
hash.merge!(attribute => value) if value
|
31
|
+
hash
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/garbanzo/ast.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
module Garbanzo
|
2
|
+
module AST
|
3
|
+
class Base
|
4
|
+
attr_accessor :nodes
|
5
|
+
|
6
|
+
def initialize(credentials)
|
7
|
+
@credentials = credentials
|
8
|
+
@nodes = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
attr_reader :credentials
|
14
|
+
|
15
|
+
def set_nodes(hash)
|
16
|
+
@nodes = {
|
17
|
+
type => credentials_hash.merge(hash),
|
18
|
+
:attributes! => { type => { xmlns: 'AnetApi/xml/v1/schema/AnetApiSchema.xsd' }}
|
19
|
+
}
|
20
|
+
self
|
21
|
+
end
|
22
|
+
|
23
|
+
def credentials_hash
|
24
|
+
{
|
25
|
+
merchant_authentication: {
|
26
|
+
name: credentials.login,
|
27
|
+
transaction_key: credentials.password
|
28
|
+
}
|
29
|
+
}
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Garbanzo
|
2
|
+
module AST
|
3
|
+
class Cancel < Base
|
4
|
+
def build(subscription_id)
|
5
|
+
hash = {
|
6
|
+
subscription_id: subscription_id
|
7
|
+
}
|
8
|
+
|
9
|
+
set_nodes hash
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def type
|
15
|
+
'ARBCancelSubscriptionRequest'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Garbanzo
|
2
|
+
module AST
|
3
|
+
class Create < Base
|
4
|
+
def build(amount, card, address, duration, interval)
|
5
|
+
hash = {
|
6
|
+
subscription: {
|
7
|
+
payment_schedule: {
|
8
|
+
interval: interval.to_h,
|
9
|
+
start_date: duration.start_date,
|
10
|
+
total_occurrences: duration.occurrences
|
11
|
+
},
|
12
|
+
amount: amount.to_i,
|
13
|
+
payment: {
|
14
|
+
credit_card: card.to_h
|
15
|
+
},
|
16
|
+
bill_to: address.to_h,
|
17
|
+
}
|
18
|
+
}
|
19
|
+
|
20
|
+
set_nodes hash
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def type
|
26
|
+
'ARBCreateSubscriptionRequest'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Garbanzo
|
2
|
+
module AST
|
3
|
+
class Status < Base
|
4
|
+
def build(subscription_id)
|
5
|
+
hash = {
|
6
|
+
subscription_id: subscription_id
|
7
|
+
}
|
8
|
+
|
9
|
+
set_nodes hash
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def type
|
15
|
+
'ARBGetSubscriptionStatusRequest'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Garbanzo
|
2
|
+
module AST
|
3
|
+
class Update < Base
|
4
|
+
def build(subscription_id, amount, card, address, duration, interval)
|
5
|
+
hash = {
|
6
|
+
subscription_id: subscription_id,
|
7
|
+
subscription: {
|
8
|
+
payment_schedule: {
|
9
|
+
start_date: duration.start_date,
|
10
|
+
total_occurrences: duration.occurrences
|
11
|
+
},
|
12
|
+
amount: amount.to_i,
|
13
|
+
payment: {
|
14
|
+
credit_card: card.to_h
|
15
|
+
},
|
16
|
+
bill_to: address.to_h,
|
17
|
+
}
|
18
|
+
}
|
19
|
+
|
20
|
+
set_nodes hash
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def type
|
26
|
+
'ARBUpdateSubscriptionRequest'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Garbanzo
|
2
|
+
class Credentials
|
3
|
+
attr_reader :login, :password, :test_mode
|
4
|
+
|
5
|
+
def initialize(login, password, test_mode = true)
|
6
|
+
@login = login
|
7
|
+
@password = password
|
8
|
+
@test_mode = test_mode
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_h
|
12
|
+
{
|
13
|
+
login: login,
|
14
|
+
password: password,
|
15
|
+
test_mode: test_mode
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
def valid?
|
20
|
+
true
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'credit_card_validator'
|
2
|
+
|
3
|
+
module Garbanzo
|
4
|
+
class CreditCard
|
5
|
+
attr_accessor :number, :exp_month, :exp_year
|
6
|
+
|
7
|
+
def initialize(number, exp_month, exp_year, card_validator = ::CreditCardValidator::Validator)
|
8
|
+
@number = number.gsub(/[^\d]/, '')
|
9
|
+
@exp_month = exp_month.to_i
|
10
|
+
@exp_year = exp_year.to_i
|
11
|
+
@card_validator = card_validator
|
12
|
+
end
|
13
|
+
|
14
|
+
# TODO: fix this
|
15
|
+
def valid?
|
16
|
+
exp_month.between?(1, 12) &&
|
17
|
+
exp_year >= Date.today.year &&
|
18
|
+
card_validator.valid?(number)
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_h
|
22
|
+
{
|
23
|
+
card_number: number,
|
24
|
+
expiration_date: expiration_date
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
28
|
+
def expiration_date
|
29
|
+
format('%04d-%02d', exp_year, exp_month)
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
attr_reader :card_validator
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Garbanzo
|
2
|
+
class Duration
|
3
|
+
attr_reader :start_date, :occurrences
|
4
|
+
|
5
|
+
def initialize(start_date = Date.today, occurrences = 9999)
|
6
|
+
@start_date = start_date
|
7
|
+
@occurrences = occurrences.to_i
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_h
|
11
|
+
{
|
12
|
+
start_date: start_date,
|
13
|
+
occurrences: occurrences
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
def valid?
|
18
|
+
start_date.respond_to?(:strftime) && occurrences.between?(1, 9999)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Garbanzo
|
2
|
+
class Interval
|
3
|
+
attr_reader :length, :unit
|
4
|
+
|
5
|
+
def initialize(length = 1, unit = :month)
|
6
|
+
@length = length.to_i
|
7
|
+
@unit = normalize_unit unit.to_sym
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_h
|
11
|
+
{
|
12
|
+
length: length,
|
13
|
+
unit: unit
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
def valid?
|
18
|
+
unit_valid? && length_valid?
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def normalize_unit(unit)
|
24
|
+
unit == :month ? :months : unit
|
25
|
+
end
|
26
|
+
|
27
|
+
def unit_valid?
|
28
|
+
months? || days?
|
29
|
+
end
|
30
|
+
|
31
|
+
def length_valid?
|
32
|
+
fail NotImplementedError unless unit_valid?
|
33
|
+
return length.between?(1, 12) if months?
|
34
|
+
return length.between?(7, 365) if days?
|
35
|
+
end
|
36
|
+
|
37
|
+
def months?
|
38
|
+
unit == :months
|
39
|
+
end
|
40
|
+
|
41
|
+
def days?
|
42
|
+
unit == :days
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
|
3
|
+
module Garbanzo
|
4
|
+
class Parser
|
5
|
+
def initialize(raw_document)
|
6
|
+
@raw_document = raw_document
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
attr_reader :raw_document
|
12
|
+
|
13
|
+
def node(name)
|
14
|
+
document.search(name.to_s).text
|
15
|
+
end
|
16
|
+
|
17
|
+
def document
|
18
|
+
@document ||= Nokogiri::XML.parse raw_document
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|