Passed
Push — fix/eco-1985-handle-invalid-pa... ( 06b43c )
by Andrey
04:20
created

PaymentController::storeAmazonPaymentIntoQuote()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 14
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 9
nc 2
nop 2
dl 0
loc 14
rs 9.9666
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\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...
12
use Spryker\Shared\Config\Config;
13
use Spryker\Yves\Kernel\Controller\AbstractController;
14
use SprykerEco\Shared\AmazonPay\AmazonPayConstants;
15
use SprykerEco\Yves\AmazonPay\Plugin\Provider\AmazonPayControllerProvider;
16
use Symfony\Component\HttpFoundation\JsonResponse;
17
use Symfony\Component\HttpFoundation\Request;
18
19
/**
20
 * @method \SprykerEco\Client\AmazonPay\AmazonPayClientInterface getClient()
21
 * @method \SprykerEco\Yves\AmazonPay\AmazonPayFactory getFactory()
22
 */
23
class PaymentController extends AbstractController
24
{
25
    const URL_PARAM_REFERENCE_ID = 'reference_id';
26
    const URL_PARAM_ACCESS_TOKEN = 'access_token';
27
    const URL_PARAM_SHIPMENT_METHOD_ID = 'shipment_method_id';
28
    const QUOTE_TRANSFER = 'quoteTransfer';
29
    const SHIPMENT_METHODS = 'shipmentMethods';
30
    const SELECTED_SHIPMENT_METHOD_ID = 'selectedShipmentMethodId';
31
    const AMAZONPAY_CONFIG = 'amazonpayConfig';
32
    const IS_ASYNCHRONOUS = 'isAsynchronous';
33
    const CART_ITEMS = 'cartItems';
34
    const SUCCESS = 'success';
35
    const ERROR_AMAZONPAY_PAYMENT_FAILED = 'amazonpay.payment.failed';
36
    const IS_AMAZON_PAYMENT_INVALID = 'isAmazonPaymentInvalid';
37
38
    /**
39
     * @param \Symfony\Component\HttpFoundation\Request $request
40
     *
41
     * @return array|\Symfony\Component\HttpFoundation\Response
42
     */
43
    public function checkoutAction(Request $request)
44
    {
45
        $quoteTransfer = $this->getFactory()
46
            ->getQuoteClient()
47
            ->getQuote();
48
49
        if (!$this->isAllowedCheckout($quoteTransfer) || !$this->isRequestComplete($request)) {
50
            $this->addErrorFromQuote($quoteTransfer);
51
52
            return $this->buildRedirectInternalResponse();
53
        }
54
55
        $this->storeAmazonPaymentIntoQuote($request, $quoteTransfer);
56
57
        return [
58
            static::QUOTE_TRANSFER => $quoteTransfer,
59
            static::CART_ITEMS => $this->getCartItems($quoteTransfer),
60
            static::AMAZONPAY_CONFIG => $this->getAmazonPayConfig(),
61
        ];
62
    }
63
64
    /**
65
     * @param \Symfony\Component\HttpFoundation\Request $request
66
     *
67
     * @return \Symfony\Component\HttpFoundation\Response
68
     */
69
    public function setOrderReferenceAction(Request $request)
70
    {
71
        $quoteTransfer = $this->getFactory()
72
            ->getQuoteClient()
73
            ->getQuote();
74
75
        if (!$this->isAmazonPayment($quoteTransfer)) {
76
            return $this->buildRedirectInternalResponse();
77
        }
78
79
        $quoteTransfer->getAmazonpayPayment()
80
            ->setOrderReferenceId(
81
                $request->request->get(static::URL_PARAM_REFERENCE_ID)
82
            );
83
84
        return new JsonResponse([static::SUCCESS => true]);
85
    }
86
87
    /**
88
     * @return array|\Symfony\Component\HttpFoundation\Response
89
     */
90
    public function getShipmentMethodsAction()
91
    {
92
        $quoteTransfer = $this->getFactory()
93
            ->getQuoteClient()
94
            ->getQuote();
95
96
        if (!$this->isAmazonPayment($quoteTransfer)) {
97
            $this->addErrorFromQuote($quoteTransfer);
98
99
            return $this->buildRedirectInternalResponse();
100
        }
101
102
        $quoteTransfer = $this->getClient()
103
            ->addSelectedAddressToQuote($quoteTransfer);
104
        $this->getFactory()
105
            ->getQuoteClient()
106
            ->setQuote($quoteTransfer);
107
        $shipmentMethods = $this->getFactory()
108
            ->getShipmentClient()
109
            ->getAvailableMethods($quoteTransfer);
110
111
        return [
112
            static::SELECTED_SHIPMENT_METHOD_ID => $this->getCurrentShipmentMethodId($quoteTransfer),
113
            static::SHIPMENT_METHODS => $shipmentMethods->getMethods(),
114
            static::IS_AMAZON_PAYMENT_INVALID => $this->isAmazonPaymentInvalid($quoteTransfer),
115
        ];
116
    }
117
118
    /**
119
     * @param \Symfony\Component\HttpFoundation\Request $request
120
     *
121
     * @return array|\Symfony\Component\HttpFoundation\RedirectResponse
122
     */
123
    public function updateShipmentMethodAction(Request $request)
124
    {
125
        $quoteTransfer = $this->getFactory()->getQuoteClient()->getQuote();
126
127
        if (!$this->isAmazonPayment($quoteTransfer)) {
128
            $this->addErrorFromQuote($quoteTransfer);
129
130
            return $this->buildRedirectInternalResponse();
131
        }
132
133
        $quoteTransfer->getShipment()->setShipmentSelection(
134
            $request->request->get(static::URL_PARAM_SHIPMENT_METHOD_ID)
135
        );
136
        $quoteTransfer = $this->getClient()
137
            ->addSelectedShipmentMethodToQuote($quoteTransfer);
138
        $quoteTransfer = $this->getFactory()
139
            ->getCalculationClient()->recalculate($quoteTransfer);
140
        $this->getFactory()
141
            ->getQuoteClient()
142
            ->setQuote($quoteTransfer);
143
144
        return [
145
            static::QUOTE_TRANSFER => $quoteTransfer,
146
        ];
147
    }
148
149
    /**
150
     * @param \Symfony\Component\HttpFoundation\Request $request
151
     *
152
     * @return \Symfony\Component\HttpFoundation\Response
153
     */
154
    public function confirmPurchaseAction(Request $request)
155
    {
156
        $quoteTransfer = $this->getFactory()->getQuoteClient()->getQuote();
157
158
        if (!$this->isAmazonPayment($quoteTransfer)) {
159
            $this->addErrorFromQuote($quoteTransfer);
160
161
            return $this->buildRedirectInternalResponse();
162
        }
163
164
        $quoteTransfer = $this->getClient()->confirmPurchase($quoteTransfer);
165
166
        if (!$quoteTransfer->getAmazonpayPayment()->getResponseHeader()->getIsSuccess()) {
167
            $this->addErrorFromQuote($quoteTransfer);
168
169
            return $this->buildRedirectExternalResponse($request);
170
        }
171
172
        $quoteTransfer = $this->getFactory()->getCalculationClient()->recalculate($quoteTransfer);
173
        $this->getFactory()->getQuoteClient()->setQuote($quoteTransfer);
174
175
        $checkoutResponseTransfer = $this->getFactory()->getCheckoutClient()->placeOrder($quoteTransfer);
176
177
        if ($checkoutResponseTransfer->getIsSuccess()) {
178
            return $this->redirectResponseInternal(AmazonPayControllerProvider::SUCCESS);
179
        }
180
181
        $this->addErrorFromQuote($quoteTransfer);
182
183
        return $this->buildRedirectInternalResponse();
184
    }
185
186
    /**
187
     * @param \Symfony\Component\HttpFoundation\Request $request
188
     *
189
     * @return array
190
     */
191
    public function successAction(Request $request)
192
    {
193
        $this->getFactory()->getQuoteClient()->clearQuote();
194
195
        return [
196
            static::IS_ASYNCHRONOUS => $this->isAsynchronous(),
197
            static::AMAZONPAY_CONFIG => $this->getAmazonPayConfig(),
198
        ];
199
    }
200
201
    /**
202
     * @param \Symfony\Component\HttpFoundation\Request $request
203
     * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
204
     *
205
     * @return void
206
     */
207
    protected function storeAmazonPaymentIntoQuote(Request $request, QuoteTransfer $quoteTransfer)
208
    {
209
        if ($quoteTransfer->getAmazonpayPayment() !== null) {
210
            return;
211
        }
212
213
        $amazonPaymentTransfer = $this->buildAmazonPaymentTransfer($request);
214
215
        $quoteTransfer->setAmazonpayPayment($amazonPaymentTransfer);
216
        $quoteTransfer = $this->getClient()
217
            ->handleCartWithAmazonPay($quoteTransfer);
218
        $this->getFactory()
219
            ->getQuoteClient()
220
            ->setQuote($quoteTransfer);
221
    }
222
223
    /**
224
     * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
225
     *
226
     * @return int
227
     */
228
    protected function getCurrentShipmentMethodId(QuoteTransfer $quoteTransfer)
229
    {
230
        if ($quoteTransfer->getShipment() === null || $quoteTransfer->getShipment()->getMethod() === null) {
231
            return 0;
232
        }
233
234
        return $quoteTransfer->getShipment()->getMethod()->getIdShipmentMethod();
235
    }
236
237
    /**
238
     * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
239
     *
240
     * @return \ArrayObject|\Generated\Shared\Transfer\ItemTransfer[]
241
     */
242
    protected function getCartItems(QuoteTransfer $quoteTransfer)
243
    {
244
        return $quoteTransfer->getItems();
245
    }
246
247
    /**
248
     * @param \Symfony\Component\HttpFoundation\Request $request
249
     *
250
     * @return bool
251
     */
252
    protected function isRequestComplete(Request $request)
253
    {
254
        return (
255
            $request->query->get(static::URL_PARAM_REFERENCE_ID) !== null &&
256
            $request->query->get(static::URL_PARAM_ACCESS_TOKEN) !== null
257
        );
258
    }
259
260
    /**
261
     * @param \Symfony\Component\HttpFoundation\Request $request
262
     *
263
     * @return \Generated\Shared\Transfer\AmazonpayPaymentTransfer
264
     */
265
    protected function buildAmazonPaymentTransfer(Request $request)
266
    {
267
        $amazonPaymentTransfer = new AmazonpayPaymentTransfer();
268
        $amazonPaymentTransfer->setOrderReferenceId($request->query->get(static::URL_PARAM_REFERENCE_ID));
269
        $amazonPaymentTransfer->setAddressConsentToken($request->query->get(static::URL_PARAM_ACCESS_TOKEN));
270
271
        return $amazonPaymentTransfer;
272
    }
273
274
    /**
275
     * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
276
     *
277
     * @return bool
278
     */
279
    protected function isAllowedCheckout(QuoteTransfer $quoteTransfer)
280
    {
281
        return $quoteTransfer->getTotals() !== null;
282
    }
283
284
    /**
285
     * @param \Symfony\Component\HttpFoundation\Request $request
286
     *
287
     * @return \Symfony\Component\HttpFoundation\RedirectResponse
288
     */
289
    protected function buildRedirectExternalResponse(Request $request)
290
    {
291
        if ($request->headers->get('Referer') === null) {
0 ignored issues
show
introduced by
The condition $request->headers->get('Referer') === null is always false.
Loading history...
292
            return $this->buildRedirectInternalResponse();
293
        }
294
295
        return $this->redirectResponseExternal($request->headers->get('Referer'));
296
    }
297
298
    /**
299
     * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
300
     *
301
     * @return void
302
     */
303
    protected function addErrorFromQuote(QuoteTransfer $quoteTransfer)
304
    {
305
        $this->addErrorMessage(
306
            $this->getErrorMessageFromQuote($quoteTransfer)
307
        );
308
    }
309
310
    /**
311
     * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
312
     *
313
     * @return bool
314
     */
315
    protected function isAmazonPayment(QuoteTransfer $quoteTransfer)
316
    {
317
        return $quoteTransfer->getAmazonpayPayment() !== null;
318
    }
319
320
    /**
321
     * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
322
     *
323
     * @return string
324
     */
325
    protected function getErrorMessageFromQuote(QuoteTransfer $quoteTransfer)
326
    {
327
        if ($quoteTransfer->getAmazonpayPayment() === null
328
            || $quoteTransfer->getAmazonpayPayment()->getResponseHeader() === null
329
            || $quoteTransfer->getAmazonpayPayment()->getResponseHeader()->getErrorMessage() === null) {
330
            return static::ERROR_AMAZONPAY_PAYMENT_FAILED;
331
        }
332
333
        return $quoteTransfer->getAmazonpayPayment()->getResponseHeader()->getErrorMessage();
334
    }
335
336
    /**
337
     * @return \Symfony\Component\HttpFoundation\RedirectResponse
338
     */
339
    protected function buildRedirectInternalResponse()
340
    {
341
        return $this->redirectResponseInternal($this->getPaymentRejectRoute());
342
    }
343
344
    /**
345
     * @return string
346
     */
347
    protected function getPaymentRejectRoute()
348
    {
349
        return Config::get(AmazonPayConstants::PAYMENT_REJECT_ROUTE);
350
    }
351
352
    /**
353
     * @return bool
354
     */
355
    protected function isAsynchronous()
356
    {
357
        return $this->getAmazonPayConfig()->getAuthTransactionTimeout() > 0
358
            && !$this->getAmazonPayConfig()->getCaptureNow();
359
    }
360
361
    /**
362
     * @return \SprykerEco\Shared\AmazonPay\AmazonPayConfigInterface
363
     */
364
    protected function getAmazonPayConfig()
365
    {
366
        return $this->getFactory()->createAmazonPayConfig();
367
    }
368
369
    /**
370
     * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
371
     *
372
     * @return bool
373
     */
374
    protected function isAmazonPaymentInvalid(QuoteTransfer $quoteTransfer)
375
    {
376
        return $quoteTransfer->getAmazonpayPayment()->getResponseHeader() !== null
377
            && false === $quoteTransfer->getAmazonpayPayment()->getResponseHeader()->getIsSuccess();
378
    }
379
}
380