PaymentManagement::createGuestPayment()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 29
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 1
eloc 13
c 1
b 0
f 1
nc 1
nop 4
dl 0
loc 29
rs 9.8333
1
<?php
2
3
namespace Getloy\GetloyMagentoGateway\Model;
4
5
use Getloy\GetloyMagentoGateway\Api\PaymentManagementInterface;
6
use Getloy\GetloyMagentoGateway\Gateway\Config\Config as GatewayConfig;
7
use Getloy\GetloyMagentoGateway\Model\CallbackResponse;
8
use Magento\Framework\UrlInterface;
9
use Magento\Sales\Api\OrderRepositoryInterface;
10
use Magento\Sales\Model\Order\Email\Sender\InvoiceSender;
11
use Magento\Payment\Gateway\Data\PaymentDataObjectFactory;
12
use Magento\Quote\Model\QuoteIdMaskFactory;
0 ignored issues
show
Bug introduced by
The type Magento\Quote\Model\QuoteIdMaskFactory 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 Magento\Quote\Api\BillingAddressManagementInterface;
14
use Magento\Quote\Api\CartManagementInterface;
15
use Magento\Quote\Api\CartRepositoryInterface;
16
use Magento\Store\Model\StoreManagerInterface;
17
18
class PaymentManagement implements PaymentManagementInterface
19
{
20
    /**
21
     * @var GatewayConfig
22
     */
23
    protected $gatewayConfig;
24
25
    /**
26
     * @var CartRepositoryInterface
27
     */
28
    protected $quoteRepository;
29
30
    /**
31
     * @var PaymentDataObjectFactory
32
     */
33
    protected $paymentDataObjectFactory;
34
35
    /**
36
     * @var QuoteIdMaskFactory
37
     */
38
    protected $quoteIdMaskFactory;
39
40
    /**
41
     * @var InvoiceSender
42
     */
43
    protected $invoiceSender;
44
45
    /**
46
     * @var OrderRepositoryInterface
47
     */
48
    protected $orderRepository;
49
50
    /**
51
     * @var BillingAddressManagementInterface
52
     */
53
    protected $billingAddressManagement;
54
55
    /**
56
     * @var StoreManagerInterface
57
     */
58
    protected $storeManager;
59
60
    /**
61
     * @var CartManagementInterface
62
     */
63
    protected $cartManagement;
64
    /**
65
     * @var UrlInterface
66
     */
67
    protected $url;
68
69
    /**
70
     * SessionInformationManagement constructor.
71
     *
72
     * @param GatewayConfig                     $gatewayConfig
73
     * @param CartRepositoryInterface           $quoteRepository
74
     * @param OrderRepositoryInterface          $orderRepository
75
     * @param PaymentDataObjectFactory          $paymentDataObjectFactory
76
     * @param QuoteIdMaskFactory                $quoteIdMaskFactory
77
     * @param InvoiceSender                     $invoiceSender
78
     * @param BillingAddressManagementInterface $billingAddressManagement
79
     * @param StoreManagerInterface             $storeManager
80
     * @param CartManagementInterface           $cartManagement
81
     * @param UrlInterface                      $url
82
     */
83
    public function __construct(
84
        GatewayConfig $gatewayConfig,
85
        CartRepositoryInterface $quoteRepository,
86
        OrderRepositoryInterface $orderRepository,
87
        PaymentDataObjectFactory $paymentDataObjectFactory,
88
        QuoteIdMaskFactory $quoteIdMaskFactory,
89
        InvoiceSender $invoiceSender,
90
        BillingAddressManagementInterface $billingAddressManagement,
91
        StoreManagerInterface $storeManager,
92
        CartManagementInterface $cartManagement,
93
        UrlInterface $url
94
    ) {
95
        $this->gatewayConfig = $gatewayConfig;
96
        $this->quoteRepository = $quoteRepository;
97
        $this->orderRepository = $orderRepository;
98
        $this->paymentDataObjectFactory = $paymentDataObjectFactory;
99
        $this->quoteIdMaskFactory = $quoteIdMaskFactory;
100
        $this->invoiceSender = $invoiceSender;
101
        $this->billingAddressManagement = $billingAddressManagement;
102
        $this->storeManager = $storeManager;
103
        $this->cartManagement = $cartManagement;
104
        $this->url = $url;
105
    }
106
107
    protected function generateTransactionId($orderId)
108
    {
109
        $tstamp = base_convert(time(), 10, 36);
110
        return sprintf('MG-%s-%s', $orderId, $tstamp);
111
    }
112
113
    protected function validateTransactionId($transactionId, $orderId)
114
    {
115
        return 1 === preg_match(
116
            sprintf('/^MG-%d-[0-9a-z]{6}$/', $orderId),
117
            $transactionId
118
        );
119
    }
120
121
    protected function generatePayload(
122
        \Magento\Quote\Model\Quote $quote,
123
        $orderId
124
    ) {
125
        $transactionId  = $this->generateTransactionId($orderId);
126
        $totalAmount    = round($quote->getGrandTotal(), 2);
127
        $currency       = $this->storeManager
128
            ->getStore()->getBaseCurrency()->getCode();
129
130
        /* @var \Magento\Quote\Api\Data\AddressInterface */
131
        $billingAddress = $quote->getBillingAddress();
132
        
133
        $getloyMerchantKey = $this->gatewayConfig->getGetloyMerchantKey();
134
        $testMode          = $this->gatewayConfig->isSandbox();
135
        $paywayMerchantId  = $this->gatewayConfig->getPaywayMerchantId();
136
        $paywayMerchantKey = $this->gatewayConfig->getPaywayApiKey();
137
138
        $getloyGateway = new \Getloy\Gateway($getloyMerchantKey);
139
        $getloyGateway->registerPaymentProvider(
140
            \Getloy\PaymentProviders::PAYWAY_KH,
141
            [
142
                'testMode' => $testMode,
143
                'merchantId' => $paywayMerchantId,
144
                'merchantKey' => $paywayMerchantKey,
145
            ]
146
        );
147
148
        $orderItems = new \Getloy\TransactionDetails\OrderItems();
149
150
        foreach ($quote->getAllVisibleItems() as $item) {
151
            $orderItems->add(
152
                new \Getloy\TransactionDetails\OrderItem(
153
                    $item->getName() ?: '',
154
                    (int) round($item->getQty(), 0),
155
                    $item->getRowTotal(),
156
                    $item->getPrice()
157
                )
158
            );
159
        }
160
161
        $order = new \Getloy\TransactionDetails\OrderDetails(
162
            $totalAmount,
163
            $currency,
164
            null,
165
            $orderItems
166
        );
167
168
169
        $payee = new \Getloy\TransactionDetails\PayeeDetails(
170
            $billingAddress->getFirstname(),
171
            $billingAddress->getLastname(),
172
            $billingAddress->getEmail() ? $billingAddress->getEmail() : '',
173
            $billingAddress->getTelephone() ? $billingAddress->getTelephone() : ''
174
        );
175
        return $getloyGateway->widgetPayload(
176
            $transactionId,
177
            \Getloy\PaymentProviders::PAYWAY_KH,
178
            $order,
179
            $payee,
180
            $this->url->getUrl('rest/default/V1/getloy/payment/callback/'.$orderId)
181
        );
182
    }
183
184
    /**
185
     * {@inheritDoc}
186
     *
187
     * @throws \Magento\Framework\Exception\LocalizedException
188
     */
189
    public function createPayment(
190
        $cartId,
191
        \Magento\Quote\Api\Data\PaymentInterface $paymentMethod,
192
        \Magento\Quote\Api\Data\AddressInterface $billingAddress
193
    ) {
194
        /**
195
         * @var \Magento\Quote\Model\Quote $quote 
196
         */
197
        $quote = $this->quoteRepository->getActive($cartId);
198
199
        return $this->placeOrderAndGetPayload(
200
            $quote,
201
            $paymentMethod,
202
            $billingAddress
203
        );
204
    }
205
206
    /**
207
     * {@inheritDoc}
208
     */
209
    public function createGuestPayment(
210
        $cartId,
211
        $email,
212
        \Magento\Quote\Api\Data\PaymentInterface $paymentMethod,
213
        \Magento\Quote\Api\Data\AddressInterface $billingAddress
214
    ) {
215
        $quoteIdMask = $this->quoteIdMaskFactory
216
            ->create()
217
            ->load($cartId, 'masked_id');
218
219
        $billingAddress->setEmail($email);
220
221
        /**
222
         * @var \Magento\Quote\Model\Quote $quote 
223
         */
224
        $quote = $this->quoteRepository->getActive($quoteIdMask->getQuoteId());
225
226
        $quote->setBillingAddress($billingAddress);
227
228
        $quote->setCheckoutMethod(
229
            \Magento\Quote\Api\CartManagementInterface::METHOD_GUEST
230
        );
231
232
        $this->quoteRepository->save($quote);
233
       
234
        return $this->placeOrderAndGetPayload(
235
            $quote,
236
            $paymentMethod,
237
            $billingAddress
238
        );
239
    }
240
241
    protected function placeOrderAndGetPayload(
242
        \Magento\Quote\Model\Quote $quote,
243
        \Magento\Quote\Api\Data\PaymentInterface $paymentMethod,
244
        \Magento\Quote\Api\Data\AddressInterface $billingAddress
245
    ) {
246
        $quote->setBillingAddress($billingAddress);
247
248
        $this->quoteRepository->save($quote);
249
250
        $orderId = $this->cartManagement->placeOrder(
251
            $quote->getId(),
252
            $paymentMethod
253
        );
254
255
        $payload = $this->generatePayload($quote, $orderId);
256
        
257
        /**
258
         * @var \Magento\Sales\Model\Order
259
         */
260
        $order = $this->orderRepository->get($orderId);
261
262
        $payment = $order->getPayment();
263
        $payment->setTransactionId($payload['tid']);
264
        $payment->setAdditionalInformation('getloy_transaction_id', $payload['tid']);
265
        $payment->setAdditionalInformation('getloy_payment_method', 'PayWay');
266
        $payment->setAdditionalInformation('getloy_method_variant', 'default');
267
        $payment->save();
268
269
        $order->addStatusHistoryComment(__('%1 payment session started.', 'PayWay'))
270
            ->save();
271
272
        return [ [
273
            'payload' => $payload,
274
        ] ];
275
    }
276
277
    /**
278
     * @param string $orderId
279
     * @param string $tid
280
     * @param string $status
281
     * @param string $amount_paid
282
     * @param string $currency
283
     * @param string $auth_hash_ext
284
     *
285
     * @return \Getloy\GetloyMagentoGateway\Model\CallbackResponse
286
     */
287
    public function handleCallback(
288
        $orderId,
289
        $tid,
290
        $status,
291
        $amount_paid,
292
        $currency,
293
        $auth_hash_ext
294
    ): CallbackResponse {
295
        $gateway = new \Getloy\Gateway($this->gatewayConfig->getGetloyMerchantKey());
296
297
        try {
298
            $callbackDetails = $gateway->validateCallback(
299
                [
300
                    'tid' => $tid,
301
                    'status' => $status,
302
                    'amount_paid' => $amount_paid,
303
                    'currency' => $currency,
304
                    'auth_hash_ext' => $auth_hash_ext
305
                ]
306
            );
307
        } catch (\Exception $e) {
308
            return new CallbackResponse('failed', 'malformed callback');
309
        }
310
311
        if (\Getloy\CallbackDetails::STATUS_SUCCESS !== $callbackDetails->status()) {
312
            return new CallbackResponse('failed', 'invalid transaction status');
313
        }
314
315
        try {
316
            /**
317
             * @var \Magento\Sales\Model\Order 
318
             */
319
            $order = $this->orderRepository->get((int) $orderId);
320
        } catch (\Exception $e) {
321
            return new CallbackResponse('failed', 'quote does not exist');
322
        }
323
324
        /**
325
         * @var \Magento\Sales\Model\Order\Payment 
326
         */
327
        $payment = $order->getPayment();
328
        $orderTid = $payment->getAdditionalInformation()['getloy_transaction_id'];
329
330
        if (!$this->validateTransactionId($tid, $orderId) || $tid !== $orderTid) {
331
            return new CallbackResponse('failed', 'order ID mismatch');
332
        }
333
334
        $totalAmount = round($order->getGrandTotal(), 2);
335
        $currency    = $order->getOrderCurrencyCode();
336
337
        if (abs($totalAmount - $callbackDetails->amountPaid()) > 0.01
338
            || $currency !== $callbackDetails->currency()
339
        ) {
340
            return new CallbackResponse('failed', 'invalid callback');
341
        }
342
343
        $order->addStatusHistoryComment(
344
            __(
345
                'PayWay payment complete. PayWay transaction ID: #%1.', 
346
                $tid
347
            )
348
        );
349
350
        $payment->setCurrencyCode($callbackDetails->currency());
351
        $payment->registerCaptureNotification($callbackDetails->amountPaid());
352
        $payment->save();
353
354
        /**
355
         * @var \Magento\Sales\Model\Order\Invoice 
356
         */
357
        $invoice = $payment->getCreatedInvoice();
358
        $this->invoiceSender->send($invoice);
359
        $order->addStatusHistoryComment(
360
            __(
361
                'You notified customer about invoice #%1.',
362
                $invoice->getIncrementId()
363
            )
364
        )
365
            ->setIsCustomerNotified(true)
366
            ->save();
367
368
        return new CallbackResponse('complete', 'callback processed successfully');
369
    }
370
}
371