cardconnect 1.0.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 (63) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/Gemfile +11 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +154 -0
  6. data/Rakefile +178 -0
  7. data/cardconnect.gemspec +25 -0
  8. data/lib/cardconnect.rb +49 -0
  9. data/lib/cardconnect/configuration.rb +13 -0
  10. data/lib/cardconnect/connection.rb +35 -0
  11. data/lib/cardconnect/error.rb +3 -0
  12. data/lib/cardconnect/services/authorization/authorization.rb +17 -0
  13. data/lib/cardconnect/services/authorization/authorization_request.rb +51 -0
  14. data/lib/cardconnect/services/authorization/authorization_response.rb +41 -0
  15. data/lib/cardconnect/services/capture/capture.rb +17 -0
  16. data/lib/cardconnect/services/capture/capture_request.rb +50 -0
  17. data/lib/cardconnect/services/capture/capture_response.rb +24 -0
  18. data/lib/cardconnect/services/deposit/deposit.rb +17 -0
  19. data/lib/cardconnect/services/deposit/deposit_request.rb +64 -0
  20. data/lib/cardconnect/services/deposit/deposit_response.rb +40 -0
  21. data/lib/cardconnect/services/inquire/inquire.rb +17 -0
  22. data/lib/cardconnect/services/inquire/inquire_request.rb +44 -0
  23. data/lib/cardconnect/services/inquire/inquire_response.rb +31 -0
  24. data/lib/cardconnect/services/refund/refund.rb +16 -0
  25. data/lib/cardconnect/services/refund/refund_request.rb +50 -0
  26. data/lib/cardconnect/services/refund/refund_response.rb +40 -0
  27. data/lib/cardconnect/services/service_endpoint.rb +69 -0
  28. data/lib/cardconnect/services/settlement_status/settlement_status.rb +17 -0
  29. data/lib/cardconnect/services/settlement_status/settlement_status_request.rb +64 -0
  30. data/lib/cardconnect/services/settlement_status/settlement_status_response.rb +39 -0
  31. data/lib/cardconnect/services/void/void.rb +16 -0
  32. data/lib/cardconnect/services/void/void_request.rb +50 -0
  33. data/lib/cardconnect/services/void/void_response.rb +40 -0
  34. data/lib/cardconnect/utils.rb +22 -0
  35. data/lib/cardconnect/version.rb +3 -0
  36. data/test/api_request_stubs.rb +83 -0
  37. data/test/api_response_stubs.rb +120 -0
  38. data/test/cardconnect/configuration_test.rb +28 -0
  39. data/test/cardconnect/connection_test.rb +36 -0
  40. data/test/cardconnect/services/authorization/authorization_request_test.rb +141 -0
  41. data/test/cardconnect/services/authorization/authorization_response_test.rb +93 -0
  42. data/test/cardconnect/services/authorization/authorization_test.rb +59 -0
  43. data/test/cardconnect/services/capture/capture_request_test.rb +65 -0
  44. data/test/cardconnect/services/capture/capture_response_test.rb +39 -0
  45. data/test/cardconnect/services/capture/capture_test.rb +58 -0
  46. data/test/cardconnect/services/deposit/deposit_request_test.rb +65 -0
  47. data/test/cardconnect/services/deposit/deposit_response_test.rb +75 -0
  48. data/test/cardconnect/services/deposit/deposit_test.rb +55 -0
  49. data/test/cardconnect/services/inquire/inquire_request_test.rb +45 -0
  50. data/test/cardconnect/services/inquire/inquire_response_test.rb +59 -0
  51. data/test/cardconnect/services/inquire/inquire_test.rb +56 -0
  52. data/test/cardconnect/services/refund/refund_request_test.rb +49 -0
  53. data/test/cardconnect/services/refund/refund_response_test.rb +73 -0
  54. data/test/cardconnect/services/refund/refund_test.rb +57 -0
  55. data/test/cardconnect/services/settlement_status/settlement_status_request_test.rb +65 -0
  56. data/test/cardconnect/services/settlement_status/settlement_status_response_test.rb +47 -0
  57. data/test/cardconnect/services/settlement_status/settlement_status_test.rb +55 -0
  58. data/test/cardconnect/services/void/void_request_test.rb +49 -0
  59. data/test/cardconnect/services/void/void_response_test.rb +77 -0
  60. data/test/cardconnect/services/void/void_test.rb +57 -0
  61. data/test/cardconnect_test.rb +14 -0
  62. data/test/test_helper.rb +33 -0
  63. metadata +179 -0
@@ -0,0 +1,31 @@
1
+ module CardConnect
2
+ module Service
3
+ class InquireResponse
4
+ include Utils
5
+
6
+ FIELDS = [:merchid, :account, :amount, :currency, :retref, :respcode,
7
+ :respproc, :respstat, :resptext, :setlstat]
8
+
9
+ attr_accessor *FIELDS
10
+ attr_reader :errors
11
+
12
+ def initialize(response)
13
+ set_attributes(response, FIELDS)
14
+ @errors = []
15
+ end
16
+
17
+ def success?
18
+ @errors.empty?
19
+ end
20
+
21
+ def body
22
+ body = {}
23
+ FIELDS.each do |attr|
24
+ body.merge!({attr => send(attr)})
25
+ end
26
+ body
27
+ end
28
+
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,16 @@
1
+ module CardConnect
2
+ module Service
3
+ class Refund < ServiceEndpoint
4
+
5
+ # Initializes a Refund Service
6
+ #
7
+ # @param connection [CardConnect::Connection]
8
+ # @return CardConnect::Service::Refund
9
+ def initialize(connection = CardConnect.connection)
10
+ super(connection)
11
+ @resource_name = '/refund'
12
+ @rest_method = 'put'
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,50 @@
1
+ module CardConnect
2
+ module Service
3
+ class RefundRequest
4
+ include Utils
5
+
6
+ REQUIRED_FIELDS = [:merchid, :retref]
7
+
8
+ OPTIONAL_FIELDS = [:amount]
9
+
10
+ FIELDS = REQUIRED_FIELDS + OPTIONAL_FIELDS
11
+
12
+ attr_accessor *FIELDS
13
+ attr_reader :errors
14
+
15
+ # Initializes a new Refund Request
16
+ #
17
+ # @param attrs [Hash]
18
+ # @return CardConnect::RefundRequest
19
+ def initialize(attrs = {})
20
+ @errors = []
21
+ set_attributes(attrs, FIELDS)
22
+ validate_required_fields
23
+ end
24
+
25
+ # Indicates that the request is valid once it is built.
26
+ def valid?
27
+ errors.empty?
28
+ end
29
+
30
+ # Builds the request payload
31
+ def payload
32
+ payload = {}
33
+ FIELDS.each do |field|
34
+ payload.merge!({field => send(field)})
35
+ end
36
+ payload
37
+ end
38
+
39
+ private
40
+
41
+ def validate_required_fields
42
+ REQUIRED_FIELDS.each do |field|
43
+ value = send(field)
44
+ value.nil? || value.empty? ? errors.push("#{field.capitalize} is missing") : next
45
+ end
46
+ end
47
+
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,40 @@
1
+ module CardConnect
2
+ module Service
3
+ class RefundResponse
4
+ include Utils
5
+
6
+ FIELDS = [:merchid, :amount, :retref, :authcode, :respcode, :respproc, :respstat, :resptext]
7
+
8
+ attr_accessor *FIELDS
9
+ attr_reader :errors
10
+
11
+ STATUS_APPROVED = 'A'
12
+ STATUS_RETRY = 'B'
13
+ STATUS_DECLINED = 'C'
14
+
15
+ def initialize(response)
16
+ set_attributes(response, FIELDS)
17
+ @errors = []
18
+ process_errors
19
+ end
20
+
21
+ def success?
22
+ errors.empty?
23
+ end
24
+
25
+ def body
26
+ body = {}
27
+ FIELDS.each do |attr|
28
+ body.merge!({attr => send(attr)})
29
+ end
30
+ body
31
+ end
32
+
33
+ private
34
+
35
+ def process_errors
36
+ @errors << resptext if [STATUS_RETRY, STATUS_DECLINED].include?(respstat)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,69 @@
1
+ module CardConnect
2
+ module Service
3
+ class ServiceEndpoint
4
+ include Utils
5
+
6
+ attr_reader :request, :response, :connection, :resource_name, :rest_method
7
+
8
+ # Parent for service endpoints (Authorization, Capture, etc.)
9
+ # This class shouldn't be called directly. Rather call the end service directly.
10
+ #
11
+ # @param connection [CardConnect::Connection]
12
+ # @return CardConnect::ServiceEndpoint
13
+ def initialize(connection = CardConnect.connection)
14
+ @resource_name = '/'
15
+ @config = CardConnect.configuration
16
+ @connection = connection
17
+ end
18
+
19
+ def path
20
+ base_api_path + resource_name
21
+ end
22
+
23
+ def build_request(params = {})
24
+ req = symbolize_keys(params)
25
+ req = req.merge(merchid: @config.merchant_id) unless req.has_key?(:merchid)
26
+ @request = request_class.new(req)
27
+ end
28
+
29
+ def submit
30
+ raise CardConnect::Error, "Request has not been built" if request.nil?
31
+ @response = send(rest_method)
32
+ end
33
+
34
+ private
35
+
36
+ def base_api_path
37
+ '/cardconnect/rest'
38
+ end
39
+
40
+ def get
41
+ begin
42
+ response_class.new(connection.get(path + request.payload).body)
43
+ rescue Faraday::ResourceNotFound => e
44
+ puts e.message
45
+ end
46
+ end
47
+
48
+ def put
49
+ begin
50
+ response_class.new(connection.put(path, request.payload).body)
51
+ rescue Faraday::ResourceNotFound => e
52
+ puts e.message
53
+ end
54
+ end
55
+
56
+ def request_class
57
+ string_to_class("#{self.class}Request")
58
+ end
59
+
60
+ def response_class
61
+ string_to_class("#{self.class}Response")
62
+ end
63
+
64
+ def string_to_class(str)
65
+ str.split('::').inject(Object) { |mod, class_name| mod.const_get(class_name) }
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,17 @@
1
+ module CardConnect
2
+ module Service
3
+ class SettlementStatus < ServiceEndpoint
4
+
5
+ # Initializes a Settlement Status Service
6
+ #
7
+ # @param connection [CardConnect::Connection]
8
+ # @return CardConnect::Service::SettlementStatus
9
+ def initialize(connection = CardConnect.connection)
10
+ super(connection)
11
+ @resource_name = '/settlestat'
12
+ @rest_method = 'get'
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,64 @@
1
+ require 'date'
2
+
3
+ module CardConnect
4
+ module Service
5
+ class SettlementStatusRequest
6
+ include Utils
7
+
8
+ REQUIRED_FIELDS = [:merchid, :date]
9
+
10
+ FIELDS = REQUIRED_FIELDS
11
+
12
+ attr_accessor *FIELDS
13
+ attr_reader :errors
14
+
15
+ # Initializes a new Settlement Status Request
16
+ #
17
+ # @param attrs [Hash]
18
+ # @return CardConnect::SettlementStatusRequest
19
+ def initialize(attrs = {})
20
+ @errors = []
21
+ set_attributes(attrs, FIELDS)
22
+ validate_required_fields
23
+ end
24
+
25
+ # Indicates that the request is valid once it is built.
26
+ def valid?
27
+ errors.empty?
28
+ end
29
+
30
+ # Builds the request payload
31
+ def payload
32
+ payload = "?"
33
+ FIELDS.each do |field|
34
+ payload += "#{field}=#{send(field)}&"
35
+ end
36
+ payload
37
+ end
38
+
39
+ private
40
+
41
+ def validate_required_fields
42
+ validate_presence_of_required_fields
43
+ validate_date_format unless date.nil? || date.empty?
44
+ end
45
+
46
+ def validate_presence_of_required_fields
47
+ REQUIRED_FIELDS.each do |field|
48
+ value = send(field)
49
+ value.nil? || value.empty? ? errors.push("#{field.capitalize} is missing") : next
50
+ end
51
+ end
52
+
53
+ def validate_date_format
54
+ begin
55
+ raise if date.length != 4
56
+ Date.parse(date, '%m%d')
57
+ rescue => e
58
+ errors.push("Date format is invalid. Please use MMDD format")
59
+ end
60
+ end
61
+
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,39 @@
1
+ module CardConnect
2
+ module Service
3
+ class SettlementStatusResponse
4
+ include Utils
5
+
6
+ FIELDS = [:merchid, :batchid, :hoststat, :hostbatch, :respproc, :txns]
7
+
8
+ attr_accessor *FIELDS
9
+ attr_reader :errors
10
+
11
+ def initialize(response)
12
+ response = response.empty? ? response : response.first
13
+ set_attributes(response, FIELDS)
14
+ parse_transactions
15
+ @errors = []
16
+ end
17
+
18
+ def success?
19
+ errors.empty?
20
+ end
21
+
22
+ def body
23
+ body = {}
24
+ FIELDS.each do |attr|
25
+ body.merge!({attr => send(attr)})
26
+ end
27
+ body
28
+ end
29
+
30
+ private
31
+
32
+ def parse_transactions
33
+ return if txns.nil?
34
+ txns.each_with_index { |txn, i| self.txns[i] = symbolize_keys(txn) }
35
+ end
36
+
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,16 @@
1
+ module CardConnect
2
+ module Service
3
+ class Void < ServiceEndpoint
4
+
5
+ # Initializes a Void Service
6
+ #
7
+ # @param connection [CardConnect::Connection]
8
+ # @return CardConnect::Service::Void
9
+ def initialize(connection = CardConnect.connection)
10
+ super(connection)
11
+ @resource_name = '/void'
12
+ @rest_method = 'put'
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,50 @@
1
+ module CardConnect
2
+ module Service
3
+ class VoidRequest
4
+ include Utils
5
+
6
+ REQUIRED_FIELDS = [:merchid, :retref]
7
+
8
+ OPTIONAL_FIELDS = [:amount]
9
+
10
+ FIELDS = REQUIRED_FIELDS + OPTIONAL_FIELDS
11
+
12
+ attr_accessor *FIELDS
13
+ attr_reader :errors
14
+
15
+ # Initializes a new Void Request
16
+ #
17
+ # @param attrs [Hash]
18
+ # @return CardConnect::VoidRequest
19
+ def initialize(attrs = {})
20
+ @errors = []
21
+ set_attributes(attrs, FIELDS)
22
+ validate_required_fields
23
+ end
24
+
25
+ # Indicates that the request is valid once it is built.
26
+ def valid?
27
+ errors.empty?
28
+ end
29
+
30
+ # Builds the request payload
31
+ def payload
32
+ payload = {}
33
+ FIELDS.each do |field|
34
+ payload.merge!({field => send(field)})
35
+ end
36
+ payload
37
+ end
38
+
39
+ private
40
+
41
+ def validate_required_fields
42
+ REQUIRED_FIELDS.each do |field|
43
+ value = send(field)
44
+ value.nil? || value.empty? ? errors.push("#{field.capitalize} is missing") : next
45
+ end
46
+ end
47
+
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,40 @@
1
+ module CardConnect
2
+ module Service
3
+ class VoidResponse
4
+ include Utils
5
+
6
+ FIELDS = [:merchid, :amount, :currency, :retref, :authcode, :respcode, :respproc, :respstat, :resptext]
7
+
8
+ attr_accessor *FIELDS
9
+ attr_reader :errors
10
+
11
+ STATUS_APPROVED = 'A'
12
+ STATUS_RETRY = 'B'
13
+ STATUS_DECLINED = 'C'
14
+
15
+ def initialize(response)
16
+ set_attributes(response, FIELDS)
17
+ @errors = []
18
+ process_errors
19
+ end
20
+
21
+ def success?
22
+ errors.empty?
23
+ end
24
+
25
+ def body
26
+ body = {}
27
+ FIELDS.each do |attr|
28
+ body.merge!({attr => send(attr)})
29
+ end
30
+ body
31
+ end
32
+
33
+ private
34
+
35
+ def process_errors
36
+ @errors << resptext if [STATUS_RETRY, STATUS_DECLINED].include?(respstat)
37
+ end
38
+ end
39
+ end
40
+ end