diff --git a/Controller/tpay/Create.php b/Controller/tpay/Create.php index fd98d71..3507169 100644 --- a/Controller/tpay/Create.php +++ b/Controller/tpay/Create.php @@ -5,6 +5,7 @@ use Magento\Checkout\Model\Session; use Magento\Framework\App\Action\Action; use Magento\Framework\App\Action\Context; +use Magento\Framework\App\CacheInterface; use Tpay\OriginApi\Utilities\Util; use tpaycom\magento2basic\Api\TpayInterface; use tpaycom\magento2basic\Model\ApiFacade\Transaction\TransactionApiFacade; @@ -25,23 +26,38 @@ class Create extends Action /** @var TransactionApiFacade */ private $transaction; - public function __construct(Context $context, TpayInterface $tpayModel, TpayService $tpayService, Session $checkoutSession) - { + /** @var CacheInterface */ + private $cache; + + /** + * {@inheritdoc} + * @param TpayInterface $tpayModel + * @param TpayService $tpayService + */ + public function __construct( + Context $context, + TpayInterface $tpayModel, + TpayService $tpayService, + Session $checkoutSession, + CacheInterface $cache + ) { $this->tpay = $tpayModel; $this->tpayService = $tpayService; $this->checkoutSession = $checkoutSession; + $this->cache = $cache; Util::$loggingEnabled = false; parent::__construct($context); } + /** {@inheritdoc} */ public function execute() { $orderId = $this->checkoutSession->getLastRealOrderId(); if ($orderId) { $payment = $this->tpayService->getPayment($orderId); $paymentData = $payment->getData(); - $this->transaction = new TransactionApiFacade($this->tpay); + $this->transaction = new TransactionApiFacade($this->tpay, $this->cache); $additionalPaymentInformation = $paymentData['additional_information']; $transaction = $this->prepareTransaction($orderId, $additionalPaymentInformation); @@ -108,12 +124,17 @@ private function prepareTransaction($orderId, array $additionalPaymentInformatio $this->handleBlikData($data, $additionalPaymentInformation['blik_code']); } else { $data['group'] = (int) $additionalPaymentInformation['group']; + $data['channel'] = (int) ($additionalPaymentInformation['channel'] ?? null); if ($this->tpay->redirectToChannel()) { $data['direct'] = 1; } } + if ($data['channel']) { + return $this->transaction->createWithInstantRedirection($data); + } + return $this->transaction->create($data); } diff --git a/Model/ApiFacade/CardTransaction/CardOpen.php b/Model/ApiFacade/CardTransaction/CardOpen.php index b032956..49d6bbc 100755 --- a/Model/ApiFacade/CardTransaction/CardOpen.php +++ b/Model/ApiFacade/CardTransaction/CardOpen.php @@ -76,6 +76,8 @@ private function processSavedCardPayment(string $orderId, int $cardId): string return 'magento2basic/tpay/success'; } + $paymentResult = $result['payments'] ?? []; + if (isset($paymentResult['status']) && 'declined' === $paymentResult['status']) { $this->tpayService->addCommentToHistory($orderId, 'Failed to pay by saved card, Elavon rejection code: '.$paymentResult['reason']); } else { diff --git a/Model/Config/Source/OnsiteChannels.php b/Model/Config/Source/OnsiteChannels.php new file mode 100644 index 0000000..d379b2a --- /dev/null +++ b/Model/Config/Source/OnsiteChannels.php @@ -0,0 +1,43 @@ +transactions = new TransactionApiFacade($tpay, $cache); + } + + public function getLabelFromValue(int $value): ?string + { + foreach ($this->toOptionArray() as $option) { + if ($option['value'] === $value) { + return $option['label']; + } + } + + return null; + } + + /** + * @inheritDoc + * + * @return array{array{value: int, label: string}} + */ + public function toOptionArray(): array + { + return array_map(function (array $channel) { + return ['value' => (int) $channel['id'], 'label' => $channel['fullName']]; + }, $this->transactions->channels()); + } +} diff --git a/Model/GenericOnSiteConfigProvider.php b/Model/GenericOnSiteConfigProvider.php new file mode 100644 index 0000000..64e6e13 --- /dev/null +++ b/Model/GenericOnSiteConfigProvider.php @@ -0,0 +1,133 @@ +paymentHelper = $paymentHelper; + $this->assetRepository = $assetRepository; + $this->methodList = $methods; + $this->scopeConfig = $scopeConfig; + $this->transactionApiFacade = $transactionApiFacade; + } + + /** + * @inheritDoc + */ + public function getConfig() + { + $tpay = $this->getPaymentMethodInstance(); + $onsites = explode(',', $this->scopeConfig->getValue('payment/tpaycom_magento2basic/onsite_channels', ScopeInterface::SCOPE_STORE)); + + $config = [ + 'tpay' => [ + 'payment' => [ + 'redirectUrl' => $tpay->getPaymentRedirectUrl(), + 'tpayLogoUrl' => $this->generateURL('tpaycom_magento2basic::images/logo_tpay.png'), + 'merchantId' => $tpay->getMerchantId(), + 'showPaymentChannels' => $this->showChannels(), + 'getTerms' => $this->getTerms(), + 'addCSS' => $this->createCSS('tpaycom_magento2basic::css/tpay.css'), + 'blikStatus' => $this->getPaymentMethodInstance()->checkBlikLevel0Settings(), + 'onlyOnlineChannels' => $this->getPaymentMethodInstance()->onlyOnlineChannels(), + 'getBlikChannelID' => TransactionModel::BLIK_CHANNEL, + 'isInstallmentsAmountValid' => $this->getPaymentMethodInstance()->getInstallmentsAmountValid(), + ], + ], + ]; + + $channels = $this->transactionApiFacade->channels(); + + foreach ($channels as $channel) { + $config['generic'][$channel['id']] = [ + 'id' => $channel['id'], + 'name' => $channel['fullName'], + 'logoUrl' => $channel['image']['url'], + ]; + } + + + return $config; + } + + /** + * @param string $name + * + * @return string + */ + public function generateURL($name) + { + return $this->assetRepository->createAsset($name)->getUrl(); + } + + /** @return null|string */ + public function showChannels() + { + $script = 'tpaycom_magento2basic::js/render_channels.js'; + + return $this->createScript($script); + } + + /** + * @param string $script + * + * @return string + */ + public function createScript($script) + { + return " + "; + } + + /** @return null|string */ + public function getTerms() + { + return $this->getPaymentMethodInstance()->getTermsURL(); + } + + /** + * @param string $css + * + * @return string + */ + public function createCSS($css) + { + return "generateURL($css)}\">"; + } + + /** @return MethodInterface|TpayInterface */ + protected function getPaymentMethodInstance() + { + if (null === $this->paymentMethod) { + $this->paymentMethod = $this->paymentHelper->getMethodInstance(TpayInterface::CODE); + } + + return $this->paymentMethod; + } +} diff --git a/Model/GenericOnsite.php b/Model/GenericOnsite.php new file mode 100644 index 0000000..c8b84ae --- /dev/null +++ b/Model/GenericOnsite.php @@ -0,0 +1,206 @@ +_isGateway = true; + $this->_canRefund = true; + $this->_canRefundInvoicePartial = true; + $this->_code = 'generic'; + $this->_title = 'generic'; + $this->storeManager = $storeManager; + } + + public function setCode(string $code): void + { + $this->_code = $code; + } + + public function setChannelId(int $channelId): void + { + $this->_channelId = $channelId; + } + + public function getChannelId(): int + { + return $this->_channelId; + } + + public function setTitle(string $title): void + { + $this->_title = $title; + } + + public function getConfigData($field, $storeId = null) + { + if (is_null($storeId)) { + $storeId = $this->storeManager->getStore()->getId(); + } + + return parent::getConfigData($field, $storeId); + } + + public function assignData(DataObject $data): GenericOnsite + { + /** @var array $additionalData */ + $additionalData = $data->getData('additional_data'); + + $info = $this->getInfoInstance(); + $info->setAdditionalInformation('channel', $additionalData['channel']); + + return $this; + } + + public function isActive($storeId = null) + { + return true; + } + + public function getTitle(): string + { + return $this->_title ?? $this->getConfigData('title'); + } + + public function getRedirectURL(): string + { + return ''; + } + + public function getTpayFormData($orderId = null): array + { + return []; + } + + public function getApiPassword(): string + { + return ''; + } + + public function getApiKey(): string + { + return ''; + } + + public function getSecurityCode(): string + { + return ''; + } + + public function getMerchantId(): int + { + return ''; + } + + public function checkBlikLevel0Settings(): bool + { + return false; + } + + public function getBlikLevelZeroStatus(): bool + { + return false; + } + + public function onlyOnlineChannels(): bool + { + return false; + } + + public function redirectToChannel(): bool + { + return true; + } + + public function getPaymentRedirectUrl(): string + { + return ''; + } + + public function getTermsURL(): string + { + return ''; + } + + public function getInvoiceSendMail(): string + { + return ''; + } + + public function getCheckProxy(): bool + { + return ''; + } + + public function getCheckTpayIP(): bool + { + return true; + } + + public function getInstallmentsAmountValid(): bool + { + return false; + } + + public function useSandboxMode(): bool + { + return true; + } + + public function getClientId(): string + { + return ''; + } + + public function getOpenApiPassword(): string + { + return ''; + } +} diff --git a/Model/GenericPaymentPlugin.php b/Model/GenericPaymentPlugin.php new file mode 100644 index 0000000..44670a6 --- /dev/null +++ b/Model/GenericPaymentPlugin.php @@ -0,0 +1,18 @@ +getConfigData('redirect_directly_to_channel'); + return true; } public function useSandboxMode(): bool @@ -448,4 +448,9 @@ private function getMagentoVersion() return $productMetadata->getVersion(); } + + public function getClientId(): string + { + return $this->getConfigData('client_id'); + } } diff --git a/Model/TpayConfig.php b/Model/TpayConfig.php new file mode 100644 index 0000000..08a48f5 --- /dev/null +++ b/Model/TpayConfig.php @@ -0,0 +1,46 @@ +data = $data; + $this->scopeConfig = $scopeConfig; + $this->onsiteChannels = $onsiteChannels; + } + + public function afterGetAvailableMethods(MethodList $compiled, $result) + { + $onsiteChannels = $this->scopeConfig->getValue(self::CONFIG_PATH, ScopeInterface::SCOPE_STORE); + + foreach (explode(',', $onsiteChannels) as $onsiteChannel) { + $method = $this->data->getMethodInstance('generic'); + $method->setChannelId($onsiteChannel); + $method->setTitle($this->onsiteChannels->getLabelFromValue($onsiteChannel)); + $method->setCode("generic-".$onsiteChannel); + + $result[] = $method; + } + + return $result; + } +} diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml index a17c546..df4339f 100644 --- a/etc/adminhtml/system.xml +++ b/etc/adminhtml/system.xml @@ -21,6 +21,14 @@ + + + validate-length maximum-length-64 + + + + validate-length maximum-length-64 + validate-no-empty validate-number validate-length maximum-length-10 @@ -108,6 +116,10 @@ Leave empty for no limit validate-number + + + tpaycom\magento2basic\Model\Config\Source\OnsiteChannels + diff --git a/etc/config.xml b/etc/config.xml index f5303c0..a5e6c07 100644 --- a/etc/config.xml +++ b/etc/config.xml @@ -29,6 +29,24 @@ PLN 0 + + pending_payment + 0 + tpaycom\magento2basic\Model\GenericOnsite + Generic + 0 + 0.10 + 1 + 1 + 0 + 0 + 1 + 0 + 1 + PLN + 1 + 0 + diff --git a/etc/di.xml b/etc/di.xml index f4a2b78..7113f4b 100644 --- a/etc/di.xml +++ b/etc/di.xml @@ -11,4 +11,10 @@ + + + + + + diff --git a/etc/frontend/di.xml b/etc/frontend/di.xml index 9c150f7..3300093 100644 --- a/etc/frontend/di.xml +++ b/etc/frontend/di.xml @@ -9,18 +9,11 @@ */ --> - - - - tpaycom\magento2basic\Model\Tpay::CODE - - - - tpaycom\magento2basic\Model\TpayConfigProvider + tpaycom\magento2basic\Model\GenericOnSiteConfigProvider diff --git a/etc/payment.xml b/etc/payment.xml index 66ff6ab..701b0d0 100644 --- a/etc/payment.xml +++ b/etc/payment.xml @@ -13,5 +13,8 @@ 1 + + 1 + diff --git a/view/frontend/layout/checkout_index_index.xml b/view/frontend/layout/checkout_index_index.xml index 1bd606d..9e0456f 100644 --- a/view/frontend/layout/checkout_index_index.xml +++ b/view/frontend/layout/checkout_index_index.xml @@ -32,6 +32,9 @@ false + + false + diff --git a/view/frontend/web/js/view/payment/method-renderer/tpay-generic-onsite.js b/view/frontend/web/js/view/payment/method-renderer/tpay-generic-onsite.js new file mode 100644 index 0000000..d5b4a9c --- /dev/null +++ b/view/frontend/web/js/view/payment/method-renderer/tpay-generic-onsite.js @@ -0,0 +1,37 @@ +/** + * + * @category payment gateway + * @package Tpaycom_Magento2.3 + * @author Tpay.com + * @copyright (https://tpay.com) + */ +define( + [ + 'Magento_Checkout/js/view/payment/default', + 'jquery' + ], + function (Component, $) { + 'use strict'; + + return Component.extend({ + defaults: { + template: 'tpaycom_magento2basic/payment/tpay-generic-onsite' + }, + + afterPlaceOrder: function () { + window.location.replace(window.checkoutConfig.tpay.payment.redirectUrl); + }, + + getLogoUrl: function (code) { + const id = code.slice(code.indexOf('-') + 1); + + return window.checkoutConfig.generic[id].logoUrl; }, + + redirectAfterPlaceOrder: false, + + isActive: function () { + return true; + } + }); + } +); diff --git a/view/frontend/web/js/view/payment/tpay-payments.js b/view/frontend/web/js/view/payment/tpay-payments.js index 25ecaed..c917960 100644 --- a/view/frontend/web/js/view/payment/tpay-payments.js +++ b/view/frontend/web/js/view/payment/tpay-payments.js @@ -20,6 +20,9 @@ define( component: 'tpaycom_magento2basic/js/view/payment/method-renderer/tpay-method' } ); + + Object.values(window.checkoutConfig.generic).forEach((element) => rendererList.push({type: `generic-${element.id}`, component: 'tpaycom_magento2basic/js/view/payment/method-renderer/tpay-generic-onsite'})) + /** Add view logic here if needed */ return Component.extend({}); } diff --git a/view/frontend/web/template/payment/tpay-generic-onsite.html b/view/frontend/web/template/payment/tpay-generic-onsite.html new file mode 100644 index 0000000..4253f95 --- /dev/null +++ b/view/frontend/web/template/payment/tpay-generic-onsite.html @@ -0,0 +1,31 @@ +
+
+ + +
+
+ +
+
+ +
+
+
+