alpha_card 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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