solidus_six_saferpay 0.1.7 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +35 -0
  3. data/.gem_release.yml +5 -0
  4. data/.github/stale.yml +17 -0
  5. data/.gitignore +18 -0
  6. data/.rspec +2 -0
  7. data/.rubocop.yml +2 -0
  8. data/.travis.yml +12 -0
  9. data/Gemfile +33 -0
  10. data/LICENSE +26 -0
  11. data/README.md +36 -20
  12. data/Rakefile +4 -54
  13. data/app/assets/config/solidus_six_saferpay_manifest.js +1 -0
  14. data/app/assets/images/solidus_six_saferpay/.keep +0 -0
  15. data/app/assets/javascripts/solidus_six_saferpay/saferpay_payment.js +4 -1
  16. data/app/assets/javascripts/spree/backend/solidus_six_saferpay.js +2 -0
  17. data/app/assets/javascripts/spree/frontend/solidus_six_saferpay.js +2 -0
  18. data/app/assets/stylesheets/spree/backend/solidus_six_saferpay.css +4 -0
  19. data/app/assets/stylesheets/spree/frontend/solidus_six_saferpay.css +4 -0
  20. data/app/controllers/spree/solidus_six_saferpay/checkout_controller.rb +82 -16
  21. data/app/controllers/spree/solidus_six_saferpay/transaction/checkout_controller.rb +1 -1
  22. data/app/models/spree/payment_method/saferpay_payment_method.rb +1 -1
  23. data/app/models/spree/payment_method/saferpay_payment_page.rb +2 -2
  24. data/app/models/spree/payment_method/saferpay_transaction.rb +2 -2
  25. data/app/services/spree/solidus_six_saferpay/cancel_authorized_payment.rb +33 -0
  26. data/app/services/spree/solidus_six_saferpay/initialize_payment.rb +0 -1
  27. data/app/services/spree/solidus_six_saferpay/initialize_transaction.rb +0 -1
  28. data/app/services/spree/solidus_six_saferpay/inquire_payment.rb +27 -1
  29. data/app/services/spree/solidus_six_saferpay/order_not_found_handler.rb +28 -0
  30. data/app/services/spree/solidus_six_saferpay/payment_not_found_handler.rb +28 -0
  31. data/app/services/spree/solidus_six_saferpay/payment_processing_success_handler.rb +26 -0
  32. data/app/views/spree/checkout/payment/_saferpay_payment.html.erb +2 -2
  33. data/app/views/spree/solidus_six_saferpay/checkout/{iframe_breakout_redirect.html.erb → iframe_breakout_redirect.erb} +1 -1
  34. data/bin/console +17 -0
  35. data/bin/rails +18 -0
  36. data/bin/rake +7 -0
  37. data/bin/setup +8 -0
  38. data/config/initializers/assets.rb +3 -0
  39. data/config/locales/de.yml +3 -0
  40. data/config/locales/en.yml +3 -0
  41. data/config/locales/fr.yml +3 -0
  42. data/config/routes.rb +8 -8
  43. data/lib/generators/solidus_six_saferpay/install/install_generator.rb +15 -3
  44. data/lib/solidus_six_saferpay.rb +6 -3
  45. data/lib/solidus_six_saferpay/configuration.rb +2 -7
  46. data/lib/solidus_six_saferpay/engine.rb +19 -10
  47. data/lib/solidus_six_saferpay/gateway.rb +11 -11
  48. data/lib/solidus_six_saferpay/payment_page_gateway.rb +8 -9
  49. data/lib/solidus_six_saferpay/transaction_gateway.rb +8 -9
  50. data/lib/solidus_six_saferpay/version.rb +3 -1
  51. data/solidus_six_saferpay.gemspec +42 -0
  52. data/spec/controllers/spree/solidus_six_saferpay/payment_page/checkout_controller_spec.rb +16 -0
  53. data/spec/controllers/spree/solidus_six_saferpay/transaction/checkout_controller_spec.rb +16 -0
  54. data/spec/factories/payment_methods.rb +23 -0
  55. data/spec/factories/payments.rb +11 -0
  56. data/spec/factories/spree/six_saferpay_payments.rb +118 -0
  57. data/spec/models/spree/six_saferpay_payment_spec.rb +203 -0
  58. data/spec/rails_helper.rb +73 -0
  59. data/spec/services/spree/solidus_six_saferpay/assert_payment_page_spec.rb +22 -0
  60. data/spec/services/spree/solidus_six_saferpay/authorize_payment_spec.rb +39 -0
  61. data/spec/services/spree/solidus_six_saferpay/authorize_transaction_spec.rb +24 -0
  62. data/spec/services/spree/solidus_six_saferpay/cancel_authorized_payment_spec.rb +58 -0
  63. data/spec/services/spree/solidus_six_saferpay/initialize_payment_page_spec.rb +81 -0
  64. data/spec/services/spree/solidus_six_saferpay/initialize_payment_spec.rb +40 -0
  65. data/spec/services/spree/solidus_six_saferpay/initialize_transaction_spec.rb +84 -0
  66. data/spec/services/spree/solidus_six_saferpay/inquire_payment_page_payment_spec.rb +20 -0
  67. data/spec/services/spree/solidus_six_saferpay/inquire_payment_spec.rb +39 -0
  68. data/spec/services/spree/solidus_six_saferpay/inquire_transaction_payment_spec.rb +21 -0
  69. data/spec/services/spree/solidus_six_saferpay/order_not_found_handler_spec.rb +30 -0
  70. data/spec/services/spree/solidus_six_saferpay/payment_not_found_handler_spec.rb +30 -0
  71. data/spec/services/spree/solidus_six_saferpay/payment_processing_success_handler_spec.rb +34 -0
  72. data/spec/services/spree/solidus_six_saferpay/payment_validator_spec.rb +100 -0
  73. data/spec/services/spree/solidus_six_saferpay/process_authorized_payment_spec.rb +39 -0
  74. data/spec/services/spree/solidus_six_saferpay/process_payment_page_payment_spec.rb +20 -0
  75. data/spec/services/spree/solidus_six_saferpay/process_transaction_payment_spec.rb +20 -0
  76. data/spec/solidus_six_saferpay/configuration_spec.rb +12 -0
  77. data/spec/solidus_six_saferpay/error_handler_spec.rb +65 -0
  78. data/spec/solidus_six_saferpay/gateway_response_spec.rb +70 -0
  79. data/spec/solidus_six_saferpay/gateway_spec.rb +365 -0
  80. data/spec/solidus_six_saferpay/payment_page_gateway_spec.rb +392 -0
  81. data/spec/solidus_six_saferpay/transaction_gateway_spec.rb +390 -0
  82. data/spec/spec_helper.rb +21 -0
  83. data/spec/support/route_access.rb +6 -0
  84. data/spec/support/shared_examples/authorize_payment.rb +132 -0
  85. data/spec/support/shared_examples/checkout_controller.rb +294 -0
  86. data/spec/support/shared_examples/inquire_payment.rb +118 -0
  87. data/spec/support/shared_examples/process_authorized_payment.rb +202 -0
  88. data/spec/support/uses_payment_page_gateway.rb +29 -0
  89. data/spec/support/uses_transaction_gateway.rb +28 -0
  90. metadata +261 -62
  91. data/app/services/spree/solidus_six_saferpay/inquire_transaction.rb +0 -7
@@ -0,0 +1,365 @@
1
+ require 'rails_helper'
2
+
3
+ module SolidusSixSaferpay
4
+ RSpec.describe Gateway do
5
+ # config options
6
+ let(:customer_id) { 'CUSTOMER_ID' }
7
+ let(:terminal_id) { 'TERMINAL_ID' }
8
+ let(:username) { 'USERNAME' }
9
+ let(:password) { 'PASSWORD' }
10
+ let(:base_url) { 'https://test.saferpay-api-host.test' }
11
+ let(:css_url) { '/custom/css/url' }
12
+
13
+ let(:gateway) do
14
+ described_class.new(
15
+ customer_id: customer_id,
16
+ terminal_id: terminal_id,
17
+ username: username,
18
+ password: password,
19
+ base_url: base_url,
20
+ css_url: css_url
21
+ )
22
+ end
23
+
24
+ describe '#new' do
25
+
26
+ it 'configures the API client' do
27
+ gateway = described_class.new(
28
+ customer_id: customer_id,
29
+ terminal_id: terminal_id,
30
+ username: username,
31
+ password: password,
32
+ base_url: base_url,
33
+ css_url: css_url
34
+ )
35
+
36
+ config = SixSaferpay.config
37
+
38
+ expect(config.customer_id).to eq(customer_id)
39
+ expect(config.terminal_id).to eq(terminal_id)
40
+ expect(config.username).to eq(username)
41
+ expect(config.password).to eq(password)
42
+ expect(config.base_url).to eq(base_url)
43
+ expect(config.css_url).to eq(css_url)
44
+ end
45
+
46
+ context 'when global options are not passed' do
47
+
48
+ before do
49
+ allow(ENV).to receive(:fetch).with('SIX_SAFERPAY_CUSTOMER_ID').and_return(customer_id)
50
+ allow(ENV).to receive(:fetch).with('SIX_SAFERPAY_TERMINAL_ID').and_return(terminal_id)
51
+ allow(ENV).to receive(:fetch).with('SIX_SAFERPAY_USERNAME').and_return(username)
52
+ allow(ENV).to receive(:fetch).with('SIX_SAFERPAY_PASSWORD').and_return(password)
53
+ allow(ENV).to receive(:fetch).with('SIX_SAFERPAY_BASE_URL').and_return(base_url)
54
+ allow(ENV).to receive(:fetch).with('SIX_SAFERPAY_CSS_URL').and_return(css_url)
55
+ end
56
+
57
+ it 'falls back to ENV vars' do
58
+ gateway = described_class.new
59
+
60
+ config = SixSaferpay.config
61
+
62
+ expect(config.customer_id).to eq(customer_id)
63
+ expect(config.terminal_id).to eq(terminal_id)
64
+ expect(config.username).to eq(username)
65
+ expect(config.password).to eq(password)
66
+ expect(config.base_url).to eq(base_url)
67
+ expect(config.css_url).to eq(css_url)
68
+ end
69
+ end
70
+ end
71
+
72
+ describe '#initialize_payment' do
73
+
74
+ let(:order) { create(:order) }
75
+ let(:payment_method) { create(:saferpay_payment_method) }
76
+
77
+ it 'fails because it does not know which interface to use' do
78
+ expect { gateway.initialize_payment(order, payment_method) }.to raise_error(NotImplementedError)
79
+ end
80
+ end
81
+
82
+ describe '#authorize' do
83
+
84
+ let(:payment) { create(:six_saferpay_payment) }
85
+ let(:amount) { payment.order.total }
86
+
87
+ it 'fails because authorize must be defined in a subclass' do
88
+ expect { gateway.authorize(amount, payment) }.to raise_error(NotImplementedError)
89
+ end
90
+ end
91
+
92
+ describe '#inquire' do
93
+
94
+ let(:payment) { create(:six_saferpay_payment) }
95
+
96
+ it 'fails because inquire must be defined in a subclass' do
97
+ expect { gateway.inquire(payment) }.to raise_error(NotImplementedError)
98
+ end
99
+ end
100
+
101
+ describe '#purchase' do
102
+ let(:payment) { create(:six_saferpay_payment) }
103
+ let(:amount) { payment.order.total }
104
+
105
+ it 'delegates to capture (with a different signature)' do
106
+ expect(gateway).to receive(:capture).with(amount, payment.transaction_id, {})
107
+
108
+ gateway.purchase(amount, payment)
109
+ end
110
+
111
+ end
112
+
113
+ describe '#capture' do
114
+ let(:amount) { 500 }
115
+ let(:transaction_id) { "TRANSACTION_ID" }
116
+
117
+ let(:api_capture_response) do
118
+ SixSaferpay::SixTransaction::CaptureResponse.new(
119
+ response_header: SixSaferpay::ResponseHeader.new(request_id: 'request_id', spec_version: 'test'),
120
+ capture_id: 'CAPTURE_ID',
121
+ status: 'CAPTURED',
122
+ date: '2015-01-30T12:45:22.258+01:00'
123
+ )
124
+ end
125
+
126
+ let(:transaction_reference) { instance_double("SixSaferpay::TransactionReference", transaction_id: transaction_id) }
127
+ let(:saferpay_capture) { instance_double("SixSaferpay::SixTransaction::Capture") }
128
+
129
+ it 'captures the given transaction via the Saferpay API' do
130
+ expect(SixSaferpay::TransactionReference).to receive(:new).with(transaction_id: transaction_id).and_return(transaction_reference)
131
+ expect(SixSaferpay::SixTransaction::Capture).to receive(:new).with(transaction_reference: transaction_reference).and_return(saferpay_capture)
132
+ expect(SixSaferpay::Client).to receive(:post).with(saferpay_capture).and_return(api_capture_response)
133
+
134
+ gateway.capture(amount, transaction_id)
135
+ end
136
+
137
+ context 'when the capture is successful' do
138
+ before do
139
+ allow(SixSaferpay::Client).to receive(:post).with(instance_of(SixSaferpay::SixTransaction::Capture)).and_return(api_capture_response)
140
+ end
141
+
142
+ it 'returns a success gateway response' do
143
+ expect(GatewayResponse).to receive(:new).with(true, instance_of(String), api_capture_response, { authorization: api_capture_response.capture_id } )
144
+
145
+ gateway.capture(amount, transaction_id)
146
+ end
147
+ end
148
+
149
+ context 'when the API raises an error' do
150
+ let(:six_saferpay_error) do
151
+ SixSaferpay::Error.new(
152
+ response_header: SixSaferpay::ResponseHeader.new(request_id: 'request_id', spec_version: 'test'),
153
+ behavior: 'ABORT',
154
+ error_name: 'INVALID_TRANSACTION',
155
+ error_message: 'error_message'
156
+ )
157
+ end
158
+
159
+ before do
160
+ allow(SixSaferpay::Client).to receive(:post).with(instance_of(SixSaferpay::SixTransaction::Capture)).and_raise(six_saferpay_error)
161
+ end
162
+
163
+ it 'handles the error gracefully' do
164
+ expect(GatewayResponse).to receive(:new).with(false, six_saferpay_error.error_message, nil, error_name: six_saferpay_error.error_name)
165
+
166
+ gateway.capture(amount, transaction_id)
167
+ end
168
+ end
169
+ end
170
+
171
+ describe '#void' do
172
+ let(:transaction_id) { 'TRANSACTION_ID' }
173
+
174
+ let(:transaction_reference) { instance_double("SixSaferpay::TransactionReference") }
175
+ let(:saferpay_cancel) { instance_double("SixSaferpay::SixTransaction::Cancel") }
176
+
177
+ let(:api_cancel_response) do
178
+ SixSaferpay::SixTransaction::CancelResponse.new(
179
+ response_header: SixSaferpay::ResponseHeader.new(request_id: 'request_id', spec_version: 'test'),
180
+ transaction_id: transaction_id,
181
+ )
182
+ end
183
+
184
+ it 'cancels the payment' do
185
+ expect(SixSaferpay::TransactionReference).to receive(:new).with(transaction_id: transaction_id).and_return(transaction_reference)
186
+ expect(SixSaferpay::SixTransaction::Cancel).to receive(:new).with(transaction_reference: transaction_reference).and_return(saferpay_cancel)
187
+ expect(SixSaferpay::Client).to receive(:post).with(saferpay_cancel).and_return(api_cancel_response)
188
+
189
+ gateway.void(transaction_id)
190
+ end
191
+
192
+ context 'when the cancellation is successful' do
193
+ before do
194
+ allow(SixSaferpay::Client).to receive(:post).with(instance_of(SixSaferpay::SixTransaction::Cancel)).and_return(api_cancel_response)
195
+ end
196
+
197
+ it 'returns a success gateway response' do
198
+ expect(GatewayResponse).to receive(:new).with(true, instance_of(String), api_cancel_response, {})
199
+
200
+ gateway.void(transaction_id)
201
+ end
202
+ end
203
+
204
+ context 'when the API raises an error' do
205
+ let(:six_saferpay_error) do
206
+ SixSaferpay::Error.new(
207
+ response_header: SixSaferpay::ResponseHeader.new(request_id: 'request_id', spec_version: 'test'),
208
+ behavior: 'ABORT',
209
+ error_name: 'INVALID_TRANSACTION',
210
+ error_message: 'error_message'
211
+ )
212
+ end
213
+
214
+ before do
215
+ allow(SixSaferpay::Client).to receive(:post).with(instance_of(SixSaferpay::SixTransaction::Cancel)).and_raise(six_saferpay_error)
216
+ end
217
+
218
+ it 'handles the error gracefully' do
219
+ expect(GatewayResponse).to receive(:new).with(false, six_saferpay_error.error_message, nil, error_name: six_saferpay_error.error_name)
220
+
221
+ gateway.void(transaction_id)
222
+ end
223
+ end
224
+ end
225
+
226
+ describe '#try_void' do
227
+ let(:transaction_id) { "TRANSACTION_ID" }
228
+ let(:payment) { create(:payment, response_code: transaction_id) }
229
+
230
+ context 'if payment is in checkout state and has transaction_id' do
231
+ it 'voids the payment' do
232
+ expect(gateway).to receive(:void).with(transaction_id, originator: gateway)
233
+
234
+ gateway.try_void(payment)
235
+ end
236
+ end
237
+ end
238
+
239
+ describe '#credit' do
240
+ let(:amount) { 400 }
241
+ let(:transaction_id) { 'TRANSACTION_ID' }
242
+ let(:options) { {a: 'a', b: 'b'} }
243
+
244
+ it 'is aliased to #refund' do
245
+ expect(gateway).to receive(:refund).with(amount, transaction_id, options)
246
+
247
+ gateway.credit(amount, transaction_id, options)
248
+ end
249
+ end
250
+
251
+ describe '#refund' do
252
+ let(:transaction_amount) { 400 }
253
+ let(:refund_amount) { 300 }
254
+ let(:transaction_id) { 'TRANSACTION_ID' }
255
+ let(:refund_id) { 'REFUND_ID' }
256
+
257
+ let!(:payment) { create(:payment_using_saferpay, response_code: transaction_id, amount: transaction_amount) }
258
+
259
+ let(:saferpay_refund) do
260
+ amount = SixSaferpay::Amount.new(value: (refund_amount * 100), currency_code: payment.order.currency)
261
+ refund = SixSaferpay::Refund.new(amount: amount, order_id: payment.order.number)
262
+ capture_reference = SixSaferpay::CaptureReference.new(capture_id: transaction_id)
263
+
264
+ SixSaferpay::SixTransaction::Refund.new(
265
+ refund: refund,
266
+ capture_reference: capture_reference
267
+ )
268
+ end
269
+
270
+ let(:api_refund_response) do
271
+ transaction = SixSaferpay::Transaction.new(
272
+ type: 'REFUND',
273
+ status: 'AUTHORIZED',
274
+ id: refund_id,
275
+ date: '2015-01-30T12:45:22.258+01:00',
276
+ amount: SixSaferpay::Amount.new(
277
+ value: refund_amount,
278
+ currency_code: payment.order.currency
279
+ ),
280
+ six_transaction_reference: 'SIX_TRANSACTION_REFERENCE'
281
+ )
282
+
283
+ payment_means = SixSaferpay::ResponsePaymentMeans.new(
284
+ brand: SixSaferpay::Brand.new(name: 'BrandName'),
285
+ display_text: 'xxxxxxxxxxxx1234'
286
+ )
287
+
288
+ SixSaferpay::SixTransaction::RefundResponse.new(
289
+ response_header: SixSaferpay::ResponseHeader.new(request_id: 'request_id', spec_version: 'test'),
290
+ transaction: transaction,
291
+ payment_means: payment_means
292
+ )
293
+ end
294
+
295
+ it 'refunds and directly captures the payment' do
296
+ expect(SixSaferpay::SixTransaction::Refund).to receive(:new).with(refund: instance_of(SixSaferpay::Refund), capture_reference: instance_of(SixSaferpay::CaptureReference)).and_return(saferpay_refund)
297
+
298
+ expect(SixSaferpay::Client).to receive(:post).with(saferpay_refund).and_return(api_refund_response)
299
+
300
+ expect(gateway).to receive(:capture).with(refund_amount, refund_id, {})
301
+
302
+ gateway.refund(refund_amount, transaction_id)
303
+ end
304
+
305
+ context 'when the refund is successful' do
306
+ let(:api_capture_response) do
307
+ SixSaferpay::SixTransaction::CaptureResponse.new(
308
+ response_header: SixSaferpay::ResponseHeader.new(request_id: 'request_id', spec_version: 'test'),
309
+ capture_id: 'CAPTURE_ID',
310
+ status: 'CAPTURED',
311
+ date: '2015-01-30T12:45:22.258+01:00'
312
+ )
313
+ end
314
+
315
+ before do
316
+ allow(SixSaferpay::Client).to receive(:post).with(instance_of(SixSaferpay::SixTransaction::Refund)).and_return(api_refund_response)
317
+ allow(SixSaferpay::Client).to receive(:post).with(instance_of(SixSaferpay::SixTransaction::Capture)).and_return(api_capture_response)
318
+ end
319
+
320
+ it 'returns a success gateway response' do
321
+ expect(GatewayResponse).to receive(:new).with(true, instance_of(String), api_capture_response, { authorization: 'CAPTURE_ID' })
322
+
323
+ gateway.refund(refund_amount, transaction_id)
324
+ end
325
+ end
326
+
327
+ context 'when the API raises an error' do
328
+ let(:six_saferpay_error) do
329
+ SixSaferpay::Error.new(
330
+ response_header: SixSaferpay::ResponseHeader.new(request_id: 'request_id', spec_version: 'test'),
331
+ behavior: 'ABORT',
332
+ error_name: 'INVALID_TRANSACTION',
333
+ error_message: 'error_message'
334
+ )
335
+ end
336
+
337
+ context 'during refunding' do
338
+ before do
339
+ allow(SixSaferpay::Client).to receive(:post).with(instance_of(SixSaferpay::SixTransaction::Refund)).and_raise(six_saferpay_error)
340
+ end
341
+
342
+ it 'handles the error gracefully' do
343
+ expect(GatewayResponse).to receive(:new).with(false, six_saferpay_error.error_message, nil, error_name: six_saferpay_error.error_name)
344
+
345
+ gateway.refund(refund_amount, transaction_id)
346
+ end
347
+ end
348
+
349
+ context 'during capture' do
350
+ before do
351
+ allow(SixSaferpay::Client).to receive(:post).with(instance_of(SixSaferpay::SixTransaction::Refund)).and_return(api_refund_response)
352
+ allow(SixSaferpay::Client).to receive(:post).with(instance_of(SixSaferpay::SixTransaction::Capture)).and_raise(six_saferpay_error)
353
+ end
354
+
355
+ it 'handles the error gracefully' do
356
+ expect(GatewayResponse).to receive(:new).with(false, six_saferpay_error.error_message, nil, error_name: six_saferpay_error.error_name)
357
+
358
+ gateway.refund(refund_amount, transaction_id)
359
+ end
360
+ end
361
+
362
+ end
363
+ end
364
+ end
365
+ end
@@ -0,0 +1,392 @@
1
+ require 'rails_helper'
2
+
3
+ module SolidusSixSaferpay
4
+ RSpec.describe PaymentPageGateway do
5
+
6
+ # config options
7
+ let(:customer_id) { 'CUSTOMER_ID' }
8
+ let(:terminal_id) { 'TERMINAL_ID' }
9
+ let(:username) { 'USERNAME' }
10
+ let(:password) { 'PASSWORD' }
11
+ let(:base_url) { 'https://test.saferpay-api-host.test' }
12
+ let(:css_url) { '/custom/css/url' }
13
+
14
+ let(:gateway) do
15
+ described_class.new(
16
+ customer_id: customer_id,
17
+ terminal_id: terminal_id,
18
+ username: username,
19
+ password: password,
20
+ base_url: base_url,
21
+ css_url: css_url
22
+ )
23
+ end
24
+
25
+ let(:order) { create(:order, total: 100) }
26
+ let(:payment_method) { create(:saferpay_payment_method) }
27
+
28
+ let(:payment) { create(:six_saferpay_payment, order: order, payment_method: payment_method) }
29
+
30
+ before do
31
+ allow(ENV).to receive(:fetch).with('SIX_SAFERPAY_CUSTOMER_ID').and_return(customer_id)
32
+ allow(ENV).to receive(:fetch).with('SIX_SAFERPAY_TERMINAL_ID').and_return(terminal_id)
33
+ allow(ENV).to receive(:fetch).with('SIX_SAFERPAY_USERNAME').and_return(username)
34
+ allow(ENV).to receive(:fetch).with('SIX_SAFERPAY_PASSWORD').and_return(password)
35
+ allow(ENV).to receive(:fetch).with('SIX_SAFERPAY_BASE_URL').and_return(base_url)
36
+ allow(ENV).to receive(:fetch).with('SIX_SAFERPAY_CSS_URL').and_return(css_url)
37
+ end
38
+
39
+ describe '#initialize_payment' do
40
+
41
+ let(:saferpay_billing_address) do
42
+ instance_double("SixSaferpay::Address",
43
+ first_name: order.billing_address.first_name,
44
+ last_name: order.billing_address.last_name,
45
+ date_of_birth: nil,
46
+ company: nil,
47
+ gender: nil,
48
+ legal_form: nil,
49
+ street: order.billing_address.address1,
50
+ street2: order.billing_address.address2,
51
+ zip: order.billing_address.zipcode,
52
+ city: order.billing_address.city,
53
+ country_subdevision_code: nil,
54
+ country_code: order.billing_address.country.iso,
55
+ phone: nil,
56
+ email: nil,
57
+ )
58
+ end
59
+
60
+ let(:saferpay_shipping_address) do
61
+ instance_double("SixSaferpay::Address",
62
+ first_name: order.shipping_address.first_name,
63
+ last_name: order.shipping_address.last_name,
64
+ date_of_birth: nil,
65
+ company: nil,
66
+ gender: nil,
67
+ legal_form: nil,
68
+ street: order.shipping_address.address1,
69
+ street2: order.shipping_address.address2,
70
+ zip: order.shipping_address.zipcode,
71
+ city: order.shipping_address.city,
72
+ country_subdevision_code: nil,
73
+ country_code: order.shipping_address.country.iso,
74
+ phone: nil,
75
+ email: nil,
76
+ )
77
+ end
78
+
79
+ let(:saferpay_amount) do
80
+ instance_double("SixSaferpay::Amount",
81
+ value: (order.total * 100),
82
+ currency_code: order.currency
83
+ )
84
+ end
85
+
86
+ let(:saferpay_payment) do
87
+ instance_double("SixSaferpay::Payment",
88
+ amount: saferpay_amount,
89
+ order_id: order.number,
90
+ description: order.number
91
+ )
92
+ end
93
+
94
+ let(:saferpay_payer) do
95
+ instance_double("SixSaferpay::Payer",
96
+ language_code: I18n.locale,
97
+ billing_address: saferpay_billing_address,
98
+ delivery_address: saferpay_shipping_address
99
+ )
100
+ end
101
+ let(:return_urls) do
102
+ instance_double("SixSaferpay::ReturnUrls",
103
+ success: solidus_six_saferpay_payment_page_success_url(order),
104
+ fd_fail: solidus_six_saferpay_payment_page_fail_url(order),
105
+ fd_abort: solidus_six_saferpay_payment_page_fail_url(order),
106
+ )
107
+ end
108
+
109
+ let(:initialize_params) do
110
+ {
111
+ payment: saferpay_payment,
112
+ payer: saferpay_payer,
113
+ return_urls: return_urls
114
+ }
115
+ end
116
+
117
+ let(:saferpay_initialize) do
118
+ instance_double("SixSaferpay::SixPaymentPage::Initialize")
119
+ end
120
+
121
+ let(:api_initialize_response) do
122
+ SixSaferpay::SixPaymentPage::InitializeResponse.new(
123
+ response_header: SixSaferpay::ResponseHeader.new(request_id: 'request_id', spec_version: 'test'),
124
+ token: 'TOKEN',
125
+ expiration: '2015-01-30T12:45:22.258+01:00',
126
+ redirect_url: '/redirect/url'
127
+ )
128
+ end
129
+
130
+
131
+ it 'initializes a payment page payment' do
132
+ # mock payment
133
+ expect(SixSaferpay::Amount).to receive(:new).with(
134
+ value: (order.total * 100),
135
+ currency_code: order.currency
136
+ ).and_return(saferpay_amount)
137
+ expect(SixSaferpay::Payment).to receive(:new).with(
138
+ amount: saferpay_amount,
139
+ order_id: order.number,
140
+ description: order.number
141
+ ).and_return(saferpay_payment)
142
+
143
+
144
+ # mock payer
145
+ expect(SixSaferpay::Address).to receive(:new).with(
146
+ first_name: order.billing_address.first_name,
147
+ last_name: order.billing_address.last_name,
148
+ date_of_birth: nil,
149
+ company: nil,
150
+ gender: nil,
151
+ legal_form: nil,
152
+ street: order.billing_address.address1,
153
+ street2: order.billing_address.address2,
154
+ zip: order.billing_address.zipcode,
155
+ city: order.billing_address.city,
156
+ country_subdevision_code: nil,
157
+ country_code: order.billing_address.country.iso,
158
+ phone: nil,
159
+ email: nil,
160
+ ).and_return(saferpay_billing_address)
161
+ expect(SixSaferpay::Address).to receive(:new).with(
162
+ first_name: order.shipping_address.first_name,
163
+ last_name: order.shipping_address.last_name,
164
+ date_of_birth: nil,
165
+ company: nil,
166
+ gender: nil,
167
+ legal_form: nil,
168
+ street: order.shipping_address.address1,
169
+ street2: order.shipping_address.address2,
170
+ zip: order.shipping_address.zipcode,
171
+ city: order.shipping_address.city,
172
+ country_subdevision_code: nil,
173
+ country_code: order.shipping_address.country.iso,
174
+ phone: nil,
175
+ email: nil,
176
+ ).and_return(saferpay_shipping_address)
177
+ expect(SixSaferpay::Payer).to receive(:new).with(
178
+ language_code: I18n.locale,
179
+ billing_address: saferpay_billing_address,
180
+ delivery_address: saferpay_shipping_address
181
+ ).and_return(saferpay_payer)
182
+
183
+ # mock return_urls
184
+ expect(SixSaferpay::ReturnUrls).to receive(:new).with(
185
+ success: solidus_six_saferpay_payment_page_success_url(order),
186
+ fd_fail: solidus_six_saferpay_payment_page_fail_url(order),
187
+ fd_abort: solidus_six_saferpay_payment_page_fail_url(order),
188
+ ).and_return(return_urls)
189
+
190
+ expect(SixSaferpay::SixPaymentPage::Initialize).to receive(:new).with(initialize_params).and_return(saferpay_initialize)
191
+
192
+ expect(SixSaferpay::Client).to receive(:post).with(saferpay_initialize).and_return(api_initialize_response)
193
+
194
+ gateway.initialize_payment(order, payment_method)
195
+ end
196
+
197
+ context 'when the payment initialization is successful' do
198
+ before do
199
+ expect(SixSaferpay::Client).to receive(:post).with(instance_of(SixSaferpay::SixPaymentPage::Initialize)).and_return(api_initialize_response)
200
+ end
201
+
202
+ it 'returns a success gateway response' do
203
+ expect(GatewayResponse).to receive(:new).with(true, instance_of(String), api_initialize_response, {})
204
+ gateway.initialize_payment(order, payment_method)
205
+ end
206
+ end
207
+
208
+ context 'when the API raises an error' do
209
+ let(:six_saferpay_error) do
210
+ SixSaferpay::Error.new(
211
+ response_header: SixSaferpay::ResponseHeader.new(request_id: 'request_id', spec_version: 'test'),
212
+ behavior: 'ABORT',
213
+ error_name: 'INVALID_TRANSACTION',
214
+ error_message: 'error_message'
215
+ )
216
+ end
217
+
218
+ before do
219
+ expect(SixSaferpay::Client).to receive(:post).with(instance_of(SixSaferpay::SixPaymentPage::Initialize)).and_raise(six_saferpay_error)
220
+ end
221
+
222
+ it 'handles the error gracefully' do
223
+ expect(GatewayResponse).to receive(:new).with(false, six_saferpay_error.error_message, nil, error_name: six_saferpay_error.error_name)
224
+
225
+ gateway.initialize_payment(order, payment_method)
226
+ end
227
+ end
228
+ end
229
+
230
+ describe '#inquire' do
231
+
232
+ let(:saferpay_assert) do
233
+ instance_double("SixSaferpay::PaymentPage::Assert")
234
+ end
235
+
236
+ let(:transaction_status) { "AUTHORIZED" }
237
+ let(:transaction_id) { "723n4MAjMdhjSAhAKEUdA8jtl9jb" }
238
+ let(:transaction_date) { "2015-01-30T12:45:22.258+01:00" }
239
+ let(:amount_value) { "100" }
240
+ let(:amount_currency) { "USD" }
241
+ let(:brand_name) { 'PaymentBrand' }
242
+ let(:display_text) { "xxxx xxxx xxxx 1234" }
243
+ let(:six_transaction_reference) { "0:0:3:723n4MAjMdhjSAhAKEUdA8jtl9jb" }
244
+
245
+ let(:payment_means) do
246
+ SixSaferpay::ResponsePaymentMeans.new(
247
+ brand: SixSaferpay::Brand.new(name: brand_name),
248
+ display_text: display_text
249
+ )
250
+ end
251
+
252
+ let(:api_inquire_response) do
253
+ SixSaferpay::SixPaymentPage::AssertResponse.new(
254
+ response_header: SixSaferpay::ResponseHeader.new(request_id: 'test', spec_version: 'test'),
255
+ transaction: SixSaferpay::Transaction.new(
256
+ type: "PAYMENT",
257
+ status: transaction_status,
258
+ id: transaction_id,
259
+ date: transaction_date,
260
+ amount: SixSaferpay::Amount.new(value: amount_value, currency_code: amount_currency),
261
+ six_transaction_reference: six_transaction_reference,
262
+ ),
263
+ payment_means: payment_means
264
+ )
265
+ end
266
+
267
+ it 'performs an assert request' do
268
+ expect(SixSaferpay::SixPaymentPage::Assert).to receive(:new).with(token: payment.token).and_return(saferpay_assert)
269
+ expect(SixSaferpay::Client).to receive(:post).and_return(api_inquire_response)
270
+
271
+ gateway.inquire(payment)
272
+ end
273
+
274
+ context 'when the payment inquiry is successful' do
275
+ before do
276
+ allow(SixSaferpay::Client).to receive(:post).with(instance_of(SixSaferpay::SixPaymentPage::Assert)).and_return(api_inquire_response)
277
+ end
278
+
279
+ it 'returns a successful gateway response' do
280
+ expect(GatewayResponse).to receive(:new).with(true, instance_of(String), api_inquire_response, {})
281
+
282
+ gateway.inquire(payment)
283
+ end
284
+ end
285
+
286
+ context 'when the API returns an error' do
287
+ let(:six_saferpay_error) do
288
+ SixSaferpay::Error.new(
289
+ response_header: SixSaferpay::ResponseHeader.new(request_id: 'request_id', spec_version: 'test'),
290
+ behavior: 'ABORT',
291
+ error_name: 'INVALID_TRANSACTION',
292
+ error_message: 'error_message'
293
+ )
294
+ end
295
+
296
+ before do
297
+ allow(SixSaferpay::Client).to receive(:post).with(instance_of(SixSaferpay::SixPaymentPage::Assert)).and_raise(six_saferpay_error)
298
+ end
299
+
300
+ it 'handles the error gracefully' do
301
+ expect(GatewayResponse).to receive(:new).with(false, six_saferpay_error.error_message, nil, error_name: six_saferpay_error.error_name)
302
+
303
+ gateway.inquire(payment)
304
+ end
305
+ end
306
+ end
307
+
308
+ describe '#authorize' do
309
+ it 'calls assert' do
310
+ expect(gateway).to receive(:assert).with(payment, {})
311
+ gateway.authorize(100, payment)
312
+ end
313
+ end
314
+
315
+ describe '#assert' do
316
+ let(:saferpay_assert) do
317
+ instance_double("SixSaferpay::PaymentPage::Assert")
318
+ end
319
+
320
+ let(:transaction_status) { "AUTHORIZED" }
321
+ let(:transaction_id) { "723n4MAjMdhjSAhAKEUdA8jtl9jb" }
322
+ let(:transaction_date) { "2015-01-30T12:45:22.258+01:00" }
323
+ let(:amount_value) { "100" }
324
+ let(:amount_currency) { "USD" }
325
+ let(:brand_name) { 'PaymentBrand' }
326
+ let(:display_text) { "xxxx xxxx xxxx 1234" }
327
+ let(:six_transaction_reference) { "0:0:3:723n4MAjMdhjSAhAKEUdA8jtl9jb" }
328
+
329
+ let(:payment_means) do
330
+ SixSaferpay::ResponsePaymentMeans.new(
331
+ brand: SixSaferpay::Brand.new(name: brand_name),
332
+ display_text: display_text
333
+ )
334
+ end
335
+
336
+ let(:api_assert_response) do
337
+ SixSaferpay::SixPaymentPage::AssertResponse.new(
338
+ response_header: SixSaferpay::ResponseHeader.new(request_id: 'test', spec_version: 'test'),
339
+ transaction: SixSaferpay::Transaction.new(
340
+ type: "PAYMENT",
341
+ status: transaction_status,
342
+ id: transaction_id,
343
+ date: transaction_date,
344
+ amount: SixSaferpay::Amount.new(value: amount_value, currency_code: amount_currency),
345
+ six_transaction_reference: six_transaction_reference,
346
+ ),
347
+ payment_means: payment_means
348
+ )
349
+ end
350
+
351
+ it 'performs an assert request' do
352
+ expect(SixSaferpay::SixPaymentPage::Assert).to receive(:new).with(token: payment.token).and_return(saferpay_assert)
353
+ expect(SixSaferpay::Client).to receive(:post).and_return(api_assert_response)
354
+
355
+ gateway.assert(payment)
356
+ end
357
+
358
+ context 'when the payment assert is successful' do
359
+ before do
360
+ allow(SixSaferpay::Client).to receive(:post).with(instance_of(SixSaferpay::SixPaymentPage::Assert)).and_return(api_assert_response)
361
+ end
362
+
363
+ it 'returns a successful gateway response' do
364
+ expect(GatewayResponse).to receive(:new).with(true, instance_of(String), api_assert_response, {})
365
+
366
+ gateway.assert(payment)
367
+ end
368
+ end
369
+
370
+ context 'when the API returns an error' do
371
+ let(:six_saferpay_error) do
372
+ SixSaferpay::Error.new(
373
+ response_header: SixSaferpay::ResponseHeader.new(request_id: 'request_id', spec_version: 'test'),
374
+ behavior: 'ABORT',
375
+ error_name: 'INVALID_TRANSACTION',
376
+ error_message: 'error_message'
377
+ )
378
+ end
379
+
380
+ before do
381
+ allow(SixSaferpay::Client).to receive(:post).with(instance_of(SixSaferpay::SixPaymentPage::Assert)).and_raise(six_saferpay_error)
382
+ end
383
+
384
+ it 'handles the error gracefully' do
385
+ expect(GatewayResponse).to receive(:new).with(false, six_saferpay_error.error_message, nil, error_name: six_saferpay_error.error_name)
386
+
387
+ gateway.assert(payment)
388
+ end
389
+ end
390
+ end
391
+ end
392
+ end