adyen 0.3.8 → 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.
Files changed (46) hide show
  1. data/.gitignore +4 -0
  2. data/.kick +35 -0
  3. data/LICENSE +3 -2
  4. data/README.rdoc +8 -4
  5. data/Rakefile +10 -0
  6. data/TODO +14 -4
  7. data/adyen.gemspec +9 -15
  8. data/lib/adyen.rb +10 -59
  9. data/lib/adyen/api.rb +281 -0
  10. data/lib/adyen/api/cacert.pem +3509 -0
  11. data/lib/adyen/api/payment_service.rb +258 -0
  12. data/lib/adyen/api/recurring_service.rb +126 -0
  13. data/lib/adyen/api/response.rb +54 -0
  14. data/lib/adyen/api/simple_soap_client.rb +118 -0
  15. data/lib/adyen/api/templates/payment_service.rb +103 -0
  16. data/lib/adyen/api/templates/recurring_service.rb +34 -0
  17. data/lib/adyen/api/test_helpers.rb +133 -0
  18. data/lib/adyen/api/xml_querier.rb +94 -0
  19. data/lib/adyen/configuration.rb +139 -0
  20. data/lib/adyen/form.rb +37 -109
  21. data/lib/adyen/formatter.rb +0 -10
  22. data/lib/adyen/matchers.rb +1 -1
  23. data/lib/adyen/notification_generator.rb +30 -0
  24. data/lib/adyen/railtie.rb +13 -0
  25. data/lib/adyen/templates/notification_migration.rb +29 -0
  26. data/lib/adyen/templates/notification_model.rb +70 -0
  27. data/spec/adyen_spec.rb +3 -45
  28. data/spec/api/api_spec.rb +139 -0
  29. data/spec/api/payment_service_spec.rb +439 -0
  30. data/spec/api/recurring_service_spec.rb +105 -0
  31. data/spec/api/response_spec.rb +35 -0
  32. data/spec/api/simple_soap_client_spec.rb +91 -0
  33. data/spec/api/spec_helper.rb +417 -0
  34. data/spec/api/test_helpers_spec.rb +83 -0
  35. data/spec/form_spec.rb +27 -23
  36. data/spec/functional/api_spec.rb +90 -0
  37. data/spec/functional/initializer.rb.sample +3 -0
  38. data/spec/spec_helper.rb +5 -5
  39. data/tasks/github-gem.rake +49 -55
  40. data/yard_extensions.rb +16 -0
  41. metadata +63 -82
  42. data/init.rb +0 -1
  43. data/lib/adyen/notification.rb +0 -151
  44. data/lib/adyen/soap.rb +0 -649
  45. data/spec/notification_spec.rb +0 -97
  46. data/spec/soap_spec.rb +0 -340
@@ -0,0 +1,105 @@
1
+ # encoding: UTF-8
2
+ require 'api/spec_helper'
3
+ require 'date'
4
+
5
+ describe Adyen::API::RecurringService do
6
+ include APISpecHelper
7
+
8
+ before do
9
+ @params = { :shopper => { :reference => 'user-id' } }
10
+ @recurring = @object = Adyen::API::RecurringService.new(@params)
11
+ end
12
+
13
+ describe_request_body_of :list, '//recurring:listRecurringDetails/recurring:request' do
14
+ it_should_validate_request_parameters :merchant_account,
15
+ :shopper => [:reference]
16
+
17
+ it "includes the merchant account handle" do
18
+ text('./recurring:merchantAccount').should == 'SuperShopper'
19
+ end
20
+
21
+ it "includes the shopper’s reference" do
22
+ text('./recurring:shopperReference').should == 'user-id'
23
+ end
24
+
25
+ it "includes the type of contract, which is always `RECURRING'" do
26
+ text('./recurring:recurring/recurring:contract').should == 'RECURRING'
27
+ end
28
+ end
29
+
30
+ describe_response_from :list, LIST_RESPONSE, 'listRecurringDetails' do
31
+ it_should_return_params_for_each_xml_backend({
32
+ :creation_date => DateTime.parse('2009-10-27T11:26:22.203+01:00'),
33
+ :last_known_shopper_email => 's.hopper@example.com',
34
+ :shopper_reference => 'user-id',
35
+ :details => [
36
+ {
37
+ :card => {
38
+ :expiry_date => Date.new(2012, 12, 31),
39
+ :holder_name => 'S. Hopper',
40
+ :number => '1111'
41
+ },
42
+ :recurring_detail_reference => 'RecurringDetailReference1',
43
+ :variant => 'mc',
44
+ :creation_date => DateTime.parse('2009-10-27T11:50:12.178+01:00')
45
+ },
46
+ {
47
+ :bank => {
48
+ :bank_account_number => '123456789',
49
+ :bank_location_id => 'bank-location-id',
50
+ :bank_name => 'AnyBank',
51
+ :bic => 'BBBBCCLLbbb',
52
+ :country_code => 'NL',
53
+ :iban => 'NL69PSTB0001234567',
54
+ :owner_name => 'S. Hopper'
55
+ },
56
+ :recurring_detail_reference => 'RecurringDetailReference2',
57
+ :variant => 'IDEAL',
58
+ :creation_date => DateTime.parse('2009-10-27T11:26:22.216+01:00')
59
+ },
60
+ ],
61
+ })
62
+
63
+ it "returns an array with just the detail references" do
64
+ @response.references.should == %w{ RecurringDetailReference1 RecurringDetailReference2 }
65
+ end
66
+
67
+ it "returns an empty hash when there are no details" do
68
+ stub_net_http(LIST_EMPTY_RESPONSE)
69
+ @recurring.list.params.should == {}
70
+ end
71
+ end
72
+
73
+ describe_request_body_of :disable, '//recurring:disable/recurring:request' do
74
+ it_should_validate_request_parameters :merchant_account,
75
+ :shopper => [:reference]
76
+
77
+ it "includes the merchant account handle" do
78
+ text('./recurring:merchantAccount').should == 'SuperShopper'
79
+ end
80
+
81
+ it "includes the shopper’s reference" do
82
+ text('./recurring:shopperReference').should == 'user-id'
83
+ end
84
+
85
+ it "includes the shopper’s recurring detail reference if it is given" do
86
+ xpath('./recurring:recurringDetailReference').should be_empty
87
+ @recurring.params[:recurring_detail_reference] = 'RecurringDetailReference1'
88
+ text('./recurring:recurringDetailReference').should == 'RecurringDetailReference1'
89
+ end
90
+ end
91
+
92
+ describe_response_from :disable, (DISABLE_RESPONSE % '[detail-successfully-disabled]'), 'disable' do
93
+ it "returns whether or not it was disabled" do
94
+ @response.should be_success
95
+ @response.should be_disabled
96
+
97
+ stub_net_http(DISABLE_RESPONSE % '[all-details-successfully-disabled]')
98
+ @response = @recurring.disable
99
+ @response.should be_success
100
+ @response.should be_disabled
101
+ end
102
+
103
+ it_should_return_params_for_each_xml_backend(:response => '[detail-successfully-disabled]')
104
+ end
105
+ end
@@ -0,0 +1,35 @@
1
+ # encoding: UTF-8
2
+ require 'api/spec_helper'
3
+
4
+ describe Adyen::API::Response do
5
+ before do
6
+ http_response = Net::HTTPOK.new('1.1', '200', 'OK')
7
+ http_response.add_field('Content-type', 'text/xml')
8
+ http_response.stub!(:body).and_return(AUTHORISE_RESPONSE)
9
+ @response = Adyen::API::Response.new(http_response)
10
+ end
11
+
12
+ it "returns a XMLQuerier instance with the response body" do
13
+ @response.xml_querier.should be_instance_of(Adyen::API::XMLQuerier)
14
+ @response.xml_querier.to_s.should == AUTHORISE_RESPONSE
15
+ end
16
+
17
+ describe "with a successful HTTP response" do
18
+ it "returns that the (HTTP) request was a success" do
19
+ @response.should_not be_a_http_failure
20
+ @response.should be_a_success
21
+ end
22
+ end
23
+
24
+ describe "with a failed HTTP response" do
25
+ before do
26
+ http_response = Net::HTTPBadRequest.new('1.1', '400', 'Bad request')
27
+ @response = Adyen::API::Response.new(http_response)
28
+ end
29
+
30
+ it "returns that the (HTTP) request was not a success" do
31
+ @response.should be_a_http_failure
32
+ @response.should_not be_a_success
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,91 @@
1
+ # encoding: UTF-8
2
+ require 'api/spec_helper'
3
+
4
+ module APISpecHelper
5
+ class SOAPClient < Adyen::API::SimpleSOAPClient
6
+ ENDPOINT_URI = 'https://%s.example.com/soap/Action'
7
+ end
8
+ end
9
+
10
+ describe Adyen::API::SimpleSOAPClient do
11
+ include APISpecHelper
12
+
13
+ before do
14
+ @client = APISpecHelper::SOAPClient.new(:reference => 'order-id')
15
+ end
16
+
17
+ it "returns the endpoint, for the current environment, from the ENDPOINT_URI constant" do
18
+ uri = APISpecHelper::SOAPClient.endpoint
19
+ uri.scheme.should == 'https'
20
+ uri.host.should == 'test.example.com'
21
+ uri.path.should == '/soap/Action'
22
+ end
23
+
24
+ it "initializes with the given parameters" do
25
+ @client.params[:reference].should == 'order-id'
26
+ end
27
+
28
+ it "merges the default parameters with the given ones" do
29
+ @client.params[:merchant_account].should == 'SuperShopper'
30
+ end
31
+
32
+ describe "call_webservice_action" do
33
+ before do
34
+ stub_net_http(AUTHORISE_RESPONSE)
35
+ @response = @client.call_webservice_action('Action', '<bananas>Yes, please</bananas>', Adyen::API::Response)
36
+ @request, @post = Net::HTTP.posted
37
+ end
38
+
39
+ after do
40
+ Net::HTTP.stubbing_enabled = false
41
+ end
42
+
43
+ it "posts to the class's endpoint" do
44
+ endpoint = APISpecHelper::SOAPClient.endpoint
45
+ @request.host.should == endpoint.host
46
+ @request.port.should == endpoint.port
47
+ @post.path.should == endpoint.path
48
+ end
49
+
50
+ it "makes a request over SSL" do
51
+ @request.use_ssl?.should be_true
52
+ end
53
+
54
+ it "verifies certificates" do
55
+ File.should exist(Adyen::API::SimpleSOAPClient::CACERT)
56
+ @request.ca_file.should == Adyen::API::SimpleSOAPClient::CACERT
57
+ @request.verify_mode.should == OpenSSL::SSL::VERIFY_PEER
58
+ end
59
+
60
+ it "uses basic-authentication with the credentials set on the Adyen::API module" do
61
+ username, password = @post.assigned_basic_auth
62
+ username.should == 'SuperShopper'
63
+ password.should == 'secret'
64
+ end
65
+
66
+ it "sends the proper headers" do
67
+ @post.header.should include(
68
+ 'accept' => ['text/xml'],
69
+ 'content-type' => ['text/xml; charset=utf-8'],
70
+ 'soapaction' => ['Action']
71
+ )
72
+ end
73
+
74
+ it "returns an Adyen::API::Response instance" do
75
+ @response.should be_instance_of(Adyen::API::Response)
76
+ @response.xml_querier.to_s.should == AUTHORISE_RESPONSE
77
+ end
78
+
79
+ it "raises when the HTTP response is a subclass of Net::HTTPClientError" do
80
+ Net::HTTP.stubbed_response = Net::HTTPBadRequest.new('1.1', '401', 'Bad request')
81
+ exception = nil
82
+ begin
83
+ @client.call_webservice_action('Action', '<bananas>Yes, please</bananas>', Adyen::API::Response)
84
+ rescue Adyen::API::SimpleSOAPClient::ClientError => e
85
+ exception = e
86
+ end
87
+ msg = "[401 Bad request] A client error occurred while calling SOAP action `Action' on endpoint `https://test.example.com/soap/Action'."
88
+ exception.message.should == msg
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,417 @@
1
+ # encoding: UTF-8
2
+ require 'spec_helper'
3
+
4
+ require 'adyen/api'
5
+
6
+ require 'rubygems'
7
+ require 'nokogiri'
8
+ require 'rexml/document'
9
+
10
+ Adyen.configuration.default_api_params = { :merchant_account => 'SuperShopper' }
11
+ Adyen.configuration.api_username = 'SuperShopper'
12
+ Adyen.configuration.api_password = 'secret'
13
+
14
+ module Net
15
+ class HTTP
16
+ class Post
17
+ attr_reader :header
18
+ attr_reader :assigned_basic_auth
19
+
20
+ alias old_basic_auth basic_auth
21
+ def basic_auth(username, password)
22
+ if Net::HTTP.stubbing_enabled
23
+ @assigned_basic_auth = [username, password]
24
+ else
25
+ old_basic_auth(username, password)
26
+ end
27
+ end
28
+
29
+ def soap_action
30
+ header['soapaction'].first
31
+ end
32
+ end
33
+
34
+ class << self
35
+ attr_accessor :stubbing_enabled, :posted, :stubbed_response
36
+
37
+ def stubbing_enabled=(enabled)
38
+ reset! if @stubbing_enabled = enabled
39
+ end
40
+
41
+ def reset!
42
+ @posted = nil
43
+ @stubbed_response = nil
44
+ end
45
+ end
46
+
47
+ def host
48
+ @address
49
+ end
50
+
51
+ alias old_start start
52
+ def start(&block)
53
+ Net::HTTP.stubbing_enabled ? yield(self) : old_start(&block)
54
+ end
55
+
56
+ alias old_request request
57
+ def request(request)
58
+ if Net::HTTP.stubbing_enabled
59
+ self.class.posted = [self, request]
60
+ self.class.stubbed_response
61
+ else
62
+ old_request(request)
63
+ end
64
+ end
65
+ end
66
+ end
67
+
68
+ module Adyen
69
+ module API
70
+ class PaymentService
71
+ public :authorise_payment_request_body,
72
+ :authorise_recurring_payment_request_body,
73
+ :authorise_one_click_payment_request_body,
74
+ :capture_request_body, :refund_request_body,
75
+ :cancel_or_refund_request_body,
76
+ :cancel_request_body
77
+ end
78
+
79
+ class RecurringService
80
+ public :list_request_body, :disable_request_body
81
+ end
82
+ end
83
+ end
84
+
85
+ module APISpecHelper
86
+ def node_for_current_object_and_method
87
+ Adyen::API::XMLQuerier.new(@object.send(@method))
88
+ end
89
+
90
+ def xpath(query, &block)
91
+ node_for_current_method.xpath(query, &block)
92
+ end
93
+
94
+ def text(query)
95
+ node_for_current_method.text(query)
96
+ end
97
+
98
+ def stub_net_http(response_body)
99
+ Net::HTTP.stubbing_enabled = true
100
+ response = Net::HTTPOK.new('1.1', '200', 'OK')
101
+ response.stub!(:body).and_return(response_body)
102
+ Net::HTTP.stubbed_response = response
103
+ end
104
+
105
+ def self.included(klass)
106
+ klass.extend ClassMethods
107
+ end
108
+
109
+ module ClassMethods
110
+ def for_each_xml_backend(&block)
111
+ [:nokogiri, :rexml].each do |xml_backend|
112
+ describe "with a #{xml_backend} backend" do
113
+ before { Adyen::API::XMLQuerier.backend = xml_backend }
114
+ after { Adyen::API::XMLQuerier.backend = :nokogiri }
115
+ instance_eval(&block)
116
+ end
117
+ end
118
+ end
119
+
120
+ def it_should_have_shortcut_methods_for_params_on_the_response
121
+ it "provides shortcut methods, on the response object, for all entries in the #params hash" do
122
+ @response.params.each do |key, value|
123
+ @response.send(key).should == value
124
+ end
125
+ end
126
+ end
127
+
128
+ def it_should_return_params_for_each_xml_backend(params)
129
+ for_each_xml_backend do
130
+ it "returns a hash with parsed response details" do
131
+ @object.send(@method).params.should == params
132
+ end
133
+ end
134
+ end
135
+
136
+ def it_should_validate_request_parameters(*params)
137
+ params.each do |param|
138
+ case param
139
+ when Symbol
140
+ it_should_validate_request_param(param) { @object.params[param] = '' }
141
+ when Hash
142
+ param.each do |name, attrs|
143
+ it_should_validate_request_param(name) { @object.params[name] = nil }
144
+ attrs.each do |attr|
145
+ it_should_validate_request_param("#{name} => :#{attr}") { @object.params[name][attr] = nil }
146
+ end
147
+ end
148
+ end
149
+ end
150
+ end
151
+
152
+ def it_should_validate_request_param(name, &block)
153
+ it "validates the `#{name}' request parameter" do
154
+ instance_eval &block
155
+ lambda { @object.send(@method) }.should raise_error(ArgumentError)
156
+ end
157
+ end
158
+
159
+ def describe_response_from(method, response, soap_action = 'authorise', &block)
160
+ describe(method) do
161
+ before do
162
+ stub_net_http(response)
163
+ @method = method
164
+ @object.params.merge!(:psp_reference => '9876543210987654')
165
+ @response = @object.send(@method)
166
+ @request, @post = Net::HTTP.posted
167
+ end
168
+
169
+ after do
170
+ Net::HTTP.stubbing_enabled = false
171
+ end
172
+
173
+ it "posts the body generated for the given parameters" do
174
+ @post.body.should == Adyen::API::SimpleSOAPClient::ENVELOPE % @object.send("#{@method}_request_body")
175
+ end
176
+
177
+ it "posts to the correct SOAP action" do
178
+ @post.soap_action.should == soap_action
179
+ end
180
+
181
+ it_should_have_shortcut_methods_for_params_on_the_response
182
+
183
+ instance_eval(&block)
184
+ end
185
+ end
186
+
187
+ def describe_request_body_of(method, xpath = nil, &block)
188
+ method = "#{method}_request_body"
189
+ describe(method) do
190
+ before { @method = method }
191
+ if xpath
192
+ define_method(:node_for_current_method) do
193
+ node_for_current_object_and_method.xpath(xpath)
194
+ end
195
+ end
196
+ instance_eval(&block)
197
+ end
198
+ end
199
+
200
+ def describe_modification_request_body_of(method, camelized_method = nil, &block)
201
+ describe_request_body_of method, "//payment:#{camelized_method || method}/payment:modificationRequest" do
202
+ before do
203
+ @payment.params[:psp_reference] = 'original-psp-reference'
204
+ end
205
+
206
+ it "includes the merchant account" do
207
+ text('./payment:merchantAccount').should == 'SuperShopper'
208
+ end
209
+
210
+ it "includes the payment (PSP) reference of the payment to refund" do
211
+ text('./payment:originalReference').should == 'original-psp-reference'
212
+ end
213
+
214
+ instance_eval(&block) if block_given?
215
+ end
216
+ end
217
+ end
218
+ end
219
+
220
+ AUTHORISE_RESPONSE = <<EOS
221
+ <?xml version="1.0" encoding="UTF-8"?>
222
+ <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
223
+ <soap:Body>
224
+ <ns1:authoriseResponse xmlns:ns1="http://payment.services.adyen.com">
225
+ <ns1:paymentResult>
226
+ <additionalData xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
227
+ <authCode xmlns="http://payment.services.adyen.com">1234</authCode>
228
+ <dccAmount xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
229
+ <dccSignature xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
230
+ <fraudResult xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
231
+ <issuerUrl xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
232
+ <md xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
233
+ <paRequest xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
234
+ <pspReference xmlns="http://payment.services.adyen.com">9876543210987654</pspReference>
235
+ <refusalReason xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
236
+ <resultCode xmlns="http://payment.services.adyen.com">Authorised</resultCode>
237
+ </ns1:paymentResult>
238
+ </ns1:authoriseResponse>
239
+ </soap:Body>
240
+ </soap:Envelope>
241
+ EOS
242
+
243
+ AUTHORISATION_DECLINED_RESPONSE = <<EOS
244
+ <?xml version="1.0" encoding="UTF-8"?>
245
+ <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
246
+ <soap:Body>
247
+ <ns1:authoriseResponse xmlns:ns1="http://payment.services.adyen.com">
248
+ <ns1:paymentResult>
249
+ <additionalData xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
250
+ <authCode xmlns="http://payment.services.adyen.com">1234</authCode>
251
+ <dccAmount xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
252
+ <dccSignature xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
253
+ <fraudResult xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
254
+ <issuerUrl xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
255
+ <md xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
256
+ <paRequest xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
257
+ <pspReference xmlns="http://payment.services.adyen.com">9876543210987654</pspReference>
258
+ <refusalReason xmlns="http://payment.services.adyen.com">You need to actually own money.</refusalReason>
259
+ <resultCode xmlns="http://payment.services.adyen.com">Refused</resultCode>
260
+ </ns1:paymentResult>
261
+ </ns1:authoriseResponse>
262
+ </soap:Body>
263
+ </soap:Envelope>
264
+ EOS
265
+
266
+ AUTHORISE_REQUEST_INVALID_RESPONSE = <<EOS
267
+ <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
268
+ <soap:Body>
269
+ <soap:Fault>
270
+ <faultcode>soap:Server</faultcode>
271
+ <faultstring>%s</faultstring>
272
+ </soap:Fault>
273
+ </soap:Body>
274
+ </soap:Envelope>
275
+ EOS
276
+
277
+ LIST_RESPONSE = <<EOS
278
+ <?xml version="1.0"?>
279
+ <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
280
+ <soap:Body>
281
+ <ns1:listRecurringDetailsResponse xmlns:ns1="http://recurring.services.adyen.com">
282
+ <ns1:result xmlns:ns2="http://payment.services.adyen.com">
283
+ <ns1:creationDate>2009-10-27T11:26:22.203+01:00</ns1:creationDate>
284
+ <details xmlns="http://recurring.services.adyen.com">
285
+ <RecurringDetail>
286
+ <bank xsi:nil="true"/>
287
+ <card>
288
+ <cvc xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
289
+ <expiryMonth xmlns="http://payment.services.adyen.com">12</expiryMonth>
290
+ <expiryYear xmlns="http://payment.services.adyen.com">2012</expiryYear>
291
+ <holderName xmlns="http://payment.services.adyen.com">S. Hopper</holderName>
292
+ <issueNumber xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
293
+ <number xmlns="http://payment.services.adyen.com">1111</number>
294
+ <startMonth xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
295
+ <startYear xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
296
+ </card>
297
+ <creationDate>2009-10-27T11:50:12.178+01:00</creationDate>
298
+ <elv xsi:nil="true"/>
299
+ <name/>
300
+ <recurringDetailReference>RecurringDetailReference1</recurringDetailReference>
301
+ <variant>mc</variant>
302
+ </RecurringDetail>
303
+ <RecurringDetail>
304
+ <bank>
305
+ <bankAccountNumber xmlns="http://payment.services.adyen.com">123456789</bankAccountNumber>
306
+ <bankLocationId xmlns="http://payment.services.adyen.com">bank-location-id</bankLocationId>
307
+ <bankName xmlns="http://payment.services.adyen.com">AnyBank</bankName>
308
+ <bic xmlns="http://payment.services.adyen.com">BBBBCCLLbbb</bic>
309
+ <countryCode xmlns="http://payment.services.adyen.com">NL</countryCode>
310
+ <iban xmlns="http://payment.services.adyen.com">NL69PSTB0001234567</iban>
311
+ <ownerName xmlns="http://payment.services.adyen.com">S. Hopper</ownerName>
312
+ </bank>
313
+ <card xsi:nil="true"/>
314
+ <creationDate>2009-10-27T11:26:22.216+01:00</creationDate>
315
+ <elv xsi:nil="true"/>
316
+ <name/>
317
+ <recurringDetailReference>RecurringDetailReference2</recurringDetailReference>
318
+ <variant>IDEAL</variant>
319
+ </RecurringDetail>
320
+ </details>
321
+ <ns1:lastKnownShopperEmail>s.hopper@example.com</ns1:lastKnownShopperEmail>
322
+ <ns1:shopperReference>user-id</ns1:shopperReference>
323
+ </ns1:result>
324
+ </ns1:listRecurringDetailsResponse>
325
+ </soap:Body>
326
+ </soap:Envelope>
327
+ EOS
328
+
329
+ LIST_EMPTY_RESPONSE = <<EOS
330
+ <?xml version="1.0"?>
331
+ <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
332
+ <soap:Body>
333
+ <ns1:listRecurringDetailsResponse xmlns:ns1="http://recurring.services.adyen.com">
334
+ <ns1:result>
335
+ <details xmlns="http://recurring.services.adyen.com"/>
336
+ <lastKnownShopperEmail xmlns="http://recurring.services.adyen.com" xsi:nil="true"/>
337
+ <shopperReference xmlns="http://recurring.services.adyen.com" xsi:nil="true"/>
338
+ </ns1:result>
339
+ </ns1:listRecurringDetailsResponse>
340
+ </soap:Body>
341
+ </soap:Envelope>
342
+ EOS
343
+
344
+ DISABLE_RESPONSE = <<EOS
345
+ <?xml version="1.0"?>
346
+ <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
347
+ <soap:Body>
348
+ <ns1:disableResponse xmlns:ns1="http://recurring.services.adyen.com">
349
+ <ns1:result>
350
+ <response xmlns="http://recurring.services.adyen.com">
351
+ %s
352
+ </response>
353
+ </ns1:result>
354
+ </ns1:disableResponse>
355
+ </soap:Body>
356
+ </soap:Envelope>
357
+ EOS
358
+
359
+ REFUND_RESPONSE = <<EOS
360
+ <?xml version="1.0"?>
361
+ <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
362
+ <soap:Body>
363
+ <ns1:refundResponse xmlns:ns1="http://payment.services.adyen.com">
364
+ <ns1:refundResult>
365
+ <additionalData xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
366
+ <pspReference xmlns="http://payment.services.adyen.com">8512865475512126</pspReference>
367
+ <response xmlns="http://payment.services.adyen.com">%s</response>
368
+ </ns1:refundResult>
369
+ </ns1:refundResponse>
370
+ </soap:Body>
371
+ </soap:Envelope>
372
+ EOS
373
+
374
+ CANCEL_OR_REFUND_RESPONSE = <<EOS
375
+ <?xml version="1.0"?>
376
+ <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
377
+ <soap:Body>
378
+ <ns1:cancelOrRefundResponse xmlns:ns1="http://payment.services.adyen.com">
379
+ <ns1:cancelOrRefundResult>
380
+ <additionalData xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
381
+ <pspReference xmlns="http://payment.services.adyen.com">8512865521218306</pspReference>
382
+ <response xmlns="http://payment.services.adyen.com">%s</response>
383
+ </ns1:cancelOrRefundResult>
384
+ </ns1:cancelOrRefundResponse>
385
+ </soap:Body>
386
+ </soap:Envelope>
387
+ EOS
388
+
389
+ CANCEL_RESPONSE = <<EOS
390
+ <?xml version="1.0"?>
391
+ <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
392
+ <soap:Body>
393
+ <ns1:cancelResponse xmlns:ns1="http://payment.services.adyen.com">
394
+ <ns1:cancelResult>
395
+ <additionalData xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
396
+ <pspReference xmlns="http://payment.services.adyen.com">8612865544848013</pspReference>
397
+ <response xmlns="http://payment.services.adyen.com">%s</response>
398
+ </ns1:cancelResult>
399
+ </ns1:cancelResponse>
400
+ </soap:Body>
401
+ </soap:Envelope>
402
+ EOS
403
+
404
+ CAPTURE_RESPONSE = <<EOS
405
+ <?xml version="1.0"?>
406
+ <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
407
+ <soap:Body>
408
+ <ns1:captureResponse xmlns:ns1="http://payment.services.adyen.com">
409
+ <ns1:captureResult>
410
+ <additionalData xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
411
+ <pspReference xmlns="http://payment.services.adyen.com">8512867956198946</pspReference>
412
+ <response xmlns="http://payment.services.adyen.com">%s</response>
413
+ </ns1:captureResult>
414
+ </ns1:captureResponse>
415
+ </soap:Body>
416
+ </soap:Envelope>
417
+ EOS