Passed
Pull Request — master (#29)
by Aleksey
08:31 queued 03:27
created

PaymentController::successAction()   B

Complexity

Conditions 7
Paths 8

Size

Total Lines 38
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 7
eloc 19
c 3
b 0
f 0
nc 8
nop 1
dl 0
loc 38
rs 8.8333
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;
1 ignored issue
show
Bug introduced by
The type Generated\Shared\Transfer\AmazonpayPaymentTransfer 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...
11
use Generated\Shared\Transfer\AmazonpayStatusTransfer;
1 ignored issue
show
Bug introduced by
The type Generated\Shared\Transfer\AmazonpayStatusTransfer 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\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...
13
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...
14
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...
15
use Spryker\Shared\Config\Config;
16
use Spryker\Yves\Kernel\Controller\AbstractController;
17
use SprykerEco\Shared\AmazonPay\AmazonPayConfig;
18
use SprykerEco\Shared\AmazonPay\AmazonPayConstants;
19
use SprykerEco\Yves\AmazonPay\Plugin\Provider\AmazonPayControllerProvider;
20
use Symfony\Component\HttpFoundation\JsonResponse;
21
use Symfony\Component\HttpFoundation\RedirectResponse;
22
use Symfony\Component\HttpFoundation\Request;
23
use Symfony\Component\HttpFoundation\Response;
24
25
/**
26
 * @method \SprykerEco\Client\AmazonPay\AmazonPayClientInterface getClient()
27
 * @method \SprykerEco\Yves\AmazonPay\AmazonPayFactory getFactory()
28
 */
29
class PaymentController extends AbstractController
30
{
31
    public const URL_PARAM_REFERENCE_ID = 'reference_id';
32
    public const URL_PARAM_SELLER_ID = 'seller_id';
33
    public const URL_PARAM_ACCESS_TOKEN = 'access_token';
34
    public const URL_PARAM_SHIPMENT_METHOD_ID = 'shipment_method_id';
35
    public const QUOTE_TRANSFER = 'quoteTransfer';
36
    public const SHIPMENT_METHODS = 'shipmentMethods';
37
    public const SELECTED_SHIPMENT_METHOD_ID = 'selectedShipmentMethodId';
38
    public const AMAZONPAY_CONFIG = 'amazonpayConfig';
39
    public const IS_ASYNCHRONOUS = 'isAsynchronous';
40
    public const CART_ITEMS = 'cartItems';
41
    public const SUCCESS = 'success';
42
    public const ERROR_AMAZONPAY_PAYMENT_FAILED = 'amazonpay.payment.failed';
43
    public const IS_AMAZON_PAYMENT_INVALID = 'isAmazonPaymentInvalid';
44
    public const ADDRESS_BOOK_MODE = 'addressBookMode';
45
    public const ORDER_REFERENCE = 'orderReferenceId';
46
47
    public const PSD2_DATA = 'psd2Data';
48
    public const PSD2_DATA_KEY_AJAX_ENDPOINT = 'psd2AjaxEndpoint';
49
    public const PSD2_DATA_KEY_SELLER_ID = 'amazonSellerId';
50
    public const PSD2_DATA_KEY_AMAZON_ORDER_REFERENCE_ID = 'amazonOrderReferenceId';
51
    public const PSD2_DATA_KEY_AMAZON_FAILURE_URL = 'amazonFailureUrl';
52
53
    /**
54
     * @param \Symfony\Component\HttpFoundation\Request $request
55
     *
56
     * @return \Spryker\Yves\Kernel\View\View|\Symfony\Component\HttpFoundation\RedirectResponse
57
     */
58
    public function checkoutAction(Request $request)
59
    {
60
        $response = $this->executeCheckoutAction($request);
61
62
        if (!is_array($response)) {
0 ignored issues
show
introduced by
The condition is_array($response) is always false.
Loading history...
63
            return $response;
64
        }
65
66
        return $this->view($response, [], '@AmazonPay/views/checkout/checkout.twig');
67
    }
68
69
    /**
70
     * @param \Symfony\Component\HttpFoundation\Request $request
71
     *
72
     * @return array|\Symfony\Component\HttpFoundation\RedirectResponse
73
     */
74
    protected function executeCheckoutAction(Request $request)
75
    {
76
        $quoteTransfer = $this->getFactory()
77
            ->getQuoteClient()
78
            ->getQuote();
79
80
        if (!$this->isAllowedCheckout($quoteTransfer) || !$this->isRequestComplete($request)) {
81
            $this->addAmazonPayErrorFromQuote($quoteTransfer);
82
83
            return $this->buildRedirectInternalResponse();
84
        }
85
86
        $this->storeAmazonPaymentIntoQuote($request, $quoteTransfer);
87
88
        $data = [
89
            static::QUOTE_TRANSFER => $quoteTransfer,
90
            static::CART_ITEMS => $this->getCartItems($quoteTransfer),
91
            static::AMAZONPAY_CONFIG => $this->getAmazonPayConfig(),
92
            static::PSD2_DATA => $this->preparePSD2Data($quoteTransfer),
93
        ];
94
95
        if ($this->isAmazonPaymentInvalid($quoteTransfer)) {
96
            $data[static::ORDER_REFERENCE] = $this->getAmazonPaymentOrderReferenceId($quoteTransfer);
97
            $data[static::ADDRESS_BOOK_MODE] = AmazonPayConfig::DISPLAY_MODE_READONLY;
98
        }
99
100
        if ($quoteTransfer->getAmazonpayPayment()->getOrderReferenceStatus()) {
101
            $data[static::ADDRESS_BOOK_MODE] = AmazonPayConfig::DISPLAY_MODE_READONLY;
102
        }
103
104
        return $data;
105
    }
106
107
    /**
108
     * @param \Symfony\Component\HttpFoundation\Request $request
109
     *
110
     * @return \Symfony\Component\HttpFoundation\Response
111
     */
112
    public function setOrderReferenceAction(Request $request)
113
    {
114
        $quoteTransfer = $this->getFactory()
115
            ->getQuoteClient()
116
            ->getQuote();
117
118
        if (!$this->isAmazonPayment($quoteTransfer)) {
119
            return $this->buildRedirectInternalResponse();
120
        }
121
122
        $quoteTransfer->getAmazonpayPayment()
123
            ->setOrderReferenceId(
124
                $request->request->get(static::URL_PARAM_REFERENCE_ID)
125
            );
126
127
        $this->saveQuote($quoteTransfer);
128
129
        return $this->createJsonResponse([static::SUCCESS => true]);
130
    }
131
132
    /**
133
     * @param \Symfony\Component\HttpFoundation\Request $request
134
     *
135
     * @return \Spryker\Yves\Kernel\View\View|\Symfony\Component\HttpFoundation\RedirectResponse
136
     */
137
    public function getShipmentMethodsAction(Request $request)
138
    {
139
        $response = $this->executeShipmentMethodsAction($request);
140
141
        if (!is_array($response)) {
0 ignored issues
show
introduced by
The condition is_array($response) is always false.
Loading history...
142
            return $response;
143
        }
144
145
        return $this->view($response, [], '@AmazonPay/views/get-shipment-methods/get-shipment-methods.twig');
146
    }
147
148
    /**
149
     * @param \Symfony\Component\HttpFoundation\Request $request
150
     *
151
     * @return \Symfony\Component\HttpFoundation\Response
152
     */
153
    public function confirmPurchaseAction(Request $request): Response
154
    {
155
        $quoteTransfer = $this->getFactory()->getQuoteClient()->getQuote();
156
        $quoteTransfer = $this->getClient()->confirmPurchase($quoteTransfer);
157
158
        $amazonpayPaymentTransfer = $quoteTransfer->getAmazonpayPayment();
159
160
        if (!$amazonpayPaymentTransfer->getResponseHeader()->getIsSuccess()
161
            && $amazonpayPaymentTransfer->getResponseHeader()->getConstraints()->count()
162
        ) {
163
            $this->addErrorMessage($amazonpayPaymentTransfer->getResponseHeader()->getErrorMessage());
164
            $payload = [
165
                static::SUCCESS => false,
166
                'url' => $this->getApplication()->url(AmazonPayControllerProvider::CHECKOUT, [
167
                    static::URL_PARAM_REFERENCE_ID => $quoteTransfer->getAmazonpayPayment()->getOrderReferenceId(),
168
                    static::URL_PARAM_ACCESS_TOKEN => $quoteTransfer->getAmazonpayPayment()->getAddressConsentToken(),
169
                ]),
170
            ];
171
172
            return $this->createJsonResponse($payload, 302);
173
        }
174
175
        $this->saveQuote($quoteTransfer);
176
177
        if (!$this->isOrderStatusOpen($quoteTransfer)) {
178
            return $this->createJsonResponse([static::SUCCESS => false], 400);
179
        }
180
181
        return $this->createJsonResponse([static::SUCCESS => true]);
182
    }
183
184
    /**
185
     * @param \Symfony\Component\HttpFoundation\Request $request
186
     *
187
     * @return array|\Symfony\Component\HttpFoundation\RedirectResponse
188
     */
189
    protected function executeShipmentMethodsAction(Request $request)
190
    {
191
        $quoteTransfer = $this->getFactory()
192
            ->getQuoteClient()
193
            ->getQuote();
194
195
        if (!$this->isAmazonPayment($quoteTransfer)) {
196
            $this->addAmazonPayErrorFromQuote($quoteTransfer);
197
198
            return $this->buildRedirectInternalResponse();
199
        }
200
201
        $quoteTransfer = $this->getClient()
202
            ->addSelectedAddressToQuote($quoteTransfer);
203
        $this->saveQuote($quoteTransfer);
204
        $shipmentMethods = $this->getFactory()
205
            ->getShipmentClient()
206
            ->getAvailableMethods($quoteTransfer);
207
208
        return [
209
            static::SELECTED_SHIPMENT_METHOD_ID => $this->getCurrentShipmentMethodId($quoteTransfer),
210
            static::SHIPMENT_METHODS => $shipmentMethods->getMethods(),
211
            static::IS_AMAZON_PAYMENT_INVALID => $this->isAmazonPaymentInvalid($quoteTransfer),
212
        ];
213
    }
214
215
    /**
216
     * @param \Symfony\Component\HttpFoundation\Request $request
217
     *
218
     * @return \Spryker\Yves\Kernel\View\View|\Symfony\Component\HttpFoundation\RedirectResponse
219
     */
220
    public function updateShipmentMethodAction(Request $request)
221
    {
222
        $response = $this->executeShipmentMethodAction($request);
223
224
        if (!is_array($response)) {
0 ignored issues
show
introduced by
The condition is_array($response) is always false.
Loading history...
225
            return $response;
226
        }
227
228
        return $this->view($response, [], '@AmazonPay/views/shipment-method/shipment-method.twig');
229
    }
230
231
    /**
232
     * @param \Symfony\Component\HttpFoundation\Request $request
233
     *
234
     * @return array|\Symfony\Component\HttpFoundation\RedirectResponse
235
     */
236
    protected function executeShipmentMethodAction(Request $request)
237
    {
238
        $quoteTransfer = $this->getFactory()->getQuoteClient()->getQuote();
239
240
        if (!$this->isAmazonPayment($quoteTransfer)) {
241
            $this->addAmazonPayErrorFromQuote($quoteTransfer);
242
243
            return $this->buildRedirectInternalResponse();
244
        }
245
246
        $quoteTransfer->getShipment()->setShipmentSelection(
247
            $request->request->get(static::URL_PARAM_SHIPMENT_METHOD_ID)
248
        );
249
        $quoteTransfer = $this->getClient()
250
            ->addSelectedShipmentMethodToQuote($quoteTransfer);
251
        $quoteTransfer = $this->getFactory()
252
            ->getCalculationClient()->recalculate($quoteTransfer);
253
        $this->saveQuote($quoteTransfer);
254
255
        return [
256
            static::QUOTE_TRANSFER => $quoteTransfer,
257
        ];
258
    }
259
260
    /**
261
     * @param \Symfony\Component\HttpFoundation\Request $request
262
     *
263
     * @return \Spryker\Yves\Kernel\View\View|\Symfony\Component\HttpFoundation\RedirectResponse
264
     */
265
    public function successAction(Request $request)
266
    {
267
        $response = $this->executeSuccessAction($request);
268
269
        $quoteTransfer = $this->getFactory()->getQuoteClient()->getQuote();
270
271
        if ($quoteTransfer->getTotals() === null) {
272
            return $this->view($response, [], '@AmazonPay/views/success/success.twig');
273
        }
274
275
        $checkoutResponseTransfer = $this->getFactory()->getCheckoutClient()->placeOrder($quoteTransfer);
276
277
        if (!$checkoutResponseTransfer->getIsSuccess()) {
278
            return $this->redirectToAmazonCheckoutPage($quoteTransfer);
279
        }
280
281
        $quoteTransfer = $this->getClient()->authorizeOrder($quoteTransfer);
282
283
        if ($this->isAuthorizationExpired($quoteTransfer)) {
284
            $quoteTransfer = $this->reauthorizeOrder($quoteTransfer);
285
        }
286
287
        $this->saveQuote($quoteTransfer);
288
289
        $authorizationStatusTransfer = $this->getAuthorizationTransfer($quoteTransfer);
290
291
        if ($this->isAuthorizationFailed($authorizationStatusTransfer)) {
292
            return $this->redirectResponseInternal(AmazonPayControllerProvider::PAYMENT_FAILED);
293
        }
294
295
        if (!$this->isAuthSucceeded($authorizationStatusTransfer) || $checkoutResponseTransfer->getIsSuccess() === false) {
296
            return $this->redirectToAmazonCheckoutPage($quoteTransfer);
297
        }
298
299
        $this->getFactory()->getCustomerClient()->markCustomerAsDirty();
300
        $this->getFactory()->getCartClient()->clearQuote();
301
302
        return $this->view($response, [], '@AmazonPay/views/success/success.twig');
303
    }
304
305
    /**
306
     * @param \Symfony\Component\HttpFoundation\Request $request
307
     *
308
     * @return array|\Symfony\Component\HttpFoundation\RedirectResponse
309
     */
310
    protected function executeSuccessAction(Request $request)
311
    {
312
        return [
313
            static::IS_ASYNCHRONOUS => $this->isAsynchronous(),
314
            static::AMAZONPAY_CONFIG => $this->getAmazonPayConfig(),
315
        ];
316
    }
317
318
    /**
319
     * @param \Symfony\Component\HttpFoundation\Request $request
320
     *
321
     * @return \Symfony\Component\HttpFoundation\Response
322
     */
323
    public function paymentFailedAction(Request $request): Response
324
    {
325
        $this->getFactory()->getMessengerClient()->addErrorMessage(static::ERROR_AMAZONPAY_PAYMENT_FAILED);
326
327
        $this->clearAmazonpayQuoteData();
328
329
        return $this->buildRedirectInternalResponse();
330
    }
331
332
    /**
333
     * @param \Symfony\Component\HttpFoundation\Request $request
334
     * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
335
     *
336
     * @return void
337
     */
338
    protected function storeAmazonPaymentIntoQuote(Request $request, QuoteTransfer $quoteTransfer)
339
    {
340
        $amazonPaymentTransfer = $this->buildAmazonPaymentTransfer($request, $quoteTransfer);
341
342
        $quoteTransfer->setAmazonpayPayment($amazonPaymentTransfer);
343
        $quoteTransfer = $this->getClient()
344
            ->handleCartWithAmazonPay($quoteTransfer);
345
        $this->saveQuote($quoteTransfer);
346
    }
347
348
    /**
349
     * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
350
     *
351
     * @return void
352
     */
353
    protected function saveQuote(QuoteTransfer $quoteTransfer)
354
    {
355
        $this->getFactory()
356
            ->getQuoteClient()
357
            ->setQuote($quoteTransfer);
358
    }
359
360
    /**
361
     * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
362
     *
363
     * @return int|null
364
     */
365
    protected function getCurrentShipmentMethodId(QuoteTransfer $quoteTransfer)
366
    {
367
        if ($quoteTransfer->getShipment() === null || $quoteTransfer->getShipment()->getMethod() === null) {
368
            return null;
369
        }
370
371
        return $quoteTransfer->getShipment()->getMethod()->getIdShipmentMethod();
372
    }
373
374
    /**
375
     * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
376
     *
377
     * @return \ArrayObject|\Generated\Shared\Transfer\ItemTransfer[]
378
     */
379
    protected function getCartItems(QuoteTransfer $quoteTransfer)
380
    {
381
        return $quoteTransfer->getItems();
382
    }
383
384
    /**
385
     * @param \Symfony\Component\HttpFoundation\Request $request
386
     *
387
     * @return bool
388
     */
389
    protected function isRequestComplete(Request $request)
390
    {
391
        return (
392
            $request->query->get(static::URL_PARAM_REFERENCE_ID) !== null &&
393
            $request->query->get(static::URL_PARAM_ACCESS_TOKEN) !== null
394
        );
395
    }
396
397
    /**
398
     * @param \Symfony\Component\HttpFoundation\Request $request
399
     * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
400
     *
401
     * @return \Generated\Shared\Transfer\AmazonpayPaymentTransfer
402
     */
403
    protected function buildAmazonPaymentTransfer(Request $request, QuoteTransfer $quoteTransfer)
404
    {
405
        $amazonPaymentTransfer = $quoteTransfer->getAmazonpayPayment() ?: new AmazonpayPaymentTransfer();
406
407
        $amazonPaymentTransfer->setOrderReferenceId($request->query->get(static::URL_PARAM_REFERENCE_ID));
408
        $amazonPaymentTransfer->setAddressConsentToken($request->query->get(static::URL_PARAM_ACCESS_TOKEN));
409
        $amazonPaymentTransfer->setFailureMFARedirectUrl($this->getApplication()->url(AmazonPayControllerProvider::CHECKOUT, [
410
            static::URL_PARAM_REFERENCE_ID => $request->query->get(static::URL_PARAM_REFERENCE_ID),
411
            static::URL_PARAM_ACCESS_TOKEN => $request->query->get(static::URL_PARAM_ACCESS_TOKEN),
412
        ]));
413
        $amazonPaymentTransfer->setSuccessMFARedirectUrl($this->getApplication()->url(AmazonPayControllerProvider::SUCCESS));
414
415
        return $amazonPaymentTransfer;
416
    }
417
418
    /**
419
     * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
420
     *
421
     * @return bool
422
     */
423
    protected function isAllowedCheckout(QuoteTransfer $quoteTransfer)
424
    {
425
        return $quoteTransfer->getTotals() !== null;
426
    }
427
428
    /**
429
     * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
430
     *
431
     * @return bool
432
     */
433
    protected function isLogoutRedirect(QuoteTransfer $quoteTransfer)
434
    {
435
        if ($this->isAmazonPaymentInvalid($quoteTransfer)) {
436
            return false;
437
        }
438
439
        if ($this->getAmazonPayConfig()->getCaptureNow() &&
440
            $quoteTransfer->getAmazonpayPayment() !== null
441
            && $quoteTransfer->getAmazonpayPayment()->getResponseHeader() !== null
442
            && !$quoteTransfer->getAmazonpayPayment()->getResponseHeader()->getIsSuccess()
443
        ) {
444
            return true;
445
        }
446
447
        return false;
448
    }
449
450
    /**
451
     * @param \Symfony\Component\HttpFoundation\Request $request
452
     *
453
     * @return \Symfony\Component\HttpFoundation\RedirectResponse
454
     */
455
    protected function buildRedirectExternalResponse(Request $request)
456
    {
457
        if ($request->headers->get('Referer') === null) {
0 ignored issues
show
introduced by
The condition $request->headers->get('Referer') === null is always false.
Loading history...
458
            return $this->buildRedirectInternalResponse();
459
        }
460
461
        return $this->redirectResponseExternal($request->headers->get('Referer'));
462
    }
463
464
    /**
465
     * @param \Generated\Shared\Transfer\CheckoutResponseTransfer $checkoutResponseTransfer
466
     *
467
     * @return void
468
     */
469
    protected function setCheckoutErrorMessages(CheckoutResponseTransfer $checkoutResponseTransfer)
470
    {
471
        foreach ($checkoutResponseTransfer->getErrors() as $checkoutErrorTransfer) {
472
            $this->addErrorMessage(
473
                $this->translateCheckoutErrorMessage($checkoutErrorTransfer)
474
            );
475
        }
476
    }
477
478
    /**
479
     * @param \Generated\Shared\Transfer\CheckoutErrorTransfer $checkoutErrorTransfer
480
     *
481
     * @return string
482
     */
483
    protected function translateCheckoutErrorMessage(CheckoutErrorTransfer $checkoutErrorTransfer): string
484
    {
485
        $checkoutErrorMessage = $checkoutErrorTransfer->getMessage();
486
487
        return $this->getFactory()->getGlossaryStorageClient()->translate(
488
            $checkoutErrorMessage,
489
            $this->getLocale(),
490
            $checkoutErrorTransfer->getParameters()
491
        ) ?: $checkoutErrorMessage;
492
    }
493
494
    /**
495
     * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
496
     *
497
     * @return void
498
     */
499
    protected function addAmazonPayErrorFromQuote(QuoteTransfer $quoteTransfer)
500
    {
501
        if ($quoteTransfer->getAmazonpayPayment() === null
502
            || $quoteTransfer->getAmazonpayPayment()->getResponseHeader() === null
503
            || $quoteTransfer->getAmazonpayPayment()->getResponseHeader()->getErrorMessage() === null) {
504
            return;
505
        }
506
507
        $this->addErrorMessage(
508
            $quoteTransfer->getAmazonpayPayment()->getResponseHeader()->getErrorMessage()
509
        );
510
    }
511
512
    /**
513
     * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
514
     *
515
     * @return bool
516
     */
517
    protected function isAmazonPayment(QuoteTransfer $quoteTransfer)
518
    {
519
        return $quoteTransfer->getAmazonpayPayment() !== null;
520
    }
521
522
    /**
523
     * @return \Symfony\Component\HttpFoundation\RedirectResponse
524
     */
525
    protected function buildRedirectInternalResponse()
526
    {
527
        return $this->redirectResponseInternal($this->getPaymentRejectRoute());
528
    }
529
530
    /**
531
     * @return string
532
     */
533
    protected function getPaymentRejectRoute()
534
    {
535
        return Config::get(AmazonPayConstants::PAYMENT_REJECT_ROUTE);
536
    }
537
538
    /**
539
     * @return bool
540
     */
541
    protected function isAsynchronous()
542
    {
543
        return $this->getAmazonPayConfig()->getAuthTransactionTimeout() > 0
544
            && !$this->getAmazonPayConfig()->getCaptureNow();
545
    }
546
547
    /**
548
     * @return \SprykerEco\Shared\AmazonPay\AmazonPayConfigInterface
549
     */
550
    protected function getAmazonPayConfig()
551
    {
552
        return $this->getFactory()->createAmazonPayConfig();
553
    }
554
555
    /**
556
     * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
557
     *
558
     * @return bool
559
     */
560
    protected function isAmazonPaymentInvalid(QuoteTransfer $quoteTransfer)
561
    {
562
        if ($quoteTransfer->getAmazonpayPayment()->getResponseHeader() !== null
563
            && $quoteTransfer->getAmazonpayPayment()->getResponseHeader()->getIsInvalidPaymentMethod()) {
564
            return true;
565
        }
566
567
        return false;
568
    }
569
570
    /**
571
     * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
572
     *
573
     * @return string|null
574
     */
575
    protected function getAmazonPaymentOrderReferenceId(QuoteTransfer $quoteTransfer)
576
    {
577
        if ($quoteTransfer->getAmazonpayPayment() !== null && $quoteTransfer->getAmazonpayPayment()->getOrderReferenceId() !== null) {
578
            return $quoteTransfer->getAmazonpayPayment()->getOrderReferenceId();
579
        }
580
581
        return null;
582
    }
583
584
    /**
585
     * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
586
     *
587
     * @return array
588
     */
589
    protected function preparePSD2Data(QuoteTransfer $quoteTransfer): array
590
    {
591
        return [
592
            static::PSD2_DATA_KEY_AJAX_ENDPOINT => $this->getApplication()->path(AmazonPayControllerProvider::CONFIRM_PURCHASE),
593
            static::PSD2_DATA_KEY_SELLER_ID => $this->getAmazonPayConfig()->getSellerId(),
594
            static::PSD2_DATA_KEY_AMAZON_ORDER_REFERENCE_ID => $quoteTransfer->getAmazonpayPayment()->getOrderReferenceId(),
595
            static::PSD2_DATA_KEY_AMAZON_FAILURE_URL => $this->getApplication()->path(AmazonPayControllerProvider::PAYMENT_FAILED),
596
        ];
597
    }
598
599
    /**
600
     * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
601
     *
602
     * @return void
603
     */
604
    protected function clearAmazonpayQuoteData(): void
605
    {
606
        $quoteTransfer = $this->getFactory()->getQuoteClient()->getQuote();
607
608
        $amazonpayPaymentTransfer = new AmazonpayPaymentTransfer();
609
610
        $quoteTransfer->setAmazonpayPayment($amazonpayPaymentTransfer);
611
612
        $this->getFactory()->getQuoteClient()->setQuote($quoteTransfer);
613
    }
614
615
    /**
616
     * @param \Generated\Shared\Transfer\AmazonpayStatusTransfer $amazonpayStatusTransfer
617
     *
618
     * @return bool
619
     */
620
    protected function isAuthSucceeded(AmazonpayStatusTransfer $amazonpayStatusTransfer): bool
621
    {
622
        return in_array($amazonpayStatusTransfer->getState(), [
623
            AmazonPayConfig::STATUS_OPEN,
624
            AmazonPayConfig::STATUS_PENDING,
625
            AmazonPayConfig::STATUS_CLOSED,
626
        ]);
627
    }
628
629
    /**
630
     * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
631
     *
632
     * @return bool
633
     */
634
    protected function isOrderStatusOpen(QuoteTransfer $quoteTransfer): bool
635
    {
636
        return $quoteTransfer->getAmazonpayPayment()->getOrderReferenceStatus()->getState() === AmazonPayConfig::STATUS_OPEN;
637
    }
638
639
    /**
640
     * @param array $payload
641
     * @param int $statusCode
642
     *
643
     * @return \Symfony\Component\HttpFoundation\JsonResponse
644
     */
645
    protected function createJsonResponse(array $payload, int $statusCode = 200): JsonResponse
646
    {
647
        return new JsonResponse($payload, $statusCode);
648
    }
649
650
    /**
651
     * @param \Generated\Shared\Transfer\AmazonpayStatusTransfer $amazonpayStatusTransfer
652
     *
653
     * @return bool
654
     */
655
    protected function isAuthorizationFailed(AmazonpayStatusTransfer $amazonpayStatusTransfer): bool
656
    {
657
        return in_array($amazonpayStatusTransfer->getState(), [
658
            AmazonPayConfig::STATUS_TRANSACTION_TIMED_OUT,
659
            AmazonPayConfig::STATUS_DECLINED
660
        ]);
661
    }
662
663
    /**
664
     * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
665
     *
666
     * @return bool
667
     */
668
    protected function isAuthorizationExpired(QuoteTransfer $quoteTransfer): bool
669
    {
670
        $authorizationStatusTransfer = $this->getAuthorizationTransfer($quoteTransfer);
671
672
        return $authorizationStatusTransfer->getState() === AmazonPayConfig::STATUS_TRANSACTION_TIMED_OUT
673
        && $authorizationStatusTransfer->getReasonCode() === AmazonPayConfig::REASON_CODE_TRANSACTION_TIMED_OUT
674
        && !$this->getAmazonPayConfig()->getCaptureNow();
675
    }
676
677
    /**
678
     * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
679
     *
680
     * @return \Generated\Shared\Transfer\QuoteTransfer
681
     */
682
    protected function reauthorizeOrder(QuoteTransfer $quoteTransfer): QuoteTransfer
683
    {
684
        $quoteTransfer->getAmazonpayPayment()->setIsReauthorizingAsync(true);
685
686
        return $this->getClient()->authorizeOrder($quoteTransfer);
687
    }
688
689
    /**
690
     * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
691
     *
692
     * @return \Generated\Shared\Transfer\AmazonpayStatusTransfer
693
     */
694
    protected function getAuthorizationTransfer(QuoteTransfer $quoteTransfer): AmazonpayStatusTransfer
695
    {
696
        return $quoteTransfer
697
            ->getAmazonpayPayment()
698
            ->getAuthorizationDetails()
699
            ->getAuthorizationStatus();
700
    }
701
702
    /**
703
     * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
704
     *
705
     * @return \Symfony\Component\HttpFoundation\RedirectResponse
706
     */
707
    protected function redirectToAmazonCheckoutPage(QuoteTransfer $quoteTransfer): RedirectResponse
708
    {
709
        return $this->redirectResponseInternal(AmazonPayControllerProvider::CHECKOUT, [
710
            static::URL_PARAM_REFERENCE_ID => $quoteTransfer->getAmazonpayPayment()->getOrderReferenceId(),
711
            static::URL_PARAM_ACCESS_TOKEN => $quoteTransfer->getAmazonpayPayment()->getAddressConsentToken(),
712
        ]);
713
    }
714
}
715