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 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' => {'amount' => transaction.amount.to_s, 'currency' => transaction.currency, 'reference' => transaction_id.to_s}
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' => {'amount' => transaction.amount.to_s, 'currency' => transaction.currency, 'reference' => transaction_id.to_s}
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
- response.response.fetch('session') { raise(SessionTokenException.new, response.message) }
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' => {'authenticationRedirect' => {'pageGenerationMode' => 'CUSTOMIZED', 'responseUrl' => postback_url}},
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' => {'amount' => transaction.amount.to_s, 'currency' => transaction.currency}
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
@@ -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, self.method, self.path, self.payload = connection, method, path, payload
9
+ self.connection = connection
10
+ self.method = method
11
+ self.path = path
12
+ self.payload = payload
10
13
  end
11
14
 
12
- def perform
13
- authorization = payload.fetch(:authorization) { true }
14
- url = "#{connection.host}/api/rest/version/4#{path}"
15
- auth_headers = {:Authorization => encode_credentials}
16
- headers = {:content_type => 'Application/json;charset=UTF-8', :accept => '*/*'}
17
- headers.merge! auth_headers if authorization
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
- Response.new({:result => e.message.upcase, :response => JSON.parse(e.response || '{}')}.to_json)
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
- %w[SUCCESS OPERATING].include? response['result'] || response['status']
33
+ result == 'SUCCESS'
15
34
  end
16
35
 
36
+ # Public: Unuseful message.
37
+ #
38
+ # Returns a string.
17
39
  def message
18
- result = response['response'].fetch('result') { 'SUCCESS' }
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
@@ -1,3 +1,3 @@
1
1
  module TNSPayments
2
- VERSION = "0.0.8"
2
+ VERSION = "0.0.9"
3
3
  end
@@ -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
@@ -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({:result => 'OPERATING'}.to_json).success?
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\",\"response\":{\"error\":{\"cause\":\"INVALID_REQUEST\",\"explanation\":\"Invalid credentials.\"},\"result\":\"ERROR\"}}"
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
- hash: 15
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
- date: 2012-04-11 00:00:00 +10:00
19
- default_executable:
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
- version_requirements: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &70254632443040 !ruby/object:Gem::Requirement
26
17
  none: false
27
- requirements:
28
- - - ">="
29
- - !ruby/object:Gem::Version
30
- hash: 3
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
- version_requirements: &id002 !ruby/object:Gem::Requirement
27
+ requirement: &70254632442580 !ruby/object:Gem::Requirement
40
28
  none: false
41
- requirements:
42
- - - ">="
43
- - !ruby/object:Gem::Version
44
- hash: 3
45
- segments:
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
- type: :development
35
+ version_requirements: *70254632442580
36
+ - !ruby/object:Gem::Dependency
52
37
  name: minitest
53
- version_requirements: &id003 !ruby/object:Gem::Requirement
38
+ requirement: &70254632442000 !ruby/object:Gem::Requirement
54
39
  none: false
55
- requirements:
56
- - - ">="
57
- - !ruby/object:Gem::Version
58
- hash: 3
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
- version_requirements: &id004 !ruby/object:Gem::Requirement
49
+ requirement: &70254632441520 !ruby/object:Gem::Requirement
68
50
  none: false
69
- requirements:
70
- - - ">="
71
- - !ruby/object:Gem::Version
72
- hash: 3
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
- version_requirements: &id005 !ruby/object:Gem::Requirement
60
+ requirement: &70254632441040 !ruby/object:Gem::Requirement
82
61
  none: false
83
- requirements:
84
- - - ">="
85
- - !ruby/object:Gem::Version
86
- hash: 3
87
- segments:
88
- - 0
89
- version: "0"
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
- has_rdoc: true
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
- hash: 3
131
- segments:
101
+ requirements:
102
+ - - ! '>='
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ segments:
132
106
  - 0
133
- version: "0"
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
- hash: 3
140
- segments:
110
+ requirements:
111
+ - - ! '>='
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ segments:
141
115
  - 0
142
- version: "0"
116
+ hash: -4303212720216238171
143
117
  requirements: []
144
-
145
118
  rubyforge_project:
146
- rubygems_version: 1.6.2
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