xpay 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +12 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +35 -0
- data/LICENSE +20 -0
- data/README.rdoc +109 -0
- data/Rakefile +52 -0
- data/UPGRADES +9 -0
- data/lib/xpay.rb +109 -0
- data/lib/xpay/core/creditcard.rb +49 -0
- data/lib/xpay/core/customer.rb +47 -0
- data/lib/xpay/core/operation.rb +58 -0
- data/lib/xpay/payment.rb +209 -0
- data/lib/xpay/transaction.rb +35 -0
- data/lib/xpay/version.rb +3 -0
- data/rails/init.rb +2 -0
- data/tasks/xpay_tasks.rake +4 -0
- data/test/fixtures/config/xpay.yml +25 -0
- data/test/fixtures/creditcards.yml +37 -0
- data/test/fixtures/customer.xml +1 -0
- data/test/fixtures/customer.yml +22 -0
- data/test/fixtures/operation.xml +1 -0
- data/test/fixtures/operation.yml +23 -0
- data/test/fixtures/request_rewritten.xml +1 -0
- data/test/fixtures/response.xml +9 -0
- data/test/fixtures/response_3d.xml +40 -0
- data/test/fixtures/root.xml +1 -0
- data/test/fixtures/xpay_defaults.yml +21 -0
- data/test/functional/payment_functional_test.rb +84 -0
- data/test/test_helper.rb +46 -0
- data/test/xpay/core/creditcard_test.rb +28 -0
- data/test/xpay/core/customer_test.rb +63 -0
- data/test/xpay/core/operation_test.rb +45 -0
- data/test/xpay/payment_test.rb +105 -0
- data/test/xpay_test.rb +41 -0
- data/xpay.gemspec +23 -0
- metadata +193 -0
@@ -0,0 +1,58 @@
|
|
1
|
+
module Xpay
|
2
|
+
|
3
|
+
# The following attribute is required for each operation:
|
4
|
+
# amount -> supplied either as String or Integer, must be in Base i.e.: 10.99 becomes 1099
|
5
|
+
#
|
6
|
+
# The following attributes are taken from the default config and can be overridden here for this request only:
|
7
|
+
# auth_type: defaults to the module default. Options are: AUTH, ST3DCARDQUERY, AUTHREVERSAL,REFUND,REFUNDREVERSAL, SETTLEMENT
|
8
|
+
# currency: defaults to module default. Override with approved currencies
|
9
|
+
# settlement day:
|
10
|
+
# callback_url: Specify the callback url for the callback from the 3D secure server. (Will be the bank that issued the card usually)
|
11
|
+
# site_reference and site_alias: are usually the same. Override the default setting for this request
|
12
|
+
# merchant_name: same as above
|
13
|
+
#
|
14
|
+
# The following attributes are entirely optional
|
15
|
+
# order_reference: Your internal order reference
|
16
|
+
# order_info: Additional info about this order/transaction
|
17
|
+
|
18
|
+
class Operation
|
19
|
+
|
20
|
+
attr_accessor :auth_type, :currency, :settlement_day, :callback_url, :site_reference, :site_alias, :merchant_name,
|
21
|
+
:order_reference, :order_info
|
22
|
+
|
23
|
+
def initialize(options={})
|
24
|
+
if !options.nil? && options.is_a?(Hash)
|
25
|
+
options.each do |key, value|
|
26
|
+
self.send("#{key}=", value) if self.respond_to? key
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def add_to_xml(doc)
|
32
|
+
req = REXML::XPath.first(doc, "//Request")
|
33
|
+
req.attributes["Type"] = self.auth_type if self.auth_type
|
34
|
+
REXML::XPath.first(doc, "//SiteReference").text = self.site_reference if self.site_reference
|
35
|
+
ops = REXML::XPath.first(doc, "//Operation")
|
36
|
+
(ops.elements["Amount"] || ops.add_element("Amount")).text = self.amount if self.amount
|
37
|
+
(ops.elements["Currency"] || ops.add_element("Currency")).text = self.currency if self.currency
|
38
|
+
(ops.elements["MerchantName"] || ops.add_element("MerchantName")).text = self.merchant_name if self.merchant_name
|
39
|
+
(ops.elements["TermUrl"] || ops.add_element("TermUrl")).text = self.callback_url if self.callback_url
|
40
|
+
if (self.order_reference || self.order_info)
|
41
|
+
req.delete_element("Order")
|
42
|
+
order = req.add_element("Order")
|
43
|
+
order.add_element("OrderReference").add_text(self.order_reference) if self.order_reference
|
44
|
+
order.add_element("OrderInformation").add_text(self.order_info) if self.order_info
|
45
|
+
end
|
46
|
+
root = doc.root
|
47
|
+
(root.elements["Certificate"] || root.add_element("Certificate")).text = self.site_alias if self.site_alias
|
48
|
+
end
|
49
|
+
|
50
|
+
def amount=(new_val)
|
51
|
+
@amount = new_val.to_s
|
52
|
+
end
|
53
|
+
|
54
|
+
def amount
|
55
|
+
@amount
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/lib/xpay/payment.rb
ADDED
@@ -0,0 +1,209 @@
|
|
1
|
+
module Xpay
|
2
|
+
|
3
|
+
# Payment Class handles all payment transaction AUTH, ST3DCARDQUERY and ST3DAUTH, also repeat transactions with ParentTransactionReference
|
4
|
+
# instantiated with p = Xpay::Payment.new(options)
|
5
|
+
# options is a Hash of the form keys creditcard, customer and operation
|
6
|
+
# there are several different options:
|
7
|
+
#
|
8
|
+
# Option 1: pass as hash options = {:creditcard => {}, :customer => {}, :operation => {}}
|
9
|
+
# in this case if the hash key is present and new CreditCard, Customer and Operation instance will be created from each hash and assigned to the class attributes
|
10
|
+
#
|
11
|
+
# Option 2: pass as Class instances of Xpay::CreditCard, Xpay::Customer and Xpay::Operation
|
12
|
+
# simply assigns it to class attributes
|
13
|
+
#
|
14
|
+
# Option 3: create with emtpy hash and use attribute accessors
|
15
|
+
# both as class and hash are possible
|
16
|
+
#
|
17
|
+
# It is not necessary to use the inbuilt classes Xpay::CreditCard, Xpay::Customer and Xpay::Operation,
|
18
|
+
# you can use your own classes (for example if you have an active_record CreditCard class.
|
19
|
+
# In this case your class(es) needs to implement a .add_to_xml method (best to copy the code from the gem classes)
|
20
|
+
#
|
21
|
+
# After initalization call the .make_payment method to process the payment
|
22
|
+
# return codes are as follows:
|
23
|
+
|
24
|
+
|
25
|
+
class Payment < Transaction
|
26
|
+
attr_reader :creditcard, :customer, :operation
|
27
|
+
|
28
|
+
def initialize(options={})
|
29
|
+
@request_xml = REXML::Document.new(Xpay.root_to_s)
|
30
|
+
self.creditcard = options[:creditcard] #.is_a?(Hash) ? Xpay::CreditCard.new(options[:creditcard]) : options[:creditcard]
|
31
|
+
self.customer = options[:customer].is_a?(Hash) ? Xpay::Customer.new(options[:customer]) : options[:customer]
|
32
|
+
self.operation = options[:operation].is_a?(Hash) ? Xpay::Operation.new(options[:operation]) : options[:operation]
|
33
|
+
create_from_xml(options[:xml], options[:pares] || nil) if options[:xml]
|
34
|
+
create_request
|
35
|
+
end
|
36
|
+
|
37
|
+
def creditcard=(v)
|
38
|
+
@creditcard = v.is_a?(Hash) ? Xpay::CreditCard.new(v) : v
|
39
|
+
create_request
|
40
|
+
end
|
41
|
+
|
42
|
+
def customer=(v)
|
43
|
+
@customer = v.is_a?(Hash) ? Xpay::Customer.new(v) : v
|
44
|
+
create_request
|
45
|
+
end
|
46
|
+
|
47
|
+
def operation=(v)
|
48
|
+
@operation = v.is_a?(Hash) ? Xpay::Operation.new(v) : v
|
49
|
+
create_request
|
50
|
+
end
|
51
|
+
|
52
|
+
# the make_payment method is where all the action is happening
|
53
|
+
# call it after you have initalized the Xpay::Payment class
|
54
|
+
# the following returns are possible:
|
55
|
+
#
|
56
|
+
# -1 a 3D Secure Authorisation is required, query your payment instance e.g. p.three_secure
|
57
|
+
# this will return a hash with all the necessary information to process the request further
|
58
|
+
# TODO provide further documentation for three_secure response block
|
59
|
+
#
|
60
|
+
# 0 Error in processing settlement request,
|
61
|
+
# query your instance e.g. p.response_block for further information
|
62
|
+
#
|
63
|
+
# 1 Settlement request approved,
|
64
|
+
# query your instance e.g. p.response_block for further information
|
65
|
+
#
|
66
|
+
# 2 Settlement request declined,
|
67
|
+
# query your instance e.g. p.response_block for further information
|
68
|
+
|
69
|
+
def make_payment
|
70
|
+
@response_xml = self.process()
|
71
|
+
if request_method=="ST3DCARDQUERY"
|
72
|
+
# In case the request was a ST3DCARDQUERY (the default case) the further processing depends on the respones. If it was an AUTH request than all is done and the response_xml gets processed
|
73
|
+
@response_xml = self.process() if response_code==0 # try once more if the response code is ZERO in ST3DCARDQUERY (According to securtrading tech support)
|
74
|
+
case response_code
|
75
|
+
when 1 # one means -> 3D AUTH required
|
76
|
+
rewrite_request_block() # Rewrite the request block with information from the response, deleting unused items
|
77
|
+
|
78
|
+
# If the card is enrolled in the scheme a redirect to a 3D Secure server is necessary, for this we need to store the request_xml in the database to be retrieved after the callback from the 3D secure Server and used to initialize a new payment object
|
79
|
+
# otherwise, if the card is not enrolled we just do a 3D AUTH straight away
|
80
|
+
if REXML::XPath.first(@response_xml, "//Enrolled").text == "Y"
|
81
|
+
rt = -1
|
82
|
+
else
|
83
|
+
# The Card is not enrolled and we do a 3D Auth request without going through a 3D Secure Server
|
84
|
+
# The PaRes element is required but empty as we did not go through a 3D Secure Server
|
85
|
+
threedsecure = REXML::XPath.first(@request_xml, "//ThreeDSecure")
|
86
|
+
pares = threedsecure.add_element("PaRes")
|
87
|
+
pares.text = ""
|
88
|
+
@response_xml = self.process()
|
89
|
+
rt = REXML::XPath.first(@response_xml, "//Result").text.to_i
|
90
|
+
end
|
91
|
+
when 2 # TWO -> do a normal AUTH request
|
92
|
+
rewrite_request_block("AUTH") # Rewrite the request block as AUTH request with information from the response, deleting unused items
|
93
|
+
@response_xml = self.process()
|
94
|
+
rt = REXML::XPath.first(@response_xml, "//Result").text.to_i
|
95
|
+
else # ALL other cases, payment declined
|
96
|
+
rt = REXML::XPath.first(@response_xml, "//Result").text.to_i
|
97
|
+
end
|
98
|
+
else
|
99
|
+
rt = REXML::XPath.first(@response_xml, "//Result").text.to_i
|
100
|
+
end
|
101
|
+
return rt
|
102
|
+
end
|
103
|
+
|
104
|
+
# The response_block is a hash and can have one of several values:
|
105
|
+
# the follwing values are always present after a transaction and can be queried to gain further details of the transaction:
|
106
|
+
# * result_code:
|
107
|
+
# 0 for failure, check error_code for further details
|
108
|
+
# 1 transaction was succesful
|
109
|
+
# 2 transaction was denied
|
110
|
+
# * security_response_code
|
111
|
+
# * security_response_postcode
|
112
|
+
# * transaction_reference
|
113
|
+
# * transactionverifier
|
114
|
+
# * transaction_time
|
115
|
+
# * auth_code
|
116
|
+
# * settlement_status
|
117
|
+
# * error_code
|
118
|
+
def response_block
|
119
|
+
create_response_block
|
120
|
+
end
|
121
|
+
|
122
|
+
def three_secure
|
123
|
+
create_three_secure
|
124
|
+
end
|
125
|
+
|
126
|
+
private
|
127
|
+
def create_request
|
128
|
+
self.creditcard.add_to_xml(@request_xml) if self.creditcard.respond_to?(:add_to_xml)
|
129
|
+
self.customer.add_to_xml(@request_xml) if self.customer.respond_to?(:add_to_xml)
|
130
|
+
self.operation.add_to_xml(@request_xml) if self.operation.respond_to?(:add_to_xml)
|
131
|
+
end
|
132
|
+
|
133
|
+
#TODO function to create classes (Customer, CreditCard and Operation) from xml document
|
134
|
+
def create_from_xml(xml, pares)
|
135
|
+
raise PaResMissing.new "(2500) PaRes argument can not be omitted." if pares.nil?
|
136
|
+
@request_xml = REXML::Document.new xml
|
137
|
+
REXML::XPath.first(@request_xml, "//ThreeDSecure").add_element("PaRes").text=pares
|
138
|
+
end
|
139
|
+
|
140
|
+
def create_response_block
|
141
|
+
@response_xml.is_a?(REXML::Document) ?
|
142
|
+
{
|
143
|
+
:result_code => (REXML::XPath.first(@response_xml, "//Result").text.to_i rescue nil),
|
144
|
+
:security_response_code => (REXML::XPath.first(@response_xml, "//SecurityResponseSecurityCode").text.to_i rescue nil),
|
145
|
+
:security_response_postcode => (REXML::XPath.first(@response_xml, "//SecurityResponsePostCode").text.to_i rescue nil),
|
146
|
+
:security_response_address => (REXML::XPath.first(@response_xml, "//SecurityResponseAddress").text.to_i rescue nil),
|
147
|
+
:transaction_reference => (REXML::XPath.first(@response_xml, "//TransactionReference").text rescue nil),
|
148
|
+
:transactionverifier => (REXML::XPath.first(@response_xml, "//TransactionVerifier").text rescue nil),
|
149
|
+
:transaction_time => (REXML::XPath.first(@response_xml, "//TransactionCompletedTimestamp").text rescue nil),
|
150
|
+
:auth_code => (REXML::XPath.first(@response_xml, "//AuthCode").text rescue nil),
|
151
|
+
:settlement_status => (REXML::XPath.first(@response_xml, "//SettleStatus").text.to_i rescue nil),
|
152
|
+
:error_code => (REXML::XPath.first(@response_xml, "//Message").text rescue nil)
|
153
|
+
} : {}
|
154
|
+
end
|
155
|
+
|
156
|
+
def create_three_secure
|
157
|
+
@response_xml.is_a?(REXML::Document) ?
|
158
|
+
{
|
159
|
+
:md => (REXML::XPath.first(@response_xml, "//MD").text rescue nil),
|
160
|
+
:pareq => (REXML::XPath.first(@response_xml, "//PaReq").text rescue nil),
|
161
|
+
:termurl => (REXML::XPath.first(@response_xml, "//TermUrl").text rescue nil),
|
162
|
+
:acsurl => (REXML::XPath.first(@response_xml, "//AcsUrl").text rescue nil),
|
163
|
+
:html => (REXML::XPath.first(@response_xml, "//Html").text rescue nil),
|
164
|
+
:request_xml => (@request_xml.to_s rescue nil)
|
165
|
+
} : {}
|
166
|
+
end
|
167
|
+
|
168
|
+
# Rewrites the request according to the response coming from SecureTrading according to the required auth_type
|
169
|
+
# This only applies if the inital request was a ST3DCARDQUERY
|
170
|
+
# It deletes elements which are not needed for the subsequent request and
|
171
|
+
# adds the required additional information if an ST3DAUTH is needed
|
172
|
+
def rewrite_request_block(auth_type="ST3DAUTH")
|
173
|
+
|
174
|
+
# set the required AUTH type
|
175
|
+
REXML::XPath.first(@request_xml, "//Request").attributes["Type"] = auth_type
|
176
|
+
|
177
|
+
# delete term url and merchant name
|
178
|
+
op = REXML::XPath.first(@request_xml, "//Operation")
|
179
|
+
op.delete_element "TermUrl"
|
180
|
+
op.delete_element "MerchantName"
|
181
|
+
|
182
|
+
# delete accept and user agent in customer info
|
183
|
+
customer_info = REXML::XPath.first(@request_xml, "//CustomerInfo")
|
184
|
+
customer_info.delete_element "//Accept"
|
185
|
+
customer_info.delete_element "//UserAgent"
|
186
|
+
|
187
|
+
# delete credit card details and add TransactionVerifier and TransactionReference from response xml
|
188
|
+
# CC details are not needed anymore as verifier and reference are sufficient
|
189
|
+
cc_details = REXML::XPath.first(@request_xml, "//CreditCard")
|
190
|
+
cc_details.delete_element "//Number"
|
191
|
+
cc_details.delete_element "//Type"
|
192
|
+
trans_ver = cc_details.add_element("TransactionVerifier")
|
193
|
+
trans_ver.text = REXML::XPath.first(@response_xml, "//TransactionVerifier").text
|
194
|
+
trans_ref = cc_details.add_element("ParentTransactionReference")
|
195
|
+
trans_ref.text = REXML::XPath.first(@response_xml, "//TransactionReference").text
|
196
|
+
|
197
|
+
# unless it is an AUTH request, add additional required info for a 3DAUTH request
|
198
|
+
unless auth_type == "AUTH"
|
199
|
+
pm_method = REXML::XPath.first(@request_xml, "//PaymentMethod")
|
200
|
+
threedsecure = pm_method.add_element("ThreeDSecure")
|
201
|
+
enrolled = threedsecure.add_element("Enrolled")
|
202
|
+
enrolled.text = REXML::XPath.first(@response_xml, "//Enrolled").text
|
203
|
+
md = threedsecure.add_element("MD")
|
204
|
+
md.text = REXML::XPath.first(@response_xml, "//MD").text rescue ""
|
205
|
+
end
|
206
|
+
true
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Xpay
|
2
|
+
require 'socket'
|
3
|
+
|
4
|
+
# The transaction class is the parent class of all Transactions be it Payment, Refund or Paypal etc.
|
5
|
+
# it provides underlying methods which all transactions have in common
|
6
|
+
# It should not be instantiated by itself
|
7
|
+
|
8
|
+
class Transaction
|
9
|
+
|
10
|
+
attr_accessor :request_xml
|
11
|
+
attr_reader :three_secure, :response_xml, :response_block
|
12
|
+
|
13
|
+
def process()
|
14
|
+
a = TCPSocket.open("localhost", Xpay.config.port)
|
15
|
+
a.write(self.request_xml.to_s + "\n")
|
16
|
+
res = a.read()
|
17
|
+
a.close
|
18
|
+
# create an xml document, use everything from the start of <ResponseBlock to the end, discard header and status etc and return it
|
19
|
+
REXML::Document.new res[res.index("<ResponseBlock"), res.length]
|
20
|
+
end
|
21
|
+
|
22
|
+
def request_method
|
23
|
+
@request_method ||= REXML::XPath.first(@request_xml, "//Request").attributes["Type"]
|
24
|
+
end
|
25
|
+
|
26
|
+
def response_code
|
27
|
+
@response_code ||= REXML::XPath.first(@response_xml, "//Result").text.to_i rescue -1
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
def response_xml=(new_val)
|
32
|
+
@response_xml = new_val if new_val.is_a?(REXML::Document)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/xpay/version.rb
ADDED
data/rails/init.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# config/xpay.yml
|
2
|
+
base: &base
|
3
|
+
port: 5000
|
4
|
+
merchant_name: Outlet Residential
|
5
|
+
|
6
|
+
development:
|
7
|
+
<<: *base
|
8
|
+
alias: testoutlet12091
|
9
|
+
site_reference: testoutlet12091
|
10
|
+
version: "3.52"
|
11
|
+
port: 6000
|
12
|
+
callback_url: "http://127.0.0.1/callback"
|
13
|
+
default_query: "AUTH"
|
14
|
+
settlement_day: "2"
|
15
|
+
default_currency: "USD"
|
16
|
+
|
17
|
+
test:
|
18
|
+
<<: *base
|
19
|
+
alias: testoutlet12091
|
20
|
+
site_reference: testoutlet12091
|
21
|
+
|
22
|
+
production:
|
23
|
+
<<: *base
|
24
|
+
alias: accommodationoutlet2538
|
25
|
+
site_reference: accommodationoutlet2538
|
@@ -0,0 +1,37 @@
|
|
1
|
+
base: &base
|
2
|
+
security_code: 123
|
3
|
+
valid_until: <%= Date.today.advance(:months => 3).strftime("%m/%y") %>
|
4
|
+
|
5
|
+
class_test:
|
6
|
+
<<: *base
|
7
|
+
card_type: Visa
|
8
|
+
number: 4111111111111111
|
9
|
+
security_code: 123
|
10
|
+
valid_from: <%= Date.today.advance(:months => -5).strftime("%m/%y") %>
|
11
|
+
issue: "1"
|
12
|
+
|
13
|
+
|
14
|
+
visa_no3d_auth:
|
15
|
+
<<: *base
|
16
|
+
card_type: Visa
|
17
|
+
number: 4111111111111111
|
18
|
+
|
19
|
+
visa_no3d_decl:
|
20
|
+
<<: *base
|
21
|
+
card_type: Visa
|
22
|
+
number: 4242424242424242
|
23
|
+
|
24
|
+
visa_3d_auth:
|
25
|
+
<<: *base
|
26
|
+
card_type: Visa
|
27
|
+
number: 4111111111111160
|
28
|
+
|
29
|
+
master_no3d_auth:
|
30
|
+
<<: *base
|
31
|
+
card_type: Mastercard
|
32
|
+
number: 5111111111111118
|
33
|
+
|
34
|
+
master_no3d_decl:
|
35
|
+
<<: *base
|
36
|
+
card_type: Mastercard
|
37
|
+
number: 5111111111111142
|
@@ -0,0 +1 @@
|
|
1
|
+
<?xml version='1.0' encoding='ISO-8859-1'?><RequestBlock Version='3.51'><Request Type='ST3DCARDQUERY'><Operation><SiteReference>site12345</SiteReference><MerchantName>CompanyName</MerchantName><TermUrl>http://localhost/gateway_callback</TermUrl></Operation><CustomerInfo><Postal><Name>JOE BLOGGS<NamePrefix>MR</NamePrefix><FirstName>Joe</FirstName><MiddleName>X</MiddleName><LastName>Bloggs</LastName><NameSuffix>PhD</NameSuffix></Name><Company>NotInventedHere.com</Company><Street>tonowhere crescent</Street><City>beyond the rainbow on stale bread</City><StateProv>East-West Swampshire</StateProv><PostalCode>X01 Z10</PostalCode><CountryCode>GB</CountryCode></Postal><Telecom><Phone>07950 843 363</Phone></Telecom><Online><Email>joe.x.bloggs@notinventedhere.com</Email></Online><Accept>text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8</Accept><UserAgent>Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; GTB5; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506; InfoPath.1; .NET4.0C; AskTbGLSV5/5.8.0.12304)</UserAgent></CustomerInfo></Request><Certificate>site12345</Certificate></RequestBlock>
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class_test:
|
2
|
+
title: MR
|
3
|
+
fullname: JOE BLOGGS
|
4
|
+
firstname: Joe
|
5
|
+
lastname: Bloggs
|
6
|
+
middlename: X
|
7
|
+
namesuffix: PhD
|
8
|
+
companyname: NotInventedHere.com
|
9
|
+
street: tonowhere crescent
|
10
|
+
city: beyond the rainbow on stale bread
|
11
|
+
stateprovince: East-West Swampshire
|
12
|
+
postcode: X01 Z10
|
13
|
+
countrycode: GB
|
14
|
+
phone: 07950 843 363
|
15
|
+
email: joe.x.bloggs@notinventedhere.com
|
16
|
+
http_accept: "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
|
17
|
+
user_agent: "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; GTB5; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506; InfoPath.1; .NET4.0C; AskTbGLSV5/5.8.0.12304)"
|
18
|
+
|
19
|
+
test_1:
|
20
|
+
fullname: V Pacher
|
21
|
+
http_accept: "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
|
22
|
+
user_agent: "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; GTB5; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506; InfoPath.1; .NET4.0C; AskTbGLSV5/5.8.0.12304)"
|
@@ -0,0 +1 @@
|
|
1
|
+
<?xml version='1.0' encoding='ISO-8859-1'?><RequestBlock Version='3.51'><Request Type='AUTH'><Operation><SiteReference>site56987</SiteReference><MerchantName>TestMerchant</MerchantName><TermUrl>https://localhost/3dcallback</TermUrl><Amount>1000</Amount><Currency>USD</Currency></Operation><Order><OrderReference>TestOrder1245</OrderReference><OrderInformation>TestOrderInfo</OrderInformation></Order></Request><Certificate>site56987</Certificate></RequestBlock>
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class_test:
|
2
|
+
auth_type: AUTH
|
3
|
+
currency: USD
|
4
|
+
amount: "1000"
|
5
|
+
settlement_day: "3"
|
6
|
+
callback_url: "https://localhost/3dcallback"
|
7
|
+
site_reference: site56987
|
8
|
+
site_alias: site56987
|
9
|
+
merchant_name: TestMerchant
|
10
|
+
order_reference: TestOrder1245
|
11
|
+
order_info: TestOrderInfo
|
12
|
+
port: 7000
|
13
|
+
|
14
|
+
test_1:
|
15
|
+
auth_type: ST3DCARDQUERY
|
16
|
+
currency: GBP
|
17
|
+
amount: "1000"
|
18
|
+
settlement_day: "1"
|
19
|
+
site_reference: testoutlet12092
|
20
|
+
site_alias: testoutlet12092
|
21
|
+
callback_url: "https://localhost/3dcallback"
|
22
|
+
merchant_name: Outlet Residential
|
23
|
+
order_reference: TestOrder1245
|
@@ -0,0 +1 @@
|
|
1
|
+
<?xml version='1.0' encoding='ISO-8859-1'?><RequestBlock Version='3.51'><Request Type='ST3DAUTH'><Operation><SiteReference>site56987</SiteReference><Amount>1000</Amount><Currency>USD</Currency></Operation><PaymentMethod><CreditCard><StartDate>05/10</StartDate><ExpiryDate>01/11</ExpiryDate><SecurityCode>123</SecurityCode><Issue>1</Issue><TransactionVerifier>ArOH5um+qGhwLbuobJ5mdgzTr1qclm1j/qyG+VGDe9QSslGFXtwFA2A6jvM+qgUuZ0lLQPvJ82U1SkLOhm32dPRABlh0EkyrvKamrsDDRcsFZhWQLmS+yE0+keSaBq8C537NQAXIYcCYVvoOVKhDwdW4hZVfOtKFND+QxR2p89rw=</TransactionVerifier><ParentTransactionReference>17-9-1909368</ParentTransactionReference></CreditCard><ThreeDSecure><Enrolled>Y</Enrolled><MD>MTI4ODAwNjYzNi41MjAuMTc2MzczMzc3MDExMjg4MDA2NjM2LjUyMC4xNzYzNzMzNzcwMTEyODgwMDY2MzYuNTIwLjE3NjM3MzM3NzAxMTI4ODAwNjYzNi41MjAuMTc2MzczMzc3MDExMjg4MDA2NjM2LjUyMC4xNzYzNzMzNzcwMTEyODgwMDY2MzYuNTIwLjE3NjM3MzM3NzAxMTI4ODAwNjYzNi41MjAuMTc2MzczMzc3MDExMjg4MDA2NjM2LjUyMC4xNzYzNzMzNzcwMTEyODgwMDY2MzYuNTIwLjE3NjM3MzM3NzAxMTI4ODAwNjYzNi41MjAuMTc2MzczMzc3MDE=</MD></ThreeDSecure></PaymentMethod><CustomerInfo><Postal><Name>JOE BLOGGS<NamePrefix>MR</NamePrefix><FirstName>Joe</FirstName><MiddleName>X</MiddleName><LastName>Bloggs</LastName><NameSuffix>PhD</NameSuffix></Name><Company>NotInventedHere.com</Company><Street>tonowhere crescent</Street><City>beyond the rainbow on stale bread</City><StateProv>East-West Swampshire</StateProv><PostalCode>X01 Z10</PostalCode><CountryCode>GB</CountryCode></Postal><Telecom><Phone>07950 843 363</Phone></Telecom><Online><Email>joe.x.bloggs@notinventedhere.com</Email></Online></CustomerInfo><Order><OrderReference>TestOrder1245</OrderReference><OrderInformation>TestOrderInfo</OrderInformation></Order></Request><Certificate>site56987</Certificate></RequestBlock>
|
@@ -0,0 +1,9 @@
|
|
1
|
+
<ResponseBlock Live='FALSE' Version='3.51'>
|
2
|
+
<Response Type='ST3DCARDQUERY'>
|
3
|
+
<OperationResponse>
|
4
|
+
<Message>(3100) Invalid ExpiryDate</Message>
|
5
|
+
<TransactionReference>17-9-1908322</TransactionReference>
|
6
|
+
<Result>0</Result>
|
7
|
+
</OperationResponse>
|
8
|
+
</Response>
|
9
|
+
</ResponseBlock>
|