Passed
Pull Request — dev (#9)
by Andrey
08:25 queued 04:31
created

PaymentController::checkoutAction()   B

Complexity

Conditions 3
Paths 2

Size

Total Lines 25
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

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