secure_trading 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.
- 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: []
|