Completed
Pull Request — master (#25)
by Andrey
13:46 queued 06:52
created

PaymentController::executeSuccessAction()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 5
nc 1
nop 1
dl 0
loc 8
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Apache OSL-2
5
 * Use of this software requires acceptance of the Evaluation License Agreement. See LICENSE file.
6
 */
7
8
namespace SprykerEco\Yves\AmazonPay\Controller;
9
10
use Generated\Shared\Transfer\AmazonpayPaymentTransfer;
11
use Generated\Shared\Transfer\CheckoutErrorTransfer;
1 ignored issue
show
Bug introduced by
The type Generated\Shared\Transfer\CheckoutErrorTransfer was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
12
use Generated\Shared\Transfer\CheckoutResponseTransfer;
1 ignored issue
show
Bug introduced by
The type Generated\Shared\Transfer\CheckoutResponseTransfer was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
13
use Generated\Shared\Transfer\QuoteTransfer;
1 ignored issue
show
Bug introduced by
The type Generated\Shared\Transfer\QuoteTransfer was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
14
use Spryker\Shared\Config\Config;
15
use Spryker\Yves\Kernel\Controller\AbstractController;
16
use SprykerEco\Shared\AmazonPay\AmazonPayConfig;
17
use SprykerEco\Shared\AmazonPay\AmazonPayConstants;
18
use SprykerEco\Yves\AmazonPay\Plugin\Provider\AmazonPayControllerProvider;
19
use Symfony\Component\HttpFoundation\JsonResponse;
20
use Symfony\Component\HttpFoundation\Request;
21
22
/**
23
 * @method \SprykerEco\Client\AmazonPay\AmazonPayClientInterface getClient()
24
 * @method \SprykerEco\Yves\AmazonPay\AmazonPayFactory getFactory()
25
 */
26
class PaymentController extends AbstractController
27
{
28
    public const URL_PARAM_REFERENCE_ID = 'reference_id';
29
    public const URL_PARAM_ACCESS_TOKEN = 'access_token';
30
    public const URL_PARAM_SHIPMENT_METHOD_ID = 'shipment_method_id';
31
    public const QUOTE_TRANSFER = 'quoteTransfer';
32
    public const SHIPMENT_METHODS = 'shipmentMethods';
33
    public const SELECTED_SHIPMENT_METHOD_ID = 'selectedShipmentMethodId';
34
    public const AMAZONPAY_CONFIG = 'amazonpayConfig';
35
    public const IS_ASYNCHRONOUS = 'isAsynchronous';
36
    public const CART_ITEMS = 'cartItems';
37
    public const SUCCESS = 'success';
38
    public const ERROR_AMAZONPAY_PAYMENT_FAILED = 'amazonpay.payment.failed';
39
    public const IS_AMAZON_PAYMENT_INVALID = 'isAmazonPaymentInvalid';
40
    public const ADDRESS_BOOK_MODE = 'addressBookMode';
41
    public const ORDER_REFERENCE = 'orderReferenceId';
42
43
    /**
44
     * @param \Symfony\Component\HttpFoundation\Request $request
45
     *
46
     * @return \Spryker\Yves\Kernel\View\View|\Symfony\Component\HttpFoundation\RedirectResponse
47
     */
48
    public function checkoutAction(Request $request)
49
    {
50
        $response = $this->executeCheckoutAction($request);
51
52
        if (!is_array($response)) {
0 ignored issues
show
introduced by
The condition is_array($response) is always false.
Loading history...
53
            return $response;
54
        }
55
56
        return $this->view($response, [], '@AmazonPay/views/checkout/checkout.twig');
57
    }
58
59
    /**
60
     * @param \Symfony\Component\HttpFoundation\Request $request
61
     *
62
     * @return array|\Symfony\Component\HttpFoundation\RedirectResponse
63
     */
64
    protected function executeCheckoutAction(Request $request)
65
    {
66
        $quoteTransfer = $this->getFactory()
67
            ->getQuoteClient()
68
            ->getQuote();
69
70
        if (!$this->isAllowedCheckout($quoteTransfer) || !$this->isRequestComplete($request)) {
71
            $this->addAmazonPayErrorFromQuote($quoteTransfer);
72
73
            return $this->buildRedirectInternalResponse();
74
        }
75
76
        $this->storeAmazonPaymentIntoQuote($request, $quoteTransfer);
77
78
        $data = [
79
            static::QUOTE_TRANSFER => $quoteTransfer,
80
            static::CART_ITEMS => $this->getCartItems($quoteTransfer),
81
            static::AMAZONPAY_CONFIG => $this->getAmazonPayConfig(),
82
        ];
83
84
        if ($this->isAmazonPaymentInvalid($quoteTransfer)) {
85
            $data[static::ORDER_REFERENCE] = $this->getAmazonPaymentOrderReferenceId($quoteTransfer);
86
            $data[static::ADDRESS_BOOK_MODE] = AmazonPayConfig::DISPLAY_MODE_READONLY;
87
        }
88
89
        return $data;
90
    }
91
92
    /**
93
     * @param \Symfony\Component\HttpFoundation\Request $request
94
     *
95
     * @return \Symfony\Component\HttpFoundation\Response
96
     */
97
    public function setOrderReferenceAction(Request $request)
98
    {
99
        $quoteTransfer = $this->getFactory()
100
            ->getQuoteClient()
101
            ->getQuote();
102
103
        if (!$this->isAmazonPayment($quoteTransfer)) {
104
            return $this->buildRedirectInternalResponse();
105
        }
106
107
        $quoteTransfer->getAmazonpayPayment()
108
            ->setOrderReferenceId(
109
                $request->request->get(static::URL_PARAM_REFERENCE_ID)
110
            );
111
112
        return new JsonResponse([static::SUCCESS => true]);
113
    }
114
115
    /**
116
     * @param \Symfony\Component\HttpFoundation\Request $request
117
     *
118
     * @return \Spryker\Yves\Kernel\View\View|\Symfony\Component\HttpFoundation\RedirectResponse
119
     */
120
    public function getShipmentMethodsAction(Request $request)
121
    {
122
        $response = $this->executeShipmentMethodsAction($request);
123
124
        if (!is_array($response)) {
0 ignored issues
show
introduced by
The condition is_array($response) is always false.
Loading history...
125
            return $response;
126
        }
127
128
        return $this->view($response, [], '@AmazonPay/views/get-shipment-methods/get-shipment-methods.twig');
129
    }
130
131
    /**
132
     * @param \Symfony\Component\HttpFoundation\Request $request
133
     *
134
     * @return array|\Symfony\Component\HttpFoundation\RedirectResponse
135
     */
136
    protected function executeShipmentMethodsAction(Request $request)
1 ignored issue
show
Unused Code introduced by
The parameter $request is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

136
    protected function executeShipmentMethodsAction(/** @scrutinizer ignore-unused */ Request $request)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
137
    {
138
        $quoteTransfer = $this->getFactory()
139
            ->getQuoteClient()
140
            ->getQuote();
141
142
        if (!$this->isAmazonPayment($quoteTransfer)) {
143
            $this->addAmazonPayErrorFromQuote($quoteTransfer);
144
145
            return $this->buildRedirectInternalResponse();
146
        }
147
148
        $quoteTransfer = $this->getClient()
149
            ->addSelectedAddressToQuote($quoteTransfer);
150
        $this->saveQuoteIntoSession($quoteTransfer);
151
        $shipmentMethods = $this->getFactory()
152
            ->getShipmentClient()
153
            ->getAvailableMethods($quoteTransfer);
154
155
        return [
156
            static::SELECTED_SHIPMENT_METHOD_ID => $this->getCurrentShipmentMethodId($quoteTransfer),
157
            static::SHIPMENT_METHODS => $shipmentMethods->getMethods(),
158
            static::IS_AMAZON_PAYMENT_INVALID => $this->isAmazonPaymentInvalid($quoteTransfer),
159
        ];
160
    }
161
162
    /**
163
     * @param \Symfony\Component\HttpFoundation\Request $request
164
     *
165
     * @return \Spryker\Yves\Kernel\View\View|\Symfony\Component\HttpFoundation\RedirectResponse
166
     */
167
    public function updateShipmentMethodAction(Request $request)
168
    {
169
        $response = $this->executeShipmentMethodAction($request);
170
171
        if (!is_array($response)) {
0 ignored issues
show
introduced by
The condition is_array($response) is always false.
Loading history...
172
            return $response;
173
        }
174
175
        return $this->view($response, [], '@AmazonPay/views/shipment-method/shipment-method.twig');
176
    }
177
178
    /**
179
     * @param \Symfony\Component\HttpFoundation\Request $request
180
     *
181
     * @return array|\Symfony\Component\HttpFoundation\RedirectResponse
182
     */
183
    protected function executeShipmentMethodAction(Request $request)
184
    {
185
        $quoteTransfer = $this->getFactory()->getQuoteClient()->getQuote();
186
187
        if (!$this->isAmazonPayment($quoteTransfer)) {
188
            $this->addAmazonPayErrorFromQuote($quoteTransfer);
189
190
            return $this->buildRedirectInternalResponse();
191
        }
192
193
        $quoteTransfer->getShipment()->setShipmentSelection(
194
            $request->request->get(static::URL_PARAM_SHIPMENT_METHOD_ID)
195
        );
196
        $quoteTransfer = $this->getClient()
197
            ->addSelectedShipmentMethodToQuote($quoteTransfer);
198
        $quoteTransfer = $this->getFactory()
199
            ->getCalculationClient()->recalculate($quoteTransfer);
200
        $this->saveQuoteIntoSession($quoteTransfer);
201
202
        return [
203
            static::QUOTE_TRANSFER => $quoteTransfer,
204
        ];
205
    }
206
207
    /**
208
     * @param \Symfony\Component\HttpFoundation\Request $request
209
     *
210
     * @return \Symfony\Component\HttpFoundation\Response
211
     */
212
    public function confirmPurchaseAction(Request $request)
1 ignored issue
show
Unused Code introduced by
The parameter $request is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

212
    public function confirmPurchaseAction(/** @scrutinizer ignore-unused */ Request $request)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
213
    {
214
        $quoteTransfer = $this->getFactory()->getQuoteClient()->getQuote();
215
216
        if (!$this->isAmazonPayment($quoteTransfer)) {
217
            $this->addAmazonPayErrorFromQuote($quoteTransfer);
218
219
            return $this->buildRedirectInternalResponse();
220
        }
221
222
        $checkoutResponseTransfer = $this->getFactory()->getCheckoutClient()->placeOrder($quoteTransfer);
223
        $this->saveQuoteIntoSession($quoteTransfer);
224
225
        if ($checkoutResponseTransfer->getIsSuccess()) {
226
            return $this->redirectResponseInternal(AmazonPayControllerProvider::SUCCESS);
227
        }
228
229
        $this->addAmazonPayErrorFromQuote($quoteTransfer);
230
        $this->setCheckoutErrorMessages($checkoutResponseTransfer);
231
232
        return $this->buildRedirectInternalResponse();
233
    }
234
235
    /**
236
     * @param \Symfony\Component\HttpFoundation\Request $request
237
     *
238
     * @return \Spryker\Yves\Kernel\View\View|\Symfony\Component\HttpFoundation\RedirectResponse
239
     */
240
    public function successAction(Request $request)
241
    {
242
        $response = $this->executeSuccessAction($request);
243
244
        if (!is_array($response)) {
0 ignored issues
show
introduced by
The condition is_array($response) is always true.
Loading history...
245
            return $response;
246
        }
247
248
        return $this->view($response, [], '@AmazonPay/views/success/success.twig');
249
    }
250
251
    /**
252
     * @param \Symfony\Component\HttpFoundation\Request $request
253
     *
254
     * @return array|\Symfony\Component\HttpFoundation\RedirectResponse
255
     */
256
    protected function executeSuccessAction(Request $request)
1 ignored issue
show
Unused Code introduced by
The parameter $request is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

256
    protected function executeSuccessAction(/** @scrutinizer ignore-unused */ Request $request)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
257
    {
258
        $this->getFactory()->getCustomerClient()->markCustomerAsDirty();
259
        $this->getFactory()->getCartClient()->clearQuote();
260
261
        return [
262
            static::IS_ASYNCHRONOUS => $this->isAsynchronous(),
263
            static::AMAZONPAY_CONFIG => $this->getAmazonPayConfig(),
264
        ];
265
    }
266
267
    /**
268
     * @param \Symfony\Component\HttpFoundation\Request $request
269
     * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
270
     *
271
     * @return void
272
     */
273
    protected function storeAmazonPaymentIntoQuote(Request $request, QuoteTransfer $quoteTransfer)
274
    {
275
        $amazonPaymentTransfer = $this->buildAmazonPaymentTransfer($request);
276
277
        $quoteTransfer->setAmazonpayPayment($amazonPaymentTransfer);
278
        $quoteTransfer = $this->getClient()
279
            ->handleCartWithAmazonPay($quoteTransfer);
280
        $this->saveQuoteIntoSession($quoteTransfer);
281
    }
282
283
    /**
284
     * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
285
     *
286
     * @return void
287
     */
288
    protected function saveQuoteIntoSession(QuoteTransfer $quoteTransfer)
289
    {
290
        $this->getFactory()
291
            ->getQuoteClient()
292
            ->setQuote($quoteTransfer);
293
    }
294
295
    /**
296
     * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
297
     *
298
     * @return int|null
299
     */
300
    protected function getCurrentShipmentMethodId(QuoteTransfer $quoteTransfer)
301
    {
302
        if ($quoteTransfer->getShipment() === null || $quoteTransfer->getShipment()->getMethod() === null) {
303
            return null;
304
        }
305
306
        return $quoteTransfer->getShipment()->getMethod()->getIdShipmentMethod();
307
    }
308
309
    /**
310
     * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
311
     *
312
     * @return \ArrayObject|\Generated\Shared\Transfer\ItemTransfer[]
313
     */
314
    protected function getCartItems(QuoteTransfer $quoteTransfer)
315
    {
316
        return $quoteTransfer->getItems();
317
    }
318
319
    /**
320
     * @param \Symfony\Component\HttpFoundation\Request $request
321
     *
322
     * @return bool
323
     */
324
    protected function isRequestComplete(Request $request)
325
    {
326
        return (
327
            $request->query->get(static::URL_PARAM_REFERENCE_ID) !== null &&
328
            $request->query->get(static::URL_PARAM_ACCESS_TOKEN) !== null
329
        );
330
    }
331
332
    /**
333
     * @param \Symfony\Component\HttpFoundation\Request $request
334
     *
335
     * @return \Generated\Shared\Transfer\AmazonpayPaymentTransfer
336
     */
337
    protected function buildAmazonPaymentTransfer(Request $request)
338
    {
339
        $amazonPaymentTransfer = new AmazonpayPaymentTransfer();
340
        $amazonPaymentTransfer->setOrderReferenceId($request->query->get(static::URL_PARAM_REFERENCE_ID));
341
        $amazonPaymentTransfer->setAddressConsentToken($request->query->get(static::URL_PARAM_ACCESS_TOKEN));
342
343
        return $amazonPaymentTransfer;
344
    }
345
346
    /**
347
     * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
348
     *
349
     * @return bool
350
     */
351
    protected function isAllowedCheckout(QuoteTransfer $quoteTransfer)
352
    {
353
        return $quoteTransfer->getTotals() !== null;
354
    }
355
356
    /**
357
     * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
358
     *
359
     * @return bool
360
     */
361
    protected function isLogoutRedirect(QuoteTransfer $quoteTransfer)
362
    {
363
        if ($this->isAmazonPaymentInvalid($quoteTransfer)) {
364
            return false;
365
        }
366
367
        if ($this->getAmazonPayConfig()->getCaptureNow() &&
368
            $quoteTransfer->getAmazonpayPayment() !== null
369
            && $quoteTransfer->getAmazonpayPayment()->getResponseHeader() !== null
370
            && !$quoteTransfer->getAmazonpayPayment()->getResponseHeader()->getIsSuccess()
371
        ) {
372
            return true;
373
        }
374
375
        return false;
376
    }
377
378
    /**
379
     * @param \Symfony\Component\HttpFoundation\Request $request
380
     *
381
     * @return \Symfony\Component\HttpFoundation\RedirectResponse
382
     */
383
    protected function buildRedirectExternalResponse(Request $request)
384
    {
385
        if ($request->headers->get('Referer') === null) {
0 ignored issues
show
introduced by
The condition $request->headers->get('Referer') === null is always false.
Loading history...
386
            return $this->buildRedirectInternalResponse();
387
        }
388
389
        return $this->redirectResponseExternal($request->headers->get('Referer'));
390
    }
391
392
    /**
393
     * @param \Generated\Shared\Transfer\CheckoutResponseTransfer $checkoutResponseTransfer
394
     *
395
     * @return void
396
     */
397
    protected function setCheckoutErrorMessages(CheckoutResponseTransfer $checkoutResponseTransfer)
398
    {
399
        foreach ($checkoutResponseTransfer->getErrors() as $checkoutErrorTransfer) {
400
            $this->addErrorMessage(
401
                $this->translateCheckoutErrorMessage($checkoutErrorTransfer)
402
            );
403
        }
404
    }
405
406
    /**
407
     * @param \Generated\Shared\Transfer\CheckoutErrorTransfer $checkoutErrorTransfer
408
     *
409
     * @return string
410
     */
411
    protected function translateCheckoutErrorMessage(CheckoutErrorTransfer $checkoutErrorTransfer): string
412
    {
413
        $checkoutErrorMessage = $checkoutErrorTransfer->getMessage();
414
415
        return $this->getFactory()->getGlossaryStorageClient()->translate(
416
            $checkoutErrorMessage,
417
            $this->getLocale(),
418
            $checkoutErrorTransfer->getParameters()
419
        ) ?: $checkoutErrorMessage;
420
    }
421
422
    /**
423
     * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
424
     *
425
     * @return void
426
     */
427
    protected function addAmazonPayErrorFromQuote(QuoteTransfer $quoteTransfer)
428
    {
429
        if ($quoteTransfer->getAmazonpayPayment() === null
430
            || $quoteTransfer->getAmazonpayPayment()->getResponseHeader() === null
431
            || $quoteTransfer->getAmazonpayPayment()->getResponseHeader()->getErrorMessage() === null) {
432
            return;
433
        }
434
435
        $this->addErrorMessage(
436
            $quoteTransfer->getAmazonpayPayment()->getResponseHeader()->getErrorMessage()
437
        );
438
    }
439
440
    /**
441
     * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
442
     *
443
     * @return bool
444
     */
445
    protected function isAmazonPayment(QuoteTransfer $quoteTransfer)
446
    {
447
        return $quoteTransfer->getAmazonpayPayment() !== null;
448
    }
449
450
    /**
451
     * @return \Symfony\Component\HttpFoundation\RedirectResponse
452
     */
453
    protected function buildRedirectInternalResponse()
454
    {
455
        return $this->redirectResponseInternal($this->getPaymentRejectRoute());
456
    }
457
458
    /**
459
     * @return string
460
     */
461
    protected function getPaymentRejectRoute()
462
    {
463
        return Config::get(AmazonPayConstants::PAYMENT_REJECT_ROUTE);
464
    }
465
466
    /**
467
     * @return bool
468
     */
469
    protected function isAsynchronous()
470
    {
471
        return $this->getAmazonPayConfig()->getAuthTransactionTimeout() > 0
472
            && !$this->getAmazonPayConfig()->getCaptureNow();
473
    }
474
475
    /**
476
     * @return \SprykerEco\Shared\AmazonPay\AmazonPayConfigInterface
477
     */
478
    protected function getAmazonPayConfig()
479
    {
480
        return $this->getFactory()->createAmazonPayConfig();
481
    }
482
483
    /**
484
     * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
485
     *
486
     * @return bool
487
     */
488
    protected function isAmazonPaymentInvalid(QuoteTransfer $quoteTransfer)
489
    {
490
        if ($quoteTransfer->getAmazonpayPayment()->getResponseHeader() !== null
491
            && $quoteTransfer->getAmazonpayPayment()->getResponseHeader()->getIsInvalidPaymentMethod()) {
492
            return true;
493
        }
494
495
        return false;
496
    }
497
498
    /**
499
     * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
500
     *
501
     * @return string|null
502
     */
503
    protected function getAmazonPaymentOrderReferenceId(QuoteTransfer $quoteTransfer)
504
    {
505
        if ($quoteTransfer->getAmazonpayPayment() !== null && $quoteTransfer->getAmazonpayPayment()->getOrderReferenceId() !== null) {
506
            return $quoteTransfer->getAmazonpayPayment()->getOrderReferenceId();
507
        }
508
509
        return null;
510
    }
511
}
512