secure_trading 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/secure_trading.rb +32 -0
- data/lib/secure_trading/connection.rb +29 -0
- data/lib/secure_trading/data_object.rb +15 -0
- data/lib/secure_trading/objects/customer.rb +33 -0
- data/lib/secure_trading/objects/order.rb +17 -0
- data/lib/secure_trading/objects/payment_card.rb +21 -0
- data/lib/secure_trading/objects/tds_response.rb +17 -0
- data/lib/secure_trading/objects/transaction.rb +16 -0
- data/lib/secure_trading/objects/user_agent.rb +9 -0
- data/lib/secure_trading/request.rb +83 -0
- data/lib/secure_trading/requests/authorisation.rb +22 -0
- data/lib/secure_trading/requests/authorisation_reversal.rb +20 -0
- data/lib/secure_trading/requests/authorisation_with_tds.rb +19 -0
- data/lib/secure_trading/requests/continuous_authorisation.rb +19 -0
- data/lib/secure_trading/requests/refund.rb +20 -0
- data/lib/secure_trading/requests/settlement.rb +25 -0
- data/lib/secure_trading/requests/tds_query.rb +47 -0
- data/lib/secure_trading/requests/transaction_query.rb +19 -0
- data/lib/secure_trading/response.rb +51 -0
- data/lib/secure_trading/util.rb +44 -0
- data/lib/secure_trading/xpay_client.rb +15 -0
- metadata +65 -0
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'uri'
|
3
|
+
require 'net/https'
|
4
|
+
require 'xmlsimple'
|
5
|
+
require 'iconv'
|
6
|
+
require 'fileutils'
|
7
|
+
|
8
|
+
SECURETRADING_API_VERSION = '3.51'
|
9
|
+
|
10
|
+
require "secure_trading/util"
|
11
|
+
require "secure_trading/connection"
|
12
|
+
require "secure_trading/xpay_client"
|
13
|
+
require "secure_trading/request"
|
14
|
+
require "secure_trading/response"
|
15
|
+
require "secure_trading/data_object"
|
16
|
+
|
17
|
+
require 'secure_trading/requests/authorisation'
|
18
|
+
require 'secure_trading/requests/authorisation_with_tds'
|
19
|
+
require 'secure_trading/requests/continuous_authorisation'
|
20
|
+
require 'secure_trading/requests/authorisation_reversal'
|
21
|
+
require 'secure_trading/requests/transaction_query'
|
22
|
+
require 'secure_trading/requests/settlement'
|
23
|
+
|
24
|
+
require 'secure_trading/objects/customer'
|
25
|
+
require 'secure_trading/objects/order'
|
26
|
+
require 'secure_trading/objects/payment_card'
|
27
|
+
require 'secure_trading/objects/tds_response'
|
28
|
+
require 'secure_trading/objects/transaction'
|
29
|
+
require 'secure_trading/objects/user_agent'
|
30
|
+
|
31
|
+
module SecureTrading
|
32
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module SecureTrading
|
2
|
+
class Connection
|
3
|
+
|
4
|
+
class CertificateFileNotFound < RuntimeError; end
|
5
|
+
|
6
|
+
attr_reader :xpay_client, :site_reference, :certificate_path
|
7
|
+
|
8
|
+
def initialize(xpay_client, site_reference, certificate_path, options = {})
|
9
|
+
@xpay_client = xpay_client
|
10
|
+
@site_reference = site_reference
|
11
|
+
@certificate_path = certificate_path
|
12
|
+
@options = options
|
13
|
+
@options[:request_cache_path] ||= File.join('', 'tmp', 'securetrading', 'requests')
|
14
|
+
end
|
15
|
+
|
16
|
+
def certificate
|
17
|
+
if File.exist?(self.certificate_path)
|
18
|
+
File.read(self.certificate_path)
|
19
|
+
else
|
20
|
+
raise CertificateFileNotFound, "Certificate file was not located at #{self.certificate_path}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def options
|
25
|
+
@options
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module SecureTrading
|
2
|
+
class DataObject
|
3
|
+
|
4
|
+
def initialize(attributes = {})
|
5
|
+
attributes.each do |key,value|
|
6
|
+
self.send("#{key}=", value) if self.respond_to?(key)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_xml(options = {})
|
11
|
+
Util.to_xml(self.to_hash, options) if self.respond_to?(:to_hash)
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module SecureTrading
|
2
|
+
module Objects
|
3
|
+
class Customer < DataObject
|
4
|
+
|
5
|
+
attr_accessor :title, :first_name, :last_name, :company, :address, :phone_number, :email_address
|
6
|
+
|
7
|
+
def to_hash
|
8
|
+
{
|
9
|
+
'Postal' => {
|
10
|
+
'Name' => { 'NamePrefix' => sanitize(self.title), 'FirstName' => sanitize(self.first_name), 'LastName' => sanitize(self.last_name) },
|
11
|
+
'Company' => sanitize(self.company),
|
12
|
+
'Street' => sanitize(self.address.street),
|
13
|
+
'City' => sanitize(self.address.city),
|
14
|
+
'StateProv' => sanitize(self.address.state),
|
15
|
+
'PostalCode' => sanitize(self.address.postal_code),
|
16
|
+
'CountryCode' => sanitize(self.address.country)
|
17
|
+
},
|
18
|
+
'Telecom' => {'Phone' => sanitize(self.phone_number)},
|
19
|
+
'Online' => {'Email' => sanitize(self.email_address)}
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
def sanitize(value)
|
24
|
+
Iconv.iconv('ascii//translit//IGNORE', 'utf-8//IGNORE', value).join
|
25
|
+
end
|
26
|
+
|
27
|
+
class Address < DataObject
|
28
|
+
attr_accessor :street, :city, :state, :postal_code, :country
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module SecureTrading
|
2
|
+
module Objects
|
3
|
+
class PaymentCard < DataObject
|
4
|
+
|
5
|
+
attr_accessor :type, :number, :issue, :start_date, :expiry_date, :security_code, :reference
|
6
|
+
|
7
|
+
def to_hash
|
8
|
+
{
|
9
|
+
'Type' => self.type,
|
10
|
+
'Number' => self.number,
|
11
|
+
'Issue' => self.issue,
|
12
|
+
'StartDate' => self.start_date,
|
13
|
+
'ExpiryDate' => self.expiry_date,
|
14
|
+
'SecurityCode' => self.security_code,
|
15
|
+
'ParentTransactionReference' => self.reference
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module SecureTrading
|
2
|
+
module Objects
|
3
|
+
class Transaction < DataObject
|
4
|
+
|
5
|
+
attr_accessor :verifier, :reference
|
6
|
+
|
7
|
+
def to_hash
|
8
|
+
{
|
9
|
+
'TransactionVerifier' => self.verifier,
|
10
|
+
'ParentTransactionReference' => self.reference
|
11
|
+
}
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module SecureTrading
|
2
|
+
class Request
|
3
|
+
|
4
|
+
class ConnectionTimeout < RuntimeError; end
|
5
|
+
class ConnectionFailed < RuntimeError; end
|
6
|
+
class PrematureXpayQuery < RuntimeError; end
|
7
|
+
|
8
|
+
attr_accessor :connection
|
9
|
+
attr_reader :response
|
10
|
+
|
11
|
+
def initialize(connection)
|
12
|
+
@connection = connection
|
13
|
+
end
|
14
|
+
|
15
|
+
## Send the XML request, using the provided connection.
|
16
|
+
def process
|
17
|
+
post_to_xpay!
|
18
|
+
self.response.success?
|
19
|
+
end
|
20
|
+
|
21
|
+
## Returns the error message provided from Xpay
|
22
|
+
def error_message
|
23
|
+
@error_message
|
24
|
+
end
|
25
|
+
|
26
|
+
## Return the full XML request for this request. The full output from this method should be sent to the secure trading
|
27
|
+
## Xpay API.
|
28
|
+
def xml_request
|
29
|
+
attributes = {}
|
30
|
+
attributes['RequestBlock'] = {'Version' => SECURETRADING_API_VERSION}
|
31
|
+
attributes['Request'] = {'Type' => self.request_type}
|
32
|
+
@xml_request ||= Util.to_xml({'Request' => self.to_hash, 'Certificate' => self.connection.certificate}, :root => 'RequestBlock', :attributes => attributes)
|
33
|
+
end
|
34
|
+
|
35
|
+
## Return a sanitized version of the xml request for storing in a data store. Sensitive card numbers and security codes will be
|
36
|
+
## replaced with asterisks and the certificate will be removed.
|
37
|
+
def sanitized_xml_request
|
38
|
+
xml = xml_request.dup
|
39
|
+
%w{ Number SecurityCode }.each do |field|
|
40
|
+
xml.gsub!(/\<#{field}\>(.+)\<\/#{field}\>/) { "<#{field}>" + ('*' * $1.size) + "</#{field}>" }
|
41
|
+
end
|
42
|
+
xml.gsub!(/\<Certificate\>(.*)\<\/Certificate\>/m, '<Certificate>{FILTERED}</Certificate>')
|
43
|
+
xml
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
## Post the XML request to the Xpay client and set the full response to @raw_xpay_response. Any connection errors
|
49
|
+
## will raise exceptions. All requests timeout after 1 minute (don't want anything silly going on really)
|
50
|
+
def post_to_xpay!
|
51
|
+
begin
|
52
|
+
Timeout::timeout(60) do
|
53
|
+
Net::HTTP.start(self.connection.xpay_client.host, self.connection.xpay_client.port) do |http|
|
54
|
+
response = http.post('/', "xml=#{self.xml_request}")
|
55
|
+
@response = Response.new(response.body)
|
56
|
+
save_xml_request
|
57
|
+
end
|
58
|
+
end
|
59
|
+
rescue Timeout::Error
|
60
|
+
raise ConnectionTimeout, "Connection to Xpay at #{self.connection.xpay_client} failed."
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
## Cache the sanitized XML request in the file system in case secure trading support want help figuring
|
65
|
+
## stuff out for themselves
|
66
|
+
def save_xml_request
|
67
|
+
## Make the directory for the requests
|
68
|
+
FileUtils.mkdir_p(@connection.options[:request_cache_path])
|
69
|
+
## Where to save the request?
|
70
|
+
if @response.transaction.reference
|
71
|
+
request_file = File.join(@connection.options[:request_cache_path], @response.transaction.reference.to_s)
|
72
|
+
## Write the XML output...
|
73
|
+
output = ["## Logged Output for Transaction #{@response.transaction.reference} on #{Time.now}"]
|
74
|
+
output << "## Request sent"
|
75
|
+
output << self.sanitized_xml_request
|
76
|
+
output << "## Response received"
|
77
|
+
output << @response.raw_response
|
78
|
+
File.open(request_file, 'w') { |f| f.write(output.join("\n\n"))}
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module SecureTrading
|
2
|
+
module Requests
|
3
|
+
class Authorisation < Request
|
4
|
+
|
5
|
+
attr_accessor :amount, :currency, :settlement_day, :customer, :payment_method, :order
|
6
|
+
|
7
|
+
def request_type
|
8
|
+
'AUTH'
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_hash
|
12
|
+
{
|
13
|
+
'Operation' => {'SiteReference' => self.connection.site_reference, 'Amount' => self.amount, 'Currency' => self.currency || 'GBP', 'SettlementDay' => self.settlement_day || 1 },
|
14
|
+
'CustomerInfo' => customer,
|
15
|
+
'PaymentMethod' => {'CreditCard' => payment_method },
|
16
|
+
'Order' => order
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module SecureTrading
|
2
|
+
module Requests
|
3
|
+
class AuthorisationReversal < Request
|
4
|
+
|
5
|
+
attr_accessor :transaction
|
6
|
+
|
7
|
+
def request_type
|
8
|
+
"AUTHREVERSAL"
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_hash
|
12
|
+
{
|
13
|
+
'Operation' => {'SiteReference' => self.connection.site_reference},
|
14
|
+
'PaymentMethod' => {'CreditCard' => self.transaction}
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module SecureTrading
|
2
|
+
module Requests
|
3
|
+
class AuthorisationWithTDS < Authorisation
|
4
|
+
|
5
|
+
attr_accessor :tds_response
|
6
|
+
|
7
|
+
def request_type
|
8
|
+
'ST3DAUTH'
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_hash
|
12
|
+
hash = super()
|
13
|
+
hash['PaymentMethod']['ThreeDSecure'] = self.tds_response
|
14
|
+
hash
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module SecureTrading
|
2
|
+
module Requests
|
3
|
+
class ContinuousAuthorisation < Authorisation
|
4
|
+
|
5
|
+
|
6
|
+
def request_type
|
7
|
+
'CONTINUOUSAUTH'
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_hash
|
11
|
+
h = super
|
12
|
+
h['Operation'].delete('Amount') if self.amount.nil?
|
13
|
+
h['Operation'].delete('Currency') if self.currency.nil?
|
14
|
+
h
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module SecureTrading
|
2
|
+
module Requests
|
3
|
+
class Refund < Request
|
4
|
+
|
5
|
+
attr_accessor :amount, :transaction
|
6
|
+
|
7
|
+
def request_type
|
8
|
+
'REFUND'
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_hash
|
12
|
+
{
|
13
|
+
'Operation' => {'SiteReference' => self.connection.site_reference, 'Amount' => self.amount},
|
14
|
+
'PaymentMethod' => {'CreditCard' => transaction },
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module SecureTrading
|
2
|
+
module Requests
|
3
|
+
class Settlement < Request
|
4
|
+
|
5
|
+
attr_accessor :amount, :transaction_reference, :date, :status
|
6
|
+
|
7
|
+
def request_type
|
8
|
+
'SETTLEMENT'
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_hash
|
12
|
+
{
|
13
|
+
'Operation' => {
|
14
|
+
'SiteReference' => self.connection.site_reference,
|
15
|
+
'TransactionReference' => self.transaction_reference,
|
16
|
+
'SettleDate' => self.date || 'NEXT',
|
17
|
+
'SettleStatus' => self.status.to_i,
|
18
|
+
'SettleAmount' => self.amount
|
19
|
+
},
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module SecureTrading
|
2
|
+
module Requests
|
3
|
+
class TDSQuery < Request
|
4
|
+
|
5
|
+
attr_accessor :amount, :currency, :user_agent, :payment_method, :order, :merchant_name, :term_url
|
6
|
+
|
7
|
+
def request_type
|
8
|
+
'ST3DCARDQUERY'
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_hash
|
12
|
+
{
|
13
|
+
'Operation' => {
|
14
|
+
'SiteReference' => self.connection.site_reference,
|
15
|
+
'Amount' => self.amount,
|
16
|
+
'Currency' => self.currency || 'GBP',
|
17
|
+
'TermUrl' => self.term_url,
|
18
|
+
'MerchantName' => self.merchant_name
|
19
|
+
},
|
20
|
+
'CustomerInfo' => self.user_agent,
|
21
|
+
'PaymentMethod' => {'CreditCard' => self.payment_method },
|
22
|
+
'Order' => self.order
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
def invalid_details?
|
27
|
+
## This can actually mean quite a few other things but for now we're assuming the card details are invalid
|
28
|
+
## as this is the most likely cause for result 0
|
29
|
+
self.response.result == 0
|
30
|
+
end
|
31
|
+
|
32
|
+
## Should we perform a 3d auth for this card?
|
33
|
+
def request_3d_auth?
|
34
|
+
return false if self.response.result == 2
|
35
|
+
self.response.result == 1 && ['Y', 'N', 'U'].include?(self.response.operation_response['Enrolled'])
|
36
|
+
end
|
37
|
+
|
38
|
+
def is_enrolled?
|
39
|
+
self.response.operation_response['Enrolled'].upcase == 'Y'
|
40
|
+
end
|
41
|
+
|
42
|
+
def enrollment_status
|
43
|
+
self.response.operation_response['Enrolled']
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module SecureTrading
|
2
|
+
module Requests
|
3
|
+
class TransactionQuery < Request
|
4
|
+
|
5
|
+
attr_accessor :reference
|
6
|
+
|
7
|
+
def request_type
|
8
|
+
'TRANSACTIONQUERY'
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_hash
|
12
|
+
{
|
13
|
+
'Operation' => {'SiteReference' => self.connection.site_reference, 'TransactionReference' => self.reference}
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module SecureTrading
|
2
|
+
class Response
|
3
|
+
|
4
|
+
attr_reader :response
|
5
|
+
|
6
|
+
def initialize(response)
|
7
|
+
@response = response
|
8
|
+
end
|
9
|
+
|
10
|
+
def xml
|
11
|
+
@xml ||= XmlSimple.xml_in(@response)
|
12
|
+
end
|
13
|
+
|
14
|
+
def type
|
15
|
+
self.xml['Response'].first['Type']
|
16
|
+
end
|
17
|
+
|
18
|
+
def live?
|
19
|
+
self.xml["Live"] == "TRUE"
|
20
|
+
end
|
21
|
+
|
22
|
+
def message
|
23
|
+
self.operation_response['Message']
|
24
|
+
end
|
25
|
+
|
26
|
+
def operation_response
|
27
|
+
Util.stringify_values(self.xml["Response"].first["OperationResponse"].first)
|
28
|
+
end
|
29
|
+
|
30
|
+
def threed3secure_response
|
31
|
+
Util.stringify_values(self.xml["Response"].first["ThreeDSecure"].first)
|
32
|
+
end
|
33
|
+
|
34
|
+
def result
|
35
|
+
operation_response['Result'].to_i
|
36
|
+
end
|
37
|
+
|
38
|
+
def success?
|
39
|
+
result == 1
|
40
|
+
end
|
41
|
+
|
42
|
+
def transaction
|
43
|
+
Objects::Transaction.new(:verifier => self.operation_response['TransactionVerifier'], :reference => self.operation_response['TransactionReference'])
|
44
|
+
end
|
45
|
+
|
46
|
+
def raw_response
|
47
|
+
@response
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'builder'
|
2
|
+
module SecureTrading
|
3
|
+
class Util
|
4
|
+
class << self
|
5
|
+
def stringify_values(hash)
|
6
|
+
hash.inject({}) do |options, (key,value)|
|
7
|
+
if value.is_a?(Array)
|
8
|
+
options[key] = value.first
|
9
|
+
else
|
10
|
+
options[key] = value
|
11
|
+
end
|
12
|
+
options
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_xml(hash, options = {})
|
17
|
+
options[:indent] ||= 2
|
18
|
+
options = {:builder => Builder::XmlMarkup.new(:indent => options[:indent])}.merge(options)
|
19
|
+
|
20
|
+
attributes = options[:attributes] ||= {}
|
21
|
+
root_attributes = attributes[options[:root].to_s] || {}
|
22
|
+
options[:builder].__send__(:method_missing, options[:root].to_s, root_attributes) do
|
23
|
+
hash.each do |key, value|
|
24
|
+
case value
|
25
|
+
when ::Hash
|
26
|
+
to_xml(value, options.merge({ :root => key, :skip_instruct => true }))
|
27
|
+
else
|
28
|
+
if value.respond_to?(:to_hash)
|
29
|
+
value = value.to_hash
|
30
|
+
end
|
31
|
+
if value.is_a?(Hash)
|
32
|
+
Util.to_xml(value, options.merge({ :root => key, :skip_instruct => true }))
|
33
|
+
else
|
34
|
+
options[:builder].tag!(key.to_s, value)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
metadata
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: secure_trading
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- aTech Media
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-05-03 00:00:00.000000000Z
|
13
|
+
dependencies: []
|
14
|
+
description:
|
15
|
+
email: adam@atechmedia.com
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- lib/secure_trading/connection.rb
|
21
|
+
- lib/secure_trading/data_object.rb
|
22
|
+
- lib/secure_trading/objects/customer.rb
|
23
|
+
- lib/secure_trading/objects/order.rb
|
24
|
+
- lib/secure_trading/objects/payment_card.rb
|
25
|
+
- lib/secure_trading/objects/tds_response.rb
|
26
|
+
- lib/secure_trading/objects/transaction.rb
|
27
|
+
- lib/secure_trading/objects/user_agent.rb
|
28
|
+
- lib/secure_trading/request.rb
|
29
|
+
- lib/secure_trading/requests/authorisation.rb
|
30
|
+
- lib/secure_trading/requests/authorisation_reversal.rb
|
31
|
+
- lib/secure_trading/requests/authorisation_with_tds.rb
|
32
|
+
- lib/secure_trading/requests/continuous_authorisation.rb
|
33
|
+
- lib/secure_trading/requests/refund.rb
|
34
|
+
- lib/secure_trading/requests/settlement.rb
|
35
|
+
- lib/secure_trading/requests/tds_query.rb
|
36
|
+
- lib/secure_trading/requests/transaction_query.rb
|
37
|
+
- lib/secure_trading/response.rb
|
38
|
+
- lib/secure_trading/util.rb
|
39
|
+
- lib/secure_trading/xpay_client.rb
|
40
|
+
- lib/secure_trading.rb
|
41
|
+
homepage: http://www.atechmedia.com
|
42
|
+
licenses: []
|
43
|
+
post_install_message:
|
44
|
+
rdoc_options: []
|
45
|
+
require_paths:
|
46
|
+
- lib
|
47
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
48
|
+
none: false
|
49
|
+
requirements:
|
50
|
+
- - ! '>='
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '0'
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ! '>='
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: '0'
|
59
|
+
requirements: []
|
60
|
+
rubyforge_project:
|
61
|
+
rubygems_version: 1.8.10
|
62
|
+
signing_key:
|
63
|
+
specification_version: 3
|
64
|
+
summary: Secure Trading Ruby Library
|
65
|
+
test_files: []
|