adyen 0.3.8 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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