alpha_card 0.3.0 → 0.4.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.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +4 -4
  3. data/CHANGELOG.md +21 -3
  4. data/Gemfile +0 -2
  5. data/Gemfile.lock +6 -24
  6. data/README.md +115 -85
  7. data/ROADMAP.md +13 -9
  8. data/alpha_card.gemspec +3 -4
  9. data/lib/alpha_card.rb +44 -72
  10. data/lib/alpha_card/account.rb +51 -0
  11. data/lib/alpha_card/attribute.rb +337 -0
  12. data/lib/alpha_card/data/credit_card_codes.yml +54 -54
  13. data/lib/alpha_card/errors/invalid_attribute_format.rb +14 -0
  14. data/lib/alpha_card/errors/invalid_attribute_type.rb +14 -0
  15. data/lib/alpha_card/errors/invalid_attribute_value.rb +14 -0
  16. data/lib/alpha_card/errors/{invalid_object_error.rb → validation_error.rb} +1 -1
  17. data/lib/alpha_card/{alpha_card_object.rb → resource.rb} +14 -28
  18. data/lib/alpha_card/resources/billing.rb +29 -0
  19. data/lib/alpha_card/{objects → resources}/order.rb +8 -8
  20. data/lib/alpha_card/{objects → resources}/shipping.rb +15 -13
  21. data/lib/alpha_card/{alpha_card_response.rb → response.rb} +21 -6
  22. data/lib/alpha_card/transaction.rb +30 -0
  23. data/lib/alpha_card/transactions/auth.rb +18 -0
  24. data/lib/alpha_card/transactions/capture.rb +32 -0
  25. data/lib/alpha_card/transactions/credit.rb +18 -0
  26. data/lib/alpha_card/{objects → transactions}/refund.rb +9 -2
  27. data/lib/alpha_card/transactions/sale.rb +91 -0
  28. data/lib/alpha_card/transactions/update.rb +61 -0
  29. data/lib/alpha_card/transactions/validate.rb +21 -0
  30. data/lib/alpha_card/transactions/void.rb +26 -0
  31. data/lib/alpha_card/version.rb +1 -1
  32. data/spec/alpha_card/attribute_spec.rb +126 -0
  33. data/spec/alpha_card/response_spec.rb +8 -4
  34. data/spec/alpha_card/transactions/auth_spec.rb +43 -0
  35. data/spec/alpha_card/{objects → transactions}/capture_spec.rb +11 -12
  36. data/spec/alpha_card/transactions/credit_spec.rb +102 -0
  37. data/spec/alpha_card/{objects → transactions}/refund_spec.rb +4 -4
  38. data/spec/alpha_card/{objects → transactions}/sale_spec.rb +42 -41
  39. data/spec/alpha_card/{objects → transactions}/update_spec.rb +4 -4
  40. data/spec/alpha_card/transactions/validate_spec.rb +100 -0
  41. data/spec/alpha_card/{objects → transactions}/void_spec.rb +11 -11
  42. data/spec/spec_helper.rb +4 -0
  43. metadata +36 -47
  44. data/lib/alpha_card/errors/alpha_card_error.rb +0 -29
  45. data/lib/alpha_card/objects/account.rb +0 -48
  46. data/lib/alpha_card/objects/billing.rb +0 -31
  47. data/lib/alpha_card/objects/capture.rb +0 -51
  48. data/lib/alpha_card/objects/sale.rb +0 -82
  49. data/lib/alpha_card/objects/update.rb +0 -54
  50. data/lib/alpha_card/objects/void.rb +0 -45
  51. data/spec/alpha_card/objects/account_spec.rb +0 -20
  52. data/spec/alpha_card/objects/deprecated_methods_spec.rb +0 -32
@@ -0,0 +1,32 @@
1
+ module AlphaCard
2
+ ##
3
+ # Implementation of Alpha Card Services Capture transaction.
4
+ #
5
+ # @example
6
+ # capture = AlphaCard::Capture.new(transaction_id: '981562', amount: '10.05')
7
+ # capture.process
8
+ #
9
+ # #=> #<AlphaCard::Response:0x1a0fda ...>
10
+ #
11
+ class Capture < Transaction
12
+ attribute :transaction_id, required: true
13
+ # Format: xx.xx
14
+ attribute :amount, required: true
15
+ attribute :tracking_number
16
+ attribute :shipping_carrier
17
+ attribute :order_id
18
+
19
+ ##
20
+ # Transaction type (default is 'capture')
21
+ #
22
+ # @attribute [r] type
23
+ attribute :type, default: 'capture', writeable: false
24
+
25
+ ##
26
+ # Original AlphaCard transaction variables names
27
+ ORIGIN_TRANSACTION_VARIABLES = {
28
+ transaction_id: :transactionid,
29
+ order_id: :orderid
30
+ }.freeze
31
+ end
32
+ end
@@ -0,0 +1,18 @@
1
+ module AlphaCard
2
+ ##
3
+ # Implementation of Alpha Card Services Credit transaction.
4
+ #
5
+ # @example
6
+ # credit = AlphaCard::Credit.new(card_expiration_date: '0117', card_number: '4111111111111111', amount: '1.00')
7
+ # credit.create(order)
8
+ #
9
+ # #=> #<AlphaCard::Response:0x1a0fda ...>
10
+ #
11
+ class Credit < Sale
12
+ ##
13
+ # Transaction type (default is 'credit')
14
+ #
15
+ # @attribute [r] type
16
+ attribute :type, default: 'credit', writable: false
17
+ end
18
+ end
@@ -1,15 +1,22 @@
1
1
  module AlphaCard
2
2
  ##
3
3
  # Implementation of Alpha Card Services Refund transaction.
4
+ #
5
+ # @example
6
+ # refund = AlphaCard::Refund.new(transaction_id: '981562', amount: '1.00')
7
+ # refund.create
8
+ #
9
+ # #=> #<AlphaCard::Response:0x1a0fda ...>
10
+ #
4
11
  class Refund < Void
5
12
  # Format: xx.xx
6
- attribute :amount, String
13
+ attribute :amount
7
14
 
8
15
  ##
9
16
  # Transaction type (default is 'refund')
10
17
  #
11
18
  # @attribute [r] type
12
- attribute :type, String, default: 'refund', writer: :private
19
+ attribute :type, default: 'refund', writable: false
13
20
 
14
21
  ##
15
22
  # Original AlphaCard transaction variables names
@@ -0,0 +1,91 @@
1
+ module AlphaCard
2
+ ##
3
+ # Implementation of Alpha Card Services Sale transaction.
4
+ # Contains all the information about Customer Credit Card,
5
+ # such as CVV, number, expiration date, etc.
6
+ # Process the Alpha Card Services payment.
7
+ class Sale < Transaction
8
+ # Format: MMYY
9
+ attribute :card_expiration_date, required: true, format: /\A((0[1-9])|(1[0-2]))\/*\d{2}\z/.freeze
10
+ attribute :card_number, required: true
11
+ attribute :amount, required: true
12
+ attribute :cvv
13
+ # Values: 'true' or 'false'
14
+ attribute :customer_receipt
15
+ attribute :check_name
16
+ attribute :check_aba
17
+ attribute :check_account
18
+ # Values: 'business' or 'personal'
19
+ attribute :account_holder_type, values: %w(business personal).freeze
20
+ # Values: 'checking' or 'savings'
21
+ attribute :account_type, values: %w(checking savings).freeze
22
+ # Values: 'PPD', 'WEB', 'TEL', or 'CCD'
23
+ attribute :sec_code, values: %w(PPD WEB TEL CCD).freeze
24
+
25
+ ##
26
+ # Payment type.
27
+ # Values: 'creditcard' or 'check'
28
+ attribute :payment, default: 'creditcard', values: %w(creditcard check).freeze
29
+
30
+ ##
31
+ # Transaction type (default is 'sale')
32
+ #
33
+ # @attribute [r] type
34
+ attribute :type, default: 'sale', writeable: false
35
+
36
+ ##
37
+ # Original AlphaCard transaction variables names
38
+ ORIGIN_TRANSACTION_VARIABLES = {
39
+ card_expiration_date: :ccexp,
40
+ card_number: :ccnumber,
41
+ check_name: :checkname,
42
+ check_aba: :checkaba,
43
+ check_account: :checkaccount
44
+ }.freeze
45
+
46
+ ##
47
+ # Creates the sale transaction for the specified <code>AlphaCard::Order</code>.
48
+ #
49
+ # @param order [AlphaCard::Order]
50
+ # An <code>AlphaCard::Order</code> object.
51
+ #
52
+ # @param credentials [Hash]
53
+ # Alpha Card merchant account credentials.
54
+ #
55
+ # @return [AlphaCard::Response]
56
+ # AlphaCard Gateway response with all the information about transaction.
57
+ #
58
+ # @raise [AlphaCard::InvalidObjectError]
59
+ # Exception if one of required attributes doesn't specified.
60
+ #
61
+ # @example
62
+ # order = AlphaCard::Order.new(id: 1, description: 'Test order')
63
+ # sale = AlphaCard::Sale.new(card_expiration_date: '0117', card_number: '4111111111111111', amount: '5.00' )
64
+ # sale.create(order)
65
+ #
66
+ # #=> #<AlphaCard::Response:0x1a0fda ...>
67
+ def process(order, credentials = Account.credentials)
68
+ validate_required_attributes!
69
+
70
+ AlphaCard.request(params_for_sale(order), credentials)
71
+ end
72
+
73
+ alias_method :create, :process
74
+
75
+ private
76
+
77
+ ##
78
+ # Returns all the necessary attributes with it's original
79
+ # names that must be passed with Sale transaction.
80
+ #
81
+ # @param order [AlphaCard::Order]
82
+ # An <code>AlphaCard::Order</code> object.
83
+ #
84
+ # @return [Hash]
85
+ # Params of *self* object merged with params
86
+ # of another object (<code>AlphaCard::Order</code>)
87
+ def params_for_sale(order)
88
+ attributes_for_request.merge(order.attributes_for_request)
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,61 @@
1
+ module AlphaCard
2
+ ##
3
+ # Implementation of Alpha Card Services Update transaction.
4
+ # Transaction updates can be used to update previous transactions
5
+ # with specific order information, such as a tracking number
6
+ # and shipping carrier.
7
+ #
8
+ # @example
9
+ # update = AlphaCard::Update.new(card_expiration_date: '0117', card_number: '4111111111111111', amount: '1.00')
10
+ # update.process(order)
11
+ #
12
+ # #=> #<AlphaCard::Response:0x1a0fda ...>
13
+ #
14
+ class Update < Void
15
+ # Total shipping amount.
16
+ # Format: x.xx
17
+ attribute :shipping, type: String
18
+ attribute :shipping_postal, type: String
19
+ attribute :ship_from_postal, type: String
20
+ attribute :shipping_country, type: String
21
+ # Values: 'ups', 'fedex', 'dhl', or 'usps'
22
+ attribute :shipping_carrier, type: String, values: %w(ups fedex dhl usps).freeze
23
+ # Format: YYYYMMDD
24
+ attribute :shipping_date, type: String, format: /\A[1-9]\d{3}((0[1-9])|(1[0-2]))((0[1-9])|((1|2)[0-9])|3[0-1])\z/.freeze
25
+ attribute :order_description, type: String
26
+ attribute :order_date, type: String
27
+ # Values: 'true' or 'false'
28
+ attribute :customer_receipt, type: String
29
+ attribute :po_number, type: String
30
+ attribute :summary_commodity_code, type: String
31
+ # Format: x.xx
32
+ attribute :duty_amount
33
+ # Format: x.xx
34
+ attribute :discount_amount
35
+ # Format: x.xx
36
+ attribute :tax
37
+ # Format: x.xx
38
+ attribute :national_tax_amount
39
+ # Format: x.xx
40
+ attribute :alternate_tax_amount
41
+ attribute :alternate_tax_id
42
+ attribute :vat_tax_amount
43
+ attribute :vat_tax_rate, type: String
44
+ attribute :vat_invoice_reference_number, type: String
45
+ attribute :customer_vat_registration, type: String
46
+ attribute :merchant_vat_registration, type: String
47
+
48
+ ##
49
+ # Transaction type (default is 'update')
50
+ #
51
+ # @attribute [r] type
52
+ attribute :type, default: 'update', writable: false
53
+
54
+ ##
55
+ # Original AlphaCard transaction variables names
56
+ ORIGIN_TRANSACTION_VARIABLES = {
57
+ transaction_id: :transactionid,
58
+ po_number: :ponumber
59
+ }.freeze
60
+ end
61
+ end
@@ -0,0 +1,21 @@
1
+ module AlphaCard
2
+ ##
3
+ # Implementation of Alpha Card Services Validate transaction.
4
+ #
5
+ # @example
6
+ # validate = AlphaCard::Validate.new(card_expiration_date: '0117', card_number: '4111111111111111')
7
+ # validate.process
8
+ #
9
+ # #=> #<AlphaCard::Response:0x1a0fda ...>
10
+ #
11
+ class Validate < Sale
12
+ ##
13
+ # Transaction type (default is 'validate')
14
+ #
15
+ # @attribute [r] type
16
+ attribute :type, default: 'validate', writable: false
17
+
18
+ # Validate transaction can't have an amount
19
+ remove_attribute :amount
20
+ end
21
+ end
@@ -0,0 +1,26 @@
1
+ module AlphaCard
2
+ ##
3
+ # Implementation of Alpha Card Services Void transaction.
4
+ #
5
+ # @example
6
+ # void = AlphaCard::Void.new(transaction_id: '981562')
7
+ # void.create
8
+ #
9
+ # #=> #<AlphaCard::Response:0x1a0fda ...>
10
+ #
11
+ class Void < Transaction
12
+ attribute :transaction_id, type: [String, Integer], required: true
13
+
14
+ ##
15
+ # Transaction type (default is 'void')
16
+ #
17
+ # @attribute [r] type
18
+ attribute :type, default: 'void', writable: false
19
+
20
+ ##
21
+ # Original AlphaCard transaction variables names
22
+ ORIGIN_TRANSACTION_VARIABLES = {
23
+ transaction_id: :transactionid
24
+ }.freeze
25
+ end
26
+ end
@@ -11,7 +11,7 @@ module AlphaCard
11
11
  # Major version number
12
12
  MAJOR = 0
13
13
  # Minor version number
14
- MINOR = 3
14
+ MINOR = 4
15
15
  # Smallest version number
16
16
  TINY = 0
17
17
 
@@ -0,0 +1,126 @@
1
+ require 'spec_helper'
2
+
3
+ describe AlphaCard::Attribute do
4
+ class User
5
+ include AlphaCard::Attribute
6
+
7
+ attribute :name
8
+ attribute :activated, values: [true, false]
9
+ attribute :role, default: 'user', writable: false
10
+ end
11
+
12
+ class Moderator < User
13
+ attribute :id, type: Integer, default: 11
14
+ attribute :status, default: 'global', writable: false
15
+ attribute :role, default: 'moderator', writable: false
16
+ end
17
+
18
+ class Admin < Moderator
19
+ attribute :role, default: 'admin', types: [String, Symbol]
20
+ attribute :birthday, format: /^\d{2}-\d{2}-\d{4}$/
21
+
22
+ attribute :created_at, required: true
23
+
24
+ remove_attribute :status
25
+ end
26
+
27
+ context 'User' do
28
+ it 'must set attributes from arguments on initialization' do
29
+ user = User.new(name: 'John', activated: true)
30
+ expect(user.name).to eq('John')
31
+ expect(user.activated).to be_truthy
32
+ end
33
+
34
+ it 'must ignore non-writable attributes on initialization' do
35
+ user = User.new(role: 'test')
36
+ expect(user.role).to eq('user')
37
+ end
38
+
39
+ it 'must set default values' do
40
+ expect(User.new.role).to eq('user')
41
+ end
42
+
43
+ it 'must not create writers for non-writable attributes' do
44
+ expect { User.new.role = '111' }.to raise_error(NoMethodError)
45
+ end
46
+
47
+ it 'must raise an error on wrong values' do
48
+ expect { User.new(activated: 'wrong') }.to raise_error(AlphaCard::InvalidAttributeValue)
49
+ end
50
+ end
51
+
52
+ context 'Moderator' do
53
+ it 'must inherit attributes' do
54
+ moderator = Moderator.new(name: 'John', activated: true)
55
+ expect(moderator.attributes).to eq(name: 'John', activated: true, id: 11, role: 'moderator', status: 'global')
56
+ end
57
+
58
+ it 'must override attributes default values' do
59
+ expect(Moderator.new.role).to eq('moderator')
60
+ end
61
+
62
+ it 'must validate typed attributes' do
63
+ expect { Moderator.new.id = '123' }.to raise_error(AlphaCard::InvalidAttributeType)
64
+ end
65
+ end
66
+
67
+ context 'Admin' do
68
+ it 'must inherit superclass attributes' do
69
+ admin = Admin.new(name: 'John', activated: true)
70
+ expect(admin.name).to eq('John')
71
+ expect(admin.id).to eq(11)
72
+ expect(admin.activated).to be_truthy
73
+ end
74
+
75
+ it 'must override superclass attributes default values' do
76
+ expect(Admin.new.role).to eq('admin')
77
+ end
78
+
79
+ it 'must override superclass attributes options (make writable)' do
80
+ admin = Admin.new
81
+ admin.role = 'something_new'
82
+ expect(admin.role).to eq('something_new')
83
+ end
84
+
85
+ it 'must override superclass attributes options (make typable)' do
86
+ expect(Admin.new(role: 'admin').role).to eq('admin')
87
+ expect(Admin.new(role: :admin).role).to eq(:admin)
88
+
89
+ expect { Admin.new(role: 123) }.to raise_error(AlphaCard::InvalidAttributeType)
90
+ end
91
+
92
+ it 'must remove attributes' do
93
+ expect { Admin.new.status = 'local' }.to raise_error(NoMethodError)
94
+ end
95
+
96
+ it 'must require attributes' do
97
+ expect(Admin.new.required_attributes?).to be_falsey
98
+ expect(Admin.new(created_at: Date.today).required_attributes?).to be_truthy
99
+ end
100
+
101
+ it 'must validate attribute format' do
102
+ error_msg = "'local' does not match the '/^\\d{2}-\\d{2}-\\d{4}$/' format"
103
+ expect { Admin.new.birthday = 'local' }.to raise_error(AlphaCard::InvalidAttributeFormat, error_msg)
104
+ end
105
+
106
+ it 'must not allow to add invalid attributes' do
107
+ expect {
108
+ Admin.class_eval <<-RUBY.strip
109
+ attribute :some, values: 10
110
+ RUBY
111
+ }.to raise_error(ArgumentError)
112
+
113
+ expect {
114
+ Admin.class_eval <<-RUBY.strip
115
+ attribute :some, values: []
116
+ RUBY
117
+ }.to raise_error(ArgumentError)
118
+
119
+ expect {
120
+ Admin.class_eval <<-RUBY.strip
121
+ attribute :some, format: 10
122
+ RUBY
123
+ }.to raise_error(ArgumentError)
124
+ end
125
+ end
126
+ end
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe AlphaCard::AlphaCardResponse do
3
+ describe AlphaCard::Response do
4
4
  let(:successful_response_mock) do
5
5
  'authcode=083319&avsresponse=&cvvresponse=M&orderid=1&response=1&response_code=100&responsetext=AP&transactionid=2303767426&type=sale'
6
6
  end
@@ -14,7 +14,7 @@ describe AlphaCard::AlphaCardResponse do
14
14
  end
15
15
 
16
16
  context 'successful request' do
17
- let(:response) { AlphaCard::AlphaCardResponse.new(successful_response_mock) }
17
+ let(:response) { AlphaCard::Response.new(successful_response_mock) }
18
18
 
19
19
  it '#success? = true' do
20
20
  expect(response.success?).to be_truthy
@@ -47,10 +47,14 @@ describe AlphaCard::AlphaCardResponse do
47
47
  it 'returns auth code' do
48
48
  expect(response.auth_code).to eq('083319')
49
49
  end
50
+
51
+ it 'returns credit card authorization message' do
52
+ expect(response.credit_card_auth_message).to eq('Approved or completed successfully')
53
+ end
50
54
  end
51
55
 
52
56
  context 'declined request' do
53
- let(:response) { AlphaCard::AlphaCardResponse.new(declined_response_mock) }
57
+ let(:response) { AlphaCard::Response.new(declined_response_mock) }
54
58
 
55
59
  it '#declined? = true' do
56
60
  expect(response.declined?).to be_truthy
@@ -78,7 +82,7 @@ describe AlphaCard::AlphaCardResponse do
78
82
  end
79
83
 
80
84
  context 'error request' do
81
- let(:response) { AlphaCard::AlphaCardResponse.new(error_response_mock) }
85
+ let(:response) { AlphaCard::Response.new(error_response_mock) }
82
86
 
83
87
  it '#error? = true' do
84
88
  expect(response.error?).to be_truthy