Passed
Branch feature/ECO-573-per-item-proce... (fe5bf4)
by Andrey
04:56
created

PaymentController::confirmPurchaseAction()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 36
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 20
nc 5
nop 1
dl 0
loc 36
rs 8.439
c 1
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;
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
26
    const URL_PARAM_REFERENCE_ID = 'reference_id';
27
    const URL_PARAM_ACCESS_TOKEN = 'access_token';
28
    const URL_PARAM_SHIPMENT_METHOD_ID = 'shipment_method_id';
29
    const QUOTE_TRANSFER = 'quoteTransfer';
30
    const SHIPMENT_METHODS = 'shipmentMethods';
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
37
    /**
38
     * @param \Symfony\Component\HttpFoundation\Request $request
39
     *
40
     * @return array|\Symfony\Component\HttpFoundation\Response
41
     */
42
    public function checkoutAction(Request $request)
43
    {
44
        $quoteTransfer = $this->getFactory()->getQuoteClient()->getQuote();
45
46
        if (!$this->isAllowedCheckout($quoteTransfer) || !$this->isRequestComplete($request)) {
47
            return $this->getFailedRedirectResponse();
48
        }
49
50
        $amazonPaymentTransfer = $this->buildAmazonPaymentTransfer($request);
51
52
        $quoteTransfer->setAmazonpayPayment($amazonPaymentTransfer);
53
        $quoteTransfer = $this->getClient()->handleCartWithAmazonpay($quoteTransfer);
0 ignored issues
show
Bug introduced by
The method handleCartWithAmazonpay() does not exist on SprykerEco\Yves\Amazonpay\AmazonpayFactory. ( Ignorable by Annotation )

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

53
        $quoteTransfer = $this->getClient()->/** @scrutinizer ignore-call */ handleCartWithAmazonpay($quoteTransfer);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
54
        $this->getFactory()->getQuoteClient()->setQuote($quoteTransfer);
55
56
        $cartItems = $this->getCartItems($quoteTransfer);
57
58
        return [
59
            self::QUOTE_TRANSFER => $quoteTransfer,
60
            self::CART_ITEMS => $cartItems,
61
            self::AMAZONPAY_CONFIG => $this->getAmazonPayConfig(),
62
        ];
63
    }
64
65
    /**
66
     * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
67
     *
68
     * @return \ArrayObject|\Generated\Shared\Transfer\ItemTransfer[]
69
     */
70
    protected function getCartItems(QuoteTransfer $quoteTransfer)
71
    {
72
        return $quoteTransfer->getItems();
73
    }
74
75
    /**
76
     * @param \Symfony\Component\HttpFoundation\Request $request
77
     *
78
     * @return bool
79
     */
80
    protected function isRequestComplete(Request $request)
81
    {
82
        return $request->query->get(static::URL_PARAM_REFERENCE_ID) !== null &&
83
            $request->query->get(static::URL_PARAM_ACCESS_TOKEN) !== null;
84
    }
85
86
    /**
87
     * @param \Symfony\Component\HttpFoundation\Request $request
88
     *
89
     * @return \Generated\Shared\Transfer\AmazonpayPaymentTransfer|null
90
     */
91
    protected function buildAmazonPaymentTransfer(Request $request)
92
    {
93
        $amazonPaymentTransfer = new AmazonpayPaymentTransfer();
94
        $amazonPaymentTransfer->setOrderReferenceId($request->query->get(static::URL_PARAM_REFERENCE_ID));
95
        $amazonPaymentTransfer->setAddressConsentToken($request->query->get(static::URL_PARAM_ACCESS_TOKEN));
96
97
        return $amazonPaymentTransfer;
98
    }
99
100
    /**
101
     * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
102
     *
103
     * @return bool
104
     */
105
    protected function isAllowedCheckout(QuoteTransfer $quoteTransfer)
106
    {
107
        return $quoteTransfer->getTotals() !== null;
108
    }
109
110
    /**
111
     * @param \Symfony\Component\HttpFoundation\Request $request
112
     *
113
     * @return \Symfony\Component\HttpFoundation\Response
114
     */
115
    public function setOrderReferenceAction(Request $request)
116
    {
117
        $quoteTransfer = $this->getFactory()->getQuoteClient()->getQuote();
118
119
        if (!$this->isAmazonPayment($quoteTransfer)) {
120
            return $this->getFailedRedirectResponse();
121
        }
122
123
        $quoteTransfer->getAmazonpayPayment()->setOrderReferenceId($request->request->get(static::URL_PARAM_REFERENCE_ID));
124
125
        return new JsonResponse([self::SUCCESS => true]);
126
    }
127
128
    /**
129
     * @return array|\Symfony\Component\HttpFoundation\Response
130
     */
131
    public function getShipmentMethodsAction()
132
    {
133
        $quoteTransfer = $this->getFactory()->getQuoteClient()->getQuote();
134
135
        if (!$this->isAmazonPayment($quoteTransfer)) {
136
            return $this->getFailedRedirectResponse();
137
        }
138
139
        $quoteTransfer = $this->getClient()->addSelectedAddressToQuote($quoteTransfer);
0 ignored issues
show
Bug introduced by
The method addSelectedAddressToQuote() does not exist on SprykerEco\Yves\Amazonpay\AmazonpayFactory. ( Ignorable by Annotation )

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

139
        $quoteTransfer = $this->getClient()->/** @scrutinizer ignore-call */ addSelectedAddressToQuote($quoteTransfer);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
140
        $this->getFactory()->getQuoteClient()->setQuote($quoteTransfer);
141
        $shipmentMethods = $this->getFactory()->getShipmentClient()->getAvailableMethods($quoteTransfer);
142
143
        return [
144
            self::SHIPMENT_METHODS => $shipmentMethods->getMethods(),
145
        ];
146
    }
147
148
    /**
149
     * @param \Symfony\Component\HttpFoundation\Request $request
150
     *
151
     * @return array|\Symfony\Component\HttpFoundation\RedirectResponse
152
     */
153
    public function updateShipmentMethodAction(Request $request)
154
    {
155
        $quoteTransfer = $this->getFactory()->getQuoteClient()->getQuote();
156
157
        if (!$this->isAmazonPayment($quoteTransfer)) {
158
            return $this->getFailedRedirectResponse();
159
        }
160
161
        $quoteTransfer->getShipment()->setShipmentSelection(
162
            (int)$request->request->get(static::URL_PARAM_SHIPMENT_METHOD_ID)
163
        );
164
        $quoteTransfer = $this->getClient()->addSelectedShipmentMethodToQuote($quoteTransfer);
0 ignored issues
show
Bug introduced by
The method addSelectedShipmentMethodToQuote() does not exist on SprykerEco\Yves\Amazonpay\AmazonpayFactory. ( Ignorable by Annotation )

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

164
        $quoteTransfer = $this->getClient()->/** @scrutinizer ignore-call */ addSelectedShipmentMethodToQuote($quoteTransfer);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
165
        $quoteTransfer = $this->getFactory()->getCalculationClient()->recalculate($quoteTransfer);
166
        $this->getFactory()->getQuoteClient()->setQuote($quoteTransfer);
167
168
        return [
169
            self::QUOTE_TRANSFER => $quoteTransfer,
170
        ];
171
    }
172
173
    /**
174
     * @param \Symfony\Component\HttpFoundation\Request $request
175
     *
176
     * @return \Symfony\Component\HttpFoundation\Response
177
     */
178
    public function confirmPurchaseAction(Request $request)
179
    {
180
        $quoteTransfer = $this->getFactory()->getQuoteClient()->getQuote();
181
182
        if (!$this->isAmazonPayment($quoteTransfer)) {
183
            return $this->getFailedRedirectResponse();
184
        }
185
186
        $quoteTransfer = $this->getClient()->confirmPurchase($quoteTransfer);
0 ignored issues
show
Bug introduced by
The method confirmPurchase() does not exist on SprykerEco\Yves\Amazonpay\AmazonpayFactory. ( Ignorable by Annotation )

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

186
        $quoteTransfer = $this->getClient()->/** @scrutinizer ignore-call */ confirmPurchase($quoteTransfer);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
187
        $quoteTransfer = $this->getFactory()->getCalculationClient()->recalculate($quoteTransfer);
188
        $this->getFactory()->getQuoteClient()->setQuote($quoteTransfer);
189
190
        if ($quoteTransfer->getAmazonpayPayment()
191
            ->getAuthorizationDetails()
192
            ->getAuthorizationStatus()
193
            ->getIsPaymentMethodInvalid()
194
        ) {
195
            return $this->redirectResponseInternal(AmazonpayControllerProvider::CHECKOUT);
196
        }
197
198
        if (!$quoteTransfer->getAmazonpayPayment()->getResponseHeader()->getIsSuccess()) {
199
            $this->addErrorMessage(
200
                $quoteTransfer->getAmazonpayPayment()->getResponseHeader()->getErrorMessage()
201
                ?? self::ERROR_AMAZONPAY_PAYMENT_FAILED
202
            );
203
204
            return $this->redirectResponseExternal($request->headers->get('Referer'));
205
        }
206
207
        $checkoutResponseTransfer = $this->getFactory()->getCheckoutClient()->placeOrder($quoteTransfer);
208
209
        if ($checkoutResponseTransfer->getIsSuccess()) {
210
            return $this->redirectResponseInternal(AmazonpayControllerProvider::SUCCESS);
211
        }
212
213
        return $this->getFailedRedirectResponse(self::ERROR_AMAZONPAY_PAYMENT_FAILED);
214
    }
215
216
    /**
217
     * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
218
     *
219
     * @return bool
220
     */
221
    protected function isAmazonPayment(QuoteTransfer $quoteTransfer)
222
    {
223
        return $quoteTransfer->getAmazonpayPayment() !== null;
224
    }
225
226
    /**
227
     * @param string|null $message
228
     *
229
     * @return \Symfony\Component\HttpFoundation\RedirectResponse
230
     */
231
    protected function getFailedRedirectResponse($message = null)
232
    {
233
        $this->addErrorMessage($message ?? self::ERROR_AMAZONPAY_PAYMENT_FAILED);
234
235
        return $this->redirectResponseInternal($this->getPaymentRejectRoute());
236
    }
237
238
    /**
239
     * @return string
240
     */
241
    protected function getPaymentRejectRoute()
242
    {
243
        return Config::get(AmazonpayConstants::PAYMENT_REJECT_ROUTE);
244
    }
245
246
    /**
247
     * @param \Symfony\Component\HttpFoundation\Request $request
248
     *
249
     * @return array
250
     */
251
    public function successAction(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

251
    public function successAction(/** @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...
252
    {
253
        $this->getFactory()->getQuoteClient()->clearQuote();
254
255
        $isAsynchronous =
256
            ($this->getAmazonPayConfig()->getAuthTransactionTimeout() > 0)
257
            && (!$this->getAmazonPayConfig()->getCaptureNow());
258
259
        return [
260
            self::IS_ASYNCHRONOUS => $isAsynchronous,
261
            self::AMAZONPAY_CONFIG => $this->getAmazonPayConfig(),
262
        ];
263
    }
264
265
    /**
266
     * @return \SprykerEco\Shared\Amazonpay\AmazonpayConfigInterface
267
     */
268
    protected function getAmazonPayConfig()
269
    {
270
        return $this->getFactory()->createAmazonpayConfig();
271
    }
272
273
}
274