diff --git a/Api/AsyncCheckerInterface.php b/Api/AsyncCheckerInterface.php new file mode 100644 index 00000000..ee75366b --- /dev/null +++ b/Api/AsyncCheckerInterface.php @@ -0,0 +1,16 @@ +initConstructor( + $productMetadataInterface, + $context, + $registry, + $adminHelper, + $data, + $shippingHelper, + $taxHelper + ); + $this->caseEntity = $caseEntity; - $this->coreRegistry = $registry; + $this->logsCollectionFactory = $logsCollectionFactory; + $this->casedataResourceModel = $casedataResourceModel; + $this->casedataFactory = $casedataFactory; + } - parent::__construct($context, $data); + public function initConstructor( + $productMetadataInterface, + $context, + $registry, + $adminHelper, + $data, + $shippingHelper, + $taxHelper + ) { + if (version_compare($productMetadataInterface->getVersion(), '2.4.0') >= 0) { + parent::__construct( + $context, + $registry, + $adminHelper, + $data, + $shippingHelper, + $taxHelper + ); + } else { + parent::__construct( + $context, + $registry, + $adminHelper, + $data + ); + } } /** @@ -54,23 +121,15 @@ public function getCaseEntity() if ($this->caseEntity->isEmpty()) { $order = $this->getOrder(); if (!$order->isEmpty()) { - $this->caseEntity = $this->caseEntity->load($order->getId(), 'order_id'); + $case = $this->casedataFactory->create(); + $this->casedataResourceModel->load($case, $order->getId(), 'order_id'); + $this->caseEntity = $case; } } return $this->caseEntity; } - /** - * Retrieve order model object - * - * @return \Magento\Sales\Model\Order - */ - public function getOrder() - { - return $this->coreRegistry->registry('sales_order'); - } - /** * Gets case guarantee disposition status */ @@ -110,4 +169,20 @@ public function getCheckpointActionReason() { return $this->getCaseEntity()->getData('checkpoint_action_reason'); } + + /** + * @return array|mixed|null + */ + public function hasLogsToDownload() + { + $order = $this->getOrder(); + + $quoteLogsCollection = $this->logsCollectionFactory->create() + ->addFieldToFilter('quote_id', ['eq' => $order->getQuoteId()]); + + $orderLogsCollection = $this->logsCollectionFactory->create() + ->addFieldToFilter('order_id', ['eq' => $order->getId()]); + + return $orderLogsCollection->count() > 0 || $quoteLogsCollection->count() > 0; + } } diff --git a/Block/Adminhtml/Grid/Column/SignifydGuarantee.php b/Block/Adminhtml/Grid/Column/SignifydGuarantee.php index baf98683..aff56532 100644 --- a/Block/Adminhtml/Grid/Column/SignifydGuarantee.php +++ b/Block/Adminhtml/Grid/Column/SignifydGuarantee.php @@ -11,12 +11,12 @@ class SignifydGuarantee extends AbstractRenderer /** * @var CasedataResourceModel */ - protected $casedataResourceModel; + public $casedataResourceModel; /** * @var CasedataFactory */ - protected $casedataFactory; + public $casedataFactory; /** * SignifydGuarantee constructor. diff --git a/Block/Adminhtml/Shopcart/Abandoned/Grid.php b/Block/Adminhtml/Shopcart/Abandoned/Grid.php index 20f27f66..1e6d0491 100644 --- a/Block/Adminhtml/Shopcart/Abandoned/Grid.php +++ b/Block/Adminhtml/Shopcart/Abandoned/Grid.php @@ -2,7 +2,10 @@ namespace Signifyd\Connect\Block\Adminhtml\Shopcart\Abandoned; +use Magento\Framework\App\ProductMetadataInterface; use Magento\Framework\Serialize\Serializer\Json as JsonSerializer; +use Magento\Framework\Stdlib\Parameters; +use Magento\Framework\Url\DecoderInterface; use Magento\Store\Model\ScopeInterface; use Signifyd\Connect\Helper\ConfigHelper; @@ -11,33 +14,77 @@ class Grid extends \Magento\Reports\Block\Adminhtml\Shopcart\Abandoned\Grid /** * @var JsonSerializer */ - protected $jsonSerializer; + public $jsonSerializer; /** * @var ConfigHelper */ - protected $configHelper; + public $configHelper; /** * Grid constructor. + * + * @param ProductMetadataInterface $productMetadataInterface * @param \Magento\Backend\Block\Template\Context $context * @param \Magento\Backend\Helper\Data $backendHelper * @param \Magento\Reports\Model\ResourceModel\Quote\CollectionFactory $quotesFactory * @param JsonSerializer $jsonSerializer * @param ConfigHelper $configHelper + * @param DecoderInterface|null $urlDecoder + * @param Parameters|null $parameters * @param array $data */ public function __construct( + ProductMetadataInterface $productMetadataInterface, \Magento\Backend\Block\Template\Context $context, \Magento\Backend\Helper\Data $backendHelper, \Magento\Reports\Model\ResourceModel\Quote\CollectionFactory $quotesFactory, JsonSerializer $jsonSerializer, ConfigHelper $configHelper, + DecoderInterface $urlDecoder = null, + Parameters $parameters = null, array $data = [] ) { + //Backward compatibility with Magento 2.4.6 or less, in this version the parent + // construct don't have $urlDecoder and $parameters parameters, causing di:compile error + $this->initConstructor( + $productMetadataInterface, + $context, + $backendHelper, + $quotesFactory, + $urlDecoder, + $parameters, + $data + ); + $this->jsonSerializer = $jsonSerializer; $this->configHelper = $configHelper; - parent::__construct($context, $backendHelper, $quotesFactory, $data); + } + + /** + * @param $productMetadataInterface + * @param $context + * @param $backendHelper + * @param $quotesFactory + * @param $urlDecoder + * @param $parameters + * @param $data + * @return void + */ + public function initConstructor( + $productMetadataInterface, + $context, + $backendHelper, + $quotesFactory, + $urlDecoder, + $parameters, + $data + ) { + if (version_compare($productMetadataInterface->getVersion(), '2.4.7') >= 0) { + parent::__construct($context, $backendHelper, $quotesFactory, $urlDecoder, $parameters, $data); + } else { + parent::__construct($context, $backendHelper, $quotesFactory, $data); + } } /** diff --git a/Block/Adminhtml/System/Config/Field/CronData.php b/Block/Adminhtml/System/Config/Field/CronData.php index ee5d2375..77ceb02c 100644 --- a/Block/Adminhtml/System/Config/Field/CronData.php +++ b/Block/Adminhtml/System/Config/Field/CronData.php @@ -13,7 +13,7 @@ class CronData extends Field /** * @var SignifydFlags */ - protected $signifydFlags; + public $signifydFlags; /** * @param \Magento\Backend\Block\Template\Context $context diff --git a/Block/Adminhtml/System/Config/Field/Version.php b/Block/Adminhtml/System/Config/Field/Version.php index 800f9418..51deb580 100644 --- a/Block/Adminhtml/System/Config/Field/Version.php +++ b/Block/Adminhtml/System/Config/Field/Version.php @@ -14,7 +14,7 @@ class Version extends Field /** * @var ResourceInterface */ - protected $moduleResource; + public $moduleResource; public function __construct( ResourceInterface $moduleResource, diff --git a/Block/Adminhtml/System/Config/Field/WebhookData.php b/Block/Adminhtml/System/Config/Field/WebhookData.php index 3101d961..d68530a3 100644 --- a/Block/Adminhtml/System/Config/Field/WebhookData.php +++ b/Block/Adminhtml/System/Config/Field/WebhookData.php @@ -13,7 +13,7 @@ class WebhookData extends Field /** * @var SignifydFlags */ - protected $signifydFlags; + public $signifydFlags; /** * @param \Magento\Backend\Block\Template\Context $context diff --git a/Controller/Adminhtml/Casedata/Logs.php b/Controller/Adminhtml/Casedata/Logs.php new file mode 100644 index 00000000..9ada241f --- /dev/null +++ b/Controller/Adminhtml/Casedata/Logs.php @@ -0,0 +1,85 @@ +logsFile = $logsFile; + $this->fileFactory = $fileFactory; + $this->filesystem = $filesystem; + } + + /** + * @return \Magento\Framework\App\ResponseInterface|\Magento\Framework\Controller\Result\Json|\Magento\Framework\Controller\ResultInterface + */ + public function execute() + { + try { + /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */ + $resultRedirect = $this->resultRedirectFactory->create(); + + $orderId = $this->getRequest()->getParam('order_id'); + + if (isset($orderId) === false) { + $this->messageManager->addErrorMessage(__('Failed to retrieve order id.')); + return $resultRedirect->setPath('*/*/'); + } + + $fileName = $this->logsFile->createLogFile($orderId); + + if (strpos($fileName, '.txt') === false) { + $this->messageManager->addErrorMessage(__($fileName)); + return $resultRedirect->setPath('*/*/'); + } + + $filePath = 'media/signifyd_logs/' . $fileName; + $directory = $this->filesystem->getDirectoryRead(DirectoryList::PUB); + + return $this->fileFactory->create($filePath, $directory->readFile($filePath), DirectoryList::PUB); + } catch (\Exception $e) { + $this->messageManager->addErrorMessage($e->getMessage()); + return $resultRedirect->setPath('*/*/'); + } + } +} diff --git a/Controller/Adminhtml/MarkAsFixed/Index.php b/Controller/Adminhtml/MarkAsFixed/Index.php index 3660911b..77e96676 100644 --- a/Controller/Adminhtml/MarkAsFixed/Index.php +++ b/Controller/Adminhtml/MarkAsFixed/Index.php @@ -15,12 +15,12 @@ class Index extends \Magento\Backend\App\Action /** * @var Context */ - protected $context; + public $context; /** * @var WriterInterface */ - protected $configWriter; + public $configWriter; /** * UpgradeSchema constructor. @@ -37,12 +37,15 @@ public function __construct( public function execute() { + /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */ + $resultRedirect = $this->resultRedirectFactory->create(); + $this->configWriter->delete("signifyd/general/upgrade4.3_inconsistency"); $this->messageManager->addSuccessMessage(__('Successfully marked as fixed')); $this->messageManager->addWarningMessage(__( "If the inconsistency message is still visible, it's necessary to clear the config cache" )); - return $this->_redirect($this->_redirect->getRefererUrl()); + return $resultRedirect->setUrl($this->_redirect->getRefererUrl()); } } diff --git a/Controller/Adminhtml/Webhooks/Register.php b/Controller/Adminhtml/Webhooks/Register.php index 97916a58..f546ee7a 100644 --- a/Controller/Adminhtml/Webhooks/Register.php +++ b/Controller/Adminhtml/Webhooks/Register.php @@ -15,32 +15,32 @@ class Register extends Action /** * @var WebhookLink */ - protected $webhookLink; + public $webhookLink; /** * @var WebhooksApiFactory */ - protected $webhooksApiFactory; + public $webhooksApiFactory; /** * @var \Magento\Store\Model\StoreManagerInterface $storeManager */ - protected $storeManager; + public $storeManager; /** * @var WebhookFactory */ - protected $webhookFactory; + public $webhookFactory; /** * @var WebhookV2Factory */ - protected $webhookV2Factory; + public $webhookV2Factory; /** * @var Client */ - protected $client; + public $client; /** * Register constructor. @@ -72,6 +72,9 @@ public function __construct( public function execute() { + /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */ + $resultRedirect = $this->resultRedirectFactory->create(); + try { $url = $this->webhookLink->getUrl(); $isWebhookRegistered = false; @@ -144,12 +147,10 @@ public function execute() $this->messageManager->addErrorMessage( __('There was a problem registering the webooks: ' . $e->getMessage()) ); - - return $this->_redirect($this->_redirect->getRefererUrl()); + return $resultRedirect->setUrl($this->_redirect->getRefererUrl()); } $this->messageManager->addSuccessMessage(__('The webhook was registred successfully.')); - - return $this->_redirect($this->_redirect->getRefererUrl()); + return $resultRedirect->setUrl($this->_redirect->getRefererUrl()); } } diff --git a/Controller/Router.php b/Controller/Router.php index e132e3c5..cbad8071 100644 --- a/Controller/Router.php +++ b/Controller/Router.php @@ -7,14 +7,14 @@ class Router implements \Magento\Framework\App\RouterInterface /** * @var \Magento\Framework\App\ActionFactory */ - protected $actionFactory; + public $actionFactory; /** * Response * * @var \Magento\Framework\App\ResponseInterface */ - protected $_response; + public $_response; /** * @param \Magento\Framework\App\ActionFactory $actionFactory @@ -32,7 +32,7 @@ public function __construct( * Validate and Match * * @param \Magento\Framework\App\RequestInterface $request - * @return bool + * @return \Magento\Framework\App\ActionInterface|void */ public function match(\Magento\Framework\App\RequestInterface $request) { @@ -50,9 +50,6 @@ public function match(\Magento\Framework\App\RequestInterface $request) return; } - return $this->actionFactory->create( - \Magento\Framework\App\Action\Forward::class, - ['request' => $request] - ); + return $this->actionFactory->create(\Magento\Framework\App\Action\Forward::class); } } diff --git a/Controller/Webhooks/Index.php b/Controller/Webhooks/Index.php index 89ceb55b..4106b413 100644 --- a/Controller/Webhooks/Index.php +++ b/Controller/Webhooks/Index.php @@ -8,7 +8,6 @@ use Magento\Framework\App\Action\Context; use Magento\Framework\App\Response\Http; use Magento\Framework\Exception\LocalizedException; -use Magento\Framework\Stdlib\DateTime\DateTime; use Magento\Sales\Model\OrderFactory; use Magento\Sales\Model\ResourceModel\Order as OrderResourceModel; use Magento\Store\Model\StoreManagerInterface; @@ -38,87 +37,86 @@ class Index extends Action /** * @var Logger */ - protected $logger; + public $logger; /** * @var ConfigHelper */ - protected $configHelper; + public $configHelper; /** * @var File */ - protected $file; + public $file; /** * @var CasedataFactory */ - protected $casedataFactory; + public $casedataFactory; /** * @var CasedataResourceModel */ - protected $casedataResourceModel; + public $casedataResourceModel; /** * @var OrderResourceModel */ - protected $orderResourceModel; + public $orderResourceModel; /** * @var JsonSerializer */ - protected $jsonSerializer; + public $jsonSerializer; /** * @var ResourceConnection */ - protected $resourceConnection; + public $resourceConnection; /** * @var StoreManagerInterface */ - protected $storeManagerInterface; + public $storeManagerInterface; /** * @var OrderFactory */ - protected $orderFactory; + public $orderFactory; /** * @var SignifydOrderResourceModel */ - protected $signifydOrderResourceModel; + public $signifydOrderResourceModel; /** * @var UpdateCaseV2Factory */ - protected $updateCaseV2Factory; + public $updateCaseV2Factory; /** * @var UpdateCaseFactory */ - protected $updateCaseFactory; + public $updateCaseFactory; /** * @var UpdateOrderFactory */ - protected $updateOrderFactory; + public $updateOrderFactory; /** * @var Client */ - protected $client; + public $client; /** * @var SignifydFlags */ - protected $signifydFlags; + public $signifydFlags; /** * Index constructor. * @param Context $context - * @param DateTime $dateTime * @param Logger $logger * @param ConfigHelper $configHelper * @param FormKey $formKey @@ -139,7 +137,6 @@ class Index extends Action */ public function __construct( Context $context, - DateTime $dateTime, Logger $logger, ConfigHelper $configHelper, FormKey $formKey, @@ -193,10 +190,6 @@ public function __construct( */ protected function getRawPost() { - if (isset($HTTP_RAW_POST_DATA) && $HTTP_RAW_POST_DATA) { - return $HTTP_RAW_POST_DATA; - } - $post = $this->file->fileGetContents("php://input"); if ($post) { @@ -271,7 +264,7 @@ public function processRequest($request, $hash, $topic) break; } - /** @var $case \Signifyd\Connect\Model\Casedata */ + /** @var \Signifyd\Connect\Model\Casedata $case */ $case = $this->casedataFactory->create(); try { @@ -312,12 +305,15 @@ public function processRequest($request, $hash, $topic) $order = $this->orderFactory->create(); $this->signifydOrderResourceModel->load($order, $case->getData('order_id')); - if (isset($order) === false) { + if ($order->isEmpty()) { $httpCode = Http::STATUS_CODE_400; throw new LocalizedException(__("Order not found")); } - $this->logger->info("WEBHOOK: Processing case {$case->getId()}"); + $this->logger->info( + "WEBHOOK: Processing case {$case->getId()} with request {$request} ", + ['entity' => $case] + ); $this->storeManagerInterface->setCurrentStore($order->getStore()->getStoreId()); $currentCaseHash = sha1(implode(',', $case->getData())); @@ -336,6 +332,10 @@ public function processRequest($request, $hash, $topic) if ($currentCaseHash == $newCaseHash) { $httpCode = Http::STATUS_CODE_200; + $this->logger->debug( + "Case {$caseId} already update with this data, no action will be taken", + ['entity' => $case] + ); throw new LocalizedException( __("Case {$caseId} already update with this data, no action will be taken") ); @@ -351,6 +351,15 @@ public function processRequest($request, $hash, $topic) $this->casedataResourceModel->save($case); } + $httpCode = empty($httpCode) ? 403 : $httpCode; + $this->getResponse()->appendBody($e->getMessage()); + $this->logger->error("WEBHOOK: {$e->getMessage()}"); + } catch (\Error $e) { + // Triggering case save to unlock case + if ($case instanceof \Signifyd\Connect\Model\ResourceModel\Casedata) { + $this->casedataResourceModel->save($case); + } + $httpCode = empty($httpCode) ? 403 : $httpCode; $this->getResponse()->appendBody($e->getMessage()); $this->logger->error("WEBHOOK: {$e->getMessage()}"); diff --git a/Cron/DeleteLogs.php b/Cron/DeleteLogs.php new file mode 100644 index 00000000..13b7414b --- /dev/null +++ b/Cron/DeleteLogs.php @@ -0,0 +1,111 @@ +scopeConfigInterface = $scopeConfigInterface; + $this->logsCollectionFactory = $logsCollectionFactory; + $this->logsResourceModel = $logsResourceModel; + $this->dateTime = $dateTime; + $this->logger = $logger; + $this->directoryList = $directoryList; + $this->driverFile = $driverFile; + $this->logsFile = $logsFile; + } + + public function execute() + { + $logsRetentionPeriod = $this->scopeConfigInterface->getValue("signifyd/advanced/logs_retention_period"); + $fromDate = $this->dateTime->gmtDate('Y-m-d H:i:s', "-{$logsRetentionPeriod} days"); + + $logsCollection = $this->logsCollectionFactory->create(); + $logsCollection->addFieldToFilter('created_at', ['lt' => $fromDate]); + + foreach ($logsCollection as $log) { + try { + $this->logsResourceModel->delete($log); + } catch (\Exception $e) { + $this->logger->info("CRON: Failed to delete log " . $log->getLogsId()); + } + } + + $this->logsFile->prepLogsDir(); + $path = $this->directoryList->getPath('media') . '/signifyd_logs'; + + try { + $this->driverFile->deleteDirectory($path); + } catch (\Exception $e) { + $this->logger->info("CRON: Failed to delete log files: " . $e->getMessage()); + } + } +} diff --git a/Cron/RetryCaseJob.php b/Cron/RetryCaseJob.php index d6d8806e..50704829 100644 --- a/Cron/RetryCaseJob.php +++ b/Cron/RetryCaseJob.php @@ -21,37 +21,37 @@ class RetryCaseJob /** * @var Logger */ - protected $logger; + public $logger; /** * @var FilterCasesByStatusFactory */ - protected $filterCasesByStatusFactory; + public $filterCasesByStatusFactory; /** * @var InReviewFactory */ - protected $inReviewFactory; + public $inReviewFactory; /** * @var WaitingSubmissionFactory */ - protected $waitingSubmissionFactory; + public $waitingSubmissionFactory; /** * @var AsyncWaitingFactory */ - protected $asyncWaitingFactory; + public $asyncWaitingFactory; /** * @var SignifydFlags */ - protected $signifydFlags; + public $signifydFlags; /** * @var PreAuthTransactionFactory */ - protected $preAuthTransactionFactory; + public $preAuthTransactionFactory; /** * RetryCaseJob constructor. diff --git a/Cron/RetryFulfillmentJob.php b/Cron/RetryFulfillmentJob.php index f7c4a13c..f8450c50 100644 --- a/Cron/RetryFulfillmentJob.php +++ b/Cron/RetryFulfillmentJob.php @@ -12,22 +12,22 @@ class RetryFulfillmentJob /** * @var Logger */ - protected $logger; + public $logger; /** * @var FulfillmentsToRetryFactory */ - protected $fulfillmentsToRetryFactory; + public $fulfillmentsToRetryFactory; /** * @var FulfillmentFactory */ - protected $fulfillmentFactory; + public $fulfillmentFactory; /** * @var SignifydFlags */ - protected $signifydFlags; + public $signifydFlags; /** * RetryFulfillmentJob constructor. diff --git a/Cron/RetryReroute.php b/Cron/RetryReroute.php new file mode 100644 index 00000000..abcca0fd --- /dev/null +++ b/Cron/RetryReroute.php @@ -0,0 +1,56 @@ +logger = $logger; + $this->reroutesToRetry = $reroutesToRetry; + $this->processCronReroute = $processCronReroute; + } + + /** + * @return void + */ + public function execute() + { + $this->logger->debug("CRON: Retry Reroute method called"); + $reroutesToRetry = ($this->reroutesToRetry)(); + + foreach ($reroutesToRetry as $rerouteToRetry) { + ($this->processCronReroute)($rerouteToRetry); + } + + $this->logger->debug("CRON: Retry Reroute method ended"); + } +} diff --git a/Cron/ValidateOrderId.php b/Cron/ValidateOrderId.php index f329b4f8..5279aa95 100644 --- a/Cron/ValidateOrderId.php +++ b/Cron/ValidateOrderId.php @@ -16,17 +16,17 @@ class ValidateOrderId /** * @var CasedataCollectionFactory */ - protected $casedataCollection; + public $casedataCollection; /** * @var WriterInterface */ - protected $writerInterface; + public $writerInterface; /** * @var ScopeConfigInterface */ - protected $scopeConfigInterface; + public $scopeConfigInterface; /** * @param CasedataCollectionFactory $casedataCollection diff --git a/CustomerData/Fingerprint.php b/CustomerData/Fingerprint.php index da943637..31878c76 100644 --- a/CustomerData/Fingerprint.php +++ b/CustomerData/Fingerprint.php @@ -13,17 +13,17 @@ class Fingerprint extends DataObject implements SectionSourceInterface /** * @var DeviceHelper */ - protected $deviceHelper; + public $deviceHelper; /** - * @var + * @var int */ - protected $quoteId; + public $quoteId; /** * @var StoreManagerInterface */ - protected $storeManagerInterface; + public $storeManagerInterface; /** * FingerprintSection constructor. diff --git a/Helper/ConfigHelper.php b/Helper/ConfigHelper.php index 427ae3fc..87749373 100644 --- a/Helper/ConfigHelper.php +++ b/Helper/ConfigHelper.php @@ -19,40 +19,40 @@ class ConfigHelper /** * @var ScopeConfigInterface */ - protected $scopeConfigInterface; + public $scopeConfigInterface; /** * Associative array of order_id => store_code * @var array */ - protected $storeCodes = []; + public $storeCodes = []; /** * Array of SignifydAPI, one for each store code * * @var array */ - protected $signifydAPI = []; + public $signifydAPI = []; /** * @var StoreManagerInterface */ - protected $storeManager; + public $storeManager; /** * @var OrderFactory */ - protected $orderFactory; + public $orderFactory; /** * @var SignifydOrderResourceModel */ - protected $signifydOrderResourceModel; + public $signifydOrderResourceModel; /** * @var JsonSerializer */ - protected $jsonSerializer; + public $jsonSerializer; /** * ConfigHelper constructor. @@ -220,11 +220,40 @@ public function getRestrictedPaymentMethodsConfig() return $restrictedPaymentMethods; } + /** + * Get restricted customer groups from store configs + * + * @return array|mixed + */ + public function getRestrictedCustomerGroupsConfig() + { + $restrictedCustomerGroups = $this->getConfigData('signifyd/general/restrict_customer_groups'); + + if (isset($restrictedCustomerGroups) === false) { + return []; + } + + $restrictedCustomerGroups = explode(',', $restrictedCustomerGroups); + $restrictedCustomerGroups = array_map('trim', $restrictedCustomerGroups); + + return $restrictedCustomerGroups; + } + + public function isCustomerGroupRestricted($customerGroupId) + { + $restrictedCustomerGroups = $this->getRestrictedCustomerGroupsConfig(); + + if (in_array($customerGroupId, $restrictedCustomerGroups)) { + return true; + } + + return false; + } + /** * Check if there is any restrictions by payment method or state * - * @param $method - * @param null $state + * @param $paymentMethodCode * @return bool */ public function isPaymentRestricted($paymentMethodCode) diff --git a/Helper/DeviceHelper.php b/Helper/DeviceHelper.php index c8b206b8..71391237 100644 --- a/Helper/DeviceHelper.php +++ b/Helper/DeviceHelper.php @@ -10,12 +10,12 @@ class DeviceHelper /** * @var ScopeConfigInterface */ - protected $scopeConfigInterface; + public $scopeConfigInterface; /** * @var StoreManagerInterface */ - protected $storeManager; + public $storeManager; /** * DeviceHelper constructor. diff --git a/Helper/FulfillmentHelper.php b/Helper/FulfillmentHelper.php index 7b59f26e..b13ad1ea 100644 --- a/Helper/FulfillmentHelper.php +++ b/Helper/FulfillmentHelper.php @@ -16,52 +16,52 @@ class FulfillmentHelper /** * @var CasedataFactory */ - protected $casedataFactory; + public $casedataFactory; /** * @var FulfillmentFactory */ - protected $fulfillmentFactory; + public $fulfillmentFactory; /** * @var CasedataResourceModel */ - protected $casedataResourceModel; + public $casedataResourceModel; /** * @var FulfillmentResourceModel */ - protected $fulfillmentResourceModel; + public $fulfillmentResourceModel; /** * @var Logger */ - protected $logger; + public $logger; /** * @var ConfigHelper */ - protected $configHelper; + public $configHelper; /** * @var SerializerInterface */ - protected $serializer; + public $serializer; /** * @var OrderHelper */ - protected $orderHelper; + public $orderHelper; /** * @var CarrierFactory */ - protected $carrierFactory; + public $carrierFactory; /** * @var OriginFactory */ - protected $originFactory; + public $originFactory; /** * FulfillmentHelper constructor. @@ -102,12 +102,13 @@ public function __construct( public function postFulfillmentToSignifyd(\Magento\Sales\Model\Order\Shipment $shipment) { + $order = $shipment->getOrder(); + if ($shipment->getId() <= 0) { - $this->logger->info('Fulfillment will not proceed because shipment has no ID'); + $this->logger->info('Fulfillment will not proceed because shipment has no ID', ['entity' => $order]); return false; } - $order = $shipment->getOrder(); $orderIncrementId = $order->getIncrementId(); $orderId = $order->getId(); @@ -118,7 +119,8 @@ public function postFulfillmentToSignifyd(\Magento\Sales\Model\Order\Shipment $s if (empty($caseCode)) { $this->logger->info( - "Fulfillment will not proceed because no case has been found: {$orderIncrementId} ({$orderId})" + "Fulfillment will not proceed because no case has been found: {$orderIncrementId} ({$orderId})", + ['entity' => $order] ); return false; } @@ -127,27 +129,34 @@ public function postFulfillmentToSignifyd(\Magento\Sales\Model\Order\Shipment $s $shipmentIncrementId = $shipment->getIncrementId(); $this->logger->debug( - "Fulfillment for case order {$orderIncrementId} ({$orderId}), shipment {$shipmentIncrementId}" + "Fulfillment for case order {$orderIncrementId} ({$orderId}), shipment {$shipmentIncrementId}", + ['entity' => $order] ); $fulfillment = $this->getFulfillmentFromDatabase($shipmentIncrementId); if ($fulfillment->getId()) { - $this->logger->debug("Fulfillment for shipment {$shipmentIncrementId} already sent"); + $this->logger->debug( + "Fulfillment for shipment {$shipmentIncrementId} already sent", + ['entity' => $order] + ); return false; } $fulfillmentData = $this->generateFulfillmentData($shipment); if ($fulfillmentData == false) { - $this->logger->debug("Fulfillment for shipment {$shipmentIncrementId} is not ready to be sent"); + $this->logger->debug( + "Fulfillment for shipment {$shipmentIncrementId} is not ready to be sent", + ['entity' => $order] + ); return false; } $fulfillment = $this->prepareFulfillmentToDatabase($fulfillmentData); $this->fulfillmentResourceModel->save($fulfillment); } catch (\Exception $e) { - $this->logger->debug("Fulfillment error: {$e->getMessage()}"); + $this->logger->debug("Fulfillment error: {$e->getMessage()}", ['entity' => $order]); return false; } @@ -291,7 +300,6 @@ public function getDeliveryEmail(\Magento\Sales\Model\Order\Shipment $shipment) { $isVirtual = true; - /** @var Mage_Sales_Model_Order_Item $item */ foreach ($shipment->getOrder()->getAllItems() as $item) { if ($item->getIsVirtual() == false) { $isVirtual = false; @@ -378,7 +386,6 @@ public function getItemUrl(\Magento\Sales\Model\Order\Shipment\Item $item) */ public function getItemImage(\Magento\Sales\Model\Order\Shipment\Item $item) { - /** @var \Magento\Catalog\Model\Product $product */ $product = $item->getOrderItem()->getProduct(); if (isset($product) === false) { diff --git a/Helper/OrderHelper.php b/Helper/OrderHelper.php index 57c749ba..e8f751d5 100644 --- a/Helper/OrderHelper.php +++ b/Helper/OrderHelper.php @@ -13,12 +13,12 @@ class OrderHelper /** * @var HistoryFactory */ - protected $historyFactory; + public $historyFactory; /** * @var HistoryResourceModel */ - protected $historyResourceModel; + public $historyResourceModel; /** * OrderHelper constructor. diff --git a/Model/Api/AccountHolderName.php b/Model/Api/AccountHolderName.php index f1816f79..3537d7b4 100644 --- a/Model/Api/AccountHolderName.php +++ b/Model/Api/AccountHolderName.php @@ -13,12 +13,12 @@ class AccountHolderName /** * @var Logger */ - protected $logger; + public $logger; /** * @var PaymentVerificationFactory */ - protected $paymentVerificationFactory; + public $paymentVerificationFactory; /** * @param Logger $logger @@ -59,7 +59,7 @@ protected function getCardholderFromQuote(Quote $quote) try { $firstname = $quote->getBillingAddress()->getFirstname(); $lastname = $quote->getBillingAddress()->getLastname(); - $cardholder = trim($firstname) . ' ' . trim($lastname); + $cardholder = trim($firstname ?? '') . ' ' . trim($lastname ?? ''); $cardholder = strtoupper($cardholder); $cardholder = preg_replace('/ +/', ' ', $cardholder); diff --git a/Model/Api/Carrier.php b/Model/Api/Carrier.php index 703a3bfc..0a881a36 100644 --- a/Model/Api/Carrier.php +++ b/Model/Api/Carrier.php @@ -10,12 +10,12 @@ class Carrier /** * @var ScopeConfigInterface */ - protected $scopeConfigInterface; + public $scopeConfigInterface; /** * @var JsonSerializer */ - protected $jsonSerializer; + public $jsonSerializer; /** * @param ScopeConfigInterface $scopeConfigInterface diff --git a/Model/Api/CaseData/PreAuth/ProcessTransaction.php b/Model/Api/CaseData/PreAuth/ProcessTransaction.php index 9f590754..6f8a1ab6 100644 --- a/Model/Api/CaseData/PreAuth/ProcessTransaction.php +++ b/Model/Api/CaseData/PreAuth/ProcessTransaction.php @@ -16,37 +16,37 @@ class ProcessTransaction /** * @var Logger */ - protected $logger; + public $logger; /** * @var CasedataFactory */ - protected $casedataFactory; + public $casedataFactory; /** * @var CasedataResourceModel */ - protected $casedataResourceModel; + public $casedataResourceModel; /** * @var ConfigHelper */ - protected $configHelper; + public $configHelper; /** * @var TransactionsFactory */ - protected $transactionsFactory; + public $transactionsFactory; /** * @var Client */ - protected $client; + public $client; /** * @var JsonSerializer */ - protected $jsonSerializer; + public $jsonSerializer; /** * Transaction constructor. @@ -96,7 +96,16 @@ public function __invoke($order) return; } - /** @var $case \Signifyd\Connect\Model\Casedata */ + $customerGroupId = $order->getCustomerGroupId(); + + if ($this->configHelper->isCustomerGroupRestricted($customerGroupId)) { + $message = 'Case creation for order ' . $order->getIncrementId() . ' with customer group id ' . + $customerGroupId . ' is restricted'; + $this->logger->debug($message, ['entity' => $order]); + return; + } + + /** @var \Signifyd\Connect\Model\Casedata $case */ $case = $this->casedataFactory->create(); $this->casedataResourceModel->load($case, $order->getId(), 'order_id'); @@ -114,17 +123,18 @@ public function __invoke($order) if ($newHashToValidateReroute == $currentHashToValidateReroute) { $this->logger->info( 'No data changes, will not send transaction ' . - $order->getIncrementId() + $order->getIncrementId(), + ['entity' => $order] ); return; } $this->logger->info("Sending pre_auth transaction to Signifyd for order - {$case->getOrderIncrement()}"); + {$case->getOrderIncrement()}", ['entity' => $order]); $this->client->postTransactionToSignifyd($saleTransaction, $order); $case->setEntries('transaction_hash', $newHashToValidateReroute); $this->casedataResourceModel->save($case); } } -} \ No newline at end of file +} diff --git a/Model/Api/CaseData/Transactions/PaymentMethod/Mapper.php b/Model/Api/CaseData/Transactions/PaymentMethod/Mapper.php deleted file mode 100644 index 1b5889f2..00000000 --- a/Model/Api/CaseData/Transactions/PaymentMethod/Mapper.php +++ /dev/null @@ -1,31 +0,0 @@ -logger->info("Post auth mapping for payment method " . $order->getPayment()->getMethod()); - - return $this->makePaymentMethod($order->getPayment()->getMethod()); - } - - /** - * @param Quote $quote - * @return int|string - */ - public function getPaymentMethodFromQuote(Quote $quote) - { - $this->logger->info("Pre auth mapping for payment method " . $quote->getPayment()->getMethod()); - - return $this->makePaymentMethod($quote->getPayment()->getMethod()); - } -} diff --git a/Model/Api/CheckoutOrder.php b/Model/Api/CheckoutOrder.php index ec70eebb..d76a4320 100644 --- a/Model/Api/CheckoutOrder.php +++ b/Model/Api/CheckoutOrder.php @@ -2,7 +2,7 @@ namespace Signifyd\Connect\Model\Api; -use Magento\Framework\Registry; +use Signifyd\Connect\Model\Registry; use Magento\Framework\Serialize\Serializer\Json as JsonSerializer; use Magento\Quote\Model\Quote; use Magento\Quote\Model\ResourceModel\Quote as QuoteResourceModel; @@ -14,102 +14,102 @@ class CheckoutOrder /** * @var Registry */ - protected $registry; + public $registry; /** * @var PurchaseFactory */ - protected $purchaseFactory; + public $purchaseFactory; /** * @var UserAccountFactory */ - protected $userAccountFactory; + public $userAccountFactory; /** * @var CoverageRequestsFactory */ - protected $coverageRequestsFactory; + public $coverageRequestsFactory; /** * @var QuoteResourceModel */ - protected $quoteResourceModel; + public $quoteResourceModel; /** * @var JsonSerializer */ - protected $jsonSerializer; + public $jsonSerializer; /** * @var DeviceFactory */ - protected $deviceFactory; + public $deviceFactory; /** * @var MerchantPlatformFactory */ - protected $merchantPlatformFactory; + public $merchantPlatformFactory; /** * @var SignifydClientFactory */ - protected $signifydClientFactory; + public $signifydClientFactory; /** * @var TagsFactory */ - protected $tagsFactory; + public $tagsFactory; /** * @var AddressFactory */ - protected $addressFactory; + public $addressFactory; /** * @var SellersFactory */ - protected $sellersFactory; + public $sellersFactory; /** * @var CustomerOrderRecommendationFactory */ - protected $customerOrderRecommendationFactory; + public $customerOrderRecommendationFactory; /** * @var SourceAccountDetailsFactory */ - protected $sourceAccountDetailsFactory; + public $sourceAccountDetailsFactory; /** * @var AcquirerDetailsFactory */ - protected $acquirerDetailsFactory; + public $acquirerDetailsFactory; /** * @var MembershipsFactory */ - protected $membershipsFactory; + public $membershipsFactory; /** * @var MerchantCategoryCodeFactory */ - protected $merchantCategoryCodeFactory; + public $merchantCategoryCodeFactory; /** * @var PaymentMethodFactory */ - protected $paymentMethodFactory; + public $paymentMethodFactory; /** * @var ConfigHelper */ - protected $configHelper; + public $configHelper; /** * @var Logger */ - protected $logger; + public $logger; /** * @param Registry $registry @@ -275,11 +275,11 @@ public function __invoke(Quote $quote, $checkoutPaymentDetails = null, $paymentM * It must be unregistered after use * @see \Signifyd\Connect\Plugin\Magento\Paypal\Model\Payflowlink */ - $this->registry->unregister('signifyd_payment_data'); + $this->registry->setData('signifyd_payment_data'); } catch (\Exception $e) { - $this->logger->info("Failed to create checkout order " . $e->getMessage()); + $this->logger->info("Failed to create checkout order " . $e->getMessage(), ['entity' => $quote]); } catch (\Error $e) { - $this->logger->info("Failed to create checkout order " . $e->getMessage()); + $this->logger->info("Failed to create checkout order " . $e->getMessage(), ['entity' => $quote]); } return $signifydOrder; diff --git a/Model/Api/CheckoutPaymentDetails.php b/Model/Api/CheckoutPaymentDetails.php index cae7542f..cff37b02 100644 --- a/Model/Api/CheckoutPaymentDetails.php +++ b/Model/Api/CheckoutPaymentDetails.php @@ -13,62 +13,62 @@ class CheckoutPaymentDetails /** * @var AddressFactory */ - protected $addressFactory; + public $addressFactory; /** * @var AccountHolderNameFactory */ - protected $accountHolderNameFactory; + public $accountHolderNameFactory; /** * @var Logger */ - protected $logger; + public $logger; /** * @var PaymentVerificationFactory */ - protected $paymentVerificationFactory; + public $paymentVerificationFactory; /** * @var AccountHolderTaxIdFactory */ - protected $accountHolderTaxIdFactory; + public $accountHolderTaxIdFactory; /** * @var AccountHolderTaxIdCountryFactory */ - protected $accountHolderTaxIdCountryFactory; + public $accountHolderTaxIdCountryFactory; /** * @var AbaRoutingNumberFactory */ - protected $abaRoutingNumberFactory; + public $abaRoutingNumberFactory; /** * @var CardTokenProviderFactory */ - protected $cardTokenProviderFactory; + public $cardTokenProviderFactory; /** * @var CardTokenFactory */ - protected $cardTokenFactory; + public $cardTokenFactory; /** * @var CardInstallmentsFactory */ - protected $cardInstallmentsFactory; + public $cardInstallmentsFactory; /** * @var AccountLast4Factory */ - protected $accountLast4Factory; + public $accountLast4Factory; /** * @var CardBrandFactory */ - protected $cardBrandFactory; + public $cardBrandFactory; /** * @param AddressFactory $addressFactory diff --git a/Model/Api/Core/Client.php b/Model/Api/Core/Client.php index 0c442866..8e42904a 100644 --- a/Model/Api/Core/Client.php +++ b/Model/Api/Core/Client.php @@ -22,74 +22,74 @@ class Client /** * @var ConfigHelper */ - protected $configHelper; + public $configHelper; /** * @var Logger */ - protected $logger; + public $logger; /** * @var OrderHelper */ - protected $orderHelper; + public $orderHelper; /** * @var JsonSerializer */ - protected $jsonSerializer; + public $jsonSerializer; /** * @var CasedataFactory */ - protected $casedataFactory; + public $casedataFactory; /** * @var CasedataResourceModel */ - protected $casedataResourceModel; + public $casedataResourceModel; /** * @var OrderResourceModel */ - protected $orderResourceModel; + public $orderResourceModel; /** * @var RecordReturnFactory */ - protected $recordReturnFactory; + public $recordReturnFactory; /** * @var DirectoryList */ - protected $directory; + public $directory; /** * @var SaleApiFactory */ - protected $saleApiFactory; + public $saleApiFactory; /** * @var CheckoutApiFactory */ - protected $checkoutApiFactory; + public $checkoutApiFactory; /** * @var WebhooksApiFactory */ - protected $webhooksApiFactory; + public $webhooksApiFactory; /** * @var WebhooksV2ApiFactory */ - protected $webhooksV2ApiFactory; + public $webhooksV2ApiFactory; /** * Array of SignifydAPI, one for each store code * * @var array */ - protected $signifydAPI = []; + public $signifydAPI = []; /** * @param ConfigHelper $configHelper @@ -143,10 +143,19 @@ public function __construct( */ public function postCaseToSignifyd($caseData, $order) { + $this->logger->info( + "Call sale api with request: " . $this->jsonSerializer->serialize($caseData), + ['entity' => $order] + ); + /** @var \Signifyd\Core\Response\SaleResponse $saleResponse */ $saleResponse = $this->getSignifydSaleApi($order)->createOrder('orders/events/sales', $caseData); if (empty($saleResponse->getSignifydId()) === false) { + $this->logger->info( + "Sale api response: " . $this->jsonSerializer->serialize($saleResponse), + ['entity' => $order] + ); $this->logger->debug("Case sent. Id is {$saleResponse->getSignifydId()}", ['entity' => $order]); $this->orderHelper->addCommentToStatusHistory( $order, @@ -154,7 +163,7 @@ public function postCaseToSignifyd($caseData, $order) ); return $saleResponse; } else { - $this->logger->error($this->jsonSerializer->serialize($saleResponse)); + $this->logger->error($this->jsonSerializer->serialize($saleResponse), ['entity' => $order]); $this->logger->error("Case failed to send.", ['entity' => $order]); $this->orderHelper->addCommentToStatusHistory($order, "Signifyd: failed to create case"); @@ -171,13 +180,22 @@ public function postCaseToSignifyd($caseData, $order) */ public function createReroute($updateData, $order) { + $this->logger->info( + "Call reroute api with request: " . $this->jsonSerializer->serialize($updateData), + ['entity' => $order] + ); + $caseResponse = $this->getSignifydSaleApi($order)->reroute($updateData); if (empty($caseResponse->getSignifydId()) === false) { + $this->logger->info( + "Reroute response: " . $this->jsonSerializer->serialize($caseResponse), + ['entity' => $order] + ); $this->logger->debug("Reroute created. Id is {$caseResponse->getSignifydId()}", ['entity' => $order]); return $caseResponse; } else { - $this->logger->error($this->jsonSerializer->serialize($caseResponse)); + $this->logger->error($this->jsonSerializer->serialize($caseResponse), ['entity' => $order]); $this->logger->error("Reroute failed to create.", ['entity' => $order]); return false; } @@ -191,7 +209,7 @@ public function cancelCaseOnSignifyd(Order $order) { $this->logger->debug("Trying to cancel case for order " . $order->getIncrementId(), ['entity' => $order]); - /** @var $case \Signifyd\Connect\Model\Casedata */ + /** @var \Signifyd\Connect\Model\Casedata $case */ $case = $this->casedataFactory->create(); $this->casedataResourceModel->load($case, $order->getId(), 'order_id'); @@ -221,7 +239,20 @@ public function cancelCaseOnSignifyd(Order $order) $this->logger->debug('Return case ' . $case->getData('order_id'), ['entity' => $order]); $recordReturn = $this->recordReturnFactory->create(); - $recordReturnResponse = $this->getSignifydSaleApi($order)->recordReturn($recordReturn($order)); + $recordReturnData = $recordReturn($order); + + $this->logger->info( + "Call record a return with: " . $this->jsonSerializer->serialize($recordReturnData), + ['entity' => $order] + ); + + $recordReturnResponse = $this->getSignifydSaleApi($order)->recordReturn($recordReturnData); + + $this->logger->info( + "Record a return response: " . $this->jsonSerializer->serialize($recordReturnResponse), + ['entity' => $order] + ); + $returnId = $recordReturnResponse->getReturnId(); if (isset($returnId)) { @@ -243,7 +274,7 @@ public function cancelCaseOnSignifyd(Order $order) $this->casedataResourceModel->save($case); } - $this->logger->error('Failed to save case data to database: ' . $e->getMessage()); + $this->logger->error('Failed to save case data to database: ' . $e->getMessage(), ['entity' => $order]); return false; } } else { @@ -259,18 +290,27 @@ public function cancelCaseOnSignifyd(Order $order) * @return bool|\Signifyd\Core\Response\CheckoutsResponse * @throws \Signifyd\Core\Exceptions\ApiException * @throws \Signifyd\Core\Exceptions\InvalidClassException - * @throws \Signifyd\Core\Exceptions\LoggerException] + * @throws \Signifyd\Core\Exceptions\LoggerException */ public function postCaseFromQuoteToSignifyd($caseData, $quote) { + $this->logger->info( + "Call checkout api with request: " . $this->jsonSerializer->serialize($caseData), + ['entity' => $quote] + ); + $caseResponse = $this->getSignifydCheckoutApi($quote) ->createOrder('orders/events/checkouts', $caseData); if (empty($caseResponse->getSignifydId()) === false) { + $this->logger->info( + "Checkout api response: " . $this->jsonSerializer->serialize($caseResponse), + ['entity' => $quote] + ); $this->logger->debug("Case sent. Id is {$caseResponse->getSignifydId()}", ['entity' => $quote]); return $caseResponse; } else { - $this->logger->error($this->jsonSerializer->serialize($caseResponse)); + $this->logger->error($this->jsonSerializer->serialize($caseResponse), ['entity' => $quote]); $this->logger->error("Case failed to send.", ['entity' => $quote]); return false; @@ -286,6 +326,11 @@ public function postCaseFromQuoteToSignifyd($caseData, $quote) */ public function postTransactionToSignifyd($transactionData, $entity) { + $this->logger->info( + "Call transaction api with request: " . $this->jsonSerializer->serialize($transactionData), + ['entity' => $entity] + ); + $caseResponse = $this->getSignifydCheckoutApi($entity)->createTransaction($transactionData); $tokenSent = $transactionData['checkoutId']; $tokenReceived = $caseResponse->getCheckoutId(); @@ -295,12 +340,17 @@ public function postTransactionToSignifyd($transactionData, $entity) "Transaction sent to quote {$entity->getId()}. Token is {$caseResponse->getCheckoutId()}" : "Transaction sent to order {$entity->getIncrementId()}. Token is {$caseResponse->getCheckoutId()}"; - $this->logger->debug($message); + $this->logger->info( + "Transaction api response: " . $this->jsonSerializer->serialize($transactionData), + ['entity' => $entity] + ); + $this->logger->debug($message, ['entity' => $entity]); return $caseResponse; } else { - $this->logger->error($this->jsonSerializer->serialize($caseResponse)); + $this->logger->error($this->jsonSerializer->serialize($caseResponse), ['entity' => $entity]); $this->logger->error( - "Transaction failed to send. Sent token ({$tokenSent}) is different from received ({$tokenReceived})" + "Transaction failed to send. Sent token ({$tokenSent}) is different from received ({$tokenReceived})", + ['entity' => $entity] ); return false; } diff --git a/Model/Api/CoverageRequests.php b/Model/Api/CoverageRequests.php index e62c23d4..05a08936 100644 --- a/Model/Api/CoverageRequests.php +++ b/Model/Api/CoverageRequests.php @@ -11,12 +11,12 @@ class CoverageRequests /** * @var JsonSerializer */ - protected $jsonSerializer; + public $jsonSerializer; /** * @var ConfigHelper */ - protected $configHelper; + public $configHelper; /** * @param JsonSerializer $jsonSerializer diff --git a/Model/Api/Device.php b/Model/Api/Device.php index ff48bf52..282edfe7 100644 --- a/Model/Api/Device.php +++ b/Model/Api/Device.php @@ -12,22 +12,22 @@ class Device /** * @var RemoteAddress */ - protected $remoteAddress; + public $remoteAddress; /** * @var ConfigHelper */ - protected $configHelper; + public $configHelper; /** * @var DeviceHelper */ - protected $deviceHelper; + public $deviceHelper; /** * @var FingerprintFactory */ - protected $fingerprintFactory; + public $fingerprintFactory; /** * @param RemoteAddress $remoteAddress diff --git a/Model/Api/Fulfillment.php b/Model/Api/Fulfillment.php index 234886fe..95588ae2 100644 --- a/Model/Api/Fulfillment.php +++ b/Model/Api/Fulfillment.php @@ -8,7 +8,7 @@ class Fulfillment /** * @var FulfillmentsFactory */ - protected $fulfillmentsFactory; + public $fulfillmentsFactory; /** * @param FulfillmentsFactory $fulfillmentsFactory diff --git a/Model/Api/Fulfillments.php b/Model/Api/Fulfillments.php index 0d59e534..e4e23677 100644 --- a/Model/Api/Fulfillments.php +++ b/Model/Api/Fulfillments.php @@ -10,7 +10,7 @@ class Fulfillments /** * @var JsonSerializer */ - protected $jsonSerializer; + public $jsonSerializer; /** * @param JsonSerializer $jsonSerializer diff --git a/Model/Api/MerchantPlatform.php b/Model/Api/MerchantPlatform.php index 0521b435..c27f26b0 100644 --- a/Model/Api/MerchantPlatform.php +++ b/Model/Api/MerchantPlatform.php @@ -9,7 +9,7 @@ class MerchantPlatform /** * @var ProductMetadataInterface */ - protected $productMetadataInterface; + public $productMetadataInterface; /** * @param ProductMetadataInterface $productMetadataInterface diff --git a/Model/Api/Origin.php b/Model/Api/Origin.php index 8173f46a..64ef02a1 100644 --- a/Model/Api/Origin.php +++ b/Model/Api/Origin.php @@ -11,17 +11,17 @@ class Origin /** * @var ScopeConfigInterface */ - protected $scopeConfigInterface; + public $scopeConfigInterface; /** * @var RegionFactory */ - protected $regionFactory; + public $regionFactory; /** * @var RegionResourceModel */ - protected $regionResourceModel; + public $regionResourceModel; /** * @param ScopeConfigInterface $scopeConfigInterface diff --git a/Model/Api/PaymentMethod.php b/Model/Api/PaymentMethod.php index c7fb06ad..31facfc7 100644 --- a/Model/Api/PaymentMethod.php +++ b/Model/Api/PaymentMethod.php @@ -10,12 +10,12 @@ class PaymentMethod /** * @var MappingVerificationFactory */ - protected $mappingVerificationFactory; + public $mappingVerificationFactory; /** * @var Logger */ - protected $logger; + public $logger; /** * @param MappingVerificationFactory $mappingVerificationFactory diff --git a/Model/Api/Product.php b/Model/Api/Product.php index 2fad6540..da651f33 100644 --- a/Model/Api/Product.php +++ b/Model/Api/Product.php @@ -14,27 +14,27 @@ class Product /** * @var CategoryCollectionFactory */ - protected $categoryCollectionFactory; + public $categoryCollectionFactory; /** * @var CategoryFactory */ - protected $categoryFactory; + public $categoryFactory; /** * @var CategoryResourceModel */ - protected $categoryResourceModel; + public $categoryResourceModel; /** * @var StoreManagerInterface */ - protected $storeManagerInterface; + public $storeManagerInterface; /** * @var SubscriptionFactory */ - protected $subscriptionFactory; + public $subscriptionFactory; /** * @param CategoryCollectionFactory $categoryCollectionFactory @@ -133,7 +133,8 @@ protected function makeProductFromOrder(OrderItem $item) if ($itemPrice <= 0) { if ($item->getParentItem()) { - if ($item->getParentItem()->getProductType() === 'configurable') { + $type = $item->getParentItem()->getProductType(); + if ($type === 'configurable' || $type === 'bundle') { $parentItemPriceInclTax = $item->getParentItem()->getPriceInclTax() ?? 0; $itemPrice = floatval(number_format($parentItemPriceInclTax, 2, '.', '')); @@ -217,7 +218,8 @@ protected function makeProductFromQuote(QuoteItem $item) if ($itemPrice <= 0) { if ($item->getParentItem()) { - if ($item->getParentItem()->getProductType() === 'configurable') { + $type = $item->getParentItem()->getProductType(); + if ($type === 'configurable' || $type === 'bundle') { $itemPriceInclTax = $item->getParentItem()->getPriceInclTax() ?? 0; $itemPrice = floatval(number_format($itemPriceInclTax, 2, '.', '')); diff --git a/Model/Api/Purchase.php b/Model/Api/Purchase.php index cadc2519..d06c27dc 100644 --- a/Model/Api/Purchase.php +++ b/Model/Api/Purchase.php @@ -11,22 +11,22 @@ class Purchase /** * @var DateTimeFactory */ - protected $dateTimeFactory; + public $dateTimeFactory; /** * @var ProductFactory */ - protected $productFactory; + public $productFactory; /** * @var ShipmentsFactory */ - protected $shipmentsFactory; + public $shipmentsFactory; /** * @var ReceivedByFactory */ - protected $receivedByFactory; + public $receivedByFactory; /** * @param DateTimeFactory $dateTimeFactory diff --git a/Model/Api/Recipient.php b/Model/Api/Recipient.php index bef50100..055380ff 100644 --- a/Model/Api/Recipient.php +++ b/Model/Api/Recipient.php @@ -12,17 +12,17 @@ class Recipient /** * @var ScopeConfigInterface */ - protected $scopeConfigInterface; + public $scopeConfigInterface; /** * @var JsonSerializer */ - protected $jsonSerializer; + public $jsonSerializer; /** * @var AddressFactory */ - protected $addressFactory; + public $addressFactory; /** * @param ScopeConfigInterface $scopeConfigInterface diff --git a/Model/Api/RecordReturn.php b/Model/Api/RecordReturn.php index 142088b8..c0997ff7 100644 --- a/Model/Api/RecordReturn.php +++ b/Model/Api/RecordReturn.php @@ -7,12 +7,12 @@ class RecordReturn /** * @var DeviceFactory */ - protected $deviceFactory; + public $deviceFactory; /** * @var ProductFactory */ - protected $productFactory; + public $productFactory; /** * @param DeviceFactory $deviceFactory diff --git a/Model/Api/SaleOrder.php b/Model/Api/SaleOrder.php index 35ea32cc..6a77589e 100644 --- a/Model/Api/SaleOrder.php +++ b/Model/Api/SaleOrder.php @@ -2,7 +2,7 @@ namespace Signifyd\Connect\Model\Api; -use Magento\Framework\Registry; +use Signifyd\Connect\Model\Registry; use Magento\Sales\Model\Order; use Signifyd\Connect\Logger\Logger; @@ -11,72 +11,72 @@ class SaleOrder /** * @var Registry */ - protected $registry; + public $registry; /** * @var PurchaseFactory */ - protected $purchaseFactory; + public $purchaseFactory; /** * @var UserAccountFactory */ - protected $userAccountFactory; + public $userAccountFactory; /** * @var CoverageRequestsFactory */ - protected $coverageRequestsFactory; + public $coverageRequestsFactory; /** * @var DeviceFactory */ - protected $deviceFactory; + public $deviceFactory; /** * @var MerchantPlatformFactory */ - protected $merchantPlatformFactory; + public $merchantPlatformFactory; /** * @var SignifydClientFactory */ - protected $signifydClientFactory; + public $signifydClientFactory; /** * @var TransactionsFactory */ - protected $transactionsFactory; + public $transactionsFactory; /** * @var TagsFactory */ - protected $tagsFactory; + public $tagsFactory; /** * @var SellersFactory */ - protected $sellersFactory; + public $sellersFactory; /** * @var CustomerOrderRecommendationFactory */ - protected $customerOrderRecommendationFactory; + public $customerOrderRecommendationFactory; /** * @var MembershipsFactory */ - protected $membershipsFactory; + public $membershipsFactory; /** * @var MerchantCategoryCodeFactory */ - protected $merchantCategoryCodeFactory; + public $merchantCategoryCodeFactory; /** * @var Logger */ - protected $logger; + public $logger; /** * @param Registry $registry @@ -168,11 +168,11 @@ public function __invoke($order) * It must be unregistered after use * @see \Signifyd\Connect\Plugin\Magento\Paypal\Model\Payflowlink */ - $this->registry->unregister('signifyd_payment_data'); + $this->registry->setData('signifyd_payment_data'); } catch (\Exception $e) { - $this->logger->info("Failed to create checkout order " . $e->getMessage()); + $this->logger->info("Failed to create sale order " . $e->getMessage(), ['entity' => $order]); } catch (\Error $e) { - $this->logger->info("Failed to create checkout order " . $e->getMessage()); + $this->logger->info("Failed to create sale order " . $e->getMessage(), ['entity' => $order]); } return $signifydOrder; diff --git a/Model/Api/Shipments.php b/Model/Api/Shipments.php index a9c99d3a..81df2ba5 100644 --- a/Model/Api/Shipments.php +++ b/Model/Api/Shipments.php @@ -13,32 +13,32 @@ class Shipments /** * @var ScopeConfigInterface */ - protected $scopeConfigInterface; + public $scopeConfigInterface; /** * @var JsonSerializer */ - protected $jsonSerializer; + public $jsonSerializer; /** * @var CarrierFactory */ - protected $carrierFactory; + public $carrierFactory; /** * @var RecipientFactory */ - protected $recipientFactory; + public $recipientFactory; /** * @var OriginFactory */ - protected $originFactory; + public $originFactory; /** * @var MinDeliveryDateFactory */ - protected $minDeliveryDateFactory; + public $minDeliveryDateFactory; /** * @param ScopeConfigInterface $scopeConfigInterface @@ -146,7 +146,7 @@ protected function makeShipmentsFromQuote(Quote $quote) $shipment['maxDeliveryDate'] = null; $shipment['shipmentId'] = null; $shipment['fulfillmentMethod'] = $this->getFulfillmentMethodMapping( - $quote->getShippingMethod(), + $quote->getShippingAddress()->getShippingMethod(), ScopeInterface::SCOPE_STORES, $quote->getStoreId() ); diff --git a/Model/Api/SignifydClient.php b/Model/Api/SignifydClient.php index 4803d5c5..29dc81a6 100644 --- a/Model/Api/SignifydClient.php +++ b/Model/Api/SignifydClient.php @@ -9,7 +9,7 @@ class SignifydClient /** * @var ModuleListInterface */ - protected $moduleList; + public $moduleList; /** * @param ModuleListInterface $moduleList diff --git a/Model/Api/Tags.php b/Model/Api/Tags.php index 05efe921..49f47ec4 100644 --- a/Model/Api/Tags.php +++ b/Model/Api/Tags.php @@ -9,7 +9,7 @@ class Tags /** * @var ScopeConfigInterface */ - protected $scopeConfigInterface; + public $scopeConfigInterface; /** * @param ScopeConfigInterface $scopeConfigInterface diff --git a/Model/Api/Transactions.php b/Model/Api/Transactions.php index d1752678..5207fb6a 100644 --- a/Model/Api/Transactions.php +++ b/Model/Api/Transactions.php @@ -21,107 +21,107 @@ class Transactions /** * @var TransactionCollectionFactory */ - protected $transactionCollectionFactory; + public $transactionCollectionFactory; /** * @var DateTimeFactory */ - protected $dateTimeFactory; + public $dateTimeFactory; /** * @var JsonSerializer */ - protected $jsonSerializer; + public $jsonSerializer; /** * @var PaymentVerificationFactory */ - protected $paymentVerificationFactory; + public $paymentVerificationFactory; /** * @var Logger */ - protected $logger; + public $logger; /** * @var QuoteResourceModel */ - protected $quoteResourceModel; + public $quoteResourceModel; /** * @var PaymentMethodFactory */ - protected $paymentMethodFactory; + public $paymentMethodFactory; /** * @var QuoteFactory */ - protected $quoteFactory; + public $quoteFactory; /** * @var CasedataFactory */ - protected $casedataFactory; + public $casedataFactory; /** * @var CasedataResourceModel */ - protected $casedataResourceModel; + public $casedataResourceModel; /** * @var ScaEvaluation */ - protected $scaEvaluation; + public $scaEvaluation; /** * @var VerificationsFactory */ - protected $verificationsFactory; + public $verificationsFactory; /** * @var CheckoutPaymentDetailsFactory */ - protected $checkoutPaymentDetailsFactory; + public $checkoutPaymentDetailsFactory; /** * @var ParentTransactionIdFactory */ - protected $parentTransactionIdFactory; + public $parentTransactionIdFactory; /** * @var GatewayStatusMessageFactory */ - protected $gatewayStatusMessageFactory; + public $gatewayStatusMessageFactory; /** * @var GatewayErrorCodeFactory */ - protected $gatewayErrorCodeFactory; + public $gatewayErrorCodeFactory; /** * @var PaypalPendingReasonCodeFactory */ - protected $paypalPendingReasonCodeFactory; + public $paypalPendingReasonCodeFactory; /** * @var PaypalProtectionEligibilityFactory */ - protected $paypalProtectionEligibilityFactory; + public $paypalProtectionEligibilityFactory; /** * @var PaypalProtectionEligibilityTypeFactory */ - protected $paypalProtectionEligibilityTypeFactory; + public $paypalProtectionEligibilityTypeFactory; /** * @var SourceAccountDetailsFactory */ - protected $sourceAccountDetailsFactory; + public $sourceAccountDetailsFactory; /** * @var AcquirerDetailsFactory */ - protected $acquirerDetailsFactory; + public $acquirerDetailsFactory; /** * @param TransactionCollectionFactory $transactionCollectionFactory @@ -372,7 +372,7 @@ protected function makeScaExemptionRequested($quoteId = null) return null; } - /** @var $case \Signifyd\Connect\Model\Casedata */ + /** @var \Signifyd\Connect\Model\Casedata $case */ $case = $this->casedataFactory->create(); $this->casedataResourceModel->load($case, $quoteId, 'quote_id'); diff --git a/Model/Api/UserAccount.php b/Model/Api/UserAccount.php index 8c1c86c1..d5ceeb99 100644 --- a/Model/Api/UserAccount.php +++ b/Model/Api/UserAccount.php @@ -4,6 +4,7 @@ use Magento\Customer\Model\CustomerFactory; use Magento\Customer\Model\ResourceModel\Customer as CustomerResourceModel; +use Magento\Framework\App\ResourceConnection; use Magento\Quote\Model\Quote; use Magento\Sales\Model\Order; use Magento\Sales\Model\ResourceModel\Order\CollectionFactory as OrderCollectionFactory; @@ -13,31 +14,39 @@ class UserAccount /** * @var CustomerFactory */ - protected $customerFactory; + public $customerFactory; /** * @var CustomerResourceModel */ - protected $customerResourceModel; + public $customerResourceModel; /** * @var OrderCollectionFactory */ - protected $orderCollectionFactory; + public $orderCollectionFactory; + + /** + * @var ResourceConnection + */ + protected $resourceConnection; /** * @param CustomerFactory $customerFactory * @param CustomerResourceModel $customerResourceModel * @param OrderCollectionFactory $orderCollectionFactory + * @param ResourceConnection $resourceConnection */ public function __construct( CustomerFactory $customerFactory, CustomerResourceModel $customerResourceModel, - OrderCollectionFactory $orderCollectionFactory + OrderCollectionFactory $orderCollectionFactory, + ResourceConnection $resourceConnection ) { $this->customerFactory = $customerFactory; $this->customerResourceModel = $customerResourceModel; $this->orderCollectionFactory = $orderCollectionFactory; + $this->resourceConnection = $resourceConnection; } /** @@ -72,7 +81,7 @@ protected function makeUserAccount(Order $order) $user['email'] = $order->getCustomerEmail(); $user['phone'] = $order->getBillingAddress()->getTelephone(); - /* @var $customer \Magento\Customer\Model\Customer */ + /* @var \Magento\Customer\Model\Customer $customer */ $customer = $this->customerFactory->create(); $this->customerResourceModel->load($customer, $order->getCustomerId()); @@ -84,29 +93,40 @@ protected function makeUserAccount(Order $order) $user['passwordLastUpdateDate'] = null; $lastOrders = $this->orderCollectionFactory->create() + ->addFieldToSelect('increment_id') ->addFieldToFilter('customer_id', ['eq' => $customer->getId()]) ->addFieldToFilter('state', ['nin' => ['closed', 'canceled']]) ->addFieldToFilter('entity_id', ['neq' => $order->getId()]); - $lastOrder = $lastOrders->getLastItem(); - $lastOrderId = $lastOrder->getIncrementId(); + $lastOrders->setOrder('entity_id', 'desc'); + $lastOrders->getSelect()->limit(1); + $lastOrderId = $lastOrders->getFirstItem()->getIncrementId(); $user['lastOrderId'] = isset($lastOrderId) ? $lastOrderId : null; - /** @var $orders \Magento\Sales\Model\ResourceModel\Order\Collection */ - $orderCollection = $this->orderCollectionFactory->create(); - $orderCollection->addFieldToFilter('customer_id', $order->getCustomerId()); - $orderCollection->load(); + $historyData = $this->getAggregateData($order->getCustomerId()); - /** @var $orderCollection \Magento\Sales\Model\Order*/ - foreach ($orderCollection as $o) { - $user['aggregateOrderCount']++; - $user['aggregateOrderDollars'] += floatval($o->getGrandTotal()); + if (isset($historyData['sum_grand_total']) && + isset($historyData['totals_order']) + ) { + $user['aggregateOrderCount'] = (int) $historyData['totals_order']; + $user['aggregateOrderDollars'] = number_format($historyData['sum_grand_total'], 2, '.', ''); } } return $user; } + public function getAggregateData($customerId) + { + $salesOrder = $this->resourceConnection->getTableName('sales_order'); + $customerOrderHistory = "SELECT customer_id, SUM(grand_total) AS 'sum_grand_total', count(*) AS " . + "'totals_order' FROM " . $salesOrder . " WHERE customer_id = " . $customerId; + $connection = $this->resourceConnection->getConnection(); + $historyDataArray = $connection->fetchAll($customerOrderHistory); + + return reset($historyDataArray); + } + /** * @param $quote Quote * @return array @@ -121,7 +141,7 @@ protected function makeUserAccountFromQuote(Quote $quote) $user['aggregateOrderCount'] = 0; $user['aggregateOrderDollars'] = 0.0; - /* @var $customer \Magento\Customer\Model\Customer */ + /* @var \Magento\Customer\Model\Customer $customer */ $customer = $this->customerFactory->create(); $this->customerResourceModel->load($customer, $quote->getCustomerId()); @@ -133,22 +153,22 @@ protected function makeUserAccountFromQuote(Quote $quote) $user['passwordLastUpdateDate'] = null; $lastOrders = $this->orderCollectionFactory->create() + ->addFieldToSelect('increment_id') ->addFieldToFilter('customer_id', ['eq' => $customer->getId()]) ->addFieldToFilter('state', ['nin' => ['closed', 'canceled']]); - $lastOrder = $lastOrders->getLastItem(); - $lastOrderId = $lastOrder->getIncrementId(); + $lastOrders->setOrder('entity_id', 'desc'); + $lastOrders->getSelect()->limit(1); + $lastOrderId = $lastOrders->getFirstItem()->getIncrementId(); $user['lastOrderId'] = isset($lastOrderId) ? $lastOrderId : null; - /** @var $orders \Magento\Sales\Model\ResourceModel\Order\Collection */ - $orderCollection = $this->orderCollectionFactory->create(); - $orderCollection->addFieldToFilter('customer_id', $quote->getCustomerId()); - $orderCollection->load(); + $historyData = $this->getAggregateData($quote->getCustomerId()); - /** @var $orderCollection \Magento\Sales\Model\Order */ - foreach ($orderCollection as $o) { - $user['aggregateOrderCount']++; - $user['aggregateOrderDollars'] += floatval($o->getGrandTotal()); + if (isset($historyData['sum_grand_total']) && + isset($historyData['totals_order']) + ) { + $user['aggregateOrderCount'] = (int) $historyData['totals_order']; + $user['aggregateOrderDollars'] = number_format($historyData['sum_grand_total'], 2, '.', ''); } } diff --git a/Model/Api/Verifications.php b/Model/Api/Verifications.php index 41eb0d83..f1692279 100644 --- a/Model/Api/Verifications.php +++ b/Model/Api/Verifications.php @@ -12,12 +12,12 @@ class Verifications /** * @var Logger */ - protected $logger; + public $logger; /** * @var PaymentVerificationFactory */ - protected $paymentVerificationFactory; + public $paymentVerificationFactory; /** * @param Logger $logger @@ -69,12 +69,7 @@ public function getAvsCode(Order $order) } $avsCode = trim(strtoupper($avsCode)); - - if ($avsAdapter->validate($avsCode)) { - return $avsCode; - } else { - return null; - } + return $avsCode; } catch (Exception $e) { $this->logger->error( 'Error fetching AVS code: ' . $e->getMessage(), @@ -109,12 +104,7 @@ public function getCvvCode(Order $order) } $cvvCode = trim(strtoupper($cvvCode)); - - if ($cvvAdapter->validate($cvvCode)) { - return $cvvCode; - } else { - return null; - } + return $cvvCode; } catch (Exception $e) { $this->logger->error( 'Error fetching CVV code: ' . $e->getMessage(), diff --git a/Model/Casedata.php b/Model/Casedata.php index a2677d17..79486cde 100644 --- a/Model/Casedata.php +++ b/Model/Casedata.php @@ -15,9 +15,6 @@ use Signifyd\Connect\Logger\Logger; use Magento\Framework\Serialize\SerializerInterface; use Signifyd\Connect\Model\ResourceModel\Order as SignifydOrderResourceModel; -use Signifyd\Connect\Model\Casedata\UpdateCaseV2Factory; -use Signifyd\Connect\Model\Casedata\UpdateCaseFactory; -use Signifyd\Connect\Model\UpdateOrderFactory; /** * ORM model declaration for case data @@ -51,67 +48,48 @@ class Casedata extends AbstractModel /** * @var ConfigHelper */ - protected $configHelper; + public $configHelper; /** * @var OrderFactory */ - protected $orderFactory; + public $orderFactory; /** * @var OrderResourceModel */ - protected $orderResourceModel; + public $orderResourceModel; /** * @var \Magento\Sales\Model\Order */ - protected $order; + public $order; /** * @var Logger */ - protected $logger; + public $logger; /** * @var SerializerInterface */ - protected $serializer; + public $serializer; /** * @var SignifydOrderResourceModel */ - protected $signifydOrderResourceModel; - - /** - * @var UpdateCaseV2Factory - */ - protected $updateCaseV2Factory; - - /** - * @var UpdateCaseFactory - */ - protected $updateCaseFactory; - - /** - * @var UpdateOrderFactory - */ - protected $updateOrderFactory; + public $signifydOrderResourceModel; /** * Casedata constructor. * @param Context $context * @param Registry $registry * @param ConfigHelper $configHelper - * @param ObjectManagerInterface $objectManager * @param OrderFactory $orderFactory * @param OrderResourceModel $orderResourceModel * @param Logger $logger * @param SerializerInterface $serializer * @param SignifydOrderResourceModel $signifydOrderResourceModel - * @param UpdateCaseV2Factory $updateCaseV2Factory - * @param UpdateCaseFactory $updateCaseFactory - * @param UpdateOrderFactory $updateOrderFactory */ public function __construct( Context $context, @@ -121,10 +99,7 @@ public function __construct( OrderResourceModel $orderResourceModel, Logger $logger, SerializerInterface $serializer, - SignifydOrderResourceModel $signifydOrderResourceModel, - UpdateCaseV2Factory $updateCaseV2Factory, - UpdateCaseFactory $updateCaseFactory, - UpdateOrderFactory $updateOrderFactory + SignifydOrderResourceModel $signifydOrderResourceModel ) { $this->configHelper = $configHelper; $this->orderFactory = $orderFactory; @@ -132,9 +107,6 @@ public function __construct( $this->logger = $logger; $this->serializer = $serializer; $this->signifydOrderResourceModel = $signifydOrderResourceModel; - $this->updateCaseV2Factory = $updateCaseV2Factory; - $this->updateCaseFactory = $updateCaseFactory; - $this->updateOrderFactory = $updateOrderFactory; parent::__construct($context, $registry); } @@ -170,7 +142,7 @@ public function getOrder($forceLoad = false, $loadForUpdate = false) } /** - * @param null $index + * @param $index * @return array|mixed|null */ public function getEntries($index = null) @@ -208,6 +180,8 @@ public function setEntries($index, $value = null) } elseif (is_string($index)) { $entries = $this->getEntries(); $entries[$index] = $value; + } else { + return $this; } $entries = $this->serializer->serialize($entries); diff --git a/Model/Casedata/FilterCasesByStatus.php b/Model/Casedata/FilterCasesByStatus.php index 21f4ee93..8d43013c 100644 --- a/Model/Casedata/FilterCasesByStatus.php +++ b/Model/Casedata/FilterCasesByStatus.php @@ -15,27 +15,27 @@ class FilterCasesByStatus extends AbstractHelper /** * @var CasedataCollectionFactory */ - protected $casedataCollectionFactory; + public $casedataCollectionFactory; /** * @var CasedataResourceModel */ - protected $casedataResourceModel; + public $casedataResourceModel; /** * @var Logger */ - protected $logger; + public $logger; /** * @var CasedataFactory */ - protected $casedataFactory; + public $casedataFactory; /** * @var ConfigHelper */ - protected $configHelper; + public $configHelper; /** * Retry constructor. @@ -99,17 +99,25 @@ public function __invoke($status, $policyName = 'post_auth') /** @var \Signifyd\Connect\Model\Casedata $case */ foreach ($casesCollection->getItems() as $case) { - $caseToUpdate = $this->casedataFactory->create(); - $this->casedataResourceModel->loadForUpdate($caseToUpdate, $case->getId()); - - $retries = $caseToUpdate->getData('retries'); - $secondsAfterUpdate = $case->getData('seconds_after_update'); - - if ($secondsAfterUpdate > $retryTimes[$retries]) { - - $casesToRetry[$caseToUpdate->getId()] = $caseToUpdate; - $caseToUpdate->setData('retries', $retries + 1); - $this->casedataResourceModel->save($caseToUpdate); + try { + $caseToUpdate = $this->casedataFactory->create(); + $this->casedataResourceModel->loadForUpdate($caseToUpdate, $case->getId()); + + $retries = $caseToUpdate->getData('retries'); + $secondsAfterUpdate = $case->getData('seconds_after_update'); + + if ($secondsAfterUpdate > $retryTimes[$retries]) { + + $casesToRetry[$caseToUpdate->getId()] = $caseToUpdate; + $caseToUpdate->setData('retries', $retries + 1); + $this->casedataResourceModel->save($caseToUpdate); + } + } catch (\Exception $e) { + $this->logger->error( + 'CRON: Case failed to load for update: ' + . $e->getMessage(), + ['entity' => $case] + ); } } diff --git a/Model/Casedata/UpdateCase.php b/Model/Casedata/UpdateCase.php index f1ab6ccf..96f910eb 100644 --- a/Model/Casedata/UpdateCase.php +++ b/Model/Casedata/UpdateCase.php @@ -20,27 +20,27 @@ class UpdateCase /** * @var ConfigHelper */ - protected $configHelper; + public $configHelper; /** * @var OrderHelper */ - protected $orderHelper; + public $orderHelper; /** * @var Logger */ - protected $logger; + public $logger; /** * @var OrderFactory */ - protected $orderFactory; + public $orderFactory; /** * @var SignifydOrderResourceModel */ - protected $signifydOrderResourceModel; + public $signifydOrderResourceModel; /** * @param ConfigHelper $configHelper diff --git a/Model/Casedata/UpdateCaseV2.php b/Model/Casedata/UpdateCaseV2.php index 51593c97..ae0fe1e9 100644 --- a/Model/Casedata/UpdateCaseV2.php +++ b/Model/Casedata/UpdateCaseV2.php @@ -20,27 +20,27 @@ class UpdateCaseV2 /** * @var ConfigHelper */ - protected $configHelper; + public $configHelper; /** * @var OrderHelper */ - protected $orderHelper; + public $orderHelper; /** * @var Logger */ - protected $logger; + public $logger; /** * @var OrderFactory */ - protected $orderFactory; + public $orderFactory; /** * @var SignifydOrderResourceModel */ - protected $signifydOrderResourceModel; + public $signifydOrderResourceModel; /** * @param ConfigHelper $configHelper diff --git a/Model/Config/Source/SignifydEnableOptions.php b/Model/Config/Source/SignifydEnableOptions.php index df387b43..1ae55b15 100644 --- a/Model/Config/Source/SignifydEnableOptions.php +++ b/Model/Config/Source/SignifydEnableOptions.php @@ -3,9 +3,9 @@ namespace Signifyd\Connect\Model\Config\Source; use Magento\Eav\Model\Entity\Attribute\Source\AbstractSource; -use Magento\Framework\Option\ArrayInterface; +use Magento\Framework\Data\OptionSourceInterface; -class SignifydEnableOptions extends AbstractSource implements ArrayInterface +class SignifydEnableOptions extends AbstractSource implements OptionSourceInterface { public function toOptionArray() { diff --git a/Model/Config/Source/SignifydGuaranteeStatus.php b/Model/Config/Source/SignifydGuaranteeStatus.php index 5d752421..fcb113c7 100644 --- a/Model/Config/Source/SignifydGuaranteeStatus.php +++ b/Model/Config/Source/SignifydGuaranteeStatus.php @@ -3,9 +3,9 @@ namespace Signifyd\Connect\Model\Config\Source; use Magento\Eav\Model\Entity\Attribute\Source\AbstractSource; -use Magento\Framework\Option\ArrayInterface; +use Magento\Framework\Data\OptionSourceInterface; -class SignifydGuaranteeStatus extends AbstractSource implements ArrayInterface +class SignifydGuaranteeStatus extends AbstractSource implements OptionSourceInterface { public function toOptionArray() { diff --git a/Model/ConfigProvider.php b/Model/ConfigProvider.php index 11e38a02..1e1d9286 100644 --- a/Model/ConfigProvider.php +++ b/Model/ConfigProvider.php @@ -17,17 +17,17 @@ class ConfigProvider implements \Magento\Checkout\Model\ConfigProviderInterface /** * @var ConfigHelper */ - protected $configHelper; + public $configHelper; /** * @var StoreManagerInterface */ - protected $storeManager; + public $storeManager; /** * @var ModuleListInterface */ - protected $moduleListInterface; + public $moduleListInterface; /** * @param ConfigHelper $configHelper diff --git a/Model/Fulfillment/FulfillmentsToRetry.php b/Model/Fulfillment/FulfillmentsToRetry.php index 31a9c9a2..8c01f3f2 100644 --- a/Model/Fulfillment/FulfillmentsToRetry.php +++ b/Model/Fulfillment/FulfillmentsToRetry.php @@ -7,102 +7,41 @@ use Signifyd\Connect\Logger\Logger; use Signifyd\Connect\Model\ResourceModel\Fulfillment\CollectionFactory as FulfillmentCollectionFactory; use Signifyd\Connect\Model\ResourceModel\Fulfillment as FulfillmentResourceModel; +use Signifyd\Connect\Model\RetryModel; -class FulfillmentsToRetry extends AbstractHelper +class FulfillmentsToRetry extends RetryModel { /** * @var Logger */ - protected $logger; + public $logger; /** * @var FulfillmentCollectionFactory */ - protected $fulfillmentCollectionFactory; + public $objectCollectionFactory; /** * @var FulfillmentResourceModel */ - protected $fulfillmentResourceModel; + public $objectResourceModel; /** * Retry constructor. * @param Context $context * @param Logger $logger - * @param FulfillmentCollectionFactory $fulfillmentCollectionFactory - * @param FulfillmentResourceModel $fulfillmentResourceModel + * @param FulfillmentCollectionFactory $objectCollectionFactory + * @param FulfillmentResourceModel $objectResourceModel */ public function __construct( Context $context, Logger $logger, - FulfillmentCollectionFactory $fulfillmentCollectionFactory, - FulfillmentResourceModel $fulfillmentResourceModel + FulfillmentCollectionFactory $objectCollectionFactory, + FulfillmentResourceModel $objectResourceModel ) { - parent::__construct($context); + parent::__construct($context, $logger); - $this->logger = $logger; - $this->fulfillmentCollectionFactory = $fulfillmentCollectionFactory; - $this->fulfillmentResourceModel = $fulfillmentResourceModel; - } - - /** - * @param $status - * @return mixed - */ - public function __invoke() - { - $retryTimes = $this->calculateRetryTimes(); - - $time = time(); - $lastTime = $time - (end($retryTimes) + 60*60*24); - $current = date('Y-m-d H:i:s', $time); - $from = date('Y-m-d H:i:s', $lastTime); - - $fulfillmentsCollection = $this->fulfillmentCollectionFactory->create(); - $fulfillmentsCollection->addFieldToFilter('inserted_at', ['gteq' => $from]); - $fulfillmentsCollection->addFieldToFilter('magento_status', ['eq' => 'waiting_submission']); - $fulfillmentsCollection->addFieldToFilter('retries', ['lt' => count($retryTimes)]); - $fulfillmentsCollection->addExpressionFieldToSelect( - 'seconds_after_inserted_at', - "TIME_TO_SEC(TIMEDIFF('{$current}', inserted_at))", - ['inserted_at'] - ); - - $fulfillmentsToRetry = []; - - /** @var \Signifyd\Connect\Model\Casedata $fulfillment */ - foreach ($fulfillmentsCollection->getItems() as $fulfillment) { - $retries = $fulfillment->getData('retries'); - $secondsAfterUpdate = $fulfillment->getData('seconds_after_inserted_at'); - - if ($secondsAfterUpdate > $retryTimes[$retries]) { - $fulfillmentsToRetry[$fulfillment->getId()] = $fulfillment; - $fulfillment->setData('retries', $retries + 1); - $this->fulfillmentResourceModel->save($fulfillment); - } - } - - return $fulfillmentsToRetry; - } - - /** - * Retry times calculated from last update - * - * @return array - */ - protected function calculateRetryTimes() - { - $retryTimes = []; - - for ($retry = 0; $retry < 15; $retry++) { - // Increment retry times exponentially - $retryTimes[$retry] = 20 * pow(2, $retry); - // Increment should not be greater than one day - $retryTimes[$retry] = $retryTimes[$retry] > 86400 ? 86400 : $retryTimes[$retry]; - // Sum retry time to previous, calculating total time to wait from last update - $retryTimes[$retry] += isset($retryTimes[$retry-1]) ? $retryTimes[$retry-1] : 0; - } - - return $retryTimes; + $this->objectCollectionFactory = $objectCollectionFactory; + $this->objectResourceModel = $objectResourceModel; } } diff --git a/Model/InconsistencyMessage.php b/Model/InconsistencyMessage.php index b7e32f61..2d22985a 100644 --- a/Model/InconsistencyMessage.php +++ b/Model/InconsistencyMessage.php @@ -16,12 +16,12 @@ class InconsistencyMessage implements MessageInterface /** * @var ScopeConfigInterface */ - protected $scopeConfigInterface; + public $scopeConfigInterface; /** * @var UrlInterface */ - protected $urlInterface; + public $urlInterface; /** * @param ScopeConfigInterface $scopeConfigInterface diff --git a/Model/Logs.php b/Model/Logs.php new file mode 100644 index 00000000..b46274ac --- /dev/null +++ b/Model/Logs.php @@ -0,0 +1,142 @@ +serializer = $serializer; + + parent::__construct($context, $registry, $resource, $resourceCollection, $data); + } + + /** + * @inheritDoc + */ + public function _construct() + { + $this->_init(\Signifyd\Connect\Model\ResourceModel\Logs::class); + } + + /** + * @inheritDoc + */ + public function getLogsId() + { + return $this->getData(self::LOGS_ID); + } + + /** + * @inheritDoc + */ + public function setLogsId($logsId) + { + return $this->setData(self::LOGS_ID, $logsId); + } + + /** + * @inheritDoc + */ + public function getCreatedAt() + { + return $this->getData(self::CREATED_AT); + } + + /** + * @inheritDoc + */ + public function setCreatedAt($createdAt) + { + return $this->setData(self::CREATED_AT, $createdAt); + } + + /** + * @inheritDoc + */ + public function getQuoteId() + { + return $this->getData(self::QUOTE_ID); + } + + /** + * @inheritDoc + */ + public function setQuoteId($quoteId) + { + return $this->setData(self::QUOTE_ID, $quoteId); + } + + /** + * @inheritDoc + */ + public function getOrderId() + { + return $this->getData(self::ORDER_ID); + } + + /** + * @inheritDoc + */ + public function setOrderId($orderId) + { + return $this->setData(self::ORDER_ID, $orderId); + } + + /** + * @inheritDoc + */ + public function getType() + { + return $this->getData(self::TYPE); + } + + /** + * @inheritDoc + */ + public function setType($type) + { + return $this->setData(self::TYPE, $type); + } + + /** + * @inheritDoc + */ + public function getEntry() + { + return $this->getData(self::ENTRY); + } + + /** + * @inheritDoc + */ + public function setEntry($entry) + { + return $this->setData(self::ENTRY, $entry); + } +} diff --git a/Model/LogsFile.php b/Model/LogsFile.php new file mode 100644 index 00000000..40f75d28 --- /dev/null +++ b/Model/LogsFile.php @@ -0,0 +1,256 @@ +directoryList = $directoryList; + $this->file = $file; + $this->signifydOrderResourceModel = $signifydOrderResourceModel; + $this->orderFactory = $orderFactory; + $this->logsCollectionFactory = $logsCollectionFactory; + $this->logger = $logger; + $this->quoteFactory = $quoteFactory; + $this->quoteResource = $quoteResource; + $this->historyCollectionFactory = $historyCollectionFactory; + $this->configDataCollectionFactory = $configDataCollectionFactory; + $this->statusCollectionFactory = $statusCollectionFactory; + $this->casedataFactory = $casedataFactory; + $this->casedataResourceModel = $casedataResourceModel; + } + + /** + * @return void + * @throws \Magento\Framework\Exception\FileSystemException + */ + public function prepLogsDir() + { + $path = $this->directoryList->getPath('media') . '/signifyd_logs'; + + try { + $this->file->checkAndCreateFolder($path); + } catch (\Exception $e) { + return; + } + } + + /** + * @param $orderId + * @return string + */ + public function createLogFile($orderId) + { + try { + $this->prepLogsDir(); + + /** @var \Magento\Sales\Model\Order $order */ + $order = $this->orderFactory->create(); + $this->signifydOrderResourceModel->load($order, $orderId); + $quoteId = $order->getQuoteId(); + $fileName = $order->getIncrementId() . '.txt'; + $filePath = $this->directoryList->getPath('media') . '/signifyd_logs/' . $fileName; + $fileData = ''; + + $this->logger->info("Generating log for order " . $order->getIncrementId()); + + /** @var \Signifyd\Connect\Model\ResourceModel\Logs\Collection $quoteLogsCollection */ + $quoteLogsCollection = $this->logsCollectionFactory->create() + ->addFieldToFilter('quote_id', ['eq' => $quoteId]) + ->addFieldToFilter('order_id', ['null' => true]); + + if ($quoteLogsCollection->count() > 0) { + /** @var \Signifyd\Connect\Model\Logs $quoteLog */ + foreach ($quoteLogsCollection as $quoteLog) { + $fileData .= '[' . strtoupper($quoteLog->getType()) . '] ' . '[' . $quoteLog->getCreatedAt() . '] ' . + $quoteLog->getEntry() . PHP_EOL; + } + } + + $orderLogsCollection = $this->logsCollectionFactory->create() + ->addFieldToFilter('order_id', ['eq' => $orderId]); + + if ($orderLogsCollection->count() > 0) { + /** @var \Signifyd\Connect\Model\Logs $orderLog */ + foreach ($orderLogsCollection as $orderLog) { + $fileData .= '[' . strtoupper($orderLog->getType()) . '] ' . '[' . $orderLog->getCreatedAt() . '] ' . + $orderLog->getEntry() . PHP_EOL; + } + } + + if ($orderLogsCollection->count() === 0 && $quoteLogsCollection->count() === 0) { + return 'No records found for order ' . $order->getIncrementId(); + } + + $quote = $this->quoteFactory->create(); + $this->quoteResource->load($quote, $order->getQuoteId()); + + $case = $this->casedataFactory->create(); + $this->casedataResourceModel->loadForUpdate($case, $orderId, 'order_id'); + + $fileData .= 'case: ' . $case->toJson() . PHP_EOL; + $fileData .= 'quote: ' . $quote->toJson() . PHP_EOL; + $fileData .= 'quote_shipping_address: ' . $quote->getShippingAddress()->toJson() . PHP_EOL; + $fileData .= 'quote_billing_address: ' . $quote->getBillingAddress()->toJson() . PHP_EOL; + + $fileData .= 'sales_order: ' . $order->toJson() . PHP_EOL; + $fileData .= 'sales_order_shipping_address: ' . $order->getShippingAddress()->toJson() . PHP_EOL; + $fileData .= 'sales_order_billing_address: ' . $order->getBillingAddress()->toJson() . PHP_EOL; + + $historyCollection = $this->historyCollectionFactory->create() + ->addFieldToFilter('parent_id', ['eq' => $orderId]); + + foreach ($historyCollection as $history) { + $fileData .= 'sales_order_status_history: ' . $history->toJson() . PHP_EOL; + } + + /** @var \Magento\Sales\Model\ResourceModel\Order\Status\Collection $statusCollectionFactory */ + $statusCollectionFactory = $this->statusCollectionFactory->create()->joinStates(); + + if ($statusCollectionFactory->count() > 0) { + $fileData .= 'ORDER STATUS' . PHP_EOL; + } + + foreach ($statusCollectionFactory as $statusState) { + $fileData .= "Status: " . $statusState->getStatus() . ", label: " . $statusState->getLabel() . + ", state: " . $statusState->getState() . PHP_EOL; + } + + /** @var \Magento\Config\Model\ResourceModel\Config\Data\Collection $configDataCollection */ + $configDataCollection = $this->configDataCollectionFactory->create(); + + $configDataCollection + ->addFieldToFilter('path', ['like' => '%signifyd%']) + ->addFieldToFilter('path', ['neq' => 'signifyd/general/key']); + + if ($configDataCollection->count() > 0) { + $fileData .= 'CORE CONFIG DATA SETTINGS' . PHP_EOL; + } + + foreach ($configDataCollection as $signifydConfig) { + $fileData .= $signifydConfig->getPath() . ": " . $signifydConfig->getValue() . PHP_EOL; + } + + $fh = new \SplFileObject($filePath, 'w'); + $fh->fwrite($fileData); + + return $fileName; + } catch (\Exception $e) { + $this->logger->error("failed to generate log: " . $e->getMessage()); + return $e->getMessage(); + } catch (\Error $e) { + $this->logger->error("failed to generate log: " . $e->getMessage()); + return $e->getMessage(); + } + } +} diff --git a/Model/LogsRepository.php b/Model/LogsRepository.php new file mode 100644 index 00000000..2ee0cb98 --- /dev/null +++ b/Model/LogsRepository.php @@ -0,0 +1,148 @@ +resource = $resource; + $this->logsFactory = $logsFactory; + $this->logsCollectionFactory = $logsCollectionFactory; + $this->searchResultsFactory = $searchResultsFactory; + $this->collectionProcessor = $collectionProcessor; + } + + /** + * @inheritDoc + */ + public function save(LogsInterface $logs) + { + try { + $this->resource->save($logs); + } catch (\Exception $exception) { + throw new CouldNotSaveException(__( + 'Could not save the logs: %1', + $exception->getMessage() + )); + } + return $logs; + } + + /** + * @inheritDoc + */ + public function get($logsId) + { + $logs = $this->logsFactory->create(); + $this->resource->load($logs, $logsId); + if (!$logs->getId()) { + throw new NoSuchEntityException(__('logs with id "%1" does not exist.', $logsId)); + } + return $logs; + } + + /** + * @inheritDoc + */ + public function getList( + \Magento\Framework\Api\SearchCriteriaInterface $criteria + ) { + $collection = $this->logsCollectionFactory->create(); + + $this->collectionProcessor->process($criteria, $collection); + + $searchResults = $this->searchResultsFactory->create(); + $searchResults->setSearchCriteria($criteria); + + $items = []; + foreach ($collection as $model) { + $items[] = $model; + } + + $searchResults->setItems($items); + $searchResults->setTotalCount($collection->getSize()); + return $searchResults; + } + + /** + * @inheritDoc + */ + public function delete(LogsInterface $logs) + { + try { + $logsModel = $this->logsFactory->create(); + $this->resource->load($logsModel, $logs->getLogsId()); + $this->resource->delete($logsModel); + } catch (\Exception $exception) { + throw new CouldNotDeleteException(__( + 'Could not delete the logs: %1', + $exception->getMessage() + )); + } + return true; + } + + /** + * @inheritDoc + */ + public function deleteById($logsId) + { + return $this->delete($this->get($logsId)); + } +} diff --git a/Model/Magento/Sales/Model/Order/Payment.php b/Model/Magento/Sales/Model/Order/Payment.php index bbec0f53..207c7a8d 100644 --- a/Model/Magento/Sales/Model/Order/Payment.php +++ b/Model/Magento/Sales/Model/Order/Payment.php @@ -17,12 +17,12 @@ class Payment extends \Magento\Sales\Model\Order\Payment /** * @var Logger */ - protected $logger; + public $logger; /** * @var ScaEvaluation */ - protected $scaEvaluation; + public $scaEvaluation; /** * @param ProductMetadataInterface $productMetadataInterface diff --git a/Model/MappingVerificationFactory.php b/Model/MappingVerificationFactory.php index d2129251..43921f6c 100644 --- a/Model/MappingVerificationFactory.php +++ b/Model/MappingVerificationFactory.php @@ -13,26 +13,26 @@ class MappingVerificationFactory /** * @var ConfigInterface */ - protected $config; + public $config; /** * @var ObjectManagerInterface */ - protected $objectManager; + public $objectManager; /** * @var PaymentMethodMappingInterface */ - protected $paymentMethodDefaultAdapter; + public $paymentMethodDefaultAdapter; /** * @var ConfigHelper */ - protected $configHelper; + public $configHelper; /** * @param ObjectManagerInterface $objectManager - * @param ConfigInterface|Config $config + * @param ConfigInterface $config * @param PaymentMethodMappingInterface $paymentMethodDefaultAdapter * @param ConfigHelper $configHelper */ @@ -55,11 +55,11 @@ public function createPaymentMethod($paymentCode) /** * @param PaymentMethodMappingInterface $defaultAdapter - * @param string $paymentCode - * @param string $configKey + * @param $paymentCode + * @param $configKey * @return PaymentMethodMappingInterface - * @throws ConfigurationMismatchException If payment verification instance - * does not implement PaymentMethodMappingInterface. + * @throws LocalizedException If payment verification instance + * does not implement PaymentMethodMappingInterface. */ private function create(PaymentMethodMappingInterface $defaultAdapter, $paymentCode, $configKey) { diff --git a/Model/Message/BuiltinConflict.php b/Model/Message/BuiltinConflict.php index 13361e84..e1003c96 100644 --- a/Model/Message/BuiltinConflict.php +++ b/Model/Message/BuiltinConflict.php @@ -5,29 +5,38 @@ */ namespace Signifyd\Connect\Model\Message; -use Magento\Framework\App\ObjectManager; +use Magento\Framework\Module\Manager as ModuleManager; class BuiltinConflict implements \Magento\Framework\Notification\MessageInterface { /** * @var \Magento\Framework\App\Config\ScopeConfigInterface */ - protected $config; + public $config; /** * @var \Magento\Store\Model\StoreRepository */ - protected $storeRepository; + public $storeRepository; /** - * @param ScopeConfigInterface $config + * @var ModuleManager + */ + public $moduleManager; + + /** + * @param \Magento\Framework\App\Config\ScopeConfigInterface $config + * @param \Magento\Store\Model\StoreRepository $storeRepository + * @param ModuleManager $moduleManager */ public function __construct( \Magento\Framework\App\Config\ScopeConfigInterface $config, - \Magento\Store\Model\StoreRepository $storeRepository + \Magento\Store\Model\StoreRepository $storeRepository, + ModuleManager $moduleManager ) { $this->config = $config; $this->storeRepository = $storeRepository; + $this->moduleManager = $moduleManager; } /** @@ -37,9 +46,7 @@ public function __construct( */ public function isDisplayed() { - $objectManager = ObjectManager::getInstance(); - $moduleManager = $objectManager->get(\Magento\Framework\Module\Manager::class); - $isBuiltinModuleEnabled = $moduleManager->isOutputEnabled('Magento_Signifyd') ? true : false; + $isBuiltinModuleEnabled = $this->moduleManager->isEnabled('Magento_Signifyd'); if (!$isBuiltinModuleEnabled) { return false; diff --git a/Model/Payment/AdyenCc/AvsEmsCodeMapper.php b/Model/Payment/AdyenCc/AvsEmsCodeMapper.php index 718b34e9..ba8388ee 100644 --- a/Model/Payment/AdyenCc/AvsEmsCodeMapper.php +++ b/Model/Payment/AdyenCc/AvsEmsCodeMapper.php @@ -6,7 +6,7 @@ class AvsEmsCodeMapper extends Base_AvsEmsCodeMapper { - protected $allowedMethods = ['adyen_cc']; + public $allowedMethods = ['adyen_cc','adyen_pay_by_link']; /** * List of mapping AVS codes diff --git a/Model/Payment/AdyenCc/BinMapper.php b/Model/Payment/AdyenCc/BinMapper.php index 899912ce..600d2e10 100644 --- a/Model/Payment/AdyenCc/BinMapper.php +++ b/Model/Payment/AdyenCc/BinMapper.php @@ -6,7 +6,7 @@ class BinMapper extends Base_BinMapper { - protected $allowedMethods = ['adyen_cc']; + public $allowedMethods = ['adyen_cc','adyen_pay_by_link']; /** * @param \Magento\Sales\Model\Order $order diff --git a/Model/Payment/AdyenCc/CvvEmsCodeMapper.php b/Model/Payment/AdyenCc/CvvEmsCodeMapper.php index 9c2c110e..7f6b6d2e 100644 --- a/Model/Payment/AdyenCc/CvvEmsCodeMapper.php +++ b/Model/Payment/AdyenCc/CvvEmsCodeMapper.php @@ -6,7 +6,7 @@ class CvvEmsCodeMapper extends Base_CvvEmsCodeMapper { - protected $allowedMethods = ['adyen_cc']; + public $allowedMethods = ['adyen_cc','adyen_pay_by_link']; /** * List of mapping CVV codes @@ -24,7 +24,7 @@ class CvvEmsCodeMapper extends Base_CvvEmsCodeMapper /** * Gets payment CVV verification code. * - * @param \Magento\Sales\Api\Data\OrderPaymentInterface $orderPayment + * @param \Magento\Sales\Model\Order $order * @return string * @throws \InvalidArgumentException If specified order payment has different payment method code. */ diff --git a/Model/Payment/AdyenCc/ExpMonthMapper.php b/Model/Payment/AdyenCc/ExpMonthMapper.php index bf2e386d..7254cee1 100644 --- a/Model/Payment/AdyenCc/ExpMonthMapper.php +++ b/Model/Payment/AdyenCc/ExpMonthMapper.php @@ -6,7 +6,7 @@ class ExpMonthMapper extends Base_ExpMonthMapper { - protected $allowedMethods = ['adyen_cc']; + public $allowedMethods = ['adyen_cc','adyen_pay_by_link']; /** * @param \Magento\Sales\Model\Order $order diff --git a/Model/Payment/AdyenCc/ExpYearMapper.php b/Model/Payment/AdyenCc/ExpYearMapper.php index 935838a9..99a52345 100644 --- a/Model/Payment/AdyenCc/ExpYearMapper.php +++ b/Model/Payment/AdyenCc/ExpYearMapper.php @@ -6,7 +6,7 @@ class ExpYearMapper extends Base_ExpYearMapper { - protected $allowedMethods = ['adyen_cc']; + public $allowedMethods = ['adyen_cc','adyen_pay_by_link']; /** * @param \Magento\Sales\Model\Order $order diff --git a/Model/Payment/AdyenCc/Last4Mapper.php b/Model/Payment/AdyenCc/Last4Mapper.php index f320fb23..b3c5c240 100644 --- a/Model/Payment/AdyenCc/Last4Mapper.php +++ b/Model/Payment/AdyenCc/Last4Mapper.php @@ -6,7 +6,7 @@ class Last4Mapper extends Base_Last4Mapper { - protected $allowedMethods = ['adyen_cc']; + public $allowedMethods = ['adyen_cc','adyen_pay_by_link']; /** * @param \Magento\Sales\Model\Order $order diff --git a/Model/Payment/AdyenCc/TransactionIdMapper.php b/Model/Payment/AdyenCc/TransactionIdMapper.php index 69bc94d4..61582539 100644 --- a/Model/Payment/AdyenCc/TransactionIdMapper.php +++ b/Model/Payment/AdyenCc/TransactionIdMapper.php @@ -6,7 +6,7 @@ class TransactionIdMapper extends Base_TransactionIdMapper { - protected $allowedMethods = ['adyen_cc']; + public $allowedMethods = ['adyen_cc','adyen_pay_by_link']; /** * Get transaction ID from database for Authorize.Net diff --git a/Model/Api/CaseData/Transactions/PaymentMethod/AdyenHpp.php b/Model/Payment/AdyenHpp/PaymentMethodMapper.php similarity index 57% rename from Model/Api/CaseData/Transactions/PaymentMethod/AdyenHpp.php rename to Model/Payment/AdyenHpp/PaymentMethodMapper.php index 2a46b3d0..3dc8a10d 100644 --- a/Model/Api/CaseData/Transactions/PaymentMethod/AdyenHpp.php +++ b/Model/Payment/AdyenHpp/PaymentMethodMapper.php @@ -1,46 +1,46 @@ getPayment()->getAdditionalInformation('brand_code'); - return $this->adyenHppMapping($paymentBrandCode, $order->getPayment()->getMethod()); + return $this->adyenHppMapping($paymentBrandCode, $order); } /** - * @param Quote $entity + * @param Quote $quote * @return null */ public function getPaymentMethodFromQuote(Quote $quote) { $paymentBrandCode = $quote->getPayment()->getAdditionalInformation('brand_code'); - return $this->adyenHppMapping($paymentBrandCode, $quote->getPayment()->getMethod()); + return $this->adyenHppMapping($paymentBrandCode, $quote); } - public function adyenHppMapping($paymentBrandCode, $paymentMethod) + public function adyenHppMapping($paymentBrandCode, $entity) { + $paymentMethod = $entity->getPayment()->getMethod(); + if (is_string($paymentBrandCode) === false) { - $this->logger->info('Adyen Hpp method code not found'); + $this->logger->info('Adyen Hpp method code not found', ['entity' => $entity]); return $this->makePaymentMethod($paymentMethod); } - $this->logger->info( - 'Mapping for Adyen Hpp method code: ' . - $paymentBrandCode - ); + $this->logger->info('Mapping for Adyen Hpp method code: ' . $paymentBrandCode, ['entity' => $entity]); switch ($paymentBrandCode) { case 'googlepay': @@ -63,8 +63,16 @@ public function adyenHppMapping($paymentBrandCode, $paymentMethod) default: $method = $this->makePaymentMethod($paymentMethod); + + $message = 'Payment method found on base mapper: ' . (empty($method) ? 'false' : $method); + $this->logger->debug($message, ['entity' => $entity]); + + return $method; } + $message = 'Payment method found on payment mapper: ' . $method; + $this->logger->debug($message, ['entity' => $entity]); + return $method; } } diff --git a/Model/Payment/AdyenPayByLink/AsyncChecker.php b/Model/Payment/AdyenPayByLink/AsyncChecker.php new file mode 100644 index 00000000..b693689b --- /dev/null +++ b/Model/Payment/AdyenPayByLink/AsyncChecker.php @@ -0,0 +1,23 @@ +getPayment()->getMethod() === 'adyen_pay_by_link' && !$order->getPayment()->getCcTransId()) { + return false; + } + return parent::__invoke($order, $casedata); + } +} diff --git a/Model/Payment/AdyenPayByLink/PaymentMethodMapper.php b/Model/Payment/AdyenPayByLink/PaymentMethodMapper.php new file mode 100644 index 00000000..39790f70 --- /dev/null +++ b/Model/Payment/AdyenPayByLink/PaymentMethodMapper.php @@ -0,0 +1,78 @@ +getPayment()->getAdditionalInformation('payment_method'); + + return $this->adyenPayByLinkMapping($payByLinkMethod, $order); + } + + /** + * @param Quote $quote + * @return null + */ + public function getPaymentMethodFromQuote(Quote $quote) + { + $payByLinkMethod = $quote->getPayment()->getAdditionalInformation('payment_method'); + + return $this->adyenPayByLinkMapping($payByLinkMethod, $quote); + } + + public function adyenPayByLinkMapping($payByLinkMethod, $entity) + { + $paymentMethod = $entity->getPayment()->getMethod(); + + if (isset($payByLinkMethod) === false) { + $this->logger->info('Adyen Pay By Link method code not found', ['entity' => $entity]); + + return $this->makePaymentMethod($paymentMethod); + } + + $this->logger->info('Mapping for Adyen Pay By Link method code: ' . $payByLinkMethod, ['entity' => $entity]); + + if (strpos($payByLinkMethod, 'amazonpay') !== false) { + $method = 'AMAZON_PAYMENTS'; + } elseif (strpos($payByLinkMethod, 'googlepay') !== false) { + $method = 'GOOGLE_PAY'; + } elseif (strpos($payByLinkMethod, 'applepay') !== false) { + $method = 'APPLE_PAY'; + } elseif (strpos($payByLinkMethod, 'paypal') !== false) { + $method = 'PAYPAL_ACCOUNT'; + } elseif (strpos($payByLinkMethod, 'debit') !== false) { + $method = 'DEBIT_CARD'; + } elseif (strpos($payByLinkMethod, 'credit') !== false || in_array($payByLinkMethod, $this->creditCard)) { + $method = 'CREDIT_CARD'; + } elseif (strpos($payByLinkMethod, 'prepaid') !== false) { + $method = 'PREPAID_CARD'; + } else { + $method = $this->makePaymentMethod($paymentMethod); + + $message = 'Payment method found on base mapper: ' . (empty($method) ? 'false' : $method); + $this->logger->debug($message, ['entity' => $entity]); + + return $method; + } + + $message = 'Payment method found on payment mapper: ' . $method; + $this->logger->debug($message, ['entity' => $entity]); + + return $method; + } +} diff --git a/Model/Payment/Authorizenet/CvvEmsCodeMapper.php b/Model/Payment/Authorizenet/CvvEmsCodeMapper.php index e04aafa9..0ca14a81 100644 --- a/Model/Payment/Authorizenet/CvvEmsCodeMapper.php +++ b/Model/Payment/Authorizenet/CvvEmsCodeMapper.php @@ -6,7 +6,7 @@ class CvvEmsCodeMapper extends Base_CvvEmsCodeMapper { - protected $allowedMethods = ['authorizenet_directpost']; + public $allowedMethods = ['authorizenet_directpost']; /** * Gets payment CVV verification code. diff --git a/Model/Payment/Authorizenet/ExpMonthMapper.php b/Model/Payment/Authorizenet/ExpMonthMapper.php index ec7c58e8..bee7c7b5 100644 --- a/Model/Payment/Authorizenet/ExpMonthMapper.php +++ b/Model/Payment/Authorizenet/ExpMonthMapper.php @@ -6,7 +6,7 @@ class ExpMonthMapper extends Base_ExpMonthMapper { - protected $allowedMethods = ['authorizenet_directpost']; + public $allowedMethods = ['authorizenet_directpost']; /** * Gets expiry month from XML response from Authorize.net diff --git a/Model/Payment/Authorizenet/ExpYearMapper.php b/Model/Payment/Authorizenet/ExpYearMapper.php index 830c18cb..e8b7b88c 100644 --- a/Model/Payment/Authorizenet/ExpYearMapper.php +++ b/Model/Payment/Authorizenet/ExpYearMapper.php @@ -6,7 +6,7 @@ class ExpYearMapper extends Base_ExpYearMapper { - protected $allowedMethods = ['authorizenet_directpost']; + public $allowedMethods = ['authorizenet_directpost']; /** * Gets expiry year from XML response from Authorize.net diff --git a/Model/Payment/Authorizenet/Last4Mapper.php b/Model/Payment/Authorizenet/Last4Mapper.php index 7ecbdf24..8880ad4a 100644 --- a/Model/Payment/Authorizenet/Last4Mapper.php +++ b/Model/Payment/Authorizenet/Last4Mapper.php @@ -6,7 +6,7 @@ class Last4Mapper extends Base_Last4Mapper { - protected $allowedMethods = ['authorizenet_directpost']; + public $allowedMethods = ['authorizenet_directpost']; /** * Gets last 4 credit card digits from XML response from Authorize.net diff --git a/Model/Payment/Authorizenet/TransactionIdMapper.php b/Model/Payment/Authorizenet/TransactionIdMapper.php index 831594d1..926f4e48 100644 --- a/Model/Payment/Authorizenet/TransactionIdMapper.php +++ b/Model/Payment/Authorizenet/TransactionIdMapper.php @@ -6,7 +6,7 @@ class TransactionIdMapper extends Base_TransactionIdMapper { - protected $allowedMethods = ['authorizenet_directpost']; + public $allowedMethods = ['authorizenet_directpost']; /** * Get transaction ID from database for Authorize.Net diff --git a/Model/Payment/Base/AsyncChecker.php b/Model/Payment/Base/AsyncChecker.php new file mode 100644 index 00000000..ebdc72a0 --- /dev/null +++ b/Model/Payment/Base/AsyncChecker.php @@ -0,0 +1,62 @@ +logger = $logger; + $this->saleOrderFactory = $saleOrderFactory; + } + + /** + * @param Order $order + * @param Casedata $case + * @return bool|void + */ + public function __invoke(Order $order, Casedata $case) + { + try { + $order->setData('origin_store_code', $case->getData('origin_store_code')); + $saleOrder = $this->saleOrderFactory->create(); + $caseModel = $saleOrder($order); + $avsCode = $caseModel['transactions'][0]['verifications']['avsResponseCode']; + $cvvCode = $caseModel['transactions'][0]['verifications']['cvvResponseCode']; + $retries = $case->getData('retries'); + + if ($retries >= 5 || empty($avsCode) === false && empty($cvvCode) === false) { + return true; + } else { + return false; + } + } catch (\Exception $e) { + $this->logger->error( + "There was a problem loading the order." + . $e->getMessage() + ); + } + } +} diff --git a/Model/Payment/Base/AvsEmsCodeMapper.php b/Model/Payment/Base/AvsEmsCodeMapper.php index 6240c04c..3eb9d40e 100644 --- a/Model/Payment/Base/AvsEmsCodeMapper.php +++ b/Model/Payment/Base/AvsEmsCodeMapper.php @@ -11,7 +11,7 @@ class AvsEmsCodeMapper extends DataMapper * * @var array */ - protected $validAvsResponseCodes = [ + public $validAvsResponseCodes = [ 'X', 'Y', 'A', 'W', 'Z', 'N', 'U', 'R', 'E', 'S', 'D', 'M', 'B', 'P', 'C', 'I', 'G' ]; diff --git a/Model/Payment/Base/CvvEmsCodeMapper.php b/Model/Payment/Base/CvvEmsCodeMapper.php index a2db7864..0ac2bc42 100644 --- a/Model/Payment/Base/CvvEmsCodeMapper.php +++ b/Model/Payment/Base/CvvEmsCodeMapper.php @@ -11,7 +11,7 @@ class CvvEmsCodeMapper extends DataMapper * * @var array */ - protected $validCvvResponseCodes = ['M', 'N', 'P', 'S', 'U']; + public $validCvvResponseCodes = ['M', 'N', 'P', 'S', 'U']; /** * Gets payment CVV verification code. diff --git a/Model/Api/CaseData/Transactions/PaymentMethod/Base.php b/Model/Payment/Base/PaymentMethodBase.php similarity index 88% rename from Model/Api/CaseData/Transactions/PaymentMethod/Base.php rename to Model/Payment/Base/PaymentMethodBase.php index a95477b3..a140b61d 100644 --- a/Model/Api/CaseData/Transactions/PaymentMethod/Base.php +++ b/Model/Payment/Base/PaymentMethodBase.php @@ -1,6 +1,6 @@ makePaymentMethod($order->getPayment()->getMethod()); + + $message = 'Payment method found on base mapper: ' . (empty($paymentMethod) ? 'false' : $paymentMethod); + $this->logger->debug($message, ['entity' => $order]); + + return $paymentMethod; + } + + /** + * @param Quote $quote + * @return int|string + */ + public function getPaymentMethodFromQuote(Quote $quote) + { + $paymentMethod = $this->makePaymentMethod($quote->getPayment()->getMethod()); + + $message = 'Payment method found on base mapper: ' . (empty($paymentMethod) ? 'false' : $paymentMethod); + $this->logger->debug($message, ['entity' => $quote]); + + return $paymentMethod; + } +} diff --git a/Model/Payment/Braintree/AvsEmsCodeMapper.php b/Model/Payment/Braintree/AvsEmsCodeMapper.php index ad42a98b..0cbd486a 100644 --- a/Model/Payment/Braintree/AvsEmsCodeMapper.php +++ b/Model/Payment/Braintree/AvsEmsCodeMapper.php @@ -17,7 +17,7 @@ */ class AvsEmsCodeMapper extends Base_AvsEmsCodeMapper { - protected $allowedMethods = ['braintree']; + public $allowedMethods = ['braintree']; /** * List of mapping AVS codes diff --git a/Model/Payment/Braintree/CvvEmsCodeMapper.php b/Model/Payment/Braintree/CvvEmsCodeMapper.php index a40d04b0..c2eb7889 100644 --- a/Model/Payment/Braintree/CvvEmsCodeMapper.php +++ b/Model/Payment/Braintree/CvvEmsCodeMapper.php @@ -17,7 +17,7 @@ */ class CvvEmsCodeMapper extends Base_CvvEmsCodeMapper { - protected $allowedMethods = ['braintree']; + public $allowedMethods = ['braintree']; /** * List of mapping CVV codes @@ -37,7 +37,7 @@ class CvvEmsCodeMapper extends Base_CvvEmsCodeMapper /** * Gets payment CVV verification code. * - * @param \Magento\Sales\Api\Data\OrderPaymentInterface $orderPayment + * @param \Magento\Sales\Model\Order $order * @return string * @throws \InvalidArgumentException If specified order payment has different payment method code. */ diff --git a/Model/Payment/Cybersource/AvsEmsCodeMapper.php b/Model/Payment/Cybersource/AvsEmsCodeMapper.php index 781c5274..cfb9aed6 100644 --- a/Model/Payment/Cybersource/AvsEmsCodeMapper.php +++ b/Model/Payment/Cybersource/AvsEmsCodeMapper.php @@ -6,7 +6,7 @@ class AvsEmsCodeMapper extends Base_AvsEmsCodeMapper { - protected $allowedMethods = ['cybersource', 'chcybersource']; + public $allowedMethods = ['cybersource', 'chcybersource']; /** * List of mapping AVS codes @@ -45,6 +45,10 @@ public function getPaymentData(\Magento\Sales\Model\Order $order) isset($apiResponse['ccAuthReply']->avsCode) ) { $avsStatus = $apiResponse['ccAuthReply']->avsCode; + } elseif (is_array($apiResponse) && + isset($apiResponse['auth_avs_code']) + ) { + $avsStatus = $apiResponse['auth_avs_code']; } $message = 'AVS found on payment mapper: ' . (empty($avsStatus) ? 'false' : $avsStatus); diff --git a/Model/Payment/Cybersource/BinMapper.php b/Model/Payment/Cybersource/BinMapper.php index b29baf2d..2e63719e 100644 --- a/Model/Payment/Cybersource/BinMapper.php +++ b/Model/Payment/Cybersource/BinMapper.php @@ -6,7 +6,7 @@ class BinMapper extends Base_BinMapper { - protected $allowedMethods = ['cybersource', 'chcybersource']; + public $allowedMethods = ['cybersource', 'chcybersource']; /** * @param \Magento\Sales\Model\Order $order diff --git a/Model/Payment/Cybersource/CvvEmsCodeMapper.php b/Model/Payment/Cybersource/CvvEmsCodeMapper.php index 68f33cc6..6d0ac359 100644 --- a/Model/Payment/Cybersource/CvvEmsCodeMapper.php +++ b/Model/Payment/Cybersource/CvvEmsCodeMapper.php @@ -6,7 +6,7 @@ class CvvEmsCodeMapper extends Base_CvvEmsCodeMapper { - protected $allowedMethods = ['cybersource']; + public $allowedMethods = ['cybersource', 'chcybersource']; /** * List of mapping CVV codes @@ -25,7 +25,7 @@ class CvvEmsCodeMapper extends Base_CvvEmsCodeMapper /** * Gets payment CVV verification code. * - * @param \Magento\Sales\Api\Data\OrderPaymentInterface $orderPayment + * @param \Magento\Sales\Model\Order $order * @return string * @throws \InvalidArgumentException If specified order payment has different payment method code. */ @@ -34,9 +34,9 @@ public function getPaymentData(\Magento\Sales\Model\Order $order) $additionalInfo = $order->getPayment()->getAdditionalInformation(); if (isset($additionalInfo['auth_cv_result']) && - isset(self::$avsMap[$additionalInfo['auth_cv_result']]) && - $this->validate(self::$avsMap[$additionalInfo['auth_cv_result']])) { - $cvvStatus = self::$avsMap[$additionalInfo['auth_cv_result']]; + isset(self::$cvvMap[$additionalInfo['auth_cv_result']]) && + $this->validate(self::$cvvMap[$additionalInfo['auth_cv_result']])) { + $cvvStatus = self::$cvvMap[$additionalInfo['auth_cv_result']]; } $message = 'CVV found on payment mapper: ' . (empty($cvvStatus) ? 'false' : $cvvStatus); diff --git a/Model/Payment/Cybersource/ExpMonthMapper.php b/Model/Payment/Cybersource/ExpMonthMapper.php index a51c0c08..c20e8867 100644 --- a/Model/Payment/Cybersource/ExpMonthMapper.php +++ b/Model/Payment/Cybersource/ExpMonthMapper.php @@ -6,7 +6,7 @@ class ExpMonthMapper extends Base_ExpMonthMapper { - protected $allowedMethods = ['cybersource']; + public $allowedMethods = ['cybersource', 'chcybersource']; /** * @param \Magento\Sales\Model\Order $order @@ -15,13 +15,19 @@ class ExpMonthMapper extends Base_ExpMonthMapper public function getPaymentData(\Magento\Sales\Model\Order $order) { $additionalInfo = $order->getPayment()->getAdditionalInformation(); + $apiResponse = $this->getSignifydPaymentData(); + $expiryDate = []; - if (isset($additionalInfo['card_expiry_date']) && empty($additionalInfo['card_expiry_date']) == false) { + if (isset($additionalInfo['card_expiry_date'])) { $expiryDate = explode("-", $additionalInfo['card_expiry_date']); + } elseif (is_array($apiResponse) && + isset($apiResponse['req_card_expiry_date']) + ) { + $expiryDate = explode("-", $apiResponse['req_card_expiry_date']); + } - if (isset($expiryDate[0])) { - $expMonth = $expiryDate[0]; - } + if (isset($expiryDate[0])) { + $expMonth = $expiryDate[0]; } $message = 'Expiry month found on payment mapper: ' . (empty($expMonth) ? 'false' : $expMonth); diff --git a/Model/Payment/Cybersource/ExpYearMapper.php b/Model/Payment/Cybersource/ExpYearMapper.php index c466e983..dc576b8c 100644 --- a/Model/Payment/Cybersource/ExpYearMapper.php +++ b/Model/Payment/Cybersource/ExpYearMapper.php @@ -6,7 +6,7 @@ class ExpYearMapper extends Base_ExpYearMapper { - protected $allowedMethods = ['cybersource']; + public $allowedMethods = ['cybersource', 'chcybersource']; /** * @param \Magento\Sales\Model\Order $order @@ -15,13 +15,19 @@ class ExpYearMapper extends Base_ExpYearMapper public function getPaymentData(\Magento\Sales\Model\Order $order) { $additionalInfo = $order->getPayment()->getAdditionalInformation(); + $apiResponse = $this->getSignifydPaymentData(); + $expiryDate = []; if (isset($additionalInfo['card_expiry_date']) && empty($additionalInfo['card_expiry_date']) == false) { $expiryDate = explode("-", $additionalInfo['card_expiry_date']); + } elseif (is_array($apiResponse) && + isset($apiResponse['req_card_expiry_date']) + ) { + $expiryDate = explode("-", $apiResponse['req_card_expiry_date']); + } - if (isset($expiryDate[1])) { - $expYear = $expiryDate[1]; - } + if (isset($expiryDate[1])) { + $expYear = $expiryDate[1]; } $message = 'Expiry year found on payment mapper: ' . (empty($expYear) ? 'false' : $expYear); diff --git a/Model/Payment/Cybersource/Last4Mapper.php b/Model/Payment/Cybersource/Last4Mapper.php index 7c072c25..a2d9e0eb 100644 --- a/Model/Payment/Cybersource/Last4Mapper.php +++ b/Model/Payment/Cybersource/Last4Mapper.php @@ -6,7 +6,7 @@ class Last4Mapper extends Base_Last4Mapper { - protected $allowedMethods = ['cybersource']; + public $allowedMethods = ['cybersource', 'chcybersource']; /** * @param \Magento\Sales\Model\Order $order @@ -15,11 +15,16 @@ class Last4Mapper extends Base_Last4Mapper public function getPaymentData(\Magento\Sales\Model\Order $order) { $additionalInfo = $order->getPayment()->getAdditionalInformation(); + $apiResponse = $this->getSignifydPaymentData(); if (isset($additionalInfo['card_number']) && empty($additionalInfo['card_number']) === false && strlen($additionalInfo['card_number']) === 4) { $last4 = $additionalInfo['card_number']; + } elseif (is_array($apiResponse) && + isset($apiResponse['req_card_number']) + ) { + $last4 = substr($apiResponse['req_card_number'], -4); } $message = 'Last4 found on payment mapper: ' . (empty($last4) ? 'false' : 'true'); diff --git a/Model/Payment/Cybersource/TransactionIdMapper.php b/Model/Payment/Cybersource/TransactionIdMapper.php index 28995afe..8cd4de6e 100644 --- a/Model/Payment/Cybersource/TransactionIdMapper.php +++ b/Model/Payment/Cybersource/TransactionIdMapper.php @@ -6,7 +6,7 @@ class TransactionIdMapper extends Base_TransactionIdMapper { - protected $allowedMethods = ['cybersource']; + public $allowedMethods = ['cybersource', 'chcybersource']; /** * Get transaction ID from database for Authorize.Net @@ -17,9 +17,14 @@ class TransactionIdMapper extends Base_TransactionIdMapper public function getPaymentData(\Magento\Sales\Model\Order $order) { $additionalInfo = $order->getPayment()->getAdditionalInformation(); + $apiResponse = $this->getSignifydPaymentData(); if (isset($additionalInfo['transaction_id']) && empty($additionalInfo['transaction_id']) === false) { $transactionId = $additionalInfo['transaction_id']; + } elseif (is_array($apiResponse) && + isset($apiResponse['transaction_id']) + ) { + $transactionId = $apiResponse['transaction_id']; } $message = 'Transaction ID found on payment mapper: ' . (empty($transactionId) ? 'false' : $transactionId); diff --git a/Model/Payment/DataMapper.php b/Model/Payment/DataMapper.php index 2616f9ff..7f5442e2 100644 --- a/Model/Payment/DataMapper.php +++ b/Model/Payment/DataMapper.php @@ -4,56 +4,62 @@ use Adyen\Config; use Magento\Framework\ObjectManagerInterface; -use Magento\Framework\Registry; +use Signifyd\Connect\Model\Registry; use Magento\Framework\Serialize\Serializer\Json as JsonSerializer; use Signifyd\Connect\Api\PaymentVerificationInterface; use Signifyd\Connect\Logger\Logger; use Signifyd\Connect\Model\PaymentGatewayFactory; use Signifyd\Connect\Helper\ConfigHelper; +use Magento\Framework\Encryption\EncryptorInterface; abstract class DataMapper implements PaymentVerificationInterface { /** * @var Registry */ - protected $registry; + public $registry; /** * @var JsonSerializer */ - protected $jsonSerializer; + public $jsonSerializer; /** * @var PaymentGatewayFactory */ - protected $paymentGatewayFactory; + public $paymentGatewayFactory; /** * List of payment methods codes * @var array */ - protected $allowedMethods = []; + public $allowedMethods = []; /** * Flag to prevent accidental loop for getCode/getData calls * @var bool */ - protected $getDataCalled = false; + public $getDataCalled = false; /** * @var Logger */ - protected $logger; + public $logger; /** * @var ConfigHelper */ - protected $configHelper; + public $configHelper; /** * @var ObjectManagerInterface */ - protected $objectManagerInterface; + public $objectManagerInterface; + + /** + * @var EncryptorInterface + */ + public $encryptor; /** * DataMapper constructor. @@ -63,6 +69,7 @@ abstract class DataMapper implements PaymentVerificationInterface * @param Logger $logger * @param ConfigHelper $configHelper * @param ObjectManagerInterface $objectManagerInterface + * @param EncryptorInterface $encryptor */ public function __construct( Registry $registry, @@ -70,7 +77,8 @@ public function __construct( PaymentGatewayFactory $paymentGatewayFactory, Logger $logger, ConfigHelper $configHelper, - ObjectManagerInterface $objectManagerInterface + ObjectManagerInterface $objectManagerInterface, + \Magento\Framework\Encryption\EncryptorInterface $encryptor ) { $this->registry = $registry; $this->jsonSerializer = $jsonSerializer; @@ -78,15 +86,16 @@ public function __construct( $this->logger = $logger; $this->configHelper = $configHelper; $this->objectManagerInterface = $objectManagerInterface; + $this->encryptor = $encryptor; } /** - * @param null $key + * @param $key * @return bool|mixed */ public function getSignifydPaymentData($key = null) { - $paymentData = $this->registry->registry('signifyd_payment_data'); + $paymentData = $this->registry->getData('signifyd_payment_data'); if (empty($key)) { return $paymentData; @@ -138,7 +147,7 @@ public function getCode(\Magento\Sales\Model\Order $order) * on extending classes * * @param \Magento\Sales\Model\Order $order - * @return string + * @return mixed */ public function getData(\Magento\Sales\Model\Order $order) { @@ -168,7 +177,7 @@ public function getData(\Magento\Sales\Model\Order $order) /** * @param \Magento\Sales\Model\Order $order - * @return false|stdClass + * @return array|bool|float|int|mixed|string */ public function getGatewayIntegrationSettings(\Magento\Sales\Model\Order $order) { @@ -180,7 +189,6 @@ public function getGatewayIntegrationSettings(\Magento\Sales\Model\Order $order) if (empty($gatewayIntegrationSettings) === false) { try { - /** @var stdClass $gatewayIntegrationSettings */ $gatewayIntegrationSettings = $this->jsonSerializer->unserialize($gatewayIntegrationSettings); $this->logger->info($this->jsonSerializer->serialize($gatewayIntegrationSettings)); } catch (\InvalidArgumentException $e) { @@ -231,6 +239,12 @@ public function getGatewayIntegrationSettings(\Magento\Sales\Model\Order $order) $order ); break; + case 'path_secure': + $gatewayIntegrationSettings['params'][$key] = $this->encryptor->decrypt($this->configHelper->getConfigData( + $param['path'], + $order + )); + break; } } diff --git a/Model/Payment/Payflow/Link/AvsEmsCodeMapper.php b/Model/Payment/Payflow/Link/AvsEmsCodeMapper.php index b4657e9f..ed499ead 100644 --- a/Model/Payment/Payflow/Link/AvsEmsCodeMapper.php +++ b/Model/Payment/Payflow/Link/AvsEmsCodeMapper.php @@ -6,7 +6,7 @@ class AvsEmsCodeMapper extends Base_AvsEmsCodeMapper { - protected $allowedMethods = ['payflow_link', 'payflow_advanced']; + public $allowedMethods = ['payflow_link', 'payflow_advanced']; /** * Gets payment AVS verification code. diff --git a/Model/Payment/Payflow/Link/CvvEmsCodeMapper.php b/Model/Payment/Payflow/Link/CvvEmsCodeMapper.php index 8ea21e6e..4dd1251c 100644 --- a/Model/Payment/Payflow/Link/CvvEmsCodeMapper.php +++ b/Model/Payment/Payflow/Link/CvvEmsCodeMapper.php @@ -6,7 +6,7 @@ class CvvEmsCodeMapper extends Base_CvvEmsCodeMapper { - protected $allowedMethods = ['payflow_link', 'payflow_advanced']; + public $allowedMethods = ['payflow_link', 'payflow_advanced']; /** * Gets payment CVV verification code. diff --git a/Model/Payment/Payflow/Link/ExpMonthMapper.php b/Model/Payment/Payflow/Link/ExpMonthMapper.php index f441895e..ffcce2ed 100644 --- a/Model/Payment/Payflow/Link/ExpMonthMapper.php +++ b/Model/Payment/Payflow/Link/ExpMonthMapper.php @@ -6,7 +6,7 @@ class ExpMonthMapper extends Base_ExpMonthMapper { - protected $allowedMethods = ['payflow_link', 'payflow_advanced']; + public $allowedMethods = ['payflow_link', 'payflow_advanced']; /** * Gets expiry month from Payflow response diff --git a/Model/Payment/Payflow/Link/ExpYearMapper.php b/Model/Payment/Payflow/Link/ExpYearMapper.php index ffefe4e5..91723f4a 100644 --- a/Model/Payment/Payflow/Link/ExpYearMapper.php +++ b/Model/Payment/Payflow/Link/ExpYearMapper.php @@ -6,7 +6,7 @@ class ExpYearMapper extends Base_ExpYearMapper { - protected $allowedMethods = ['payflow_link', 'payflow_advanced']; + public $allowedMethods = ['payflow_link', 'payflow_advanced']; /** * Gets expiry year from Payflow response diff --git a/Model/Payment/Payflow/Link/Last4Mapper.php b/Model/Payment/Payflow/Link/Last4Mapper.php index e9ad1a94..304be8e9 100644 --- a/Model/Payment/Payflow/Link/Last4Mapper.php +++ b/Model/Payment/Payflow/Link/Last4Mapper.php @@ -6,7 +6,7 @@ class Last4Mapper extends Base_Last4Mapper { - protected $allowedMethods = ['payflow_link', 'payflow_advanced']; + public $allowedMethods = ['payflow_link', 'payflow_advanced']; /** * Gets last 4 credit card digits from Payflow response diff --git a/Model/Payment/Payflow/Link/TransactionIdMapper.php b/Model/Payment/Payflow/Link/TransactionIdMapper.php index ed4fb6e7..59a902ec 100644 --- a/Model/Payment/Payflow/Link/TransactionIdMapper.php +++ b/Model/Payment/Payflow/Link/TransactionIdMapper.php @@ -6,7 +6,7 @@ class TransactionIdMapper extends Base_TransactionIdMapper { - protected $allowedMethods = ['payflow_link', 'payflow_advanced']; + public $allowedMethods = ['payflow_link', 'payflow_advanced']; /** * Gets transaction ID from Payflow response diff --git a/Model/Payment/Payflow/Pro/AvsEmsCodeMapper.php b/Model/Payment/Payflow/Pro/AvsEmsCodeMapper.php index 0ec34182..12b595b3 100644 --- a/Model/Payment/Payflow/Pro/AvsEmsCodeMapper.php +++ b/Model/Payment/Payflow/Pro/AvsEmsCodeMapper.php @@ -6,7 +6,7 @@ class AvsEmsCodeMapper extends Base_AvsEmsCodeMapper { - protected $allowedMethods = ['payflowpro']; + public $allowedMethods = ['payflowpro']; /** * List of mapping AVS codes diff --git a/Model/Payment/Payflow/Pro/CvvEmsCodeMapper.php b/Model/Payment/Payflow/Pro/CvvEmsCodeMapper.php index 265c4c27..f8272b3e 100644 --- a/Model/Payment/Payflow/Pro/CvvEmsCodeMapper.php +++ b/Model/Payment/Payflow/Pro/CvvEmsCodeMapper.php @@ -6,7 +6,7 @@ class CvvEmsCodeMapper extends Base_CvvEmsCodeMapper { - protected $allowedMethods = ['payflowpro']; + public $allowedMethods = ['payflowpro']; /** * List of mapping CVV codes diff --git a/Model/Payment/PaymentServicesPaypal/AvsEmsCodeMapper.php b/Model/Payment/PaymentServicesPaypal/AvsEmsCodeMapper.php new file mode 100644 index 00000000..7bb47c42 --- /dev/null +++ b/Model/Payment/PaymentServicesPaypal/AvsEmsCodeMapper.php @@ -0,0 +1,63 @@ + 'A', + 'B' => 'B', + 'C' => 'I', + 'D' => 'D', + 'E' => 'S', + 'F' => 'M', + 'G' => 'G', + 'I' => 'G', + 'M' => 'Y', + 'N' => 'N', + 'P' => 'P', + 'R' => 'R', + 'S' => 'S', + 'U' => 'U', + 'W' => 'W', + 'X' => 'X', + 'Y' => 'Y', + 'Z' => 'Z' + ]; + + /** + * Gets payment AVS verification code. + * + * @param \Magento\Sales\Model\Order $order + * @return string + * @throws \InvalidArgumentException If specified order payment has different payment method code. + */ + public function getPaymentData(\Magento\Sales\Model\Order $order) + { + $avsStatus = $order->getPayment()->getCcAvsStatus(); + + if (isset($avsStatus)) { + if (in_array($avsStatus, array_keys(self::$avsMap))) { + $avsStatus = self::$avsMap[$avsStatus]; + } else { + $avsStatus = 'E'; + } + + $message = 'AVS found on payment mapper: ' . (empty($avsStatus) ? 'false' : $avsStatus); + $this->logger->debug($message, ['entity' => $order]); + } else { + $avsStatus = parent::getPaymentData($order); + } + + return $avsStatus; + } +} diff --git a/Model/Payment/PaymentServicesPaypal/CvvEmsCodeMapper.php b/Model/Payment/PaymentServicesPaypal/CvvEmsCodeMapper.php new file mode 100644 index 00000000..370c2071 --- /dev/null +++ b/Model/Payment/PaymentServicesPaypal/CvvEmsCodeMapper.php @@ -0,0 +1,53 @@ + 'E', + 'I' => 'I', + 'M' => 'M', + 'N' => 'N', + 'P' => 'P', + 'S' => 'N', + 'U' => 'U', + 'X' => 'X' + ]; + + /** + * Gets payment CVV verification code. + * + * @param \Magento\Sales\Model\Order $order + * @return string + * @throws \InvalidArgumentException If specified order payment has different payment method code. + */ + public function getPaymentData(\Magento\Sales\Model\Order $order) + { + $cvvStatus = $order->getPayment()->getCcCidStatus(); + + if (isset($cvvStatus)) { + if (in_array($cvvStatus, array_keys(self::$cvvMap))) { + $cvvStatus = self::$cvvMap[$cvvStatus]; + } else { + $cvvStatus = null; + } + + $message = 'CVV found on payment mapper: ' . (empty($cvvStatus) ? 'false' : $cvvStatus); + $this->logger->debug($message, ['entity' => $order]); + } else { + $cvvStatus = parent::getPaymentData($order); + } + + return $cvvStatus; + } +} diff --git a/Model/Payment/PaymentServicesPaypal/TransactionIdMapper.php b/Model/Payment/PaymentServicesPaypal/TransactionIdMapper.php new file mode 100644 index 00000000..4b99b549 --- /dev/null +++ b/Model/Payment/PaymentServicesPaypal/TransactionIdMapper.php @@ -0,0 +1,30 @@ +getPayment()->getAdditionalInformation('paypal_txn_id'); + + $message = 'Transaction id found on payment mapper: ' . (empty($transactionId) ? 'false' : $transactionId); + $this->logger->debug($message, ['entity' => $order]); + + if (empty($transactionId)) { + $transactionId = parent::getPaymentData($order); + } + + return $transactionId; + } +} diff --git a/Model/Payment/RootwaysAuthorizecimOption/AvsEmsCodeMapper.php b/Model/Payment/RootwaysAuthorizecimOption/AvsEmsCodeMapper.php new file mode 100644 index 00000000..5b0b1d33 --- /dev/null +++ b/Model/Payment/RootwaysAuthorizecimOption/AvsEmsCodeMapper.php @@ -0,0 +1,41 @@ +getPayment()->getAdditionalInformation(); + $avsStatus = null; + + if (empty($additionalInfo['avs_response_code']) == false) { + $avsStatus = $additionalInfo['avs_response_code']; + if ($avsStatus == 'B') { + $avsStatus = 'U'; + } + } + + if ($this->validate($avsStatus) == false) { + $avsStatus = null; + } + + $message = 'AVS found on payment mapper: ' . (empty($avsStatus) ? 'false' : $avsStatus); + $this->logger->debug($message, ['entity' => $order]); + + if (empty($avsStatus)) { + $avsStatus = parent::getPaymentData($order); + } + return $avsStatus; + } +} diff --git a/Model/Payment/RootwaysAuthorizecimOption/BinMapper.php b/Model/Payment/RootwaysAuthorizecimOption/BinMapper.php new file mode 100644 index 00000000..347334f0 --- /dev/null +++ b/Model/Payment/RootwaysAuthorizecimOption/BinMapper.php @@ -0,0 +1,33 @@ +getPayment()->getAdditionalInformation(); + + $bin = null; + if (isset($additionalInfo['card_bin'])) { + $bin = $additionalInfo['card_bin']; + } + + $message = 'Bin found on payment mapper: ' . (empty($bin) ? 'false' : 'true'); + $this->logger->debug($message, ['entity' => $order]); + + if (empty($bin)) { + $bin = parent::getPaymentData($order); + } + + return $bin; + } +} diff --git a/Model/Payment/Stripe/Payments/AsyncChecker.php b/Model/Payment/Stripe/Payments/AsyncChecker.php new file mode 100644 index 00000000..632dbc08 --- /dev/null +++ b/Model/Payment/Stripe/Payments/AsyncChecker.php @@ -0,0 +1,30 @@ +getOrder()->getPayment()->getMethod() === 'stripe_payments' && + $case->getEntries('stripe_status') !== 'approved' + ) { + $this->logger->info( + "CRON: case no: {$case->getOrderIncrement()}" . + " will not be sent because the stripe hasn't approved it yet", + ['entity' => $case] + ); + return false; + } + return true; + } +} diff --git a/Model/Payment/Stripe/Payments/AvsEmsCodeMapper.php b/Model/Payment/Stripe/Payments/AvsEmsCodeMapper.php index 255e34d6..530ab120 100644 --- a/Model/Payment/Stripe/Payments/AvsEmsCodeMapper.php +++ b/Model/Payment/Stripe/Payments/AvsEmsCodeMapper.php @@ -8,7 +8,7 @@ class AvsEmsCodeMapper extends Base_AvsEmsCodeMapper { use MapperTrait; - protected $allowedMethods = ['stripe_payments']; + public $allowedMethods = ['stripe_payments']; /** * List of mapping AVS codes @@ -17,7 +17,7 @@ class AvsEmsCodeMapper extends Base_AvsEmsCodeMapper * * @var array */ - protected $avsMap = [ + public $avsMap = [ 'pass_pass' => 'Y', 'pass_fail' => 'A', 'fail_pass' => 'Z', diff --git a/Model/Payment/Stripe/Payments/CvvEmsCodeMapper.php b/Model/Payment/Stripe/Payments/CvvEmsCodeMapper.php index 6de9a922..f30edfc7 100644 --- a/Model/Payment/Stripe/Payments/CvvEmsCodeMapper.php +++ b/Model/Payment/Stripe/Payments/CvvEmsCodeMapper.php @@ -8,7 +8,7 @@ class CvvEmsCodeMapper extends Base_CvvEmsCodeMapper { use MapperTrait; - protected $allowedMethods = ['stripe_payments']; + public $allowedMethods = ['stripe_payments']; /** * List of mapping CVV codes @@ -17,7 +17,7 @@ class CvvEmsCodeMapper extends Base_CvvEmsCodeMapper * * @var array */ - protected $cvvMap = [ + public $cvvMap = [ 'pass' => 'M', 'fail' => 'N', 'unchecked' => 'P' diff --git a/Model/Payment/Stripe/Payments/ExpMonthMapper.php b/Model/Payment/Stripe/Payments/ExpMonthMapper.php index e1a4e04f..b0c6cf67 100644 --- a/Model/Payment/Stripe/Payments/ExpMonthMapper.php +++ b/Model/Payment/Stripe/Payments/ExpMonthMapper.php @@ -8,7 +8,7 @@ class ExpMonthMapper extends Base_ExpMonthMapper { use MapperTrait; - protected $allowedMethods = ['stripe_payments']; + public $allowedMethods = ['stripe_payments']; /** * Gets expiry month diff --git a/Model/Payment/Stripe/Payments/ExpYearMapper.php b/Model/Payment/Stripe/Payments/ExpYearMapper.php index 361e2364..46d0bd33 100644 --- a/Model/Payment/Stripe/Payments/ExpYearMapper.php +++ b/Model/Payment/Stripe/Payments/ExpYearMapper.php @@ -8,7 +8,7 @@ class ExpYearMapper extends Base_ExpYearMapper { use MapperTrait; - protected $allowedMethods = ['stripe_payments']; + public $allowedMethods = ['stripe_payments']; /** * Gets expiry year diff --git a/Model/Payment/Stripe/Payments/Last4Mapper.php b/Model/Payment/Stripe/Payments/Last4Mapper.php index 9eda7443..cf1d8a25 100644 --- a/Model/Payment/Stripe/Payments/Last4Mapper.php +++ b/Model/Payment/Stripe/Payments/Last4Mapper.php @@ -8,7 +8,7 @@ class Last4Mapper extends Base_Last4Mapper { use MapperTrait; - protected $allowedMethods = ['stripe_payments']; + public $allowedMethods = ['stripe_payments']; /** * Gets last 4 credit card digits diff --git a/Model/Payment/Stripe/Payments/MapperTrait.php b/Model/Payment/Stripe/Payments/MapperTrait.php index 51322b45..efb85d31 100644 --- a/Model/Payment/Stripe/Payments/MapperTrait.php +++ b/Model/Payment/Stripe/Payments/MapperTrait.php @@ -16,7 +16,7 @@ public function getCharge(\Magento\Sales\Model\Order $order) } $registryKey = "signify_stripe_payment_charge_{$order->getId()}"; - $charge = $this->registry->registry($registryKey); + $charge = $this->registry->getData($registryKey); if (is_object($charge)) { return $charge; @@ -66,7 +66,7 @@ public function getCharge(\Magento\Sales\Model\Order $order) return false; } - $this->registry->register($registryKey, $charge); + $this->registry->setData($registryKey, $charge); return $charge; } } diff --git a/Model/PaymentGatewayFactory.php b/Model/PaymentGatewayFactory.php index 58afe158..1303611b 100644 --- a/Model/PaymentGatewayFactory.php +++ b/Model/PaymentGatewayFactory.php @@ -9,12 +9,12 @@ class PaymentGatewayFactory /** * @var ObjectManagerInterface */ - protected $objectManager; + public $objectManager; /** * @var array */ - protected $gateways = []; + public $gateways = []; /** * PaymentGatewayFactory constructor. diff --git a/Model/PaymentVerificationFactory.php b/Model/PaymentVerificationFactory.php index 4f9a5fad..a3a4975a 100644 --- a/Model/PaymentVerificationFactory.php +++ b/Model/PaymentVerificationFactory.php @@ -7,6 +7,7 @@ use Magento\Payment\Gateway\ConfigInterface; use Magento\Framework\Exception\LocalizedException; use Signifyd\Connect\Helper\ConfigHelper; +use Signifyd\Connect\Api\AsyncCheckerInterface; /** * Creates verification service for provided payment method, or PaymentVerificationInterface::class @@ -17,61 +18,66 @@ class PaymentVerificationFactory /** * @var ConfigInterface */ - protected $config; + public $config; /** * @var ObjectManagerInterface */ - protected $objectManager; + public $objectManager; /** * @var PaymentVerificationInterface */ - protected $avsDefaultAdapter; + public $avsDefaultAdapter; /** * @var PaymentVerificationInterface */ - protected $cvvDefaultAdapter; + public $cvvDefaultAdapter; /** * @var PaymentVerificationInterface */ - protected $cardholderDefaultAdapter; + public $cardholderDefaultAdapter; /** * @var PaymentVerificationInterface */ - protected $last4DefaultAdapter; + public $last4DefaultAdapter; /** * @var PaymentVerificationInterface */ - protected $expMonthDefaultAdapter; + public $expMonthDefaultAdapter; /** * @var PaymentVerificationInterface */ - protected $expYearDefaultAdapter; + public $expYearDefaultAdapter; /** * @var PaymentVerificationInterface */ - protected $binDefaultAdapter; + public $binDefaultAdapter; /** * @var PaymentVerificationInterface */ - protected $transactionIdDefaultAdapter; + public $transactionIdDefaultAdapter; + + /** + * @var AsyncCheckerInterface + */ + public $asyncCheckDefaultAdapter; /** * @var ConfigHelper */ - protected $configHelper; + public $configHelper; /** * @param ObjectManagerInterface $objectManager - * @param ConfigInterface|Config $config + * @param ConfigInterface $config * @param PaymentVerificationInterface $avsDefaultAdapter * @param PaymentVerificationInterface $cvvDefaultAdapter * @param PaymentVerificationInterface $cardholderDefaultAdapter @@ -79,6 +85,7 @@ class PaymentVerificationFactory * @param PaymentVerificationInterface $expMonthDefaultAdapter * @param PaymentVerificationInterface $expYearDefaultAdapter * @param PaymentVerificationInterface $binDefaultAdapter + * @param AsyncCheckerInterface $asyncCheckDefaultAdapter * @param ConfigHelper $configHelper */ public function __construct( @@ -92,6 +99,7 @@ public function __construct( PaymentVerificationInterface $expYearDefaultAdapter, PaymentVerificationInterface $binDefaultAdapter, PaymentVerificationInterface $transactionIdDefaultAdapter, + AsyncCheckerInterface $asyncCheckDefaultAdapter, ConfigHelper $configHelper ) { $this->config = $config; @@ -104,6 +112,7 @@ public function __construct( $this->expYearDefaultAdapter = $expYearDefaultAdapter; $this->binDefaultAdapter = $binDefaultAdapter; $this->transactionIdDefaultAdapter = $transactionIdDefaultAdapter; + $this->asyncCheckDefaultAdapter = $asyncCheckDefaultAdapter; $this->configHelper = $configHelper; } @@ -211,6 +220,20 @@ public function createPaymentTransactionId($paymentCode) return $this->create($this->transactionIdDefaultAdapter, $paymentCode, 'signifyd_transaction_id_adapter'); } + + /** + * Creates instance of bin mapper. + * Exception will be thrown if mapper does not implement AsyncCheckerInterface. + * + * @param string $paymentCode + * @return AsyncCheckerInterface + * @throws \Exception + */ + public function createPaymentAsyncChecker($paymentCode) + { + return $this->create($this->asyncCheckDefaultAdapter, $paymentCode, 'signifyd_async_checker'); + } + /** * Creates instance of PaymentVerificationInterface. * Default implementation will be returned if payment method does not implement PaymentVerificationInterface. @@ -219,14 +242,15 @@ public function createPaymentTransactionId($paymentCode) * If not found will try for signifyd/payment/[method]/[config_key] * We keep looking on payment/[method]/[config_key] because this is the path on 3.5.1 and older versions * - * @param PaymentVerificationInterface $defaultAdapter + * @param PaymentVerificationInterface|AsyncCheckerInterface $defaultAdapter * @param string $paymentCode * @param string $configKey * @return PaymentVerificationInterface - * @throws ConfigurationMismatchException If payment verification instance + * @throws LocalizedException If payment verification instance + * @return PaymentVerificationInterface|AsyncCheckerInterface * does not implement PaymentVerificationInterface. */ - private function create(PaymentVerificationInterface $defaultAdapter, $paymentCode, $configKey) + private function create($defaultAdapter, $paymentCode, $configKey) { $this->config->setMethodCode($paymentCode); $verificationClass = $this->config->getValue($configKey); @@ -240,9 +264,9 @@ private function create(PaymentVerificationInterface $defaultAdapter, $paymentCo } $mapper = $this->objectManager->create($verificationClass); - if (!$mapper instanceof PaymentVerificationInterface) { + if (!$mapper instanceof PaymentVerificationInterface && !$mapper instanceof AsyncCheckerInterface) { throw new LocalizedException( - __('Signifyd_Connect: %1 must implement %2', $verificationClass, PaymentVerificationInterface::class) + __('Signifyd_Connect: %1 must implement %2', $verificationClass, PaymentVerificationInterface::class, AsyncCheckerInterface::class) ); } return $mapper; diff --git a/Model/ProcessCron/CaseData/AsyncWaiting.php b/Model/ProcessCron/CaseData/AsyncWaiting.php index 7206230e..16b72323 100644 --- a/Model/ProcessCron/CaseData/AsyncWaiting.php +++ b/Model/ProcessCron/CaseData/AsyncWaiting.php @@ -13,63 +13,64 @@ use Signifyd\Connect\Model\ResourceModel\Order as SignifydOrderResourceModel; use Signifyd\Connect\Model\UpdateOrderFactory; use Signifyd\Connect\Model\Api\SaleOrderFactory; +use Signifyd\Connect\Model\PaymentVerificationFactory; class AsyncWaiting { /** * @var Logger */ - protected $logger; + public $logger; /** * @var ConfigHelper */ - protected $configHelper; + public $configHelper; /** * @var OrderResourceModel */ - protected $orderResourceModel; + public $orderResourceModel; /** * @var OrderFactory */ - protected $orderFactory; + public $orderFactory; /** * @var SignifydOrderResourceModel */ - protected $signifydOrderResourceModel; + public $signifydOrderResourceModel; /** * @var UpdateCaseFactory */ - protected $updateCaseFactory; + public $updateCaseFactory; /** * @var UpdateOrderFactory */ - protected $updateOrderFactory; + public $updateOrderFactory; /** * @var CasedataResourceModel */ - protected $casedataResourceModel; + public $casedataResourceModel; /** - * @var \StripeIntegration\Payments\Model\Config + * @var StoreManagerInterface */ - protected $stripeConfig; + public $storeManagerInterface; /** - * @var StoreManagerInterface + * @var SaleOrderFactory */ - protected $storeManagerInterface; + public $saleOrderFactory; /** - * @var SaleOrderFactory + * @var PaymentVerificationFactory */ - protected $saleOrderFactory; + public $paymentVerificationFactory; /** * AsyncWaiting constructor. @@ -94,7 +95,8 @@ public function __construct( UpdateOrderFactory $updateOrderFactory, CasedataResourceModel $casedataResourceModel, StoreManagerInterface $storeManagerInterface, - SaleOrderFactory $saleOrderFactory + SaleOrderFactory $saleOrderFactory, + PaymentVerificationFactory $paymentVerificationFactory ) { $this->configHelper = $configHelper; $this->logger = $logger; @@ -106,6 +108,7 @@ public function __construct( $this->casedataResourceModel = $casedataResourceModel; $this->storeManagerInterface = $storeManagerInterface; $this->saleOrderFactory = $saleOrderFactory; + $this->paymentVerificationFactory = $paymentVerificationFactory; } /** @@ -114,6 +117,8 @@ public function __construct( */ public function __invoke(array $asyncWaitingCases) { + $previousStore = $this->storeManagerInterface->getStore()->getId(); + /** @var \Signifyd\Connect\Model\Casedata $case */ foreach ($asyncWaitingCases as $case) { try { @@ -132,25 +137,10 @@ public function __invoke(array $asyncWaitingCases) $this->casedataResourceModel->delete($case); } - $order->setData('origin_store_code', $case->getData('origin_store_code')); - $saleOrder = $this->saleOrderFactory->create(); - $caseModel = $saleOrder($order); - $avsCode = $caseModel['transactions'][0]['verifications']['avsResponseCode']; - $cvvCode = $caseModel['transactions'][0]['verifications']['cvvResponseCode']; - $retries = $case->getData('retries'); + /** @var \Signifyd\Connect\Model\Payment\Base\AsyncChecker $asyncCheck */ + $asyncCheck = $this->paymentVerificationFactory->createPaymentAsyncChecker($order->getPayment()->getMethod()); - if ($case->getOrder()->getPayment()->getMethod() === 'stripe_payments' && - $case->getEntries('stripe_status') !== 'approved' - ) { - $this->logger->info( - "CRON: case no: {$case->getOrderIncrement()}" . - " will not be sent because the stripe hasn't approved it yet", - ['entity' => $case] - ); - continue; - } - - if ($retries >= 5 || empty($avsCode) === false && empty($cvvCode) === false) { + if ($asyncCheck($order, $case)) { try { $this->casedataResourceModel->loadForUpdate($case, (string) $case->getData('entity_id')); @@ -174,5 +164,7 @@ public function __invoke(array $asyncWaitingCases) ); } } + + $this->storeManagerInterface->setCurrentStore($previousStore); } } diff --git a/Model/ProcessCron/CaseData/InReview.php b/Model/ProcessCron/CaseData/InReview.php index fe49ece8..5be95a31 100644 --- a/Model/ProcessCron/CaseData/InReview.php +++ b/Model/ProcessCron/CaseData/InReview.php @@ -19,62 +19,57 @@ class InReview /** * @var Logger */ - protected $logger; + public $logger; /** * @var ConfigHelper */ - protected $configHelper; + public $configHelper; /** * @var OrderResourceModel */ - protected $orderResourceModel; + public $orderResourceModel; /** * @var OrderFactory */ - protected $orderFactory; + public $orderFactory; /** * @var SignifydOrderResourceModel */ - protected $signifydOrderResourceModel; + public $signifydOrderResourceModel; /** * @var UpdateCaseFactory */ - protected $updateCaseFactory; + public $updateCaseFactory; /** * @var UpdateOrderFactory */ - protected $updateOrderFactory; + public $updateOrderFactory; /** * @var CasedataResourceModel */ - protected $casedataResourceModel; - - /** - * @var \StripeIntegration\Payments\Model\Config - */ - protected $stripeConfig; + public $casedataResourceModel; /** * @var StoreManagerInterface */ - protected $storeManagerInterface; + public $storeManagerInterface; /** * @var ReInitStripeFactory */ - protected $reInitStripeFactory; + public $reInitStripeFactory; /** * @var Client */ - protected $client; + public $client; /** * InReview constructor. @@ -117,11 +112,13 @@ public function __construct( } /** - * @param array $asyncWaitingCases + * @param array $inReviewCases * @return void */ public function __invoke(array $inReviewCases) { + $previousStore = $this->storeManagerInterface->getStore()->getId(); + /** @var \Signifyd\Connect\Model\Casedata $case */ foreach ($inReviewCases as $case) { try { @@ -149,7 +146,8 @@ public function __invoke(array $inReviewCases) if ($currentCaseHash == $newCaseHash) { $this->logger->info( "CRON: Case {$case->getId()} already update with this data," . - " no action will be taken" + " no action will be taken", + ['entity' => $case] ); // Triggering case save to unlock case @@ -170,7 +168,8 @@ public function __invoke(array $inReviewCases) $this->logger->error( 'CRON: Failed to save case data to database: ' - . $e->getMessage() + . $e->getMessage(), + ['entity' => $case] ); } } catch (\Exception $e) { @@ -185,5 +184,7 @@ public function __invoke(array $inReviewCases) ); } } + + $this->storeManagerInterface->setCurrentStore($previousStore); } } diff --git a/Model/ProcessCron/CaseData/PreAuthTransaction.php b/Model/ProcessCron/CaseData/PreAuthTransaction.php index d32d4db2..337ca755 100644 --- a/Model/ProcessCron/CaseData/PreAuthTransaction.php +++ b/Model/ProcessCron/CaseData/PreAuthTransaction.php @@ -14,32 +14,32 @@ class PreAuthTransaction /** * @var Logger */ - protected $logger; + public $logger; /** * @var OrderResourceModel */ - protected $orderResourceModel; + public $orderResourceModel; /** * @var OrderFactory */ - protected $orderFactory; + public $orderFactory; /** * @var SignifydOrderResourceModel */ - protected $signifydOrderResourceModel; + public $signifydOrderResourceModel; /** * @var StoreManagerInterface */ - protected $storeManagerInterface; + public $storeManagerInterface; /** * @var ProcessTransactionFactory */ - protected $processTransactionFactory; + public $processTransactionFactory; /** * PreAuthTransaction constructor. @@ -67,11 +67,13 @@ public function __construct( } /** - * @param array $asyncWaitingCases + * @param array $preAuthCases * @return void */ public function __invoke(array $preAuthCases) { + $previousStore = $this->storeManagerInterface->getStore()->getId(); + /** @var \Signifyd\Connect\Model\Casedata $case */ foreach ($preAuthCases as $case) { try { @@ -107,5 +109,7 @@ public function __invoke(array $preAuthCases) ); } } + + $this->storeManagerInterface->setCurrentStore($previousStore); } -} \ No newline at end of file +} diff --git a/Model/ProcessCron/CaseData/WaitingSubmission.php b/Model/ProcessCron/CaseData/WaitingSubmission.php index 1ef740bd..d01721ce 100644 --- a/Model/ProcessCron/CaseData/WaitingSubmission.php +++ b/Model/ProcessCron/CaseData/WaitingSubmission.php @@ -21,67 +21,62 @@ class WaitingSubmission /** * @var Logger */ - protected $logger; + public $logger; /** * @var ConfigHelper */ - protected $configHelper; + public $configHelper; /** * @var OrderResourceModel */ - protected $orderResourceModel; + public $orderResourceModel; /** * @var OrderFactory */ - protected $orderFactory; + public $orderFactory; /** * @var SignifydOrderResourceModel */ - protected $signifydOrderResourceModel; + public $signifydOrderResourceModel; /** * @var UpdateCaseFactory */ - protected $updateCaseFactory; + public $updateCaseFactory; /** * @var UpdateOrderFactory */ - protected $updateOrderFactory; + public $updateOrderFactory; /** * @var CasedataResourceModel */ - protected $casedataResourceModel; - - /** - * @var \StripeIntegration\Payments\Model\Config - */ - protected $stripeConfig; + public $casedataResourceModel; /** * @var StoreManagerInterface */ - protected $storeManagerInterface; + public $storeManagerInterface; /** * @var ReInitStripeFactory */ - protected $reInitStripeFactory; + public $reInitStripeFactory; /** * @var SaleOrderFactory */ - protected $saleOrderFactory; + public $saleOrderFactory; /** * @var Client */ - protected $client; + public $client; /** * WaitingSubmission constructor. @@ -132,6 +127,8 @@ public function __construct( */ public function __invoke(array $waitingSubmissionCases) { + $previousStore = $this->storeManagerInterface->getStore()->getId(); + /** @var \Signifyd\Connect\Model\Casedata $case */ foreach ($waitingSubmissionCases as $case) { try { @@ -150,6 +147,7 @@ public function __invoke(array $waitingSubmissionCases) try { $this->casedataResourceModel->loadForUpdate($case, (string) $case->getData('entity_id')); $saleOrder = $this->saleOrderFactory->create(); + $order->setData('origin_store_code', $case->getData('origin_store_code')); $caseModel = $saleOrder($order); /** @var \Signifyd\Core\Response\SaleResponse $caseResponse */ $caseResponse = $this->client->postCaseToSignifyd($caseModel, $order); @@ -179,5 +177,7 @@ public function __invoke(array $waitingSubmissionCases) ); } } + + $this->storeManagerInterface->setCurrentStore($previousStore); } } diff --git a/Model/ProcessCron/Fulfillment.php b/Model/ProcessCron/Fulfillment.php index 7bdcbdd7..7eef7ab8 100644 --- a/Model/ProcessCron/Fulfillment.php +++ b/Model/ProcessCron/Fulfillment.php @@ -2,6 +2,7 @@ namespace Signifyd\Connect\Model\ProcessCron; +use Magento\Framework\Serialize\Serializer\Json as JsonSerializer; use Signifyd\Connect\Helper\ConfigHelper; use Signifyd\Connect\Helper\OrderHelper; use Signifyd\Connect\Logger\Logger; @@ -16,42 +17,47 @@ class Fulfillment /** * @var ConfigHelper */ - protected $configHelper; + public $configHelper; /** * @var FulfillmentResourceModel */ - protected $fulfillmentResourceModel; + public $fulfillmentResourceModel; /** * @var Logger */ - protected $logger; + public $logger; /** * @var OrderHelper */ - protected $orderHelper; + public $orderHelper; /** * @var SignifydOrderResourceModel */ - protected $signifydOrderResourceModel; + public $signifydOrderResourceModel; /** * @var OrderFactory */ - protected $orderFactory; + public $orderFactory; /** * @var FulfillmentFactory */ - protected $fulfillmentFactory; + public $fulfillmentFactory; /** * @var Client */ - protected $client; + public $client; + + /** + * @var JsonSerializer + */ + public $jsonSerializer; /** * Fulfillment constructor. @@ -63,6 +69,7 @@ class Fulfillment * @param OrderFactory $orderFactory * @param FulfillmentFactory $fulfillmentFactory * @param Client $client + * @param JsonSerializer $jsonSerializer */ public function __construct( ConfigHelper $configHelper, @@ -72,7 +79,8 @@ public function __construct( SignifydOrderResourceModel $signifydOrderResourceModel, OrderFactory $orderFactory, FulfillmentFactory $fulfillmentFactory, - Client $client + Client $client, + JsonSerializer $jsonSerializer ) { $this->configHelper = $configHelper; $this->fulfillmentResourceModel = $fulfillmentResourceModel; @@ -82,6 +90,7 @@ public function __construct( $this->orderFactory = $orderFactory; $this->fulfillmentFactory = $fulfillmentFactory; $this->client = $client; + $this->jsonSerializer = $jsonSerializer; } /** @@ -98,6 +107,9 @@ public function __invoke($fulfillments) $fulfillmentApi = $this->fulfillmentFactory->create(); $fulfillmentData = $fulfillmentApi($fulfillment); + $this->logger->info("Call addFulfillments with request: " . + $this->jsonSerializer->serialize($fulfillmentData), ['entity' => $order]); + $fulfillmentBulkResponse = $this->client ->getSignifydSaleApi($order)->addFulfillment($fulfillmentData); $fulfillmentOrderId = $fulfillmentBulkResponse->getOrderId(); @@ -105,12 +117,14 @@ public function __invoke($fulfillments) if (isset($fulfillmentOrderId) === false) { $message = "CRON: Fullfilment failed to send"; } else { + $this->logger->info("AddFulfillments response: " . + $this->jsonSerializer->serialize($fulfillmentBulkResponse), ['entity' => $order]); $message = "CRON: Fullfilment sent"; $fulfillment->setMagentoStatus(\Signifyd\Connect\Model\Fulfillment::COMPLETED_STATUS); $this->fulfillmentResourceModel->save($fulfillment); } - $this->logger->debug($message); + $this->logger->debug($message, ['entity' => $order]); $this->orderHelper->addCommentToStatusHistory($order, $message); } catch (\Exception $e) { $this->logger->error( diff --git a/Model/ProcessCron/Reroute.php b/Model/ProcessCron/Reroute.php new file mode 100644 index 00000000..50cfcd6b --- /dev/null +++ b/Model/ProcessCron/Reroute.php @@ -0,0 +1,209 @@ +paymentUpdateFactory = $paymentUpdateFactory; + $this->casedataFactory = $casedataFactory; + $this->casedataResourceModel = $casedataResourceModel; + $this->configHelper = $configHelper; + $this->jsonSerializer = $jsonSerializer; + $this->logger = $logger; + $this->updateCaseFactory = $updateCaseFactory; + $this->updateOrderFactory = $updateOrderFactory; + $this->shipmentsFactory = $shipmentsFactory; + $this->client = $client; + $this->deviceFactory = $deviceFactory; + $this->orderFactory = $orderFactory; + $this->signifydOrderResourceModel = $signifydOrderResourceModel; + $this->rerouteResourceModel = $rerouteResourceModel; + } + + /** + * @param \Signifyd\Connect\Model\Reroute $reroute + * @return void + */ + public function __invoke(\Signifyd\Connect\Model\Reroute $reroute) + { + try { + $orderId = $reroute->getOrderId(); + $case = $this->casedataFactory->create(); + $this->casedataResourceModel->loadForUpdate($case, $orderId, 'order_id'); + $order = $this->orderFactory->create(); + $this->signifydOrderResourceModel->load($order, $orderId); + + $this->logger->info("Send case update for order {$order->getIncrementId()}", ['entity' => $order]); + + $makeShipments = $this->shipmentsFactory->create(); + $shipments = $makeShipments($order); + $recipient = $shipments[0]['destination']; + $recipientJson = $this->jsonSerializer->serialize($recipient); + $newHashToValidateReroute = sha1($recipientJson); + $currentHashToValidateReroute = $case->getEntries('hash'); + + if ($newHashToValidateReroute == $currentHashToValidateReroute) { + $this->logger->info( + "No data changes, will not update order {$order->getIncrementId()}", + ['entity' => $order] + ); + $reroute->setMagentoStatus(\Signifyd\Connect\Model\Fulfillment::COMPLETED_STATUS); + $this->rerouteResourceModel->save($reroute); + return; + } + + $device = $this->deviceFactory->create(); + $rerout = []; + $rerout['orderId'] = $order->getIncrementId(); + $rerout['device'] = $device($order->getQuoteId(), $order->getStoreId()); + $rerout['shipments'] = $shipments; + $updateResponse = $this->client->createReroute($rerout, $order); + + $this->logger->info("Case updated for order {$order->getIncrementId()}", ['entity' => $order]); + + if ($updateResponse !== false) { + $reroute->setMagentoStatus(\Signifyd\Connect\Model\Fulfillment::COMPLETED_STATUS); + $this->rerouteResourceModel->save($reroute); + } + + $case->setEntries('hash', $newHashToValidateReroute); + $updateCase = $this->updateCaseFactory->create(); + $case = $updateCase($case, $updateResponse); + + if ($case->getOrigData('guarantee') !== $case->getData('guarantee')) { + $case->setStatus(\Signifyd\Connect\Model\Casedata::IN_REVIEW_STATUS); + $updateOrder = $this->updateOrderFactory->create(); + $case = $updateOrder($case); + } + + $this->casedataResourceModel->save($case); + } catch (\Exception $e) { + $this->logger->error( + "Failed to process Reroute to order {$reroute->getOrderId()}: " + . $e->getMessage() + ); + } catch (\Error $e) { + $this->logger->error( + "Failed to process Reroute to order {$reroute->getOrderId()}: " + . $e->getMessage() + ); + } + } +} diff --git a/Model/Registry.php b/Model/Registry.php new file mode 100644 index 00000000..a1c373a0 --- /dev/null +++ b/Model/Registry.php @@ -0,0 +1,10 @@ +_init(\Signifyd\Connect\Model\ResourceModel\Reroute::class); + } + + /** + * @inheritDoc + */ + public function getRerouteId() + { + return $this->getData(self::REROUTE_ID); + } + + /** + * @inheritDoc + */ + public function setRerouteId($rerouteId) + { + return $this->setData(self::REROUTE_ID, $rerouteId); + } + + /** + * @inheritDoc + */ + public function getOrderId() + { + return $this->getData(self::ORDER_ID); + } + + /** + * @inheritDoc + */ + public function setOrderId($orderId) + { + return $this->setData(self::ORDER_ID, $orderId); + } + + /** + * @inheritDoc + */ + public function getMagentoStatus() + { + return $this->getData(self::MAGENTO_STATUS); + } + + /** + * @inheritDoc + */ + public function setMagentoStatus($magentoStatus) + { + return $this->setData(self::MAGENTO_STATUS, $magentoStatus); + } + + /** + * @inheritDoc + */ + public function getRetries() + { + return $this->getData(self::RETRIES); + } + + /** + * @inheritDoc + */ + public function setRetries($retries) + { + return $this->setData(self::RETRIES, $retries); + } + + /** + * @inheritDoc + */ + public function getInsertedAt() + { + return $this->getData(self::INSERTED_AT); + } + + /** + * @inheritDoc + */ + public function setInsertedAt($insertedAt) + { + return $this->setData(self::INSERTED_AT, $insertedAt); + } +} diff --git a/Model/Reroute/ReroutesToRetry.php b/Model/Reroute/ReroutesToRetry.php new file mode 100644 index 00000000..f5f2e888 --- /dev/null +++ b/Model/Reroute/ReroutesToRetry.php @@ -0,0 +1,47 @@ +objectCollectionFactory = $objectCollectionFactory; + $this->objectResourceModel = $objectResourceModel; + } +} diff --git a/Model/RerouteRepository.php b/Model/RerouteRepository.php new file mode 100644 index 00000000..eae12e78 --- /dev/null +++ b/Model/RerouteRepository.php @@ -0,0 +1,148 @@ +resource = $resource; + $this->rerouteFactory = $rerouteFactory; + $this->rerouteCollectionFactory = $rerouteCollectionFactory; + $this->searchResultsFactory = $searchResultsFactory; + $this->collectionProcessor = $collectionProcessor; + } + + /** + * @inheritDoc + */ + public function save(RerouteInterface $reroute) + { + try { + $this->resource->save($reroute); + } catch (\Exception $exception) { + throw new CouldNotSaveException(__( + 'Could not save the reroute: %1', + $exception->getMessage() + )); + } + return $reroute; + } + + /** + * @inheritDoc + */ + public function get($rerouteId) + { + $reroute = $this->rerouteFactory->create(); + $this->resource->load($reroute, $rerouteId); + if (!$reroute->getId()) { + throw new NoSuchEntityException(__('reroute with id "%1" does not exist.', $rerouteId)); + } + return $reroute; + } + + /** + * @inheritDoc + */ + public function getList( + \Magento\Framework\Api\SearchCriteriaInterface $criteria + ) { + $collection = $this->rerouteCollectionFactory->create(); + + $this->collectionProcessor->process($criteria, $collection); + + $searchResults = $this->searchResultsFactory->create(); + $searchResults->setSearchCriteria($criteria); + + $items = []; + foreach ($collection as $model) { + $items[] = $model; + } + + $searchResults->setItems($items); + $searchResults->setTotalCount($collection->getSize()); + return $searchResults; + } + + /** + * @inheritDoc + */ + public function delete(RerouteInterface $reroute) + { + try { + $rerouteModel = $this->rerouteFactory->create(); + $this->resource->load($rerouteModel, $reroute->getRerouteId()); + $this->resource->delete($rerouteModel); + } catch (\Exception $exception) { + throw new CouldNotDeleteException(__( + 'Could not delete the reroute: %1', + $exception->getMessage() + )); + } + return true; + } + + /** + * @inheritDoc + */ + public function deleteById($rerouteId) + { + return $this->delete($this->get($rerouteId)); + } +} diff --git a/Model/ResourceModel/Casedata.php b/Model/ResourceModel/Casedata.php index 1e7f7fce..f1849acc 100644 --- a/Model/ResourceModel/Casedata.php +++ b/Model/ResourceModel/Casedata.php @@ -19,12 +19,12 @@ class Casedata extends AbstractDb /** * @var bool */ - protected $loadForUpdate = false; + public $loadForUpdate = false; /** * @var ScopeConfigInterface */ - protected $scopeConfigInterface; + public $scopeConfigInterface; /** * Casedata constructor. @@ -81,7 +81,7 @@ public function loadForUpdate(\Signifyd\Connect\Model\Casedata $case, $value, $f parent::save($case); $this->loadForUpdate = false; - $this->commit(); + $this->getConnection()->commit(); return $return; } @@ -115,7 +115,7 @@ public function save(\Magento\Framework\Model\AbstractModel $case) } /** - * @param Casedata $case + * @param \Signifyd\Connect\Model\Casedata $case * @return bool */ public function isCaseLocked(\Signifyd\Connect\Model\Casedata $case) diff --git a/Model/ResourceModel/Logs.php b/Model/ResourceModel/Logs.php new file mode 100644 index 00000000..8a4aea71 --- /dev/null +++ b/Model/ResourceModel/Logs.php @@ -0,0 +1,22 @@ +_init('signifyd_connect_logs', 'logs_id'); + } +} diff --git a/Model/ResourceModel/Logs/Collection.php b/Model/ResourceModel/Logs/Collection.php new file mode 100644 index 00000000..52ff39b5 --- /dev/null +++ b/Model/ResourceModel/Logs/Collection.php @@ -0,0 +1,30 @@ +_init( + \Signifyd\Connect\Model\Logs::class, + \Signifyd\Connect\Model\ResourceModel\Logs::class + ); + } +} diff --git a/Model/ResourceModel/Order.php b/Model/ResourceModel/Order.php index 0d1c6d59..4c47efa8 100644 --- a/Model/ResourceModel/Order.php +++ b/Model/ResourceModel/Order.php @@ -7,7 +7,7 @@ class Order extends \Magento\Sales\Model\ResourceModel\Order /** * @var bool */ - protected $loadForUpdate = false; + public $loadForUpdate = false; public function loadForUpdate(\Magento\Framework\Model\AbstractModel $object, $value, $field = null) { diff --git a/Model/ResourceModel/Reroute.php b/Model/ResourceModel/Reroute.php new file mode 100644 index 00000000..6c9f647b --- /dev/null +++ b/Model/ResourceModel/Reroute.php @@ -0,0 +1,22 @@ +_init('signifyd_connect_reroute', 'reroute_id'); + } +} diff --git a/Model/ResourceModel/Reroute/Collection.php b/Model/ResourceModel/Reroute/Collection.php new file mode 100644 index 00000000..72388431 --- /dev/null +++ b/Model/ResourceModel/Reroute/Collection.php @@ -0,0 +1,30 @@ +_init( + \Signifyd\Connect\Model\Reroute::class, + \Signifyd\Connect\Model\ResourceModel\Reroute::class + ); + } +} diff --git a/Model/RetryModel.php b/Model/RetryModel.php new file mode 100644 index 00000000..44f582de --- /dev/null +++ b/Model/RetryModel.php @@ -0,0 +1,93 @@ +logger = $logger; + } + + /** + * @param $status + * @return mixed + */ + public function __invoke() + { + $retryTimes = $this->calculateRetryTimes(); + + $time = time(); + $lastTime = $time - (end($retryTimes) + 60*60*24); + $current = date('Y-m-d H:i:s', $time); + $from = date('Y-m-d H:i:s', $lastTime); + + $objectCollection = $this->objectCollectionFactory->create(); + $objectCollection->addFieldToFilter('inserted_at', ['gteq' => $from]); + $objectCollection->addFieldToFilter('magento_status', ['eq' => 'waiting_submission']); + $objectCollection->addFieldToFilter('retries', ['lt' => count($retryTimes)]); + $objectCollection->addExpressionFieldToSelect( + 'seconds_after_inserted_at', + "TIME_TO_SEC(TIMEDIFF('{$current}', inserted_at))", + ['inserted_at'] + ); + + $objectsToRetry = []; + + foreach ($objectCollection->getItems() as $object) { + $retries = $object->getData('retries'); + $secondsAfterUpdate = $object->getData('seconds_after_inserted_at'); + + if ($secondsAfterUpdate > $retryTimes[$retries]) { + $objectsToRetry[$object->getId()] = $object; + $object->setData('retries', $retries + 1); + $this->objectResourceModel->save($object); + } + } + + return $objectsToRetry; + } + + /** + * Retry times calculated from last update + * + * @return array + */ + protected function calculateRetryTimes() + { + $retryTimes = []; + + for ($retry = 0; $retry < 15; $retry++) { + // Increment retry times exponentially + $retryTimes[$retry] = 20 * pow(2, $retry); + // Increment should not be greater than one day + $retryTimes[$retry] = $retryTimes[$retry] > 86400 ? 86400 : $retryTimes[$retry]; + // Sum retry time to previous, calculating total time to wait from last update + $retryTimes[$retry] += isset($retryTimes[$retry-1]) ? $retryTimes[$retry-1] : 0; + } + + return $retryTimes; + } +} diff --git a/Model/ScaPreAuth/ScaEvaluation.php b/Model/ScaPreAuth/ScaEvaluation.php index bf4a0bc9..fee55ca8 100644 --- a/Model/ScaPreAuth/ScaEvaluation.php +++ b/Model/ScaPreAuth/ScaEvaluation.php @@ -15,27 +15,27 @@ class ScaEvaluation extends AbstractModel /** * @var CasedataFactory */ - protected $casedataFactory; + public $casedataFactory; /** * @var CasedataResourceModel */ - protected $casedataResourceModel; + public $casedataResourceModel; /** * @var ScaEvaluationModelFactory */ - protected $scaEvaluationModelFactory; + public $scaEvaluationModelFactory; /** * @var SerializerInterface */ - protected $serializer; + public $serializer; /** * @var ConfigHelper */ - protected $configHelper; + public $configHelper; /** * @param Context $context diff --git a/Model/ScaPreAuth/ScaEvaluationConfig.php b/Model/ScaPreAuth/ScaEvaluationConfig.php index c4df907f..e21c6ec6 100644 --- a/Model/ScaPreAuth/ScaEvaluationConfig.php +++ b/Model/ScaPreAuth/ScaEvaluationConfig.php @@ -11,7 +11,7 @@ class ScaEvaluationConfig extends AbstractModel /** * @var ConfigHelper */ - protected $configHelper; + public $configHelper; /** * @param Context $context diff --git a/Model/SignifydFlags.php b/Model/SignifydFlags.php index 7e8c8a90..4419c6f5 100644 --- a/Model/SignifydFlags.php +++ b/Model/SignifydFlags.php @@ -6,8 +6,8 @@ class SignifydFlags { const FILE_NAME = 'signifyd_flags.json'; - protected $directoryList; - protected $fileDriver; + public $directoryList; + public $fileDriver; public function __construct( \Magento\Framework\App\Filesystem\DirectoryList $directoryList, @@ -24,14 +24,14 @@ public function __construct( */ public function updateWebhookFlag($time = null) { - $filePath = $this->directoryList->getPath('log') . '/' . self::FILE_NAME; + $directory = $this->directoryList->getPath('log'); + $filePath = $directory . '/' . self::FILE_NAME; $data = $this->readFlags(); if (!$data) { $data = []; } $data['webhook'] = $time ?: date('Y-m-d H:i:s'); if (!$this->fileDriver->isExists($filePath)) { - $directory = dirname($filePath); $this->fileDriver->createDirectory($directory); $this->fileDriver->touch($filePath); } @@ -45,14 +45,14 @@ public function updateWebhookFlag($time = null) */ public function updateCronFlag($time = null) { - $filePath = $this->directoryList->getPath('log') . '/' . self::FILE_NAME; + $directory = $this->directoryList->getPath('log'); + $filePath = $directory . '/' . self::FILE_NAME; $data = $this->readFlags(); if (!$data) { $data = []; } $data['cron'] = $time ?: date('Y-m-d H:i:s'); if (!$this->fileDriver->isExists($filePath)) { - $directory = dirname($filePath); $this->fileDriver->createDirectory($directory); $this->fileDriver->touch($filePath); } diff --git a/Model/Stripe/ReInit.php b/Model/Stripe/ReInit.php index 6b44436b..41b5321a 100644 --- a/Model/Stripe/ReInit.php +++ b/Model/Stripe/ReInit.php @@ -9,12 +9,12 @@ class ReInit /** * @var ObjectManagerInterface */ - protected $objectManager; + public $objectManager; /** * @var \StripeIntegration\Payments\Model\Config */ - protected $stripeConfig; + public $stripeConfig; /** * @param ObjectManagerInterface $objectManager diff --git a/Model/System/Config/Backend/Enabled.php b/Model/System/Config/Backend/Enabled.php index bf507f09..9c4b03bd 100644 --- a/Model/System/Config/Backend/Enabled.php +++ b/Model/System/Config/Backend/Enabled.php @@ -5,21 +5,26 @@ */ namespace Signifyd\Connect\Model\System\Config\Backend; -use Magento\Framework\App\ObjectManager; use Magento\Framework\Message\ManagerInterface; use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\Module\Manager as ModuleManager; class Enabled extends \Magento\Framework\App\Config\Value { /** * @var ManagerInterface */ - protected $messageManager; + public $messageManager; /** * @var \Magento\Store\Model\StoreRepository */ - protected $storeRepository; + public $storeRepository; + + /** + * @var ModuleManager + */ + public $moduleManager; /** * @param \Magento\Framework\Model\Context $context @@ -29,6 +34,7 @@ class Enabled extends \Magento\Framework\App\Config\Value * @param \Magento\Framework\Model\ResourceModel\AbstractResource|null $resource * @param \Magento\Framework\Data\Collection\AbstractDb|null $resourceCollection * @param \Magento\Store\Model\StoreRepository $storeRepository + * @param ModuleManager $moduleManager * @param array $data */ public function __construct( @@ -40,10 +46,12 @@ public function __construct( \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null, \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null, \Magento\Store\Model\StoreRepository $storeRepository, + ModuleManager $moduleManager, array $data = [] ) { $this->messageManager = $messageManager; $this->storeRepository = $storeRepository; + $this->moduleManager = $moduleManager; parent::__construct($context, $registry, $config, $cacheTypeList, $resource, $resourceCollection, $data); } @@ -57,9 +65,7 @@ public function beforeSave() return $this; } - $objectManager = ObjectManager::getInstance(); - $moduleManager = $objectManager->get(\Magento\Framework\Module\Manager::class); - $isBuiltinEnabled = $moduleManager->isOutputEnabled('Magento_Signifyd') ? true : false; + $isBuiltinEnabled = $this->moduleManager->isEnabled('Magento_Signifyd'); if (!$isBuiltinEnabled) { return $this; diff --git a/Model/System/Config/Source/Options/Loglevel.php b/Model/System/Config/Source/Options/Loglevel.php index a86e4a60..38ea1e3f 100644 --- a/Model/System/Config/Source/Options/Loglevel.php +++ b/Model/System/Config/Source/Options/Loglevel.php @@ -2,7 +2,9 @@ namespace Signifyd\Connect\Model\System\Config\Source\Options; -class Loglevel implements \Magento\Framework\Option\ArrayInterface +use Magento\Framework\Data\OptionSourceInterface; + +class Loglevel implements OptionSourceInterface { /** * Options getter diff --git a/Model/System/Config/Source/Options/Negative.php b/Model/System/Config/Source/Options/Negative.php index 3023559a..74e6c837 100644 --- a/Model/System/Config/Source/Options/Negative.php +++ b/Model/System/Config/Source/Options/Negative.php @@ -6,23 +6,23 @@ namespace Signifyd\Connect\Model\System\Config\Source\Options; use Magento\Framework\App\Config\ScopeConfigInterface; -use Magento\Framework\Option\ArrayInterface; +use Magento\Framework\Data\OptionSourceInterface; use Magento\Store\Model\ScopeInterface; /** * Option data for negative order actions */ -class Negative implements ArrayInterface +class Negative implements OptionSourceInterface { /** * @var ScopeConfigInterface */ - protected $coreConfig; + public $coreConfig; /** * @var \Magento\Framework\App\RequestInterface */ - protected $request; + public $request; /** * Negative constructor. diff --git a/Model/System/Config/Source/Options/PolicyName.php b/Model/System/Config/Source/Options/PolicyName.php index 1aef2f75..129022c5 100644 --- a/Model/System/Config/Source/Options/PolicyName.php +++ b/Model/System/Config/Source/Options/PolicyName.php @@ -2,7 +2,9 @@ namespace Signifyd\Connect\Model\System\Config\Source\Options; -class PolicyName implements \Magento\Framework\Option\ArrayInterface +use Magento\Framework\Data\OptionSourceInterface; + +class PolicyName implements OptionSourceInterface { /** * Options getter diff --git a/Model/System/Config/Source/Options/Positive.php b/Model/System/Config/Source/Options/Positive.php index f35686a4..da59d055 100644 --- a/Model/System/Config/Source/Options/Positive.php +++ b/Model/System/Config/Source/Options/Positive.php @@ -6,23 +6,23 @@ namespace Signifyd\Connect\Model\System\Config\Source\Options; use Magento\Framework\App\Config\ScopeConfigInterface; -use Magento\Framework\Option\ArrayInterface; +use Magento\Framework\Data\OptionSourceInterface; use Magento\Store\Model\ScopeInterface; /** * Option data for positive order actions */ -class Positive implements ArrayInterface +class Positive implements OptionSourceInterface { /** * @var ScopeConfigInterface */ - protected $coreConfig; + public $coreConfig; /** * @var \Magento\Framework\App\RequestInterface */ - protected $request; + public $request; /** * Positive constructor. diff --git a/Model/System/Config/Source/Options/Reviewed.php b/Model/System/Config/Source/Options/Reviewed.php index bbfe0da5..ba8b3737 100644 --- a/Model/System/Config/Source/Options/Reviewed.php +++ b/Model/System/Config/Source/Options/Reviewed.php @@ -6,23 +6,23 @@ namespace Signifyd\Connect\Model\System\Config\Source\Options; use Magento\Framework\App\Config\ScopeConfigInterface; -use Magento\Framework\Option\ArrayInterface; +use Magento\Framework\Data\OptionSourceInterface; use Magento\Store\Model\ScopeInterface; /** * Option data for positive order actions */ -class Reviewed implements ArrayInterface +class Reviewed implements OptionSourceInterface { /** * @var ScopeConfigInterface */ - protected $coreConfig; + public $coreConfig; /** * @var \Magento\Framework\App\RequestInterface */ - protected $request; + public $request; /** * Positive constructor. diff --git a/Model/ThreeDsIntegration.php b/Model/ThreeDsIntegration.php index 19335b50..d2280ebb 100644 --- a/Model/ThreeDsIntegration.php +++ b/Model/ThreeDsIntegration.php @@ -19,64 +19,64 @@ class ThreeDsIntegration /** * @var CasedataFactory */ - protected $casedataFactory; + public $casedataFactory; /** * @var CasedataResourceModel */ - protected $casedataResourceModel; + public $casedataResourceModel; /** * @var Logger */ - protected $logger; + public $logger; /** * @var ConfigHelper */ - protected $configHelper; + public $configHelper; /** * @var StoreManagerInterface */ - protected $storeManager; + public $storeManager; /** * @var CheckoutSession */ - protected $checkoutSession; + public $checkoutSession; /** * @var JsonSerializer */ - protected $jsonSerializer; + public $jsonSerializer; /** * @var CartRepositoryInterface */ - protected $cartRepositoryInterface; + public $cartRepositoryInterface; /** * @var OrderFactory */ - protected $orderFactory; + public $orderFactory; /** * @var SignifydOrderResourceModel */ - protected $signifydOrderResourceModel; + public $signifydOrderResourceModel; /** * @var TransactionsFactory */ - protected $transactionsFactory; + public $transactionsFactory; /** * @var Client */ - protected $client; + public $client; - protected $signifydFields = ['eci', 'cavv', 'version', 'transStatus', 'transStatusReason', 'acsOperatorId', + public $signifydFields = ['eci', 'cavv', 'version', 'transStatus', 'transStatusReason', 'acsOperatorId', 'dsTransId', 'threeDsServerTransId', 'cavvAlgorithm', 'exemptionIndicator', 'timestamp']; /** @@ -132,7 +132,7 @@ public function setThreeDsData(array $threeDsData, $quoteId = null) if (isset($quoteId)) { $quote = $this->cartRepositoryInterface->get($quoteId); - if (isset($quote) === false) { + if ($quote->isEmpty()) { $this->logger->info("Error getting quote"); return; @@ -140,7 +140,7 @@ public function setThreeDsData(array $threeDsData, $quoteId = null) } else { $quote = $this->checkoutSession->getQuote(); - if (isset($quote) === false) { + if ($quote->isEmpty()) { $this->logger->info("Quote not found magento checkout session"); return; @@ -152,15 +152,7 @@ public function setThreeDsData(array $threeDsData, $quoteId = null) } $quoteId = $quote->getId(); - - if (isset($quoteId) === false) { - $this->logger->info("Quote id not found"); - - return; - } - $threeDsData = $this->validateFields($threeDsData); - $case = $this->casedataFactory->create(); $this->casedataResourceModel->load($case, $quoteId, 'quote_id'); @@ -187,7 +179,7 @@ public function validateSentTransaction($quoteId) $order = $this->orderFactory->create(); $this->signifydOrderResourceModel->load($order, $orderId); - if (isset($order) === false) { + if ($order->isEmpty()) { return; } diff --git a/Model/TransactionIntegration.php b/Model/TransactionIntegration.php index aa8b7d5f..c718a948 100644 --- a/Model/TransactionIntegration.php +++ b/Model/TransactionIntegration.php @@ -2,12 +2,12 @@ namespace Signifyd\Connect\Model; +use Magento\Checkout\Model\Session as CheckoutSession; use Signifyd\Connect\Helper\ConfigHelper; use Signifyd\Connect\Logger\Logger; use Signifyd\Connect\Model\Api\Core\Client; use Signifyd\Connect\Model\ResourceModel\Casedata as CasedataResourceModel; use Magento\Store\Model\StoreManagerInterface; -use Magento\Checkout\Model\Cart as CheckoutCart; use Signifyd\Connect\Model\Api\TransactionsFactory; class TransactionIntegration @@ -15,46 +15,46 @@ class TransactionIntegration /** * @var CasedataFactory */ - protected $casedataFactory; + public $casedataFactory; /** * @var CasedataResourceModel */ - protected $casedataResourceModel; + public $casedataResourceModel; /** * @var Logger */ - protected $logger; + public $logger; /** * @var ConfigHelper */ - protected $configHelper; + public $configHelper; /** * @var StoreManagerInterface */ - protected $storeManager; + public $storeManager; /** - * @var CheckoutCart + * @var CheckoutSession */ - protected $checkoutCart; + public $checkoutSession; /** * @var TransactionsFactory */ - protected $transactionsFactory; + public $transactionsFactory; /** * @var Client */ - protected $client; + public $client; - protected $gatewayRefusedReason = null; + public $gatewayRefusedReason = null; - protected $gatewayStatusMessage = null; + public $gatewayStatusMessage = null; /** * CheckoutPaymentsDetailsHandler constructor. @@ -62,7 +62,7 @@ class TransactionIntegration * @param CasedataResourceModel $casedataResourceModel * @param Logger $logger * @param StoreManagerInterface $storeManager - * @param CheckoutCart $checkoutCart + * @param CheckoutSession $checkoutSession * @param TransactionsFactory $transactionsFactory * @param ConfigHelper $configHelper * @param Client $client @@ -72,7 +72,7 @@ public function __construct( CasedataResourceModel $casedataResourceModel, Logger $logger, StoreManagerInterface $storeManager, - CheckoutCart $checkoutCart, + CheckoutSession $checkoutSession, TransactionsFactory $transactionsFactory, ConfigHelper $configHelper, Client $client @@ -81,7 +81,7 @@ public function __construct( $this->casedataResourceModel = $casedataResourceModel; $this->logger = $logger; $this->storeManager = $storeManager; - $this->checkoutCart = $checkoutCart; + $this->checkoutSession = $checkoutSession; $this->transactionsFactory = $transactionsFactory; $this->configHelper = $configHelper; $this->client = $client; @@ -89,15 +89,15 @@ public function __construct( public function submitToTransactionApi() { - $quote = $this->checkoutCart->getQuote(); + $quote = $this->checkoutSession->getQuote(); - if (isset($quote) === false) { + if ($quote->isEmpty()) { return null; } $paymentMethod = $quote->getPayment()->getMethod(); - if (isset($paymentMethod) === false) { + if (empty($paymentMethod)) { return null; } diff --git a/Model/UpdateOrder.php b/Model/UpdateOrder.php index ff4c0414..447222a4 100644 --- a/Model/UpdateOrder.php +++ b/Model/UpdateOrder.php @@ -10,6 +10,7 @@ use Magento\Sales\Model\Order; use Magento\Sales\Model\OrderFactory; use Magento\Sales\Model\ResourceModel\Order as OrderResourceModel; +use Magento\Store\Model\ScopeInterface; use Signifyd\Connect\Helper\ConfigHelper; use Signifyd\Connect\Helper\OrderHelper; use Signifyd\Connect\Logger\Logger; @@ -29,72 +30,72 @@ class UpdateOrder /** * @var ConfigHelper */ - protected $configHelper; + public $configHelper; /** * @var OrderHelper */ - protected $orderHelper; + public $orderHelper; /** * @var Logger */ - protected $logger; + public $logger; /** * @var SerializerInterface */ - protected $serializer; + public $serializer; /** * @var ScopeConfigInterface */ - protected $scopeConfigInterface; + public $scopeConfigInterface; /** * @var OrderResourceModel */ - protected $orderResourceModel; + public $orderResourceModel; /** * @var HoldFactory */ - protected $holdFactory; + public $holdFactory; /** * @var UnholdFactory */ - protected $unholdFactory; + public $unholdFactory; /** * @var CancelFactory */ - protected $cancelFactory; + public $cancelFactory; /** * @var CaptureFactory */ - protected $captureFactory; + public $captureFactory; /** * @var RefundFactory */ - protected $refundFactory; + public $refundFactory; /** * @var UpdateOrderAction */ - protected $updateOrderAction; + public $updateOrderAction; /** * @var OrderFactory */ - protected $orderFactory; + public $orderFactory; /** * @var SignifydOrderResourceModel */ - protected $signifydOrderResourceModel; + public $signifydOrderResourceModel; /** * @param ConfigHelper $configHelper @@ -146,6 +147,25 @@ public function __construct( public function __invoke($case) { + $bypassUpdates = $this->scopeConfigInterface->getValue('signifyd/advanced/bypass_additional_updates'); + + if ($case->getMagentoStatus() == 'completed' && $bypassUpdates == 1) { + $order = $this->orderFactory->create(); + $this->signifydOrderResourceModel->load($order, $case->getData('order_id')); + + $this->logger->info( + 'Order ' . $order->getIncrementId() . ' will ' . + 'not be updated as the bypass for additional updates is enabled', + ['entity' => $order] + ); + $this->orderHelper->addCommentToStatusHistory( + $order, + "Signifyd: will not update the order as the bypass for additional updates is enabled" + ); + + return $case; + } + $orderAction = $this->updateOrderAction->handleGuaranteeChange($case); $this->logger->debug( @@ -270,6 +290,14 @@ public function __invoke($case) $this->orderResourceModel->getConnection()->rollBack(); } + return $case; + } catch (\Error $e) { + $this->logger->debug($e->getMessage()); + + if ($enableTransaction) { + $this->orderResourceModel->getConnection()->rollBack(); + } + return $case; } } diff --git a/Model/UpdateOrder/Action.php b/Model/UpdateOrder/Action.php index 0310faa1..6228a2db 100644 --- a/Model/UpdateOrder/Action.php +++ b/Model/UpdateOrder/Action.php @@ -19,22 +19,22 @@ class Action /** * @var Logger */ - protected $logger; + public $logger; /** * @var OrderFactory */ - protected $orderFactory; + public $orderFactory; /** * @var SignifydOrderResourceModel */ - protected $signifydOrderResourceModel; + public $signifydOrderResourceModel; /** * @var ConfigHelper */ - protected $configHelper; + public $configHelper; /** * @param Logger $logger diff --git a/Model/UpdateOrder/Cancel.php b/Model/UpdateOrder/Cancel.php index 5e1c5925..8e177bf2 100644 --- a/Model/UpdateOrder/Cancel.php +++ b/Model/UpdateOrder/Cancel.php @@ -21,32 +21,32 @@ class Cancel /** * @var ConfigHelper */ - protected $configHelper; + public $configHelper; /** * @var OrderHelper */ - protected $orderHelper; + public $orderHelper; /** * @var Logger */ - protected $logger; + public $logger; /** * @var OrderResourceModel */ - protected $orderResourceModel; + public $orderResourceModel; /** * @var OrderFactory */ - protected $orderFactory; + public $orderFactory; /** * @var SignifydOrderResourceModel */ - protected $signifydOrderResourceModel; + public $signifydOrderResourceModel; /** * @param ConfigHelper $configHelper @@ -85,6 +85,7 @@ public function __invoke($order, $case, $orderAction, $completeCase) $this->orderResourceModel->save($order); $completeCase = true; + $this->logger->debug("Signifyd: order canceled, {$orderAction["reason"]}", ['entity' => $order]); $this->orderHelper->addCommentToStatusHistory( $order, "Signifyd: order canceled, {$orderAction["reason"]}" @@ -100,6 +101,22 @@ public function __invoke($order, $case, $orderAction, $completeCase) $orderAction['action'] = false; + $this->orderHelper->addCommentToStatusHistory( + $order, + "Signifyd: order cannot be canceled, {$e->getMessage()}" + ); + throw new LocalizedException(__($e->getMessage())); + } catch (\Error $e) { + $this->logger->debug($e->__toString(), ['entity' => $order]); + $case->setEntries('fail', 1); + + if ($order->canHold()) { + $order->hold(); + $this->signifydOrderResourceModel->save($order); + } + + $orderAction['action'] = false; + $this->orderHelper->addCommentToStatusHistory( $order, "Signifyd: order cannot be canceled, {$e->getMessage()}" diff --git a/Model/UpdateOrder/Capture.php b/Model/UpdateOrder/Capture.php index 9b85ae89..ffb7ffb3 100644 --- a/Model/UpdateOrder/Capture.php +++ b/Model/UpdateOrder/Capture.php @@ -24,52 +24,52 @@ class Capture /** * @var ConfigHelper */ - protected $configHelper; + public $configHelper; /** * @var OrderHelper */ - protected $orderHelper; + public $orderHelper; /** * @var Logger */ - protected $logger; + public $logger; /** * @var OrderResourceModel */ - protected $orderResourceModel; + public $orderResourceModel; /** * @var InvoiceService */ - protected $invoiceService; + public $invoiceService; /** * @var InvoiceSender */ - protected $invoiceSender; + public $invoiceSender; /** * @var InvoiceResourceModel */ - protected $invoiceResourceModel; + public $invoiceResourceModel; /** * @var TransactionFactory */ - protected $transactionFactory; + public $transactionFactory; /** * @var OrderFactory */ - protected $orderFactory; + public $orderFactory; /** * @var SignifydOrderResourceModel */ - protected $signifydOrderResourceModel; + public $signifydOrderResourceModel; /** * @param ConfigHelper $configHelper @@ -148,7 +148,7 @@ public function __invoke($order, $case, $enableTransaction, $completeCase) $completeCase = true; } elseif ($order->getInvoiceCollection()->count() > 0) { - $this->logger->info("Invoice already created"); + $this->logger->info("Invoice already created", ['entity' => $order]); $completeCase = true; } else { $reason = $this->orderHelper->getCannotInvoiceReason($order); @@ -179,6 +179,22 @@ public function __invoke($order, $case, $enableTransaction, $completeCase) $this->signifydOrderResourceModel->save($order); } + $this->orderHelper->addCommentToStatusHistory( + $order, + "Signifyd: unable to create invoice: {$e->getMessage()}" + ); + } catch (\Error $e) { + $this->logger->debug('Error creating invoice: ' . $e->__toString(), ['entity' => $order]); + $case->setEntries('fail', 1); + + $order = $this->orderFactory->create(); + $this->signifydOrderResourceModel->load($order, $case->getData('order_id')); + + if ($order->canHold()) { + $order->hold(); + $this->signifydOrderResourceModel->save($order); + } + $this->orderHelper->addCommentToStatusHistory( $order, "Signifyd: unable to create invoice: {$e->getMessage()}" diff --git a/Model/UpdateOrder/Hold.php b/Model/UpdateOrder/Hold.php index 72429c1f..547d9c81 100644 --- a/Model/UpdateOrder/Hold.php +++ b/Model/UpdateOrder/Hold.php @@ -20,22 +20,22 @@ class Hold /** * @var ConfigHelper */ - protected $configHelper; + public $configHelper; /** * @var OrderHelper */ - protected $orderHelper; + public $orderHelper; /** * @var Logger */ - protected $logger; + public $logger; /** * @var OrderResourceModel */ - protected $orderResourceModel; + public $orderResourceModel; /** * @param ConfigHelper $configHelper @@ -61,8 +61,9 @@ public function __invoke($order, $case, $orderAction, $completeCase) try { $order->hold(); $this->orderResourceModel->save($order); - $completeCase = true; + + $this->logger->debug("Signifyd: {$orderAction["reason"]}", ['entity' => $order]); $this->orderHelper->addCommentToStatusHistory( $order, "Signifyd: {$orderAction["reason"]}" @@ -71,6 +72,13 @@ public function __invoke($order, $case, $orderAction, $completeCase) $this->logger->debug($e->__toString(), ['entity' => $order]); $case->setEntries('fail', 1); + $message = "Signifyd: order cannot be updated to on hold, {$e->getMessage()}"; + $this->orderHelper->addCommentToStatusHistory($order, $message); + throw new LocalizedException(__($e->getMessage())); + } catch (\Error $e) { + $this->logger->debug($e->__toString(), ['entity' => $order]); + $case->setEntries('fail', 1); + $message = "Signifyd: order cannot be updated to on hold, {$e->getMessage()}"; $this->orderHelper->addCommentToStatusHistory($order, $message); throw new LocalizedException(__($e->getMessage())); diff --git a/Model/UpdateOrder/Refund.php b/Model/UpdateOrder/Refund.php index 39a6448e..09f1e90d 100644 --- a/Model/UpdateOrder/Refund.php +++ b/Model/UpdateOrder/Refund.php @@ -22,42 +22,42 @@ class Refund /** * @var ConfigHelper */ - protected $configHelper; + public $configHelper; /** * @var OrderHelper */ - protected $orderHelper; + public $orderHelper; /** * @var Logger */ - protected $logger; + public $logger; /** * @var OrderResourceModel */ - protected $orderResourceModel; + public $orderResourceModel; /** * @var CreditmemoFactory */ - protected $creditmemoFactory; + public $creditmemoFactory; /** * @var CreditmemoService */ - protected $creditmemoService; + public $creditmemoService; /** * @var OrderFactory */ - protected $orderFactory; + public $orderFactory; /** * @var SignifydOrderResourceModel */ - protected $signifydOrderResourceModel; + public $signifydOrderResourceModel; /** * @param ConfigHelper $configHelper @@ -104,6 +104,7 @@ public function __invoke($order, $case, $completeCase) if ($invoices->getTotalCount() > 0) { $this->createInvoicesCreditMemo($invoices, $order); + $completeCase = true; } else { if ($order->canHold()) { $order->hold(); @@ -116,9 +117,8 @@ public function __invoke($order, $case, $completeCase) "tried to refund, but there is no invoice to add credit memo", ['entity' => $order] ); + $case->setEntries('fail', 1); } - - $completeCase = true; } catch (\Exception $e) { $order = $this->orderFactory->create(); $this->signifydOrderResourceModel->load($order, $case->getData('order_id')); @@ -134,6 +134,25 @@ public function __invoke($order, $case, $completeCase) ['entity' => $order] ); + $this->orderHelper->addCommentToStatusHistory( + $order, + "Signifyd: unable to create creditmemo: {$e->getMessage()}" + ); + } catch (\Error $e) { + $order = $this->orderFactory->create(); + $this->signifydOrderResourceModel->load($order, $case->getData('order_id')); + $case->setEntries('fail', 1); + + if ($order->canHold()) { + $order->hold(); + $this->signifydOrderResourceModel->save($order); + } + + $this->logger->debug( + 'Exception creating creditmemo: ' . $e->__toString(), + ['entity' => $order] + ); + $this->orderHelper->addCommentToStatusHistory( $order, "Signifyd: unable to create creditmemo: {$e->getMessage()}" diff --git a/Model/UpdateOrder/Unhold.php b/Model/UpdateOrder/Unhold.php index 4a849e77..b2b99be7 100644 --- a/Model/UpdateOrder/Unhold.php +++ b/Model/UpdateOrder/Unhold.php @@ -19,22 +19,22 @@ class Unhold /** * @var ConfigHelper */ - protected $configHelper; + public $configHelper; /** * @var OrderHelper */ - protected $orderHelper; + public $orderHelper; /** * @var Logger */ - protected $logger; + public $logger; /** * @var OrderResourceModel */ - protected $orderResourceModel; + public $orderResourceModel; /** * @param ConfigHelper $configHelper @@ -65,6 +65,7 @@ public function __invoke($order, $case, $orderAction, $completeCase) $completeCase = true; + $this->logger->debug("Signifyd: order status updated, {$orderAction["reason"]}", ['entity' => $order]); $this->orderHelper->addCommentToStatusHistory( $order, "Signifyd: order status updated, {$orderAction["reason"]}" @@ -73,6 +74,15 @@ public function __invoke($order, $case, $orderAction, $completeCase) $this->logger->debug($e->__toString(), ['entity' => $order]); $case->setEntries('fail', 1); + $this->orderHelper->addCommentToStatusHistory( + $order, + "Signifyd: order status cannot be updated, {$e->getMessage()}" + ); + throw new LocalizedException(__($e->getMessage())); + } catch (\Error $e) { + $this->logger->debug($e->__toString(), ['entity' => $order]); + $case->setEntries('fail', 1); + $this->orderHelper->addCommentToStatusHistory( $order, "Signifyd: order status cannot be updated, {$e->getMessage()}" diff --git a/Model/WebhookLink.php b/Model/WebhookLink.php index 71139763..2726b3d2 100644 --- a/Model/WebhookLink.php +++ b/Model/WebhookLink.php @@ -15,17 +15,17 @@ class WebhookLink implements CommentInterface /** * @var \Magento\Framework\Url */ - protected $urlBuilder; + public $urlBuilder; /** * @var \Magento\Store\Model\StoreManagerInterface */ - protected $storeManager; + public $storeManager; /** * @var \Magento\Framework\App\RequestInterface */ - protected $request; + public $request; /** * WebhookLink constructor. diff --git a/Observer/Api/Transaction.php b/Observer/Api/Transaction.php index 4f7cfaa9..8e70a2dd 100644 --- a/Observer/Api/Transaction.php +++ b/Observer/Api/Transaction.php @@ -13,17 +13,17 @@ class Transaction implements ObserverInterface /** * @var Logger */ - protected $logger; + public $logger; /** * @var ConfigHelper */ - protected $configHelper; + public $configHelper; /** * @var ProcessTransactionFactory */ - protected $processTransactionFactory; + public $processTransactionFactory; /** * Transaction constructor. @@ -45,7 +45,7 @@ public function execute(Observer $observer) { if ($this->configHelper->isEnabled()) { try { - /** @var $order \Magento\Sales\Model\Order */ + /** @var \Magento\Sales\Model\Order $order */ $order = $observer->getEvent()->getOrder(); $processTransaction = $this->processTransactionFactory->create(); diff --git a/Observer/Cancel.php b/Observer/Cancel.php index 55f91ca4..69437112 100644 --- a/Observer/Cancel.php +++ b/Observer/Cancel.php @@ -20,17 +20,17 @@ class Cancel implements ObserverInterface /** * @var \Signifyd\Connect\Logger\Logger */ - protected $logger; + public $logger; /** * @var \Signifyd\Connect\Helper\ConfigHelper */ - protected $configHelper; + public $configHelper; /** * @var Client */ - protected $client; + public $client; /** * Cancel constructor. @@ -51,7 +51,7 @@ public function __construct( public function execute(Observer $observer) { try { - /** @var $order Order */ + /** @var Order $order */ $order = $observer->getEvent()->getOrder(); if ($order instanceof Order == false) { @@ -63,7 +63,6 @@ public function execute(Observer $observer) } if ($order instanceof Order == false) { - /** @var \Magento\Sales\Model\Creditmemo $creditmemo */ $creditmemo = $observer->getEvent()->getCreditmemo(); if ($creditmemo instanceof \Magento\Sales\Model\Order\Creditmemo) { diff --git a/Observer/CronJob.php b/Observer/CronJob.php index a856526c..5ea5678b 100644 --- a/Observer/CronJob.php +++ b/Observer/CronJob.php @@ -3,14 +3,14 @@ namespace Signifyd\Connect\Observer; use Magento\Framework\Event\ObserverInterface; -use Magento\Framework\Registry; +use Signifyd\Connect\Model\Registry; class CronJob implements ObserverInterface { /** * @var Registry */ - protected $registry; + public $registry; /** * CronJob constructor. @@ -24,12 +24,7 @@ public function __construct(Registry $registry) public function execute(\Magento\Framework\Event\Observer $observer) { $cronJob = $observer->getEvent()->getData('job_name'); - $cronJobRegistry = $this->registry->registry('signifyd_cron_job_run'); - if (isset($cronJobRegistry)) { - $this->registry->unregister('signifyd_cron_job_run'); - } - - $this->registry->register('signifyd_cron_job_run', $cronJob); + $this->registry->setData('signifyd_cron_job_run', $cronJob); } } diff --git a/Observer/Debug/Order.php b/Observer/Debug/Order.php index e5b8dfdb..5cd8ce75 100644 --- a/Observer/Debug/Order.php +++ b/Observer/Debug/Order.php @@ -8,7 +8,7 @@ use Magento\Framework\Event\Observer; use Magento\Framework\Event\ObserverInterface; -use Magento\Framework\Registry; +use Signifyd\Connect\Model\Registry; use Magento\Framework\UrlInterface; use Signifyd\Connect\Logger\Debugger; use Signifyd\Connect\Helper\ConfigHelper; @@ -21,22 +21,22 @@ class Order implements ObserverInterface /** * @var \Signifyd\Connect\Logger\Debugger */ - protected $logger; + public $logger; /** * @var ConfigHelper */ - protected $configHelper; + public $configHelper; /** * @var UrlInterface */ - protected $url; + public $url; /** * @var Registry */ - protected $registry; + public $registry; /** * Order constructor. @@ -60,7 +60,7 @@ public function __construct( public function execute(Observer $observer) { try { - /** @var $order \Magento\Sales\Model\Order */ + /** @var \Magento\Sales\Model\Order $order */ $order = $observer->getEvent()->getOrder(); $log = $this->configHelper->getConfigData('signifyd/logs/log', $order); @@ -71,7 +71,7 @@ public function execute(Observer $observer) $currentState = $order->getOrigData('state'); $incrementId = $order->getIncrementId(); - $cronJob = $this->registry->registry('signifyd_cron_job_run'); + $cronJob = $this->registry->getData('signifyd_cron_job_run'); if (isset($cronJob)) { $this->logger->debug("cron job current process: {$cronJob}"); diff --git a/Observer/Fulfillment.php b/Observer/Fulfillment.php index 952be59b..5d087f98 100644 --- a/Observer/Fulfillment.php +++ b/Observer/Fulfillment.php @@ -3,22 +3,26 @@ namespace Signifyd\Connect\Observer; use Magento\Framework\Event\ObserverInterface; -use Magento\Framework\Registry; +use Signifyd\Connect\Model\Registry; use Signifyd\Connect\Helper\FulfillmentHelper; use Signifyd\Connect\Logger\Logger; class Fulfillment implements ObserverInterface { - /** @var FulfillmentHelper */ - protected $fulfillmentHelper; + /** + * @var FulfillmentHelper + */ + public $fulfillmentHelper; - /** @var Registry */ - protected $registry; + /** + * @var Registry + */ + public $registry; /** * @var Logger */ - protected $logger; + public $logger; /** * Fulfillment constructor. @@ -56,12 +60,12 @@ public function execute(\Magento\Framework\Event\Observer $observer) // This registry entry is used to don't trigger fulfillment creation multiple times on a single save $registryKey = "signifyd_action_shipment_{$shipment->getId()}"; - if ($this->registry->registry($registryKey) == 1) { + if ($this->registry->getData($registryKey) == 1) { $this->logger->info('Fulfillment will not proceed because registry key found: ' . $registryKey); return; } - $this->registry->register($registryKey, 1); + $this->registry->setData($registryKey, 1); $this->fulfillmentHelper->postFulfillmentToSignifyd($shipment); } diff --git a/Observer/Order/SalesOrderAddressSave.php b/Observer/Order/SalesOrderAddressSave.php index c5bc31e4..e9264600 100644 --- a/Observer/Order/SalesOrderAddressSave.php +++ b/Observer/Order/SalesOrderAddressSave.php @@ -4,113 +4,67 @@ use Magento\Framework\Event\Observer; use Magento\Framework\Event\ObserverInterface; -use Magento\Framework\Serialize\Serializer\Json as JsonSerializer; -use Magento\Sales\Model\Order; use Signifyd\Connect\Helper\ConfigHelper; use Signifyd\Connect\Logger\Logger; -use Signifyd\Connect\Model\Casedata\UpdateCaseFactory; -use Signifyd\Models\PaymentUpdateFactory; use Signifyd\Connect\Model\CasedataFactory; +use Signifyd\Connect\Model\ProcessCron\Reroute as ProcessCronReroute; use Signifyd\Connect\Model\ResourceModel\Casedata as CasedataResourceModel; -use Signifyd\Connect\Model\UpdateOrderFactory; -use Signifyd\Connect\Model\Api\ShipmentsFactory; -use Signifyd\Connect\Model\Api\DeviceFactory; -use Signifyd\Connect\Model\Api\Core\Client; +use Signifyd\Connect\Model\RerouteFactory; +use Signifyd\Connect\Model\ResourceModel\Reroute as RerouteResourceModel; class SalesOrderAddressSave implements ObserverInterface { - /** - * @var PaymentUpdateFactory - */ - protected $paymentUpdateFactory; - /** * @var CasedataFactory */ - protected $casedataFactory; + public $casedataFactory; /** * @var CasedataResourceModel */ - protected $casedataResourceModel; + public $casedataResourceModel; /** * @var ConfigHelper */ - protected $configHelper; - - /** - * @var JsonSerializer - */ - protected $jsonSerializer; + public $configHelper; /** * @var Logger */ - protected $logger; + public $logger; /** - * @var UpdateCaseFactory + * @var ProcessCronReroute */ - protected $updateCaseFactory; + public $processCronReroute; /** - * @var UpdateOrderFactory + * @var RerouteFactory */ - protected $updateOrderFactory; + public $rerouteFactory; /** - * @var ShipmentsFactory + * @var RerouteResourceModel */ - protected $shipmentsFactory; + public $rerouteResourceModel; - /** - * @var Client - */ - protected $client; - - /** - * @var DeviceFactory - */ - protected $deviceFactory; - - /** - * @param PaymentUpdateFactory $paymentUpdateFactory - * @param CasedataFactory $casedataFactory - * @param CasedataResourceModel $casedataResourceModel - * @param ConfigHelper $configHelper - * @param JsonSerializer $jsonSerializer - * @param Logger $logger - * @param UpdateCaseFactory $updateCaseFactory - * @param UpdateOrderFactory $updateOrderFactory - * @param ShipmentsFactory $shipmentsFactory - * @param Client $client - * @param DeviceFactory $deviceFactory - */ public function __construct( - PaymentUpdateFactory $paymentUpdateFactory, CasedataFactory $casedataFactory, CasedataResourceModel $casedataResourceModel, ConfigHelper $configHelper, - JsonSerializer $jsonSerializer, Logger $logger, - UpdateCaseFactory $updateCaseFactory, - UpdateOrderFactory $updateOrderFactory, - ShipmentsFactory $shipmentsFactory, - Client $client, - DeviceFactory $deviceFactory + ProcessCronReroute $processCronReroute, + RerouteFactory $rerouteFactory, + RerouteResourceModel $rerouteResourceModel ) { - $this->paymentUpdateFactory = $paymentUpdateFactory; $this->casedataFactory = $casedataFactory; $this->casedataResourceModel = $casedataResourceModel; $this->configHelper = $configHelper; - $this->jsonSerializer = $jsonSerializer; $this->logger = $logger; - $this->updateCaseFactory = $updateCaseFactory; - $this->updateOrderFactory = $updateOrderFactory; - $this->shipmentsFactory = $shipmentsFactory; - $this->client = $client; - $this->deviceFactory = $deviceFactory; + $this->processCronReroute = $processCronReroute; + $this->rerouteFactory = $rerouteFactory; + $this->rerouteResourceModel = $rerouteResourceModel; } public function execute(Observer $observer) @@ -139,41 +93,18 @@ public function execute(Observer $observer) return; } - $this->logger->info("Send case update for order {$order->getIncrementId()}"); - - $makeShipments = $this->shipmentsFactory->create(); - $shipments = $makeShipments($order); - $recipient = $shipments[0]['destination']; - $recipientJson = $this->jsonSerializer->serialize($recipient); - $newHashToValidateReroute = sha1($recipientJson); - $currentHashToValidateReroute = $case->getEntries('hash'); - - if ($newHashToValidateReroute == $currentHashToValidateReroute) { - $this->logger->info("No data changes, will not update order {$order->getIncrementId()}"); - return; - } - - $device = $this->deviceFactory->create(); - $rerout = []; - $rerout['orderId'] = $order->getIncrementId(); - $rerout['device'] = $device($order->getQuoteId(), $order->getStoreId()); - $rerout['shipments'] = $shipments; - $updateResponse = $this->client->createReroute($rerout, $order); - - $this->logger->info("Case updated for order {$order->getIncrementId()}"); - $this->logger->info($this->jsonSerializer->serialize($updateResponse)); - - $case->setEntries('hash', $newHashToValidateReroute); - $updateCase = $this->updateCaseFactory->create(); - $case = $updateCase($case, $updateResponse); + /** @var \Signifyd\Connect\Model\Reroute $reroute */ + $reroute = $this->rerouteFactory->create(); + $this->rerouteResourceModel->load($reroute, $orderId, 'order_id'); - if ($case->getOrigData('signifyd_status') !== $case->getData('signifyd_status')) { - $case->setStatus(\Signifyd\Connect\Model\Casedata::IN_REVIEW_STATUS); - $updateOrder = $this->updateOrderFactory->create(); - $case = $updateOrder($case); + if ($reroute->isEmpty() === false) { + $this->rerouteResourceModel->delete($reroute); + $reroute = $this->rerouteFactory->create(); } - $this->casedataResourceModel->save($case); + $reroute->setOrderId($orderId); + $this->rerouteResourceModel->save($reroute); + ($this->processCronReroute)($reroute); } catch (\Exception $e) { $this->logger->info('Failed to update case'); } diff --git a/Observer/Order/Save/Before.php b/Observer/Order/Save/Before.php index e249349b..8f8f52a9 100644 --- a/Observer/Order/Save/Before.php +++ b/Observer/Order/Save/Before.php @@ -10,33 +10,39 @@ use Magento\Store\Model\StoreManagerInterface; use Signifyd\Connect\Logger\Logger; use Signifyd\Connect\Helper\ConfigHelper; +use Magento\Framework\Serialize\Serializer\Json as JsonSerializer; class Before implements ObserverInterface { /** - * @var Logger; + * @var Logger */ - protected $logger; + public $logger; /** * @var AppState */ - protected $appState; + public $appState; /** * @var ConfigHelper */ - protected $configHelper; + public $configHelper; /** * @var StoreManagerInterface */ - protected $storeManager; + public $storeManager; /** * @var RequestInterface */ - protected $request; + public $request; + + /** + * @var JsonSerializer + */ + public $jsonSerializer; /** * Before constructor. @@ -45,19 +51,22 @@ class Before implements ObserverInterface * @param ConfigHelper $configHelper * @param StoreManagerInterface $storeManager * @param RequestInterface $request + * @param JsonSerializer $jsonSerializer */ public function __construct( Logger $loger, AppState $appState, ConfigHelper $configHelper, StoreManagerInterface $storeManager, - RequestInterface $request + RequestInterface $request, + JsonSerializer $jsonSerializer ) { $this->logger = $loger; $this->appState = $appState; $this->configHelper = $configHelper; $this->storeManager = $storeManager; $this->request = $request; + $this->jsonSerializer = $jsonSerializer; } /** @@ -67,7 +76,7 @@ public function __construct( public function execute(Observer $observer, $checkOwnEventsMethods = true) { try { - /** @var $order Order */ + /** @var Order $order */ $order = $observer->getEvent()->getOrder(); if (!is_object($order)) { @@ -77,6 +86,8 @@ public function execute(Observer $observer, $checkOwnEventsMethods = true) if ($this->configHelper->isEnabled($order) == false) { return; } + $data = $this->request->getContent(); + $this->setPaymentData($order, $data); // Fix for Magento bug https://github.com/magento/magento2/issues/7227 // x_forwarded_for should be copied from quote, but quote does not have the field on database @@ -97,4 +108,21 @@ public function execute(Observer $observer, $checkOwnEventsMethods = true) $this->logger->error($ex->getMessage(), $context); } } + + /** + * @param $order + * @param $data + * @return void + */ + public function setPaymentData($order, $data) + { + if ($order->getPayment()->getMethod() === 'rootways_authorizecim_option' && empty($data) === false) { + $dataArray = $this->jsonSerializer->unserialize($data); + if (isset($dataArray['paymentMethod']) && + isset($dataArray['paymentMethod']['additional_data']) && + isset($dataArray['paymentMethod']['additional_data']['card_bin'])) { + $order->getPayment()->setAdditionalInformation('card_bin', $dataArray['paymentMethod']['additional_data']['card_bin']); + } + } + } } diff --git a/Observer/PreAuth.php b/Observer/PreAuth.php index 95f92cfd..6f404dbf 100644 --- a/Observer/PreAuth.php +++ b/Observer/PreAuth.php @@ -22,83 +22,89 @@ use Magento\Framework\App\Request\Http as RequestHttp; use Magento\Framework\Serialize\Serializer\Json as JsonSerializer; use Magento\Framework\ObjectManagerInterface; +use Signifyd\Connect\Model\Api\Recipient; class PreAuth implements ObserverInterface { /** * @var Logger */ - protected $logger; + public $logger; /** * @var CartRepositoryInterface */ - protected $quoteRepository; + public $quoteRepository; /** * @var ResponseFactory */ - protected $responseFactory; + public $responseFactory; /** * @var UrlInterface */ - protected $url; + public $url; /** * @var RedirectFactory */ - protected $resultRedirectFactory; + public $resultRedirectFactory; /** * @var ResponseInterface */ - protected $responseInterface; + public $responseInterface; /** * @var ScopeConfigInterface */ - protected $scopeConfigInterface; + public $scopeConfigInterface; /** * @var CasedataFactory */ - protected $casedataFactory; + public $casedataFactory; /** * @var CasedataResourceModel */ - protected $casedataResourceModel; + public $casedataResourceModel; /** * @var RequestHttp */ - protected $requestHttp; + public $requestHttp; /** * @var JsonSerializer */ - protected $jsonSerializer; + public $jsonSerializer; /** * @var ConfigHelper */ - protected $configHelper; + public $configHelper; /** * @var ObjectManagerInterface */ - protected $objectManagerInterface; + public $objectManagerInterface; /** * @var CheckoutOrderFactory */ - protected $checkoutOrderFactory; + public $checkoutOrderFactory; /** * @var Client */ - protected $client; + public $client; + + /** + * @var Recipient + */ + public $recipient; /** * PreAuth constructor. @@ -117,6 +123,7 @@ class PreAuth implements ObserverInterface * @param ObjectManagerInterface $objectManagerInterface * @param CheckoutOrderFactory $checkoutOrderFactory * @param Client $client + * @param Recipient $recipient */ public function __construct( Logger $logger, @@ -133,7 +140,8 @@ public function __construct( ConfigHelper $configHelper, ObjectManagerInterface $objectManagerInterface, CheckoutOrderFactory $checkoutOrderFactory, - Client $client + Client $client, + Recipient $recipient ) { $this->logger = $logger; $this->quoteRepository = $quoteRepository; @@ -150,6 +158,7 @@ public function __construct( $this->objectManagerInterface = $objectManagerInterface; $this->checkoutOrderFactory = $checkoutOrderFactory; $this->client = $client; + $this->recipient = $recipient; } public function execute(Observer $observer) @@ -162,7 +171,7 @@ public function execute(Observer $observer) return; } - $this->logger->info("policy validation"); + $this->logger->info("policy validation", ['entity' => $quote]); $policyName = $this->configHelper->getPolicyName( $quote->getStore()->getScopeType(), @@ -184,6 +193,12 @@ public function execute(Observer $observer) $paymentMethod = $dataArray['paymentMethod']['method']; } + if (isset($paymentMethod) && $this->configHelper->isPaymentRestricted($paymentMethod)) { + $message = 'Case creation with payment ' . $paymentMethod . ' is restricted'; + $this->logger->debug($message, ['entity' => $quote]); + return; + } + $isPreAuth = $this->configHelper->getIsPreAuth( $policyName, $paymentMethod, @@ -192,7 +207,7 @@ public function execute(Observer $observer) ); if ($isPreAuth === false) { - /** @var $case \Signifyd\Connect\Model\Casedata */ + /** @var \Signifyd\Connect\Model\Casedata $case */ $case = $this->casedataFactory->create(); $this->casedataResourceModel->load($case, $quote->getId(), 'quote_id'); @@ -203,11 +218,13 @@ public function execute(Observer $observer) return; } - $policyRejectMessage = $this->scopeConfigInterface->getValue( - 'signifyd/advanced/policy_pre_auth_reject_message', - ScopeInterface::SCOPE_STORES, - $quote->getStoreId() - ); + $customerGroupId = $quote->getCustomerGroupId(); + + if ($this->configHelper->isCustomerGroupRestricted($customerGroupId)) { + $message = 'Case creation with customer group id ' . $customerGroupId . ' is restricted'; + $this->logger->debug($message, ['entity' => $quote]); + return; + } $checkoutPaymentDetails = []; @@ -273,10 +290,18 @@ public function execute(Observer $observer) $checkoutPaymentDetails['cardExpiryYear'] = $dataArray['paymentMethod']['additional_data']['cardExpiryYear'] ?? null; + + if ($paymentMethod === 'rootways_authorizecim_option') { + $checkoutPaymentDetails = $this->mappingForAuthnetRootwaysCim($checkoutPaymentDetails, $dataArray); + } + + if ($paymentMethod === 'authnetcim') { + $checkoutPaymentDetails = $this->mappingForAuthnet($checkoutPaymentDetails, $dataArray); + } } } - $this->logger->info("Creating case for quote {$quote->getId()}"); + $this->logger->info("Creating case for quote {$quote->getId()}", ['entity' => $quote]); $this->addSignifydDataToPayment($quote, $checkoutPaymentDetails); $checkoutOrder = $this->checkoutOrderFactory->create(); $caseFromQuote = $checkoutOrder($quote, $checkoutPaymentDetails, $paymentMethod); @@ -297,7 +322,7 @@ public function execute(Observer $observer) $magentoStatus = Casedata::IN_REVIEW_STATUS; } - /** @var $case \Signifyd\Connect\Model\Casedata */ + /** @var \Signifyd\Connect\Model\Casedata $case */ $case = $this->casedataFactory->create(); $this->casedataResourceModel->load($case, $quote->getId(), 'quote_id'); $case->setCode($caseResponse->signifydId); @@ -319,12 +344,17 @@ public function execute(Observer $observer) ); } + $recipient = ($this->recipient)($quote); + $recipientJson = $this->jsonSerializer->serialize($recipient); + $hashToValidateReroute = sha1($recipientJson); + $case->setEntries('hash', $hashToValidateReroute); + $this->casedataResourceModel->save($case); } } catch (\Exception $e) { $caseAction = false; $caseResponse = null; - $this->logger->error($e->getMessage()); + $this->logger->error($e->getMessage(), ['entity' => $quote]); } $enabledConfig = $this->scopeConfigInterface->getValue( @@ -340,6 +370,12 @@ public function execute(Observer $observer) $stopCheckoutProcess = $this->getStopCheckoutProcess($caseResponse, $caseAction); if ($stopCheckoutProcess) { + $policyRejectMessage = $this->scopeConfigInterface->getValue( + 'signifyd/advanced/policy_pre_auth_reject_message', + ScopeInterface::SCOPE_STORES, + $quote->getStoreId() + ); + throw new LocalizedException(__($policyRejectMessage)); } } @@ -367,12 +403,17 @@ public function addSignifydDataToPayment($quote, $checkoutPaymentDetails) return; } - if (isset($checkoutPaymentDetails['cardBin'])) { + $ccNumber = $quote->getPayment()->getData('cc_number'); + + if (!isset($ccNumber) && + isset($checkoutPaymentDetails['cardBin']) && + isset($checkoutPaymentDetails['cardLast4'])) { + $quote->getPayment()->setData( 'cc_number', - $checkoutPaymentDetails['cardBin'] . - 000000 . - $checkoutPaymentDetails['cardLast4'] ?? 0000 + ($checkoutPaymentDetails['cardBin'] ?? '000000') . + '000000' . + ($checkoutPaymentDetails['cardLast4'] ?? '0000') ); } @@ -392,4 +433,62 @@ public function addSignifydDataToPayment($quote, $checkoutPaymentDetails) $quote->getPayment()->setCcExpYear($checkoutPaymentDetails['cardExpiryYear']); } } + + /** + * @param $checkoutPaymentDetails + * @param $dataArray + * @return mixed + */ + public function mappingForAuthnetRootwaysCim($checkoutPaymentDetails, $dataArray) + { + $additionalData = $dataArray['paymentMethod']['additional_data']; + + $checkoutPaymentDetails['cardExpiryMonth'] = $additionalData['cc_exp_month'] ?? null; + $checkoutPaymentDetails['cardExpiryYear'] = $additionalData['cc_exp_year'] ?? null; + + $cc_number = $additionalData['cc_number'] ?? null; + if ($cc_number) { + $checkoutPaymentDetails['cardLast4'] = substr($cc_number, -4); + $checkoutPaymentDetails['cardBin'] = substr($cc_number, 0, 6); + } else { + $checkoutPaymentDetails['cardLast4'] = null; + $checkoutPaymentDetails['cardBin'] = $additionalData['card_bin'] ?? null; + } + + return $checkoutPaymentDetails; + } + + /** + * @param $checkoutPaymentDetails + * @param $dataArray + * @return mixed + */ + public function mappingForAuthnet($checkoutPaymentDetails, $dataArray) + { + $additionalData = $dataArray['paymentMethod']['additional_data']; + + if (isset($dataArray['paymentMethod']['additional_data']['card_id'])) { + /** @var \ParadoxLabs\TokenBase\Model\ResourceModel\Card\Collection $cardCollection */ + $cardCollection = $this->objectManagerInterface->create( + \ParadoxLabs\TokenBase\Model\ResourceModel\Card\CollectionFactory::class + )->create() + ->addFieldToFilter('hash', ['eq' => $dataArray['paymentMethod']['additional_data']['card_id']]); + + $card = $cardCollection->getFirstItem(); + + if (empty($card->getData('additional')) === false) { + $additionalData = $this->jsonSerializer->unserialize($card->getData('additional')); + } + } + + $checkoutPaymentDetails['cardExpiryMonth'] = $additionalData['cc_exp_month'] ?? null; + + $checkoutPaymentDetails['cardExpiryYear'] = $additionalData['cc_exp_year'] ?? null; + + $checkoutPaymentDetails['cardLast4'] = $additionalData['cc_last4'] ?? null; + + $checkoutPaymentDetails['cardBin'] = $additionalData['cc_bin'] ?? null; + + return $checkoutPaymentDetails; + } } diff --git a/Observer/Purchase.php b/Observer/Purchase.php index ac71eb83..64aff6b6 100644 --- a/Observer/Purchase.php +++ b/Observer/Purchase.php @@ -8,6 +8,7 @@ use Magento\Framework\Event\Observer; use Magento\Framework\Event\ObserverInterface; +use Signifyd\Connect\Model\Registry; use Magento\Framework\Serialize\Serializer\Json as JsonSerializer; use Magento\Sales\Model\Order; use Magento\Sales\Model\OrderFactory; @@ -26,6 +27,7 @@ use Signifyd\Connect\Model\Api\RecipientFactory; use Signifyd\Connect\Model\Api\SaleOrderFactory; use Signifyd\Connect\Model\Api\Core\Client; +use Signifyd\Connect\Model\PaymentVerificationFactory; /** * Observer for purchase event. Sends order data to Signifyd service @@ -33,40 +35,40 @@ class Purchase implements ObserverInterface { /** - * @var Logger; + * @var Logger */ - protected $logger; + public $logger; /** * @var ConfigHelper */ - protected $configHelper; + public $configHelper; /** * @var CasedataFactory */ - protected $casedataFactory; + public $casedataFactory; /** * @var CasedataResourceModel */ - protected $casedataResourceModel; + public $casedataResourceModel; /** * @var SignifydOrderResourceModel */ - protected $signifydOrderResourceModel; + public $signifydOrderResourceModel; /** * @var OrderFactory */ - protected $orderFactory; + public $orderFactory; /** * Methods that should wait e-mail sent to hold order * @var array */ - protected $specialMethods = ['payflow_express']; + public $specialMethods = ['payflow_express']; /** * List of methods that uses a different event for triggering case creation @@ -75,57 +77,67 @@ class Purchase implements ObserverInterface * * @var array */ - protected $ownEventsMethods = ['authorizenet_directpost', 'paypal_express']; + public $ownEventsMethods = ['authorizenet_directpost', 'paypal_express']; /** * @var DateTime */ - protected $dateTime; + public $dateTime; /** * @var ScopeConfigInterface */ - protected $scopeConfigInterface; + public $scopeConfigInterface; /** * @var StoreManagerInterface */ - protected $storeManager; + public $storeManager; /** * @var AppState */ - protected $appState; + public $appState; /** * @var CasedataCollectionFactory */ - protected $casedataCollectionFactory; + public $casedataCollectionFactory; /** * @var JsonSerializer */ - protected $jsonSerializer; + public $jsonSerializer; /** * @var UpdateOrderAction */ - protected $updateOrderAction; + public $updateOrderAction; /** * @var RecipientFactory */ - protected $recipientFactory; + public $recipientFactory; /** * @var SaleOrderFactory */ - protected $saleOrderFactory; + public $saleOrderFactory; /** * @var Client */ - protected $client; + public $client; + + /** + * @var PaymentVerificationFactory + */ + public $paymentVerificationFactory; + + /** + * @var Registry + */ + protected $registry; /** * Purchase constructor. @@ -145,6 +157,8 @@ class Purchase implements ObserverInterface * @param RecipientFactory $recipientFactory * @param SaleOrderFactory $saleOrderFactory * @param Client $client + * @param PaymentVerificationFactory $paymentVerificationFactory + * @param Registry $registry */ public function __construct( Logger $logger, @@ -162,7 +176,9 @@ public function __construct( JsonSerializer $jsonSerializer, RecipientFactory $recipientFactory, SaleOrderFactory $saleOrderFactory, - Client $client + Client $client, + PaymentVerificationFactory $paymentVerificationFactory, + Registry $registry ) { $this->logger = $logger; $this->configHelper = $configHelper; @@ -180,6 +196,8 @@ public function __construct( $this->recipientFactory = $recipientFactory; $this->saleOrderFactory = $saleOrderFactory; $this->client = $client; + $this->paymentVerificationFactory = $paymentVerificationFactory; + $this->registry = $registry; } /** @@ -188,12 +206,15 @@ public function __construct( */ public function execute(Observer $observer, $checkOwnEventsMethods = true) { - try { - $this->logger->info('Processing Signifyd event ' . $observer->getEvent()->getName()); + /** @var Order $order */ + $order = $observer->getEvent()->getOrder(); + try { /** @var $order Order */ $order = $observer->getEvent()->getOrder(); + $this->logger->info('Processing Signifyd event ' . $observer->getEvent()->getName(), ['entity' => $order]); + if (isset($order) === false) { return; } @@ -217,7 +238,7 @@ public function execute(Observer $observer, $checkOwnEventsMethods = true) $casesFromQuotes->getFirstItem()->getMagentoStatus() != 'completed' ) { $casesFromQuote = $casesFromQuotes->getFirstItem(); - /** @var $case \Signifyd\Connect\Model\Casedata */ + /** @var \Signifyd\Connect\Model\Casedata $casesFromQuoteLoaded */ $casesFromQuoteLoaded = $this->casedataFactory->create(); $this->casedataResourceModel->load($casesFromQuoteLoaded, $casesFromQuote->getCode(), 'code'); $orderId = $casesFromQuoteLoaded->getData('order_id'); @@ -234,7 +255,8 @@ public function execute(Observer $observer, $checkOwnEventsMethods = true) if ($casesFromQuoteLoaded->getData('magento_status') == Casedata::PRE_AUTH) { $this->logger->info( "Completing case for order {$order->getIncrementId()} ({$order->getId()}) " . - "because it is a pre auth case" + "because it is a pre auth case", + ['entity' => $order] ); $casesFromQuoteLoaded->setData('magento_status', Casedata::COMPLETED_STATUS); } @@ -261,7 +283,7 @@ public function execute(Observer $observer, $checkOwnEventsMethods = true) $incrementId = $order->getIncrementId(); if ($this->isIgnored($order)) { - $this->logger->debug("Order {$incrementId} ignored"); + $this->logger->debug("Order {$incrementId} ignored", ['entity' => $order]); return; } @@ -280,13 +302,25 @@ public function execute(Observer $observer, $checkOwnEventsMethods = true) } if ($this->configHelper->isPaymentRestricted($paymentMethod)) { + $restrictedPaymentMethods = + $this->configHelper->getConfigData('signifyd/general/restrict_payment_methods') ?? ''; $message = 'Case creation for order ' . $incrementId . - ' with payment ' . $paymentMethod . ' is restricted'; + ' with payment ' . $paymentMethod . ' is restricted' . + ' by rule ' . $restrictedPaymentMethods; $this->logger->debug($message, ['entity' => $order]); return; } - /** @var $case \Signifyd\Connect\Model\Casedata */ + $customerGroupId = $order->getCustomerGroupId(); + + if ($this->configHelper->isCustomerGroupRestricted($customerGroupId)) { + $message = 'Case creation for order ' . $incrementId . + ' with customer group id ' . $customerGroupId . ' is restricted'; + $this->logger->debug($message, ['entity' => $order]); + return; + } + + /** @var \Signifyd\Connect\Model\Casedata $case */ $case = $this->casedataFactory->create(); $this->casedataResourceModel->load($case, $order->getId(), 'order_id'); @@ -346,6 +380,15 @@ public function execute(Observer $observer, $checkOwnEventsMethods = true) return; } + $gatewayRestriction = $this->registry->getData('gateway_restriction'); + + if (isset($gatewayRestriction)) { + $message = 'Case creation for order ' . $incrementId . + ' is restricted by gateway: ' . $gatewayRestriction; + $this->logger->debug($message, ['entity' => $order]); + return; + } + $message = "Creating case for order {$incrementId} ({$order->getId()}), state {$state}, payment method {$paymentMethod}"; $this->logger->debug($message, ['entity' => $order]); @@ -357,14 +400,15 @@ public function execute(Observer $observer, $checkOwnEventsMethods = true) $saleOrder = $this->saleOrderFactory->create(); $orderData = $saleOrder($order); - // Stop case sending if order has an async payment method - if (in_array($paymentMethod, $this->getAsyncPaymentMethodsConfig()) && - isset($orderData['transactions']) && - isset($orderData['transactions'][0]) && - isset($orderData['transactions'][0]['verifications']) && - isset($orderData['transactions'][0]['verifications']['avsResponseCode']) === false && - isset($orderData['transactions'][0]['verifications']['cvvResponseCode']) === false - ) { + $hasAsyncRestriction = $this->getHasAsyncRestriction($paymentMethod); + + if (in_array($paymentMethod, $this->getAsyncPaymentMethodsConfig()) && $hasAsyncRestriction === false) { + + /** @var \Signifyd\Connect\Model\Payment\Base\AsyncChecker $asyncCheck */ + $asyncCheck = $this->paymentVerificationFactory->createPaymentAsyncChecker($order->getPayment()->getMethod()); + } + + if (isset($asyncCheck)) { $case->setMagentoStatus(Casedata::ASYNC_WAIT); try { @@ -377,7 +421,7 @@ public function execute(Observer $observer, $checkOwnEventsMethods = true) // Initial hold order $this->holdOrder($order, $case, $isPassive); } catch (\Exception $ex) { - $this->logger->error($ex->__toString()); + $this->logger->error($ex->__toString(), ['entity' => $order]); } return; @@ -445,6 +489,30 @@ public function getAsyncPaymentMethodsConfig() return $asyncPaymentMethods; } + /** + * Get async payment methods from store configs + * + * @return bool + */ + public function getHasAsyncRestriction($paymentMethod) + { + try { + //stripe payments no longer needs to be async in versions 3.4.0 or higher + if ($paymentMethod == 'stripe_payments') { + $stripeVersion = \StripeIntegration\Payments\Model\Config::$moduleVersion; + $process = version_compare($stripeVersion, '3.4.0') >= 0 ? "synchronous" : "asynchronous"; + + $this->logger->info("Stripe on version {$stripeVersion} is " . $process); + + return version_compare($stripeVersion, '3.4.0') >= 0; + } + } catch (\Exception $e) { + + } + + return false; + } + /** * Check if order is ignored based on installation date * @@ -465,8 +533,8 @@ public function isIgnored(Order $order) $createdAtDate = $this->dateTime->gmtTimestamp($order->getCreatedAt()); if ($createdAtDate < $installationDate) { - $this->logger->info("Installation date: {$installationDate}"); - $this->logger->info("Created at date: {$createdAtDate}"); + $this->logger->info("Installation date: {$installationDate}", ['entity' => $order]); + $this->logger->info("Created at date: {$createdAtDate}", ['entity' => $order]); return true; } else { @@ -562,6 +630,10 @@ public function holdOrder(Order $order, Casedata $case, $isPassive = false) return false; } + if ($order->getPayment()->getMethod() === 'adyen_pay_by_link') { + return false; + } + $this->logger->debug( 'Purchase Observer Order Hold: No: ' . $order->getIncrementId(), ['entity' => $order] diff --git a/Patch/MAG-925-Fix-cron-processing-for-large-batches.patch b/Patch/MAG-925-Fix-cron-processing-for-large-batches.patch new file mode 100644 index 00000000..72d7dfa6 --- /dev/null +++ b/Patch/MAG-925-Fix-cron-processing-for-large-batches.patch @@ -0,0 +1,66 @@ +diff --git a/vendor/signifyd/module-connect/Model/Casedata.php b/vendor/signifyd/module-connect/Model/Casedata.php +index 79486cd..dcd4935 100644 +--- a/vendor/signifyd/module-connect/Model/Casedata.php ++++ b/vendor/signifyd/module-connect/Model/Casedata.php +@@ -228,13 +228,15 @@ class Casedata extends AbstractModel + * @param $updated + * @return mixed + */ +- public function setUpdated($updated = null) ++ public function setUpdated($updated = null, $updateRetries = true) + { + if (empty($updated)) { + $updated = date('Y-m-d H:i:s', time()); + } + +- $this->setRetries(0); ++ if ($updateRetries) { ++ $this->setRetries(0); ++ } + + return parent::setUpdated($updated); + } +diff --git a/vendor/signifyd/module-connect/Model/Casedata/FilterCasesByStatus.php b/vendor/signifyd/module-connect/Model/Casedata/FilterCasesByStatus.php +index 8d43013..9b1f364 100644 +--- a/vendor/signifyd/module-connect/Model/Casedata/FilterCasesByStatus.php ++++ b/vendor/signifyd/module-connect/Model/Casedata/FilterCasesByStatus.php +@@ -88,13 +88,8 @@ class FilterCasesByStatus extends AbstractHelper + ['updated'] + ); + ++ $casesCollection->setOrder('updated', 'ASC'); + $cronBatchSize = $this->configHelper->getCronBatchSize(); +- +- if (isset($cronBatchSize) && is_numeric($cronBatchSize)) { +- $casesCollection->setPageSize((int)$cronBatchSize); +- $casesCollection->setOrder('updated', 'ASC'); +- } +- + $casesToRetry = []; + + /** @var \Signifyd\Connect\Model\Casedata $case */ +@@ -107,9 +102,9 @@ class FilterCasesByStatus extends AbstractHelper + $secondsAfterUpdate = $case->getData('seconds_after_update'); + + if ($secondsAfterUpdate > $retryTimes[$retries]) { +- + $casesToRetry[$caseToUpdate->getId()] = $caseToUpdate; + $caseToUpdate->setData('retries', $retries + 1); ++ $caseToUpdate->setUpdated(null, false); + $this->casedataResourceModel->save($caseToUpdate); + } + } catch (\Exception $e) { +@@ -119,6 +114,13 @@ class FilterCasesByStatus extends AbstractHelper + ['entity' => $case] + ); + } ++ ++ if (isset($cronBatchSize) ++ && is_numeric($cronBatchSize) ++ && count($casesToRetry) >= $cronBatchSize ++ ) { ++ break; ++ } + } + + return $casesToRetry; diff --git a/Patch/pre-auth-authorizenet.patch b/Patch/pre-auth-authorizenet.patch index 2b588bec..1cc67910 100644 --- a/Patch/pre-auth-authorizenet.patch +++ b/Patch/pre-auth-authorizenet.patch @@ -1,23 +1,8 @@ -From 2124338b987b96a4772fe8c0e86a7a0e6a74d170 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?=C3=89bano=20Lopes?= -Date: Wed, 11 Jan 2023 13:39:13 +0000 -Subject: [PATCH] 5.3.0-MAG-786: AuthNet. - ---- - .../ParadoxLabs/Authnetcim/Model/Gateway.php | 113 ++++++++++++++++++ - Observer/PreAuth.php | 38 ++++++ - docs/PASS-PAYMENT-PRE-AUTH.md | 9 ++ - docs/TRANSACTIONS-INTEGRATION.md | 4 +- - etc/config.xml | 2 +- - etc/di.xml | 2 + - 6 files changed, 165 insertions(+), 3 deletions(-) - create mode 100644 Model/ParadoxLabs/Authnetcim/Model/Gateway.php - -diff --git a/vendor/signifyd/module-connect/Model/ParadoxLabs/Authnetcim/Model/Gateway.php b/vendor/signifyd/module-connect/Model/ParadoxLabs/Authnetcim/Model/Gateway.php +diff --git a/Model/ParadoxLabs/Authnetcim/Model/Gateway.php b/Model/ParadoxLabs/Authnetcim/Model/Gateway.php new file mode 100644 index 0000000..0dbba48 --- /dev/null -+++ b/vendor/signifyd/module-connect/Model/ParadoxLabs/Authnetcim/Model/Gateway.php ++++ b/Model/ParadoxLabs/Authnetcim/Model/Gateway.php @@ -0,0 +1,113 @@ + - $checkoutPaymentDetails['cardExpiryYear'] = - $dataArray['paymentMethod']['additional_data']['cardExpiryYear'] ?? null; -+ -+ if ($paymentMethod === 'authnetcim') { -+ $checkoutPaymentDetails = $this->mappingForAuthnet($checkoutPaymentDetails, $dataArray); -+ } - } - - $this->logger->info("Creating case for quote {$quote->getId()}"); -@@ -340,4 +344,38 @@ class PreAuth implements ObserverInterface - throw new LocalizedException(__($policyRejectMessage)); - } - } -+ -+ /** -+ * @param $checkoutPaymentDetails -+ * @param $dataArray -+ * @return mixed -+ */ -+ public function mappingForAuthnet($checkoutPaymentDetails, $dataArray) -+ { -+ $additionalData = $dataArray['paymentMethod']['additional_data']; -+ -+ if (isset($dataArray['paymentMethod']['additional_data']['card_id'])) { -+ /** @var \ParadoxLabs\TokenBase\Model\ResourceModel\Card\Collection $cardCollection */ -+ $cardCollection = $this->objectManagerInterface->create( -+ \ParadoxLabs\TokenBase\Model\ResourceModel\Card\CollectionFactory::class -+ )->create() -+ ->addFieldToFilter('hash', ['eq' => $dataArray['paymentMethod']['additional_data']['card_id']]); -+ -+ $card = $cardCollection->getFirstItem(); -+ -+ if (empty($card->getData('additional')) === false) { -+ $additionalData = $this->jsonSerializer->unserialize($card->getData('additional')); -+ } -+ } -+ -+ $checkoutPaymentDetails['cardExpiryMonth'] = $additionalData['cc_exp_month'] ?? null; -+ -+ $checkoutPaymentDetails['cardExpiryYear'] = $additionalData['cc_exp_year'] ?? null; -+ -+ $checkoutPaymentDetails['cardLast4'] = $additionalData['cc_last4'] ?? null; -+ -+ $checkoutPaymentDetails['cardBin'] = $additionalData['cc_bin'] ?? null; -+ -+ return $checkoutPaymentDetails; -+ } - } -diff --git a/vendor/signifyd/module-connect/docs/PASS-PAYMENT-PRE-AUTH.md b/vendor/signifyd/module-connect/docs/PASS-PAYMENT-PRE-AUTH.md -index 323c712..6c258d5 100644 ---- a/vendor/signifyd/module-connect/docs/PASS-PAYMENT-PRE-AUTH.md -+++ b/vendor/signifyd/module-connect/docs/PASS-PAYMENT-PRE-AUTH.md -@@ -120,6 +120,15 @@ git apply pre-auth-braintree-magento-2.X.patch - - Expiry date: no - - Cardholder name: no - -+### Authorize.net -+ -+- Call transaction API on failure: yes -+- Payment data available: -+ - Bin: yes (not available for saved cards) -+ - Last4: yes -+ - Expiry date: yes -+ - Cardholder name: yes -+ - ### Amazon Pay / PayPal Express - - Not compatible with any pre auth flows, not even the basic behavior to block the customer on pre auth decline. Needs custom work on checkout as it has a specific behavior on checkout process. -\ No newline at end of file -diff --git a/vendor/signifyd/module-connect/docs/TRANSACTIONS-INTEGRATION.md b/vendor/signifyd/module-connect/docs/TRANSACTIONS-INTEGRATION.md -index 4510d93..f2afb23 100644 ---- a/vendor/signifyd/module-connect/docs/TRANSACTIONS-INTEGRATION.md -+++ b/vendor/signifyd/module-connect/docs/TRANSACTIONS-INTEGRATION.md -@@ -11,13 +11,13 @@ For each payment method that want to integrate with the transaction endpoint, it - It is necessary to add the payment method to the mapped list in the etc/config.xml file: - - ```xml --{"CREDIT_CARD":["payflow_link", "payflow_advanced", "authorizenet_acceptjs", "adyen_cc", "adyen_oneclick", "adyen_hpp", "braintree", "cybersource", "stripe_payments", "anet_creditcard", "authorizenet_directpost", "openpay_cards", "holacash", "stripe_payments"],"CHECK":["checkmo"]} -+{"CREDIT_CARD":["payflow_link", "payflow_advanced", "authorizenet_acceptjs", "adyen_cc", "adyen_oneclick", "adyen_hpp", "braintree", "cybersource", "stripe_payments", "anet_creditcard", "authorizenet_directpost", "openpay_cards", "holacash", "stripe_payments", "authnetcim"],"CHECK":["checkmo"]} - ``` - - Likewise, it is necessary to update the payment method mapping doc on docs/PAYMENT-MAPPING.md file: - - ```sql --INSERT INTO core_config_data (path, value) VALUES ('signifyd/general/payment_methods_config', '{"CREDIT_CARD":["payflow_link", "payflow_advanced", "authorizenet_acceptjs", "adyen_cc", "braintree", "cybersource", "stripe_payments", "anet_creditcard", "authorizenet_directpost", "openpay_cards", "holacash"],"CHECK":["checkmo"], "SIGNIFYD-PAYMENT-CODE": ["magento-payment-code"]}'); -+INSERT INTO core_config_data (path, value) VALUES ('signifyd/general/payment_methods_config', '{"CREDIT_CARD":["payflow_link", "payflow_advanced", "authorizenet_acceptjs", "adyen_cc", "adyen_oneclick", "adyen_hpp", "braintree", "cybersource", "stripe_payments", "anet_creditcard", "authorizenet_directpost", "openpay_cards", "holacash", "stripe_payments", "authnetcim"],"CHECK":["checkmo"]}'); - ``` - - ### Implementation of card data -diff --git a/vendor/signifyd/module-connect/etc/config.xml b/vendor/signifyd/module-connect/etc/config.xml -index 1301b16..30ba6fe 100644 ---- a/vendor/signifyd/module-connect/etc/config.xml -+++ b/vendor/signifyd/module-connect/etc/config.xml -@@ -14,7 +14,7 @@ - pending_payment,payment_review,canceled,closed,complete - holded,pending_payment,payment_review,canceled,closed,complete - checkmo,cashondelivery,banktransfer,purchaseorder,free -- {"CREDIT_CARD":["payflow_link", "payflow_advanced", "authorizenet_acceptjs", "adyen_cc", "adyen_oneclick", "adyen_hpp", "braintree", "cybersource", "stripe_payments", "anet_creditcard", "authorizenet_directpost", "openpay_cards", "holacash", "stripe_payments"],"CHECK":["checkmo"]} -+ {"CREDIT_CARD":["payflow_link", "payflow_advanced", "authorizenet_acceptjs", "adyen_cc", "adyen_oneclick", "adyen_hpp", "braintree", "cybersource", "stripe_payments", "anet_creditcard", "authorizenet_directpost", "openpay_cards", "holacash", "stripe_payments", "authnetcim"],"CHECK":["checkmo"]} - {"FEDEX":["fedex"],"DHL":["dhl"],"SHIPWIRE":[],"USPS":["usps"],"UPS":["ups"]} - {"EXPRESS":["FEDEX_EXPRESS_SAVER", "7", "B", "C", "D", "U", "K", "L", "I", "N", "T", "X", "INT_4", "INT_5", "INT_6", "INT_7", "54", "07"],"ELECTRONIC":[],"FIRST_CLASS":["0_FCLE", "0_FCL", "0_FCP", "0_FCPC", "15", "53", "61", "INT_13", "INT_14", "INT_15", "INT_21"],"FIRST_CLASS_INTERNATIONAL":[],"FREE":["freeshipping"],"FREIGHT":["FEDEX_1_DAY_FREIGHT", "FEDEX_2_DAY_FREIGHT", "FEDEX_3_DAY_FREIGHT", "INTERNATIONAL_ECONOMY_FREIGHT", "INTERNATIONAL_PRIORITY_FREIGHT", "FEDEX_FREIGHT", "FEDEX_NATIONAL_FREIGHT"],"GROUND":["FEDEX_GROUND", "GROUND_HOME_DELIVERY", "INTERNATIONAL_GROUND", "4", "03"],"INTERNATIONAL":["INTERNATIONAL_ECONOMY", "INTERNATIONAL_FIRST"],"OVERNIGHT":["FIRST_OVERNIGHT", "PRIORITY_OVERNIGHT", "STANDARD_OVERNIGHT"],"PRIORITY":["1", "2", "3", "13", "16", "17", "22", "23", "25", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "57", "58", "59", "62", "63", "64", "INT_1", "INT_2", "INT_8", "INT_9", "INT_10", "INT_11", "INT_16", "INT_17", "INT_18", "INT_19", "INT_20", "INT_22", "INT_23", "INT_24", "INT_25", "INT_27"],"PRIORITY_INTERNATIONAL":["EUROPE_FIRST_INTERNATIONAL_PRIORITY", "INTERNATIONAL_PRIORITY"],"PICKUP":["pickup"],"STANDARD":["11"],"STORE_TO_STORE":[],"TWO_DAY":["FEDEX_2_DAY", "FEDEX_2_DAY_AM", "59", "02"]} - cybersource,mercadopago_basic,stripe_payments -diff --git a/vendor/signifyd/module-connect/etc/di.xml b/vendor/signifyd/module-connect/etc/di.xml -index 4d5454a..08fe6c7 100644 ---- a/vendor/signifyd/module-connect/etc/di.xml -+++ b/vendor/signifyd/module-connect/etc/di.xml -@@ -138,4 +138,6 @@ + ++ - -+ -+ - --- -2.17.1 - + diff --git a/Patch/pre-auth-braintree-magento-2.3.patch b/Patch/pre-auth-braintree-magento-2.3.patch index 65d74425..d6f9ffbf 100644 --- a/Patch/pre-auth-braintree-magento-2.3.patch +++ b/Patch/pre-auth-braintree-magento-2.3.patch @@ -1,59 +1,86 @@ -Index: Plugin/Braintree/Gateway/Validator/GeneralResponseValidator.php -=================================================================== -diff --git a/vendor/signifyd/module-connect/Plugin/Braintree/Gateway/Validator/GeneralResponseValidator.php b/vendor/signifyd/module-connect/Plugin/Braintree/Gateway/Validator/GeneralResponseValidator.php +From bbb491624e708712094aa360269ca6521e44103c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=89bano=20Lopes?= +Date: Thu, 7 Mar 2024 18:04:56 +0000 +Subject: [PATCH] v5.7.0: magento patch 2.3.x + +--- + .../PayPal/GeneralResponseValidator.php | 106 ++++++++++++++++++ + etc/di.xml | 4 + + 2 files changed, 110 insertions(+) + create mode 100644 Plugin/Braintree/Gateway/Validator/PayPal/GeneralResponseValidator.php + +diff --git a/vendor/signifyd/module-connect/Plugin/Braintree/Gateway/Validator/PayPal/GeneralResponseValidator.php b/vendor/signifyd/module-connect/Plugin/Braintree/Gateway/Validator/PayPal/GeneralResponseValidator.php new file mode 100644 ---- /dev/null (revision f70a8543cd60ea6936c57cc645cf7059b28e8177) -+++ b/vendor/signifyd/module-connect/Plugin/Braintree/Gateway/Validator/GeneralResponseValidator.php (revision f70a8543cd60ea6936c57cc645cf7059b28e8177) -@@ -0,0 +1,89 @@ +index 0000000..a817efd +--- /dev/null ++++ b/vendor/signifyd/module-connect/Plugin/Braintree/Gateway/Validator/PayPal/GeneralResponseValidator.php +@@ -0,0 +1,106 @@ +subjectReader = $subjectReader; + } +} \ No newline at end of file -Index: etc/di.xml -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== diff --git a/vendor/signifyd/module-connect/etc/di.xml b/vendor/signifyd/module-connect/etc/di.xml ---- a/vendor/signifyd/module-connect/etc/di.xml (revision b4376027ccf94ffa12fc11206dc9e38aa31fce77) -+++ b/vendor/signifyd/module-connect/etc/di.xml (revision f70a8543cd60ea6936c57cc645cf7059b28e8177) -@@ -1,5 +1,9 @@ - - +index 7ab144e..0b575e3 100644 +--- a/vendor/signifyd/module-connect/etc/di.xml ++++ b/vendor/signifyd/module-connect/etc/di.xml +@@ -85,6 +85,10 @@ + + + + + + + - - - + + + +-- +2.17.1 + diff --git a/Patch/pre-auth-braintree-magento-2.4.patch b/Patch/pre-auth-braintree-magento-2.4.patch index 49898b8d..2aeee8f1 100644 --- a/Patch/pre-auth-braintree-magento-2.4.patch +++ b/Patch/pre-auth-braintree-magento-2.4.patch @@ -1,62 +1,86 @@ -Index: Plugin/Braintree/Gateway/Validator/PayPal/GeneralResponseValidator.php -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== +From a29ec370c5a787163e72d15e5a5bfe249b324fb2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=89bano=20Lopes?= +Date: Thu, 7 Mar 2024 17:42:49 +0000 +Subject: [PATCH] MAG-897: MFTF create invoice. + +--- + .../PayPal/GeneralResponseValidator.php | 106 ++++++++++++++++++ + etc/di.xml | 4 + + 2 files changed, 110 insertions(+) + create mode 100644 Plugin/Braintree/Gateway/Validator/PayPal/GeneralResponseValidator.php + diff --git a/vendor/signifyd/module-connect/Plugin/Braintree/Gateway/Validator/PayPal/GeneralResponseValidator.php b/vendor/signifyd/module-connect/Plugin/Braintree/Gateway/Validator/PayPal/GeneralResponseValidator.php new file mode 100644 ---- /dev/null (revision 181d36a5b276d283bbe3b331815057e52023d42d) -+++ b/vendor/signifyd/module-connect/Plugin/Braintree/Gateway/Validator/PayPal/GeneralResponseValidator.php (revision 181d36a5b276d283bbe3b331815057e52023d42d) -@@ -0,0 +1,89 @@ +index 0000000..c63570f +--- /dev/null ++++ b/vendor/signifyd/module-connect/Plugin/Braintree/Gateway/Validator/PayPal/GeneralResponseValidator.php +@@ -0,0 +1,106 @@ +subjectReader = $subjectReader; + } +} -Index: etc/di.xml -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== +\ No newline at end of file diff --git a/vendor/signifyd/module-connect/etc/di.xml b/vendor/signifyd/module-connect/etc/di.xml ---- a/vendor/signifyd/module-connect/etc/di.xml (revision b4376027ccf94ffa12fc11206dc9e38aa31fce77) -+++ b/vendor/signifyd/module-connect/etc/di.xml (revision 181d36a5b276d283bbe3b331815057e52023d42d) -@@ -1,5 +1,9 @@ - - +index 7ab144e..d21ea13 100644 +--- a/vendor/signifyd/module-connect/etc/di.xml ++++ b/vendor/signifyd/module-connect/etc/di.xml +@@ -85,6 +85,10 @@ + + + + + + + - - - + + + +-- +2.17.1 + diff --git a/Plugin/Adyen/Payment/Controller/Process/Json.php b/Plugin/Adyen/Payment/Controller/Process/Json.php index 3bb7791d..13d8e9e0 100644 --- a/Plugin/Adyen/Payment/Controller/Process/Json.php +++ b/Plugin/Adyen/Payment/Controller/Process/Json.php @@ -3,6 +3,7 @@ namespace Signifyd\Connect\Plugin\Adyen\Payment\Controller\Process; use Adyen\Payment\Controller\Process\Json as AdyenJson; +use Magento\Framework\Serialize\Serializer\Json as JsonSerializer; use Signifyd\Connect\Helper\ConfigHelper; use Signifyd\Connect\Logger\Logger; use Signifyd\Connect\Model\Api\Core\Client; @@ -13,53 +14,64 @@ use Magento\Quote\Model\QuoteFactory; use Magento\Quote\Model\ResourceModel\Quote as QuoteResourceModel; use Signifyd\Connect\Model\Api\TransactionsFactory; +use Magento\Framework\App\Request\Http as RequestHttp; class Json { /** * @var CasedataFactory */ - protected $casedataFactory; + public $casedataFactory; /** * @var CasedataResourceModel */ - protected $casedataResourceModel; + public $casedataResourceModel; /** * @var Logger */ - protected $logger; + public $logger; /** * @var StoreManagerInterface */ - protected $storeManager; + public $storeManager; /** * @var QuoteFactory */ - protected $quoteFactory; + public $quoteFactory; /** * @var QuoteResourceModel */ - protected $quoteResourceModel; + public $quoteResourceModel; /** * @var TransactionsFactory */ - protected $transactionsFactory; + public $transactionsFactory; /** * @var ConfigHelper */ - protected $configHelper; + public $configHelper; /** * @var Client */ - protected $client; + public $client; + + /** + * @var JsonSerializer + */ + public $jsonSerializer; + + /** + * @var RequestHttp + */ + public $requestHttp; /** * CheckoutPaymentsDetailsHandler constructor. @@ -72,6 +84,8 @@ class Json * @param TransactionsFactory $transactionsFactory * @param ConfigHelper $configHelper * @param Client $client + * @param JsonSerializer $jsonSerializer + * @param RequestHttp $requestHttp */ public function __construct( CasedataFactory $casedataFactory, @@ -82,7 +96,9 @@ public function __construct( QuoteResourceModel $quoteResourceModel, TransactionsFactory $transactionsFactory, ConfigHelper $configHelper, - Client $client + Client $client, + JsonSerializer $jsonSerializer, + RequestHttp $requestHttp ) { $this->casedataFactory = $casedataFactory; $this->casedataResourceModel = $casedataResourceModel; @@ -93,6 +109,8 @@ public function __construct( $this->transactionsFactory = $transactionsFactory; $this->configHelper = $configHelper; $this->client = $client; + $this->jsonSerializer = $jsonSerializer; + $this->requestHttp = $requestHttp; } public function beforeExecute(AdyenJson $subject) @@ -108,7 +126,7 @@ public function beforeExecute(AdyenJson $subject) \Magento\Store\Model\ScopeInterface::SCOPE_STORES, $this->storeManager->getStore()->getId() ); - $notificationItems = json_decode(file_get_contents('php://input'), true); + $notificationItems = $this->jsonSerializer->unserialize($this->requestHttp->getContent()); if ($isPreAuth === false && empty($notificationItems) === true) { return null; @@ -126,7 +144,7 @@ public function beforeExecute(AdyenJson $subject) $isSuccess = $notificationItems['notificationItems'][0]['NotificationRequestItem']['success']; $reason = $notificationItems['notificationItems'][0]['NotificationRequestItem']['reason']; - /** @var $case \Signifyd\Connect\Model\Casedata */ + /** @var \Signifyd\Connect\Model\Casedata $case */ $case = $this->casedataFactory->create(); $this->casedataResourceModel->load($case, $orderIncrement, 'order_increment'); @@ -136,7 +154,8 @@ public function beforeExecute(AdyenJson $subject) } $this->logger->info( - "collecting Adyen pre-authorization transaction data for case " . $case->getCode() + "collecting Adyen pre-authorization transaction data for case " . $case->getCode(), + ['entity' => $case] ); $adyenData = []; diff --git a/Plugin/Adyen/Payment/Gateway/Http/Client/TransactionPayment.php b/Plugin/Adyen/Payment/Gateway/Http/Client/TransactionPayment.php index a67712d4..0cca2e31 100644 --- a/Plugin/Adyen/Payment/Gateway/Http/Client/TransactionPayment.php +++ b/Plugin/Adyen/Payment/Gateway/Http/Client/TransactionPayment.php @@ -13,22 +13,22 @@ class TransactionPayment /** * @var StoreManagerInterface */ - protected $storeManager; + public $storeManager; /** * @var Logger */ - protected $logger; + public $logger; /** * @var ScaEvaluation */ - protected $scaEvaluation; + public $scaEvaluation; /** * @var ScaEvaluationConfig */ - protected $scaEvaluationConfig; + public $scaEvaluationConfig; /** * @param StoreManagerInterface $storeManager diff --git a/Plugin/Adyen/Payment/Gateway/Request/CheckoutDataBuilderSca.php b/Plugin/Adyen/Payment/Gateway/Request/CheckoutDataBuilderSca.php index 791e3ca7..39f2fe00 100644 --- a/Plugin/Adyen/Payment/Gateway/Request/CheckoutDataBuilderSca.php +++ b/Plugin/Adyen/Payment/Gateway/Request/CheckoutDataBuilderSca.php @@ -4,7 +4,6 @@ use Adyen\Payment\Gateway\Request\CheckoutDataBuilder as AdyenCheckoutDataBuilder; use Magento\Framework\App\Config\ScopeConfigInterface; -use Magento\Framework\Registry; use Magento\Quote\Model\QuoteFactory; use Magento\Quote\Model\ResourceModel\Quote as QuoteResourceModel; use Magento\Store\Model\StoreManagerInterface; @@ -19,57 +18,52 @@ class CheckoutDataBuilderSca /** * @var QuoteResourceModel */ - protected $quoteResourceModel; + public $quoteResourceModel; /** * @var QuoteFactory */ - protected $quoteFactory; + public $quoteFactory; /** * @var int */ - protected $quoteId; + public $quoteId; /** * @var ScopeConfigInterface */ - protected $scopeConfig; + public $scopeConfig; /** * @var ConfigHelper */ - protected $configHelper; + public $configHelper; /** * @var Logger */ - protected $logger; + public $logger; /** * @var StoreManagerInterface */ - protected $storeManagerInterface; + public $storeManagerInterface; /** * @var ScaEvaluation */ - protected $scaEvaluation; + public $scaEvaluation; /** * @var CasedataFactory */ - protected $casedataFactory; + public $casedataFactory; /** * @var CasedataResourceModel */ - protected $casedataResourceModel; - - /** - * @var Registry - */ - protected $registry; + public $casedataResourceModel; /** * CheckoutDataBuilder constructor. @@ -82,7 +76,6 @@ class CheckoutDataBuilderSca * @param ScaEvaluation $scaEvaluation * @param CasedataFactory $casedataFactory * @param CasedataResourceModel $casedataResourceModel - * @param Registry $registry */ public function __construct( QuoteResourceModel $quoteResourceModel, @@ -93,8 +86,7 @@ public function __construct( StoreManagerInterface $storeManagerInterface, ScaEvaluation $scaEvaluation, CasedataFactory $casedataFactory, - CasedataResourceModel $casedataResourceModel, - Registry $registry + CasedataResourceModel $casedataResourceModel ) { $this->quoteResourceModel = $quoteResourceModel; $this->quoteFactory = $quoteFactory; @@ -105,7 +97,6 @@ public function __construct( $this->scaEvaluation = $scaEvaluation; $this->casedataFactory = $casedataFactory; $this->casedataResourceModel = $casedataResourceModel; - $this->registry = $registry; } public function beforeBuild(AdyenCheckoutDataBuilder $subject, array $buildSubject) @@ -113,7 +104,6 @@ public function beforeBuild(AdyenCheckoutDataBuilder $subject, array $buildSubje /** @var \Magento\Payment\Gateway\Data\PaymentDataObject $paymentDataObject */ $paymentDataObject = \Magento\Payment\Gateway\Helper\SubjectReader::readPayment($buildSubject); $payment = $paymentDataObject->getPayment(); - /** @var \Magento\Sales\Model\Order $order */ $this->quoteId = $payment->getOrder()->getQuoteId(); } @@ -134,7 +124,7 @@ public function afterBuild(AdyenCheckoutDataBuilder $subject, $request) switch ($scaEvaluation->outcome) { case 'REQUEST_EXEMPTION': - $this->logger->info("Signifyd's recommendation is to request exemption"); + $this->logger->info("Signifyd's recommendation is to request exemption", ['entity' => $quote]); $placement = $scaEvaluation->exemptionDetails->placement; $scaExemption = 'tra'; @@ -151,14 +141,14 @@ public function afterBuild(AdyenCheckoutDataBuilder $subject, $request) $recommendation = $scaEvaluation->outcome == 'DELEGATE_TO_PSP' ? 'no exemption/exclusion identified' : 'exclusion'; - $this->logger->info("Signifyd's recommendation is {$recommendation}"); + $this->logger->info("Signifyd's recommendation is {$recommendation}", ['entity' => $quote]); $executeThreeD = ''; $scaExemption = ''; break; case 'SOFT_DECLINE': - $this->logger->info("Processor responds back with a soft decline"); + $this->logger->info("Processor responds back with a soft decline", ['entity' => $quote]); $executeThreeD = 'always'; $scaExemption = ''; diff --git a/Plugin/Adyen/Payment/Helper/PaymentResponseHandler.php b/Plugin/Adyen/Payment/Helper/PaymentResponseHandler.php index 6c1e5197..4b67da87 100644 --- a/Plugin/Adyen/Payment/Helper/PaymentResponseHandler.php +++ b/Plugin/Adyen/Payment/Helper/PaymentResponseHandler.php @@ -2,50 +2,106 @@ namespace Signifyd\Connect\Plugin\Adyen\Payment\Helper; +use Signifyd\Connect\Model\Registry; use Magento\Framework\Serialize\Serializer\Json as JsonSerializer; use Magento\Sales\Api\OrderRepositoryInterface; +use Magento\Sales\Model\Order; +use Signifyd\Connect\Helper\OrderHelper; +use Signifyd\Connect\Logger\Logger; +use Signifyd\Connect\Model\Casedata; +use Signifyd\Connect\Model\ResourceModel\Casedata as CasedataResourceModel; +use Signifyd\Connect\Model\ResourceModel\Order as SignifydOrderResourceModel; use Signifyd\Connect\Model\ThreeDsIntegration; use Adyen\Payment\Helper\PaymentResponseHandler as AdyenPaymentResponseHandler; use Magento\Framework\App\Request\Http as HttpRequest; +use Signifyd\Connect\Model\CasedataFactory; class PaymentResponseHandler { /** * @var ThreeDsIntegration */ - protected $threeDsIntegration; + public $threeDsIntegration; /** * @var HttpRequest */ - protected $httpRequest; + public $httpRequest; /** * @var JsonSerializer */ - protected $jsonSerializer; + public $jsonSerializer; /** * @var OrderRepositoryInterface */ private $orderRepository; + /** + * @var SignifydOrderResourceModel + */ + protected $signifydOrderResourceModel; + + /** + * @var Logger + */ + protected $logger; + + /** + * @var OrderHelper + */ + protected $orderHelper; + + /** + * @var CasedataFactory + */ + protected $casedataFactory; + + /** + * @var CasedataResourceModel + */ + protected $casedataResourceModel; + + /** + * @var Registry + */ + protected $registry; + /** * @param ThreeDsIntegration $threeDsIntegration * @param HttpRequest $httpRequest * @param JsonSerializer $jsonSerializer * @param OrderRepositoryInterface $orderRepository + * @param SignifydOrderResourceModel $signifydOrderResourceModel + * @param Logger $logger + * @param CasedataFactory $casedataFactory + * @param CasedataResourceModel $casedataResourceModel + * @param OrderHelper $orderHelper + * @param Registry $registry */ public function __construct( ThreeDsIntegration $threeDsIntegration, HttpRequest $httpRequest, JsonSerializer $jsonSerializer, - OrderRepositoryInterface $orderRepository + OrderRepositoryInterface $orderRepository, + SignifydOrderResourceModel $signifydOrderResourceModel, + Logger $logger, + CasedataFactory $casedataFactory, + CasedataResourceModel $casedataResourceModel, + OrderHelper $orderHelper, + Registry $registry ) { $this->threeDsIntegration = $threeDsIntegration; $this->httpRequest = $httpRequest; $this->jsonSerializer = $jsonSerializer; $this->orderRepository = $orderRepository; + $this->signifydOrderResourceModel = $signifydOrderResourceModel; + $this->logger = $logger; + $this->casedataFactory = $casedataFactory; + $this->casedataResourceModel = $casedataResourceModel; + $this->orderHelper = $orderHelper; + $this->registry = $registry; } public function beforeFormatPaymentResponse( @@ -55,17 +111,17 @@ public function beforeFormatPaymentResponse( $additionalData = null ) { if (isset($additionalData) === false || is_array($additionalData) === false) { - return; + return [$resultCode, $action, $additionalData]; } if (isset($additionalData['threeDAuthenticated']) === false) { - return; + return [$resultCode, $action, $additionalData]; } if ($additionalData['threeDAuthenticated'] === 'false' && isset($additionalData['scaExemptionRequested']) === false ) { - return; + return [$resultCode, $action, $additionalData]; } $content = $this->httpRequest->getContent(); @@ -77,12 +133,12 @@ public function beforeFormatPaymentResponse( if (isset($payload['orderId'])) { $orderId = $payload['orderId']; } else { - return; + return [$resultCode, $action, $additionalData]; } } elseif (isset($contentArray['orderId'])) { $orderId = $contentArray['orderId']; } else { - return; + return [$resultCode, $action, $additionalData]; } $order = $this->orderRepository->get($orderId); @@ -162,4 +218,73 @@ public function beforeFormatPaymentResponse( return [$resultCode, $action, $additionalData]; } + + public function beforeHandlePaymentResponse( + AdyenPaymentResponseHandler $subject, + $paymentsResponse, + $payment, + $order = null + ) { + if (empty($paymentsResponse) || null === $order) { + return [$paymentsResponse, $payment, $order]; + } + + try { + if (isset($paymentsResponse['resultCode']) && $paymentsResponse['resultCode'] === $subject::REFUSED) { + $this->registry->setData( + 'gateway_restriction', + 'Adyen refused payment' + ); + + $orderId = $order->getId(); + $case = $this->casedataFactory->create(); + $this->casedataResourceModel->load($case, $orderId, 'order_id'); + + if ($case->isEmpty()) { + return [$paymentsResponse, $payment, $order]; + } + + if ($order->canUnhold()) { + try { + $order->unhold(); + $this->signifydOrderResourceModel->save($order); + $this->logger->info( + "Unhold order {$order->getIncrementId()} before adyen tries to cancel", + ['entity' => $order] + ); + + $this->orderHelper->addCommentToStatusHistory( + $order, + "Signifyd: unhold order before adyen tries to cancel" + ); + } catch (\Exception $e) { + $this->logger->debug($e->__toString(), ['entity' => $order]); + + $this->orderHelper->addCommentToStatusHistory( + $order, + "Signifyd: order cannot be unholded, {$e->getMessage()}" + ); + } + } + } + } catch (\Exception $ex) { + $context = []; + + if (isset($order) && $order instanceof Order) { + $context['entity'] = $order; + } + + $this->logger->error($ex->getMessage(), $context); + } catch (\Error $ex) { + $context = []; + + if (isset($order) && $order instanceof Order) { + $context['entity'] = $order; + } + + $this->logger->error($ex->getMessage(), $context); + } + + return [$paymentsResponse, $payment, $order]; + } } diff --git a/Plugin/Adyen/Payment/Helper/Webhook.php b/Plugin/Adyen/Payment/Helper/Webhook.php new file mode 100644 index 00000000..2e606575 --- /dev/null +++ b/Plugin/Adyen/Payment/Helper/Webhook.php @@ -0,0 +1,139 @@ +logger = $logger; + $this->casedataFactory = $casedataFactory; + $this->casedataResourceModel = $casedataResourceModel; + $this->orderResourceModel = $orderResourceModel; + $this->orderHelper = $orderHelper; + $this->objectManagerInterface = $objectManagerInterface; + } + + public function aroundProcessNotification(AdyenWebhook $subject, callable $proceed, $notification) + { + try { + $adyenOrderHelper = $this->objectManagerInterface->create( + \Adyen\Payment\Helper\Order::class + ); + + $order = $adyenOrderHelper->getOrderByIncrementId($notification->getMerchantReference()); + + if (!$order) { + return $proceed($notification); + } + + $orderId = $order->getId(); + $case = $this->casedataFactory->create(); + $this->casedataResourceModel->load($case, $orderId, 'order_id'); + + if ($case->isEmpty()) { + return $proceed($notification); + } + + $isHoldedBeforeAdyenProcess = $order->canUnhold(); + + if ($isHoldedBeforeAdyenProcess) { + $order->unhold(); + $this->orderResourceModel->save($order); + } + + $returnValue = $proceed($notification); + + $order = $adyenOrderHelper->getOrderByIncrementId($notification->getMerchantReference()); + + //Setting order to hold after adyen process + if ($isHoldedBeforeAdyenProcess && $order->canHold()) { + $order->hold(); + $this->orderResourceModel->save($order); + $this->logger->info( + "Hold order {$order->getIncrementId()} after adyen processing", + ['entity' => $case] + ); + + $this->orderHelper->addCommentToStatusHistory( + $order, + "Signifyd: hold order after adyen processing" + ); + } + } catch (\Exception $ex) { + $context = []; + + if (isset($order) && $order instanceof Order) { + $context['entity'] = $order; + } + + $this->logger->error($ex->getMessage(), $context); + } catch (\Error $ex) { + $context = []; + + if (isset($order) && $order instanceof Order) { + $context['entity'] = $order; + } + + $this->logger->error($ex->getMessage(), $context); + } + + if (isset($returnValue)) { + return $returnValue; + } else { + return $proceed($notification); + } + } +} diff --git a/Plugin/Braintree/GeneralResponseValidator.php b/Plugin/Braintree/GeneralResponseValidator.php index 6a0c1758..ed81a08b 100644 --- a/Plugin/Braintree/GeneralResponseValidator.php +++ b/Plugin/Braintree/GeneralResponseValidator.php @@ -18,49 +18,49 @@ class GeneralResponseValidator /** * @var CasedataFactory */ - protected $casedataFactory; + public $casedataFactory; /** * @var CasedataResourceModel */ - protected $casedataResourceModel; + public $casedataResourceModel; /** * @var Logger */ - protected $logger; + public $logger; /** * @var StoreManagerInterface */ - protected $storeManager; + public $storeManager; /** * @var QuoteFactory */ - protected $quoteFactory; + public $quoteFactory; /** * @var QuoteResourceModel */ - protected $quoteResourceModel; + public $quoteResourceModel; /** * @var TransactionsFactory */ - protected $transactionsFactory; + public $transactionsFactory; /** * @var ConfigHelper */ - protected $configHelper; + public $configHelper; /** * @var Client */ - protected $client; + public $client; - protected $subjectReader; + public $subjectReader; /** * CheckoutPaymentsDetailsHandler constructor. @@ -122,7 +122,11 @@ public function beforeValidate($subject, array $validationSubject) return; } - $responseBraintree = $response->jsonSerialize()['transaction']->jsonSerialize() ?? []; + if (isset($response->jsonSerialize()['transaction'])) { + $responseBraintree = $response->jsonSerialize()['transaction']->jsonSerialize(); + } else { + $responseBraintree = []; + } if (isset($responseBraintree['orderId']) && isset($responseBraintree['cvvResponseCode']) && @@ -141,7 +145,7 @@ public function beforeValidate($subject, array $validationSubject) $reason = 'default'; } - /** @var $case \Signifyd\Connect\Model\Casedata */ + /** @var \Signifyd\Connect\Model\Casedata $case */ $case = $this->casedataFactory->create(); $this->casedataResourceModel->load($case, $orderIncrement, 'order_increment'); @@ -175,7 +179,8 @@ public function beforeValidate($subject, array $validationSubject) } $this->logger->info( - "collecting Braintree pre-authorization transaction data for case " . $case->getCode() + "collecting Braintree pre-authorization transaction data for case " . $case->getCode(), + ['entity' => $case] ); $branitreeData = []; diff --git a/Plugin/CyberSource/Gateway/Command/HandleResponseCommand.php b/Plugin/CyberSource/Gateway/Command/HandleResponseCommand.php new file mode 100644 index 00000000..94b7eb2f --- /dev/null +++ b/Plugin/CyberSource/Gateway/Command/HandleResponseCommand.php @@ -0,0 +1,241 @@ +transactionIntegration = $transactionIntegration; + $this->registry = $registry; + $this->objectManagerInterface = $objectManagerInterface; + } + + /** + * @param \CyberSource\SecureAcceptance\Gateway\Helper\SubjectReader $subject + * @param $response + * @return mixed + */ + public function afterReadResponse(\CyberSource\SecureAcceptance\Gateway\Helper\SubjectReader $subject, $response) + { + if (is_array($response) === false) { + return $response; + } + + if (isset($response['decision']) === false) { + return $response; + } + + if ($response['decision'] != 'REJECT' && $response['decision'] != 'DECLINE') { + $this->registry->setData('signifyd_payment_data', $response); + return $response; + } + + $signifydReason = null; + $signifydMessage = null; + + if (isset($response['reasonCode'])) { + $reasonCode = $response['reasonCode']; + } elseif (isset($response['reason_code'])) { + $reasonCode = $response['reason_code']; + } else { + return $response; + } + + switch ($reasonCode) { + case '101': + $signifydReason = 'CARD_DECLINED'; + $signifydMessage = 'Declined - The request is missing one or more fields'; + break; + + case '102': + $signifydReason = 'EXPIRED_CARD'; + $signifydMessage = 'Declined - One or more fields in the request contains invalid data.'; + break; + + case '104': + $signifydReason = 'EXPIRED_CARD'; + $signifydMessage = 'Declined - The merchantReferenceCode sent with this authorization request matches' . + ' the merchantReferenceCode of another authorization request that you sent in the last 15 minutes.'; + break; + + case '150': + $signifydReason = 'PROCESSING_ERROR'; + $signifydMessage = 'Error - General system failure.'; + break; + + case '151': + $signifydReason = 'PROCESSING_ERROR'; + $signifydMessage = 'Error - The request was received but there was a server timeout.' . + ' This error does not include timeouts between the client and the server.'; + break; + + case '152': + $signifydReason = 'PROCESSING_ERROR'; + $signifydMessage = 'Error: The request was received, but a service did not finish running in time.'; + break; + + case '154': + $signifydReason = 'CARD_DECLINED'; + $signifydMessage = 'Bad MaC key.'; + break; + + case '200': + case '230': + case '400': + case '520': + $signifydReason = 'CARD_DECLINED'; + $signifydMessage = 'Soft Decline.'; + break; + + case '201': + $signifydReason = 'CARD_DECLINED'; + $signifydMessage = 'Decline - The issuing bank has questions about the request.'; + break; + + case '202': + $signifydReason = 'EXPIRED_CARD'; + $signifydMessage = 'Decline - Expired card. You might also receive this if the expiration date you' . + ' provided does not match the date the issuing bank has on file.'; + break; + + case '203': + $signifydReason = 'CARD_DECLINED'; + $signifydMessage = 'Decline - General decline of the card. No other information provided by' . + ' the issuing bank.'; + break; + + case '204': + $signifydReason = 'INSUFFICIENT_FUNDS'; + $signifydMessage = 'Decline - Insufficient funds in the account.'; + break; + + case '205': + $signifydReason = 'STOLEN_CARD'; + $signifydMessage = 'Decline - Stolen or lost card.'; + break; + + case '207': + $signifydReason = 'CARD_DECLINED'; + $signifydMessage = 'Decline - Issuing bank unavailable.'; + break; + + case '208': + $signifydReason = 'CARD_DECLINED'; + $signifydMessage = 'Decline - Inactive card or card not authorized for card-not-present transactions.'; + break; + + case '209': + case '211': + $signifydReason = 'INVALID_CVC'; + $signifydMessage = 'Decline - card verification number (CVN) did not match.'; + break; + + case '210': + $signifydReason = 'INSUFFICIENT_FUNDS'; + $signifydMessage = 'Decline - The card has reached the credit limit.'; + break; + + case '220': + case '221': + case '222': + case '231': + case '232': + case '233': + case '234': + case '235': + case '237': + case '238': + case '239': + case '241': + case '242': + case '243': + case '246': + case '247': + case '251': + case '254': + case '268': + case '450': + case '475': + case '476': + case '478': + case '480': + case '481': + case '490': + case '491': + case '700': + case '701': + case '702': + case '703': + $signifydReason = 'CARD_DECLINED'; + $signifydMessage = 'Decline - Generic Decline.'; + break; + + case '236': + case '248': + case '250': + $signifydReason = 'PROCESSING_ERROR'; + $signifydMessage = 'Decline - Processor failure.'; + break; + + case '240': + $signifydReason = 'INVALID_NUMBER'; + $signifydMessage = 'Decline - The card type sent is invalid or does not correlate with the credit' . + ' card number.'; + break; + + case '451': + case '452': + case '453': + case '454': + case '455': + case '456': + case '457': + case '458': + case '459': + case '460': + case '461': + $signifydReason = 'INCORRECT_ADDRESS'; + $signifydMessage = 'Invalid address.'; + break; + } + + if (isset($signifydReason) === false || isset($signifydMessage) === false) { + return $response; + } + + $this->transactionIntegration->setGatewayStatusMessage($signifydMessage); + $this->transactionIntegration->setGatewayRefusedReason($signifydReason); + $this->transactionIntegration->submitToTransactionApi(); + + return $response; + } +} diff --git a/Plugin/CyberSource/Gateway/Http/Client/SOAPClient.php b/Plugin/CyberSource/Gateway/Http/Client/SOAPClient.php index f49dd407..3bc7feb8 100644 --- a/Plugin/CyberSource/Gateway/Http/Client/SOAPClient.php +++ b/Plugin/CyberSource/Gateway/Http/Client/SOAPClient.php @@ -3,7 +3,7 @@ namespace Signifyd\Connect\Plugin\CyberSource\Gateway\Http\Client; use CyberSource\SecureAcceptance\Gateway\Http\Client\SOAPClient as CyberSOAPClient; -use Magento\Framework\Registry; +use Signifyd\Connect\Model\Registry; use Signifyd\Connect\Model\TransactionIntegration; class SOAPClient @@ -11,12 +11,12 @@ class SOAPClient /** * @var TransactionIntegration */ - protected $transactionIntegration; + public $transactionIntegration; /** * @var Registry */ - protected $registry; + public $registry; /** * CheckoutPaymentsDetailsHandler constructor. @@ -47,7 +47,7 @@ public function afterPlaceRequest(CyberSOAPClient $subject, $response) } if ($response['decision'] != 'REJECT') { - $this->registry->register('signifyd_payment_data', $response); + $this->registry->setData('signifyd_payment_data', $response); return $response; } diff --git a/Plugin/Holacash/Model/Payment.php b/Plugin/Holacash/Model/Payment.php index 0b820bb6..0e6d74f3 100644 --- a/Plugin/Holacash/Model/Payment.php +++ b/Plugin/Holacash/Model/Payment.php @@ -2,6 +2,7 @@ namespace Signifyd\Connect\Plugin\Holacash\Model; +use Magento\Checkout\Model\Session as CheckoutSession; use Signifyd\Connect\Helper\ConfigHelper; use Signifyd\Connect\Logger\Logger; use Signifyd\Connect\Model\Api\Core\Client; @@ -9,7 +10,6 @@ use Signifyd\Connect\Model\ResourceModel\Casedata as CasedataResourceModel; use Magento\Store\Model\StoreManagerInterface; use Holacash\Payment\Model\PaymentMethod as HolacashPayment; -use Magento\Checkout\Model\Cart as CheckoutCart; use Signifyd\Connect\Model\Api\TransactionsFactory; class Payment @@ -17,42 +17,42 @@ class Payment /** * @var CasedataFactory */ - protected $casedataFactory; + public $casedataFactory; /** * @var CasedataResourceModel */ - protected $casedataResourceModel; + public $casedataResourceModel; /** * @var Logger */ - protected $logger; + public $logger; /** * @var StoreManagerInterface */ - protected $storeManager; + public $storeManager; /** - * @var CheckoutCart + * @var CheckoutSession */ - protected $checkoutCart; + public $checkoutSession; /** * @var TransactionsFactory */ - protected $transactionsFactory; + public $transactionsFactory; /** * @var ConfigHelper */ - protected $configHelper; + public $configHelper; /** * @var Client */ - protected $client; + public $client; /** * CheckoutPaymentsDetailsHandler constructor. @@ -61,7 +61,7 @@ class Payment * @param CasedataResourceModel $casedataResourceModel * @param Logger $logger * @param StoreManagerInterface $storeManager - * @param CheckoutCart $checkoutCart + * @param CheckoutSession $checkoutSession * @param ConfigHelper $configHelper * @param Client $client */ @@ -70,7 +70,7 @@ public function __construct( CasedataResourceModel $casedataResourceModel, Logger $logger, StoreManagerInterface $storeManager, - CheckoutCart $checkoutCart, + CheckoutSession $checkoutSession, TransactionsFactory $transactionsFactory, ConfigHelper $configHelper, Client $client @@ -79,7 +79,7 @@ public function __construct( $this->casedataResourceModel = $casedataResourceModel; $this->logger = $logger; $this->storeManager = $storeManager; - $this->checkoutCart = $checkoutCart; + $this->checkoutSession = $checkoutSession; $this->transactionsFactory = $transactionsFactory; $this->configHelper = $configHelper; $this->client = $client; @@ -106,16 +106,14 @@ public function beforeError(HolacashPayment $subject, $response) $this->storeManager->getStore()->getId() ); - $quote = $this->checkoutCart->getQuote(); + $quote = $this->checkoutSession->getQuote(); - if ($isPreAuth === false || isset($quote) === false) { + if ($isPreAuth === false || $quote->isEmpty()) { return null; } $quoteId = $quote->getId(); - /** - * @var $case \Signifyd\Connect\Model\Casedata - */ + /** @var \Signifyd\Connect\Model\Casedata $case */ $case = $this->casedataFactory->create(); $this->casedataResourceModel->load($case, $quoteId, 'quote_id'); @@ -199,7 +197,7 @@ public function beforeError(HolacashPayment $subject, $response) } if ($case->getEntries('HolaCashRefusedReason') == $signifydReason) { - $this->logger->info("Reason already send"); + $this->logger->info("Reason already send", ['entity' => $case]); return null; } diff --git a/Plugin/Logger/Logger.php b/Plugin/Logger/Logger.php index 5748cd32..cef54081 100644 --- a/Plugin/Logger/Logger.php +++ b/Plugin/Logger/Logger.php @@ -4,26 +4,44 @@ use Signifyd\Connect\Helper\ConfigHelper; use Signifyd\Connect\Logger\Logger as SignifydLogger; +use Signifyd\Connect\Model\LogsFactory; +use Signifyd\Connect\Model\ResourceModel\Logs as LogsResourceModel; class Logger { /** * @var bool */ - protected $log; + public $log; /** * @var ConfigHelper */ - protected $configHelper; + public $configHelper; + + /** + * @var LogsFactory + */ + public $logsFactory; + + /** + * @var LogsResourceModel + */ + public $logsResourceModel; /** * @param ConfigHelper $configHelper + * @param LogsFactory $logsFactory + * @param LogsResourceModel $logsResourceModel */ public function __construct( - ConfigHelper $configHelper + ConfigHelper $configHelper, + LogsFactory $logsFactory, + LogsResourceModel $logsResourceModel ) { $this->configHelper = $configHelper; + $this->logsFactory = $logsFactory; + $this->logsResourceModel = $logsResourceModel; $this->log = $this->configHelper->getConfigData('signifyd/logs/log'); } @@ -42,6 +60,19 @@ public function aroundAddRecord(SignifydLogger $subject, callable $proceed, $lev if (isset($context['entity'])) { $log = $this->configHelper->getConfigData('signifyd/logs/log', $context['entity']); + + try { + /** @var \Signifyd\Connect\Model\Logs $modelLogs */ + $modelLogs = $this->getSignifydLogModel($context['entity']); + $type = $level === 200 ? 'Info' : 'Debug'; + $modelLogs->setType($type); + $modelLogs->setEntry($message); + $this->logsResourceModel->save($modelLogs); + } catch (\Error $e) { + + } catch (\Exception $e) { + + } unset($context['entity']); } else { $log = $this->log; @@ -53,4 +84,31 @@ public function aroundAddRecord(SignifydLogger $subject, callable $proceed, $lev return $result; } -} \ No newline at end of file + + public function getSignifydLogModel($entity) + { + /** @var \Signifyd\Connect\Model\Logs $logs */ + $logs = $this->logsFactory->create(); + + if ($entity instanceof \Signifyd\Connect\Model\Casedata && $entity->isEmpty() == false) { + $orderId = $entity->getOrderId(); + $quoteId = $entity->getQuoteId(); + + if (isset($orderId)) { + $logs->setOrderId($orderId); + } + + if (isset($quoteId)) { + $logs->setQuoteId($quoteId); + } + } elseif ($entity instanceof \Magento\Sales\Model\Order && $entity->isEmpty() == false) { + $orderId = $entity->getId(); + $logs->setOrderId($orderId); + } elseif ($entity instanceof \Magento\Quote\Model\Quote && $entity->isEmpty() == false) { + $quoteId = $entity->getId(); + $logs->setQuoteId($quoteId); + } + + return $logs; + } +} diff --git a/Plugin/Magento/Authorizenet/Model/TransactionService.php b/Plugin/Magento/Authorizenet/Model/TransactionService.php index c32d1617..1fea82c1 100644 --- a/Plugin/Magento/Authorizenet/Model/TransactionService.php +++ b/Plugin/Magento/Authorizenet/Model/TransactionService.php @@ -2,14 +2,14 @@ namespace Signifyd\Connect\Plugin\Magento\Authorizenet\Model; -use Magento\Framework\Registry; +use Signifyd\Connect\Model\Registry; class TransactionService { /** * @var Registry */ - protected $registry; + public $registry; /** * Payflowlink constructor. @@ -28,8 +28,7 @@ public function __construct( */ public function afterGetTransactionDetails(\Magento\Authorizenet\Model\TransactionService $subject, $result) { - $this->registry->unregister('signifyd_payment_data'); - $this->registry->register('signifyd_payment_data', $result); + $this->registry->setData('signifyd_payment_data', $result); return $result; } } diff --git a/Plugin/Magento/Csp/Model/Collector/ControllerCollector.php b/Plugin/Magento/Csp/Model/Collector/ControllerCollector.php new file mode 100644 index 00000000..92d19aec --- /dev/null +++ b/Plugin/Magento/Csp/Model/Collector/ControllerCollector.php @@ -0,0 +1,39 @@ +fetchPolicyFactory = $fetchPolicyFactory; + } + + public function beforeCollect(MagentoControllerCollector $subject, array $defaultPolicies) + { + //plugin necessary to send the fingerprint without the Signifyd script generating a CSP error + $defaultPolicies[] = $this->fetchPolicyFactory->create( + [ + 'id' => 'script-src', + 'noneAllowed' => false, + 'hostSources' => ['https://h64.online-metrix.net'], + 'schemeSources' => [], + 'selfAllowed' => true, + 'inlineAllowed' => true + ] + ); + + return [$defaultPolicies]; + } +} diff --git a/Plugin/Magento/PaymentServicesPaypal/Gateway/Http/ServiceClient.php b/Plugin/Magento/PaymentServicesPaypal/Gateway/Http/ServiceClient.php new file mode 100644 index 00000000..91ea183d --- /dev/null +++ b/Plugin/Magento/PaymentServicesPaypal/Gateway/Http/ServiceClient.php @@ -0,0 +1,91 @@ +transactionIntegration = $transactionIntegration; + } + + /** + * @param PaymentServicesPaypalServiceClient $subject + * @param callable $proceed + * @param $transferObject + * @return void + * @throws ClientException + */ + public function aroundPlaceRequest(PaymentServicesPaypalServiceClient $subject, callable $proceed, $transferObject) + { + try { + return $proceed($transferObject); + } catch (ClientException $e) { + $signifydReason = null; + $deniedResponse = __( + 'Your payment was not successful. ' + . 'Ensure you have entered your details correctly and try again, ' + . 'or try a different payment method. If you have continued problems, ' + . 'contact the issuing bank for your payment method.' + ); + $processingErrorResponse = __('Error happened when processing the request. Please try again later.'); + + $errorCode = array_search($e->getMessage(), PaymentServicesPaypalServiceClient::CAPTURE_ERRORS); + + if ($errorCode === false) { + if ($e->getMessage() == $deniedResponse) { + $errorCode = "PAYMENT_DENIED"; + } elseif ($e->getMessage() == $processingErrorResponse) { + $errorCode = "PROCESSING_ERROR"; + } else { + throw new ClientException(__($e->getMessage())); + } + } + + switch ($errorCode) { + case 'PROCESSING_ERROR': + case 'INVALID_CURRENCY_CODE': + case 'CANNOT_BE_ZERO_OR_NEGATIVE': + case 'DECIMAL_PRECISION': + case 'PAYMENT_DENIED': + case 'DECIMALS_NOT_SUPPORTED': + case 'TRANSACTION_REFUSED': + case 'AUTHORIZATION_VOIDED': + case 'MAX_CAPTURE_COUNT_EXCEEDED': + case 'DUPLICATE_INVOICE_ID': + case 'AUTH_CAPTURE_CURRENCY_MISMATCH': + case 'AUTHORIZATION_ALREADY_CAPTURED': + case 'AUTHORIZATION_EXPIRED': + case 'MAX_CAPTURE_AMOUNT_EXCEEDED': + case 'PAYEE_ACCOUNT_LOCKED_OR_CLOSED': + case 'PAYER_ACCOUNT_LOCKED_OR_CLOSED': + $signifydReason = 'PROCESSING_ERROR'; + break; + + case 'PAYER_CANNOT_PAY': + $signifydReason = 'INSUFFICIENT_FUNDS'; + break; + } + + $this->transactionIntegration->setGatewayRefusedReason($signifydReason); + $this->transactionIntegration->setGatewayStatusMessage($e->getMessage()); + $this->transactionIntegration->submitToTransactionApi(); + + throw new ClientException(__($e->getMessage())); + } + } +} diff --git a/Plugin/Magento/Paypal/Model/Payflowlink.php b/Plugin/Magento/Paypal/Model/Payflowlink.php index 7fa22c5f..bc5bfa7c 100644 --- a/Plugin/Magento/Paypal/Model/Payflowlink.php +++ b/Plugin/Magento/Paypal/Model/Payflowlink.php @@ -2,14 +2,14 @@ namespace Signifyd\Connect\Plugin\Magento\Paypal\Model; -use Magento\Framework\Registry; +use Signifyd\Connect\Model\Registry; class Payflowlink { /** * @var Registry */ - protected $registry; + public $registry; /** * Payflowlink constructor. @@ -28,7 +28,7 @@ public function __construct( */ public function beforeProcess(\Magento\Paypal\Model\Payflowlink $subject, $responseData) { - $this->registry->register('signifyd_payment_data', $responseData); + $this->registry->setData('signifyd_payment_data', $responseData); return [$responseData]; } } diff --git a/Plugin/Magento/Sales/Api/OrderRepositoryInterface.php b/Plugin/Magento/Sales/Api/OrderRepositoryInterface.php index f42ed32c..f66590c5 100644 --- a/Plugin/Magento/Sales/Api/OrderRepositoryInterface.php +++ b/Plugin/Magento/Sales/Api/OrderRepositoryInterface.php @@ -15,22 +15,22 @@ class OrderRepositoryInterface /** * @var OrderFactory */ - protected $orderFactory; + public $orderFactory; /** * @var OrderExtensionFactory */ - protected $orderExtensionFactory; + public $orderExtensionFactory; /** * @var CasedataResourceModel */ - protected $casedataResourceModel; + public $casedataResourceModel; /** * @var CasedataFactory */ - protected $casedataFactory; + public $casedataFactory; /** * @param OrderExtensionFactory $extensionFactory @@ -57,7 +57,7 @@ public function __construct( public function setSignifydOrderAttributeData(OrderInterface $order) { try { - /** @var $case \Signifyd\Connect\Model\Casedata */ + /** @var \Signifyd\Connect\Model\Casedata $case */ $case = $this->casedataFactory->create(); $this->casedataResourceModel->load($case, $order->getId(), 'order_id'); diff --git a/Plugin/Magento/Sales/Block/Adminhtml/Order/View.php b/Plugin/Magento/Sales/Block/Adminhtml/Order/View.php index 4570922d..74594ba7 100644 --- a/Plugin/Magento/Sales/Block/Adminhtml/Order/View.php +++ b/Plugin/Magento/Sales/Block/Adminhtml/Order/View.php @@ -5,30 +5,39 @@ use Magento\Sales\Block\Adminhtml\Order\View as MagentoOrderView; use Signifyd\Connect\Model\CasedataFactory; use Signifyd\Connect\Model\ResourceModel\Casedata as CasedataResourceModel; +use Signifyd\Connect\Model\UpdateOrder\Action as UpdateOrderAction; class View { /** * @var CasedataFactory */ - protected $casedataFactory; + public $casedataFactory; /** * @var CasedataResourceModel */ - protected $casedataResourceModel; + public $casedataResourceModel; + + /** + * @var UpdateOrderAction + */ + public $updateOrderAction; /** * View constructor. * @param CasedataFactory $casedataFactory * @param CasedataResourceModel $casedataResourceModel + * @param UpdateOrderAction $updateOrderAction */ public function __construct( CasedataFactory $casedataFactory, - CasedataResourceModel $casedataResourceModel + CasedataResourceModel $casedataResourceModel, + UpdateOrderAction $updateOrderAction ) { $this->casedataResourceModel = $casedataResourceModel; $this->casedataFactory = $casedataFactory; + $this->updateOrderAction = $updateOrderAction; } public function beforeAddButton( @@ -40,14 +49,14 @@ public function beforeAddButton( $region = 'toolbar' ) { if ($buttonId == 'order_unhold') { - /** @var $case \Signifyd\Connect\Model\Casedata */ + /** @var \Signifyd\Connect\Model\Casedata $case */ $case = $this->casedataFactory->create(); $this->casedataResourceModel->load($case, $subject->getOrder()->getId(), 'order_id'); if (!$case->isEmpty()) { $guarantee = $case->getData('guarantee'); - if (!$case->isHoldReleased() && $guarantee == 'N/A') { + if (!$this->updateOrderAction->isHoldReleased($case) && $guarantee == 'N/A') { $url = $subject->getUrl('sales/*/unhold', ['signifyd_unhold' => 1]); $data['class'] = $data['class'] . ' confirm-unhold'; diff --git a/Plugin/Magento/Sales/Controller/Adminhtml/Order/Unhold.php b/Plugin/Magento/Sales/Controller/Adminhtml/Order/Unhold.php index e055cd19..cc77664b 100644 --- a/Plugin/Magento/Sales/Controller/Adminhtml/Order/Unhold.php +++ b/Plugin/Magento/Sales/Controller/Adminhtml/Order/Unhold.php @@ -8,38 +8,44 @@ use Signifyd\Connect\Model\ResourceModel\Casedata as CasedataResourceModel; use Signifyd\Connect\Helper\OrderHelper; use Magento\Framework\App\ResourceConnection; +use Signifyd\Connect\Model\UpdateOrder\Action as UpdateOrderAction; class Unhold { /** * @var OrderRepositoryInterface */ - protected $orderRepository; + public $orderRepository; /** * @var OrderHelper */ - protected $orderHelper; + public $orderHelper; /** * @var Session */ - protected $authSession; + public $authSession; /** * @var CasedataFactory */ - protected $casedataFactory; + public $casedataFactory; /** * @var CasedataResourceModel */ - protected $casedataResourceModel; + public $casedataResourceModel; /** * @var ResourceConnection */ - protected $resourceConnection; + public $resourceConnection; + + /** + * @var UpdateOrderAction + */ + public $updateOrderAction; /** * Unhold constructor. @@ -49,6 +55,7 @@ class Unhold * @param CasedataFactory $casedataFactory * @param CasedataResourceModel $casedataResourceModel * @param ResourceConnection $resourceConnection + * @param UpdateOrderAction $updateOrderAction */ public function __construct( OrderRepositoryInterface $orderRepository, @@ -56,7 +63,8 @@ public function __construct( Session $authSession, CasedataFactory $casedataFactory, CasedataResourceModel $casedataResourceModel, - ResourceConnection $resourceConnection + ResourceConnection $resourceConnection, + UpdateOrderAction $updateOrderAction ) { $this->orderRepository = $orderRepository; $this->orderHelper = $orderHelper; @@ -64,6 +72,7 @@ public function __construct( $this->casedataResourceModel = $casedataResourceModel; $this->casedataFactory = $casedataFactory; $this->resourceConnection = $resourceConnection; + $this->updateOrderAction = $updateOrderAction; } /** @@ -87,7 +96,7 @@ public function afterExecute(\Magento\Sales\Controller\Adminhtml\Order $subject, try { /** @var \Magento\Sales\Model\Order $order */ $order = $this->orderRepository->get($orderId); - /** @var $case \Signifyd\Connect\Model\Casedata */ + /** @var \Signifyd\Connect\Model\Casedata $case */ $case = $this->casedataFactory->create(); $this->orderHelper->addCommentToStatusHistory( @@ -97,7 +106,7 @@ public function afterExecute(\Magento\Sales\Controller\Adminhtml\Order $subject, $this->casedataResourceModel->loadForUpdate($case, $order->getId(), 'order_id', 2); - if ($case->isHoldReleased() === false) { + if ($this->updateOrderAction->isHoldReleased($case) === false) { $case->setEntries('hold_released', 1); } diff --git a/Plugin/MercadoPago/Model/Core.php b/Plugin/MercadoPago/Model/Core.php index 6428e257..2e05ec42 100644 --- a/Plugin/MercadoPago/Model/Core.php +++ b/Plugin/MercadoPago/Model/Core.php @@ -10,7 +10,7 @@ class Core /** * @var TransactionIntegration */ - protected $transactionIntegration; + public $transactionIntegration; /** * @param TransactionIntegration $transactionIntegration diff --git a/Plugin/Openpay/Cards/Model/Payment.php b/Plugin/Openpay/Cards/Model/Payment.php index d81cfb46..f02b5d24 100644 --- a/Plugin/Openpay/Cards/Model/Payment.php +++ b/Plugin/Openpay/Cards/Model/Payment.php @@ -10,49 +10,49 @@ use Signifyd\Connect\Model\ResourceModel\Casedata as CasedataResourceModel; use Magento\Store\Model\StoreManagerInterface; use Openpay\Cards\Model\Payment as OpenpayPayment; -use Magento\Checkout\Model\Cart as CheckoutCart; +use Magento\Checkout\Model\Session as CheckoutSession; class Payment { /** * @var CasedataFactory */ - protected $casedataFactory; + public $casedataFactory; /** * @var CasedataResourceModel */ - protected $casedataResourceModel; + public $casedataResourceModel; /** * @var Logger */ - protected $logger; + public $logger; /** * @var StoreManagerInterface */ - protected $storeManager; + public $storeManager; /** - * @var CheckoutCart + * @var CheckoutSession */ - protected $checkoutCart; + public $checkoutSession; /** * @var TransactionsFactory */ - protected $transactionsFactory; + public $transactionsFactory; /** * @var ConfigHelper */ - protected $configHelper; + public $configHelper; /** * @var Client */ - protected $client; + public $client; /** * CheckoutPaymentsDetailsHandler constructor. @@ -60,26 +60,26 @@ class Payment * @param CasedataResourceModel $casedataResourceModel * @param Logger $logger * @param StoreManagerInterface $storeManager - * @param CheckoutCart $checkoutCart * @param TransactionsFactory $transactionsFactory * @param ConfigHelper $configHelper * @param Client $client + * @param CheckoutSession $checkoutSession */ public function __construct( CasedataFactory $casedataFactory, CasedataResourceModel $casedataResourceModel, Logger $logger, StoreManagerInterface $storeManager, - CheckoutCart $checkoutCart, TransactionsFactory $transactionsFactory, ConfigHelper $configHelper, - Client $client + Client $client, + CheckoutSession $checkoutSession ) { $this->casedataFactory = $casedataFactory; $this->casedataResourceModel = $casedataResourceModel; $this->logger = $logger; $this->storeManager = $storeManager; - $this->checkoutCart = $checkoutCart; + $this->checkoutSession = $checkoutSession; $this->transactionsFactory = $transactionsFactory; $this->configHelper = $configHelper; $this->client = $client; @@ -106,14 +106,14 @@ public function beforeError(OpenpayPayment $subject, $e) $this->storeManager->getStore()->getId() ); - $quote = $this->checkoutCart->getQuote(); + $quote = $this->checkoutSession->getQuote(); - if ($isPreAuth === false || isset($quote) === false) { + if ($isPreAuth === false || $quote->isEmpty()) { return null; } $quoteId = $quote->getId(); - /** @var $case \Signifyd\Connect\Model\Casedata */ + /** @var \Signifyd\Connect\Model\Casedata $case */ $case = $this->casedataFactory->create(); $this->casedataResourceModel->load($case, $quoteId, 'quote_id'); @@ -171,7 +171,7 @@ public function beforeError(OpenpayPayment $subject, $e) } if ($case->getEntries('OpenPayRefusedReason') == $signifydReason) { - $this->logger->info("Reason already send"); + $this->logger->info("Reason already send", ['entity' => $case]); return null; } diff --git a/Plugin/Rootways/Authorizecim/Gateway/Validator/ResponseValidatorPlugin.php b/Plugin/Rootways/Authorizecim/Gateway/Validator/ResponseValidatorPlugin.php new file mode 100644 index 00000000..b055b72c --- /dev/null +++ b/Plugin/Rootways/Authorizecim/Gateway/Validator/ResponseValidatorPlugin.php @@ -0,0 +1,115 @@ +transactionIntegration = $transactionIntegration; + $this->logger = $logger; + } + + public function beforeValidate(AuthorizecimResponseValidator $subject, array $validationSubject) + { + try { + $response = SubjectReader::readResponse($validationSubject); + $errorCode = []; + $errorMessages = []; + + if (isset($response['transactionResponse']['errors']['error']['errorText'])) { + $errorCode[] = $response['transactionResponse']['errors']['error']['errorCode']; + $errorMessages[] = __($response['transactionResponse']['errors']['error']['errorText']); + $this->submitErrorToSignifyd($errorCode, $errorMessages); + } + } catch (\Exception $e) { + $this->logger->critical($e); + } catch (\Error $err) { + $this->logger->critical($err); + } + + return [$validationSubject]; + } + + protected function submitErrorToSignifyd($errorCode, $errorMessages) + { + $authorizeErrorCode = $errorCode[0] ?? ''; + $authorizeErrorMessages = $errorMessages[0]->getText() ?? ''; + + //Mapping the error according to Signifyd doc + switch ($authorizeErrorCode) { + case 6: + case 37: + case 315: + $signifydReason = 'INVALID_NUMBER'; + break; + + case 7: + case 8: + case 316: + case 317: + $signifydReason = 'INVALID_EXPIRY_DATE'; + break; + + case 19: + case 20: + case 21: + case 22: + case 23: + case 25: + case 26: + case 35: + case 57: + case 58: + case 59: + case 60: + case 61: + case 62: + case 63: + case 120: + case 121: + case 122: + case 153: + case 170: + case 171: + case 172: + case 173: + case 180: + case 181: + case 192: + case 261: + $signifydReason = 'PROCESSING_ERROR'; + break; + + default: + $signifydReason = 'CARD_DECLINED'; + break; + + } + + $this->transactionIntegration->setGatewayRefusedReason($signifydReason); + $this->transactionIntegration->setGatewayStatusMessage($authorizeErrorMessages); + $this->transactionIntegration->submitToTransactionApi(); + } +} diff --git a/Plugin/StripeIntegration/Payments/Api/Service.php b/Plugin/StripeIntegration/Payments/Api/Service.php index 3d1c305a..eab19796 100644 --- a/Plugin/StripeIntegration/Payments/Api/Service.php +++ b/Plugin/StripeIntegration/Payments/Api/Service.php @@ -10,7 +10,7 @@ class Service /** * @var TransactionIntegration */ - protected $transactionIntegration; + public $transactionIntegration; /** * CheckoutPaymentsDetailsHandler constructor. diff --git a/Plugin/StripeIntegration/Payments/Helper/Generic.php b/Plugin/StripeIntegration/Payments/Helper/Generic.php index 837fc2e6..2d3fa9e1 100644 --- a/Plugin/StripeIntegration/Payments/Helper/Generic.php +++ b/Plugin/StripeIntegration/Payments/Helper/Generic.php @@ -23,27 +23,27 @@ class Generic /** * @var Logger */ - protected $logger; + public $logger; /** * @var OrderHelper */ - protected $orderHelper; + public $orderHelper; /** * @var OrderResourceModel */ - protected $orderResourceModel; + public $orderResourceModel; /** * @var CasedataFactory */ - protected $casedataFactory; + public $casedataFactory; /** * @var CasedataResourceModel */ - protected $casedataResourceModel; + public $casedataResourceModel; /** * Cancel constructor. @@ -92,7 +92,8 @@ public function beforeCancelOrCloseOrder( $order->unhold(); $this->orderResourceModel->save($order); $this->logger->info( - "Unhold order {$order->getIncrementId()} before stripe tries to cancel or close" + "Unhold order {$order->getIncrementId()} before stripe tries to cancel or close", + ['entity' => $order] ); $this->orderHelper->addCommentToStatusHistory( diff --git a/Plugin/StripeIntegration/Payments/Helper/Order.php b/Plugin/StripeIntegration/Payments/Helper/Order.php index f5fe966f..5f7be8d2 100644 --- a/Plugin/StripeIntegration/Payments/Helper/Order.php +++ b/Plugin/StripeIntegration/Payments/Helper/Order.php @@ -19,27 +19,27 @@ class Order /** * @var Logger */ - protected $logger; + public $logger; /** * @var CasedataFactory */ - protected $casedataFactory; + public $casedataFactory; /** * @var CasedataResourceModel */ - protected $casedataResourceModel; + public $casedataResourceModel; /** * @var OrderResourceModel */ - protected $orderResourceModel; + public $orderResourceModel; /** * @var OrderHelper */ - protected $orderHelper; + public $orderHelper; /** * Cancel constructor. @@ -87,7 +87,8 @@ public function aroundOnTransaction(StripeIntegrationOrder $subject, callable $p $order->hold(); $this->orderResourceModel->save($order); $this->logger->info( - "Hold order {$order->getIncrementId()} after stripe remove" + "Hold order {$order->getIncrementId()} after stripe remove", + ['entity' => $case] ); $this->orderHelper->addCommentToStatusHistory( diff --git a/Setup/Patch/Data/CoverageRequestUpdate.php b/Setup/Patch/Data/CoverageRequestUpdate.php index 04b5cc3f..2d397033 100644 --- a/Setup/Patch/Data/CoverageRequestUpdate.php +++ b/Setup/Patch/Data/CoverageRequestUpdate.php @@ -11,12 +11,12 @@ class CoverageRequestUpdate implements DataPatchInterface /** * @var WriterInterface */ - protected $configWriter; + public $configWriter; /** * @var ConfigHelper */ - protected $configHelper; + public $configHelper; /** * @param WriterInterface $configWriter @@ -30,6 +30,9 @@ public function __construct( $this->configHelper = $configHelper; } + /** + * @return $this|CoverageRequestUpdate + */ public function apply() { $decisionRequest = $this->configHelper->getDecisionRequest(); @@ -43,6 +46,8 @@ public function apply() $this->configWriter->save('signifyd/general/decision_request', 'NONE'); break; } + + return $this; } /** diff --git a/Setup/Patch/Data/InstallConfig.php b/Setup/Patch/Data/InstallConfig.php index b46ad5c4..81b162f8 100644 --- a/Setup/Patch/Data/InstallConfig.php +++ b/Setup/Patch/Data/InstallConfig.php @@ -9,22 +9,22 @@ class InstallConfig implements DataPatchInterface { - protected $logger; + public $logger; /** * @var WriterInterface */ - protected $writerInterface; + public $writerInterface; /** * @var ScopeConfigInterface */ - protected $scopeConfigInterface; + public $scopeConfigInterface; /** * @var DateTime */ - protected $dateTime; + public $dateTime; /** * @param \Signifyd\Connect\Logger\Install $logger @@ -44,6 +44,9 @@ public function __construct( $this->dateTime = $dateTime; } + /** + * @return $this|InstallConfig + */ public function apply() { try { @@ -55,6 +58,8 @@ public function apply() } catch (\Exception $e) { $this->logger->error($e->getMessage()); } + + return $this; } /** diff --git a/Setup/Patch/Data/UpdateOrderId.php b/Setup/Patch/Data/UpdateOrderId.php index b8e096aa..2b4e93b3 100644 --- a/Setup/Patch/Data/UpdateOrderId.php +++ b/Setup/Patch/Data/UpdateOrderId.php @@ -12,17 +12,17 @@ class UpdateOrderId implements DataPatchInterface /** * @var SchemaSetupInterface */ - protected $schemaSetupInterface; + public $schemaSetupInterface; /** * @var Install */ - protected $logger; + public $logger; /** * @var WriterInterface */ - protected $configWriter; + public $configWriter; /** * @param SchemaSetupInterface $schemaSetupInterface @@ -39,6 +39,9 @@ public function __construct( $this->configWriter = $configWriter; } + /** + * @return $this|UpdateOrderId + */ public function apply() { $signifydConnectCase = $this->schemaSetupInterface->getTable('signifyd_connect_case'); @@ -67,6 +70,8 @@ public function apply() $this->logger->debug('Update order_id on magento status different from complete failed'); $this->configWriter->save("signifyd/general/upgrade4.3_inconsistency", "setup"); } + + return $this; } /** diff --git a/Test/Integration/Cases/Cron/CreateTest.php b/Test/Integration/Cases/Cron/CreateTest.php index 838e0d1e..f3150546 100644 --- a/Test/Integration/Cases/Cron/CreateTest.php +++ b/Test/Integration/Cases/Cron/CreateTest.php @@ -6,15 +6,20 @@ use Signifyd\Connect\Model\Casedata; use Signifyd\Connect\Model\Casedata\UpdateCaseV2Factory; use Signifyd\Connect\Model\Casedata\UpdateCaseFactory; +use Signifyd\Connect\Model\UpdateOrderFactory; +use Signifyd\Connect\Model\LogsFile; +use Magento\Framework\Filesystem; +use Magento\Framework\App\Filesystem\DirectoryList; +use Magento\Framework\Filesystem\Driver\File as DriverFile; class CreateTest extends OrderTestCase { /** * @var \Signifyd\Connect\Cron\RetryCaseJob */ - protected $retryCaseJob; + public $retryCaseJob; - protected $paymentMethod = 'banktransfer'; + public $paymentMethod = 'banktransfer'; public function setUp(): void { @@ -22,6 +27,11 @@ public function setUp(): void $this->retryCaseJob = $this->objectManager->create(\Signifyd\Connect\Cron\RetryCaseJob::class); $this->updateCaseFactory = $this->objectManager->create(UpdateCaseFactory::class); + $this->updateOrderFactory = $this->objectManager->create(UpdateOrderFactory::class); + $this->logsFile = $this->objectManager->create(LogsFile::class); + $this->filesystem = $this->objectManager->create(Filesystem::class); + $this->directoryList = $this->objectManager->get(DirectoryList::class); + $this->driverFile = $this->objectManager->create(DriverFile::class); } /** diff --git a/Test/Integration/Cases/Cron/RetryFulfillmentJob.php b/Test/Integration/Cases/Cron/RetryFulfillmentJob.php index af5d35a3..105fbc81 100644 --- a/Test/Integration/Cases/Cron/RetryFulfillmentJob.php +++ b/Test/Integration/Cases/Cron/RetryFulfillmentJob.php @@ -9,7 +9,7 @@ class RetryFulfillmentJob extends OrderTestCase /** * @var \Signifyd\Connect\Cron\RetryFulfillmentJob */ - protected $retryFulfillmentJob; + public $retryFulfillmentJob; public function setUp(): void { diff --git a/Test/Integration/Cases/Logs/CreateLog.php b/Test/Integration/Cases/Logs/CreateLog.php new file mode 100644 index 00000000..a2c21ffc --- /dev/null +++ b/Test/Integration/Cases/Logs/CreateLog.php @@ -0,0 +1,45 @@ +processReviewCase(true); + $case = $this->getCase(); + $requestJson = $this->getRequestJson($case); + $updateCaseFactory = $this->updateCaseFactory->create(); + $case = $updateCaseFactory($case, $requestJson); + + $this->assertLogValidation($case); + } + + public function assertLogValidation($case) + { + $fileName = $this->logsFile->createLogFile($case->getData('order_id')); + $filePath = 'media/signifyd_logs/' . $fileName; + $directory = $this->filesystem->getDirectoryRead(DirectoryList::PUB); + + try { + $readFile = $directory->readFile($filePath); + } catch (\Exception $e) { + $readFile = null; + } + + $this->assertEquals(Casedata::COMPLETED_STATUS, $case->getData('magento_status')); + $this->assertTrue(isset($readFile)); + } +} diff --git a/Test/Integration/Cases/Logs/DeleteLog.php b/Test/Integration/Cases/Logs/DeleteLog.php new file mode 100644 index 00000000..04e4b0b7 --- /dev/null +++ b/Test/Integration/Cases/Logs/DeleteLog.php @@ -0,0 +1,47 @@ +logsFile->createLogFile($case->getData('order_id')); + $filePath = 'media/signifyd_logs/' . $fileName; + $directory = $this->filesystem->getDirectoryRead(DirectoryList::PUB); + + try { + $readFile = $directory->readFile($filePath); + } catch (\Exception $e) { + $readFile = null; + } + + if (isset($readFile)) { + $this->logsFile->prepLogsDir(); + $path = $this->directoryList->getPath('media') . '/signifyd_logs'; + + try { + $this->driverFile->deleteDirectory($path); + $directoryDeleted = true; + } catch (\Exception $e) { + } + + try { + $readFilePostDelete = $directory->readFile($filePath); + } catch (\Exception $e) { + $readFilePostDelete = null; + } + } + + $this->assertEquals(Casedata::COMPLETED_STATUS, $case->getData('magento_status')); + $this->assertTrue($directoryDeleted); + //must be false after delete directory + $this->assertFalse(isset($readFilePostDelete)); + //validate if the file is successfully created + $this->assertTrue(isset($readFile)); + } +} diff --git a/Test/Integration/Cases/Reviewed/ToRejectTest.php b/Test/Integration/Cases/Reviewed/ToRejectTest.php index 1c2c6577..460009c8 100644 --- a/Test/Integration/Cases/Reviewed/ToRejectTest.php +++ b/Test/Integration/Cases/Reviewed/ToRejectTest.php @@ -12,19 +12,39 @@ public function testCronCreateCase() // Bypassing test } + public function initConfig() + { + /** @var \Magento\Framework\App\Config\Storage\WriterInterface $writerInterface */ + $writerInterface = $this->objectManager->create(\Magento\Framework\App\Config\Storage\WriterInterface::class); + $writerInterface->save('signifyd/advanced/guarantee_negative_action', 'cancel'); + $writerInterface->save('signifyd/advanced/guarantee_positive_action', 'unhold'); + } + /** * @magentoDataFixture configFixture */ public function testToReject() { + $this->initConfig(); + $this->processReviewCase(); $case = $this->getCase(); $requestJson = $this->getRequestJson($case, false); $updateCaseFactory = $this->updateCaseFactory->create(); $case = $updateCaseFactory($case, $requestJson); + $this->assertEqualsUpdate($case); + } + + public function assertEqualsUpdate($case) + { + $updateOrder = $this->updateOrderFactory->create(); + $case = $updateOrder($case); + $order = $this->getOrder($case->getData('order_id')); + $this->assertEquals(Casedata::COMPLETED_STATUS, $case->getData('magento_status')); $this->assertEquals('REJECT', $case->getData('guarantee')); $this->assertEquals('ACCEPT', $case->getOrigData('guarantee')); + $this->assertFalse($order->canCancel()); } } diff --git a/Test/Integration/Cases/Update/BypassAdditionalUpdatesTest.php b/Test/Integration/Cases/Update/BypassAdditionalUpdatesTest.php new file mode 100644 index 00000000..d0278b85 --- /dev/null +++ b/Test/Integration/Cases/Update/BypassAdditionalUpdatesTest.php @@ -0,0 +1,30 @@ +objectManager->create(\Magento\Framework\App\Config\Storage\WriterInterface::class); + $writerInterface->save('signifyd/advanced/guarantee_negative_action', 'cancel'); + $writerInterface->save('signifyd/advanced/guarantee_positive_action', 'unhold'); + $writerInterface->save('signifyd/advanced/bypass_additional_updates', 1); + } + + public function assertEqualsUpdate($case) + { + $updateOrder = $this->updateOrderFactory->create(); + $case = $updateOrder($case); + $order = $this->getOrder($case->getData('order_id')); + + $this->assertEquals(Casedata::COMPLETED_STATUS, $case->getData('magento_status')); + $this->assertEquals('REJECT', $case->getData('guarantee')); + $this->assertEquals('ACCEPT', $case->getOrigData('guarantee')); + $this->assertTrue($order->canCancel()); + } +} diff --git a/Test/Integration/Cases/Update/OrderAddressTest.php b/Test/Integration/Cases/Update/OrderAddressTest.php index a6d7ac6c..263d1b19 100644 --- a/Test/Integration/Cases/Update/OrderAddressTest.php +++ b/Test/Integration/Cases/Update/OrderAddressTest.php @@ -10,12 +10,12 @@ class OrderAddressTest extends OrderTestCase /** * @var \Magento\Sales\Model\Order\AddressRepository */ - protected $addressRepository; + public $addressRepository; /** * @var \Magento\Sales\Model\OrderRepository */ - protected $orderRepository; + public $orderRepository; public function setUp(): void { diff --git a/Test/Integration/Cases/Webhook/V2ReviewTest.php b/Test/Integration/Cases/Webhook/V2ReviewTest.php index 59126b46..67ba0ce3 100644 --- a/Test/Integration/Cases/Webhook/V2ReviewTest.php +++ b/Test/Integration/Cases/Webhook/V2ReviewTest.php @@ -8,7 +8,7 @@ class V2ReviewTest extends OrderTestCase { - protected $incrementId = '100000002'; + public $incrementId = '100000002'; /** * @magentoDataFixture configFixture diff --git a/Test/Integration/Cases/Webhook/V3ReviewTest.php b/Test/Integration/Cases/Webhook/V3ReviewTest.php index 07e26a46..79c5a81b 100644 --- a/Test/Integration/Cases/Webhook/V3ReviewTest.php +++ b/Test/Integration/Cases/Webhook/V3ReviewTest.php @@ -8,7 +8,7 @@ class V3ReviewTest extends OrderTestCase { - protected $incrementId = '100000002'; + public $incrementId = '100000002'; /** * @magentoDataFixture configFixture diff --git a/Test/Integration/OrderTestCase.php b/Test/Integration/OrderTestCase.php index 9ccec8b3..617014e1 100644 --- a/Test/Integration/OrderTestCase.php +++ b/Test/Integration/OrderTestCase.php @@ -17,7 +17,7 @@ class OrderTestCase extends TestCase /** * @var QuoteIdMaskFactory */ - protected $quoteIdMaskFactory; + public $quoteIdMaskFactory; /** * @inheritdoc diff --git a/Test/Integration/TestCase.php b/Test/Integration/TestCase.php index 90d07fa4..29c8fc7a 100644 --- a/Test/Integration/TestCase.php +++ b/Test/Integration/TestCase.php @@ -11,17 +11,17 @@ class TestCase extends \PHPUnit\Framework\TestCase /** * @var \Magento\Framework\ObjectManagerInterface */ - protected $objectManager; + public $objectManager; /** * @var \Signifyd\Connect\Logger\Logger */ - protected $logger; + public $logger; /** * @var string */ - protected $incrementId; + public $incrementId; /** * @inheritdoc @@ -73,11 +73,17 @@ public function getFulfillment($incrementId = null) /** * @return \Magento\Sales\Model\Order */ - public function getOrder() + public function getOrder($orderId = null) { /** @var \Magento\Sales\Model\Order $order */ $order = $this->objectManager->get(\Magento\Sales\Model\Order::class); - $order->loadByIncrementId($this->incrementId); + + if (isset($orderId)) { + $order->load($orderId); + } else { + $order->loadByIncrementId($this->incrementId); + } + return $order; } } diff --git a/Test/Integration/_files/customer/customer.php b/Test/Integration/_files/customer/customer.php index fa1a4c13..e903c28b 100644 --- a/Test/Integration/_files/customer/customer.php +++ b/Test/Integration/_files/customer/customer.php @@ -1,8 +1,5 @@ create(\Magento\Customer\Model\Address::class); diff --git a/Test/Integration/_files/customer/customer_address_rollback.php b/Test/Integration/_files/customer/customer_address_rollback.php index 0e2362e4..ea101815 100644 --- a/Test/Integration/_files/customer/customer_address_rollback.php +++ b/Test/Integration/_files/customer/customer_address_rollback.php @@ -1,8 +1,4 @@ get(\Magento\Framework\Registry::class); diff --git a/Test/Integration/_files/customer/customer_rollback.php b/Test/Integration/_files/customer/customer_rollback.php index 3b2d5904..542b5e94 100644 --- a/Test/Integration/_files/customer/customer_rollback.php +++ b/Test/Integration/_files/customer/customer_rollback.php @@ -1,8 +1,4 @@ + + + + ACn3V1o8UtMAYrQFYqcTYm5DtzbWJ96H + signifyd/general/key + + + without_restriction + signifyd/general/restrict_payment_methods + + + PRE_AUTH + POST_AUTH + signifyd/general/policy_name + + + 1 + true + true + John.Doe@example.com + John + Doe + John Doe + pwdTest123! + 0 + 0 + General + Signifyd_Refuse + + + John + Doe + 368 + + 110 Greene St #306 + + New York + New York + US + 10012 + +15552293326 + Yes + Yes + RegionNY + United States + + diff --git a/Test/Mftf/Section/AdminSignifydSection.xml b/Test/Mftf/Section/AdminSignifydSection.xml new file mode 100644 index 00000000..29de9900 --- /dev/null +++ b/Test/Mftf/Section/AdminSignifydSection.xml @@ -0,0 +1,8 @@ + + + +
+ +
+
diff --git a/Test/Mftf/Test/SignifydAcceptPreAuthCaseTest.xml b/Test/Mftf/Test/SignifydAcceptPreAuthCaseTest.xml new file mode 100644 index 00000000..8745e4ba --- /dev/null +++ b/Test/Mftf/Test/SignifydAcceptPreAuthCaseTest.xml @@ -0,0 +1,22 @@ + + + + + + + + + <description value="Validate pre auth case creation"/> + <severity value="CRITICAL"/> + <group value="signifyd"/> + </annotations> + <before> + <!-- Set signifyd pre auth--> + <magentoCLI command="config:set {{SignifydPolicy.path}} {{SignifydPolicy.pre}}" stepKey="setPolicy"/> + </before> + + <!-- Assert that the case was accept --> + <see selector="{{AdminSignifydSection.signifydDecision}}" userInput="ACCEPT" stepKey="seeCaseCreated"/> + </test> +</tests> \ No newline at end of file diff --git a/Test/Mftf/Test/SignifydRejectPreAuthCaseTest.xml b/Test/Mftf/Test/SignifydRejectPreAuthCaseTest.xml new file mode 100644 index 00000000..b3b12e9d --- /dev/null +++ b/Test/Mftf/Test/SignifydRejectPreAuthCaseTest.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="SignifydRejectPreAuthCaseTest" extends="SignifydSuccessPostAuthCaseTest"> + <annotations> + <features value="Signifyd Pre Auth Refused"/> + <stories value="Pre auth case refused"/> + <title value="Pre auth case refused"/> + <description value="Order creation blocked at checkout"/> + <severity value="CRITICAL"/> + <group value="signifyd"/> + </annotations> + <before> + <remove keyForRemoval="loginAsAdmin"/> + <createData entity="Signifyd_Customer_Refuse" stepKey="createCustomer"/> + + <!-- Set signifyd pre auth--> + <magentoCLI command="config:set {{SignifydPolicy.path}} {{SignifydPolicy.pre}}" stepKey="setPolicy"/> + </before> + <after> + <remove keyForRemoval="logout"/> + </after> + + <remove keyForRemoval="waitForLoadSuccessPage2"/> + <remove keyForRemoval="getOrderId"/> + <remove keyForRemoval="clickContinueShoppingButton"/> + <remove keyForRemoval="seeHomePageUrl"/> + <remove keyForRemoval="seeHomePageTitle"/> + <remove keyForRemoval="goToOrdersPage"/> + <remove keyForRemoval="filterOrdersGridById"/> + <remove keyForRemoval="clickCreatedOrderInGrid"/> + <remove keyForRemoval="seeCaseCreated"/> + + <waitForElement selector="{{CheckoutCartMessageSection.errorMessage}}" time="30" stepKey="waitForErrorMessage"/> + <see selector="{{CheckoutCartMessageSection.errorMessage}}" userInput="Your order cannot be processed, please contact our support team" stepKey="assertErrorMessage"/> + </test> +</tests> \ No newline at end of file diff --git a/Test/Mftf/Test/SignifydSuccessPostAuthCaseTest.xml b/Test/Mftf/Test/SignifydSuccessPostAuthCaseTest.xml new file mode 100644 index 00000000..42d2e2d5 --- /dev/null +++ b/Test/Mftf/Test/SignifydSuccessPostAuthCaseTest.xml @@ -0,0 +1,86 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="SignifydSuccessPostAuthCaseTest"> + <annotations> + <features value="Signifyd Post Auth"/> + <stories value="Post auth case created successfully"/> + <title value="Post auth case"/> + <description value="Validate case creation"/> + <severity value="CRITICAL"/> + <group value="signifyd"/> + </annotations> + <before> + <createData entity="_defaultCategory" stepKey="createCategory"/> + <createData entity="SimpleProduct" stepKey="createProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <createData entity="Simple_US_Customer" stepKey="createCustomer"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> + + <!-- Remove checkmo from restrict payment --> + <magentoCLI command="config:set signifyd/general/enabled 1" stepKey="enableExtension"/> + + <!-- Remove checkmo from restrict payment --> + <magentoCLI command="config:set {{SignifydPaymentRestriction.path}} {{SignifydPaymentRestriction.value}}" stepKey="removePaymentRestriction"/> + + <!-- Set MFTF signifyd api key--> + <magentoCLI command="config:set {{SignifydApi.path}} {{SignifydApi.value}}" stepKey="fillApiKey"/> + + <!-- Set signifyd post auth--> + <magentoCLI command="config:set {{SignifydPolicy.path}} {{SignifydPolicy.post}}" stepKey="setPolicy"/> + </before> + <after> + <!--Logout from customer account--> + <actionGroup ref="StorefrontCustomerLogoutActionGroup" stepKey="logoutCustomer"/> + + <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <deleteData createDataKey="createCustomer" stepKey="deleteCustomer"/> + <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> + </after> + <!--Go to Storefront as Customer--> + <actionGroup ref="LoginToStorefrontActionGroup" stepKey="customerLogin"> + <argument name="Customer" value="$$createCustomer$$" /> + </actionGroup> + + <!-- Add simple product to cart and go to checkout--> + <actionGroup ref="AddSimpleProductToCartActionGroup" stepKey="addProductToCart"> + <argument name="product" value="$$createProduct$$"/> + </actionGroup> + <actionGroup ref="GoToCheckoutFromMinicartActionGroup" stepKey="goToCheckoutFromMinicart" /> + + <!--Select Shipping Rate "Flat Rate"--> + <click selector="{{CheckoutShippingMethodsSection.checkShippingMethodByName('Flat Rate')}}" stepKey="selectFlatShippingMethod"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask2"/> + + <!--Click next--> + <actionGroup ref="StorefrontCheckoutClickNextButtonActionGroup" stepKey="clickNext"/> + + <!-- Checkout select Check/Money Order payment --> + <actionGroup ref="CheckoutSelectCheckMoneyOrderPaymentActionGroup" stepKey="selectCheckMoneyPayment2"/> + + <!--Click Place Order button--> + <click selector="{{CheckoutPaymentSection.placeOrder}}" stepKey="clickPlaceOrder2"/> + <see selector="{{CheckoutSuccessMainSection.successTitle}}" userInput="Thank you for your purchase!" stepKey="waitForLoadSuccessPage2"/> + + <!-- Grab order id --> + <grabTextFrom selector="{{CheckoutSuccessMainSection.orderNumber22}}" stepKey="getOrderId"/> + + <!--Continue shopping--> + <click selector="{{CheckoutSuccessMainSection.continueShoppingButton}}" stepKey="clickContinueShoppingButton"/> + <seeCurrentUrlEquals url="{{_ENV.MAGENTO_BASE_URL}}" stepKey="seeHomePageUrl"/> + <see userInput="Home Page" selector="{{StorefrontCMSPageSection.mainTitle}}" stepKey="seeHomePageTitle"/> + + <!-- Open created order --> + <actionGroup ref="AdminOrdersPageOpenActionGroup" stepKey="goToOrdersPage"/> + <actionGroup ref="FilterOrderGridByIdActionGroup" stepKey="filterOrdersGridById"> + <argument name="orderId" value="$getOrderId"/> + </actionGroup> + <click selector="{{AdminDataGridTableSection.firstRow}}" stepKey="clickCreatedOrderInGrid"/> + + <!-- Assert that the case was created successfully --> + <see selector="{{AdminSignifydSection.signifydDecision}}" userInput="N/A" stepKey="seeCaseCreated"/> + </test> +</tests> \ No newline at end of file diff --git a/Ui/Component/Listing/Columns/CaseLink.php b/Ui/Component/Listing/Columns/CaseLink.php index 9a63ab04..2a537b84 100644 --- a/Ui/Component/Listing/Columns/CaseLink.php +++ b/Ui/Component/Listing/Columns/CaseLink.php @@ -20,17 +20,17 @@ class CaseLink extends Column /** * @var SerializerInterface */ - protected $serializer; + public $serializer; /** * @var CasedataFactory */ - protected $casedataFactory; + public $casedataFactory; /** * @var CasedataResourceModel */ - protected $casedataResourceModel; + public $casedataResourceModel; /** * CaseLink constructor. diff --git a/composer.json b/composer.json index 3d027aa6..43b639cb 100644 --- a/composer.json +++ b/composer.json @@ -2,12 +2,12 @@ "name": "signifyd/module-connect", "description": "Signifyd integration for Magento", "require": { - "signifyd/signifyd-php": "4.1.2", + "signifyd/signifyd-php": "4.1.4", "monolog/monolog": ">=1.16.0", "php": ">=5.5.22" }, "type": "magento2-module", - "version": "5.4.0", + "version": "5.8.2", "autoload": { "files": [ "registration.php" diff --git a/docs/LOGS-RETENTION-PERIOD.md b/docs/LOGS-RETENTION-PERIOD.md new file mode 100644 index 00000000..03789ef0 --- /dev/null +++ b/docs/LOGS-RETENTION-PERIOD.md @@ -0,0 +1,38 @@ +[Signifyd Extension for Magento 2](../README.md) > Logs retention period + +# Logs retention period + +By default, Signifyd extension stores logs for a period of 60 days. Logs can be downloaded from the order view. + +### Add custom period + +The custom value must be an integer representing the number of days. +To include custom period use the command below on your database: + +``` +INSERT INTO core_config_data (path, value) VALUES ('signifyd/advanced/logs_retention_period', 70); +``` + +### Update custom period + +To modify an existing custom period, use the command below: + +``` +UPDATE core_config_data SET value=70 WHERE path='signifyd/advanced/logs_retention_period'; +``` + +### Delete custom period + +To use the extension default period, use the command below: + +``` +DELETE FROM core_config_data WHERE path='signifyd/advanced/logs_retention_period'; +``` + +### Checking current custom period + +To check the current custom period, run the command below: + +``` +SELECT * FROM core_config_data WHERE path='signifyd/advanced/logs_retention_period'; +``` diff --git a/docs/PASS-PAYMENT-PRE-AUTH.md b/docs/PASS-PAYMENT-PRE-AUTH.md index 60be5fbb..58f89580 100644 --- a/docs/PASS-PAYMENT-PRE-AUTH.md +++ b/docs/PASS-PAYMENT-PRE-AUTH.md @@ -82,6 +82,8 @@ git apply pre-auth-authorizenet.patch ## Compatible methods ### Adyen +#### Link to the extension https://github.com/Adyen/adyen-magento2 +#### Tested on 9.3.0 - Call transaction API on failure: yes - Payment data available: @@ -91,6 +93,8 @@ git apply pre-auth-authorizenet.patch - Cardholder name: no ### Adyen One-click (saved cards) +#### Link to the extension https://github.com/Adyen/adyen-magento2 +#### Tested on 9.3.0 - Call transaction API on failure: yes - Payment data available: @@ -100,6 +104,8 @@ git apply pre-auth-authorizenet.patch - Cardholder name: no ### Braintree +#### Magento built in +#### Tested on 4.5.0 - Call transaction API on failure: yes - Payment data available: @@ -109,15 +115,8 @@ git apply pre-auth-authorizenet.patch - Cardholder name: no ### OpenPay - -- Call transaction API on failure: yes -- Payment data available: - - Bin: yes - - Last4: yes - - Expiry date: yes - - Cardholder name: no - -### Holocash +#### Link to the extension https://github.com/open-pay/openpay-magento2-cards +#### Tested on 2.3.0 - Call transaction API on failure: yes - Payment data available: @@ -127,6 +126,11 @@ git apply pre-auth-authorizenet.patch - Cardholder name: no ### Stripe +#### Link to the extension https://commercemarketplace.adobe.com/stripe-stripe-payments.html +#### Tested on 3.5.16 + +> [!IMPORTANT] +> Stripe is compatible with pre auth, however it's not possible to collect any payment data - Call transaction API on failure: yes - Payment data available: @@ -135,7 +139,9 @@ git apply pre-auth-authorizenet.patch - Expiry date: no - Cardholder name: no -### Authorize.net +### Authorize.net ParadoxLabs +#### Link to the extension https://commercemarketplace.adobe.com/paradoxlabs-authnetcim.html +#### Tested on 5.0.1 - Call transaction API on failure: yes - Payment data available: @@ -144,7 +150,20 @@ git apply pre-auth-authorizenet.patch - Expiry date: yes - Cardholder name: yes +### Authorize.net Rootways +#### Link to the extension https://www.rootways.com/magento-2-authorize-net-cim-extension +#### Tested on 3.0.1 + +- Call transaction API on failure: yes +- Payment data available: + - Bin: yes (not available for saved cards) + - Last4: yes + - Expiry date: yes + - Cardholder name: no + ### Mercado Pago - Custom Checkout +#### Link to the extension https://commercemarketplace.adobe.com/mercadopago-adb-payment.html +#### Tested on 3.19.0 - Call transaction API on failure: yes - Payment data available: @@ -154,6 +173,8 @@ git apply pre-auth-authorizenet.patch - Cardholder name: no ### Cybersource (Flex Microform) +#### Link to the extension https://commercemarketplace.adobe.com/cybersource-global-payment-management.html +#### Tested on 3.5.6 - Call transaction API on failure: yes - Payment data available: @@ -162,6 +183,19 @@ git apply pre-auth-authorizenet.patch - Expiry date: yes - Cardholder name: yes +### Cybersource (Checkout API) +#### Link to the extension https://commercemarketplace.adobe.com/cybersource-global-payment-management.html +#### Tested on 3.5.6 + +- Call transaction API on failure: yes +- Payment data available: + - Bin: no + - Last4: no + - Expiry date: no + - Cardholder name: no + ### Amazon Pay / PayPal Express +#### Magento built in +#### Tested on 101.0.6 -Not compatible with any pre auth flows, not even the basic behavior to block the customer on pre auth decline. Needs custom work on checkout as it has a specific behavior on checkout process. \ No newline at end of file +Not compatible with any pre auth flows, not even the basic behavior to block the customer on pre auth decline. Needs custom work on checkout as it has a specific behavior on checkout process. diff --git a/docs/PAYMENT-DETAILS-GATEWAY.md b/docs/PAYMENT-DETAILS-GATEWAY.md index 94b84a7d..57c2a3d4 100644 --- a/docs/PAYMENT-DETAILS-GATEWAY.md +++ b/docs/PAYMENT-DETAILS-GATEWAY.md @@ -58,7 +58,7 @@ To provide a parameter as a direct value, the properties "type" and "value" must {"params":{"transactionKey":{"type":"direct","value":"XSS983HDN3"}}} ``` -To provide a parameter as a reference to an existing Magento setting, the properties "type" and "path" must me provided. For the "type" property, the string "path" must be set and the "path" property must contain the path for the desired setting. Below example shows how to get the AuthorizeNet transaction key from AuthorizeNet's official extension: this way re-typing the transaction key directly in settings is not necessary. The extension will get it from the provided path. Also, if for some reason the transaction key is changed on AuthorizeNet's extension settings, changing it on the gateway integration settings will not be necessary. +To provide a parameter as a reference to an existing Magento setting, the properties "type" and "path" must me provided. For the "type" property, the string "path" must be defined for non-encrypted fields or "path_secure" for encrypted fields. The "path" property must contain the path for the desired setting. Below example shows how to get the AuthorizeNet transaction key from AuthorizeNet's official extension: this way re-typing the transaction key directly in settings is not necessary. The extension will get it from the provided path. Also, if for some reason the transaction key is changed on AuthorizeNet's extension settings, changing it on the gateway integration settings will not be necessary. ```json {"params":{"transactionKey":{"type":"path","path":"authorize_net/anet_core/trans_key"}}} diff --git a/docs/PAYMENT-DETAILS.md b/docs/PAYMENT-DETAILS.md index a1b1593a..83786e2a 100644 --- a/docs/PAYMENT-DETAILS.md +++ b/docs/PAYMENT-DETAILS.md @@ -127,30 +127,22 @@ class InformationCodeMapper extends Signifyd_InformationCodeMapper At the end of getPaymentData method the parent::getPaymentData($orderPayment) can be called as a fallback if the information is not found or missing. That will trigger Base mapper and it will try to find the information on Magento standard location on database. -## Built in mappers +## Mappers -Here is a list of the payment methods that have a built in helper on the extension and will have payment data collected. If the cardholder name is not found, the billing first and last name will be used. - -### Authorize.Net -- Code: authorizenet_directpost -- Magento built in - -**Available data** -- CVV Status -- AVS Status -- Last4 -- Transaction ID +Here is a list of the payment methods that have a payment data collected. If the cardholder name is not found, the billing first and last name will be used. ### PayPal Express/PayPal Standard +#### Magento built in +#### Tested on 101.0.6 - Code: paypal_express -- Magento built in **Available data** - Transaction ID ### PayPal Payments Pro/PayPal Payflow Pro +#### Magento built in +#### Tested on 101.0.6 - Code: payflowpro -- Magento built in **Available data** - CVV Status @@ -161,8 +153,9 @@ Here is a list of the payment methods that have a built in helper on the extensi - Transaction ID ### PayPal Payflow Link +#### Magento built in +#### Tested on 101.0.6 - Code: payflow_link -- Magento built in **Available data** - CVV Status @@ -173,8 +166,9 @@ Here is a list of the payment methods that have a built in helper on the extensi - Transaction ID ### PayPal Payments Advanced +#### Magento built in +#### Tested on 101.0.6 - Code: payflow_advanced -- Magento built in **Available data** - CVV Status @@ -185,8 +179,9 @@ Here is a list of the payment methods that have a built in helper on the extensi - Transaction ID ### Braintree +#### Magento built in +#### Tested on 4.5.0 - Code: braintree -- Magento built in **Available data** - CVV Status @@ -197,6 +192,8 @@ Here is a list of the payment methods that have a built in helper on the extensi - Transaction ID ### Stripe Payments +#### Link to the extension https://commercemarketplace.adobe.com/stripe-stripe-payments.html +#### Tested on 3.5.16 - Code: stripe_payments **Available data** @@ -206,3 +203,56 @@ Here is a list of the payment methods that have a built in helper on the extensi - Expiry Month - Expiry Year - Transaction ID + +### Adyen +#### Link to the extension https://github.com/Adyen/adyen-magento2 +#### Tested on 9.3.0 +- Code: adyen_cc + +**Available data** +- AVS Response Code +- CVV Response Code +- Bin +- Last 4 +- Expiry Month +- Expiry Year +- Transaction ID + +### OpenPay +#### Link to the extension https://github.com/open-pay/openpay-magento2-cards +#### Tested on 2.3.0 +- Code: openpay_cards + +**Available data** +- Bin +- Last 4 +- Expiry Month +- Expiry Year +- Transaction ID + +### Authorize.Net Paradoxlabs +#### Link to the extension https://commercemarketplace.adobe.com/paradoxlabs-authnetcim.html +#### Tested on 5.0.1 +- Code: authnetcim + +**Available data** +- AVS Response Code +- Last4 +- Transaction ID +- Last4 +- Expiry Month +- Expiry Year + +### Authorize.Net Rootways +#### Link to the extension https://www.rootways.com/magento-2-authorize-net-cim-extension +#### Tested on 3.0.1 +- Code: rootways_authorizecim_option + +**Available data** +- CVV Status +- Last4 +- Transaction ID +- Last4 +- Bin +- Expiry Month +- Expiry Year \ No newline at end of file diff --git a/docs/PAYMENT-MAPPING.md b/docs/PAYMENT-MAPPING.md index 70ba0278..26fa67fc 100644 --- a/docs/PAYMENT-MAPPING.md +++ b/docs/PAYMENT-MAPPING.md @@ -15,7 +15,7 @@ Payment method code is defined by payment extension developer and usually can be Add the desired payment method Signifyd and Magento codes to the JSON string on command below and run it on your databse: ```sql -INSERT INTO core_config_data (path, value) VALUES ('signifyd/general/payment_methods_config', '{"CREDIT_CARD":["payflow_link", "payflow_advanced", "authorizenet_acceptjs", "adyen_cc", "braintree", "cybersource", "stripe_payments", "anet_creditcard", "authorizenet_directpost", "openpay_cards", "holacash", "stripe_payments", "mercadopago_custom", "chcybersource"],"CHECK":["checkmo"], "SIGNIFYD-PAYMENT-CODE": ["magento-payment-code"]}'); +INSERT INTO core_config_data (path, value) VALUES ('signifyd/general/payment_methods_config', '{"CREDIT_CARD":["payflow_link", "payflow_advanced", "authorizenet_acceptjs", "adyen_cc", "adyen_oneclick", "adyen_hpp", "braintree", "cybersource", "anet_creditcard", "authorizenet_directpost", "openpay_cards", "holacash", "stripe_payments", "mercadopago_custom", "chcybersource", "payment_services_paypal_hosted_fields", "payment_services_paypal_vault", "authnetcim"],"CHECK":["checkmo"],"PAYPAL_ACCOUNT":["payment_services_paypal_smart_buttons"],"APPLE_PAY":["payment_services_paypal_apple_pay"]}'); ``` A list of the possible values for SIGNIFYD-PAYMENT-CODE can be founded on Signifyd API docs, look for transactions.paymentMethod field. diff --git a/docs/REROUTE.md b/docs/REROUTE.md new file mode 100644 index 00000000..b2af869a --- /dev/null +++ b/docs/REROUTE.md @@ -0,0 +1,10 @@ +[Signifyd Extension for Magento 2](../README.md) > Reroute + +# Reroute + +This endpoint should be called anytime Delivery Address on an Order needs to be changed. +Orders can be updated a maximum of 100 times for a new decision. + +The reroute will be automatically created in Magento whenever an order's shipping address changes. +The first attempt is made when saving the address, however, if an error occurs, the reroute will be done via cron. +Orders that do not exist on Signifyd or that already have a shipment created will not be sent. \ No newline at end of file diff --git a/docs/RESTRICT-CUSTOMER-GROUPS.md b/docs/RESTRICT-CUSTOMER-GROUPS.md new file mode 100644 index 00000000..418822d2 --- /dev/null +++ b/docs/RESTRICT-CUSTOMER-GROUPS.md @@ -0,0 +1,40 @@ +[Signifyd Extension for Magento 2](../README.md) > Restrict orders by customer groups + +# Restrict orders by customer groups + +**_Warning: These steps should only be performed under the instruction and supervision of Signifyd. If these steps are not completed correctly you may experience issues with the Signifyd extension and or your Magento store. It is recommended to test this on a development environment first._** + +## Things to know before getting started + +Orders placed by a group of customers can be excluded from being sent to Signifyd. These orders will not be created in Signifyd and the extension will not interfere with the order workflow i.e. place the order on hold or capture the payment. + +If you want to exclude customer groups you will need to provide a list of customer groups id in a comma separated list `2,5,7`. You will also need to clear the configuration or full cache for the change to take effect. + +### Add custom customer groups + +Insert the list of customer groups id you want to restrict and then run the command below on your database: + +``` +`INSERT INTO core_config_data (path, value) VALUES ('signifyd/general/restrict_customer_groups', 'INSERT-LIST-OF-CUSTOMER-GROUPS-ID-HERE');` +``` +### Update custom customer groups + +To modify an existing restricted list, insert the list of new customer groups id you want to restrict and then run the following command on your database: + +``` +UPDATE core_config_data SET value='INSERT-LIST-OF-CUSTOMER-GROUPS-ID-HERE' WHERE path='signifyd/general/restrict_customer_groups'; +``` +### Delete custom customer groups + +To remove all customer group restriction, just delete it from the database: + +``` +DELETE FROM core_config_data WHERE path='signifyd/general/restrict_customer_groups'; +``` + +### Check current restriction settings + +To check the current restricted customer group id, run the command below on your database: + +``` +SELECT * FROM core_config_data WHERE path = 'signifyd/general/restrict_customer_groups'; diff --git a/docs/RESTRICT-PAYMENTS.md b/docs/RESTRICT-PAYMENTS.md index 77824678..322638d4 100644 --- a/docs/RESTRICT-PAYMENTS.md +++ b/docs/RESTRICT-PAYMENTS.md @@ -12,14 +12,14 @@ By default the extension will automatically exclude orders with the following pa ### Add custom payment methods -Insert the list of payment codes you want to restict and then run the command below on your database: +Insert the list of payment codes you want to restrict and then run the command below on your database: ``` INSERT INTO core_config_data (path, value) VALUES ('signifyd/general/restrict_payment_methods', 'INSERT-LIST-OF-PAYMENT-METHODS-HERE'); ``` ### Update custom payment methods -To modify an existing restricted list, insert the list of new payment codes you want to restict and then run the following command on your database: +To modify an existing restricted list, insert the list of new payment codes you want to restrict and then run the following command on your database: ``` UPDATE core_config_data SET value='INSERT-LIST-OF-PAYMENT-METHODS-HERE' WHERE path='signifyd/general/restrict_payment_methods'; diff --git a/docs/RETURN-REQUEST.md b/docs/RETURN-REQUEST.md new file mode 100644 index 00000000..1622b3c6 --- /dev/null +++ b/docs/RETURN-REQUEST.md @@ -0,0 +1,5 @@ +[Signifyd Extension for Magento 2](../README.md) > Return request + +# Return request + +The return will be automatically created by Magento whenever an order is canceled or refunded in full. It is also necessary that the order is recommended by Signifyd as approved, orders without a recommendation or that are classified as rejected will not be sent. diff --git a/docs/TRANSACTIONS-INTEGRATION.md b/docs/TRANSACTIONS-INTEGRATION.md index 4510d939..31c357af 100644 --- a/docs/TRANSACTIONS-INTEGRATION.md +++ b/docs/TRANSACTIONS-INTEGRATION.md @@ -11,13 +11,13 @@ For each payment method that want to integrate with the transaction endpoint, it It is necessary to add the payment method to the mapped list in the etc/config.xml file: ```xml -<payment_methods_config>{"CREDIT_CARD":["payflow_link", "payflow_advanced", "authorizenet_acceptjs", "adyen_cc", "adyen_oneclick", "adyen_hpp", "braintree", "cybersource", "stripe_payments", "anet_creditcard", "authorizenet_directpost", "openpay_cards", "holacash", "stripe_payments"],"CHECK":["checkmo"]}</payment_methods_config> +<payment_methods_config>{"CREDIT_CARD":["payflow_link", "payflow_advanced", "authorizenet_acceptjs", "adyen_cc", "adyen_oneclick", "adyen_hpp", "braintree", "cybersource", "anet_creditcard", "authorizenet_directpost", "openpay_cards", "holacash", "stripe_payments", "mercadopago_custom", "chcybersource", "payment_services_paypal_hosted_fields", "payment_services_paypal_vault"],"CHECK":["checkmo"],"PAYPAL_ACCOUNT":["payment_services_paypal_smart_buttons"],"APPLE_PAY":["payment_services_paypal_apple_pay"]}</payment_methods_config> ``` Likewise, it is necessary to update the payment method mapping doc on docs/PAYMENT-MAPPING.md file: ```sql -INSERT INTO core_config_data (path, value) VALUES ('signifyd/general/payment_methods_config', '{"CREDIT_CARD":["payflow_link", "payflow_advanced", "authorizenet_acceptjs", "adyen_cc", "braintree", "cybersource", "stripe_payments", "anet_creditcard", "authorizenet_directpost", "openpay_cards", "holacash"],"CHECK":["checkmo"], "SIGNIFYD-PAYMENT-CODE": ["magento-payment-code"]}'); +INSERT INTO core_config_data (path, value) VALUES ('signifyd/general/payment_methods_config', '{"CREDIT_CARD":["payflow_link", "payflow_advanced", "authorizenet_acceptjs", "adyen_cc", "adyen_oneclick", "adyen_hpp", "braintree", "cybersource", "anet_creditcard", "authorizenet_directpost", "openpay_cards", "holacash", "stripe_payments", "mercadopago_custom", "chcybersource", "payment_services_paypal_hosted_fields", "payment_services_paypal_vault"],"CHECK":["checkmo"],"PAYPAL_ACCOUNT":["payment_services_paypal_smart_buttons"],"APPLE_PAY":["payment_services_paypal_apple_pay"]}'); ``` ### Implementation of card data diff --git a/etc/adminhtml/system/signifyd/general.xml b/etc/adminhtml/system/signifyd/general.xml index d287520e..fdfc6728 100644 --- a/etc/adminhtml/system/signifyd/general.xml +++ b/etc/adminhtml/system/signifyd/general.xml @@ -16,5 +16,8 @@ <label>Signifyd Policy</label> <source_model>Signifyd\Connect\Model\System\Config\Source\Options\PolicyName</source_model> </field> + <!-- MFTF Magento CLI command --> + <field id="restrict_payment_methods" type="text" sortOrder="70" showInWebsite="0" showInStore="0" showInDefault="0" translate="label"> + </field> </group> </include> diff --git a/etc/config.xml b/etc/config.xml index 88ff7dec..2736bae2 100644 --- a/etc/config.xml +++ b/etc/config.xml @@ -14,10 +14,10 @@ <restrict_states_default>pending_payment,payment_review,canceled,closed,complete</restrict_states_default> <restrict_states_create>holded,pending_payment,payment_review,canceled,closed,complete</restrict_states_create> <restrict_payment_methods>checkmo,cashondelivery,banktransfer,purchaseorder,free</restrict_payment_methods> - <payment_methods_config>{"CREDIT_CARD":["payflow_link", "payflow_advanced", "authorizenet_acceptjs", "adyen_cc", "adyen_oneclick", "adyen_hpp", "braintree", "cybersource", "anet_creditcard", "authorizenet_directpost", "openpay_cards", "holacash", "stripe_payments", "mercadopago_custom", "chcybersource"],"CHECK":["checkmo"]}</payment_methods_config> + <payment_methods_config>{"CREDIT_CARD":["payflow_link", "payflow_advanced", "authorizenet_acceptjs", "adyen_cc", "adyen_pay_by_link", "adyen_oneclick", "adyen_hpp", "braintree", "cybersource", "anet_creditcard", "authorizenet_directpost", "openpay_cards", "holacash", "stripe_payments", "mercadopago_custom", "chcybersource", "payment_services_paypal_hosted_fields", "payment_services_paypal_vault", "rootways_authorizecim_option", "authnetcim"],"CHECK":["checkmo"],"PAYPAL_ACCOUNT":["payment_services_paypal_smart_buttons"],"APPLE_PAY":["payment_services_paypal_apple_pay"],"GOOGLE_PAY":["payment_services_paypal_google_pay"]}</payment_methods_config> <shipper_config>{"FEDEX":["fedex"],"DHL":["dhl"],"SHIPWIRE":[],"USPS":["usps"],"UPS":["ups"]}</shipper_config> <shipping_method_config>{"EXPRESS":["FEDEX_EXPRESS_SAVER", "7", "B", "C", "D", "U", "K", "L", "I", "N", "T", "X", "INT_4", "INT_5", "INT_6", "INT_7", "54", "07"],"ELECTRONIC":[],"FIRST_CLASS":["0_FCLE", "0_FCL", "0_FCP", "0_FCPC", "15", "53", "61", "INT_13", "INT_14", "INT_15", "INT_21"],"FIRST_CLASS_INTERNATIONAL":[],"FREE":["freeshipping"],"FREIGHT":["FEDEX_1_DAY_FREIGHT", "FEDEX_2_DAY_FREIGHT", "FEDEX_3_DAY_FREIGHT", "INTERNATIONAL_ECONOMY_FREIGHT", "INTERNATIONAL_PRIORITY_FREIGHT", "FEDEX_FREIGHT", "FEDEX_NATIONAL_FREIGHT"],"GROUND":["FEDEX_GROUND", "GROUND_HOME_DELIVERY", "INTERNATIONAL_GROUND", "4", "03"],"INTERNATIONAL":["INTERNATIONAL_ECONOMY", "INTERNATIONAL_FIRST"],"OVERNIGHT":["FIRST_OVERNIGHT", "PRIORITY_OVERNIGHT", "STANDARD_OVERNIGHT"],"PRIORITY":["1", "2", "3", "13", "16", "17", "22", "23", "25", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "57", "58", "59", "62", "63", "64", "INT_1", "INT_2", "INT_8", "INT_9", "INT_10", "INT_11", "INT_16", "INT_17", "INT_18", "INT_19", "INT_20", "INT_22", "INT_23", "INT_24", "INT_25", "INT_27"],"PRIORITY_INTERNATIONAL":["EUROPE_FIRST_INTERNATIONAL_PRIORITY", "INTERNATIONAL_PRIORITY"],"PICKUP":["pickup"],"STANDARD":["11"],"STORE_TO_STORE":[],"TWO_DAY":["FEDEX_2_DAY", "FEDEX_2_DAY_AM", "59", "02"]}</shipping_method_config> - <async_payment_methods>cybersource,mercadopago_basic,stripe_payments</async_payment_methods> + <async_payment_methods>cybersource,mercadopago_basic,stripe_payments,adyen_pay_by_link</async_payment_methods> <lock_timeout>20</lock_timeout> <enable_transaction>0</enable_transaction> <decision_request>FRAUD</decision_request> @@ -28,6 +28,8 @@ <guarantee_positive_action>nothing</guarantee_positive_action> <policy_pre_auth_reject_message>Your order cannot be processed, please contact our support team</policy_pre_auth_reject_message> <cron_batch_size>20</cron_batch_size> + <bypass_additional_updates>0</bypass_additional_updates> + <logs_retention_period>60</logs_retention_period> </advanced> <logs> <log>1</log> @@ -50,9 +52,21 @@ </adyen_cc> <adyen_hpp> - <signifyd_payment_method_adapter>Signifyd\Connect\Model\Api\CaseData\Transactions\PaymentMethod\AdyenHpp</signifyd_payment_method_adapter> + <signifyd_payment_method_adapter>Signifyd\Connect\Model\Payment\AdyenHpp\PaymentMethodMapper</signifyd_payment_method_adapter> </adyen_hpp> + <adyen_pay_by_link> + <signifyd_async_checker>Signifyd\Connect\Model\Payment\AdyenPayByLink\AsyncChecker</signifyd_async_checker> + <signifyd_avs_ems_adapter>Signifyd\Connect\Model\Payment\AdyenCc\AvsEmsCodeMapper</signifyd_avs_ems_adapter> + <signifyd_bin_adapter>Signifyd\Connect\Model\Payment\AdyenCc\BinMapper</signifyd_bin_adapter> + <signifyd_cvv_ems_adapter>Signifyd\Connect\Model\Payment\AdyenCc\CvvEmsCodeMapper</signifyd_cvv_ems_adapter> + <signifyd_exp_month_adapter>Signifyd\Connect\Model\Payment\AdyenCc\ExpMonthMapper</signifyd_exp_month_adapter> + <signifyd_exp_year_adapter>Signifyd\Connect\Model\Payment\AdyenCc\ExpYearMapper</signifyd_exp_year_adapter> + <signifyd_last4_adapter>Signifyd\Connect\Model\Payment\AdyenCc\Last4Mapper</signifyd_last4_adapter> + <signifyd_transaction_id_adapter>Signifyd\Connect\Model\Payment\AdyenCc\TransactionIdMapper</signifyd_transaction_id_adapter> + <signifyd_payment_method_adapter>Signifyd\Connect\Model\Payment\AdyenPayByLink\PaymentMethodMapper</signifyd_payment_method_adapter> + </adyen_pay_by_link> + <authorizenet_directpost> <signifyd_cvv_ems_adapter>Signifyd\Connect\Model\Payment\Authorizenet\CvvEmsCodeMapper</signifyd_cvv_ems_adapter> <signifyd_last4_adapter>Signifyd\Connect\Model\Payment\Authorizenet\Last4Mapper</signifyd_last4_adapter> @@ -61,6 +75,11 @@ <signifyd_transaction_id_adapter>Signifyd\Connect\Model\Payment\Authorizenet\TransactionIdMapper</signifyd_transaction_id_adapter> </authorizenet_directpost> + <rootways_authorizecim_option> + <signifyd_avs_ems_adapter>Signifyd\Connect\Model\Payment\RootwaysAuthorizecimOption\AvsEmsCodeMapper</signifyd_avs_ems_adapter> + <signifyd_bin_adapter>Signifyd\Connect\Model\Payment\RootwaysAuthorizecimOption\BinMapper</signifyd_bin_adapter> + </rootways_authorizecim_option> + <braintree> <signifyd_avs_ems_adapter>Signifyd\Connect\Model\Payment\Braintree\AvsEmsCodeMapper</signifyd_avs_ems_adapter> <signifyd_cvv_ems_adapter>Signifyd\Connect\Model\Payment\Braintree\CvvEmsCodeMapper</signifyd_cvv_ems_adapter> @@ -79,6 +98,11 @@ <chcybersource> <signifyd_avs_ems_adapter>Signifyd\Connect\Model\Payment\Cybersource\AvsEmsCodeMapper</signifyd_avs_ems_adapter> <signifyd_bin_adapter>Signifyd\Connect\Model\Payment\Cybersource\BinMapper</signifyd_bin_adapter> + <signifyd_cvv_ems_adapter>Signifyd\Connect\Model\Payment\Cybersource\CvvEmsCodeMapper</signifyd_cvv_ems_adapter> + <signifyd_exp_month_adapter>Signifyd\Connect\Model\Payment\Cybersource\ExpMonthMapper</signifyd_exp_month_adapter> + <signifyd_exp_year_adapter>Signifyd\Connect\Model\Payment\Cybersource\ExpYearMapper</signifyd_exp_year_adapter> + <signifyd_last4_adapter>Signifyd\Connect\Model\Payment\Cybersource\Last4Mapper</signifyd_last4_adapter> + <signifyd_transaction_id_adapter>Signifyd\Connect\Model\Payment\Cybersource\TransactionIdMapper</signifyd_transaction_id_adapter> </chcybersource> <payflowpro> @@ -108,7 +132,20 @@ <signifyd_last4_adapter>Signifyd\Connect\Model\Payment\Stripe\Payments\Last4Mapper</signifyd_last4_adapter> <signifyd_exp_month_adapter>Signifyd\Connect\Model\Payment\Stripe\Payments\ExpMonthMapper</signifyd_exp_month_adapter> <signifyd_exp_year_adapter>Signifyd\Connect\Model\Payment\Stripe\Payments\ExpYearMapper</signifyd_exp_year_adapter> + <signifyd_async_checker>Signifyd\Connect\Model\Payment\Stripe\Payments\AsyncChecker</signifyd_async_checker> </stripe_payments> + + <payment_services_paypal_hosted_fields> + <signifyd_avs_ems_adapter>Signifyd\Connect\Model\Payment\PaymentServicesPaypal\AvsEmsCodeMapper</signifyd_avs_ems_adapter> + <signifyd_cvv_ems_adapter>Signifyd\Connect\Model\Payment\PaymentServicesPaypal\CvvEmsCodeMapper</signifyd_cvv_ems_adapter> + <signifyd_transaction_id_adapter>Signifyd\Connect\Model\Payment\PaymentServicesPaypal\TransactionIdMapper</signifyd_transaction_id_adapter> + </payment_services_paypal_hosted_fields> + + <payment_services_paypal_smart_buttons> + <signifyd_avs_ems_adapter>Signifyd\Connect\Model\Payment\PaymentServicesPaypal\AvsEmsCodeMapper</signifyd_avs_ems_adapter> + <signifyd_cvv_ems_adapter>Signifyd\Connect\Model\Payment\PaymentServicesPaypal\CvvEmsCodeMapper</signifyd_cvv_ems_adapter> + <signifyd_transaction_id_adapter>Signifyd\Connect\Model\Payment\PaymentServicesPaypal\TransactionIdMapper</signifyd_transaction_id_adapter> + </payment_services_paypal_smart_buttons> </payment> </signifyd> </default> diff --git a/etc/crontab.xml b/etc/crontab.xml index 8b20f6fd..fac1d035 100644 --- a/etc/crontab.xml +++ b/etc/crontab.xml @@ -4,9 +4,15 @@ <job name="cron_retry" instance="Signifyd\Connect\Cron\RetryCaseJob" method="execute"> <schedule>*/1 * * * *</schedule> </job> + <job name="delete_logs" instance="Signifyd\Connect\Cron\DeleteLogs" method="execute"> + <schedule>0 2 * * *</schedule> + </job> <job name="cron_retry_fulfillment" instance="Signifyd\Connect\Cron\RetryFulfillmentJob" method="execute"> <schedule>*/5 * * * *</schedule> </job> + <job name="cron_retry_reroute" instance="Signifyd\Connect\Cron\RetryReroute" method="execute"> + <schedule>*/5 * * * *</schedule> + </job> <job name="cron_validate_order_id" instance="Signifyd\Connect\Cron\ValidateOrderId" method="execute"> <schedule>0 3 * * *</schedule> </job> diff --git a/etc/db_schema.xml b/etc/db_schema.xml index de981442..cb0784a7 100644 --- a/etc/db_schema.xml +++ b/etc/db_schema.xml @@ -53,4 +53,27 @@ <column identity="false" name="retries" padding="11" nullable="false" default="0" xsi:type="int"/> <column name="inserted_at" nullable="true" default="CURRENT_TIMESTAMP" xsi:type="datetime"/> </table> + <table comment="signifyd_connect_reroute Table" engine="innodb" name="signifyd_connect_reroute" resource="default"> + <column xsi:type="int" name="reroute_id" padding="10" unsigned="true" nullable="false" identity="true" comment="Entity Id"/> + <constraint referenceId="PRIMARY" xsi:type="primary"> + <column name="reroute_id"/> + </constraint> + <column name="order_id" nullable="true" xsi:type="int" comment="order_id" identity="false"/> + <column length="50" name="magento_status" default="waiting_submission" nullable="false" xsi:type="varchar"/> + <column identity="false" name="retries" padding="11" nullable="false" default="0" xsi:type="int"/> + <column name="inserted_at" nullable="true" default="CURRENT_TIMESTAMP" xsi:type="datetime"/> + </table> + <table name="signifyd_connect_logs" resource="default" engine="innodb" comment="signifyd_connect_logs Table"> + <column xsi:type="int" name="logs_id" padding="10" unsigned="true" nullable="false" identity="true" comment="Entity Id"/> + <constraint xsi:type="primary" referenceId="PRIMARY"> + <column name="logs_id"/> + </constraint> + <column name="created_at" nullable="true" default="CURRENT_TIMESTAMP" xsi:type="timestamp" comment="created_at"/> + <column name="quote_id" nullable="true" unsigned="true" xsi:type="int" padding="10" comment="Quote Id"/> + <column name="order_id" nullable="true" unsigned="true" xsi:type="int" padding="10" comment="Order Id"/> + <column name="type" nullable="false" xsi:type="varchar" comment="type" length="255"/> + <column name="entry" nullable="false" xsi:type="text" comment="entry"/> + <constraint xsi:type="foreign" referenceId="QUOTE_ID_QUOTE_ENTITY_ID" table="signifyd_connect_logs" column="quote_id" referenceTable="quote" referenceColumn="entity_id" onDelete="CASCADE"/> + <constraint xsi:type="foreign" referenceId="ORDER_ID_SALES_ORDER_ENTITY_ID" table="signifyd_connect_logs" column="order_id" referenceTable="sales_order" referenceColumn="entity_id" onDelete="CASCADE"/> + </table> </schema> diff --git a/etc/di.xml b/etc/di.xml index c9c2dd8e..cc164e31 100644 --- a/etc/di.xml +++ b/etc/di.xml @@ -72,6 +72,7 @@ <argument name="expYearDefaultAdapter" xsi:type="object">Signifyd\Connect\Model\Payment\Base\ExpYearMapper</argument> <argument name="binDefaultAdapter" xsi:type="object">Signifyd\Connect\Model\Payment\Base\BinMapper</argument> <argument name="transactionIdDefaultAdapter" xsi:type="object">Signifyd\Connect\Model\Payment\Base\TransactionIdMapper</argument> + <argument name="asyncCheckDefaultAdapter" xsi:type="object">Signifyd\Connect\Model\Payment\Base\AsyncChecker</argument> </arguments> </type> @@ -79,7 +80,7 @@ <type name="Signifyd\Connect\Model\MappingVerificationFactory"> <arguments> <argument name="config" xsi:type="object">Magento\Payment\Gateway\Config\Config</argument> - <argument name="paymentMethodDefaultAdapter" xsi:type="object">Signifyd\Connect\Model\Api\CaseData\Transactions\PaymentMethod\Mapper</argument> + <argument name="paymentMethodDefaultAdapter" xsi:type="object">Signifyd\Connect\Model\Payment\Base\PaymentMethodMapper</argument> </arguments> </type> @@ -144,6 +145,10 @@ <plugin name="Signifyd_Connect_Plugin_StripeIntegration_Payments_Helper_Order" type="\Signifyd\Connect\Plugin\StripeIntegration\Payments\Helper\Order" /> </type> + <type name="Adyen\Payment\Helper\Webhook"> + <plugin name="Signifyd_Connect_Plugin_Adyen_Payment_Helper_Webhook" type="\Signifyd\Connect\Plugin\Adyen\Payment\Helper\Webhook" /> + </type> + <type name="Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult"> <plugin name="signifydSalesOrderGrid" type="\Signifyd\Connect\Plugin\OrderGrid\SalesOrderGridPlugin"/> </type> @@ -164,9 +169,29 @@ <plugin name="Signifyd_Connect_Plugin_Logger_Logger" type="\Signifyd\Connect\Plugin\Logger\Logger" /> </type> - <!-- Preferences --> + <type name="CyberSource\SecureAcceptance\Gateway\Helper\SubjectReader"> + <plugin name="Signifyd_Connect_Plugin_CyberSource_Command_HandleResponseCommand" type="\Signifyd\Connect\Plugin\CyberSource\Gateway\Command\HandleResponseCommand" /> + </type> - <preference for="Magento\Reports\Block\Adminhtml\Shopcart\Abandoned\Grid" type="Signifyd\Connect\Block\Adminhtml\Shopcart\Abandoned\Grid" /> + <type name="Magento\PaymentServicesPaypal\Gateway\Http\ServiceClient"> + <plugin name="Signifyd_Connect_Plugin_Magento_PaymentServicesPaypal_Gateway_Http_ServiceClient" type="\Signifyd\Connect\Plugin\Magento\PaymentServicesPaypal\Gateway\Http\ServiceClient" /> + </type> + <type name="Rootways\Authorizecim\Gateway\Validator\ResponseValidator"> + <plugin name="signifyd_response_validator_plugin" type="Signifyd\Connect\Plugin\Rootways\Authorizecim\Gateway\Validator\ResponseValidatorPlugin" sortOrder="10"/> + </type> + + <type name="Magento\Csp\Model\Collector\ControllerCollector"> + <plugin name="Signifyd_Connect_Plugin_Magento_Csp_Model_Collector_ControllerCollector" type="Signifyd\Connect\Plugin\Magento\Csp\Model\Collector\ControllerCollector"/> + </type> + + <!-- Preferences --> + <preference for="Magento\Reports\Block\Adminhtml\Shopcart\Abandoned\Grid" type="Signifyd\Connect\Block\Adminhtml\Shopcart\Abandoned\Grid" /> <preference for="Magento\Sales\Model\Order\Payment" type="Signifyd\Connect\Model\Magento\Sales\Model\Order\Payment" /> + <preference for="Signifyd\Connect\Api\RerouteRepositoryInterface" type="Signifyd\Connect\Model\RerouteRepository"/> + <preference for="Signifyd\Connect\Api\Data\RerouteInterface" type="Signifyd\Connect\Model\Reroute"/> + <preference for="Signifyd\Connect\Api\Data\RerouteSearchResultsInterface" type="Magento\Framework\Api\SearchResults"/> + <preference for="Signifyd\Connect\Api\LogsRepositoryInterface" type="Signifyd\Connect\Model\LogsRepository"/> + <preference for="Signifyd\Connect\Api\Data\LogsInterface" type="Signifyd\Connect\Model\Logs"/> + <preference for="Signifyd\Connect\Api\Data\LogsSearchResultsInterface" type="Magento\Framework\Api\SearchResults"/> </config> diff --git a/etc/frontend/csp_whitelist.xml b/etc/frontend/csp_whitelist.xml index 89f728ab..f9c23ded 100644 --- a/etc/frontend/csp_whitelist.xml +++ b/etc/frontend/csp_whitelist.xml @@ -5,6 +5,7 @@ <values> <value id="signifyd-cdn-scripts" type="host">https://cdn-scripts.signifyd.com</value> <value id="signifyd-imgs" type="host">https://imgs.signifyd.com</value> + <value id="signifyd-metrix" type="host">https://h64.online-metrix.net</value> </values> </policy> <policy id="img-src"> diff --git a/etc/module.xml b/etc/module.xml index 68764e34..56533b33 100644 --- a/etc/module.xml +++ b/etc/module.xml @@ -5,7 +5,7 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> - <module name="Signifyd_Connect" setup_version="5.4.0"> + <module name="Signifyd_Connect" setup_version="5.8.2"> <sequence> <module name="Magento_Sales" /> <module name="Magento_Payment" /> diff --git a/view/adminhtml/layout/sales_order_view.xml b/view/adminhtml/layout/sales_order_view.xml index 962ffec0..fc7c2416 100644 --- a/view/adminhtml/layout/sales_order_view.xml +++ b/view/adminhtml/layout/sales_order_view.xml @@ -1,10 +1,5 @@ <?xml version="1.0"?> -<!-- -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> + <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="admin-2columns-left" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <body> <referenceContainer name="content"> diff --git a/view/adminhtml/requirejs-config.js b/view/adminhtml/requirejs-config.js index 131da3e1..7d603ed6 100644 --- a/view/adminhtml/requirejs-config.js +++ b/view/adminhtml/requirejs-config.js @@ -1,8 +1,3 @@ -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - var config = { map: { '*': { diff --git a/view/adminhtml/templates/case_info.phtml b/view/adminhtml/templates/case_info.phtml index 53407327..31bc94cd 100644 --- a/view/adminhtml/templates/case_info.phtml +++ b/view/adminhtml/templates/case_info.phtml @@ -1,11 +1,3 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -// @codingStandardsIgnoreFile -?> <?php /** @var $block Signifyd\Connect\Block\Adminhtml\CaseInfo */ ?> <?php @@ -23,20 +15,41 @@ if ($block->getCaseEntity()->isEmpty()) { <table class="admin__table-secondary order-case-table"> <tbody> <tr> - <th class="col-guarantee-disposition"><?= $block->escapeHtml(__('Signifyd Decision')) ?></th> - <td class="col-guarantee-disposition"><?= $block->escapeHtml($block->getCaseGuaranteeDisposition()) ?></td> + <th class="col-guarantee-disposition" id="signifyd-decision"><?= $block->escapeHtml(__('Signifyd Decision')) ?></th> + <td class="col-guarantee-disposition" id="signifyd-decision-value"><?= $block->escapeHtml($block->getCaseGuaranteeDisposition()) ?></td> </tr> <tr> - <th class="col-guarantee-disposition"><?= $block->escapeHtml(__('Score')) ?></th> - <td class="col-guarantee-disposition"><?= $block->escapeHtml($block->getCaseScore()) ?></td> + <th class="col-guarantee-disposition" id="signifyd-score"><?= $block->escapeHtml(__('Score')) ?></th> + <td class="col-guarantee-disposition" id="signifyd-score-value"><?= $block->escapeHtml($block->getCaseScore()) ?></td> </tr> <?php $reason = $block->getCheckpointActionReason(); ?> <?php if (empty($reason) === false): ?> <tr> - <th class="col-guarantee-disposition"><?= $block->escapeHtml(__('Action Reason')) ?></th> - <td class="col-guarantee-disposition"><?= $block->escapeHtml($reason) ?></td> + <th class="col-guarantee-disposition" id="signifyd-reason"><?= $block->escapeHtml(__('Action Reason')) ?></th> + <td class="col-guarantee-disposition" id="signifyd-reason-value"><?= $block->escapeHtml($reason) ?></td> </tr> <?php endif; ?> + <tr> + <th class="col-guarantee-disposition" id="signifyd-logs"><?= $block->escapeHtml(__('Order Logs')) ?></th> + <?php if ($block->hasLogsToDownload()): ?> + <td class="col-lgos" id="signifyd-logs-value"> + <div class="col-lgos"> + <a id="download-log" title="Download Order Logs" type="button" + class="action-primary action-add" data-ui-id="widget-button-17" + href="<?= $block->escapeUrl($block->getUrl( + 'signifyd_admin/casedata/logs', + ['order_id' => $block->getOrder()->getId()] + )) ?>">Download Order Logs</a> + </div> + </td> + <?php else: ?> + <td class="col-logs" id="signifyd-logs-value"> + <div class="col-logs"> + <p>There are no logs to download</p> + </div> + </td> + <?php endif; ?> + </tr> </tbody> </table> </div> diff --git a/view/adminhtml/web/js/sales_order_view.js b/view/adminhtml/web/js/sales_order_view.js index d318bc72..83a11bd1 100644 --- a/view/adminhtml/web/js/sales_order_view.js +++ b/view/adminhtml/web/js/sales_order_view.js @@ -1,8 +1,3 @@ -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - define([ 'jquery', 'Magento_Ui/js/modal/confirm', diff --git a/view/base/requirejs-config.js b/view/base/requirejs-config.js index 2eabcdfc..b298b1e6 100644 --- a/view/base/requirejs-config.js +++ b/view/base/requirejs-config.js @@ -18,6 +18,12 @@ var config = { }, "Holacash_Payment/js/view/payment/method-renderer/holacash_gateway": { 'Signifyd_Connect/js/model/holacash-cc-method-mixin': true, + }, + 'CyberSource_SecureAcceptance/js/view/payment/method-renderer/sa/redirect': { + 'Signifyd_Connect/js/model/cyber-redirect-mixin': true + }, + 'Rootways_Authorizecim/js/view/payment/method-renderer/authorizecim-method': { + 'Signifyd_Connect/js/model/authorizecim-method-mixin': true } } } diff --git a/view/frontend/layout/default.xml b/view/frontend/layout/default.xml index d6ac2f30..6d304077 100644 --- a/view/frontend/layout/default.xml +++ b/view/frontend/layout/default.xml @@ -4,15 +4,6 @@ <referenceContainer name="before.body.end"> <block class="Magento\Framework\View\Element\Template" name="signifyd.connect.fingerprint" template="Signifyd_Connect::fingerprint.phtml"> - <arguments> - <argument name="jsLayout" xsi:type="array"> - <item name="components" xsi:type="array"> - <item name="signifyd-fingerprint" xsi:type="array"> - <item name="component" xsi:type="string">Signifyd_Connect/js/view/signifyd-fingerprint</item> - </item> - </item> - </argument> - </arguments> </block> </referenceContainer> </body> diff --git a/view/frontend/templates/fingerprint.phtml b/view/frontend/templates/fingerprint.phtml index 0cfbdcc7..de27cb00 100644 --- a/view/frontend/templates/fingerprint.phtml +++ b/view/frontend/templates/fingerprint.phtml @@ -1,9 +1,82 @@ -<div data-role="signifyd-fingerprint" data-bind="scope: 'signifyd-fingerprint'"></div> +<?php +$scriptString = <<<script + define( + 'signifyd-fingerprint-module', + [ + 'uiComponent', + 'Magento_Customer/js/customer-data', + 'jquery' + ], function (Component, customerData, $) { + 'use strict'; + + var SignifydFingerprint = function() { -<script type="text/x-magento-init"> -{ - "[data-role=signifyd-fingerprint]": { - "Magento_Ui/js/core/app": <?= /* @escapeNotVerified */ $block->getJsLayout() ?> - } -} -</script> + return { + initialize: function () { + var me = this; + + if (jQuery('.checkout-onepage-success').length > 0) { + customerData.reload(['signifyd-fingerprint']); + } else { + me.data = customerData.get('signifyd-fingerprint'); + me.sent = false; + + me.sent = me.checkSessionId(me.data().dataOrderSessionId); + + if (me.sent === false) { + me.observing = me.data.subscribe(function (newData) { + me.sent = me.checkSessionId(newData.dataOrderSessionId); + }); + } + } + }, + + checkSessionId: function(dataOrderSessionId) { + var me = this; + + if (typeof dataOrderSessionId !== 'undefined' && dataOrderSessionId.length > 0) { + if (typeof $.cookie('signifyd-' + dataOrderSessionId) !== 'undefined') { + console.log('Fingerprint already sent'); + } else { + console.log('Sending fingerprint...'); + $.cookie('signifyd-' + dataOrderSessionId, true); + + me.callScript(dataOrderSessionId); + + if (typeof me.observing != "undefined") { + me.observing.dispose(); + } + + return true; + } + } else { + console.log('Will not send fingerprint'); + console.log(dataOrderSessionId); + + return false; + } + }, + + callScript: function(dataOrderSessionId) { + var signifydScript = document.createElement('script'); + signifydScript.setAttribute('async', true); + signifydScript.setAttribute('type', 'text/javascript'); + signifydScript.setAttribute('id', 'sig-api'); + signifydScript.setAttribute('data-order-session-id', dataOrderSessionId); + signifydScript.setAttribute('src', 'https://cdn-scripts.signifyd.com/api/script-tag.js'); + + $("head").append(signifydScript); + } + } + }; + + jQuery(function() { + SignifydFingerprint().initialize(); + }); + }); + + require(['signifyd-fingerprint-module']); +script; +?> + +<?= /* @noEscape */ $secureRenderer->renderTag('script', [], $scriptString, false); ?> diff --git a/view/frontend/web/js/model/authorizecim-method-mixin.js b/view/frontend/web/js/model/authorizecim-method-mixin.js new file mode 100644 index 00000000..df5a50aa --- /dev/null +++ b/view/frontend/web/js/model/authorizecim-method-mixin.js @@ -0,0 +1,45 @@ +define([ + 'jquery' +], function ($) { + 'use strict'; + + var mixin = { + + getData: function() { + var data = this._super(); + + this.vaultEnabler.visitAdditionalData(data); + + if (this.isAcceptjs() || this.isAcceptUIjs()) { + delete data.additional_data.cc_number; + + $.extend(true, data, { + 'additional_data': { + 'data_value': $('#' + this.getCode() + '_data_value').val(), + 'data_descriptor': $('#' + this.getCode() + '_data_descriptor').val(), + 'captcha_string': this.cToken, + 'card_bin': ($('#'+this.getCode()+'_cc_number').val() || '').substring(0, 6) + } + }); + + if (this.isAcceptUIjs()) { + data['additional_data']['cc_number'] = this.hostedform_cc_number_last4; + data['additional_data']['cc_exp_month'] = this.hostedform_exp_month; + data['additional_data']['cc_exp_year'] = this.hostedform_exp_year; + } + } else { + $.extend(true, data, { + 'additional_data': { + 'captcha_string': this.cToken + } + }); + } + + return data; + } + }; + + return function (target) { + return target.extend(mixin); + }; +}); diff --git a/view/frontend/web/js/model/cyber-redirect-mixin.js b/view/frontend/web/js/model/cyber-redirect-mixin.js new file mode 100644 index 00000000..437f2f8f --- /dev/null +++ b/view/frontend/web/js/model/cyber-redirect-mixin.js @@ -0,0 +1,83 @@ +define( + [ + 'jquery', + 'Magento_Ui/js/modal/modal', + 'mage/url', + 'Magento_Payment/js/view/payment/iframe', + 'Magento_Checkout/js/model/payment/additional-validators', + 'Magento_Checkout/js/action/set-payment-information', + 'Magento_Checkout/js/model/full-screen-loader', + 'Magento_Vault/js/view/payment/vault-enabler'], + function($, modal, urlBuilder, Component, additionalValidators, setPaymentInformationAction, fullScreenLoader, VaultEnabler) { + 'use strict'; + + return function (target) { + return target.extend({ + /** + * List all Adyen billing agreements + * Set up installments + * + * @returns {Array} + */ + placeOrder: function () { + if (!this.validateHandler() || !additionalValidators.validate()) { + return; + } + var isEnabled = window.checkoutConfig.cybersource_recaptcha && window.checkoutConfig.cybersource_recaptcha.enabled.cybersource; + var recaptcha_invisible = window.checkoutConfig.payment.chcybersource.recaptcha_invisible; + if(isEnabled && recaptcha_invisible != "invisible"){ + var options = { + type: 'popup', + responsive: true, + innerScroll: true, + buttons: [{ + text: $.mage.__('OK'), + class: 'mymodal1', + click: function () { + $('body').trigger('processStart'); + var url = urlBuilder.build("checkout"); + window.location = url; + this.closeModal(); + } + }] + }; + + var popup = modal(options, $('#sa-recaptcha')); + var rresponse = jQuery('#g-recaptcha-response').val(); + if(rresponse.length == 0) { + $("#sa-recaptcha").modal("openModal"); + $('.action-close').css('display', 'none'); + this.isPlaceOrderActionAllowed(false); + return false; + } + $('#sa-recaptcha').on('modalclosed', function() { + $('body').trigger('processStart'); + var url = urlBuilder.build("checkout"); + window.location = url; + }); + } + + fullScreenLoader.startLoader(); + + this.isPlaceOrderActionAllowed(false); + + this.getPlaceOrderDeferredObject() + //fail added in case of failure on checkout + .fail( + function (response) { + //stop loader added + fullScreenLoader.stopLoader(); + return response; + } + ).then(this.placeOrderHandler) + .then(this.initTimeoutHandler.bind(this)) + .always( + function () { + this.isPlaceOrderActionAllowed(true); + }.bind(this) + ) + ; + } + }); + }; + }); diff --git a/view/frontend/web/js/view/signifyd-fingerprint.js b/view/frontend/web/js/view/signifyd-fingerprint.js deleted file mode 100644 index cf683c6b..00000000 --- a/view/frontend/web/js/view/signifyd-fingerprint.js +++ /dev/null @@ -1,63 +0,0 @@ -define([ - 'uiComponent', - 'Magento_Customer/js/customer-data', - 'jquery' -], function (Component, customerData, $) { - 'use strict'; - - return Component.extend({ - /** @inheritdoc */ - initialize: function () { - var me = this; - me._super(); - - if (jQuery('.checkout-onepage-success').length > 0) { - customerData.reload(['signifyd-fingerprint']); - - } else { - me.data = customerData.get('signifyd-fingerprint'); - me.sent = false; - - me.sent = me.checkSessionId(me.data().dataOrderSessionId); - - if (me.sent === false) { - me.observing = me.data.subscribe(function (newData) { - me.sent = me.checkSessionId(newData.dataOrderSessionId); - }); - } - } - }, - - checkSessionId: function(dataOrderSessionId) { - var me = this; - - if (typeof dataOrderSessionId !== 'undefined' && dataOrderSessionId.length > 0) { - console.log('Sending fingerprint...'); - - me.callScript(dataOrderSessionId); - - if (typeof me.observing != "undefined") { - me.observing.dispose(); - } - - return true; - } else { - console.log('Will not send fingerprint'); - console.log(dataOrderSessionId); - - return false; - } - }, - - callScript: function(dataOrderSessionId) { - var script = document.createElement('script'); - script.setAttribute('async', true); - script.setAttribute('type', 'text/javascript'); - script.setAttribute('id', 'sig-api'); - script.setAttribute('data-order-session-id', dataOrderSessionId); - script.setAttribute('src', 'https://cdn-scripts.signifyd.com/api/script-tag.js'); - - $("body").append(script); - } - }); -});