alpha_card 0.1.6 → 0.1.7

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f7e8e249cdf49bffd9bbda0825018bc6406e0c52
4
- data.tar.gz: 6241892718864310e112ec3c39eb6cdc7efac26f
3
+ metadata.gz: 6af86a7de326ef53708c81f07ed025792c44841c
4
+ data.tar.gz: 5a670c2177f9b7ac326f34ea1c3e34decd5ea37c
5
5
  SHA512:
6
- metadata.gz: d604d1ca794b016047390a7bd9915a54ae3ef4d4b25d4514808ac28f109a5f2aeb9e328793f58df4b706ddc7b3557800c15906df9893e6d23d68687a6beec605
7
- data.tar.gz: 7a46b389c6aaeec686a189e5add88b864929ffe1be3169fa5f5e40c285da37efb5e593d8635367ce722329d12dc24d5781aa33970717ca6dc6d0c9c0dd35e65b
6
+ metadata.gz: ca0333c53125849ca415b73a10d9a4c659d54cff80879bc0f2aadd3aa502ffecc3af758ed87709ce83ba7016d57679b7a6f023f672952d7e9f3788fda29f7ad1
7
+ data.tar.gz: 0bea0ef881a98bd593a99a20883de46f2b94f1d6cf384caa39dbeaed8f95f53a99afa8855a22becba76f0e0f6b5ac90017263dda9d2473a4564e7938c525d7a9
data/Gemfile CHANGED
@@ -4,5 +4,4 @@ gemspec
4
4
 
5
5
  gem 'virtus'
6
6
  gem 'rest_client'
7
- gem 'rack'
8
7
  gem 'coveralls', require: false
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |gem|
2
2
  gem.name = 'alpha_card'
3
- gem.version = '0.1.6'
4
- gem.date = '2014-06-26'
3
+ gem.version = '0.1.7'
4
+ gem.date = '2014-06-27'
5
5
  gem.summary = 'Alpha Card Services DirectPost API for Ruby'
6
6
  gem.description = 'Gem for creating sales with Alpha Card Services DirectPost API'
7
7
  gem.authors = ['Nikita Bulaj']
@@ -1,8 +1,9 @@
1
+ # encoding:utf-8
1
2
  require 'yaml'
2
3
  require 'virtus'
3
- require 'rack'
4
4
  require 'rest_client'
5
5
 
6
+ require 'alpha_card/utils'
6
7
  require 'alpha_card/object'
7
8
  require 'alpha_card/alpha_card_object'
8
9
  require 'alpha_card/alpha_card_response'
@@ -14,25 +15,55 @@ require 'alpha_card/billing'
14
15
  require 'alpha_card/order'
15
16
  require 'alpha_card/sale'
16
17
 
18
+ ##
19
+ # AlphaCard is a library for processing payments with Alpha Card Services, Inc.
17
20
  module AlphaCard
18
- # DirectPost API URL
21
+ ##
22
+ # Alpha Card Gateway DirectPost API URL
19
23
  @api_base = 'https://secure.alphacardgateway.com/api/transact.php'
20
24
 
25
+ ##
21
26
  # Global Payment Systems (NDC) Credit Card Authorization Codes
27
+ #
28
+ # @see http://floristwiki.ftdi.com/images/c/ce/Appendix_A_-_Credit_Card_Authorization_Codes.pdf Credit Card Authorization Codes
22
29
  CREDIT_CARD_CODES = YAML.load_file(File.expand_path('../alpha_card/data/codes.yml', __FILE__)) unless defined? CREDIT_CARD_CODES
23
30
 
24
31
  class << self
32
+ # @return [String] Alpha Card Gateway DirectPost API URL.
25
33
  attr_accessor :api_base
26
34
  end
27
35
 
28
- # AlphaCard.request(params, account) -> AlphaCardResponse
36
+ ##
37
+ # Send the POST request to the AlphaCard Gateway from the
38
+ # specified account. Request must contains params - Alpha Card
39
+ # transcation variables.
40
+ #
41
+ # @param [Hash] params
42
+ # Alpha Card transaction variables.
43
+ # @param [AlphaCard::Account] account
44
+ # An <code>AlphaCard::Account</code> credentials object.
45
+ #
46
+ # @return [AlphaCard::AlphaCardResponse]
47
+ # Response from Alpha Card Gateway.
29
48
  #
30
- # Do the POST request to the AlphaCard Gateway with <i>params</i>
31
- # from specified AlphaCard <i>account</i>.
49
+ # @raise [AlphaCard::AlphaCardError]
50
+ # AlphaCardError Exception if request failed.
32
51
  #
33
- # account = AlphaCard::Account.new('user', 'pass')
34
- # params = {amount: '10.00'}
35
- # r = AlphaCard.request(params, account) #=> AlphaCardResponse
52
+ # @example
53
+ # account = AlphaCard::Account.new('demo', 'password')
54
+ # response = AlphaCard.request(
55
+ # {
56
+ # cexp: '0720',
57
+ # ccnumber: '4111111111111111',
58
+ # amount: '10.00'
59
+ # },
60
+ # account
61
+ # )
62
+ #
63
+ # #=> #<AlphaCard::AlphaCardResponse:0x1a0fda8 @data={"response"=>"1",
64
+ # "responsetext"=>"SUCCESS", "authcode"=>"123", "transactionid"=>"123",
65
+ # "avsresponse"=>"", "cvvresponse"=>"N", "orderid"=>"", "type"=>"",
66
+ # "response_code"=>"100"}>
36
67
  def self.request(params = {}, account)
37
68
  unless account.filled?
38
69
  raise AlphaCardError.new('You must set credentials to create the sale!')
@@ -52,26 +83,35 @@ module AlphaCard
52
83
 
53
84
  private
54
85
 
55
- # AlphaCard.handle_errors(response) -> Exception
56
- # AlphaCard.handle_errors(response) -> nil
86
+ ##
87
+ # Raises an exception if Alpha Card Gateway return an error or
88
+ # decline code for the request. Message is taken from the Global
89
+ # Payment Systems Credit Card Authorization Codes (codes.yml).
90
+ # If code wasn't found in <code>CREDIT_CARD_CODES</code>, then
91
+ # message = Alpha Card response text.
92
+ #
93
+ # @param [AlphaCard::AlphaCardResponse] response
94
+ # Alpha Card Response object.
57
95
  #
58
- # Raise an exception if AlphaCard Gateway return an error or decline
59
- # the request.
96
+ # @raise [AlphaCard::AlphaCardError]
97
+ # AlphaCardError Exception if request failed.
60
98
  #
61
- # response = AlphaCard.request(params, account)
62
- # handle_errors(response) #=> nil or Exception
99
+ # @return [String]
100
+ # Alpha Card Services response text.
63
101
  def self.handle_alpha_card_errors(response)
64
102
  code = response.text
65
103
  raise AlphaCardError.new(CREDIT_CARD_CODES[code] || code) unless response.success?
66
104
  end
67
105
 
68
- # AlphaCard.handle_connection_errors(exception) -> Exception
106
+ ##
107
+ # Raises an exception if a network error occurs. It
108
+ # could be request timeout, socket error or anything else.
69
109
  #
70
- # Raise an exception if AlphaCard Gateway return some exception
71
- # due to connection problems or some other net errors.
110
+ # @param [Exception] e
111
+ # Exception object.
72
112
  #
73
- # response = RestClient.post(URL, {param: 'value'})
74
- # handle_connection_errors(response) #=> Exception
113
+ # @raise [AlphaCard::AlphaCardError]
114
+ # AlphaCardError Exception.
75
115
  def self.handle_connection_errors(e)
76
116
  case e
77
117
  when RestClient::ServerBrokeConnection, RestClient::RequestTimeout
@@ -1,13 +1,45 @@
1
1
  module AlphaCard
2
+ ##
3
+ # Implementation of Alpha Card Services account object.
4
+ # Contains credentials (username and password) for
5
+ # the Alpha Card Gateway API access.
2
6
  class Account < AlphaCardObject
3
7
  attribute :username, String
4
8
  attribute :password, String
5
9
 
10
+ ##
11
+ # <code>AlphaCard::Account</code> constructor.
12
+ #
13
+ # @param [String] username
14
+ # @param [String] password
15
+ #
16
+ # @example
17
+ # AlphaCard::Account.new('demo', 'password')
18
+ #
19
+ # #=> #<AlphaCard::Account:0x000000039b18a8 @username="demo", @password="password">
6
20
  def initialize(username, password)
7
21
  self.username = username
8
22
  self.password = password
9
23
  end
10
24
 
25
+ ##
26
+ # Say if all the credentials of Account is filled.
27
+ # Username and password can't be a <code>nil</code>
28
+ # object or an empty <code>String</code>.
29
+ #
30
+ # @return [Boolean]
31
+ # True if username and password is filled.
32
+ #
33
+ # @example
34
+ # account = AlphaCard::Account.new('demo', 'password')
35
+ # account.filled?
36
+ #
37
+ # #=> true
38
+ #
39
+ # account = AlphaCard::Account.new('', nil)
40
+ # account.filled?
41
+ #
42
+ # #=> false
11
43
  def filled?
12
44
  [self.username, self.password].all?(&:present?)
13
45
  end
@@ -1,4 +1,6 @@
1
1
  module AlphaCard
2
+ ##
3
+ # Class for Alpha Card Gateway errors and exceptions.
2
4
  class AlphaCardError < StandardError
3
5
  end
4
6
  end
@@ -1,16 +1,22 @@
1
1
  module AlphaCard
2
+ ##
3
+ # Parent class for each Alpha Card Gateway object, such as
4
+ # Order, Billing, Sale and others.
2
5
  class AlphaCardObject
3
6
  include Virtus.model
4
7
 
5
- # filled_attributes -> Hash
8
+ ##
9
+ # Returns the <code>Hash</code> with only filled attributes
10
+ # of the <code>AlphaCard::AlphaCardObject</code>.
6
11
  #
7
- # Returns only filled attributes, not nil ones.
12
+ # @return [Hash]
13
+ # Filled attributes of the <code>AlphaCard::AlphaCardObject</code>.
8
14
  #
9
- # order = AlphaCard::Order.new({})
10
- # order.filled_attributes #=> {}
11
-
12
- # order = AlphaCard::Order.new({orderid: '1'})
13
- # order.filled_attributes #=> {orderid: '1'}
15
+ # @example
16
+ # order = AlphaCard::Order.new({orderid: '1', tax: nil, ponumber: 'PO123'})
17
+ # order.filled_attributes
18
+ #
19
+ # #=> {orderid: '1', ponumber: 'PO123'}
14
20
  def filled_attributes
15
21
  self.attributes.select { |key, value| value.present? }
16
22
  end
@@ -1,13 +1,20 @@
1
1
  module AlphaCard
2
+ ##
3
+ # Implementation of Alpha Card Services response.
4
+ # Contains all the data, that Alpha Card Gateway
5
+ # returned for the request.
2
6
  class AlphaCardResponse
3
7
  attr_reader :data
4
8
 
9
+ # Success response code
5
10
  APPROVED = '1'
11
+ # Decline response code
6
12
  DECLINED = '2'
13
+ # Error response code
7
14
  ERROR = '3'
8
15
 
9
16
  def initialize(request_body)
10
- @data = Rack::Utils.parse_nested_query(request_body)
17
+ @data = AlphaCard::Utils.parse_query(request_body)
11
18
  end
12
19
 
13
20
  def text
@@ -1,4 +1,7 @@
1
1
  module AlphaCard
2
+ ##
3
+ # Implementation of Alpha Card Services order billing information.
4
+ # Contains all the billing information (customer name, email, email, etc).
2
5
  class Billing < AlphaCardObject
3
6
  attribute :firstname, String
4
7
  attribute :lastname, String
@@ -1,17 +1,47 @@
1
- # Object class needed to implement some nice
2
- # active_support features for projects, that
3
- # doesn't need active_support.
4
- #
5
- # Use-case: standalone Ruby scripts
1
+ ##
2
+ # Some stolen methods from the active_support gem.
3
+ # For the clear dependencies.
4
+ # @todo Remove this class, rewrite library code
6
5
  class Object
6
+ # An object is blank if it's false, empty, or a whitespace string.
7
+ # For example, '', ' ', +nil+, [], and {} are all blank.
8
+ #
9
+ # This simplifies
10
+ #
11
+ # address.nil? || address.empty?
12
+ #
13
+ # to
14
+ #
15
+ # address.blank?
16
+ #
17
+ # @return [true, false]
7
18
  def blank?
8
19
  respond_to?(:empty?) ? !!empty? : !self
9
20
  end
10
21
 
22
+ # An object is present if it's not blank.
23
+ #
24
+ # @return [true, false]
11
25
  def present?
12
26
  !blank?
13
27
  end
14
28
 
29
+ # Invokes the public method whose name goes as first argument just like
30
+ # +public_send+ does, except that if the receiver does not respond to it the
31
+ # call returns +nil+ rather than raising an exception.
32
+ #
33
+ # This method is defined to be able to write
34
+ #
35
+ # @person.try(:name)
36
+ #
37
+ # instead of
38
+ #
39
+ # @person ? @person.name : nil
40
+ #
41
+ # +try+ returns +nil+ when called on +nil+ regardless of whether it responds
42
+ # to the method:
43
+ #
44
+ # nil.try(:to_i) # => nil, rather than 0
15
45
  def try(*a, &b)
16
46
  if a.empty? && block_given?
17
47
  yield self
@@ -1,4 +1,7 @@
1
1
  module AlphaCard
2
+ ##
3
+ # Implementation of Alpha Card Services Order object.
4
+ # Contains all the information about order (id, description, etc).
2
5
  class Order < AlphaCardObject
3
6
  attribute :orderid, Integer
4
7
  attribute :orderdescription, String
@@ -1,24 +1,44 @@
1
1
  module AlphaCard
2
+ ##
3
+ # Implementation of Alpha Card Services Sale object.
4
+ # Contains all the information about Customer Credit Card,
5
+ # such as CVV, number, expiration date, etc.
6
+ # Process the Alpha Card Services payment.
2
7
  class Sale < AlphaCardObject
3
8
  attribute :ccexp, String
4
9
  attribute :ccnumber, String
5
10
  attribute :amount, String
6
11
  attribute :cvv, String
7
12
 
8
- # Not writable attribute, define the type of transaction (default is 'sale')
13
+ ##
14
+ # Not writable attribute, defines the type of transaction (default is 'sale')
15
+ #
16
+ # @attribute [r] type
9
17
  attribute :type, String, default: 'sale', writer: :private
10
18
 
11
- # create(order, account) -> true
12
- # create(order, account) -> false
13
- # create(order, account) -> Exception
19
+ ##
20
+ # Creates the sale for the specified <code>AlphaCard::Order</code>
21
+ # with the <code>AlphaCard::Account</code> credentials.
22
+ #
23
+ # @param [AlphaCard::Order] params
24
+ # An <code>AlphaCard::Order</code> object.
25
+ # @param [AlphaCard::Account] account
26
+ # An <code>AlphaCard::Account</code> object.
27
+ #
28
+ # @return [Boolean]
29
+ # True if sale was created successfully.
30
+ # Raise an AlphaCardError exception if some error occurred.
31
+ #
32
+ # @raise [Exception]
33
+ # Exception if one of required attributes doesn't specified.
14
34
  #
15
- # Creates the sale for the <i>order</i> with specified
16
- # attributes, such as <i>ccexp</i>, <i>ccnumber</i>, <i>amount</i>
17
- # and <i>cvv</i>.
35
+ # @example
36
+ # account = AlphaCard::Account.new('demo', 'password')
37
+ # order = AlphaCard::Order.new({orderid: 1, orderdescription: 'Test order'})
38
+ # sale = AlphaCard::Sale.new({ccexp: '0117', ccnumber: '4111111111111111', amount: "5.00" })
39
+ # sale.create(order, account)
18
40
  #
19
- # attrs = {ccexp: '0117', ccnumber: '123', amount: '10.00'}
20
- # sale = AlphaCard::Sale.new(attrs)
21
- # sale.create(order, account) #=> true or false
41
+ # #=> true
22
42
  def create(order, account)
23
43
  [:ccexp, :ccnumber, :amount].each do |attr|
24
44
  raise Exception.new("No #{attr} information provided") if self[attr].blank?
@@ -1,4 +1,7 @@
1
1
  module AlphaCard
2
+ ##
3
+ # Implementation of Alpha Card Services order shipping information.
4
+ # Contains all the shipping information (address, city, zip, etc).
2
5
  class Shipping < AlphaCardObject
3
6
  attribute :address_1, String
4
7
  attribute :address_2, String
@@ -0,0 +1,90 @@
1
+ module AlphaCard
2
+ ##
3
+ # Some stolen methods to clear library dependencies.
4
+ class Utils
5
+ ##
6
+ # This one is from the rack gem. It is useful for
7
+ # parsing of Alpha Card Gateway response body.
8
+ # @see https://github.com/rack/rack rack gem GitHub
9
+ class << self
10
+ ##
11
+ # Default separators for query string.
12
+ DEFAULT_SEP = /[&;] */n
13
+
14
+ # A part of the rack gem.
15
+ class KeySpaceConstrainedParams
16
+ def initialize(limit = 65536)
17
+ @limit = limit
18
+ @size = 0
19
+ @params = {}
20
+ end
21
+
22
+ def [](key)
23
+ @params[key]
24
+ end
25
+
26
+ def []=(key, value)
27
+ @size += key.size if key && !@params.key?(key)
28
+ raise RangeError, 'exceeded available parameter key space' if @size > @limit
29
+ @params[key] = value
30
+ end
31
+
32
+ def key?(key)
33
+ @params.key?(key)
34
+ end
35
+
36
+ def to_params_hash
37
+ hash = @params
38
+ hash.keys.each do |key|
39
+ value = hash[key]
40
+ if value.kind_of?(self.class)
41
+ hash[key] = value.to_params_hash
42
+ elsif value.kind_of?(Array)
43
+ value.map! { |x| x.kind_of?(self.class) ? x.to_params_hash : x }
44
+ end
45
+ end
46
+ hash
47
+ end
48
+ end
49
+
50
+ ##
51
+ # Unescapes a URI escaped string with +encoding+. +encoding+ will be the
52
+ # target encoding of the string returned, and it defaults to UTF-8
53
+ if defined?(::Encoding)
54
+ def unescape(s, encoding = Encoding::UTF_8)
55
+ URI.decode_www_form_component(s, encoding)
56
+ end
57
+ else
58
+ def unescape(s, encoding = nil)
59
+ URI.decode_www_form_component(s, encoding)
60
+ end
61
+ end
62
+
63
+ ##
64
+ # Parses a query string to a Hash by breaking it up
65
+ # at the '&' and ';' characters.
66
+ def parse_query(qs, d = nil, &unescaper)
67
+ unescaper ||= method(:unescape)
68
+
69
+ params = KeySpaceConstrainedParams.new
70
+
71
+ (qs || '').split(d ? /[#{d}] */n : DEFAULT_SEP).each do |p|
72
+ next if p.empty?
73
+ k, v = p.split('=', 2).map(&unescaper)
74
+
75
+ if cur = params[k]
76
+ if cur.class == Array
77
+ params[k] << v
78
+ else
79
+ params[k] = [cur, v]
80
+ end
81
+ else
82
+ params[k] = v
83
+ end
84
+ end
85
+
86
+ params.to_params_hash
87
+ end
88
+ end
89
+ end
90
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: alpha_card
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nikita Bulaj
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-26 00:00:00.000000000 Z
11
+ date: 2014-06-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -49,6 +49,7 @@ files:
49
49
  - lib/alpha_card/order.rb
50
50
  - lib/alpha_card/sale.rb
51
51
  - lib/alpha_card/shipping.rb
52
+ - lib/alpha_card/utils.rb
52
53
  - spec/alpha_card/alpha_card_response_spec.rb
53
54
  - spec/alpha_card/alpha_card_spec.rb
54
55
  - spec/spec_helper.rb
@@ -77,3 +78,4 @@ signing_key:
77
78
  specification_version: 4
78
79
  summary: Alpha Card Services DirectPost API for Ruby
79
80
  test_files: []
81
+ has_rdoc: