From 26ebb4e40388f655083d8119d417a2d9870e3ccc Mon Sep 17 00:00:00 2001 From: Lucas Pereira Date: Tue, 21 May 2024 17:31:57 -0300 Subject: [PATCH 1/6] new version --- Api/UpdateStatusesInterface.php | 5 +- .../Order/View/Tab/PixPaymentInfo.php | 36 +++ Block/Payment/Info.php | 29 +- Block/Success.php | 8 + Helper/Data.php | 4 + Model/Config/Source/Ambiente.php | 2 +- Model/Config/Source/Discount.php | 4 +- Model/Payment/Boleto.php | 8 +- Model/Payment/Cc.php | 8 +- Model/Payment/Pix.php | 265 ++++++++++++++++++ Model/UpdateStatuses.php | 133 +++++---- README-en.md | 131 +++++++++ README.md | 116 ++++---- Setup/UpgradeSchema.php | 20 ++ etc/adminhtml/system.xml | 139 +++++---- etc/config.xml | 30 ++ etc/module.xml | 2 +- etc/payment.xml | 3 + i18n/pt_BR.csv | 95 +++++++ view/adminhtml/layout/sales_order_view.xml | 11 + view/adminhtml/templates/form/array.phtml | 2 +- .../order/view/tab/pix_payment_info.phtml | 27 ++ view/adminhtml/web/css/pix.css | 83 ++++++ view/frontend/layout/checkout_index_index.xml | 8 + .../layout/checkout_onepage_success.xml | 7 +- view/frontend/layout/sales_order_view.xml | 3 + view/frontend/templates/info.phtml | 37 ++- view/frontend/templates/success.phtml | 43 ++- view/frontend/web/css/pix.css | 66 +++++ .../payment/method-renderer/pix-method.js | 207 ++++++++++++++ view/frontend/web/js/view/payment/pix.js | 19 ++ .../web/template/payment/cc-form.html | 4 +- view/frontend/web/template/payment/pix.html | 69 +++++ 33 files changed, 1448 insertions(+), 176 deletions(-) create mode 100644 Block/Adminhtml/Order/View/Tab/PixPaymentInfo.php create mode 100644 Model/Payment/Pix.php create mode 100644 README-en.md create mode 100644 i18n/pt_BR.csv create mode 100644 view/adminhtml/layout/sales_order_view.xml create mode 100644 view/adminhtml/templates/order/view/tab/pix_payment_info.phtml create mode 100644 view/adminhtml/web/css/pix.css create mode 100644 view/frontend/web/css/pix.css create mode 100644 view/frontend/web/js/view/payment/method-renderer/pix-method.js create mode 100644 view/frontend/web/js/view/payment/pix.js create mode 100644 view/frontend/web/template/payment/pix.html diff --git a/Api/UpdateStatusesInterface.php b/Api/UpdateStatusesInterface.php index df6ef4e..5946154 100755 --- a/Api/UpdateStatusesInterface.php +++ b/Api/UpdateStatusesInterface.php @@ -1,13 +1,14 @@ request = $http; + $this->orderRepository = $orderRepositoryInterface; + } + public function getOrder() + { + $orderId = $this->request->getParam('order_id'); + $order = $this->orderRepository->get($orderId); + return $order; + } + + + public function getPaymentMethodByOrder() + { + $order = $this->getOrder(); + $payment = $order->getPayment(); + return $payment->getMethod(); + } +} \ No newline at end of file diff --git a/Block/Payment/Info.php b/Block/Payment/Info.php index 2e5f381..29f6c07 100755 --- a/Block/Payment/Info.php +++ b/Block/Payment/Info.php @@ -1,4 +1,5 @@ _checkoutSession = $checkoutSession; $this->_orderFactory = $orderFactory; + $this->request = $http; + $this->orderRepository = $orderRepositoryInterface; } @@ -33,7 +40,12 @@ public function getOrder() if ($this->_checkoutSession->getLastRealOrderId()) { return $this->_checkoutSession->getLastRealOrder(); } - if ($order = $this->getInfo()->getOrder()) { + // if ($order = $this->getInfo()->getOrder()) { + // return $order; + // } + else { + $orderId = $this->request->getParam('order_id'); + $order = $this->orderRepository->get($orderId); return $order; } return false; @@ -45,6 +57,13 @@ public function getPaymentMethod() return $payment->getMethod(); } + public function getPaymentMethodByOrder() + { + $order = $this->getOrder(); + $payment = $order->getPayment(); + return $payment->getMethod(); + } + public function getPaymentInfo() { $order = $this->getOrder(); @@ -66,6 +85,14 @@ public function getPaymentInfo() ); break; + case 'pix': + return array( + 'tipo' => 'Pix', + 'url' => 'qrcode', + 'texto' => 'Escaneie o QrCode ou copie o código para realizar o pagamento' + + ); + break; } } diff --git a/Block/Success.php b/Block/Success.php index fb915d2..dfffa3e 100755 --- a/Block/Success.php +++ b/Block/Success.php @@ -24,6 +24,14 @@ public function __construct( public function getBoleto() { return $this->checkoutSession->getBoleto(); } + + public function getPixQrCode() { + return $this->checkoutSession->getPixQrCode(); + } + + public function getPixPayload() { + return $this->checkoutSession->getPixPayload(); + } public function getOrder() { return $this->_order = $this->_orderFactory->create()->loadByIncrementId( diff --git a/Helper/Data.php b/Helper/Data.php index 697a568..12be300 100755 --- a/Helper/Data.php +++ b/Helper/Data.php @@ -106,4 +106,8 @@ public function getInstallments() { public function getMinParcela(){ return $this->getConfig('payment/asaasmagento2/options_cc/min_parcela'); } + + public function getPixInstructions(){ + return $this->getConfig('payment/asaasmagento2/options_pix/instrucoes'); + } } diff --git a/Model/Config/Source/Ambiente.php b/Model/Config/Source/Ambiente.php index ab435a3..1e82aea 100755 --- a/Model/Config/Source/Ambiente.php +++ b/Model/Config/Source/Ambiente.php @@ -7,6 +7,6 @@ class Ambiente * @var string[] */ public function toOptionArray() { - return [['value' => 'production', 'label' => __('Produção')], ['value' => 'dev', 'label' => __('Desenvolvimento')],]; + return [['value' => 'production', 'label' => __('Production')], ['value' => 'dev', 'label' => __('Development')],]; } } diff --git a/Model/Config/Source/Discount.php b/Model/Config/Source/Discount.php index eaff564..81c716d 100644 --- a/Model/Config/Source/Discount.php +++ b/Model/Config/Source/Discount.php @@ -8,8 +8,8 @@ class Discount { * @var string[] */ public function toOptionArray() { return [ - ['value' => 'FIXED', 'label' => __('Valor Fixo')], - ['value' => 'PERCENTAGE', 'label' => __('Percentual')], + ['value' => 'FIXED', 'label' => __('Fixed Value')], + ['value' => 'PERCENTAGE', 'label' => __('Percentage')], ]; } } diff --git a/Model/Payment/Boleto.php b/Model/Payment/Boleto.php index 97a1519..ea83b81 100755 --- a/Model/Payment/Boleto.php +++ b/Model/Payment/Boleto.php @@ -26,15 +26,15 @@ public function __construct( \Magento\Payment\Helper\Data $paymentData, \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, \Magento\Payment\Model\Method\Logger $logger, - \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null, - \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null, - array $data = [], \Asaas\Magento2\Helper\Data $helper, \Magento\Checkout\Model\Session $checkout, \Magento\Store\Model\StoreManagerInterface $store, \Magento\Framework\Message\ManagerInterface $message, \Magento\Framework\Encryption\EncryptorInterface $encryptor, - \Magento\Customer\Model\Customer $customerRepositoryInterface + \Magento\Customer\Model\Customer $customerRepositoryInterface, + \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null, + \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null, + array $data = [] ) { parent::__construct( $context, diff --git a/Model/Payment/Cc.php b/Model/Payment/Cc.php index fcd79bd..8f10c63 100755 --- a/Model/Payment/Cc.php +++ b/Model/Payment/Cc.php @@ -31,14 +31,14 @@ public function __construct( \Magento\Payment\Helper\Data $paymentData, \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, \Magento\Payment\Model\Method\Logger $logger, - \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null, - \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null, - array $data = [], \Asaas\Magento2\Helper\Data $helper, \Magento\Checkout\Model\Session $checkout, \Magento\Framework\Message\ManagerInterface $messageManager, \Magento\Framework\Encryption\EncryptorInterface $encryptor, - \Magento\Customer\Model\Customer $customerRepositoryInterface + \Magento\Customer\Model\Customer $customerRepositoryInterface, + \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null, + \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null, + array $data = [] ) { parent::__construct( $context, diff --git a/Model/Payment/Pix.php b/Model/Payment/Pix.php new file mode 100644 index 0000000..e8ee630 --- /dev/null +++ b/Model/Payment/Pix.php @@ -0,0 +1,265 @@ +helperData = $helper; + $this->checkoutSession = $checkout; + $this->store = $store; + $this->messageInterface = $message; + $this->_decrypt = $encryptor; + $this->_customerRepositoryInterface = $customerRepositoryInterface; + } + + public function isAvailable(\Magento\Quote\Api\Data\CartInterface $quote = null) { + if (!$this->helperData->getStatusBillet()) { + return false; + } + return parent::isAvailable($quote); + } + + public function order(\Magento\Payment\Model\InfoInterface $payment, $amount) { + try { + //Pegando informações adicionais do pagamento (CPF) (Refatorar) + $info = $this->getInfoInstance(); + $paymentInfo = $info->getAdditionalInformation(); + $discount = $this->helperData->getDiscout(); + + $days = $this->helperData->getDays(); + $date = new \DateTime("+$days days"); + $notification = $this->helperData->getNotifications(); + + //pegando dados do pedido do cliente + $order = $payment->getOrder(); + $shippingaddress = $order->getBillingAddress(); + + if (!isset($shippingaddress->getStreet()[2])) { + throw new \Exception("Por favor, preencha seu endereço corretamente.", 1); + } + + //Verifica a existência do usuário na Asaas obs: colocar cpf aqui + $user = (array)$this->userExists($paymentInfo['pix_cpf']); + if (!$user) { + throw new \Exception("Por favor, verifique suas Credenciais (Ambiente, ApiKey)", 1); + } + if (count($user['data']) >= 1) { + $currentUser = $user['data'][0]->id; + } else { + //Pega os dados do usuário necessários para a criação da conta na Asaas + $dataUser['name'] = $shippingaddress->getFirstName() . ' ' . $shippingaddress->getLastName(); + $dataUser['email'] = $shippingaddress->getEmail(); + $dataUser['cpfCnpj'] = $paymentInfo['pix_cpf']; + $dataUser['postalCode'] = $shippingaddress->getPostcode(); + + //Habilita notificações entre o Asaas e o comprador + if (isset($notification)) { + $dataUser['notificationDisabled'] = 'false'; + } else { + $dataUser['notificationDisabled'] = 'true'; + } + + //Verifica se foi informado o número foi informado + if (isset($shippingaddress->getStreet()[1])) { + $dataUser['addressNumber'] = $shippingaddress->getStreet()[1]; + } + + $newUser = (array)$this->createUser($dataUser); + if (!$newUser) { + throw new \Exception("Por favor, verifique suas Credenciais (Ambiente, ApiKey)", 1); + } + $currentUser = $newUser['id']; + } + + //Monta os dados para uma cobrança com pix + $request['customer'] = $currentUser; + $request['billingType'] = "PIX"; + $request['value'] = $amount; + $request['externalReference'] = $order->getIncrementId(); + $request['dueDate'] = $date->format('Y-m-d'); + $request['description'] = "Pedido " . $order->getIncrementId(); + $request['origin'] = 'Magento'; + + //Informações de Desconto + $request['discount']['value'] = $discount['value_discount']; + $request['discount']['type'] = $discount['type_discount']; + $request['discount']['dueDateLimitDays'] = $discount['due_limit_days']; + + //Informações de Multa + $request['interest']['value'] = $this->helperData->getInterest(); + + //Informações de juros + $request['fine']['value'] = $this->helperData->getFine(); + + $paymentDone = (array)$this->doPayment($request); + if (isset($paymentDone['errors'])) { + throw new \Exception($paymentDone['errors'][0]->description, 1); + } + + $qrCode = (array)$this->getQrCode($paymentDone['id']); + + if (!isset($qrCode['encodedImage']) || !isset($qrCode['payload'])) { + throw new \Exception($paymentDone['errors'][0]->description, 1); + } + + $this->checkoutSession->setPixQrCode($qrCode['encodedImage']); + $this->checkoutSession->setPixPayload($qrCode['payload']); + + $order->setData('pix_asaas_qrcode', $qrCode['encodedImage']); + $order->setData('pix_asaas_payload', $qrCode['payload']); + $order->save(); + + } catch (\Exception $e) { + throw new \Magento\Framework\Exception\LocalizedException(__($e->getMessage())); + } + } + + public function assignData(\Magento\Framework\DataObject $data) { + $info = $this->getInfoInstance(); + $info->setAdditionalInformation('pix_cpf', $data['additional_data']['pix_cpf'] ?? null); + return $this; + } + + public function userExists($cpf) { + $curl = curl_init(); + + curl_setopt_array($curl, array( + CURLOPT_URL => $this->helperData->getUrl() . "/api/v3/customers?cpfCnpj=" . $cpf, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_ENCODING => "", + CURLOPT_MAXREDIRS => 10, + CURLOPT_TIMEOUT => 0, + CURLOPT_FOLLOWLOCATION => true, + CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, + CURLOPT_CUSTOMREQUEST => "GET", + CURLOPT_HTTPHEADER => array( + "access_token: " . $this->_decrypt->decrypt($this->helperData->getAcessToken()), + "Content-Type: application/json" + ), + )); + + $response = curl_exec($curl); + + curl_close($curl); + return json_decode($response); + } + + public function createUser($data) { + $curl = curl_init(); + + curl_setopt_array($curl, array( + CURLOPT_URL => $this->helperData->getUrl() . "/api/v3/customers", + CURLOPT_RETURNTRANSFER => true, + CURLOPT_ENCODING => "", + CURLOPT_MAXREDIRS => 10, + CURLOPT_TIMEOUT => 0, + CURLOPT_FOLLOWLOCATION => true, + CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, + CURLOPT_CUSTOMREQUEST => "POST", + CURLOPT_POSTFIELDS => json_encode($data), + CURLOPT_HTTPHEADER => array( + "access_token: " . $this->_decrypt->decrypt($this->helperData->getAcessToken()), + "Content-Type: application/json" + ), + )); + + $response = curl_exec($curl); + + curl_close($curl); + return json_decode($response); + } + public function doPayment($data) { + $curl = curl_init(); + + curl_setopt_array($curl, array( + CURLOPT_URL => $this->helperData->getUrl() . "/api/v3/payments", + CURLOPT_RETURNTRANSFER => true, + CURLOPT_ENCODING => "", + CURLOPT_MAXREDIRS => 10, + CURLOPT_TIMEOUT => 0, + CURLOPT_FOLLOWLOCATION => true, + CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, + CURLOPT_CUSTOMREQUEST => "POST", + CURLOPT_POSTFIELDS => json_encode($data), + CURLOPT_HTTPHEADER => array( + "access_token: " . $this->_decrypt->decrypt($this->helperData->getAcessToken()), + "Content-Type: application/json" + ), + )); + + $response = curl_exec($curl); + + curl_close($curl); + + return json_decode($response); + } + + public function getQrCode($paymentId) { + $curl = curl_init(); + + curl_setopt_array($curl, array( + CURLOPT_URL => $this->helperData->getUrl() . "/api/v3/payments/{$paymentId}/pixQrCode", + CURLOPT_RETURNTRANSFER => true, + CURLOPT_ENCODING => "", + CURLOPT_MAXREDIRS => 10, + CURLOPT_TIMEOUT => 0, + CURLOPT_FOLLOWLOCATION => true, + CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, + CURLOPT_CUSTOMREQUEST => "GET", + CURLOPT_HTTPHEADER => array( + "access_token: " . $this->_decrypt->decrypt($this->helperData->getAcessToken()), + "Content-Type: application/json" + ), + )); + + $response = curl_exec($curl); + + curl_close($curl); + + return json_decode($response); + } +} diff --git a/Model/UpdateStatuses.php b/Model/UpdateStatuses.php index c6f0664..7a082f2 100755 --- a/Model/UpdateStatuses.php +++ b/Model/UpdateStatuses.php @@ -1,78 +1,107 @@ orderFactory = $orderFactory; + $this->orderFactory = $orderFactory; $this->orderRepository = $orderRepository; - $this->helperData = $helper; + $this->helperData = $helper; } - /** - * Post Company. - * - * @api - * @param mixed $event + /** + * @param mixed $event * @param mixed $payment - * @return mixed + * @return false|string + * @api */ - public function doUpdate($event, $payment) { - + public function doUpdate($event, $payment) + { $token_magento = $this->helperData->getTokenWebhook(); $asaas_token = apache_request_headers(); - if ((isset($asaas_token['Asaas-Access-Token']) && isset($token_magento))) { - if ($token_magento !== $asaas_token['Asaas-Access-Token']) { - throw new \Magento\Framework\Webapi\Exception(__("Token Webhook inválido. Favor veriricar!"), 0, \Magento\Framework\Webapi\Exception::HTTP_UNAUTHORIZED); + try { + if ((isset($asaas_token['Asaas-Access-Token']) && isset($token_magento))) { + if ($token_magento !== $asaas_token['Asaas-Access-Token']) { + throw new \Magento\Framework\Webapi\Exception( + __("Token Webhook not valid."), + 0, + \Magento\Framework\Webapi\Exception::HTTP_UNAUTHORIZED); + } + $this->updateOrder($event, $payment); } - $this->updateOrder($event, $payment); - } else if ((!isset($asaas_token['Asaas-Access-Token']) && !isset($token_magento))) { - $this->updateOrder($event, $payment); - } else { - throw new \Magento\Framework\Webapi\Exception(__("Token Webhook inválido. Favor veriricar!"), 0, \Magento\Framework\Webapi\Exception::HTTP_UNAUTHORIZED); + else if ((!isset($asaas_token['Asaas-Access-Token']) && !isset($token_magento))) { + $this->updateOrder($event, $payment); + } + else { + throw new \Magento\Framework\Webapi\Exception( + __("Token Webhook not valid."), + 0, + \Magento\Framework\Webapi\Exception::HTTP_UNAUTHORIZED); + } + $response = ['request' => 'successful', 'dataRequest' => ['externalReference' => $payment['externalReference']]]; + } catch (\Exception $e) { + $response = ['request' => ['error' => ['error' => true, 'message' => $e->getMessage()]]]; } + + return json_encode($response); } - private function updateOrder($event, $payment) { - $paymentobj = (array) $payment; - $orderId = $this->orderFactory->create()->loadByIncrementId($paymentobj['externalReference']); - if (!$orderId->getId()) { - throw new \Magento\Framework\Webapi\Exception(__("Order Id not found"), 0, \Magento\Framework\Webapi\Exception::HTTP_NOT_FOUND); - } - if ($event == "PAYMENT_CONFIRMED" or $event == "PAYMENT_RECEIVED") { - $order = $this->orderRepository->get($orderId->getId()); - $order->setState(\Magento\Sales\Model\Order::STATE_PROCESSING); - $order->setStatus(\Magento\Sales\Model\Order::STATE_PROCESSING); - $this->orderRepository->save($order); - } elseif ( - $event == "PAYMENT_OVERDUE" or - $event == "PAYMENT_DELETED" or - $event == "PAYMENT_RESTORED" or - $event == "PAYMENT_REFUNDED" or - $event == "PAYMENT_AWAITING_CHARGEBACK_REVERSAL" - ) { - $order = $this->orderRepository->get($orderId->getId()); - $order->setState(\Magento\Sales\Model\Order::STATE_CANCELED); - $order->setStatus(\Magento\Sales\Model\Order::STATE_CANCELED); + /** + * @param $event + * @param $payment + * @return \Magento\Sales\Model\Order + * @throws \Magento\Framework\Webapi\Exception + */ + private function updateOrder($event, $payment) + { + try { + $paymentObj = (array)$payment; + $order = $this->orderFactory->create()->loadByIncrementId($paymentObj['externalReference']); + $orderId = $order->getId(); + + if (!$orderId) { + throw new \Magento\Framework\Webapi\Exception( + __("Order Id not found"), + 0, + \Magento\Framework\Webapi\Exception::HTTP_NOT_FOUND); + } + + switch ($event) { + case "PAYMENT_CONFIRMED": + case "PAYMENT_RECEIVED": + $order->setState(\Magento\Sales\Model\Order::STATE_PROCESSING); + $order->setStatus(\Magento\Sales\Model\Order::STATE_PROCESSING); + break; + + case "PAYMENT_OVERDUE": + case "PAYMENT_DELETED": + case "PAYMENT_RESTORED": + case "PAYMENT_REFUNDED": + case "PAYMENT_AWAITING_CHARGEBACK_REVERSAL": + $order->setState(\Magento\Sales\Model\Order::STATE_CANCELED); + $order->setStatus(\Magento\Sales\Model\Order::STATE_CANCELED); + break; + } + $this->orderRepository->save($order); - return http_response_code(200); + + return $order; + } catch (\Exception $e) { + throw new \Magento\Framework\Webapi\Exception(__($e->getMessage())); } } } diff --git a/README-en.md b/README-en.md new file mode 100644 index 0000000..73f94f1 --- /dev/null +++ b/README-en.md @@ -0,0 +1,131 @@ +# Integration Module [Asaas Payments](https://www.asaas.com/) + +## Installation + +> We recommend having a test environment to validate changes and updates before updating your production store. Also, make sure to create a backup with all information before executing any update/installation procedures. + +### Compatible Versions + +- [x] 2.3.x +- [x] 2.4.x + +### Prerequisite + +- PHP version must be at least 7.1.X. + +### Asaas Module Installation + +- Download the module by cloning this repository, and follow the steps below according to how your store was installed: + +### Install using Composer + +1. Install via packagist + - ```composer require asaas/module-magento2``` + - At this point, your Magento authentication credentials may be requested. If you have any questions, there is a description of how to proceed in this [official documentation link](http://devdocs.magento.com/guides/v2.0/install-gde/prereq/connect-auth.html). +2. Run the commands: + - ```php bin/magento setup:upgrade``` + - ```php bin/magento setup:static-content:deploy``` ou ```php bin/magento setup:static-content:deploy pt_BR```, according to your store's configurations. + +### Install using GitHub + +- If your store was created through the clone or download of the Magento project, follow these steps: + +1. Extract the contents of the ZIP download and move it to ```Asaas/Magento2/``` folder. +2. Check if your directories in your store are like this: `app/code/Asaas/Magento2`. +3. Run the command ```bin/magento setup:upgrade``` +4. Run the command ```bin/magento setup:di:compile``` +5. Run the command ```bin/magento setup:static-content:deploy -f``` +6. Run the command ```bin/magento cache:clean``` + + +### Settings + +Access the Magento Admin Panel and through the the left menu go to `Stores` > `Configuration` > `Customers` > `Customer Configuration` > `Name and Address Options`. In `Number of Lines in a Street Address` you should inform the number 4, as shown in the image below: + +![FOTO 1](.github/img/01.png) + +After configuring the Customer, Access the Magento Admin Panel and through the the left menu go to `Stores` > `Configuration` > `Sales` > `Payment Methods`. The screen to configure the payment methods of the store will be loaded. + +

+ +

+ +### How to enable Asaas on your site + +In the first information block, there is the configuration to enable or disable the module completely, check `Yes` to continue the configuration. + +Next, we have `General Settings`, `Credit Card Settings`, `Billet Settings` and `Pix Settings`. + +Note: For the following settings to work, all the previous steps must have been followed. + +![FOTO 3](.github/img/03.png) + + +### General Settings + +- Api Key + - Asaas account integration key. Production and sandbox tokens are distinct. + + - Debug + - Enables or disables debug functionality. + +- Environment + - Selects which environment version the site will be pointing to. The available environments are: Desenvolvimento (Development) and Produção (Production). + +- URL for Billing Webhooks + - URL to be informed in the billing webhook on the Asaas website, so that at the moment of payment approval, the order status is changed. + +- Display Order + - Display order of the enabled payment methods in the module being shown on the Checkout screen. + +- Authentication Token + - Token to authenticate requests coming from the Asaas Webhook. + +- Enable notifications between Asaas and buyer + - Enables email messages informing payment status changes. This option can be enabled or not. + +![FOTO 4](.github/img/04.png) + +### Credit Card Settings + +- Enabled + - Enables or disables the credit card payment method. + +- Payment Installments + - Set maximum number of allowed installments and percentage of interest to each installment. + +- Available Card Brands + - Select credit card brands supported by the store for payment. + +- Minimum installment amount + - Set the minimum installment amount allowed + +![FOTO 5](.github/img/05.png) + +### Billet Settings + +- Enabled + - Enables or disables the billet payment method. + +- Billet validity days + - Gets the current date and adds the requested number of days to the billet expiration. + +- Message to user + - Message displayed on the thank you screen after completing the order. + +- Discount Settings, Interest Settings, and Fine Settings allow you to set the discounts, interest, and fines of the billet, respectively. + +![FOTO 6](.github/img/06.png) + +### Pix Settings + +- Enabled + - Enables or disables the pix payment method. + +- Pix expiration days + - Gets the current date and adds the requested number of days to the QR Code expiration. + +- Message to user + - Message displayed on the thank you screen after completing the order. + +![FOTO 7](.github/img/07.png) diff --git a/README.md b/README.md index 501e038..ec2ab1f 100755 --- a/README.md +++ b/README.md @@ -1,50 +1,49 @@ -# Módulo de integração [Asaas Pagamentos](https://www.asaas.com/) +# Módulo de Integração [Asaas Payments](https://www.asaas.com/) ## Instalação -> Recomendamos que você possua um ambiente de testes para validar as alterações e atualizações antes de atualiar sua loja em produção. Também que seja feito um **backup** com todas as informações antes de executar qualquer procedimento de atualização/instalação. +> Recomendamos ter um ambiente de teste para validar alterações e atualizações antes de atualizar sua loja de produção. Além disso, certifique-se de criar um backup com todas as informações antes de executar qualquer procedimento de atualização/instalação. -### Versões Compativeis: +### Versões Compatíveis - [x] 2.3.x - [x] 2.4.x - -### Pré requisito: -- Requer a que o PHP esteja no mínimo na versão 7.1.X. +### Pré-requisitos -### Instalação do Módulo Asaas: +- A versão do PHP deve ser pelo menos 7.1.X. -- Realize o download do módulo, clonando esse repositório, e siga os seguintes passos de acordo com a forma que sua loja foi instalada: +### Instalação do Módulo Asaas -### Instalar usando o Composer +- Baixe o módulo clonando este repositório e siga os passos abaixo de acordo com a forma como sua loja foi instalada: -1. Instale via packagist +### Instalar usando Composer + +1. Instale via packagist - ```composer require asaas/module-magento2``` - - Neste momento, podem ser solicitadas suas credenciais de autenticação do Magento. Caso tenha alguma dúvida, há uma descrição de como proceder nesse [link da documentação oficial](http://devdocs.magento.com/guides/v2.0/install-gde/prereq/connect-auth.html). + - Nesse momento, suas credenciais de autenticação do Magento podem ser solicitadas. Se você tiver alguma dúvida, há uma descrição de como proceder neste [link da documentação oficial](http://devdocs.magento.com/guides/v2.0/install-gde/prereq/connect-auth.html). 2. Execute os comandos: - ```php bin/magento setup:upgrade``` - ```php bin/magento setup:static-content:deploy``` ou ```php bin/magento setup:static-content:deploy pt_BR```, de acordo com as configurações da sua loja. - ### Instalar usando o github +### Instalar usando GitHub -- Caso sua loja tenha sido criada por meio do clone ou download do projeto magento, siga os seguintes passos: +- Se sua loja foi criada através do clone ou download do projeto Magento, siga estes passos: -1. Extraia o conteúdo do download ZIP e mova o para ```\Magento2\``` para dentro da pasta ```Asaas``` -2. Verifique se está dessa maneira seus diretórios na sua loja ```app/code/Asaas/Magento2``` +1. Extraia o conteúdo do download ZIP e mova-o para a pasta ```Asaas/Magento2/```. +2. Verifique se os diretórios na sua loja estão assim: `app/code/Asaas/Magento2`. 3. Execute o comando ```bin/magento setup:upgrade``` 4. Execute o comando ```bin/magento setup:di:compile``` 5. Execute o comando ```bin/magento setup:static-content:deploy -f``` 6. Execute o comando ```bin/magento cache:clean``` - ### Configurações -Acesse no Painel Administrativo do Magento no menu lateral clique em `Lojas`, depois clique em `Configuração`, na sequencia clique em `Clientes`, depois `Configurações de Cliente`, depois acesse a opção `Opções de Nome e Endereço`. Em `Número de Linhas em Endereço` você deve informar o número 4, conforme imagem abaixo: +Acesse o Painel Administrativo do Magento e, através do menu à esquerda, vá para `Stores` > `Configuration` > `Customers` > `Customer Configuration` > `Name and Address Options`. Em `Number of Lines in a Street Address` você deve informar o número 4, conforme mostrado na imagem abaixo: ![FOTO 1](.github/img/01.png) -Após realizar a configuração do Cliente, acesse no Painel Administrativo do Magento No menu lateral clique em `Lojas`, na sequencia clique em `Configuração`, no sub-menu `Vendas` clique em `Formas de Pagamento`. Será carregada a tela para configurar os meios de pagamentos do site. +Após configurar o Cliente, acesse o Painel Administrativo do Magento e, através do menu à esquerda, vá para `Stores` > `Configuration` > `Sales` > `Payment Methods`. A tela para configurar os métodos de pagamento da loja será carregada.

@@ -52,62 +51,79 @@ Após realizar a configuração do Cliente, acesse no Painel Administrativo do M ### Como habilitar o Asaas no seu site -No primeiro bloco de informação, está a configuração para habilitar ou desabilitar o módulo por completo, marque `Sim` para continuar a configuração. +No primeiro bloco de informações, há a configuração para habilitar ou desabilitar o módulo completamente, marque `Yes` para continuar a configuração. -Em seguida temos as configurações gerais, configurações de cartão de crédito e configurações de boleto +Em seguida, temos `General Settings`, `Credit Card Settings`, `Billet Settings` e `Pix Settings`. -OBS: Para que todas as configurações a seguir funcionem, todo o passo a passo anterior deve ter sido seguido. - -![FOTO 3](.github/img/03.png) +Nota: Para que as configurações a seguir funcionem, todos os passos anteriores devem ter sido seguidos. +![FOTO 3](.github/img/03.png) ### Configurações Gerais - Api Key - - Chave de integração da conta Asaas. Os tokens de produção e sandbox são distintos. + - Chave de integração da conta Asaas. Tokens de produção e sandbox são distintos. + +- Debug + - Habilita ou desabilita a funcionalidade de debug. -- Ambiente - - Seleciona qual versão de ambiente que o site estará apontando. Os ambientes disponíveis são: ```Desenvolvimento``` e ```Produção```. - +- Environment + - Seleciona qual versão do ambiente o site estará apontando. Os ambientes disponíveis são: Desenvolvimento e Produção. -- URL para Webhooks de cobrança - - URL a ser informada no Webhook de cobrança no site da Asaas, para que no momento de aprovação do pagamento, o status do pedido seja alterado. - -- Ordem de exibição +- URL para Webhooks de Cobrança + - URL a ser informada no webhook de cobrança no site do Asaas, para que no momento da aprovação do pagamento o status do pedido seja alterado. + +- Display Order - Ordem de exibição dos métodos de pagamento habilitados no módulo sendo mostrados na tela de Checkout. - + +- Authentication Token + - Token para autenticar solicitações provenientes do Webhook do Asaas. + - Habilitar notificações entre Asaas e comprador - - Habilita mensagens via e-mail informando as alterações de status de pagamento. Podendo esta opção ser habilitada ou não. + - Habilita mensagens de email informando alterações no status do pagamento. Esta opção pode ser habilitada ou não. ![FOTO 4](.github/img/04.png) -### Configurações Cartão de Crédito +### Configurações de Cartão de Crédito -- Habilitado - - Habilita ou desabilita o método de pagamento com cartão de cŕedito. +- Enabled + - Habilita ou desabilita o método de pagamento por cartão de crédito. -- Parcelas - - Este campo além de trazer a quantidade máxima de parceamento permitida, também já adiciona um percentual de juros em cada parcela caso o cliente opte. +- Parcelamento + - Define o número máximo de parcelas permitidas e a porcentagem de juros para cada parcela. -- Tipo do Cartão de Crédito - - Seleciona e exibe no formulário de cartão de crédito as bandeiras disponíveis para pagamento. +- Bandeiras Disponíveis + - Seleciona as bandeiras de cartão de crédito suportadas pela loja para pagamento. -![FOTO 5](.github/img/05.png) - -

- -

+- Valor mínimo da parcela + - Define o valor mínimo da parcela permitido. +![FOTO 5](.github/img/05.png) ### Configurações de Boleto -- Habilitado - - Habilita ou desabilita o método de pagamento com boleto. +- Enabled + - Habilita ou desabilita o método de pagamento por boleto. - Dias de validade do boleto - - Pega a data atual, e adiciona a quantidade solicitada de dias para o vencimento do boleto. + - Obtém a data atual e adiciona o número de dias solicitados para a expiração do boleto. -- Instruções ao usuário - - Mensagem exibida na tela de agradecimento após finalização do pedido. +- Mensagem para o usuário + - Mensagem exibida na tela de agradecimento após a conclusão do pedido. + +- Configurações de Desconto, Configurações de Juros e Configurações de Multa permitem definir os descontos, juros e multas do boleto, respectivamente. ![FOTO 6](.github/img/06.png) + +### Configurações de Pix + +- Enabled + - Habilita ou desabilita o método de pagamento por Pix. + +- Dias de validade do Pix + - Obtém a data atual e adiciona o número de dias solicitados para a expiração do QR Code. + +- Mensagem para o usuário + - Mensagem exibida na tela de agradecimento após a conclusão do pedido. + +![FOTO 7](.github/img/07.png) \ No newline at end of file diff --git a/Setup/UpgradeSchema.php b/Setup/UpgradeSchema.php index 488fd44..3e456a9 100755 --- a/Setup/UpgradeSchema.php +++ b/Setup/UpgradeSchema.php @@ -23,6 +23,26 @@ public function upgrade(SchemaSetupInterface $setup, ModuleContextInterface $con 'nullable' => true, 'comment' => 'Boleto asaas' ] + ); + $setup->getConnection()->addColumn( + $setup->getTable($orderTable), + 'pix_asaas_qrcode', + [ + 'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT, + 'default' => null, + 'nullable' => true, + 'comment' => 'Pix Asaas Qrcode' + ] + ); + $setup->getConnection()->addColumn( + $setup->getTable($orderTable), + 'pix_asaas_payload', + [ + 'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT, + 'default' => null, + 'nullable' => true, + 'comment' => 'Pix Asaas Payload' + ] ); $setup->endSetup(); diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml index 8449380..5c211e2 100755 --- a/etc/adminhtml/system.xml +++ b/etc/adminhtml/system.xml @@ -2,35 +2,35 @@
- - - - - Ativar ou desativar o módulo por completo. + + + + Activate or deactivate entire module. Magento\Config\Model\Config\Source\Yesno + 1 - - - + + + Asaas\Magento2\Block\System\Config\Form\Field\Disable - acesse a Aba Integração na área Minha Conta e informe a URL da sua aplicação que deve receber o POST do Asaas. Lembre-se de selecionar a versão da API "v3" ao habilitar o webhook. Clique aqui para a documentação oficial do Asaas]]> + access the Integration Tab in the My Account area and enter the URL of your application that should receive the POST from Asaas. Remember to select API version "v3" when enabling the webhook. Click here for the official Asaas documentation]]> - + - acesse a Aba Integração na área Minha Conta. Clique aqui para a documentação oficial do Asaas]]> + access the Integration Tab in the My Account area. Click here for the official Asaas documentation]]> required-entry Magento\Config\Model\Config\Backend\Encrypted 1 - - - aqui para a documentação oficial do Asaas]]> + + + here for the official Asaas documentation]]> 1 @@ -43,42 +43,42 @@ - + Asaas\Magento2\Model\Config\Source\Ambiente 1 - - - Habilita notificações ao ser realizado uma compra. + + + Enable notifications when a purchase is made. Magento\Config\Model\Config\Source\Yesno 1 - - - Ordem de exibição em relação a outras formas de pagamento. + + + Display order in relation to other payment methods. 1 - + 1 - + - + Magento\Config\Model\Config\Source\Yesno - - - Deve ser usado ponto. Ex: 1.99 ou 5.75 + + + Decimal point should be used. Example: 1.99 or 5.75. Asaas\Magento2\Block\Adminhtml\Form\Field\Parcelas Magento\Config\Model\Config\Backend\Serialized\ArraySerialized @@ -87,14 +87,14 @@ required-entry - + Asaas\Magento2\Model\Config\Source\Tipos 1 - + 1 @@ -102,35 +102,38 @@ - + - + 1 - + Magento\Config\Model\Config\Source\Yesno - + required-entry 1 - - - Mensagem exibida na tela de agradecimento após finalização do pedido. + + + Message displayed on the thank you screen after completing the order. 1 - - - - Valor fixo ou Percentual + + + 1 + + + + Fixed value or percentage Asaas\Magento2\Model\Config\Source\Discount 1 @@ -138,15 +141,15 @@ required-entry - + 1 required-entry - - - Dias antes do vencimento para aplicar desconto. Ex: 0 = até o vencimento, 1 = até um dia antes, 2 = até dois dias antes, e assim por diante + + + Days before due date to apply discount. Example: 0 = until due date, 1 = up to one day before, 2 = up to two days before, and so on 1 @@ -154,29 +157,61 @@ - - - + + + 1 + + + required-entry 1 - Percentual de juros ao mês sobre o valor da cobrança para pagamento após o vencimento + Percentage of interest per month on the amount charged for payment after maturity - - - + + + 1 + + + required-entry 1 - Percentual de multa sobre o valor da cobrança para pagamento após o vencimento + Percentage of fine on the amount of the charge for payment after the due date + + + + + 1 + + + + Magento\Config\Model\Config\Source\Yesno + + + + required-entry + + 1 + + + + + Message displayed on the thank you screen after completing the order. + + 1 + + + +
diff --git a/etc/config.xml b/etc/config.xml index 155b253..6453611 100755 --- a/etc/config.xml +++ b/etc/config.xml @@ -2,6 +2,28 @@ + + + + 0.00 + + + 0 + + 0.00 + 0 + + + 0 + + + 0 + + + + 0 + + order Asaas\Magento2\Model\Payment\Cc @@ -18,6 +40,14 @@ Boleto 0 + + 1 + Asaas\Magento2\Model\Payment\Pix + holded + order + Pix + 0 + diff --git a/etc/module.xml b/etc/module.xml index 4121ddb..215ba77 100755 --- a/etc/module.xml +++ b/etc/module.xml @@ -1,6 +1,6 @@ - + diff --git a/etc/payment.xml b/etc/payment.xml index 4862ba5..dd75df3 100755 --- a/etc/payment.xml +++ b/etc/payment.xml @@ -12,5 +12,8 @@ 0 + + 0 + diff --git a/i18n/pt_BR.csv b/i18n/pt_BR.csv new file mode 100644 index 0000000..2b2b709 --- /dev/null +++ b/i18n/pt_BR.csv @@ -0,0 +1,95 @@ +Yes,Sim +No,Não +Add,Adicionar +Production,Produção +Development,Desenvolvimento +Installments,Parcelas +"Fixed Value","Valor Fixo" +Percentage,Percentual +"Token Webhook not valid.","Token de Webhook inválido." +"Order Id not found","Id do pedido não encontrado" +Action,Ação +"Add after","Adicionar depois" +Delete,Remover +"Credit Card Type","Tipo de Cartão de Crédito" +"--Please Select--","--Favor Selecionar--" +"Credit Card Number2","Número do Cartão de Crédito2" +"Expiration Date","Data de Validade" +"Card Verification Number","Código de Verificação do Cartão" +"Card Verification Number Visual Reference","Referência Visual do Código de Verificação do Cartão" +"What is this?","O que é isso?" +"* Required Fields","* Campos Obrigatórios" +"Account Information","Informação da conta" +"Change Email","Trocar Email" +"Change Password","Rrocar Senha" +"Change Email and Password","Trocar Email e Senha" +"Current Password","Senha Atual" +"New Password","Senha Nova" +"Password Strength","Força da Senha" +"No Password","Sem Senha" +"Confirm New Password","Confirmar Senha Nova" +Save,Salvar +"Go back","Voltar" +"Personal Information","Informações Pessoais" +"Sign Up for Newsletter","Inscreva-se no Boletim Informativo" +"Address Information","Informação de Endereço" +Address,Endereço +"Street Address %1","Rua %1" +"Please select a region, state or province.","Selecione uma região, estado ou província." +"Sign-in Information","Informações de login" +Password,Senha +"Confirm Password","Confirmar Senha" +"Create an Account","Criar uma Conta" +Back,Voltar +"Payment Pix Information","Informações sobre Pix de Pagamento" +"Copy PIX","Copiar PIX" +"'Your order number is: ' .","'Seu número de pedido é: ' ." +"Your order # is: %1.","Seu # de pedido é: %1." +"Place Order","Realizar Pedido" +"Credit Card Information","Informações do Cartão de Crédito" +"Credit Card Owner Name","Nome do Proprietário do Cartão de Crédito" +Phone,Telefone +"Credit Card Number","Número do Cartão de Crédito" +Month,Mês +Year,Ano +Select,Selecionar +"Asaas Payments","Asaas Pagamentos" +Active,Ativo +"Activate or deactivate entire module.","Ativar ou desativar o módulo inteiro." +"General Settings","Configurações Gerais" +"URL for Billing Webhooks","URL para Webhooks de Faturamento" +"To enable the webhook, access the Integration Tab in the My Account area and enter the URL of your application that should receive the POST from Asaas. Remember to select API version ""v3"" when enabling the webhook. Click here for the official Asaas documentation","Para habilitar o webhook, acesse a Aba Integração na área Minha Conta e informe a URL da sua aplicação que deve receber o POST do Asaas. Lembre-se de selecionar a versão da API ""v3"" ao habilitar o webhook. Clique aqui para a documentação oficial do Asaas" +"API Key","Chave da API" +"To obtain your API Key access the Integration Tab in the My Account area. Click here for the official Asaas documentation","Para obter sua chave da API acesse a Aba Integração na área Minha Conta. Clique aqui para a documentação oficial do Asaas" +"Authentication Token","Token de Autenticação" +"A token to authenticate requests coming from the Asaas Webhook. This token can be entered in the My Account area, Integration tab. Click here for the official Asaas documentation","Um token para autenticar as requisições vindas do Webhook do Asaas. Este token pode ser informado na área Minha Conta, aba Integração. Clique aqui para a documentação oficial do Asaas" +Debug,Debug +Environment,Ambiente +"Enable notifications between Asaas and buyer","Ativar notificações entre a Asaas e o comprador" +"Enable notifications when a purchase is made.","Ativar notificações quando uma compra é feita." +"Display order","Ordem de exibição" +"Display order in relation to other payment methods.","Ordem de exibição em relação a outras formas de pagamento." +"Credit Card Settings","Configurações do Cartão de Crédito" +Enabled,Habilitado +"Payment Installments","Parcelas" +"Decimal point should be used. Example: 1.99 or 5.75.","Deve ser usado ponto. Ex: 1.99 ou 5.75." +"Available Card Brands","Bandeiras de Cartões Disponíveis" +"Minimum installment amount","Valor mínimo da parcela" +"Billet Settings","Configurações de Boleto" +"Billet validity days","Dias de validade do boleto" +"Message to user","Mensagem ao usuário" +"Message displayed on the thank you screen after completing the order.","Mensagem exibida na tela de agradecimento após finalização do pedido." +"Discount Settings","Configurações de Desconto" +"Discount Type","Tipo do Desconto" +"Fixed value or percentage","Valor fixo ou Percentual" +"Discount Value","Valor do Desconto" +"Valid days to apply the discount","Dias Válidos para aplicar o Desconto" +"Days before due date to apply discount. Example: 0 = until due date, 1 = up to one day before, 2 = up to two days before, and so on","Dias antes do vencimento para aplicar desconto. Ex: 0 = até o vencimento, 1 = até um dia antes, 2 = até dois dias antes, e assim por diante" +"Interest Settings","Configurações de Juros" +"Interest Percentage","Percentual de Juros" +"Percentage of interest per month on the amount charged for payment after maturity","Percentual de juros ao mês sobre o valor da cobrança para pagamento após o vencimento" +"Fine Settings","Configurações de Multa" +"Fine Percentage","Percentual de Multa" +"Percentage of fine on the amount of the charge for payment after the due date","Percentual de multa sobre o valor da cobrança para pagamento após o vencimento" +"Pix Settings","Configurações de Pix" +"Pix expiration days","Dias de validade do pix" diff --git a/view/adminhtml/layout/sales_order_view.xml b/view/adminhtml/layout/sales_order_view.xml new file mode 100644 index 0000000..44a7195 --- /dev/null +++ b/view/adminhtml/layout/sales_order_view.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/view/adminhtml/templates/form/array.phtml b/view/adminhtml/templates/form/array.phtml index 1b94a22..8a42a13 100755 --- a/view/adminhtml/templates/form/array.phtml +++ b/view/adminhtml/templates/form/array.phtml @@ -16,7 +16,7 @@ $_colspan = $block->isAddAfter() ? 2 : 1; - + getColumns() as $columnName => $column) : ?> diff --git a/view/adminhtml/templates/order/view/tab/pix_payment_info.phtml b/view/adminhtml/templates/order/view/tab/pix_payment_info.phtml new file mode 100644 index 0000000..79e9dad --- /dev/null +++ b/view/adminhtml/templates/order/view/tab/pix_payment_info.phtml @@ -0,0 +1,27 @@ +getPaymentMethodByOrder() == 'pix'): + $order = $block->getOrder(); + $qrcode = $order->getData('pix_asaas_qrcode'); + $pixPayload = $order->getData('pix_asaas_payload'); +?> +
+ +
+
+ +
+
+ + diff --git a/view/adminhtml/web/css/pix.css b/view/adminhtml/web/css/pix.css new file mode 100644 index 0000000..37cb6ce --- /dev/null +++ b/view/adminhtml/web/css/pix.css @@ -0,0 +1,83 @@ +.pix-instructions { + font-size: 20px; +} + +.qrcode-image { + width: 200px; + height: 200px; +} + +.qrcode-text { + width: 50%; + height: 100px; + resize: none; + pointer-events: none; + background-color: #f7f7f7; + color: #333; + border: 1px solid #ddd; + padding: 5px; + font-family: Arial, sans-serif; + font-size: 14px; +} + +.modal-popup .modal-inner-wrap { + width: 30%; +} + +.modal-inner-content { + min-height: 50vh; + padding-bottom: 40px; + padding-top: 40px; +} + +.modal-inner-content object { + width: 100%; + height: 25vh; + padding-bottom: 10px; +} + +.linha-digitavel { + position: relative; + margin-top: 10px; +} + +.linha-digitavel .copy { + position: absolute; + left: -2%; + width: 104%; + height: 100%; + opacity: 0; + transition: .5s; + color: white; + background-color: #8080808a; + text-align: center; + padding-top: 20px; + padding-bottom: 20px; +} + +.linha-digitavel:hover .copy { + opacity: 1; + cursor: pointer; +} + +.linha-digitavel img { + height: 60%; + filter: invert(100%) sepia(0%) saturate(4273%) hue-rotate(181deg) brightness(116%) contrast(107%); +} + +.invisible { + display: none; + visibility: hidden; +} + +@media screen and (max-width: 1200px) { + .modal-popup .modal-inner-wrap { + width: 50%; + } +} + +@media screen and (max-width: 768px) { + .modal-popup .modal-inner-wrap { + width: 80%; + } +} \ No newline at end of file diff --git a/view/frontend/layout/checkout_index_index.xml b/view/frontend/layout/checkout_index_index.xml index a0103bd..756fe6f 100755 --- a/view/frontend/layout/checkout_index_index.xml +++ b/view/frontend/layout/checkout_index_index.xml @@ -40,6 +40,14 @@ + + Asaas_Magento2/js/view/payment/pix + + + true + + + diff --git a/view/frontend/layout/checkout_onepage_success.xml b/view/frontend/layout/checkout_onepage_success.xml index 101f31c..6111319 100755 --- a/view/frontend/layout/checkout_onepage_success.xml +++ b/view/frontend/layout/checkout_onepage_success.xml @@ -1,8 +1,13 @@ + + + + - \ No newline at end of file + + \ No newline at end of file diff --git a/view/frontend/layout/sales_order_view.xml b/view/frontend/layout/sales_order_view.xml index 864c305..62e3e2d 100755 --- a/view/frontend/layout/sales_order_view.xml +++ b/view/frontend/layout/sales_order_view.xml @@ -1,5 +1,8 @@ + + + diff --git a/view/frontend/templates/info.phtml b/view/frontend/templates/info.phtml index 865ad27..c1136b2 100755 --- a/view/frontend/templates/info.phtml +++ b/view/frontend/templates/info.phtml @@ -1,5 +1,40 @@ getPaymentMethod() == 'boleto'): +if ($block->getPaymentMethodByOrder() == 'boleto'): $boletoUrl = $block->getPaymentInfo(); ?> + + +getPaymentMethodByOrder() == 'pix'): + $pix = $block->getPaymentInfo(); + $order = $block->getOrder(); + $qrcode = $order->getData('pix_asaas_qrcode'); + $pixPayload = $order->getData('pix_asaas_payload'); +?> + +
+
+ +
+ +
+
+ +
+
+ + + \ No newline at end of file diff --git a/view/frontend/templates/success.phtml b/view/frontend/templates/success.phtml index d0b0b4d..650cf3c 100755 --- a/view/frontend/templates/success.phtml +++ b/view/frontend/templates/success.phtml @@ -1,9 +1,18 @@ get('Asaas\Magento2\Helper\Data'); $order = $block->getOrder(); $boleto = $block->getBoleto(); +$qrcode = $block->getPixQrCode(); +$pixPayload = $block->getPixPayload(); $payment = $order->getPayment(); $order->getShippingMethod(); -if ($payment->getMethod() === "cc" || $payment->getMethod() === "boleto") : + +$decodedImage = base64_decode($qrcode ?? ''); +$imageName = 'image_' . uniqid() . '.png'; + +if ($payment->getMethod() === "cc" || $payment->getMethod() === "boleto" || $payment->getMethod() === "pix") : + + ?>
getIncrementId()) : ?> @@ -13,7 +22,7 @@ if ($payment->getMethod() === "cc" || $payment->getMethod() === "boleto") :

getMethod() === "boleto") : ?> - get('Asaas\Magento2\Helper\Data'); + getInstrucoes(); ?> @@ -21,7 +30,35 @@ if ($payment->getMethod() === "cc" || $payment->getMethod() === "boleto") :

%1.', $order->getIncrementId()); ?>

- + + getMethod() === "cc"): ?> + + + getMethod() === "boleto"): ?> + + + getMethod() === "pix"):?> +

getPixInstructions(); ?>

+ +
+
+ +
+ + +
\ No newline at end of file diff --git a/view/frontend/web/css/pix.css b/view/frontend/web/css/pix.css new file mode 100644 index 0000000..697ec61 --- /dev/null +++ b/view/frontend/web/css/pix.css @@ -0,0 +1,66 @@ +.pix-instructions { + font-size: 20px; +} + +.qrcode-image { + width: 200px; + height: 200px; +} + +.qrcode-text { + width: 50%; + height: 100px; + resize: none; + pointer-events: none; + background-color: #f7f7f7; + color: #333; + border: 1px solid #ddd; + padding: 5px; + font-family: Arial, sans-serif; + font-size: 14px; +} + +.modal-popup .modal-inner-wrap { + width: 30%; +} + +.modal-inner-content { + min-height: 50vh; + padding-bottom: 40px; + padding-top: 40px; +} + +.modal-inner-content object { + width: 100%; + height: 25vh; + padding-bottom: 10px; +} + +.linha-digitavel { + position: relative; + margin-top: 10px; +} + +.linha-digitavel .copy { + position: absolute; + left: -2%; + width: 104%; + height: 100%; + opacity: 0; + transition: .5s; + color: white; + background-color: #8080808a; + text-align: center; + padding-top: 20px; + padding-bottom: 20px; +} + +.linha-digitavel:hover .copy { + opacity: 1; + cursor: pointer; +} + +.linha-digitavel img { + height: 60%; + filter: invert(100%) sepia(0%) saturate(4273%) hue-rotate(181deg) brightness(116%) contrast(107%); +} \ No newline at end of file diff --git a/view/frontend/web/js/view/payment/method-renderer/pix-method.js b/view/frontend/web/js/view/payment/method-renderer/pix-method.js new file mode 100644 index 0000000..74bd9bb --- /dev/null +++ b/view/frontend/web/js/view/payment/method-renderer/pix-method.js @@ -0,0 +1,207 @@ +define( + [ + 'Magento_Checkout/js/view/payment/default', + 'jquery', + 'Magento_Checkout/js/model/payment/additional-validators', + 'Magento_Ui/js/model/messageList' + ], + function (Component, $, validators, messageList) { + 'use strict'; + + return Component.extend({ + defaults: { + template: 'Asaas_Magento2/payment/pix', + pixCpf: '', + }, + validate: function () { + + var isValid; + + function validarCPF(cpf) { + var cpf; + var i; + var add; + var rev; + cpf = cpf.replace(/[^\d]+/g, ''); + if (cpf == '') return false; + // Elimina CPFs invalidos conhecidos + if (cpf.length != 11 || + cpf == "00000000000" || + cpf == "11111111111" || + cpf == "22222222222" || + cpf == "33333333333" || + cpf == "44444444444" || + cpf == "55555555555" || + cpf == "66666666666" || + cpf == "77777777777" || + cpf == "88888888888" || + cpf == "99999999999") + return false; + // Valida 1o digito + add = 0; + for (i = 0; i < 9; i++) + add += parseInt(cpf.charAt(i)) * (10 - i); + rev = 11 - (add % 11); + if (rev == 10 || rev == 11) + rev = 0; + if (rev != parseInt(cpf.charAt(9))) + return false; + // Valida 2o digito + add = 0; + for (i = 0; i < 10; i++) + add += parseInt(cpf.charAt(i)) * (11 - i); + rev = 11 - (add % 11); + if (rev == 10 || rev == 11) + rev = 0; + if (rev != parseInt(cpf.charAt(10))) + return false; + return true; + } + + function validarCNPJ(cnpj) { + cnpj = cnpj.replace(/[^\d]+/g, ''); + + if (cnpj == '') return false; + + if (cnpj.length != 14) + return false; + + // Elimina CNPJs invalidos conhecidos + if (cnpj == "00000000000000" || + cnpj == "11111111111111" || + cnpj == "22222222222222" || + cnpj == "33333333333333" || + cnpj == "44444444444444" || + cnpj == "55555555555555" || + cnpj == "66666666666666" || + cnpj == "77777777777777" || + cnpj == "88888888888888" || + cnpj == "99999999999999") + return false; + + // Valida DVs + console.log(cnpj) + console.log(cnpj.length) + var tamanho = cnpj.length - 2 + var numeros = cnpj.substring(0, tamanho); + var digitos = cnpj.substring(tamanho); + var soma = 0; + var pos = tamanho - 7; + for (let i = tamanho; i >= 1; i--) { + soma += numeros.charAt(tamanho - i) * pos--; + if (pos < 2) + pos = 9; + } + var resultado = soma % 11 < 2 ? 0 : 11 - soma % 11; + if (resultado != digitos.charAt(0)) + return false; + + tamanho = tamanho + 1; + numeros = cnpj.substring(0, tamanho); + soma = 0; + pos = tamanho - 7; + for (let i = tamanho; i >= 1; i--) { + soma += numeros.charAt(tamanho - i) * pos--; + if (pos < 2) + pos = 9; + } + resultado = soma % 11 < 2 ? 0 : 11 - soma % 11; + if (resultado != digitos.charAt(1)) + return false; + + return true; + + } + + isValid = this.pixCpf().length <= 14 ? validarCPF(this.pixCpf()) : validarCNPJ(this.pixCpf()); + if (!isValid) { + messageList.addErrorMessage({ + message: "CPF/CNPJ inválido" + }); + } + + var $form = $('#' + this.getCode() + '-form'); + return $form.validation() && $form.validation('isValid') && isValid; + }, + + getMailingAddress: function () { + return window.checkoutConfig.payment.checkmo.mailingAddress; + }, + + getInstructions: function () { + return window.checkoutConfig.payment.instructions[this.item.method]; + }, + + + getCpfCnpjValue: function () { + const cpfcnpj = window.checkoutConfig.payment.cc.cpf_cnpj; + if(!cpfcnpj){ + this.pixCpf(''); + } + else{ + this.pixCpf(cpfcnpj); + } + }, + + initObservable: function () { + this._super() + .observe([ + 'pixCpf' + ]); + + return this; + }, + initialize: function () { + var self = this; + // setTimeout(function(){ + + // const input_cpf = document.getElementsByClassName("cpf")[0]; + + // input_cpf.addEventListener("focus" , function(event) { + // input_cpf.value = "___.___.___-__" + // setTimeout(function() { + // input_cpf.setSelectionRange(0, 0) + // }, 1) + // }) + + // input_cpf.addEventListener("blur" , function() { + // this.value = "" + // }) + + // input_cpf.addEventListener("keydown", function(event) { + // event.preventDefault() + // if("0123456789".indexOf(event.key) !== -1 + // && this.value.indexOf("_") !== -1) { + // this.value = this.value.replace(/_/, event.key) + // const next_index = this.value.indexOf("_") + // this.setSelectionRange(next_index, next_index) + // } else if (event.key === "Backspace") { + // this.value = this.value.replace(/(\d$)|(\d(?=\D+$))/, "_") + // const next_index = this.value.indexOf("_") + // this.setSelectionRange(next_index, next_index) + // } + // }) }, 5000); + this._super(); + + //Set expiration year to credit card data object + this.pixCpf.subscribe(function (value) { + boleto.pixCpf = value; + }); + }, + + + getData: function () { + return { + 'method': this.item.method, + 'additional_data': { + 'pix_cpf': this.pixCpf().replace(/[^\d]+/g, '') + } + }; + }, + getCode: function () { + return 'pix'; + } + } + ); + } + ); \ No newline at end of file diff --git a/view/frontend/web/js/view/payment/pix.js b/view/frontend/web/js/view/payment/pix.js new file mode 100644 index 0000000..7d62ea6 --- /dev/null +++ b/view/frontend/web/js/view/payment/pix.js @@ -0,0 +1,19 @@ +define( + [ + 'uiComponent', + 'Magento_Checkout/js/model/payment/renderer-list' + ], + function ( + Component, + rendererList + ) { + 'use strict'; + rendererList.push( + { + type: 'pix', + component: 'Asaas_Magento2/js/view/payment/method-renderer/pix-method' + } + ); + return Component.extend({}); + } + ); \ No newline at end of file diff --git a/view/frontend/web/template/payment/cc-form.html b/view/frontend/web/template/payment/cc-form.html index 79c14a1..f498a84 100755 --- a/view/frontend/web/template/payment/cc-form.html +++ b/view/frontend/web/template/payment/cc-form.html @@ -83,6 +83,8 @@ +
+
Parcelas escapeHtml($column['label']) ?>
+ + + +
+ From 8b9b819def9fab6cbf8fb56cf29e168d124484d7 Mon Sep 17 00:00:00 2001 From: Lucas Pereira Date: Mon, 3 Jun 2024 14:59:42 -0300 Subject: [PATCH 5/6] fix deprecated on php8.2 --- Helper/Data.php | 58 ++++++++++++++++++++---------- Model/AdditionalConfigProvider.php | 30 ++++++++++------ Observer/OrderObserver.php | 29 ++++++++------- 3 files changed, 76 insertions(+), 41 deletions(-) diff --git a/Helper/Data.php b/Helper/Data.php index 12be300..b4ea2ac 100755 --- a/Helper/Data.php +++ b/Helper/Data.php @@ -4,7 +4,8 @@ use \Magento\Framework\App\Helper\AbstractHelper; -class Data extends AbstractHelper { +class Data extends AbstractHelper +{ /** * @var \Magento\Framework\App\Config\ScopeConfigInterface */ @@ -13,15 +14,18 @@ class Data extends AbstractHelper { * returning config value **/ - public function getConfig($path) { + public function getConfig($path) + { $storeScope = \Magento\Store\Model\ScopeInterface::SCOPE_STORE; + return $this->scopeConfig->getValue($path, $storeScope); } /** * Return url **/ - public function getUrl() { + public function getUrl() + { if ($this->getConfig('payment/asaasmagento2/general_options/ambiente') === 'production') { return !$this->getConfig('payment/asaasmagento2/general_options/url_prod') ? "https://www.asaas.com" : @@ -33,39 +37,48 @@ public function getUrl() { } } - public function getDiscout(){ + public function getDiscout() + { return $this->getConfig('payment/asaasmagento2/options_boleto/options_boleto_discount'); } - public function getFine(){ + public function getFine() + { return $this->getConfig('payment/asaasmagento2/options_boleto/options_boleto_fine/value_fine'); } - public function getTokenWebhook(){ + public function getTokenWebhook() + { return $this->getConfig('payment/asaasmagento2/general_options/token_webhook'); } - public function getInterest(){ + public function getInterest() + { return $this->getConfig('payment/asaasmagento2/options_boleto/options_boleto_interest/value_interest'); } - public function getAcessToken() { + public function getAcessToken() + { return $this->getConfig('payment/asaasmagento2/general_options/api_key'); } - public function getNotifications() { + public function getNotifications() + { return $this->getConfig('payment/asaasmagento2/general_options/active_notifications'); } - public function getDays() { + public function getDays() + { return $this->getConfig('payment/asaasmagento2/options_boleto/validade'); } - private function getModuleEnabled() { + private function getModuleEnabled() + { return $this->getConfig('payment/asaasmagento2/active'); } - public function getStatusBillet() { + public function getStatusBillet() + { if ($this->getModuleEnabled() && $this->getConfig('payment/asaasmagento2/options_boleto/active_billet')) { return true; } else { @@ -73,7 +86,8 @@ public function getStatusBillet() { } } - public function getStatusCc() { + public function getStatusCc() + { if ($this->getModuleEnabled() && $this->getConfig('payment/asaasmagento2/options_cc/active_cc')) { return true; } else { @@ -81,12 +95,18 @@ public function getStatusCc() { } } - public function getInstrucoes() { + public function getInstrucoes() + { return $this->getConfig('payment/asaasmagento2/options_boleto/instrucoes'); } - public function getInstallments() { + public function getInstallments() + { + $installmentsConfig = $this->getConfig('payment/asaasmagento2/options_cc/parcelas'); + if (empty($installmentsConfig)) { + return false; + } $installments = json_decode($this->getConfig('payment/asaasmagento2/options_cc/parcelas')); - if(!$installments){ + if (!$installments) { return false; } $i = 1; @@ -103,11 +123,13 @@ public function getInstallments() { return $installmentss; } - public function getMinParcela(){ + public function getMinParcela() + { return $this->getConfig('payment/asaasmagento2/options_cc/min_parcela'); } - public function getPixInstructions(){ + public function getPixInstructions() + { return $this->getConfig('payment/asaasmagento2/options_pix/instrucoes'); } } diff --git a/Model/AdditionalConfigProvider.php b/Model/AdditionalConfigProvider.php index 42fb2a0..e2c6bc6 100755 --- a/Model/AdditionalConfigProvider.php +++ b/Model/AdditionalConfigProvider.php @@ -4,40 +4,50 @@ use Magento\Checkout\Model\ConfigProviderInterface; -class AdditionalConfigProvider implements ConfigProviderInterface { +class AdditionalConfigProvider implements ConfigProviderInterface +{ + private $helperData; + private $cart; + private $ccConfig; + private $customerRepositoryInterface; public function __construct( \Asaas\Magento2\Helper\Data $helper, \Magento\Checkout\Model\Cart $cart, \Magento\Payment\Model\CcConfig $ccConfig, \Magento\Customer\Model\Customer $customerRepositoryInterface - ) { + ) { $this->helperData = $helper; $this->cart = $cart; $this->ccConfig = $ccConfig; - $this->_customerRepositoryInterface = $customerRepositoryInterface; + $this->customerRepositoryInterface = $customerRepositoryInterface; } - - public function getInstallments() { + + public function getInstallments() + { $installments = $this->helperData->getInstallments(); return $installments; } - public function getCpfCnpj() { + public function getCpfCnpj() + { $customerId = $this->cart->getQuote()->getCustomerId(); - $customer = $this->_customerRepositoryInterface->load($customerId); + $customer = $this->customerRepositoryInterface->load($customerId); return $customer->getTaxvat(); } - public function getGrandTotal(){ + public function getGrandTotal() + { return $this->cart->getQuote()->getGrandTotal(); } - public function getMinParcelas(){ + public function getMinParcelas() + { return $this->helperData->getMinParcela(); } - public function getConfig() { + public function getConfig() + { $config = [ 'payment' => [ 'cc' => [ diff --git a/Observer/OrderObserver.php b/Observer/OrderObserver.php index 279bfd2..1e3fc85 100755 --- a/Observer/OrderObserver.php +++ b/Observer/OrderObserver.php @@ -1,23 +1,26 @@ session = $session; - - } + } + public function execute(\Magento\Framework\Event\Observer $observer) - { - $order = $observer->getEvent()->getOrder(); - $boleto = $this->session->getBoleto(); - $order->setBoletoAsaas($boleto); - $order->setState("pending")->setStatus("pending"); - $order->save(); - } -} \ No newline at end of file + { + $order = $observer->getEvent()->getOrder(); + $boleto = $this->session->getBoleto(); + $order->setBoletoAsaas($boleto); + $order->setState("pending")->setStatus("pending"); + $order->save(); + } +} \ No newline at end of file From f899740a104c8ece63db481553f1fa6fed26c1fe Mon Sep 17 00:00:00 2001 From: Lucas Pereira Date: Thu, 11 Jul 2024 13:16:12 -0300 Subject: [PATCH 6/6] add user agent to all requests --- Model/Payment/Boleto.php | 3 +++ Model/Payment/Cc.php | 3 +++ Model/Payment/Pix.php | 4 ++++ composer.json | 2 +- etc/module.xml | 2 +- 5 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Model/Payment/Boleto.php b/Model/Payment/Boleto.php index ea83b81..c19c6fe 100755 --- a/Model/Payment/Boleto.php +++ b/Model/Payment/Boleto.php @@ -164,6 +164,7 @@ public function userExists($cpf) { CURLOPT_FOLLOWLOCATION => true, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => "GET", + CURLOPT_USERAGENT => "magento", CURLOPT_HTTPHEADER => array( "access_token: " . $this->_decrypt->decrypt($this->helperData->getAcessToken()), "Content-Type: application/json" @@ -188,6 +189,7 @@ public function createUser($data) { CURLOPT_FOLLOWLOCATION => true, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => "POST", + CURLOPT_USERAGENT => "magento", CURLOPT_POSTFIELDS => json_encode($data), CURLOPT_HTTPHEADER => array( "access_token: " . $this->_decrypt->decrypt($this->helperData->getAcessToken()), @@ -212,6 +214,7 @@ public function doPayment($data) { CURLOPT_FOLLOWLOCATION => true, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => "POST", + CURLOPT_USERAGENT => "magento", CURLOPT_POSTFIELDS => json_encode($data), CURLOPT_HTTPHEADER => array( "access_token: " . $this->_decrypt->decrypt($this->helperData->getAcessToken()), diff --git a/Model/Payment/Cc.php b/Model/Payment/Cc.php index 8f10c63..3fc7d4f 100755 --- a/Model/Payment/Cc.php +++ b/Model/Payment/Cc.php @@ -188,6 +188,7 @@ public function userExists($cpf) { CURLOPT_FOLLOWLOCATION => true, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => "GET", + CURLOPT_USERAGENT => "magento", CURLOPT_HTTPHEADER => array( "access_token: " . $this->_decrypt->decrypt($this->helperData->getAcessToken()), "Content-Type: application/json" @@ -212,6 +213,7 @@ public function createUser($data) { CURLOPT_FOLLOWLOCATION => true, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => "POST", + CURLOPT_USERAGENT => "magento", CURLOPT_POSTFIELDS => json_encode($data), CURLOPT_HTTPHEADER => array( "access_token: " . $this->_decrypt->decrypt($this->helperData->getAcessToken()), @@ -237,6 +239,7 @@ public function doPayment($data) { CURLOPT_FOLLOWLOCATION => true, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => "POST", + CURLOPT_USERAGENT => "magento", CURLOPT_POSTFIELDS => json_encode($data), CURLOPT_HTTPHEADER => array( "access_token: " . $this->_decrypt->decrypt($this->helperData->getAcessToken()), diff --git a/Model/Payment/Pix.php b/Model/Payment/Pix.php index e8ee630..7d4ae24 100644 --- a/Model/Payment/Pix.php +++ b/Model/Payment/Pix.php @@ -176,6 +176,7 @@ public function userExists($cpf) { CURLOPT_FOLLOWLOCATION => true, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => "GET", + CURLOPT_USERAGENT => "magento", CURLOPT_HTTPHEADER => array( "access_token: " . $this->_decrypt->decrypt($this->helperData->getAcessToken()), "Content-Type: application/json" @@ -200,6 +201,7 @@ public function createUser($data) { CURLOPT_FOLLOWLOCATION => true, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => "POST", + CURLOPT_USERAGENT => "magento", CURLOPT_POSTFIELDS => json_encode($data), CURLOPT_HTTPHEADER => array( "access_token: " . $this->_decrypt->decrypt($this->helperData->getAcessToken()), @@ -224,6 +226,7 @@ public function doPayment($data) { CURLOPT_FOLLOWLOCATION => true, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => "POST", + CURLOPT_USERAGENT => "magento", CURLOPT_POSTFIELDS => json_encode($data), CURLOPT_HTTPHEADER => array( "access_token: " . $this->_decrypt->decrypt($this->helperData->getAcessToken()), @@ -250,6 +253,7 @@ public function getQrCode($paymentId) { CURLOPT_FOLLOWLOCATION => true, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => "GET", + CURLOPT_USERAGENT => "magento", CURLOPT_HTTPHEADER => array( "access_token: " . $this->_decrypt->decrypt($this->helperData->getAcessToken()), "Content-Type: application/json" diff --git a/composer.json b/composer.json index f9b81c7..04a55f6 100755 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "asaas/module-magento2", "description": "Asaas Payment", - "version": "1.2.0", + "version": "1.2.1", "type": "magento2-module", "license": "OSL-3.0", "authors": [], diff --git a/etc/module.xml b/etc/module.xml index c0c1941..eb6df2f 100755 --- a/etc/module.xml +++ b/etc/module.xml @@ -1,6 +1,6 @@ - +