garbanzo 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
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
@@ -0,0 +1,9 @@
1
+ module Garbanzo
2
+ module AST
3
+ require 'garbanzo/ast/base'
4
+ require 'garbanzo/ast/create'
5
+ require 'garbanzo/ast/cancel'
6
+ require 'garbanzo/ast/status'
7
+ require 'garbanzo/ast/update'
8
+ end
9
+ end
@@ -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,11 @@
1
+ module Garbanzo
2
+ class Connection
3
+ attr_accessor :login, :password, :test_mode
4
+
5
+ def initialize(login = nil, password = nil, test_mode = false)
6
+ @login = login
7
+ @password = password
8
+ @test_mode = test_mode
9
+ end
10
+ end
11
+ 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,10 @@
1
+ require 'garbanzo/credentials'
2
+ require 'garbanzo/interval'
3
+ require 'garbanzo/duration'
4
+ require 'garbanzo/address'
5
+ require 'garbanzo/credit_card'
6
+
7
+ module Garbanzo
8
+ module Parameters
9
+ end
10
+ 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