xpay 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -11,6 +11,8 @@ http://www.securetrading.com/support/xpay.html for futher details, in depth spec
11
11
  $ gem install xpay
12
12
 
13
13
  * configure by either creating a yaml file at config/xpay.yml or call Xpay.set_config with a hash
14
+ * (make sure to use Xpay.set_config(options_hash) instead of setting the options direct as that would
15
+ * prevent the new xml from being generated)
14
16
  * the following options can be set:
15
17
  - merchant_name
16
18
  - version
@@ -20,7 +22,7 @@ http://www.securetrading.com/support/xpay.html for futher details, in depth spec
20
22
  - callback_url
21
23
 
22
24
  == Usage
23
- === An example of a 3D-Secure Transaction
25
+ * An example of a 3D-Secure Transaction
24
26
 
25
27
  -first: create the class instance for CreditCard, Customer and Operatioon
26
28
 
@@ -93,7 +95,7 @@ http://www.securetrading.com/support/xpay.html for futher details, in depth spec
93
95
 
94
96
  The possible values of rt are as above.
95
97
 
96
- === more examples to follow
98
+ * more examples to follow
97
99
 
98
100
 
99
101
  == Copyright
data/Rakefile CHANGED
@@ -16,6 +16,7 @@ namespace :test do
16
16
  Rake::TestTask.new(:unit) do |test|
17
17
  test.libs << 'lib' << 'test'
18
18
  test.ruby_opts << '-rubygems'
19
+ test.test_files = FileList['test/*_test.rb']
19
20
  test.pattern = 'test/xpay/**/*_test.rb'
20
21
  test.verbose = true
21
22
  end
data/UPGRADES CHANGED
@@ -7,3 +7,11 @@
7
7
 
8
8
  0.0.3 => 0.0.4
9
9
  * bug fixed that prevents loading of MerchantName from config and create root xml
10
+
11
+ 0.0.4 => 0.0.5
12
+ * bug fix that prevents having a return value on make_payment with non ST3DCARDQUERY as request
13
+
14
+ 0.0.5 => 0.0.6
15
+ * bug fixed that prevents changing the config via hash
16
+ * added TransactionQuery as class that allows to query previous transactions
17
+ * force Issue number into string in CreditCard when given as Integer
@@ -20,6 +20,7 @@ module Xpay
20
20
  # default_currency: GBP
21
21
 
22
22
  autoload :Payment, 'xpay/payment'
23
+ autoload :TransactionQuery, 'xpay/transaction_query'
23
24
  autoload :CreditCard, 'xpay/core/creditcard'
24
25
  autoload :Customer, 'xpay/core/customer'
25
26
  autoload :Operation, 'xpay/core/operation'
@@ -45,6 +46,7 @@ module Xpay
45
46
  end
46
47
 
47
48
  class PaResMissing < XpayError; end
49
+ class AttributeMissing < XpayError; end
48
50
  class General < XpayError; end
49
51
 
50
52
  class << self
@@ -75,6 +77,7 @@ module Xpay
75
77
  conf.each do |key, value|
76
78
  @xpay_config.send("#{key}=", value) if @xpay_config.respond_to? key
77
79
  end
80
+ @request_xml = create_root_xml
78
81
  return true
79
82
  end
80
83
 
@@ -94,6 +97,8 @@ module Xpay
94
97
  operation = request.add_element "Operation"
95
98
  site_ref = operation.add_element "SiteReference"
96
99
  site_ref.text = config.site_reference
100
+ operation.add_element("Currency").text = config.default_currency if config.default_currency
101
+ operation.add_element("SettlementDay").text = config.settlement_day if config.settlement_day
97
102
  if config.default_query == "ST3DCARDQUERY"
98
103
  mn = operation.add_element "MerchantName"
99
104
  mn.text = config.merchant_name
@@ -2,6 +2,7 @@ module Xpay
2
2
  class CreditCard
3
3
  attr_accessor :card_type, :valid_until, :valid_from, :issue, :parent_transaction_ref, :transaction_verifier
4
4
  attr_writer :security_code
5
+
5
6
  def initialize(options={})
6
7
  if !options.nil? && options.is_a?(Hash)
7
8
  options.each do |key, value|
@@ -18,6 +19,10 @@ module Xpay
18
19
  @number = new_val.to_s.gsub(/[^0-9]/, "")
19
20
  end
20
21
 
22
+ def issue=(issue)
23
+ @issue = issue.to_s
24
+ end
25
+
21
26
  def security_code=(new_val)
22
27
  @security_code = new_val.to_s
23
28
  end
@@ -67,10 +67,10 @@ module Xpay
67
67
  # query your instance e.g. p.response_block for further information
68
68
 
69
69
  def make_payment
70
- @response_xml = self.process()
70
+ @response_xml = process()
71
71
  if request_method=="ST3DCARDQUERY"
72
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)
73
+ @response_xml = process() if response_code==0 # try once more if the response code is ZERO in ST3DCARDQUERY (According to securtrading tech support)
74
74
  case response_code
75
75
  when 1 # one means -> 3D AUTH required
76
76
  rewrite_request_block() # Rewrite the request block with information from the response, deleting unused items
@@ -85,20 +85,20 @@ module Xpay
85
85
  threedsecure = REXML::XPath.first(@request_xml, "//ThreeDSecure")
86
86
  pares = threedsecure.add_element("PaRes")
87
87
  pares.text = ""
88
- @response_xml = self.process()
89
- rt = REXML::XPath.first(@response_xml, "//Result").text.to_i
88
+ @response_xml = process()
89
+ rt = response_code
90
90
  end
91
91
  when 2 # TWO -> do a normal AUTH request
92
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
93
+ @response_xml = process()
94
+ rt = response_code
95
95
  else # ALL other cases, payment declined
96
- rt = REXML::XPath.first(@response_xml, "//Result").text.to_i
96
+ rt = response_code
97
97
  end
98
98
  else
99
- rt = REXML::XPath.first(@response_xml, "//Result").text.to_i
99
+ rt = response_code
100
100
  end
101
- return rt
101
+ rt
102
102
  end
103
103
 
104
104
  # The response_block is a hash and can have one of several values:
@@ -175,33 +175,26 @@ module Xpay
175
175
  REXML::XPath.first(@request_xml, "//Request").attributes["Type"] = auth_type
176
176
 
177
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"
178
+ ops = REXML::XPath.first(@request_xml, "//Operation")
179
+ ["TermUrl", "MerchantName"].each { |e| ops.delete_element e }
181
180
 
182
181
  # delete accept and user agent in customer info
183
182
  customer_info = REXML::XPath.first(@request_xml, "//CustomerInfo")
184
- customer_info.delete_element "//Accept"
185
- customer_info.delete_element "//UserAgent"
183
+ ["Accept", "UserAgent"].each { |e| customer_info.delete_element e }
186
184
 
187
185
  # delete credit card details and add TransactionVerifier and TransactionReference from response xml
188
186
  # CC details are not needed anymore as verifier and reference are sufficient
189
187
  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
188
+ ["Number", "Type", "SecurityCode", "StartDate", "ExpiryDate", "Issue"].each { |e| cc_details.delete_element e }
189
+ cc_details.add_element("TransactionVerifier").text = REXML::XPath.first(@response_xml, "//TransactionVerifier").text
190
+ cc_details.add_element("ParentTransactionReference").text = REXML::XPath.first(@response_xml, "//TransactionReference").text
196
191
 
197
192
  # unless it is an AUTH request, add additional required info for a 3DAUTH request
198
193
  unless auth_type == "AUTH"
199
194
  pm_method = REXML::XPath.first(@request_xml, "//PaymentMethod")
200
195
  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 ""
196
+ threedsecure.add_element("Enrolled").text = REXML::XPath.first(@response_xml, "//Enrolled").text
197
+ threedsecure.add_element("MD").text = REXML::XPath.first(@response_xml, "//MD").text rescue ""
205
198
  end
206
199
  true
207
200
  end
@@ -10,24 +10,25 @@ module Xpay
10
10
  attr_accessor :request_xml
11
11
  attr_reader :three_secure, :response_xml, :response_block
12
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
13
 
22
14
  def request_method
23
15
  @request_method ||= REXML::XPath.first(@request_xml, "//Request").attributes["Type"]
24
16
  end
25
17
 
26
18
  def response_code
27
- @response_code ||= REXML::XPath.first(@response_xml, "//Result").text.to_i rescue -1
19
+ REXML::XPath.first(@response_xml, "//Result").text.to_i rescue nil
28
20
  end
29
21
 
30
22
  private
23
+ def process()
24
+ a = TCPSocket.open("localhost", Xpay.config.port)
25
+ a.write(self.request_xml.to_s + "\n")
26
+ res = a.read()
27
+ a.close
28
+ # create an xml document, use everything from the start of <ResponseBlock to the end, discard header and status etc and return it
29
+ REXML::Document.new res[res.index("<ResponseBlock"), res.length]
30
+ end
31
+
31
32
  def response_xml=(new_val)
32
33
  @response_xml = new_val if new_val.is_a?(REXML::Document)
33
34
  end
@@ -0,0 +1,72 @@
1
+ module Xpay
2
+
3
+ # This class allows you to query the status of a transaction processed with Xpay
4
+ # the following attributes are required:
5
+ # either a TransactionReference or your own OrderReference from a previous transaction
6
+ # and your SiteReference if not already set in the config, you can also pass it to overwrite it for this transaction
7
+ class TransactionQuery < Transaction
8
+ attr_accessor :transaction_reference, :order_reference, :site_reference, :site_alias
9
+
10
+ def initialize(options={})
11
+ @request_xml = REXML::Document.new(Xpay.root_to_s)
12
+ options.each do |key, value|
13
+ self.send("#{key}=", value) if self.respond_to? key
14
+ end
15
+ create_request
16
+ end
17
+
18
+ def query
19
+ @response_xml = process()
20
+ return response_code
21
+ end
22
+
23
+ # The response_block is a hash and can have one of several values:
24
+ # the follwing values are always present after a transaction and can be queried to gain further details of the transaction:
25
+ # * result_code:
26
+ # 0 for failure, check error_code for further details
27
+ # 1 transaction was succesful
28
+ # 2 transaction was denied
29
+ # * transaction_reference
30
+ # * transactionverifier
31
+ # * transaction_time
32
+ # * auth_code
33
+ # * amount
34
+ # * the order reference
35
+ def response_block
36
+ create_response_block
37
+ end
38
+
39
+ private
40
+
41
+ # Write the xml document needed for processing, fill in elements need and delete unused ones from the root_xml
42
+ # raises an error if any necessary elements are missing
43
+ def create_request
44
+ raise AttributeMissing.new "(2500) TransactionReference or OrderReference need to be present." if (transaction_reference.nil? && order_reference.nil?)
45
+ raise AttributeMissing.new "(2500) SiteReference must be present." if (site_reference.nil? && (REXML::XPath.first(@request_xml, "//SiteReference").text.blank? rescue true))
46
+ REXML::XPath.first(@request_xml, "//Request").attributes["Type"] = "TRANSACTIONQUERY"
47
+ ops = REXML::XPath.first(@request_xml, "//Operation")
48
+ ["TermUrl", "MerchantName", "Currency", "SettlementDay"].each { |e| ops.delete_element e }
49
+ (ops.elements["SiteReference"] || ops.add_element("SiteReference")).text = self.site_reference if self.site_reference
50
+ (ops.elements["TransactionReference"] || ops.add_element("TransactionReference")).text = self.transaction_reference if self.transaction_reference
51
+ order = REXML::XPath.first(@request_xml, "//Operation")
52
+ (order.elements["OrderReference"] || order.add_element("OrderReference")).text = self.order_reference if self.order_reference
53
+ root = @request_xml.root
54
+ (root.elements["Certificate"] || root.add_element("Certificate")).text = self.site_alias if self.site_alias
55
+
56
+ end
57
+
58
+ def create_response_block
59
+ @response_xml.is_a?(REXML::Document) ?
60
+ {
61
+ :result_code => (REXML::XPath.first(@response_xml, "//Result").text.to_i rescue nil),
62
+ :transaction_reference => (REXML::XPath.first(@response_xml, "//TransactionReference").text rescue nil),
63
+ :transactionverifier => (REXML::XPath.first(@response_xml, "//TransactionVerifier").text rescue nil),
64
+ :transaction_time => (REXML::XPath.first(@response_xml, "//TransactionCompletedTimestamp").text rescue nil),
65
+ :auth_code => (REXML::XPath.first(@response_xml, "//AuthCode").text rescue nil),
66
+ :amount => (REXML::XPath.first(@response_xml, "//Amount").text.to_i rescue nil),
67
+ :order_reference => (REXML::XPath.first(@response_xml, "//OrderReference").text rescue nil),
68
+ } : {}
69
+ end
70
+
71
+ end
72
+ end
@@ -1,3 +1,3 @@
1
1
  module Xpay
2
- Version = '0.0.5'
2
+ Version = '0.0.6'
3
3
  end
@@ -0,0 +1 @@
1
+ <?xml version='1.0' encoding='ISO-8859-1'?><RequestBlock Version='3.52'><Request Type='AUTH'><Operation><SiteReference>testoutlet12091</SiteReference><Currency>USD</Currency><SettlementDay>2</SettlementDay></Operation></Request><Certificate>testoutlet12091</Certificate></RequestBlock>
@@ -8,7 +8,7 @@ class_test:
8
8
  number: 4111111111111111
9
9
  security_code: 123
10
10
  valid_from: <%= Date.today.advance(:months => -5).strftime("%m/%y") %>
11
- issue: "1"
11
+ issue: 1
12
12
 
13
13
 
14
14
  visa_no3d_auth:
@@ -1 +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>
1
+ <?xml version='1.0' encoding='ISO-8859-1'?><RequestBlock Version='3.51'><Request Type='ST3DCARDQUERY'><Operation><SiteReference>site12345</SiteReference><Currency>GBP</Currency><SettlementDay>1</SettlementDay><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 @@
1
+ <?xml version='1.0' encoding='ISO-8859-1'?><RequestBlock Version='3.51'><Request Type='ST3DCARDQUERY'><Operation><SiteReference>site12345</SiteReference><Currency>GBP</Currency><SettlementDay>1</SettlementDay><MerchantName>CompanyName</MerchantName><TermUrl>http://localhost/gateway_callback</TermUrl></Operation></Request><Certificate>site12345</Certificate></RequestBlock>
@@ -1 +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>
1
+ <?xml version='1.0' encoding='ISO-8859-1'?><RequestBlock Version='3.51'><Request Type='AUTH'><Operation><SiteReference>site56987</SiteReference><Currency>USD</Currency><SettlementDay>1</SettlementDay><MerchantName>TestMerchant</MerchantName><TermUrl>https://localhost/3dcallback</TermUrl><Amount>1000</Amount></Operation><Order><OrderReference>TestOrder1245</OrderReference><OrderInformation>TestOrderInfo</OrderInformation></Order></Request><Certificate>site56987</Certificate></RequestBlock>
@@ -1 +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>
1
+ <?xml version='1.0' encoding='ISO-8859-1'?><RequestBlock Version='3.51'><Request Type='ST3DAUTH'><Operation><SiteReference>site56987</SiteReference><Currency>USD</Currency><SettlementDay>1</SettlementDay><Amount>1000</Amount></Operation><PaymentMethod><CreditCard><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>
@@ -1 +1 @@
1
- <?xml version='1.0' encoding='ISO-8859-1'?><RequestBlock Version='3.51'><Request Type='ST3DCARDQUERY'><Operation><SiteReference>site12345</SiteReference></Operation></Request><Certificate>site12345</Certificate></RequestBlock>
1
+ <RequestBlock Version='3.51'><Request Type='ST3DCARDQUERY'><Operation><Currency>GBP</Currency><SettlementDay>1</SettlementDay><MerchantName>CompanyName</MerchantName><TermUrl>http://localhost/gateway_callback</TermUrl></Operation></Request><Certificate>site12345</Certificate></RequestBlock>
@@ -0,0 +1 @@
1
+ <RequestBlock Version='3.51'><Request Type='TRANSACTIONQUERY'><Operation><SiteReference>site1234</SiteReference><TransactionReference>17-9-1908322</TransactionReference><OrderReference>121-1010272211</OrderReference></Operation></Request><Certificate>site12345</Certificate></RequestBlock>
@@ -0,0 +1,16 @@
1
+ <?xml version='1.0' encoding='ISO-8859-1'?>
2
+ <ResponseBlock Live="FALSE" Version="3.51">
3
+ <Response Type="TRANSACTIONQUERY">
4
+ <OperationResponse>
5
+ <TransactionReference>2-2-35117</TransactionReference>
6
+ <AuthCode>AUTH CODE: ab123</AuthCode>
7
+ <Result>1</Result>
8
+ <Amount>1234</Amount>
9
+ <TransactionCompletedTimestamp>2004-08-31 16:17:03</TransactionCompletedTimestamp>
10
+ <TransactionVerifier>ApTtGHQ/WUQYRj</TransactionVerifier>
11
+ </OperationResponse>
12
+ <Order>
13
+ <OrderReference>orderref0001</OrderReference>
14
+ </Order>
15
+ </Response>
16
+ </ResponseBlock>
@@ -0,0 +1,28 @@
1
+ require 'test_helper'
2
+ require 'xpay'
3
+
4
+
5
+ class TransactionFunctionalTest < Test::Unit::TestCase
6
+
7
+ context "a visa succesful no 3D payment" do
8
+ setup do
9
+ options = {:creditcard => Xpay::CreditCard.new(credit_card("visa_no3d_auth")), :operation => Xpay::Operation.new(operation("test_1")), :customer => Xpay::Customer.new(customer("test_1"))}
10
+ @p = Xpay::Payment.new(options)
11
+ Xpay.config.port = 5000
12
+ @p.make_payment
13
+ @tq = Xpay::TransactionQuery.new(:transaction_reference => @p.response_block[:transaction_reference], :site_reference => "testoutlet12092", :site_alias => "testoutlet12092")
14
+ @tq.query
15
+ end
16
+
17
+ should "create a transaction query" do
18
+ d { @p.response_block.to_yaml }
19
+ assert_instance_of Xpay::TransactionQuery, @tq
20
+ end
21
+
22
+ should "have a non empty response block" do
23
+ assert !@tq.response_block.empty?
24
+ end
25
+
26
+ end
27
+
28
+ end
@@ -15,24 +15,22 @@ end
15
15
  def customer(which)
16
16
  conf = YAML::load(ERB.new(IO.read(File.expand_path(File.dirname(__FILE__) + '/fixtures/customer.yml'))).result)[which]
17
17
  end
18
- def customer_xml_string
19
- x = REXML::Document.new(File.open(File.expand_path(File.dirname(__FILE__) + '/fixtures/customer.xml'))).root.to_s
20
- end
18
+
19
+
21
20
 
22
21
  def operation(which)
23
22
  conf = YAML::load(ERB.new(IO.read(File.expand_path(File.dirname(__FILE__) + '/fixtures/operation.yml'))).result)[which]
24
23
  end
25
- def operation_xml_string(which="operation")
26
- operation_xml(which).root.to_s
27
- end
28
- def operation_xml(which="operation")
24
+
25
+
26
+ def load_xml(which="")
29
27
  REXML::Document.new(File.open(File.expand_path(File.dirname(__FILE__) + "/fixtures/#{which}.xml")))
30
28
  end
31
-
32
- def root_xml_string
33
- x = REXML::Document.new(File.open(File.expand_path(File.dirname(__FILE__) + '/fixtures/root.xml'))).root.to_s
29
+ def load_xml_string(which="")
30
+ load_xml(which).root.to_s
34
31
  end
35
32
 
33
+
36
34
  def xpay_config(which)
37
35
  YAML::load(IO.read(File.expand_path(File.dirname(__FILE__) + '/fixtures/xpay_defaults.yml')))[which]
38
36
  end
@@ -56,7 +56,7 @@ class CustomerTest < Test::Unit::TestCase
56
56
  end
57
57
  should "create a xml document according to xpay spec" do
58
58
  @cus.add_to_xml(@request_xml)
59
- assert_equal(customer_xml_string, @request_xml.root.to_s)
59
+ assert_equal(load_xml_string("customer"), @request_xml.root.to_s)
60
60
  end
61
61
  end
62
62
 
@@ -38,7 +38,7 @@ class OperationTest < Test::Unit::TestCase
38
38
  end
39
39
  should "create an xml document according to xpay spec" do
40
40
  @ops.add_to_xml(@request_xml)
41
- assert_equal(operation_xml_string, @request_xml.root.to_s)
41
+ assert_equal @request_xml.root.to_s, load_xml_string("operation")
42
42
  end
43
43
 
44
44
  end
@@ -53,7 +53,7 @@ class PaymentTest < Test::Unit::TestCase
53
53
  context "an empty payment instance with set 3D secure response" do
54
54
  setup do
55
55
  @p = Xpay::Payment.new()
56
- @p.send("response_xml=", operation_xml("response_3d"))
56
+ @p.send("response_xml=", load_xml("response_3d"))
57
57
  end
58
58
 
59
59
  should "have a non-empty hash as a response block" do
@@ -69,13 +69,12 @@ class PaymentTest < Test::Unit::TestCase
69
69
  Xpay::Payment.send(:public, *Xpay::Payment.private_instance_methods)
70
70
  options = {:creditcard => Xpay::CreditCard.new(credit_card("class_test")), :operation => Xpay::Operation.new(operation("class_test")), :customer => Xpay::Customer.new(customer("class_test"))}
71
71
  @p = Xpay::Payment.new(options)
72
- @p.send("response_xml=", operation_xml("response_3d"))
72
+ @p.send("response_xml=", load_xml("response_3d"))
73
73
 
74
74
  end
75
75
  should "have a new request_xml after rewrite" do
76
76
  @p.rewrite_request_block
77
- assert_equal operation_xml_string("request_rewritten"), @p.request_xml.root.to_s
78
- d { @p.request_xml.to_s }
77
+ assert_equal @p.request_xml.root.to_s, load_xml_string("request_rewritten")
79
78
  end
80
79
 
81
80
  should "have a non-empty hash as a response block" do
@@ -89,13 +88,13 @@ class PaymentTest < Test::Unit::TestCase
89
88
 
90
89
  context "a payment instance created from xml without PaRes" do
91
90
  should "throw error 2500, PaRes missing" do
92
- options = {:xml => operation_xml_string("request_rewritten")}
91
+ options = {:xml => load_xml_string("request_rewritten")}
93
92
  assert_raise(Xpay::PaResMissing) {Xpay::Payment.new(options)}
94
93
  end
95
94
  end
96
95
  context "a payment instance created from xml without PaRes" do
97
96
  setup do
98
- options = {:xml => operation_xml_string("request_rewritten"), :pares => "ABJASDKA+SDKAJ/SGDSAD"}
97
+ options = {:xml => load_xml_string("request_rewritten"), :pares => "ABJASDKA+SDKAJ/SGDSAD"}
99
98
  @p = Xpay::Payment.new(options)
100
99
  end
101
100
  should "should have a request_xml document" do
@@ -0,0 +1,93 @@
1
+ require "test_helper"
2
+ require 'xpay'
3
+
4
+ class TransactionQueryTest < Test::Unit::TestCase
5
+ context "an empty instance" do
6
+ should "raise attribute missing error" do
7
+ assert_raise(Xpay::AttributeMissing) { Xpay::TransactionQuery.new() }
8
+ end
9
+ end
10
+
11
+ context "an instance with missing site refence " do
12
+ setup do
13
+ ops = REXML::XPath.first(Xpay.root_xml, "//Operation")
14
+ ops.delete_element "SiteReference"
15
+ end
16
+
17
+ should "raise attribute missing error" do
18
+ assert_raise(Xpay::AttributeMissing) { Xpay::TransactionQuery.new(:transaction_reference => "17-9-1908322", :order_reference => "121-1010272211") }
19
+ end
20
+ end
21
+ context "an instance with empty site refence " do
22
+ setup do
23
+ REXML::XPath.first(Xpay.root_xml, "//SiteReference").text = ""
24
+ end
25
+
26
+ should "raise attribute missing error" do
27
+ assert_raise(Xpay::AttributeMissing) { Xpay::TransactionQuery.new(:transaction_reference => "17-9-1908322", :order_reference => "121-1010272211") }
28
+ end
29
+ end
30
+
31
+ context "a new instance with only a transaction reference" do
32
+ setup do
33
+ @t = Xpay::TransactionQuery.new({:transaction_reference => "17-9-1908322"})
34
+ end
35
+
36
+ should "instantiate without error" do
37
+ assert_instance_of Xpay::TransactionQuery, @t
38
+ end
39
+ end
40
+
41
+ context "a new instance with only a order reference" do
42
+ setup do
43
+ @t = Xpay::TransactionQuery.new({:order_reference => "17-9-1908322"})
44
+ end
45
+
46
+ should "instantiate without error" do
47
+ assert_instance_of Xpay::TransactionQuery, @t
48
+ end
49
+ end
50
+
51
+ context "a new instance" do
52
+ setup do
53
+ @t = Xpay::TransactionQuery.new({:transaction_reference => "17-9-1908322", :order_reference => "121-1010272211", :site_reference => "site1234"})
54
+ end
55
+
56
+ should "have a the same xml as the module" do
57
+ assert_equal @t.request_xml.root.to_s, load_xml_string("transactionquery")
58
+ end
59
+
60
+ should "have an empty repsonse block" do
61
+ assert @t.response_block.empty?
62
+ end
63
+
64
+ should "have attributes" do
65
+ assert @t.respond_to? :transaction_reference
66
+ assert @t.respond_to? :order_reference
67
+ assert @t.respond_to? :site_reference
68
+ assert @t.respond_to? :site_alias
69
+ end
70
+
71
+ context "given a response block" do
72
+ setup do
73
+ Xpay::TransactionQuery.send(:public, *Xpay::TransactionQuery.private_instance_methods)
74
+ @t.send("response_xml=", load_xml("transactionquery_response"))
75
+ end
76
+
77
+ should "have a response block" do
78
+ assert !@t.response_block.empty?
79
+ end
80
+
81
+ should "have values" do
82
+ rb = @t.response_block
83
+ assert_equal "2-2-35117", rb[:transaction_reference]
84
+ assert_equal "AUTH CODE: ab123", rb[:auth_code]
85
+ assert_equal 1, rb[:result_code]
86
+ assert_equal "2004-08-31 16:17:03", rb[:transaction_time]
87
+ assert_equal "ApTtGHQ/WUQYRj", rb[:transactionverifier]
88
+ assert_equal "orderref0001", rb[:order_reference]
89
+ end
90
+ end
91
+ end
92
+
93
+ end
@@ -1,5 +1,6 @@
1
1
  require 'test_helper'
2
2
  require 'xpay'
3
+
3
4
  class XpayTest < Test::Unit::TestCase
4
5
  context "the xpay module" do
5
6
  setup do
@@ -7,22 +8,31 @@ class XpayTest < Test::Unit::TestCase
7
8
  end
8
9
 
9
10
  should "have standard config xml" do
10
- assert_kind_of(REXML::Document,@xpay.root_xml)
11
+ assert_kind_of(REXML::Document, @xpay.root_xml)
11
12
  assert_equal @xpay.config, OpenStruct.new(xpay_config("default"))
12
13
  end
13
14
  should "have xml document formed to xpay spec" do
14
- assert_equal @xpay.root_xml.root.to_s, root_xml_string
15
+ assert_equal load_xml_string("root"), @xpay.root_xml.root.to_s
15
16
  end
17
+
16
18
  should "load a new config from yaml file" do
17
- assert @xpay.load_config(File.expand_path(File.dirname(__FILE__)+ '/fixtures'))
19
+ assert @xpay.load_config(File.expand_path(File.dirname(__FILE__) + '/fixtures'))
18
20
  end
19
21
 
20
- context "with new configuration" do
22
+ context "with new configuration from yaml file" do
21
23
 
22
24
  should "have a new config" do
23
25
  assert_equal @xpay.config, OpenStruct.new(xpay_config("config_load_test"))
24
26
  end
25
27
 
28
+ should "have a new root_xml" do
29
+ assert_equal load_xml_string("config_load_test"), @xpay.root_xml.root.to_s
30
+ end
31
+
32
+ should "have config.port 6000" do
33
+ assert_equal 6000, @xpay.config.port
34
+ end
35
+
26
36
  should "have an environment" do
27
37
  assert_equal @xpay.environment, "development"
28
38
  end
@@ -35,7 +45,9 @@ class XpayTest < Test::Unit::TestCase
35
45
  should "load a new config from hash" do
36
46
  assert @xpay.set_config(xpay_config("default"))
37
47
  assert_equal @xpay.config, OpenStruct.new(xpay_config("default"))
48
+ assert_equal load_xml_string("default_config"), @xpay.root_xml.root.to_s
38
49
  end
39
50
 
40
51
  end
41
52
  end
53
+
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xpay
3
3
  version: !ruby/object:Gem::Version
4
- hash: 21
4
+ hash: 19
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 5
10
- version: 0.0.5
9
+ - 6
10
+ version: 0.0.6
11
11
  platform: ruby
12
12
  authors:
13
13
  - Volker Pacher
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-10-26 00:00:00 +01:00
18
+ date: 2010-10-28 00:00:00 +01:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -121,6 +121,7 @@ files:
121
121
  - lib/xpay.rb
122
122
  - lib/xpay/transaction.rb
123
123
  - lib/xpay/version.rb
124
+ - lib/xpay/transaction_query.rb
124
125
  - lib/xpay/core/customer.rb
125
126
  - lib/xpay/core/operation.rb
126
127
  - lib/xpay/core/creditcard.rb
@@ -128,22 +129,28 @@ files:
128
129
  - rails/init.rb
129
130
  - test/xpay_test.rb
130
131
  - test/fixtures/customer.xml
132
+ - test/fixtures/config_load_test.xml
131
133
  - test/fixtures/operation.yml
134
+ - test/fixtures/transactionquery.xml
132
135
  - test/fixtures/operation.xml
133
136
  - test/fixtures/response.xml
134
137
  - test/fixtures/creditcards.yml
138
+ - test/fixtures/default_config.xml
135
139
  - test/fixtures/customer.yml
136
140
  - test/fixtures/xpay_defaults.yml
137
141
  - test/fixtures/request_rewritten.xml
142
+ - test/fixtures/transactionquery_response.xml
138
143
  - test/fixtures/response_3d.xml
139
144
  - test/fixtures/root.xml
140
145
  - test/fixtures/config/xpay.yml
146
+ - test/functional/transactionquery_functional_test.rb
141
147
  - test/functional/payment_functional_test.rb
142
148
  - test/test_helper.rb
143
149
  - test/xpay/core/creditcard_test.rb
144
150
  - test/xpay/core/customer_test.rb
145
151
  - test/xpay/core/operation_test.rb
146
152
  - test/xpay/payment_test.rb
153
+ - test/xpay/transactionquery_test.rb
147
154
  - LICENSE
148
155
  - UPGRADES
149
156
  - README.rdoc