breadmachine 0.0.0 → 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +48 -4
- data/lib/breadmachine/dto/card.rb +23 -9
- data/lib/breadmachine/dto/customer_info.rb +19 -5
- data/lib/breadmachine/dto/order_info.rb +18 -5
- data/lib/breadmachine/extensions/string.rb +11 -0
- data/lib/breadmachine/extensions.rb +2 -1
- data/lib/breadmachine/secure_trading/auth_request.rb +4 -2
- data/lib/breadmachine/secure_trading/auth_reversal_request.rb +3 -5
- data/lib/breadmachine/secure_trading/auth_reversal_response.rb +6 -1
- data/lib/breadmachine/secure_trading/card_xml.rb +13 -9
- data/lib/breadmachine/secure_trading/payment_methods.rb +18 -6
- data/lib/breadmachine/secure_trading/st_3d_auth_request.rb +32 -10
- data/lib/breadmachine/secure_trading/st_3d_auth_response.rb +20 -11
- data/lib/breadmachine/secure_trading/st_3d_card_query_request.rb +28 -9
- data/lib/breadmachine/secure_trading/st_3d_card_query_response.rb +122 -23
- data/lib/breadmachine/secure_trading/xpay.rb +121 -10
- data/lib/breadmachine/secure_trading/xpay_response.rb +29 -0
- data/lib/breadmachine/secure_trading/xpay_socket.rb +5 -1
- data/lib/breadmachine/secure_trading.rb +4 -2
- data/lib/breadmachine.rb +7 -2
- data/spec/secure_trading/auth_request_spec.rb +12 -7
- data/spec/secure_trading/card_xml_spec.rb +43 -17
- data/spec/secure_trading/order_info_xml_spec.rb +2 -2
- data/spec/secure_trading/st_3d_auth_request_spec.rb +12 -7
- data/spec/secure_trading/st_3d_card_query_request_spec.rb +19 -8
- data/spec/secure_trading/st_3d_card_query_response_spec.rb +87 -30
- data/spec/secure_trading/st_auth_reversal_request_spec.rb +42 -0
- data/spec/secure_trading/xpay_response_spec.rb +26 -0
- data/spec/secure_trading/xpay_socket_spec.rb +15 -2
- data/spec/secure_trading/xpay_spec.rb +19 -2
- metadata +35 -3
- data/spec/secure_trading/st_auth_request_spec.rb +0 -0
@@ -2,24 +2,135 @@ module BreadMachine
|
|
2
2
|
module SecureTrading
|
3
3
|
|
4
4
|
class XPay
|
5
|
+
|
6
|
+
# A class method which wraps the individual request block with the
|
7
|
+
# necessary xml for the XPay gateway. Once the request is wrapped, this
|
8
|
+
# method writes it to the Xpay client and returns the response.
|
9
|
+
#
|
5
10
|
def self.exchange(request)
|
6
|
-
|
11
|
+
xpay = self.new
|
12
|
+
xpay.exchange(request)
|
13
|
+
end
|
14
|
+
|
15
|
+
def exchange(request, retries = 3)
|
16
|
+
request_xml = generate_xml(request)
|
17
|
+
begin
|
18
|
+
response_xml = exchange_with_xpay_client(request_xml)
|
19
|
+
response = request.response(response_xml)
|
20
|
+
handle_errors(response)
|
21
|
+
return response
|
22
|
+
rescue BreadMachine::GatewayConnectionError
|
23
|
+
retry unless (retries -= 1) == 0
|
24
|
+
raise
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
protected
|
29
|
+
|
30
|
+
def generate_xml(request)
|
7
31
|
xml = Builder::XmlMarkup.new(:indent => 2)
|
32
|
+
xml.instruct!
|
8
33
|
xml.RequestBlock('Version' => '3.51') do |request_block|
|
9
34
|
request_block << request.to_xml
|
10
35
|
xml.Certificate BreadMachine::SecureTrading::configuration.site_reference
|
11
36
|
end
|
12
|
-
|
13
|
-
|
14
|
-
|
37
|
+
return xml.to_s
|
38
|
+
end
|
39
|
+
|
40
|
+
def exchange_with_xpay_client(request_xml)
|
15
41
|
XPaySocket.open("localhost", 5000) do |socket|
|
16
|
-
socket.write
|
17
|
-
|
42
|
+
socket.write request_xml
|
43
|
+
socket.read
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# Error codes from Xpay API documentation
|
48
|
+
#
|
49
|
+
# 100 Timeout reading from socket:
|
50
|
+
# ST Xpay did not receive the full XML in the given time from your
|
51
|
+
# application.
|
52
|
+
#
|
53
|
+
# 101 Error reading from socket:
|
54
|
+
# ST Xpay did not receive a correct connection request from your
|
55
|
+
# application.
|
56
|
+
#
|
57
|
+
# 1000 Failed to connect to a payment gateway:
|
58
|
+
# The ST Xpay client was unable to find a payment gateway.
|
59
|
+
#
|
60
|
+
# 1100 Failed to receive from payment gateway:
|
61
|
+
# ST Xpay did not receive any response from the payment gateway.
|
62
|
+
#
|
63
|
+
# 2100 Missing SiteReference or Certificate tag:
|
64
|
+
# The XML ST Xpay received was missing the site reference and/or
|
65
|
+
# your secure ST Xpay certificate.
|
66
|
+
#
|
67
|
+
# 2500 [Various messages - One of the fields contains an invalid value]:
|
68
|
+
# The information returned contains the field name that was omitted
|
69
|
+
# from the request or contained incorrect information.
|
70
|
+
#
|
71
|
+
# 3000 Gateway error:
|
72
|
+
# A SecureTrading payment gateway failed to receive a full ST Xpay
|
73
|
+
# request.
|
74
|
+
#
|
75
|
+
# 3010 Transaction Not Received Successfully:
|
76
|
+
# A SecureTrading payment gateway obtained the request but failed to
|
77
|
+
# decrypt it.
|
78
|
+
#
|
79
|
+
# 3100 Error with transaction details:
|
80
|
+
# The data retrieved was incorrectly defined.
|
81
|
+
#
|
82
|
+
# 3100 Error in XML: Unknown Transaction Type:
|
83
|
+
# The Request Type attribute was incorrect.
|
84
|
+
#
|
85
|
+
# 3100 Error Parsing XML (invalid site reference for this certificate):
|
86
|
+
# The certificate included in the XML request is invalid for the
|
87
|
+
# SecureTrading sitereference included in the XML.
|
88
|
+
#
|
89
|
+
# 3100 Gateway Connection Error:
|
90
|
+
# The data obtained by ST Xpay was incorrect.
|
91
|
+
#
|
92
|
+
# 3100 Error parsing XML: [+reason]
|
93
|
+
# The gateway obtained invalid XML.
|
94
|
+
#
|
95
|
+
# 3100 Invalid Merchant Configuration:
|
96
|
+
# Merchant data on the gateway is inconsistent with merchant
|
97
|
+
# information in the XML (For example. invalid currency,
|
98
|
+
# payment type, etc).
|
99
|
+
#
|
100
|
+
# 3330 Transaction storage failure. Please try again later:
|
101
|
+
# Gateway failed to store the transaction details before
|
102
|
+
# authorisation.
|
103
|
+
#
|
104
|
+
# 3350 Transaction acceptance failure. Please try again later:
|
105
|
+
# Gateway failed to update the transaction details after performing
|
106
|
+
# the authorisation.
|
107
|
+
#
|
108
|
+
# 5000 Transport Error:
|
109
|
+
# Failed to connect to acquiring bank or the acquiring bank did not
|
110
|
+
# respond.
|
111
|
+
#
|
112
|
+
# 5100 Missing TransactionReference:
|
113
|
+
# The transaction cannot be found in the database.
|
114
|
+
#
|
115
|
+
# 10500 Various Message:
|
116
|
+
# Xpay4 was unable to process your request.
|
117
|
+
#
|
118
|
+
def handle_errors(response)
|
119
|
+
if response.error?
|
120
|
+
message = response.message
|
121
|
+
case message.match(/\((\d+)\)/)[1].to_i
|
122
|
+
when 100, 101, 1000, 1100, 3000, 3010, 3330, 3350, 5000:
|
123
|
+
raise BreadMachine::GatewayConnectionError.new(message)
|
124
|
+
when 2100, 3100:
|
125
|
+
raise BreadMachine::MerchantConfigurationError.new(message)
|
126
|
+
when 2500, 5100, 10500:
|
127
|
+
raise BreadMachine::MerchantRequestError.new(message)
|
128
|
+
end
|
18
129
|
end
|
19
|
-
|
20
|
-
request.response(response_xml)
|
21
130
|
end
|
131
|
+
|
22
132
|
end
|
23
|
-
|
133
|
+
|
24
134
|
end
|
25
|
-
end
|
135
|
+
end
|
136
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module BreadMachine
|
2
|
+
module SecureTrading
|
3
|
+
|
4
|
+
class XpayResponse
|
5
|
+
|
6
|
+
def initialize(xml)
|
7
|
+
@xml = Nokogiri::XML.parse(xml)
|
8
|
+
end
|
9
|
+
|
10
|
+
# Checks whether there has been an error somewhere in the chain of servers
|
11
|
+
# which are processing your request (for example, if Visa's server cacked,
|
12
|
+
# or XPay had an internal error, this would come back as true).
|
13
|
+
#
|
14
|
+
def error?
|
15
|
+
result == '0'
|
16
|
+
end
|
17
|
+
|
18
|
+
def result
|
19
|
+
@xml.xpath('//OperationResponse/Result').text
|
20
|
+
end
|
21
|
+
|
22
|
+
def message
|
23
|
+
@xml.xpath('//OperationResponse/Message').text
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
@@ -7,6 +7,7 @@ module BreadMachine
|
|
7
7
|
|
8
8
|
autoload :XPay, 'breadmachine/secure_trading/xpay'
|
9
9
|
autoload :XPaySocket, 'breadmachine/secure_trading/xpay_socket'
|
10
|
+
autoload :XpayResponse, 'breadmachine/secure_trading/xpay_response'
|
10
11
|
|
11
12
|
autoload :CardXml, 'breadmachine/secure_trading/card_xml'
|
12
13
|
|
@@ -21,9 +22,10 @@ module BreadMachine
|
|
21
22
|
autoload :St3dAuthRequest, 'breadmachine/secure_trading/st_3d_auth_request'
|
22
23
|
autoload :St3dAuthResponse, 'breadmachine/secure_trading/st_3d_auth_response'
|
23
24
|
|
24
|
-
autoload :AuthReversalRequest, 'breadmachine/secure_trading/auth_reversal_request'
|
25
25
|
autoload :AuthRequest, 'breadmachine/secure_trading/auth_request'
|
26
|
-
|
26
|
+
|
27
|
+
autoload :AuthReversalRequest, 'breadmachine/secure_trading/auth_reversal_request'
|
28
|
+
autoload :AuthReversalResponse, 'breadmachine/secure_trading/auth_reversal_response'
|
27
29
|
|
28
30
|
extend BreadMachine::SecureTrading::Config::ClassMethods
|
29
31
|
|
data/lib/breadmachine.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
require 'money'
|
2
2
|
require 'nokogiri'
|
3
3
|
require 'builder'
|
4
|
+
require 'activesupport'
|
4
5
|
|
5
6
|
require 'breadmachine/extensions'
|
6
|
-
|
7
7
|
require 'breadmachine/secure_trading'
|
8
8
|
|
9
9
|
module BreadMachine
|
@@ -24,4 +24,9 @@ class Builder::XmlBase
|
|
24
24
|
def <<(text)
|
25
25
|
_text(text.indent(@level * @indent))
|
26
26
|
end
|
27
|
-
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class BreadMachine::Exception < Exception; end;
|
30
|
+
class BreadMachine::GatewayConnectionError < BreadMachine::Exception; end;
|
31
|
+
class BreadMachine::MerchantConfigurationError < BreadMachine::Exception; end;
|
32
|
+
class BreadMachine::MerchantRequestError < BreadMachine::Exception; end;
|
@@ -2,16 +2,25 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
|
2
2
|
|
3
3
|
describe BreadMachine::SecureTrading::AuthRequest do
|
4
4
|
|
5
|
-
it "should
|
6
|
-
|
5
|
+
it "should ensure amount is Money of correct currency" do
|
6
|
+
BreadMachine::SecureTrading.configuration.currency = 'USD'
|
7
|
+
amount = Money.new(200_00, 'GBP')
|
8
|
+
|
9
|
+
lambda {
|
10
|
+
@request = described_class.new(amount, @card, @customer_info, @order_info, @settlement_day)
|
11
|
+
}.should raise_error ArgumentError, "Currency mismatch"
|
12
|
+
end
|
13
|
+
|
7
14
|
describe "XML generation" do
|
8
15
|
|
9
16
|
before(:each) do
|
17
|
+
BreadMachine::SecureTrading.configuration.currency = 'GBP'
|
10
18
|
@amount = Money.sterling(12_99)
|
11
19
|
@card = BreadMachine::Card.make
|
12
20
|
@customer_info = BreadMachine::CustomerInfo.make(:auth)
|
13
21
|
@order_info = BreadMachine::OrderInfo.make
|
14
|
-
@
|
22
|
+
@settlement_day = 1
|
23
|
+
@request = described_class.new(@amount, @card, @customer_info, @order_info, @settlement_day)
|
15
24
|
end
|
16
25
|
|
17
26
|
it "should set correct request type" do
|
@@ -35,10 +44,6 @@ describe BreadMachine::SecureTrading::AuthRequest do
|
|
35
44
|
end
|
36
45
|
end
|
37
46
|
|
38
|
-
it "should ensure amount is Money of correct currency" do
|
39
|
-
pending "Check that currency of amount matches currency specified in config"
|
40
|
-
end
|
41
|
-
|
42
47
|
it "should append CustomerInfo element" do
|
43
48
|
request_xml.should have_tag("Request/CustomerInfo")
|
44
49
|
end
|
@@ -1,54 +1,80 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
2
|
|
3
|
-
class TestCard
|
4
|
-
attr_accessor :issuer, :number, :expiry_date, :start_date, :issue, :security_code, :parent_transaction_reference
|
5
|
-
include BreadMachine::SecureTrading::CardXml
|
6
|
-
end
|
7
|
-
|
8
3
|
describe BreadMachine::SecureTrading::CardXml do
|
9
4
|
|
10
|
-
|
5
|
+
subject do
|
6
|
+
described_class.new(@card)
|
7
|
+
end
|
8
|
+
|
9
|
+
def xml
|
10
|
+
Nokogiri::XML::Document.parse(subject.to_xml)
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "xml representation from card" do
|
11
14
|
|
12
15
|
before(:each) do
|
13
|
-
@card =
|
16
|
+
@card = BreadMachine::Card.new
|
14
17
|
end
|
15
|
-
|
18
|
+
|
16
19
|
it "should have CreditCard root element" do
|
17
|
-
xml
|
20
|
+
xml.should have_tag('/CreditCard')
|
18
21
|
end
|
19
22
|
|
20
23
|
it "should have correct Type element" do
|
21
24
|
@card.issuer = 'Maestro'
|
22
|
-
xml
|
25
|
+
xml.should have_tag("CreditCard/Type", 'Maestro')
|
23
26
|
end
|
24
27
|
|
25
28
|
it "should have correct Number element" do
|
26
29
|
@card.number = 6759050000000005
|
27
|
-
xml
|
30
|
+
xml.should have_tag("CreditCard/Number", '6759050000000005')
|
28
31
|
end
|
29
32
|
|
30
33
|
it "should have correct ExpiryDate element" do
|
31
34
|
@card.expiry_date = '07/11'
|
32
|
-
xml
|
35
|
+
xml.should have_tag("CreditCard/ExpiryDate", '07/11')
|
33
36
|
end
|
34
37
|
|
35
38
|
it "should have correct StartDate element" do
|
36
39
|
@card.start_date = '03/08'
|
37
|
-
xml
|
40
|
+
xml.should have_tag("CreditCard/StartDate", '03/08')
|
38
41
|
end
|
39
42
|
|
40
43
|
it "should have correct Issue element" do
|
41
44
|
@card.issue = 2
|
42
|
-
xml
|
45
|
+
xml.should have_tag("CreditCard/Issue", '2')
|
43
46
|
end
|
44
47
|
|
45
48
|
it "should have correct SecurityCode element" do
|
46
49
|
@card.security_code = 789
|
47
|
-
xml
|
50
|
+
xml.should have_tag("CreditCard/SecurityCode", '789')
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should have correct ParentTransactionReference element" do
|
54
|
+
@card.transaction_reference = '13-2-9875373'
|
55
|
+
xml.should have_tag("CreditCard/ParentTransactionReference", '13-2-9875373')
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "xml representation from transaction" do
|
61
|
+
|
62
|
+
before(:each) do
|
63
|
+
@card = BreadMachine::Card.new
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should have CreditCard root element" do
|
67
|
+
xml.should have_tag('/CreditCard')
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should have correct TransactionVerifier element" do
|
71
|
+
@card.transaction_verifier = 'A_TRANSACTION_VERIFIER'
|
72
|
+
xml.should have_tag("CreditCard/TransactionVerifier", 'A_TRANSACTION_VERIFIER')
|
48
73
|
end
|
49
74
|
|
50
|
-
|
51
|
-
|
75
|
+
it "should have correct ParentTransactionReference element" do
|
76
|
+
@card.transaction_reference = 'A_TRANSACTION_REFERENCE'
|
77
|
+
xml.should have_tag("CreditCard/ParentTransactionReference", 'A_TRANSACTION_REFERENCE')
|
52
78
|
end
|
53
79
|
|
54
80
|
end
|
@@ -18,12 +18,12 @@ describe BreadMachine::SecureTrading::OrderInfoXml do
|
|
18
18
|
generated_xml.should have_tag('/Order')
|
19
19
|
end
|
20
20
|
|
21
|
-
it "should have correct
|
21
|
+
it "should have correct OrderReference" do
|
22
22
|
@order_info.order_reference = 'Order 12345'
|
23
23
|
generated_xml.should have_tag('Order/OrderReference', 'Order 12345')
|
24
24
|
end
|
25
25
|
|
26
|
-
it "should have correct
|
26
|
+
it "should have correct OrderInformation" do
|
27
27
|
@order_info.order_information = '1 Bag of Assorted Widgets'
|
28
28
|
generated_xml.should have_tag('Order/OrderInformation', '1 Bag of Assorted Widgets')
|
29
29
|
end
|
@@ -2,17 +2,26 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
|
2
2
|
|
3
3
|
describe BreadMachine::SecureTrading::St3dAuthRequest do
|
4
4
|
|
5
|
-
it "should
|
6
|
-
|
5
|
+
it "should ensure amount is Money of correct currency" do
|
6
|
+
BreadMachine::SecureTrading.configuration.currency = 'USD'
|
7
|
+
amount = Money.new(200_00, 'GBP')
|
8
|
+
|
9
|
+
lambda {
|
10
|
+
@request = described_class.new(amount, @card, @customer_info, @order_info, @three_d, @settlement_day)
|
11
|
+
}.should raise_error ArgumentError, "Currency mismatch"
|
12
|
+
end
|
13
|
+
|
7
14
|
describe "XML generation" do
|
8
15
|
|
9
16
|
before(:each) do
|
17
|
+
BreadMachine::SecureTrading.configuration.currency = 'GBP'
|
10
18
|
@amount = Money.sterling(12_99)
|
11
19
|
@card = BreadMachine::Card.make
|
12
20
|
@customer_info = BreadMachine::CustomerInfo.make(:auth)
|
13
21
|
@order_info = BreadMachine::OrderInfo.make
|
14
22
|
@three_d = BreadMachine::ThreeDSecureCredentials.make
|
15
|
-
@
|
23
|
+
@settlement_day = 1
|
24
|
+
@request = described_class.new(@amount, @card, @customer_info, @order_info, @three_d, @settlement_day)
|
16
25
|
end
|
17
26
|
|
18
27
|
it "should set correct request type" do
|
@@ -36,10 +45,6 @@ describe BreadMachine::SecureTrading::St3dAuthRequest do
|
|
36
45
|
end
|
37
46
|
end
|
38
47
|
|
39
|
-
it "should ensure amount is Money of correct currency" do
|
40
|
-
pending "Check that currency of amount matches currency specified in config"
|
41
|
-
end
|
42
|
-
|
43
48
|
it "should append CustomerInfo element" do
|
44
49
|
request_xml.should have_tag("Request/CustomerInfo")
|
45
50
|
end
|
@@ -2,11 +2,19 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
|
2
2
|
|
3
3
|
describe BreadMachine::SecureTrading::St3dCardQueryRequest do
|
4
4
|
|
5
|
-
it "should
|
5
|
+
it "should ensure amount is Money of correct currency" do
|
6
|
+
BreadMachine::SecureTrading.configuration.currency = 'USD'
|
7
|
+
amount = Money.new(200_00, 'GBP')
|
8
|
+
|
9
|
+
lambda {
|
10
|
+
@request = described_class.new(amount, @card, @customer_info, @order_info)
|
11
|
+
}.should raise_error ArgumentError, "Currency mismatch"
|
12
|
+
end
|
6
13
|
|
7
14
|
context "XML generation" do
|
8
15
|
|
9
16
|
before(:each) do
|
17
|
+
BreadMachine::SecureTrading.configuration.currency = 'GBP'
|
10
18
|
@card = BreadMachine::Card.make
|
11
19
|
@customer_info = BreadMachine::CustomerInfo.make(:card_query)
|
12
20
|
@order_info = BreadMachine::OrderInfo.make
|
@@ -25,7 +33,7 @@ describe BreadMachine::SecureTrading::St3dCardQueryRequest do
|
|
25
33
|
config.term_url = 'http://www.example.com'
|
26
34
|
config.merchant_name = "Bob's Widgets Inc."
|
27
35
|
end
|
28
|
-
amount = Money.
|
36
|
+
amount = Money.us_dollar(10_99)
|
29
37
|
|
30
38
|
@request = described_class.new(amount, @card, @customer_info, @order_info)
|
31
39
|
|
@@ -38,6 +46,15 @@ describe BreadMachine::SecureTrading::St3dCardQueryRequest do
|
|
38
46
|
request_xml.should have_tag("Operation/MerchantName", "Bob's Widgets Inc.")
|
39
47
|
end
|
40
48
|
|
49
|
+
it "should append to term_url if set in options" do
|
50
|
+
BreadMachine::SecureTrading.configuration.term_url = 'http://www.example.com'
|
51
|
+
options = {:term_url_append => '/some_value'}
|
52
|
+
|
53
|
+
@request = described_class.new(@amount, @card, @customer_info, @order_info, options)
|
54
|
+
|
55
|
+
request_xml.should have_tag("Operation/TermUrl", "http://www.example.com/some_value")
|
56
|
+
end
|
57
|
+
|
41
58
|
it "should append CustomerInfo element" do
|
42
59
|
request_xml.should have_tag("Request/CustomerInfo")
|
43
60
|
end
|
@@ -45,13 +62,7 @@ describe BreadMachine::SecureTrading::St3dCardQueryRequest do
|
|
45
62
|
it "should append PaymentMethod element" do
|
46
63
|
request_xml.should have_tag("Request/PaymentMethod")
|
47
64
|
end
|
48
|
-
|
49
|
-
it "should ensure amount is Money of correct currency" do
|
50
|
-
pending "Check that currency of amount matches currency specified in config"
|
51
|
-
end
|
52
65
|
|
53
|
-
it "should populate PaymentMethod element with correct data when querying from a previous ParentTransactionReference"
|
54
|
-
|
55
66
|
it "should append Order element" do
|
56
67
|
request_xml.should have_tag("Request/Order")
|
57
68
|
end
|
@@ -2,52 +2,109 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
|
2
2
|
|
3
3
|
describe BreadMachine::SecureTrading::St3dCardQueryResponse do
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
describe "#successful?" do
|
6
|
+
|
7
|
+
it "should be successful when Result element is 1" do
|
8
|
+
response = described_class.new(successful_response(result = 1))
|
9
|
+
response.should be_successful
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should be successful when Result element is 2" do
|
13
|
+
response = described_class.new(successful_response(result = 2))
|
14
|
+
response.should be_successful
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should not be successful when Result element is 0" do
|
18
|
+
response = described_class.new(failed_response)
|
19
|
+
response.should_not be_successful
|
20
|
+
end
|
21
|
+
|
9
22
|
end
|
10
23
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
24
|
+
describe "#error?" do
|
25
|
+
|
26
|
+
it "should be error when Result element is 0" do
|
27
|
+
response = described_class.new(failed_response)
|
28
|
+
response.should be_error
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should not be error when Result element is 1" do
|
32
|
+
response = described_class.new(successful_response(result = 1))
|
33
|
+
response.should_not be_error
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should not be error when Result element is 2" do
|
37
|
+
response = described_class.new(successful_response(result = 2))
|
38
|
+
response.should_not be_error
|
39
|
+
end
|
40
|
+
|
15
41
|
end
|
16
42
|
|
17
|
-
|
18
|
-
@response = described_class.new(successful_response)
|
19
|
-
@response.pa_req.should == "EXAMPLE-PA-REQ"
|
20
|
-
end
|
43
|
+
describe "accessors" do
|
21
44
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
45
|
+
it "should select PaReq" do
|
46
|
+
response = described_class.new(successful_response)
|
47
|
+
response.pa_req.should == "EXAMPLE-PA-REQ"
|
48
|
+
end
|
26
49
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
50
|
+
it "should select MD" do
|
51
|
+
response = described_class.new(successful_response)
|
52
|
+
response.md.should == "EXAMPLE-MD"
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should select AcsUrl" do
|
56
|
+
response = described_class.new(successful_response)
|
57
|
+
response.acs_url.should == "https://securetrading.net/secureweb/testacs0.cgi"
|
58
|
+
end
|
31
59
|
|
32
|
-
|
33
|
-
|
34
|
-
|
60
|
+
it "should select TranscationReference" do
|
61
|
+
response = described_class.new(successful_response)
|
62
|
+
response.transaction_reference.should == "15-9-1266891"
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should select Enrolled" do
|
66
|
+
response = described_class.new(successful_response)
|
67
|
+
response.enrolled.should == "Y"
|
68
|
+
end
|
69
|
+
|
35
70
|
end
|
36
71
|
|
37
|
-
|
38
|
-
|
72
|
+
describe "Auth type" do
|
73
|
+
|
74
|
+
it "should return s3 secure auth for auth type when card is enrolled" do
|
75
|
+
response = described_class.new(successful_response(result = 1, enrolled = 'Y'))
|
76
|
+
response.auth_type.should == BreadMachine::SecureTrading::St3dAuthRequest
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should return s3 secure auth for auth type when card is not enrolled" do
|
80
|
+
response = described_class.new(successful_response(result = 1, enrolled = 'N'))
|
81
|
+
response.auth_type.should == BreadMachine::SecureTrading::St3dAuthRequest
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should return standard auth for auth type when card provider is not part of scheme" do
|
85
|
+
response = described_class.new(successful_response(result = 2))
|
86
|
+
response.auth_type.should == BreadMachine::SecureTrading::AuthRequest
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should return standard auth for auth type when response is error" do
|
90
|
+
response = described_class.new(successful_response(result = 0))
|
91
|
+
response.auth_type.should == BreadMachine::SecureTrading::AuthRequest
|
92
|
+
end
|
93
|
+
|
39
94
|
end
|
95
|
+
|
96
|
+
|
40
97
|
|
41
|
-
def
|
42
|
-
<<-
|
98
|
+
def successful_response(result = 1, enrolled = 'Y')
|
99
|
+
<<-XML
|
43
100
|
<ResponseBlock Live="FALSE" Version="3.51">
|
44
101
|
<Response Type="ST3DCARDQUERY">
|
45
102
|
<OperationResponse>
|
46
103
|
<TransactionReference>15-9-1266891</TransactionReference>
|
47
104
|
<TransactionCompletedTimestamp>2009-09-24 14:50:41</TransactionCompletedTimestamp>
|
48
105
|
<TransactionVerifier>AY4LBwreQ1qwbPpuH5PswO4eN7KD27qmNBLG03tCrhBSzLpRXKBXw+PwY7dcuzuGoQXAPVB7phZYZhcP8YcBy9LFXO8zRW02QaHhXXykY7+ekmsYdNGEYjeLE8wI2vUGpD9IrGySGgYQySq1zIFg1wtUg4LmyrlAlUyQUOvPof8c=</TransactionVerifier>
|
49
|
-
<Result
|
50
|
-
<Enrolled
|
106
|
+
<Result>#{result}</Result>
|
107
|
+
<Enrolled>#{enrolled}</Enrolled>
|
51
108
|
<Html></Html>
|
52
109
|
<MD>EXAMPLE-MD</MD>
|
53
110
|
<PaReq>EXAMPLE-PA-REQ</PaReq>
|
@@ -60,7 +117,7 @@ describe BreadMachine::SecureTrading::St3dCardQueryResponse do
|
|
60
117
|
</Order>
|
61
118
|
</Response>
|
62
119
|
</ResponseBlock>
|
63
|
-
|
120
|
+
XML
|
64
121
|
end
|
65
122
|
|
66
123
|
def failed_response
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe BreadMachine::SecureTrading::AuthReversalRequest do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
transaction = mock('transaction')
|
7
|
+
transaction.stub(:transaction_reference => 'A_TRANSACTION_REFERENCE')
|
8
|
+
transaction.stub(:transaction_verifier => 'A_TRANSACTION_VERIFIER')
|
9
|
+
@order_info = BreadMachine::OrderInfo.make
|
10
|
+
@request = described_class.new(transaction, @order_info)
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "XML generation" do
|
14
|
+
|
15
|
+
def xml
|
16
|
+
Nokogiri::XML::Document.parse(@request.to_xml)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should set correct request type" do
|
20
|
+
xml.should have_tag("/Request[@Type='AUTHREVERSAL']")
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should populate Operation element with correct data" do
|
24
|
+
BreadMachine::SecureTrading.configuration.site_reference = 'site12345'
|
25
|
+
|
26
|
+
xml.should have_tag("Request/Operation")
|
27
|
+
xml.should have_tag("Operation/SiteReference", "site12345")
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should append CreditCard element" do
|
31
|
+
xml.should have_tag("Request/PaymentMethod/CreditCard")
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should append Order element" do
|
35
|
+
xml.should have_tag("Request/Order")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should return correct response" do
|
40
|
+
@request.response('<xml>').should be_a(BreadMachine::SecureTrading::AuthReversalResponse)
|
41
|
+
end
|
42
|
+
end
|