tns_payments 0.0.8 → 0.0.9
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +6 -0
- data/lib/tns_payments.rb +4 -0
- data/lib/tns_payments/connection.rb +57 -5
- data/lib/tns_payments/error_response.rb +92 -0
- data/lib/tns_payments/request.rb +33 -8
- data/lib/tns_payments/response.rb +26 -5
- data/lib/tns_payments/transaction.rb +7 -0
- data/lib/tns_payments/version.rb +1 -1
- data/test/unit/conntection_test.rb +1 -1
- data/test/unit/error_response_test.rb +102 -0
- data/test/unit/response_test.rb +2 -2
- metadata +70 -96
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
## 0.0.9 / 2012-04-12
|
4
|
+
|
5
|
+
* Error Responses get their own class in an attempt to provide consistency.
|
6
|
+
* Added TomDoc documentation.
|
7
|
+
* Separated concerns in Request class.
|
8
|
+
|
3
9
|
## 0.0.8 / 2012-04-11
|
4
10
|
|
5
11
|
* Default open_timeout and read_timeout to something sensible.
|
data/lib/tns_payments.rb
CHANGED
@@ -1,12 +1,16 @@
|
|
1
1
|
require 'tns_payments/connection'
|
2
2
|
require 'tns_payments/request'
|
3
3
|
require 'tns_payments/response'
|
4
|
+
require 'tns_payments/error_response'
|
4
5
|
require 'tns_payments/transaction'
|
5
6
|
require 'tns_payments/version'
|
6
7
|
|
7
8
|
module TNSPayments
|
8
9
|
class SessionTokenException < Exception; end
|
9
10
|
|
11
|
+
# Public: A proxy method to Connection.new.
|
12
|
+
#
|
13
|
+
# Returns a new Connection.
|
10
14
|
def self.new options = {}
|
11
15
|
Connection.new options
|
12
16
|
end
|
@@ -7,6 +7,9 @@ module TNSPayments
|
|
7
7
|
attr_accessor :api_key, :host, :merchant_id
|
8
8
|
attr_writer :session_token
|
9
9
|
|
10
|
+
# Public: Request to check that the gateway is operating.
|
11
|
+
#
|
12
|
+
# Returns a boolean.
|
10
13
|
def available?
|
11
14
|
request(:get, '/information', :authorization => false).success?
|
12
15
|
end
|
@@ -16,10 +19,17 @@ module TNSPayments
|
|
16
19
|
self.host = options.fetch(:host) { 'https://secure.ap.tnspayments.com' }
|
17
20
|
end
|
18
21
|
|
22
|
+
# Public: Payment form url that includes a session token.
|
23
|
+
#
|
24
|
+
# Returns a url.
|
19
25
|
def payment_form_url
|
20
26
|
"#{host}/form/#{session_token}"
|
21
27
|
end
|
22
28
|
|
29
|
+
# Public: A single transaction to authorise the payment and transfer funds
|
30
|
+
# from the cardholder's account to your account.
|
31
|
+
#
|
32
|
+
# Returns a Response object.
|
23
33
|
def purchase transaction, token
|
24
34
|
transaction = Transaction.new transaction
|
25
35
|
order_id = transaction.order_id
|
@@ -28,24 +38,38 @@ module TNSPayments
|
|
28
38
|
'apiOperation' => 'PAY',
|
29
39
|
'cardDetails' => card_details(token),
|
30
40
|
'order' => {'reference' => transaction.reference},
|
31
|
-
'transaction' => {
|
41
|
+
'transaction' => {
|
42
|
+
'amount' => transaction.amount.to_s,
|
43
|
+
'currency' => transaction.currency,
|
44
|
+
'reference' => transaction_id.to_s
|
45
|
+
}
|
32
46
|
}
|
33
47
|
|
34
48
|
request :put, "/merchant/#{merchant_id}/order/#{order_id}/transaction/#{transaction_id}", params
|
35
49
|
end
|
36
50
|
|
51
|
+
# Public: Request to refund previously captured funds.
|
52
|
+
#
|
53
|
+
# Returns a Response object.
|
37
54
|
def refund transaction
|
38
55
|
transaction = Transaction.new transaction
|
39
56
|
order_id = transaction.order_id.to_i
|
40
57
|
transaction_id = transaction.transaction_id
|
41
58
|
params = {
|
42
59
|
'apiOperation' => 'REFUND',
|
43
|
-
'transaction' => {
|
60
|
+
'transaction' => {
|
61
|
+
'amount' => transaction.amount.to_s,
|
62
|
+
'currency' => transaction.currency,
|
63
|
+
'reference' => transaction_id.to_s
|
64
|
+
}
|
44
65
|
}
|
45
66
|
|
46
67
|
request :put, "/merchant/#{merchant_id}/order/#{order_id}/transaction/#{transaction_id}", params
|
47
68
|
end
|
48
69
|
|
70
|
+
# Public: Request to store a card for later retrieval via token.
|
71
|
+
#
|
72
|
+
# Returns a Response object.
|
49
73
|
def create_credit_card_token token
|
50
74
|
params = {
|
51
75
|
'cardDetails' => card_details(token)
|
@@ -54,28 +78,56 @@ module TNSPayments
|
|
54
78
|
request :post, "/merchant/#{merchant_id}/token", params
|
55
79
|
end
|
56
80
|
|
81
|
+
# Public:
|
82
|
+
#
|
83
|
+
# Returns a Response object.
|
57
84
|
def delete_credit_card_token token
|
58
85
|
request :delete, "/merchant/#{merchant_id}/token/#{token}"
|
59
86
|
end
|
60
87
|
|
88
|
+
# Public: Request to create a Form Session. A Form Session is used by the
|
89
|
+
# Hosted Payment Form service to temporarily store card details so
|
90
|
+
# that the merchant does not need to handle these details directly.
|
91
|
+
#
|
92
|
+
# Returns a Response object.
|
61
93
|
def session_token
|
62
94
|
@session_token ||= begin
|
63
95
|
response = request :post, "/merchant/#{merchant_id}/session"
|
64
|
-
|
96
|
+
if response.success?
|
97
|
+
response.response.fetch('session')
|
98
|
+
else
|
99
|
+
raise SessionTokenException.new, response.explanation
|
100
|
+
end
|
65
101
|
end
|
66
102
|
end
|
67
103
|
|
104
|
+
# Public: Request to check a cardholder's enrollment in the 3DSecure scheme.
|
105
|
+
#
|
106
|
+
# Returns a Response object.
|
68
107
|
def check_enrollment transaction, token, postback_url
|
69
108
|
params = {
|
70
|
-
'3DSecure' => {
|
109
|
+
'3DSecure' => {
|
110
|
+
'authenticationRedirect' => {
|
111
|
+
'pageGenerationMode' => 'CUSTOMIZED',
|
112
|
+
'responseUrl' => postback_url
|
113
|
+
}
|
114
|
+
},
|
71
115
|
'apiOperation' => 'CHECK_3DS_ENROLLMENT',
|
72
116
|
'cardDetails' => card_details(token),
|
73
|
-
'transaction' => {
|
117
|
+
'transaction' => {
|
118
|
+
'amount' => transaction.amount.to_s,
|
119
|
+
'currency' => transaction.currency
|
120
|
+
}
|
74
121
|
}
|
75
122
|
|
76
123
|
request :put, "/merchant/#{merchant_id}/3DSecureId/#{transaction.three_domain_id}", params
|
77
124
|
end
|
78
125
|
|
126
|
+
# Public: Interprets the authentication response returned from the card
|
127
|
+
# Issuer's Access Control Server (ACS) after the cardholder
|
128
|
+
# completes the authentication process.
|
129
|
+
#
|
130
|
+
# Returns a Response object.
|
79
131
|
def process_acs_result three_domain_id, pa_res
|
80
132
|
params = {
|
81
133
|
'3DSecure' => {'paRes' => pa_res},
|
@@ -0,0 +1,92 @@
|
|
1
|
+
module TNSPayments
|
2
|
+
class ErrorResponse < Response
|
3
|
+
# Public: Check if the request was rejected because it did not conform to
|
4
|
+
# the API protocol.
|
5
|
+
#
|
6
|
+
# Returns booelan.
|
7
|
+
def invalid_request?
|
8
|
+
cause == 'INVALID_REQUEST'
|
9
|
+
end
|
10
|
+
|
11
|
+
# Public: Check if the server did not have enough resources to process the
|
12
|
+
# request at the moment.
|
13
|
+
#
|
14
|
+
# Returns booelan.
|
15
|
+
def server_busy?
|
16
|
+
cause == 'SERVER_BUSY'
|
17
|
+
end
|
18
|
+
|
19
|
+
# Public: Check if the request was rejected due to security reasons such as
|
20
|
+
# firewall rules, expired certificate, etc.
|
21
|
+
#
|
22
|
+
# Returns booelan.
|
23
|
+
def request_rejected?
|
24
|
+
cause == 'REQUEST_REJECTED'
|
25
|
+
end
|
26
|
+
|
27
|
+
# Public: Check if there was an internal system failure.
|
28
|
+
#
|
29
|
+
# Returns booelan.
|
30
|
+
def server_failed?
|
31
|
+
cause == 'SERVER_FAILED'
|
32
|
+
end
|
33
|
+
|
34
|
+
# Public: Check if the request timed out.
|
35
|
+
#
|
36
|
+
# Returns boolean.
|
37
|
+
def timedout?
|
38
|
+
cause == 'REQUEST_TIMEDOUT'
|
39
|
+
end
|
40
|
+
|
41
|
+
# Public: Broadly categorizes the cause of the error.
|
42
|
+
#
|
43
|
+
# Returns string.
|
44
|
+
def cause
|
45
|
+
response['error']['cause']
|
46
|
+
end
|
47
|
+
|
48
|
+
# Pubic: Textual description of the error based on the cause.
|
49
|
+
#
|
50
|
+
# Returns string.
|
51
|
+
def explanation
|
52
|
+
if invalid_request? || server_busy?
|
53
|
+
response['error']['explanation']
|
54
|
+
else
|
55
|
+
"No explanation available for #{cause}"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Public: Indicates the name of the field that failed validation.
|
60
|
+
#
|
61
|
+
# Returns name of invalid field.
|
62
|
+
def field
|
63
|
+
response['error']['field'] if invalid_request?
|
64
|
+
end
|
65
|
+
|
66
|
+
# Public: Indicates the code that helps the support team to quickly
|
67
|
+
# identify the exact cause of the error.
|
68
|
+
#
|
69
|
+
# Returns a support code.
|
70
|
+
def support_code
|
71
|
+
if server_failed? || request_rejected?
|
72
|
+
response['error']['supportCode']
|
73
|
+
else
|
74
|
+
"No support code for #{cause}"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Public: Determine if the request was successful.
|
79
|
+
#
|
80
|
+
# Returns false.
|
81
|
+
def success?
|
82
|
+
false
|
83
|
+
end
|
84
|
+
|
85
|
+
# Public: A system-generated high level overall result of the operation.
|
86
|
+
#
|
87
|
+
# Returns string.
|
88
|
+
def result
|
89
|
+
response['result']
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
data/lib/tns_payments/request.rb
CHANGED
@@ -6,16 +6,27 @@ module TNSPayments
|
|
6
6
|
attr_accessor :connection, :method, :path, :payload
|
7
7
|
|
8
8
|
def initialize connection, method, path, payload = {}
|
9
|
-
self.connection
|
9
|
+
self.connection = connection
|
10
|
+
self.method = method
|
11
|
+
self.path = path
|
12
|
+
self.payload = payload
|
10
13
|
end
|
11
14
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
headers
|
17
|
-
headers
|
15
|
+
# Public: A hash representing the headers for the request.
|
16
|
+
#
|
17
|
+
# Returns a hash of headers.
|
18
|
+
def headers
|
19
|
+
headers = {}
|
20
|
+
headers[:accept] = '*/*'
|
21
|
+
headers[:content_type] = 'Application/json;charset=UTF-8'
|
22
|
+
headers[:Authorization] = encode_credentials if authorization
|
23
|
+
headers
|
24
|
+
end
|
18
25
|
|
26
|
+
# Public: Execute the request.
|
27
|
+
#
|
28
|
+
# Returns a response object.
|
29
|
+
def perform
|
19
30
|
args = {
|
20
31
|
:method => method,
|
21
32
|
:url => url,
|
@@ -27,13 +38,27 @@ module TNSPayments
|
|
27
38
|
|
28
39
|
Response.new RestClient::Request.execute(args)
|
29
40
|
rescue RestClient::Exception => e
|
30
|
-
|
41
|
+
response = e.response
|
42
|
+
|
43
|
+
if response.message == 'Request Timeout'
|
44
|
+
response = JSON.generate({:error => {:cause => 'REQUEST_TIMEDOUT'}})
|
45
|
+
end
|
46
|
+
|
47
|
+
ErrorResponse.new response
|
31
48
|
end
|
32
49
|
|
33
50
|
private
|
34
51
|
|
52
|
+
def authorization
|
53
|
+
payload.fetch(:authorization) { true }
|
54
|
+
end
|
55
|
+
|
35
56
|
def encode_credentials
|
36
57
|
'Basic ' + Base64.encode64(":#{connection.api_key}")
|
37
58
|
end
|
59
|
+
|
60
|
+
def url
|
61
|
+
"#{connection.host}/api/rest/version/4#{path}"
|
62
|
+
end
|
38
63
|
end
|
39
64
|
end
|
@@ -6,20 +6,41 @@ module TNSPayments
|
|
6
6
|
@raw_response = response
|
7
7
|
end
|
8
8
|
|
9
|
+
# Public: The parsed response.
|
10
|
+
#
|
11
|
+
# Returns a hash of the parsed response.
|
9
12
|
def response
|
10
13
|
@response ||= JSON.parse(raw_response)
|
11
14
|
end
|
12
15
|
|
16
|
+
# Public: The result of the request.
|
17
|
+
#
|
18
|
+
# Returns a string.
|
19
|
+
def result
|
20
|
+
if response.has_key?('status')
|
21
|
+
response['status'] == 'OPERATING' ? 'SUCCESS' : 'ERROR'
|
22
|
+
elsif response.has_key?('3DSecure')
|
23
|
+
'SUCCESS'
|
24
|
+
else
|
25
|
+
response['result']
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Public: Check if the request was successful.
|
30
|
+
#
|
31
|
+
# Returns boolean.
|
13
32
|
def success?
|
14
|
-
|
33
|
+
result == 'SUCCESS'
|
15
34
|
end
|
16
35
|
|
36
|
+
# Public: Unuseful message.
|
37
|
+
#
|
38
|
+
# Returns a string.
|
17
39
|
def message
|
18
|
-
|
19
|
-
if result == 'ERROR'
|
20
|
-
response['response']['error']['explanation']
|
21
|
-
else
|
40
|
+
if success?
|
22
41
|
'Successful request'
|
42
|
+
else
|
43
|
+
ErrorResponse.new(raw_response).explanation
|
23
44
|
end
|
24
45
|
end
|
25
46
|
end
|
@@ -7,10 +7,17 @@ module TNSPayments
|
|
7
7
|
super
|
8
8
|
end
|
9
9
|
|
10
|
+
# Public: TNS require a minimum order_id of 10000000000 for what I can only
|
11
|
+
# assume is legacy requirements.
|
12
|
+
#
|
13
|
+
# Returns a minimum order_id.
|
10
14
|
def minimum_order_id
|
11
15
|
@minimum_order_id ||= 10000000000
|
12
16
|
end
|
13
17
|
|
18
|
+
# Public: TNS require an order_id to be sent with each transaction.
|
19
|
+
#
|
20
|
+
# Returns the order_id.
|
14
21
|
def order_id
|
15
22
|
minimum_order_id + @transaction.order_id.to_i
|
16
23
|
end
|
data/lib/tns_payments/version.rb
CHANGED
@@ -94,7 +94,7 @@ class TNSPayments::ConnectionTest < MiniTest::Unit::TestCase
|
|
94
94
|
end
|
95
95
|
|
96
96
|
def test_unsuccessful_session_token_request_raises_an_exception
|
97
|
-
stub_session_token_request.to_return(:status => 400, :body => '{}')
|
97
|
+
stub_session_token_request.to_return(:status => 400, :body => '{"error":{"cause":"Invalid merchant_id"}}')
|
98
98
|
assert_raises SessionTokenException do
|
99
99
|
@gateway.session_token
|
100
100
|
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TNSPayments::ErrorResponseTest < MiniTest::Unit::TestCase
|
4
|
+
def test_cause_exists
|
5
|
+
json = JSON.generate({'error' => {'cause' => 'foo'}})
|
6
|
+
assert_equal 'foo', TNSPayments::ErrorResponse.new(json).cause
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_invalid_request_is_true
|
10
|
+
json = JSON.generate({'error' => {'cause' => 'INVALID_REQUEST'}})
|
11
|
+
assert TNSPayments::ErrorResponse.new(json).invalid_request?
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_invalid_request_is_false
|
15
|
+
json = JSON.generate({'error' => {'cause' => 'SERVER_BUSY'}})
|
16
|
+
refute TNSPayments::ErrorResponse.new(json).invalid_request?
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_server_busy_is_true
|
20
|
+
json = JSON.generate({'error' => {'cause' => 'SERVER_BUSY'}})
|
21
|
+
assert TNSPayments::ErrorResponse.new(json).server_busy?
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_server_busy_is_false
|
25
|
+
json = JSON.generate({'error' => {'cause' => 'INVALID_REQUEST'}})
|
26
|
+
refute TNSPayments::ErrorResponse.new(json).server_busy?
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_request_rejected_is_true
|
30
|
+
json = JSON.generate({'error' => {'cause' => 'REQUEST_REJECTED'}})
|
31
|
+
assert TNSPayments::ErrorResponse.new(json).request_rejected?
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_request_rejected_is_false
|
35
|
+
json = JSON.generate({'error' => {'cause' => 'SERVER_BUSY'}})
|
36
|
+
refute TNSPayments::ErrorResponse.new(json).request_rejected?
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_server_failed_is_true
|
40
|
+
json = JSON.generate({'error' => {'cause' => 'SERVER_FAILED'}})
|
41
|
+
assert TNSPayments::ErrorResponse.new(json).server_failed?
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_server_failed_is_false
|
45
|
+
json = JSON.generate({'error' => {'cause' => 'REQUEST_REJECTED'}})
|
46
|
+
refute TNSPayments::ErrorResponse.new(json).server_failed?
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_explanation_when_invalid_request
|
50
|
+
json = JSON.generate({'error' => {'cause' => 'INVALID_REQUEST', 'explanation' => 'Damn'}})
|
51
|
+
assert_equal 'Damn', TNSPayments::ErrorResponse.new(json).explanation
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_explanation_when_server_busy
|
55
|
+
json = JSON.generate({'error' => {'cause' => 'SERVER_BUSY', 'explanation' => 'Damn'}})
|
56
|
+
assert_equal 'Damn', TNSPayments::ErrorResponse.new(json).explanation
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_explanation_when_anything_else
|
60
|
+
json = JSON.generate({'error' => {'cause' => 'SERVER_FAILED', 'explanation' => 'Damn'}})
|
61
|
+
assert_equal 'No explanation available for SERVER_FAILED', TNSPayments::ErrorResponse.new(json).explanation
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_field_when_invalid_request
|
65
|
+
json = JSON.generate({'error' => {'cause' => 'INVALID_REQUEST', 'field' => 'foo'}})
|
66
|
+
assert_equal 'foo', TNSPayments::ErrorResponse.new(json).field
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_field_when_anything_else
|
70
|
+
json = JSON.generate({'error' => {'cause' => 'SERVER_FAILED', 'field' => 'foo'}})
|
71
|
+
assert_nil TNSPayments::ErrorResponse.new(json).field
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_support_code_when_server_failed
|
75
|
+
json = JSON.generate({'error' => {'cause' => 'SERVER_FAILED', 'supportCode' => 'foo'}})
|
76
|
+
assert_equal 'foo', TNSPayments::ErrorResponse.new(json).support_code
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_support_code_when_request_rejected
|
80
|
+
json = JSON.generate({'error' => {'cause' => 'REQUEST_REJECTED', 'supportCode' => 'foo'}})
|
81
|
+
assert_equal 'foo', TNSPayments::ErrorResponse.new(json).support_code
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_support_code_when_anything_else
|
85
|
+
json = JSON.generate({'error' => {'cause' => 'INVALID_REQUEST', 'supportCode' => 'foo'}})
|
86
|
+
assert_equal 'No support code for INVALID_REQUEST', TNSPayments::ErrorResponse.new(json).support_code
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_timedout
|
90
|
+
json = JSON.generate({'error' => {'cause' => 'REQUEST_TIMEDOUT'}})
|
91
|
+
assert TNSPayments::ErrorResponse.new(json).timedout?
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_success_is_false
|
95
|
+
refute TNSPayments::ErrorResponse.new('{}').success?
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_result
|
99
|
+
json = JSON.generate({'result' => 'ERROR'})
|
100
|
+
assert_equal 'ERROR', TNSPayments::ErrorResponse.new(json).result
|
101
|
+
end
|
102
|
+
end
|
data/test/unit/response_test.rb
CHANGED
@@ -2,7 +2,7 @@ require 'helper'
|
|
2
2
|
|
3
3
|
class TNSPayments::ResponseTest < MiniTest::Unit::TestCase
|
4
4
|
def test_success_when_operating
|
5
|
-
assert Response.new({:
|
5
|
+
assert Response.new({:status => 'OPERATING'}.to_json).success?
|
6
6
|
end
|
7
7
|
|
8
8
|
def test_success_when_success
|
@@ -14,7 +14,7 @@ class TNSPayments::ResponseTest < MiniTest::Unit::TestCase
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def test_message_when_error_request
|
17
|
-
response = "{\"result\":\"401 UNAUTHORIZED\",\"
|
17
|
+
response = "{\"result\":\"401 UNAUTHORIZED\",\"error\":{\"cause\":\"INVALID_REQUEST\",\"explanation\":\"Invalid credentials.\"},\"result\":\"ERROR\"}"
|
18
18
|
assert_equal 'Invalid credentials.', Response.new(response).message
|
19
19
|
end
|
20
20
|
|
metadata
CHANGED
@@ -1,154 +1,128 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: tns_payments
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.9
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 0
|
9
|
-
- 8
|
10
|
-
version: 0.0.8
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Tim Cooper
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
dependencies:
|
21
|
-
- !ruby/object:Gem::Dependency
|
22
|
-
prerelease: false
|
23
|
-
type: :runtime
|
12
|
+
date: 2012-04-12 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
24
15
|
name: json
|
25
|
-
|
16
|
+
requirement: &70254632443040 !ruby/object:Gem::Requirement
|
26
17
|
none: false
|
27
|
-
requirements:
|
28
|
-
- -
|
29
|
-
- !ruby/object:Gem::Version
|
30
|
-
|
31
|
-
segments:
|
32
|
-
- 0
|
33
|
-
version: "0"
|
34
|
-
requirement: *id001
|
35
|
-
- !ruby/object:Gem::Dependency
|
36
|
-
prerelease: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
37
22
|
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70254632443040
|
25
|
+
- !ruby/object:Gem::Dependency
|
38
26
|
name: rest-client
|
39
|
-
|
27
|
+
requirement: &70254632442580 !ruby/object:Gem::Requirement
|
40
28
|
none: false
|
41
|
-
requirements:
|
42
|
-
- -
|
43
|
-
- !ruby/object:Gem::Version
|
44
|
-
|
45
|
-
|
46
|
-
- 0
|
47
|
-
version: "0"
|
48
|
-
requirement: *id002
|
49
|
-
- !ruby/object:Gem::Dependency
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :runtime
|
50
34
|
prerelease: false
|
51
|
-
|
35
|
+
version_requirements: *70254632442580
|
36
|
+
- !ruby/object:Gem::Dependency
|
52
37
|
name: minitest
|
53
|
-
|
38
|
+
requirement: &70254632442000 !ruby/object:Gem::Requirement
|
54
39
|
none: false
|
55
|
-
requirements:
|
56
|
-
- -
|
57
|
-
- !ruby/object:Gem::Version
|
58
|
-
|
59
|
-
segments:
|
60
|
-
- 0
|
61
|
-
version: "0"
|
62
|
-
requirement: *id003
|
63
|
-
- !ruby/object:Gem::Dependency
|
64
|
-
prerelease: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
65
44
|
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70254632442000
|
47
|
+
- !ruby/object:Gem::Dependency
|
66
48
|
name: rake
|
67
|
-
|
49
|
+
requirement: &70254632441520 !ruby/object:Gem::Requirement
|
68
50
|
none: false
|
69
|
-
requirements:
|
70
|
-
- -
|
71
|
-
- !ruby/object:Gem::Version
|
72
|
-
|
73
|
-
segments:
|
74
|
-
- 0
|
75
|
-
version: "0"
|
76
|
-
requirement: *id004
|
77
|
-
- !ruby/object:Gem::Dependency
|
78
|
-
prerelease: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
79
55
|
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70254632441520
|
58
|
+
- !ruby/object:Gem::Dependency
|
80
59
|
name: webmock
|
81
|
-
|
60
|
+
requirement: &70254632441040 !ruby/object:Gem::Requirement
|
82
61
|
none: false
|
83
|
-
requirements:
|
84
|
-
- -
|
85
|
-
- !ruby/object:Gem::Version
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
requirement: *id005
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *70254632441040
|
91
69
|
description: Integration with TNS Payments Gateway
|
92
|
-
email:
|
70
|
+
email:
|
93
71
|
- coop@latrobest.com
|
94
72
|
executables: []
|
95
|
-
|
96
73
|
extensions: []
|
97
|
-
|
98
74
|
extra_rdoc_files: []
|
99
|
-
|
100
|
-
files:
|
75
|
+
files:
|
101
76
|
- .gitignore
|
102
77
|
- CHANGELOG.md
|
103
78
|
- Gemfile
|
104
79
|
- Rakefile
|
105
80
|
- lib/tns_payments.rb
|
106
81
|
- lib/tns_payments/connection.rb
|
82
|
+
- lib/tns_payments/error_response.rb
|
107
83
|
- lib/tns_payments/request.rb
|
108
84
|
- lib/tns_payments/response.rb
|
109
85
|
- lib/tns_payments/transaction.rb
|
110
86
|
- lib/tns_payments/version.rb
|
111
87
|
- test/helper.rb
|
112
88
|
- test/unit/conntection_test.rb
|
89
|
+
- test/unit/error_response_test.rb
|
113
90
|
- test/unit/response_test.rb
|
114
91
|
- test/unit/transaction_test.rb
|
115
92
|
- tns_payments.gemspec
|
116
|
-
|
117
|
-
homepage: ""
|
93
|
+
homepage: ''
|
118
94
|
licenses: []
|
119
|
-
|
120
95
|
post_install_message:
|
121
96
|
rdoc_options: []
|
122
|
-
|
123
|
-
require_paths:
|
97
|
+
require_paths:
|
124
98
|
- lib
|
125
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
99
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
126
100
|
none: false
|
127
|
-
requirements:
|
128
|
-
- -
|
129
|
-
- !ruby/object:Gem::Version
|
130
|
-
|
131
|
-
segments:
|
101
|
+
requirements:
|
102
|
+
- - ! '>='
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '0'
|
105
|
+
segments:
|
132
106
|
- 0
|
133
|
-
|
134
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
107
|
+
hash: -4303212720216238171
|
108
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
135
109
|
none: false
|
136
|
-
requirements:
|
137
|
-
- -
|
138
|
-
- !ruby/object:Gem::Version
|
139
|
-
|
140
|
-
segments:
|
110
|
+
requirements:
|
111
|
+
- - ! '>='
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: '0'
|
114
|
+
segments:
|
141
115
|
- 0
|
142
|
-
|
116
|
+
hash: -4303212720216238171
|
143
117
|
requirements: []
|
144
|
-
|
145
118
|
rubyforge_project:
|
146
|
-
rubygems_version: 1.
|
119
|
+
rubygems_version: 1.8.11
|
147
120
|
signing_key:
|
148
121
|
specification_version: 3
|
149
122
|
summary: Integration with TNS Payments Gateway
|
150
|
-
test_files:
|
123
|
+
test_files:
|
151
124
|
- test/helper.rb
|
152
125
|
- test/unit/conntection_test.rb
|
126
|
+
- test/unit/error_response_test.rb
|
153
127
|
- test/unit/response_test.rb
|
154
128
|
- test/unit/transaction_test.rb
|