diff --git a/Api/RecipientInterface.php b/Api/RecipientInterface.php index 750e13ae..1473f28a 100644 --- a/Api/RecipientInterface.php +++ b/Api/RecipientInterface.php @@ -20,7 +20,7 @@ public function searchRecipient(): string; /** * @param string $id - * @return KycLinkResponseInterface + * @return Pagarme\Pagarme\Api\KycLinkResponseInterface */ public function createKycLink(string $id); } diff --git a/Block/Adminhtml/System/Config/Form/Field/HubIntegration.php b/Block/Adminhtml/System/Config/Form/Field/HubIntegration.php index c7fa226a..e05ce128 100644 --- a/Block/Adminhtml/System/Config/Form/Field/HubIntegration.php +++ b/Block/Adminhtml/System/Config/Form/Field/HubIntegration.php @@ -5,8 +5,8 @@ use Exception; use Magento\Backend\Block\Template\Context; use Magento\Config\Block\System\Config\Form\Field; +use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\Data\Form\Element\AbstractElement; -use Magento\Framework\Phrase; use Pagarme\Core\Hub\Services\HubIntegrationService; use Pagarme\Pagarme\Concrete\Magento2CoreSetup; use Pagarme\Pagarme\Model\Account; @@ -18,12 +18,16 @@ class HubIntegration extends Field */ private $account; + protected $scopeConfig; + public function __construct( Account $account, + ScopeConfigInterface $scopeConfig, Context $context, array $data = [] ) { $this->account = $account; + $this->scopeConfig = $scopeConfig; parent::__construct($context, $data); } @@ -32,31 +36,46 @@ public function __construct( * @return string * @throws Exception */ - protected function _renderValue(AbstractElement $element) + protected function _renderValue(AbstractElement $element): string { Magento2CoreSetup::bootstrap(); - $installId = Magento2CoreSetup::getModuleConfiguration() - ->getHubInstallId(); - - $hubUrl = $this->getHubUrl($installId); - $buttonText = $this->getButtonText($installId); + $installId = Magento2CoreSetup::getModuleConfiguration()->getHubInstallId(); + $installIdValue = !empty($installId) ? $installId->getValue() : ''; + $defaultInstallId = $this->scopeConfig->getValue( + 'pagarme_pagarme/hub/install_id', + ScopeConfigInterface::SCOPE_TYPE_DEFAULT, + 0 + ); + $defaultInstallId = $defaultInstallId ?? ''; - $html = ''; + $html = sprintf( + '', + $installIdValue === $defaultInstallId ? 'default' : 'scope' + ); $html .= $this->_getElementHtml($element); + $hidden = ' hidden'; $html .= sprintf( - '%s', - $hubUrl, - $buttonText + '%s', + $this->getBaseIntegrateUrl(), + $installId ? $hidden : '', + __("Integrate With Pagar.me") + ); + + $html .= sprintf( + '%s', + $this->getHubUrl($installId), + $installId ? '' : $hidden, + __("View Integration") ); if ($this->account->hasMerchantAndAccountIds()) { - $dashUrl = $this->account->getDashUrl(); $html .= sprintf( - '%s', - $dashUrl, + '%s', + $this->account->getDashUrl(), + $installId ? '' : $hidden, __('Access Pagar.me Dash') ); } @@ -66,16 +85,6 @@ protected function _renderValue(AbstractElement $element) return $html; } - /** - * @param $installId - * @return Phrase - */ - private function getButtonText($installId): Phrase - { - return $installId - ? __("View Integration") : __("Integrate With Pagar.me"); - } - /** * @param $installId * @return string @@ -97,12 +106,20 @@ private function getBaseIntegrateUrl(): string $this->getPublicAppKey() ); - $params = sprintf( - '?redirect=%swebsite/%s/&install_token/%s', - $this->getRedirectUrl(), - Magento2CoreSetup::getCurrentStoreId(), - $this->getInstallToken() - ); + if($this->getRequest()->getParam('website') !== null) { + $params = sprintf( + '?redirect=%swebsite/%s/&install_token/%s', + $this->getRedirectUrl(), + Magento2CoreSetup::getCurrentStoreId(), + $this->getInstallToken() + ); + } else { + $params = sprintf( + '?redirect=%s&install_token/%s', + $this->getRedirectUrl(), + $this->getInstallToken() + ); + } return $baseUrl . $params; } diff --git a/Block/Payment/Info/BaseCardInfo.php b/Block/Payment/Info/BaseCardInfo.php index 7c7a72c3..2874e3ef 100644 --- a/Block/Payment/Info/BaseCardInfo.php +++ b/Block/Payment/Info/BaseCardInfo.php @@ -16,11 +16,34 @@ abstract class BaseCardInfo extends Cc /** * @return array + */ + public function getTransactionInfo() + { + $charge = $this->getLastCharge(); + if ($charge->getLastTransaction()->getCardData() == null) { + return []; + } + $lastFourDigitsWithDots = sprintf( + "**** **** **** %s", + $charge->getLastTransaction()->getCardData()->getLastFourDigits()->getValue() + ); + return array_merge( + $charge->getAcquirerTidCapturedAndAuthorize(), + ['tid' => $charge->getLastTransaction()->getAcquirerTid() ?? ""], + ['cardBrand' => $charge->getLastTransaction()->getCardData()->getBrand()->getName() ?? ""], + ['installments' => $this->getInfo()->getAdditionalInformation('cc_installments') ?? ""], + ['lastFour' => $lastFourDigitsWithDots], + ['acquirerMessage' => $charge->getLastTransaction()->getAcquirerMessage() ?? ""] + ); + } + + /** + * @return mixed|array|Charge * @throws InvalidParamException * @throws LocalizedException * @throws Exception */ - public function getTransactionInfo() + private function getLastCharge() { Magento2CoreSetup::bootstrap(); $orderService = new OrderService(); @@ -40,21 +63,9 @@ public function getTransactionInfo() return []; } - $charge = current($orderObject->getCharges()); - $lastFourDigitsWithDots = sprintf( - "**** **** **** %s", - $charge->getLastTransaction()->getCardData()->getLastFourDigits()->getValue() - ); - return array_merge( - $charge->getAcquirerTidCapturedAndAuthorize(), - ['tid' => $charge->getLastTransaction()->getAcquirerTid() ?? ""], - ['cardBrand' => $charge->getLastTransaction()->getCardData()->getBrand()->getName() ?? ""], - ['installments' => $this->getInfo()->getAdditionalInformation('cc_installments') ?? ""], - ['lastFour' => $lastFourDigitsWithDots], - ['acquirerMessage' => $charge->getLastTransaction()->getAcquirerMessage() ?? ""] - ); + return current($orderObject->getCharges()); } - + /** * @param mixed $orderService * @param mixed $pagarmeId diff --git a/Concrete/Magento2CoreSetup.php b/Concrete/Magento2CoreSetup.php index a61ec500..eb729e5d 100644 --- a/Concrete/Magento2CoreSetup.php +++ b/Concrete/Magento2CoreSetup.php @@ -2,37 +2,29 @@ namespace Pagarme\Pagarme\Concrete; -use Magento\Framework\App\Config as Magento2StoreConfig; +use DateTimeZone; +use Exception; use Magento\Config\Model\Config as Magento2ModelConfig; +use Magento\Framework\App\Config as Magento2StoreConfig; use Magento\Framework\App\Config\ScopeConfigInterface; -use Magento\Framework\Stdlib\DateTime\TimezoneInterface; -use Magento\Store\Model\ScopeInterface as ScopeInterface; use Magento\Framework\App\ObjectManager; use Magento\Framework\App\ProductMetadataInterface; use Magento\Framework\Filesystem\DirectoryList; -use Magento\Store\Model\StoreManager as MagentoStoreManager; +use Magento\Framework\Stdlib\DateTime\TimezoneInterface; +use Magento\Store\Model\ScopeInterface; +use Magento\Store\Model\StoreManagerInterface; +use Magento\Store\Model\Website\Interceptor; use Pagarme\Core\Kernel\Abstractions\AbstractModuleCoreSetup; use Pagarme\Core\Kernel\Aggregates\Configuration; use Pagarme\Core\Kernel\Factories\ConfigurationFactory; use Pagarme\Core\Kernel\Services\MoneyService; use Pagarme\Core\Kernel\ValueObjects\CardBrand; use Pagarme\Core\Kernel\ValueObjects\Configuration\CardConfig; -use Pagarme\Pagarme\Gateway\Transaction\Base\Config\Config; -use Pagarme\Pagarme\Gateway\Transaction\CreditCard\Config\ConfigInterface; -use Pagarme\Pagarme\Model\Installments\Config\ConfigInterface as InstallmentConfigInterface; use Pagarme\Pagarme\Helper\ModuleHelper; -use Pagarme\Pagarme\Model\Enum\CreditCardBrandEnum; -use Pagarme\Pagarme\Concrete\Magento2DatabaseDecorator; -use Pagarme\Pagarme\Concrete\Magento2PlatformOrderDecorator; -use Pagarme\Pagarme\Concrete\Magento2PlatformInvoiceDecorator; -use Pagarme\Pagarme\Concrete\Magento2PlatformCreditmemoDecorator; -use Pagarme\Pagarme\Concrete\Magento2DataService; -use Pagarme\Pagarme\Concrete\Magento2PlatformPaymentMethodDecorator; -use Pagarme\Pagarme\Concrete\Magento2PlatformProductDecorator; use Pagarme\Pagarme\Model\ConfigNotification; -use Magento\Store\Model\StoreManagerInterface; -use Magento\Store\Model\Website\Interceptor; +use Pagarme\Pagarme\Model\Enum\CreditCardBrandEnum; use stdClass; +use Throwable; final class Magento2CoreSetup extends AbstractModuleCoreSetup { @@ -74,19 +66,19 @@ protected function setConfig() { self::$config = [ AbstractModuleCoreSetup::CONCRETE_DATABASE_DECORATOR_CLASS => - Magento2DatabaseDecorator::class, + Magento2DatabaseDecorator::class, AbstractModuleCoreSetup::CONCRETE_PLATFORM_ORDER_DECORATOR_CLASS => - Magento2PlatformOrderDecorator::class, + Magento2PlatformOrderDecorator::class, AbstractModuleCoreSetup::CONCRETE_PLATFORM_INVOICE_DECORATOR_CLASS => - Magento2PlatformInvoiceDecorator::class, + Magento2PlatformInvoiceDecorator::class, AbstractModuleCoreSetup::CONCRETE_PLATFORM_CREDITMEMO_DECORATOR_CLASS => - Magento2PlatformCreditmemoDecorator::class, + Magento2PlatformCreditmemoDecorator::class, AbstractModuleCoreSetup::CONCRETE_DATA_SERVICE => - Magento2DataService::class, + Magento2DataService::class, AbstractModuleCoreSetup::CONCRETE_PLATFORM_PAYMENT_METHOD_DECORATOR_CLASS => - Magento2PlatformPaymentMethodDecorator::class, + Magento2PlatformPaymentMethodDecorator::class, AbstractModuleCoreSetup::CONCRETE_PRODUCT_DECORATOR_CLASS => - Magento2PlatformProductDecorator::class + Magento2PlatformProductDecorator::class ]; } @@ -134,7 +126,7 @@ public function loadModuleConfigurationFromPlatform($storeConfig = null) $storeConfig = $objectManager->get(Magento2StoreConfig::class); } - $configData = new \stdClass(); + $configData = new stdClass(); $storeId = self::getCurrentStoreId(); @@ -167,7 +159,7 @@ public function loadModuleConfigurationFromPlatform($storeConfig = null) self::$moduleConfig = $config; self::$instance->setApiBaseUrl(); - } catch (\Throwable $error) { + } catch (Throwable $error) { $configErrorNotify = new ConfigNotification(); $configErrorNotify->addNotify($error); } @@ -212,13 +204,13 @@ static private function fillWithVoucherConfig(&$dataObj, $storeConfig) $section = 'payment/pagarme_voucher/'; - $voucherObject = new \stdClass(); + $voucherObject = new stdClass(); $dataObj->voucherConfig = self::fillDataObj($storeConfig, $options, $voucherObject, $section); $operation = Configuration::CARD_OPERATION_AUTH_ONLY; if ($dataObj->voucherConfig->cardOperation === 'authorize_capture') { - $operation = Configuration::CARD_OPERATION_AUTH_AND_CAPTURE; + $operation = Configuration::CARD_OPERATION_AUTH_AND_CAPTURE; } $dataObj->voucherConfig->cardOperation = $operation; @@ -237,7 +229,7 @@ static private function fillWithDebitConfig(&$dataObj, $storeConfig) $section = 'payment/pagarme_debit/'; - $debitObject = new \stdClass(); + $debitObject = new stdClass(); $dataObj->debitConfig = self::fillDataObj($storeConfig, $options, $debitObject, $section); $dataObj->debitConfig->cardOperation = Configuration::CARD_OPERATION_AUTH_AND_CAPTURE; @@ -279,9 +271,10 @@ static private function fillWithCardConfig(&$dataObj, $storeConfig) } private static function fillWithPixConfig( - stdClass $configData, + stdClass $configData, ScopeConfigInterface $storeConfig - ) { + ) + { $options = [ 'enabled' => 'active', 'expirationQrCode' => 'expiration_qrcode', @@ -291,15 +284,16 @@ private static function fillWithPixConfig( $section = 'payment/pagarme_pix/'; - $pixObject = new \stdClass(); + $pixObject = new stdClass(); $configData->pixConfig = self::fillDataObj($storeConfig, $options, $pixObject, $section); } - + private static function fillWithGooglePayConfig( - stdClass $configData, + stdClass $configData, ScopeConfigInterface $storeConfig - ) { + ) + { $options = [ 'enabled' => 'active', 'title' => 'title', @@ -309,7 +303,7 @@ private static function fillWithGooglePayConfig( $section = 'payment/pagarme_googlepay/'; - $googlePayObject = new \stdClass(); + $googlePayObject = new stdClass(); $configData->googlePayConfig = self::fillDataObj($storeConfig, $options, $googlePayObject, $section); } @@ -380,7 +374,7 @@ static private function fillWithPagarmeKeys(&$dataObj, $storeConfig) $section = 'pagarme_pagarme/global/'; - $keys = new \stdClass; + $keys = new stdClass; $dataObj->keys = self::fillDataObj( @@ -415,7 +409,7 @@ static private function fillWithAddressConfig(&$dataObj, $storeConfig) ]; $section = 'payment/pagarme_customer_address/'; - $addressAttributes = new \stdClass(); + $addressAttributes = new stdClass(); $dataObj->addressAttributes = self::fillDataObj( $storeConfig, @@ -455,7 +449,7 @@ static private function getBrandConfig($storeConfig, $section) $scope = ScopeInterface::SCOPE_WEBSITES; $storeId = self::getCurrentStoreId(); - $selectedBrands = $storeConfig->getValue($section . 'cctypes', $scope, $storeId) ?? ''; + $selectedBrands = $storeConfig->getValue($section . 'cctypes', $scope, $storeId) ?? ''; $brands = array_merge([''], explode( ',', $selectedBrands @@ -482,12 +476,12 @@ static private function getBrandConfig($storeConfig, $section) $max = $storeConfig->getValue($section . 'installments_number' . $brand, $scope, $storeId); } - $minValue = $storeConfig->getValue($section . 'installment_min_amount' . $brand, $scope, $storeId); - $initial = $storeConfig->getValue($section . 'installments_interest_rate_initial' . $brand, $scope, $storeId); - $incremental = $storeConfig->getValue($section . 'installments_interest_rate_incremental' . $brand, $scope, $storeId); - $maxWithout = $storeConfig->getValue($section . 'installments_max_without_interest' . $brand, $scope, $storeId); + $minValue = $storeConfig->getValue($section . 'installment_min_amount' . $brand, $scope, $storeId); + $initial = $storeConfig->getValue($section . 'installments_interest_rate_initial' . $brand, $scope, $storeId); + $incremental = $storeConfig->getValue($section . 'installments_interest_rate_incremental' . $brand, $scope, $storeId); + $maxWithout = $storeConfig->getValue($section . 'installments_max_without_interest' . $brand, $scope, $storeId); - $interestByBrand = $storeConfig->getValue($section . 'installments_interest_by_issuer' . $brand, $scope, $storeId); + $interestByBrand = $storeConfig->getValue($section . 'installments_interest_by_issuer' . $brand, $scope, $storeId); if (empty($interestByBrand)) { $initial = 0; $incremental = 0; @@ -541,46 +535,41 @@ public static function getDefaultStoreViewCode() public static function getCurrentStoreId() { $objectManager = ObjectManager::getInstance(); - $config = $objectManager->get(Magento2ModelConfig::class); - $storeInterfaceName = '\Magento\Store\Model\StoreManagerInterface'; - $storeManager = $objectManager->get($storeInterfaceName); + $requestClass = '\Magento\Framework\App\RequestInterface'; + $request = $objectManager->get($requestClass); - $store = $storeManager->getWebsite()->getId(); + if ($request->getControllerName() !== 'system_config') { + $storeInterfaceName = '\Magento\Store\Model\StoreManagerInterface'; + $storeManager = $objectManager->get($storeInterfaceName); - if ($config->getScope() == 'websites') { - $store = $config->getScopeId(); + return $storeManager->getStore()->getWebsite()->getId(); } - if ($config->getScope() == 'stores') { - $store = $storeManager - ->getStore($config->getScopeId()) - ->getWebsite() - ->getId(); + if ($request->getParam(ScopeInterface::SCOPE_WEBSITE)) { + return $request->getParam(ScopeInterface::SCOPE_WEBSITE); } - if ($config->getScope() == 'default') { - $store = $storeManager->getDefaultStoreView()->getStoreId(); + if ($request->getParam(ScopeInterface::SCOPE_STORE)) { + return $request->getParam(ScopeInterface::SCOPE_STORE); } - return $store; + return 0; } + /** + * @return int + */ public static function getDefaultStoreId() { - $objectManager = ObjectManager::getInstance(); - $storeInterfaceName = '\Magento\Store\Model\StoreManagerInterface'; - $storeManager = $objectManager->get($storeInterfaceName); - - $defaultStoreView = $storeManager->getDefaultStoreView(); - - return $defaultStoreView->getStoreId(); + return 0; } /** + * @return DateTimeZone + * @throws Exception * @since 1.7.1 * - * @return \DateTimeZone */ protected function getPlatformStoreTimezone() { @@ -592,9 +581,8 @@ protected function getPlatformStoreTimezone() $timezoneString = $timezone->getConfigTimezone( ScopeInterface::SCOPE_STORE ); - $dateTimeZone = new \DateTimeZone($timezoneString); - return $dateTimeZone; + return new DateTimeZone($timezoneString); } static private function fillWithRecurrenceConfig(&$dataObj, $storeConfig) @@ -622,7 +610,7 @@ static private function fillWithRecurrenceConfig(&$dataObj, $storeConfig) $section = 'pagarme_pagarme/recurrence/'; - $recurrenceConfig = new \stdClass(); + $recurrenceConfig = new stdClass(); $dataObj->recurrenceConfig = self::fillDataObj( $storeConfig, $options, @@ -632,9 +620,10 @@ static private function fillWithRecurrenceConfig(&$dataObj, $storeConfig) } static private function fillWithMarketplaceConfig( - stdClass $configData, + stdClass $configData, ScopeConfigInterface $storeConfig - ) { + ) + { $options = [ 'enabled' => 'active', 'responsibilityForProcessingFees' @@ -651,8 +640,15 @@ static private function fillWithMarketplaceConfig( $section = 'pagarme_pagarme/marketplace/'; - $marketplaceObject = new \stdClass(); + $marketplaceObject = new stdClass(); $configData->marketplaceConfig = self::fillDataObj($storeConfig, $options, $marketplaceObject, $section); } + + /** + * @return null + */ + public static function getInstallmentType() { + return null; + } } diff --git a/Controller/Adminhtml/Hub/Index.php b/Controller/Adminhtml/Hub/Index.php index 4161cf3c..82c713c2 100644 --- a/Controller/Adminhtml/Hub/Index.php +++ b/Controller/Adminhtml/Hub/Index.php @@ -2,17 +2,23 @@ namespace Pagarme\Pagarme\Controller\Adminhtml\Hub; +use Magento\Backend\App\Action; use Magento\Backend\App\Action\Context; use Magento\Framework\App\Cache\Manager; +use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\App\Config\Storage\WriterInterface; use Magento\Framework\App\RequestInterface; +use Magento\Framework\Controller\ResultInterface; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\View\Result\PageFactory; use Magento\Framework\Webapi\Exception as MagentoException; +use Magento\Store\Model\ScopeInterface; use Magento\Store\Model\StoreManagerInterface; use Pagarme\Core\Hub\Services\HubIntegrationService; use Pagarme\Pagarme\Concrete\Magento2CoreSetup; -class Index extends \Magento\Backend\App\Action +class Index extends Action { protected $resultPageFactory; protected $configWriter; @@ -50,18 +56,16 @@ public function __construct( /** * Index action * - * @return \Magento\Framework\Controller\ResultInterface + * @return ResultInterface + * @throws MagentoException|LocalizedException + * @throws \Exception */ public function execute() { $params = $this->requestObject->getParams(); - $websiteId = isset($params['website']) - ? $params['website'] - : $this->storeManager->getDefaultStoreView()->getWebsiteId(); - - $storeId = $this->storeManager->getWebsite($websiteId) - ->getDefaultStore()->getId(); - $this->storeManager->setCurrentStore($storeId); + $scopeUrl = $this->getScopeUrl(); + $websiteId = $params['website'] ?? 0; + $this->storeManager->setCurrentStore($websiteId); Magento2CoreSetup::bootstrap(); @@ -85,161 +89,145 @@ public function execute() } $url = $this->getUrl('adminhtml/system_config/edit/section/payment'); - header('Location: ' . explode('?', $url ?? '')[0] . 'website/' . $websiteId); + $header = 'Location: ' . explode('?', $url ?? '')[0]; + if (!empty($websiteId) && !empty($scopeUrl)) { + $header .= $scopeUrl . '/' . $websiteId; + } + header($header); exit; } - private function getCallbackUrl($websiteId) - { - $baseUrl = $this->storeManager->getStore()->getBaseUrl(); - return $baseUrl . "rest/V1/pagarme/hub/command?websiteId=" . $websiteId; - } - - private function getWebHookkUrl() + /** + * @return string + */ + public function getScopeName(): string { - $baseUrl = $this->storeManager->getStore()->getBaseUrl(); - return $baseUrl . "rest/V1/pagarme/webhook"; - } + $request = $this->requestObject; - private function allWebsitesIntegrated($currentWebsiteId) - { - $websites = $this->storeManager->getWebsites(); - $magento2CoreSetup = new Magento2CoreSetup(); + if ($request->getParam(ScopeInterface::SCOPE_WEBSITE)) { + return ScopeInterface::SCOPE_WEBSITES; + } - foreach ($websites as $websiteId => $website) { - $storeId = $this->storeManager->getWebsite($websiteId) - ->getDefaultStore()->getId(); + if ($request->getParam(ScopeInterface::SCOPE_STORE)) { + return ScopeInterface::SCOPE_STORES; + } - $this->storeManager->setCurrentStore($storeId); + return ScopeConfigInterface::SCOPE_TYPE_DEFAULT; + } - $magento2CoreSetup->loadModuleConfigurationFromPlatform(); - $currentConfiguration = Magento2CoreSetup::getModuleConfiguration(); + /** + * @return string|null + */ + public function getScopeUrl() + { + $request = $this->requestObject; - $isSameWebsite = $websiteId === intval($currentWebsiteId); + if ($request->getParam(ScopeInterface::SCOPE_WEBSITE)) { + return ScopeInterface::SCOPE_WEBSITE; + } - if (!$isSameWebsite && !$currentConfiguration->isHubEnabled()) { - return false; - } + if ($request->getParam(ScopeInterface::SCOPE_STORE)) { + return ScopeInterface::SCOPE_STORE; } - return true; + return null; } - private function removeDefaultConfigKeys() + /** + * @param $websiteId + * @return string + * @throws NoSuchEntityException + */ + private function getCallbackUrl($websiteId) { - $this->configWriter->save( - "pagarme_pagarme/global/secret_key", - null, - 'default', - 0 - ); - - $this->configWriter->save( - "pagarme_pagarme/global/public_key", - null, - 'default', - 0 - ); + $baseUrl = $this->storeManager->getStore()->getBaseUrl(); + $callbackUrl = $baseUrl . "rest/V1/pagarme/hub/command"; - $this->configWriter->save( - "pagarme_pagarme/global/secret_key_test", - null, - 'default', - 0 - ); + if (!empty($websiteId)) { + $callbackUrl .= "?websiteId=" . $websiteId; + } - $this->configWriter->save( - "pagarme_pagarme/global/public_key_test", - null, - 'default', - 0 - ); - $this->configWriter->save( - "pagarme_pagarme/hub/account_id", - null, - 'default', - 0 - ); + return $callbackUrl; + } - $this->configWriter->save( - "pagarme_pagarme/hub/merchant_id", - null, - 'default', - 0 - ); + /** + * @return string + * @throws NoSuchEntityException + */ + private function getWebHookkUrl() + { + $baseUrl = $this->storeManager->getStore()->getBaseUrl(); + return $baseUrl . "rest/V1/pagarme/webhook"; } private function updateStoreFields($websiteId) { $currentConfiguration = Magento2CoreSetup::getModuleConfiguration(); + $scope = $this->getScopeName(); $this->configWriter->save( "pagarme_pagarme/hub/install_id", $currentConfiguration->getHubInstallId()->getValue(), - 'websites', + $scope, $websiteId ); $this->configWriter->save( "pagarme_pagarme/hub/environment", $currentConfiguration->getHubEnvironment()->getValue(), - 'websites', + $scope, $websiteId ); $this->configWriter->save( "pagarme_pagarme/global/secret_key", $currentConfiguration->getSecretKey()->getValue(), - 'websites', + $scope, $websiteId ); $this->configWriter->save( "pagarme_pagarme/global/public_key", $currentConfiguration->getPublicKey()->getValue(), - 'websites', + $scope, $websiteId ); $this->configWriter->save( "pagarme_pagarme/hub/account_id", $currentConfiguration->getAccountId()->getValue(), - 'websites', + $scope, $websiteId ); $this->configWriter->save( "pagarme_pagarme/hub/merchant_id", $currentConfiguration->getMerchantId()->getValue(), - 'websites', + $scope, $websiteId ); $this->configWriter->save( "pagarme_pagarme/global/test_mode", 0, - 'websites', + $scope, $websiteId ); $this->configWriter->save( "pagarme_pagarme/global/secret_key_test", null, - 'websites', + $scope, $websiteId ); $this->configWriter->save( "pagarme_pagarme/global/public_key_test", null, - 'websites', + $scope, $websiteId ); - if ($this->allWebsitesIntegrated($websiteId)) { - $this->removeDefaultConfigKeys(); - } - $this->cacheManager->clean(['config']); } } diff --git a/Gateway/Transaction/GooglePay/Config/Config.php b/Gateway/Transaction/GooglePay/Config/Config.php index f941f911..e1033cf4 100755 --- a/Gateway/Transaction/GooglePay/Config/Config.php +++ b/Gateway/Transaction/GooglePay/Config/Config.php @@ -56,7 +56,7 @@ public function getMerchantName() public function getCardBrands() { $brandsAllowed = []; - $creditCardBrandsSelected = explode(',', $this->getConfig(static::CARD_BRANDS)); + $creditCardBrandsSelected = explode(',', $this->getConfig(static::CARD_BRANDS) ?? ''); foreach ($creditCardBrandsSelected as $brand) { if (in_array(strtoupper($brand), static::GOOGLE_POSSIBLE_BRANDS)) { $brandsAllowed[] = strtoupper($brand); diff --git a/Model/Account.php b/Model/Account.php index f0950ce3..f6aab4e2 100644 --- a/Model/Account.php +++ b/Model/Account.php @@ -9,11 +9,11 @@ use Magento\Framework\App\RequestInterface; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Exception\NoSuchEntityException; -use Magento\Store\Model\ScopeInterface; use Magento\Store\Model\StoreManagerInterface; use Pagarme\Core\Kernel\Aggregates\Configuration; use Pagarme\Core\Middle\Model\Account as AccountMiddle; use Pagarme\Pagarme\Concrete\Magento2CoreSetup; +use Pagarme\Pagarme\Controller\Adminhtml\Hub\Index as HubControllerIndex; use Pagarme\Pagarme\Model\Api\HubCommand; use Pagarme\Pagarme\Service\AccountService; use Psr\Log\LoggerInterface; @@ -70,6 +70,11 @@ class Account */ protected $pagarmeConfigProvider; + /** + * @var HubControllerIndex + */ + protected $hubControllerIndex; + /** * @param WriterInterface $configWriter * @param StoreManagerInterface $storeManager @@ -78,17 +83,21 @@ class Account * @param CollectionFactory $configCollectionFactory * @param LoggerInterface $logger * @param Session $session + * @param PagarmeConfigProvider $pagarmeConfigProvider + * @param HubControllerIndex $hubControllerIndex */ public function __construct( - WriterInterface $configWriter, + WriterInterface $configWriter, StoreManagerInterface $storeManager, - AccountService $accountService, - HubCommand $hubCommand, - CollectionFactory $configCollectionFactory, - LoggerInterface $logger, - Session $session, - PagarmeConfigProvider $pagarmeConfigProvider - ) { + AccountService $accountService, + HubCommand $hubCommand, + CollectionFactory $configCollectionFactory, + LoggerInterface $logger, + Session $session, + PagarmeConfigProvider $pagarmeConfigProvider, + HubControllerIndex $hubControllerIndex + ) + { $this->configWriter = $configWriter; $this->storeManager = $storeManager; $this->accountService = $accountService; @@ -97,11 +106,14 @@ public function __construct( $this->logger = $logger; $this->session = $session; $this->pagarmeConfigProvider = $pagarmeConfigProvider; + $this->hubControllerIndex = $hubControllerIndex; } /** * @param mixed $website * @return void + * @throws LocalizedException + * @throws NoSuchEntityException */ public function validateDashSettings($website) { @@ -119,7 +131,7 @@ public function validateDashSettings($website) $this->configWriter->save( PagarmeConfigProvider::PATH_DASH_ERRORS, json_encode($account->getErrors()), - ScopeInterface::SCOPE_WEBSITES, + $this->hubControllerIndex->getScopeName(), $website ); $this->savePaymentTypes($account, $website); @@ -145,9 +157,8 @@ public function saveAccountIdFromWebhook($account) $this->configWriter->save( PagarmeConfigProvider::PATH_ACCOUNT_ID, $account['id'], - ScopeInterface::SCOPE_WEBSITES, - $this->storeManager->getStore() - ->getWebsiteId() + $this->hubControllerIndex->getScopeName(), + $this->storeManager->getStore()->getWebsiteId() ); } @@ -161,7 +172,7 @@ public function getDashSettingsErrors() $this->initializeConfig(); $collection = $this->configCollectionFactory->create(); $collection->addFieldToFilter('path', ['eq' => PagarmeConfigProvider::PATH_DASH_ERRORS]); - $collection->addFieldToFilter('scope', ['eq' => ScopeInterface::SCOPE_WEBSITES]); + $collection->addFieldToFilter('scope', ['eq' => $this->hubControllerIndex->getScopeName()]); $collection->addFieldToFilter('scope_id', ['eq' => $this->session->getWebsiteId()]); if ($collection->count() === 0) { @@ -192,7 +203,7 @@ public function getPaymentType(string $paymentName, bool $gateway = true) : PagarmeConfigProvider::PATH_IS_PAYMENT_PSP_TYPE; $collection = $this->configCollectionFactory->create(); $collection->addFieldToFilter('path', ['eq' => sprintf($paymentType, $paymentName)]); - $collection->addFieldToFilter('scope', ['eq' => ScopeInterface::SCOPE_WEBSITES]); + $collection->addFieldToFilter('scope', ['eq' => $this->hubControllerIndex->getScopeName()]); $collection->addFieldToFilter('scope_id', ['eq' => $this->session->getWebsiteId()]); if ($collection->count() === 0) { @@ -287,7 +298,7 @@ private function initializeConfig($website = null) $websiteId = $this->session->getWebsiteId(); } - if (!$websiteId) { + if (!$websiteId && $websiteId !== 0) { $websiteId = $this->storeManager->getStore() ->getWebsiteId(); } @@ -374,7 +385,7 @@ private function saveConfig($path, $value, $website) $this->configWriter->save( $path, $value, - ScopeInterface::SCOPE_WEBSITES, + $this->hubControllerIndex->getScopeName(), $website ); } diff --git a/Model/Api/HubCommand.php b/Model/Api/HubCommand.php index 4fdceddb..8d445a0d 100644 --- a/Model/Api/HubCommand.php +++ b/Model/Api/HubCommand.php @@ -3,6 +3,7 @@ namespace Pagarme\Pagarme\Model\Api; use Magento\Framework\App\Cache\Manager; +use Magento\Framework\App\Cache\Type\Config; use Magento\Framework\App\Config\Storage\WriterInterface; use Magento\Framework\Webapi\Exception as MagentoException; use Magento\Framework\Webapi\Rest\Request; @@ -10,6 +11,7 @@ use Pagarme\Core\Hub\Services\HubIntegrationService; use Pagarme\Pagarme\Api\HubCommandInterface; use Pagarme\Pagarme\Concrete\Magento2CoreSetup; +use Pagarme\Pagarme\Controller\Adminhtml\Hub\Index as HubControllerIndex; class HubCommand implements HubCommandInterface { @@ -38,18 +40,29 @@ class HubCommand implements HubCommandInterface */ protected $storeManager; + /** + * @var HubControllerIndex + */ + private $hubControllerIndex; + public function __construct( Request $request, WriterInterface $configWriter, Manager $cacheManager, - StoreManagerInterface $storeManager + StoreManagerInterface $storeManager, + HubControllerIndex $hubControllerIndex ) { $this->request = $request; $this->configWriter = $configWriter; $this->cacheManager = $cacheManager; $this->storeManager = $storeManager; + $this->hubControllerIndex = $hubControllerIndex; } + /** + * @throws MagentoException + * @throws \Exception + */ public function execute() { $params = json_decode( @@ -57,13 +70,8 @@ public function execute() ); $paramsFromUrl = $this->request->getParams(); - $this->websiteId = isset($paramsFromUrl['websiteId']) - ? $paramsFromUrl['websiteId'] - : $this->storeManager->getDefaultStoreView()->getWebsiteId(); + $this->websiteId = $paramsFromUrl['websiteId'] ?? 0; - $storeId = $this->storeManager->getWebsite($this->websiteId) - ->getDefaultStore()->getId(); - $this->storeManager->setCurrentStore($storeId); Magento2CoreSetup::bootstrap(); $hubIntegrationService = new HubIntegrationService(); @@ -83,79 +91,73 @@ public function execute() return "Command $params->command executed successfully"; } - $commandMessage = $this->$command(); - return $commandMessage; + return $this->$command(); } public function uninstallCommand() { - if (!$this->websiteId) { - $this->websiteId = 1; + $scope = $this->hubControllerIndex->getScopeName(); + $websiteId = $this->websiteId ?? Magento2CoreSetup::getCurrentStoreId(); + + if (!$websiteId) { + $websiteId = 0; } - $this->configWriter->save( + + $this->configWriter->delete( "pagarme_pagarme/hub/install_id", - null, - 'websites', - $this->websiteId + $scope, + $websiteId ); - $this->configWriter->save( + $this->configWriter->delete( "pagarme_pagarme/hub/environment", - null, - 'websites', - $this->websiteId + $scope, + $websiteId ); - $this->configWriter->save( + $this->configWriter->delete( "pagarme_pagarme/global/secret_key", - null, - 'websites', - $this->websiteId + $scope, + $websiteId ); - $this->configWriter->save( + $this->configWriter->delete( "pagarme_pagarme/global/public_key", - null, - 'websites', - $this->websiteId + $scope, + $websiteId ); - $this->configWriter->save( + $this->configWriter->delete( "pagarme_pagarme/global/secret_key_test", - null, - 'websites', - $this->websiteId + $scope, + $websiteId ); - $this->configWriter->save( + $this->configWriter->delete( "pagarme_pagarme/global/public_key_test", - null, - 'websites', - $this->websiteId + $scope, + $websiteId ); - $this->configWriter->save( + $this->configWriter->delete( "pagarme_pagarme/hub/account_id", - null, - 'websites', - $this->websiteId + $scope, + $websiteId ); - $this->configWriter->save( + $this->configWriter->delete( "pagarme_pagarme/hub/merchant_id", - null, - 'websites', - $this->websiteId + $scope, + $websiteId ); - $this->configWriter->save( + $this->configWriter->delete( "pagarme_pagarme/hub/account_errors", - null, - 'websites', - $this->websiteId + $scope, + $websiteId ); - $this->cacheManager->clean(['config']); + $this->cacheManager->clean([Config::TYPE_IDENTIFIER]); return "Hub uninstalled successfully"; } diff --git a/Model/Notifications.php b/Model/Notifications.php index 28a946b2..a55ffbc9 100644 --- a/Model/Notifications.php +++ b/Model/Notifications.php @@ -60,9 +60,11 @@ class Notifications extends Message * @param Registry $registry * @param Account $account * @param HubIntegration $hubIntegration + * @param UrlInterface $urlInterface * @param AbstractResource|null $resource * @param AbstractDb|null $resourceCollection * @param array $data + * @throws NoSuchEntityException */ public function __construct( ConfigInterface $config, @@ -271,18 +273,7 @@ private function addDashSettingsMessages() */ private function buildDashLink(string $label, string $dashPage = '') { - if (!$this->account->hasMerchantAndAccountIds()) { - return $label; - } - - $dashSettings = !empty($dashPage) ? "settings/{$dashPage}/" : ''; - $url = $this->account->getDashUrl() . $dashSettings; - - return sprintf( - '%s', - $url, - $label - ); + return $label; } /** diff --git a/Observer/DashConfigValidatorObserver.php b/Observer/DashConfigValidatorObserver.php index f33b2c1f..41e970fa 100644 --- a/Observer/DashConfigValidatorObserver.php +++ b/Observer/DashConfigValidatorObserver.php @@ -4,8 +4,10 @@ use Magento\Framework\Event\Observer; use Magento\Framework\Event\ObserverInterface; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Store\Model\StoreManagerInterface; +use Pagarme\Pagarme\Controller\Adminhtml\Hub\Index as HubControllerIndex; use Pagarme\Pagarme\Model\Account; class DashConfigValidatorObserver implements ObserverInterface @@ -20,33 +22,45 @@ class DashConfigValidatorObserver implements ObserverInterface */ protected $storeManager; + /** + * @var HubControllerIndex + */ + protected $hubControllerIndex; + /** * @param Account $account * @param StoreManagerInterface $storeManager + * @param HubControllerIndex $hubControllerIndex */ public function __construct( - Account $account, - StoreManagerInterface $storeManager - ) { + Account $account, + StoreManagerInterface $storeManager, + HubControllerIndex $hubControllerIndex + ) + { $this->account = $account; $this->storeManager = $storeManager; + $this->hubControllerIndex = $hubControllerIndex; } /** * @param Observer $observer * @return $this - * @throws NoSuchEntityException + * @throws NoSuchEntityException|LocalizedException */ public function execute(Observer $observer) { - $section = $observer->getRequest() - ->getParam('section'); + $section = $observer->getRequest()->getParam('section'); if ($section !== 'payment') { return $this; } - $website = $observer->getRequest() - ->getParam('website', $this->storeManager->getStore()->getWebsiteId()); + $scopeUrl = $this->hubControllerIndex->getScopeUrl() ?? 'default'; + $websiteCode = $this->hubControllerIndex->getScopeUrl() ? $this->storeManager->getWebsite()->getId() : 0; + $website = $observer->getRequest()->getParam( + $scopeUrl, + $websiteCode + ); $this->account->validateDashSettings($website); return $this; diff --git a/Observer/HubIntegrationObserver.php b/Observer/HubIntegrationObserver.php new file mode 100644 index 00000000..8a15fd71 --- /dev/null +++ b/Observer/HubIntegrationObserver.php @@ -0,0 +1,48 @@ +hubCommand = $hubCommand; + } + + /** + * @param Observer $observer + * @return void + */ + public function execute(Observer $observer) + { + $configData = $observer->getData('event')->getData('configData'); + + if ($configData[ScopeInterface::SCOPE_WEBSITE] === null) { + return; + } + + $pagarmeGlobalFields = $configData['groups']['pagarme_pagarme']['groups']['pagarme_pagarme_global']['fields']; + $integrationUseDefault = 0; + + if (array_key_exists('hub_integration', $pagarmeGlobalFields)) { + $integrationUseDefault = $pagarmeGlobalFields['hub_integration']['inherit']; + } + + if ($integrationUseDefault === '1') { + $this->hubCommand->uninstallCommand(); + } + } +} diff --git a/README.md b/README.md index 384bb588..0565732d 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ composer require pagarme/pagarme-magento2-module ## Requirements * PHP >= 7.1 -* Magento2 >= 2.3 & <= 2.4.5 +* Magento2 >= 2.3 & <= 2.4.6 ## Configuration @@ -36,3 +36,9 @@ Open a new Issue following our issue template [ISSUE-TEMPLATE](ISSUE-TEMPLATE.md ## Changelog See in [releases](https://github.com/pagarme/magento2-module/releases) + + +## Contributors +| ![robsoned avatar](https://avatars.githubusercontent.com/u/18008565?v=4) | +|-------------------------------------------------------------------------------------- +| [robsoned](https://github.com/robsoned) | \ No newline at end of file diff --git a/Test/Unit/Gateway/Transaction/GooglePay/Config/ConfigTest.php b/Test/Unit/Gateway/Transaction/GooglePay/Config/ConfigTest.php new file mode 100644 index 00000000..e0d087c4 --- /dev/null +++ b/Test/Unit/Gateway/Transaction/GooglePay/Config/ConfigTest.php @@ -0,0 +1,37 @@ +makePartial(['getConfig']); + $config->shouldAllowMockingProtectedMethods(); + $config->shouldReceive('getConfig')->andReturn('visa'); + $allowedBrands = $config->getCardBrands(); + $this->assertIsArray($allowedBrands); + $this->assertEquals(['VISA'], $allowedBrands); + } + public function testGetCardBrandsIfTwoBrandsActives() + { + $config = \Mockery::mock(Config::class)->makePartial(['getConfig']); + $config->shouldAllowMockingProtectedMethods(); + $config->shouldReceive('getConfig')->andReturn('visa,mastercard'); + $allowedBrands = $config->getCardBrands(); + $this->assertIsArray($allowedBrands); + $this->assertEquals(['VISA', 'MASTERCARD'], $allowedBrands); + } + + public function testGetCardBrandsWithBrandNotAllowedForGooglePay() + { + $config = \Mockery::mock(Config::class)->makePartial(['getConfig']); + $config->shouldAllowMockingProtectedMethods(); + $config->shouldReceive('getConfig')->andReturn('visa,jcb'); + $allowedBrands = $config->getCardBrands(); + $this->assertIsArray($allowedBrands); + $this->assertEquals(['VISA'], $allowedBrands); + } +} diff --git a/composer.json b/composer.json index f4fda02f..0d4d8886 100755 --- a/composer.json +++ b/composer.json @@ -1,12 +1,12 @@ { "name": "pagarme/pagarme-magento2-module", "license": "MIT", - "version": "2.5.0", + "version": "2.6.0", "type": "magento2-module", "description": "Magento 2 Module Pagar.me", "require": { "php": ">=7.1", - "pagarme/ecommerce-module-core": "~2.5.0" + "pagarme/ecommerce-module-core": "2.6.*" }, "require-dev": { "phpunit/phpunit": "^5 | ^6 | ^7 | ^8 | ^9", diff --git a/etc/adminhtml/system/global.xml b/etc/adminhtml/system/global.xml index f2f6b03c..6fc46ead 100644 --- a/etc/adminhtml/system/global.xml +++ b/etc/adminhtml/system/global.xml @@ -3,9 +3,10 @@ - + Pagarme\Pagarme\Block\Adminhtml\System\Config\Form\Field\HubIntegration + pagarme_pagarme/hub/install_id diff --git a/etc/adminhtml/system/transaction/googlepay.xml b/etc/adminhtml/system/transaction/googlepay.xml index f55127d1..d57f9c26 100644 --- a/etc/adminhtml/system/transaction/googlepay.xml +++ b/etc/adminhtml/system/transaction/googlepay.xml @@ -1,6 +1,5 @@ - - + @@ -11,20 +10,40 @@ payment/pagarme_googlepay/title + + 1 + - + + + Dashboard at: Settings > Keys > Account ID]]> + pagarme_pagarme/hub/account_id + + 1 + + + - here.]]> + here.]]> payment/pagarme_googlepay/merchant_id + + 1 + - + payment/pagarme_googlepay/merchant_name Name of your store that will be displayed to the customer while purchasing through Google Pay. + + 1 + - + payment/pagarme_googlepay/sort_order + + 1 + - \ No newline at end of file + diff --git a/etc/events.xml b/etc/events.xml index 18e83e56..60172a18 100644 --- a/etc/events.xml +++ b/etc/events.xml @@ -1,75 +1,87 @@ - + - + - + - + - + - + - + - + - - + + - + - + - + + + + - + - + - + - + instance="Pagarme\Pagarme\Observer\OrderCancelAfter"/> - + instance="Pagarme\Pagarme\Observer\OrderCancelAfter"/> - + instance="Pagarme\Pagarme\Observer\CartAddProductAfterObserver"/> - + instance="Pagarme\Pagarme\Observer\UpdateProductPlanObserver"/> - + instance="Pagarme\Pagarme\Observer\CustomerLogin"/> - - + diff --git a/etc/module.xml b/etc/module.xml index 2ae94da5..dffb28dd 100755 --- a/etc/module.xml +++ b/etc/module.xml @@ -9,7 +9,7 @@ */ --> - + diff --git a/i18n/pt_BR.csv b/i18n/pt_BR.csv index 81dcae63..30712c96 100644 --- a/i18n/pt_BR.csv +++ b/i18n/pt_BR.csv @@ -474,6 +474,7 @@ "Company address","Endereço da empresa" "Mother name","Nome da mãe" "Date of birth","Data de nascimento" +"dd/mm/yyyy","dd/mm/aaaa" "Monthly income","Renda mensal" "Profession","Profissão" "Reference point","Ponto de referência" @@ -481,6 +482,7 @@ "Annual revenue","Faturamento anual" "Founding date","Data de fundação" "Company type","Tipo da empresa" +"E.g. LTDA. or SA.","Ex: LTDA. ou SA." "Company name","Razão social" "Managing partner","Sócio administrador" "Managing partner phone numbers","Números de telefones do sócio administrador" @@ -606,7 +608,9 @@ "Recipient not founded.","Recebedor não encontrado." "Failed to generate the security validation link.","Falha ao gerar o link de validação de segurança." "Something went wrong, please try again later.","Algo deu errado, por favor tente novamente mais tarde." -"Google Pay identifier required to create successful orders, find out how to request here.", "Identificador do Google Pay necessário para criação de pedidos com sucesso, saiba como solicitar aqui." +"Pagar.me account ID", "ID da conta Pagar.me" +"Consult the Dashboard at: Settings > Keys > Account ID", "Consulte na Dashboard em: Configurações > Chaves > ID da Conta" +"Google Pay identifier required to create successful orders. Find out how to request here.", "Identificador do Google Pay necessário para criação de pedidos com sucesso. Saiba como solicitar aqui." "MerchantId Google Pay", "MerchantId Google Pay" "Store name on Google Pay", "Nome da loja no Google Pay" "Name of your store that will be displayed to the customer while purchasing through Google Pay.", "Nome da sua loja que será exibida ao cliente durante a compra pelo Google Pay." diff --git a/view/adminhtml/layout/adminhtml_system_config_edit.xml b/view/adminhtml/layout/adminhtml_system_config_edit.xml index 998a8f56..06c5e5db 100644 --- a/view/adminhtml/layout/adminhtml_system_config_edit.xml +++ b/view/adminhtml/layout/adminhtml_system_config_edit.xml @@ -5,6 +5,7 @@ + diff --git a/view/adminhtml/requirejs-config.js b/view/adminhtml/requirejs-config.js index 4d78b889..ea043711 100644 --- a/view/adminhtml/requirejs-config.js +++ b/view/adminhtml/requirejs-config.js @@ -2,8 +2,7 @@ const config = { map: { '*': { orderCharge: 'Pagarme_Pagarme/js/view/order/orderCharge', - creditCardAdminPagarme: 'Pagarme_Pagarme/js/view/form/creditCard', - pagarmeJqueryMask: 'Pagarme_Pagarme/js/jquery.mask.min' + creditCardAdminPagarme: 'Pagarme_Pagarme/js/view/form/creditCard' } } } diff --git a/view/adminhtml/templates/form/creditcard.phtml b/view/adminhtml/templates/form/creditcard.phtml index 1bfaaca5..2f907b08 100644 --- a/view/adminhtml/templates/form/creditcard.phtml +++ b/view/adminhtml/templates/form/creditcard.phtml @@ -45,7 +45,8 @@ $code = $block->getMethodCode();
- +
@@ -91,7 +92,8 @@ $code = $block->getMethodCode(); type="number" min="0" name="payment[cc_cid]" - class="hosted-control hosted-cid cc_cid"/> + class="hosted-control hosted-cid cc_cid" + inputmode="numeric"/>
diff --git a/view/adminhtml/templates/info/card.phtml b/view/adminhtml/templates/info/card.phtml index 0cc47db3..5aebcf62 100644 --- a/view/adminhtml/templates/info/card.phtml +++ b/view/adminhtml/templates/info/card.phtml @@ -3,6 +3,9 @@ * @var \Pagarme\Core\Kernel\Aggregates\Transaction $info */ $info = $this->getTransactionInfo(); + if(empty($info)) { + return; + } ?> getTitle()); ?> diff --git a/view/adminhtml/templates/marketplace/recipients/create.phtml b/view/adminhtml/templates/marketplace/recipients/create.phtml index 8b4fd375..c50b43b8 100644 --- a/view/adminhtml/templates/marketplace/recipients/create.phtml +++ b/view/adminhtml/templates/marketplace/recipients/create.phtml @@ -1,5 +1,6 @@ getAllRegionsOfCountry(); -$editRecipient = $block->getEditRecipient(); ?> +$editRecipient = $block->getEditRecipient(); +$datePlaceholder = __('dd/mm/yyyy'); ?>
@@ -250,8 +251,8 @@ $editRecipient = $block->getEditRecipient(); ?>
+ placeholder="" data-datepicker + data-date-mask data-toggle-required>
@@ -290,14 +291,15 @@ $editRecipient = $block->getEditRecipient(); ?>
-
+
-
+
+ id="recipient-corporation-type" + placeholder="" data-toggle-required>
@@ -305,11 +307,12 @@ $editRecipient = $block->getEditRecipient(); ?> -
+
+ placeholder="" + data-datepicker data-date-mask>
@@ -633,7 +636,8 @@ $editRecipient = $block->getEditRecipient(); ?>
diff --git a/view/adminhtml/web/css/integration_buttons.css b/view/adminhtml/web/css/integration_buttons.css index 59b87f70..20f803b9 100644 --- a/view/adminhtml/web/css/integration_buttons.css +++ b/view/adminhtml/web/css/integration_buttons.css @@ -1,4 +1,8 @@ -#pagarme-hub-button, #pagarme-dash-button { +#row_payment_other_pagarme_pagarme_pagarme_pagarme_global_hub_integration .control-value { + display: none; +} + +a.pagarme-integration-button, #pagarme-dash-button { background-color: #65a300; border-color: #65a300; border-radius: 2px; @@ -17,7 +21,7 @@ color: #fff; user-select: none; transition: background-color .2s ease-in-out, border-color .2s ease-in-out; - margin: 0 1rem 1rem 0; + margin: 0 1rem 0 0; } #pagarme-dash-button { @@ -27,18 +31,35 @@ text-transform: none; } -#pagarme-hub-button:hover, #pagarme-hub-button:active, #pagarme-hub-button:focus { +a.pagarme-integration-button.hidden { + display: none !important; +} + +.is-disabled a.pagarme-integration-button { + background-color: #e9e9e9; + border-color: #adadad; + color: #303030; + pointer-events: none; + touch-action: none; + cursor: not-allowed; + opacity: 0.5; +} + +a.pagarme-integration-button:hover, a.pagarme-integration-button:active, a.pagarme-integration-button:focus { background-color: #7da300; border-color: #7da300; + color: #fff; + text-decoration: none; } #pagarme-dash-button:hover, #pagarme-dash-button:active, #pagarme-dash-button:focus { background-color: #dbdbdb; } -#pagarme-hub-button:after { +#pagarme-integrate-button:after, +#pagarme-view-integration-button:after{ content: ""; - background: url("data:image/png;base64,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qwxGjgVUoUJy/OB/8LtbszA16SYFY0DgxbY/RoDuXaBZt+3vY9tungD+Z+BKa/urDWD2k/R6W4scAaFt4OK6rcl7wOUOMPikS4bkSH6aQqEAvJ/RN+WAgVugd83trbWP0wcgQ10t3wAHh8BokbLXPd7d09nbv2da/f0AhAxyrtE/1ZMAAA0YaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/Pgo8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA0LjQuMC1FeGl2MiI+CiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiCiAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICB4bWxuczpHSU1QPSJodHRwOi8vd3d3LmdpbXAub3JnL3htcC8iCiAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgeG1wTU06RG9jdW1lbnRJRD0iZ2ltcDpkb2NpZDpnaW1wOjE3YWFmOTUyLWNiMTYtNDc5Mi1hMmU1LWZkZGRmODY1ZWFmZCIKICAgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpiZGE4ODI3My0wNzllLTQ2NTAtYjAyYS0wOTRlZTkwOWQzOTciCiAgIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDphNGVlM2VhMi02NzM5LTQwODYtYWY4ZS00NjgyNmU3ZmNiNTgiCiAgIGRjOkZvcm1hdD0iaW1hZ2UvcG5nIgogICBHSU1QOkFQST0iMi4wIgogICBHSU1QOlBsYXRmb3JtPSJXaW5kb3dzIgogICBHSU1QOlRpbWVTdGFtcD0iMTYyMTUyMzk4MDE2MTIxMCIKICAgR0lNUDpWZXJzaW9uPSIyLjEwLjI0IgogICB0aWZmOk9yaWVudGF0aW9uPSIxIgogICB4bXA6Q3JlYXRvclRvb2w9IkdJTVAgMi4xMCI+CiAgIDx4bXBNTTpIaXN0b3J5PgogICAgPHJkZjpTZXE+CiAgICAgPHJkZjpsaQogICAgICBzdEV2dDphY3Rpb249InNhdmVkIgogICAgICBzdEV2dDpjaGFuZ2VkPSIvIgogICAgICBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOmRkMmI0OWM4LTVjYjQtNGYxZC04ZDFhLTBmNmE2YzcxNDRiOCIKICAgICAgc3RFdnQ6c29mdHdhcmVBZ2VudD0iR2ltcCAyLjEwIChXaW5kb3dzKSIKICAgICAgc3RFdnQ6d2hlbj0iMjAyMS0wNS0yMFQxMjoxOTo0MCIvPgogICAgPC9yZGY6U2VxPgogICA8L3htcE1NOkhpc3Rvcnk+CiAgPC9yZGY6RGVzY3JpcHRpb24+CiA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgCjw/eHBhY2tldCBlbmQ9InciPz7JVoCNAAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH5QUUDxMowsDBfAAAAo5JREFUSMe9lr1rFEEUwGf37nK5RKKQXAJBUUM0okiKEKy0sbAJ+QsCaayMVarYKdhpK1gKwoGIIiLEQiGYFMEvhBj01ETiHrmPvdzebnZ3dj7ejI0Qc97sfW185Qxvf/PezPxmNRQSmOy+TMS7RyWSVSnlLwC6iqm74lPn7dH+MY6iDsrwiqwTIHiJMHyv7OTORwokCuBeCMGAPq+4hbP/BSik+IMFRhi+s2a8Th5IS/fqg9pWf6x6xZMHBlQsorSLK5Oqb+qhRE2TQgJuZZGapqd7kodf2Z450VaVlpePlXeN44ThacL8+wxosclKi6ZjnOj4IC1nMylM3WtCgNkIyoG9/5xb6orkBOetjf6A+o8aQQPq3Y70rnqBc7NBa6npGKcjhtq3wqAM6OPINUgYfvq3EvZXKSBvbZxSJlfc/BAHdkVKOe0G1vizTwt6I2DJ3kqD4JV6QCmlJAzf/SfJ9ssXKQveCLlfIRzYtk+cG4XqZncDUcyr2gqCG5nV63sLpxwvSCkhbC8A+AfTMdIq4Hpu+RAHZqnyLbc4jhBCyCfO1WbVxYG9K9lbSkkzTh6qcr3AmUNG+euAEGC34ksvsOdDgDOqPMqDB/qR3qFZTdP7WjmRXYnUnGqOC7YW4tljendX7+VWr0BcT4x4xB6ta6Bq9ruUQtQFIn04riGtLcHG9cQQQuhH7fjI4IRPmL8Y0xOp2jkQzIgLKXZibQAlQkQ1l0z0TCnfQyFgvWWYlMR0tr60paSKW7jU6qtOGH7SqQcXm/+FEIHlFs91BCxYm4OMk2wTMKAMz0Zi+9xOdoDy4EWIC/NuYE11ytFqB0wnN9mX6p+J6bEzCGm9INhPysnStvUtMzZ8AXcK/A0UsGey2h9i1gAAAABJRU5ErkJggg=="); + background-image: url("data:image/png;base64,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qwxGjgVUoUJy/OB/8LtbszA16SYFY0DgxbY/RoDuXaBZt+3vY9tungD+Z+BKa/urDWD2k/R6W4scAaFt4OK6rcl7wOUOMPikS4bkSH6aQqEAvJ/RN+WAgVugd83trbWP0wcgQ10t3wAHh8BokbLXPd7d09nbv2da/f0AhAxyrtE/1ZMAAA0YaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/Pgo8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA0LjQuMC1FeGl2MiI+CiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiCiAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICB4bWxuczpHSU1QPSJodHRwOi8vd3d3LmdpbXAub3JnL3htcC8iCiAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgeG1wTU06RG9jdW1lbnRJRD0iZ2ltcDpkb2NpZDpnaW1wOjE3YWFmOTUyLWNiMTYtNDc5Mi1hMmU1LWZkZGRmODY1ZWFmZCIKICAgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpiZGE4ODI3My0wNzllLTQ2NTAtYjAyYS0wOTRlZTkwOWQzOTciCiAgIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDphNGVlM2VhMi02NzM5LTQwODYtYWY4ZS00NjgyNmU3ZmNiNTgiCiAgIGRjOkZvcm1hdD0iaW1hZ2UvcG5nIgogICBHSU1QOkFQST0iMi4wIgogICBHSU1QOlBsYXRmb3JtPSJXaW5kb3dzIgogICBHSU1QOlRpbWVTdGFtcD0iMTYyMTUyMzk4MDE2MTIxMCIKICAgR0lNUDpWZXJzaW9uPSIyLjEwLjI0IgogICB0aWZmOk9yaWVudGF0aW9uPSIxIgogICB4bXA6Q3JlYXRvclRvb2w9IkdJTVAgMi4xMCI+CiAgIDx4bXBNTTpIaXN0b3J5PgogICAgPHJkZjpTZXE+CiAgICAgPHJkZjpsaQogICAgICBzdEV2dDphY3Rpb249InNhdmVkIgogICAgICBzdEV2dDpjaGFuZ2VkPSIvIgogICAgICBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOmRkMmI0OWM4LTVjYjQtNGYxZC04ZDFhLTBmNmE2YzcxNDRiOCIKICAgICAgc3RFdnQ6c29mdHdhcmVBZ2VudD0iR2ltcCAyLjEwIChXaW5kb3dzKSIKICAgICAgc3RFdnQ6d2hlbj0iMjAyMS0wNS0yMFQxMjoxOTo0MCIvPgogICAgPC9yZGY6U2VxPgogICA8L3htcE1NOkhpc3Rvcnk+CiAgPC9yZGY6RGVzY3JpcHRpb24+CiA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgCjw/eHBhY2tldCBlbmQ9InciPz7JVoCNAAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH5QUUDxMowsDBfAAAAo5JREFUSMe9lr1rFEEUwGf37nK5RKKQXAJBUUM0okiKEKy0sbAJ+QsCaayMVarYKdhpK1gKwoGIIiLEQiGYFMEvhBj01ETiHrmPvdzebnZ3dj7ejI0Qc97sfW185Qxvf/PezPxmNRQSmOy+TMS7RyWSVSnlLwC6iqm74lPn7dH+MY6iDsrwiqwTIHiJMHyv7OTORwokCuBeCMGAPq+4hbP/BSik+IMFRhi+s2a8Th5IS/fqg9pWf6x6xZMHBlQsorSLK5Oqb+qhRE2TQgJuZZGapqd7kodf2Z450VaVlpePlXeN44ThacL8+wxosclKi6ZjnOj4IC1nMylM3WtCgNkIyoG9/5xb6orkBOetjf6A+o8aQQPq3Y70rnqBc7NBa6npGKcjhtq3wqAM6OPINUgYfvq3EvZXKSBvbZxSJlfc/BAHdkVKOe0G1vizTwt6I2DJ3kqD4JV6QCmlJAzf/SfJ9ssXKQveCLlfIRzYtk+cG4XqZncDUcyr2gqCG5nV63sLpxwvSCkhbC8A+AfTMdIq4Hpu+RAHZqnyLbc4jhBCyCfO1WbVxYG9K9lbSkkzTh6qcr3AmUNG+euAEGC34ksvsOdDgDOqPMqDB/qR3qFZTdP7WjmRXYnUnGqOC7YW4tljendX7+VWr0BcT4x4xB6ta6Bq9ruUQtQFIn04riGtLcHG9cQQQuhH7fjI4IRPmL8Y0xOp2jkQzIgLKXZibQAlQkQ1l0z0TCnfQyFgvWWYlMR0tr60paSKW7jU6qtOGH7SqQcXm/+FEIHlFs91BCxYm4OMk2wTMKAMz0Zi+9xOdoDy4EWIC/NuYE11ytFqB0wnN9mX6p+J6bEzCGm9INhPysnStvUtMzZ8AXcK/A0UsGey2h9i1gAAAABJRU5ErkJggg=="); background-size: 16px 16px; background-repeat: no-repeat; display: inline-block; diff --git a/view/adminhtml/web/js/global.js b/view/adminhtml/web/js/global.js new file mode 100644 index 00000000..88bf0751 --- /dev/null +++ b/view/adminhtml/web/js/global.js @@ -0,0 +1,79 @@ +require([ + "jquery", + "jquery/ui", +], function ($) { + "use strict"; + $(document).ready(function () { + const + integrationButtonsRow = $('#row_payment_other_pagarme_pagarme_pagarme_pagarme_global_hub_integration'), + integrationButtons = $('a.pagarme-integration-button'), + integrateButton = $('#pagarme-integrate-button'), + viewIntegrationButton = $('#pagarme-view-integration-button'), + dashButton = $('#pagarme-dash-button'), + integrationUseDefault = $('#payment_other_pagarme_pagarme_pagarme_pagarme_global_hub_integration_inherit'), + integratedScope = $('[data-pagarme-integration-scope]').attr('data-pagarme-integration-scope'), + hasIntegration = + $('#row_payment_other_pagarme_pagarme_pagarme_pagarme_global_hub_integration .control-value') + .html() !== '', + disabledClass = 'is-disabled', + hiddenClass = 'hidden'; + + if (integrationUseDefault.is(':checked') && hasIntegration) { + disableButtons(); + } + + integrationButtons.on('click', function(event) { + const isDisabled = integrationButtonsRow.hasClass(disabledClass); + + if (isDisabled) { + event.preventDefault(); + } + }); + + integrationUseDefault.on('change', function() { + if ($(this).is(':checked')) { + disableButtons(); + showIntegratedButtons(); + return; + } + + enableButtons(); + hideIntegratedButtons(); + }) + + function disableButtons() { + if (!hasIntegration) { + return; + } + + integrationButtonsRow.addClass(disabledClass); + } + + function enableButtons() { + integrationButtonsRow.removeClass(disabledClass); + } + + function hideIntegratedButtons() { + if (integratedScope !== 'default') { + return; + } + + viewIntegrationButton.addClass(hiddenClass); + dashButton.addClass(hiddenClass); + integrateButton.removeClass(hiddenClass); + } + + function showIntegratedButtons() { + if ( + (integratedScope === 'default' && !integrationUseDefault.is(':checked')) + || !hasIntegration + ) { + return; + } + + integrateButton.addClass(hiddenClass); + viewIntegrationButton.removeClass(hiddenClass); + dashButton.removeClass(hiddenClass); + } + }); +}); diff --git a/view/base/requirejs-config.js b/view/base/requirejs-config.js index 868164c2..1185ae0c 100644 --- a/view/base/requirejs-config.js +++ b/view/base/requirejs-config.js @@ -1,7 +1,16 @@ const config = { map: { '*': { - numberFormatter: 'Pagarme_Pagarme/js/helper/numberFormatter' + numberFormatter: 'Pagarme_Pagarme/js/helper/numberFormatter', + pagarmeJqueryMask: 'Pagarme_Pagarme/js/jquery.mask.min' + }, + shim : { + 'pagarmeJqueryMask' : { + deps : ['jquery'] + }, + 'Pagarme_Pagarme/js/core/checkout/PaymentMethodController' : { + deps : ['pagarmeJqueryMask'] + } } } } diff --git a/view/adminhtml/web/js/jquery.mask.min.js b/view/base/web/js/jquery.mask.min.js similarity index 100% rename from view/adminhtml/web/js/jquery.mask.min.js rename to view/base/web/js/jquery.mask.min.js diff --git a/view/frontend/templates/info/card.phtml b/view/frontend/templates/info/card.phtml index 67862452..28cb0f32 100644 --- a/view/frontend/templates/info/card.phtml +++ b/view/frontend/templates/info/card.phtml @@ -3,6 +3,9 @@ * @var \Pagarme\Core\Kernel\Aggregates\Transaction $info */ $info = $this->getTransactionInfo(); + if(empty($info)) { + return; + } ?> getTitle()); ?> diff --git a/view/frontend/web/js/core/checkout/CreditCardToken.js b/view/frontend/web/js/core/checkout/CreditCardToken.js index 9169724b..b4a9bbf0 100644 --- a/view/frontend/web/js/core/checkout/CreditCardToken.js +++ b/view/frontend/web/js/core/checkout/CreditCardToken.js @@ -3,7 +3,7 @@ define([], () => { constructor(formObject, documentNumber = null) { this.documentNumber = documentNumber; if (documentNumber != null) { - this.documentNumber = documentNumber.replace(/(\.|\/|\-)/g,""); + this.documentNumber = documentNumber.replace(/[^0-9]+/g, ''); } this.formObject = formObject; } @@ -12,7 +12,7 @@ define([], () => { type: "card", card : { holder_name: this.formObject.creditCardHolderName.val(), - number: this.formObject.creditCardNumber.val(), + number: this.formObject.creditCardNumber.val().replace(/[^0-9]+/g, ''), exp_month: this.formObject.creditCardExpMonth.val(), exp_year: this.formObject.creditCardExpYear.val(), cvv: this.formObject.creditCardCvv.val(), diff --git a/view/frontend/web/js/core/checkout/PaymentMethodController.js b/view/frontend/web/js/core/checkout/PaymentMethodController.js index fa471215..02c2b567 100644 --- a/view/frontend/web/js/core/checkout/PaymentMethodController.js +++ b/view/frontend/web/js/core/checkout/PaymentMethodController.js @@ -14,6 +14,7 @@ define([ 'Pagarme_Pagarme/js/core/models/BoletoCreditcardModel', 'Pagarme_Pagarme/js/core/models/GooglePayModel', 'Pagarme_Pagarme/js/core/validators/CustomerValidator', + 'pagarmeJqueryMask' ], ( $, PlatformConfig, @@ -460,18 +461,9 @@ define([ const paymentMethodController = this; formObject.creditCardNumber.unbind(); - formObject.creditCardNumber.on('keydown', function () { - const element = $(this); - paymentMethodController.limitCharacters(element, 19); - }); const binObj = new Bin(); - formObject.creditCardNumber.on('keyup', function () { - const element = $(this); - paymentMethodController.clearLetters(element); - }); - formObject.creditCardNumber.on('change', function () { const element = $(this); @@ -479,6 +471,8 @@ define([ paymentMethodController.setBin(binObj, element, formObject); }, 300); }); + + formObject.creditCardNumber.mask('0000 0000 0000 0000'); } twoCardsTotal(paymentMethod) { @@ -841,15 +835,16 @@ define([ setBin(binObj, creditCardNumberElement, formObject) { const bin = binObj; - const cardNumber = bin.formatNumber(creditCardNumberElement.val()); + const cardNumber = creditCardNumberElement.val().replace(/[^0-9]+/g, ''); + const cardBin = bin.formatNumber(cardNumber); - if (cardNumber.length < 4) { + if (cardBin.length < 4) { return; } - const isNewBrand = bin.validate(cardNumber); + const isNewBrand = bin.validate(cardBin); - bin.init(cardNumber); + bin.init(cardBin); const formHandler = new FormHandler(); formHandler.init(formObject); @@ -862,20 +857,6 @@ define([ } - limitCharacters(element, limit) { - const val = element.val(); - - if (val != "" && val.length > limit) { - element.val(val.substring(0, limit)); - } - } - - clearLetters(element) { - const val = element.val(); - const newVal = val.replace(/[^0-9]+/g, ''); - element.val(newVal); - } - clearNumbers(element) { const val = element.val(); const newVal = val.replace(/[0-9.-]+/g, ''); diff --git a/view/frontend/web/js/view/payment/default.js b/view/frontend/web/js/view/payment/default.js index 387719df..422c861b 100644 --- a/view/frontend/web/js/view/payment/default.js +++ b/view/frontend/web/js/view/payment/default.js @@ -51,15 +51,10 @@ define( $t, globalMessageList, urlBuilder, - PagarmeCore, - PaymentController, - PlatformPlaceOrder + PagarmeCore ) { - return Component.extend({ initPaymentMethod: function() { - var _self = this; - const platFormConfig = window.checkoutConfig; platFormConfig.moduleUrls = {}; const installmentsUrl = installmentsAction(); @@ -125,12 +120,12 @@ define( */ beforeplaceOrder: function(data, event){ - var _self = this; + const _self = this; PagarmeCore.platFormConfig.addresses.billingAddress = quote.billingAddress(); - var PlatformPlaceOrder = { - obj : _self, + const PlatformPlaceOrder = { + obj: _self, data: data, event: event }; @@ -145,9 +140,9 @@ define( * Select current payment token */ selectPaymentMethod: function() { - var data = this.getData(); + const data = this.getData(); if (data == undefined) { - var platFormConfig = PagarmeCore.platFormConfig; + const platFormConfig = PagarmeCore.platFormConfig; PagarmeCore.init(this.getModel(), platFormConfig); } selectPaymentMethodAction(this.getData()); @@ -161,9 +156,9 @@ define( this.oldInstallmentTax = 0; } - var total = quote.getTotals()(); - var subTotalIndex = null; - for (var i = 0, len = total.total_segments.length; i < len; i++) { + const total = quote.getTotals()(); + let subTotalIndex = null; + for (let i = 0, len = total.total_segments.length; i < len; i++) { if (total.total_segments[i].code == "grand_total") { subTotalIndex = i; continue; diff --git a/view/frontend/web/template/payment/creditcard-form.html b/view/frontend/web/template/payment/creditcard-form.html index e71d49b3..817c5e66 100644 --- a/view/frontend/web/template/payment/creditcard-form.html +++ b/view/frontend/web/template/payment/creditcard-form.html @@ -55,12 +55,11 @@
@@ -116,14 +115,14 @@ CVV
- + />