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.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/Gemfile +11 -0
- data/LICENSE.txt +22 -0
- data/README.md +154 -0
- data/Rakefile +178 -0
- data/cardconnect.gemspec +25 -0
- data/lib/cardconnect.rb +49 -0
- data/lib/cardconnect/configuration.rb +13 -0
- data/lib/cardconnect/connection.rb +35 -0
- data/lib/cardconnect/error.rb +3 -0
- data/lib/cardconnect/services/authorization/authorization.rb +17 -0
- data/lib/cardconnect/services/authorization/authorization_request.rb +51 -0
- data/lib/cardconnect/services/authorization/authorization_response.rb +41 -0
- data/lib/cardconnect/services/capture/capture.rb +17 -0
- data/lib/cardconnect/services/capture/capture_request.rb +50 -0
- data/lib/cardconnect/services/capture/capture_response.rb +24 -0
- data/lib/cardconnect/services/deposit/deposit.rb +17 -0
- data/lib/cardconnect/services/deposit/deposit_request.rb +64 -0
- data/lib/cardconnect/services/deposit/deposit_response.rb +40 -0
- data/lib/cardconnect/services/inquire/inquire.rb +17 -0
- data/lib/cardconnect/services/inquire/inquire_request.rb +44 -0
- data/lib/cardconnect/services/inquire/inquire_response.rb +31 -0
- data/lib/cardconnect/services/refund/refund.rb +16 -0
- data/lib/cardconnect/services/refund/refund_request.rb +50 -0
- data/lib/cardconnect/services/refund/refund_response.rb +40 -0
- data/lib/cardconnect/services/service_endpoint.rb +69 -0
- data/lib/cardconnect/services/settlement_status/settlement_status.rb +17 -0
- data/lib/cardconnect/services/settlement_status/settlement_status_request.rb +64 -0
- data/lib/cardconnect/services/settlement_status/settlement_status_response.rb +39 -0
- data/lib/cardconnect/services/void/void.rb +16 -0
- data/lib/cardconnect/services/void/void_request.rb +50 -0
- data/lib/cardconnect/services/void/void_response.rb +40 -0
- data/lib/cardconnect/utils.rb +22 -0
- data/lib/cardconnect/version.rb +3 -0
- data/test/api_request_stubs.rb +83 -0
- data/test/api_response_stubs.rb +120 -0
- data/test/cardconnect/configuration_test.rb +28 -0
- data/test/cardconnect/connection_test.rb +36 -0
- data/test/cardconnect/services/authorization/authorization_request_test.rb +141 -0
- data/test/cardconnect/services/authorization/authorization_response_test.rb +93 -0
- data/test/cardconnect/services/authorization/authorization_test.rb +59 -0
- data/test/cardconnect/services/capture/capture_request_test.rb +65 -0
- data/test/cardconnect/services/capture/capture_response_test.rb +39 -0
- data/test/cardconnect/services/capture/capture_test.rb +58 -0
- data/test/cardconnect/services/deposit/deposit_request_test.rb +65 -0
- data/test/cardconnect/services/deposit/deposit_response_test.rb +75 -0
- data/test/cardconnect/services/deposit/deposit_test.rb +55 -0
- data/test/cardconnect/services/inquire/inquire_request_test.rb +45 -0
- data/test/cardconnect/services/inquire/inquire_response_test.rb +59 -0
- data/test/cardconnect/services/inquire/inquire_test.rb +56 -0
- data/test/cardconnect/services/refund/refund_request_test.rb +49 -0
- data/test/cardconnect/services/refund/refund_response_test.rb +73 -0
- data/test/cardconnect/services/refund/refund_test.rb +57 -0
- data/test/cardconnect/services/settlement_status/settlement_status_request_test.rb +65 -0
- data/test/cardconnect/services/settlement_status/settlement_status_response_test.rb +47 -0
- data/test/cardconnect/services/settlement_status/settlement_status_test.rb +55 -0
- data/test/cardconnect/services/void/void_request_test.rb +49 -0
- data/test/cardconnect/services/void/void_response_test.rb +77 -0
- data/test/cardconnect/services/void/void_test.rb +57 -0
- data/test/cardconnect_test.rb +14 -0
- data/test/test_helper.rb +33 -0
- 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
|