From 7261f047d1d3b91d9874da4b54f49b912917f86c Mon Sep 17 00:00:00 2001 From: Kamil Balwierz Date: Tue, 2 Jun 2026 16:45:46 +0200 Subject: [PATCH 1/5] Payment retry features --- CHANGELOG.MD | 8 ++ Controller/Adminhtml/Order/Reminder.php | 78 +++++++++++++++++ Model/Config/Source/EmailTemplate.php | 17 ++++ Model/TpayPayment.php | 2 + Plugin/AddSendReminderButtonInOrderView.php | 40 +++++++++ Service/ReminderService.php | 84 +++++++++++++++++++ Service/TpayService.php | 5 +- Setup/Patch/Data/InstallOrderStatus.php | 49 +++++++++++ ViewModel/Order/Button.php | 44 ++++++++++ etc/acl.xml | 19 +++++ etc/adminhtml/di.xml | 15 ++++ etc/adminhtml/routes.xml | 17 ++++ etc/adminhtml/system.xml | 4 + etc/config.xml | 3 + etc/email_templates.xml | 10 +++ i18n/pl_PL.csv | 12 +++ .../email/payment_reminder_email.html | 18 ++++ view/frontend/layout/sales_order_view.xml | 14 ++++ view/frontend/templates/button.phtml | 16 ++++ 19 files changed, 453 insertions(+), 2 deletions(-) create mode 100644 Controller/Adminhtml/Order/Reminder.php create mode 100644 Model/Config/Source/EmailTemplate.php create mode 100644 Plugin/AddSendReminderButtonInOrderView.php create mode 100644 Service/ReminderService.php create mode 100644 Setup/Patch/Data/InstallOrderStatus.php create mode 100644 ViewModel/Order/Button.php create mode 100644 etc/acl.xml create mode 100644 etc/adminhtml/di.xml create mode 100644 etc/adminhtml/routes.xml create mode 100644 etc/email_templates.xml create mode 100644 view/frontend/email/payment_reminder_email.html create mode 100644 view/frontend/layout/sales_order_view.xml create mode 100644 view/frontend/templates/button.phtml diff --git a/CHANGELOG.MD b/CHANGELOG.MD index e3519bd..8625eb8 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 2.8.0 + +### Added + +- New order status `pending_payment_tpay` assigned to newly created orders with Tpay payment methods. +- Ability to click "Pay with Tpay" in customer order details view (for orders in status `pending_payment_tpay`) +- Ability to send payment reminders from adminhtml order details view (for orders in status `pending_payment_tpay`) + ## 2.7.0 ### Added diff --git a/Controller/Adminhtml/Order/Reminder.php b/Controller/Adminhtml/Order/Reminder.php new file mode 100644 index 0000000..6d7d4d7 --- /dev/null +++ b/Controller/Adminhtml/Order/Reminder.php @@ -0,0 +1,78 @@ +reminderService = $reminderService; + $this->orderRepository = $orderRepository; + } + + public function execute() + { + $order = $this->orderRepository->get($this->getRequest()->getParam('order_id')); + + if (TpayPayment::ORDER_STATUS_PENDING !== $order->getStatus()) { + $this->messageManager->addErrorMessage(__('Reminder allowed only for pending payments.')); + + return $this->redirectBack(); + } + + $payment = $order->getPayment(); + if (null === $payment) { + $this->messageManager->addErrorMessage(__('No payment found for this order.')); + + return $this->redirectBack(); + } + + $info = $payment->getAdditionalInformation(); + if (empty($info['transaction_url'])) { + $this->messageManager->addErrorMessage(__('Payment does not contain transaction url.')); + + return $this->redirectBack(); + } + + try { + if ($this->reminderService->reminder($order)) { + $this->messageManager->addSuccessMessage(__('Reminder has been sent.')); + + return $this->redirectBack(); + } + } catch (Throwable $exception) { + $this->messageManager->addErrorMessage($exception->getMessage()); + } + + $this->messageManager->addErrorMessage(__('Problem during sending reminder.')); + + return $this->redirectBack(); + } + + protected function _isAllowed() + { + return $this->_authorization->isAllowed('Tpay_Magento2::send_reminder'); + } + + private function redirectBack() + { + return $this->resultRedirectFactory->create()->setPath('sales/order/view', ['order_id' => $this->getRequest()->getParam('order_id')]); + } +} diff --git a/Model/Config/Source/EmailTemplate.php b/Model/Config/Source/EmailTemplate.php new file mode 100644 index 0000000..0da6a6d --- /dev/null +++ b/Model/Config/Source/EmailTemplate.php @@ -0,0 +1,17 @@ +getAuthorization()->isAllowed('Tpay_Magento2::send_reminder')) { + return; + } + $order = $subject->getOrder(); + if (null === $order) { + return; + } + if (TpayPayment::ORDER_STATUS_PENDING !== $order->getStatus()) { + return; + } + $payment = $order->getPayment(); + if (null === $payment) { + return; + } + $info = $payment->getAdditionalInformation(); + if (empty($info['transaction_url'])) { + return; + } + + $subject->addButton( + 'send_tpay_reminder', + [ + 'label' => __('Send Payment Reminder'), + 'onclick' => "setLocation('".$subject->getUrl('tpay/order/reminder')."')", + 'class' => 'secondary', + ] + ); + } +} diff --git a/Service/ReminderService.php b/Service/ReminderService.php new file mode 100644 index 0000000..f6244be --- /dev/null +++ b/Service/ReminderService.php @@ -0,0 +1,84 @@ +transportBuilder = $transportBuilder; + $this->inlineTranslation = $inlineTranslation; + $this->orderRepository = $orderRepository; + $this->scopeConfig = $scopeConfig; + } + + public function reminder(OrderInterface $order) + { + $payment = $order->getPayment(); + if (null === $payment) { + return false; + } + $info = $payment->getAdditionalInformation(); + if (null === $info) { + return false; + } + if (empty($info['transaction_url'])) { + return false; + } + $paymentUrl = $info['transaction_url']; + + $this->inlineTranslation->suspend(); + + $templateId = $this->scopeConfig->getValue('payment/tpaycom_magento2basic/sale_settings/payment_remind_email_template', ScopeInterface::SCOPE_STORE, $order->getStoreId()); + if (empty($templateId)) { + $templateId = 'payment_tpaycom_magento2basic_sale_settings_payment_remind_email_template'; + } + + $transport = $this->transportBuilder + ->setTemplateIdentifier($templateId) + ->setTemplateOptions([ + 'area' => Area::AREA_FRONTEND, + 'store' => $order->getStoreId(), + ]) + ->setTemplateVars([ + 'paymentUrl' => $paymentUrl, + 'order' => $order->getIncrementId(), + 'name' => $order->getCustomerName(), + ]) + ->setFromByScope('general', $order->getStoreId()) + ->addTo($order->getCustomerEmail(), $order->getCustomerName()) + ->getTransport(); + + $transport->sendMessage(); + $this->inlineTranslation->resume(); + + $order->addCommentToStatusHistory(__('Payment reminder sent')); + $this->orderRepository->save($order); + + return true; + } +} diff --git a/Service/TpayService.php b/Service/TpayService.php index 055b377..0d73cad 100644 --- a/Service/TpayService.php +++ b/Service/TpayService.php @@ -12,6 +12,7 @@ use Magento\Sales\Model\Order\Payment\Transaction; use Magento\Sales\Model\Service\InvoiceService; use Tpay\Magento2\Helper\OrderResolver; +use Tpay\Magento2\Model\TpayPayment; class TpayService { @@ -48,7 +49,7 @@ public function setOrderStatePendingPayment(string $orderId, bool $sendEmail): O ->setBaseTotalPaid(0.00) ->setBaseTotalDue($order->getBaseGrandTotal()) ->setState(Order::STATE_PENDING_PAYMENT) - ->addStatusToHistory(true); + ->addStatusToHistory(TpayPayment::ORDER_STATUS_PENDING); $order->setSendEmail($sendEmail); $this->orderRepository->save($order); @@ -60,7 +61,7 @@ public function addCommentToHistory($orderId, $comment) { /** @var Order $order */ $order = $this->orderResolver->getOrderByIncrementId($orderId); - $order->addStatusToHistory($order->getState(), $comment); + $order->addStatusToHistory($order->getStatus(), $comment); $this->orderRepository->save($order); } diff --git a/Setup/Patch/Data/InstallOrderStatus.php b/Setup/Patch/Data/InstallOrderStatus.php new file mode 100644 index 0000000..b034155 --- /dev/null +++ b/Setup/Patch/Data/InstallOrderStatus.php @@ -0,0 +1,49 @@ +moduleDataSetup = $moduleDataSetup; + } + + public static function getDependencies() + { + return []; + } + + public function getAliases() + { + return []; + } + + public function apply() + { + $this->moduleDataSetup->getConnection()->insert( + $this->moduleDataSetup->getTable('sales_order_status'), + [ + 'status' => TpayPayment::ORDER_STATUS_PENDING, + 'label' => __('Pending Payment with Tpay'), + ] + ); + + $this->moduleDataSetup->getConnection()->insert( + $this->moduleDataSetup->getTable('sales_order_status_state'), + [ + 'status' => TpayPayment::ORDER_STATUS_PENDING, + 'state' => 'pending_payment', + 'is_default' => 0, + 'visible_on_front' => 1, + ] + ); + } +} diff --git a/ViewModel/Order/Button.php b/ViewModel/Order/Button.php new file mode 100644 index 0000000..bb62e8d --- /dev/null +++ b/ViewModel/Order/Button.php @@ -0,0 +1,44 @@ +registry = $registry; + } + + public function shouldShowButton(): bool + { + if (TpayPayment::ORDER_STATUS_PENDING !== $this->getOrder()->getStatus()) { + return false; + } + + return !empty($this->getPaymentUrl()); + } + + public function getPaymentUrl(): ?string + { + $payment = $this->getOrder()->getPayment(); + if (null === $payment) { + return null; + } + $info = $payment->getAdditionalInformation(); + + return $info['transaction_url'] ?? null; + } + + private function getOrder(): OrderInterface + { + return $this->registry->registry('current_order'); + } +} diff --git a/etc/acl.xml b/etc/acl.xml new file mode 100644 index 0000000..a281b44 --- /dev/null +++ b/etc/acl.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + diff --git a/etc/adminhtml/di.xml b/etc/adminhtml/di.xml new file mode 100644 index 0000000..159da90 --- /dev/null +++ b/etc/adminhtml/di.xml @@ -0,0 +1,15 @@ + + + + + + diff --git a/etc/adminhtml/routes.xml b/etc/adminhtml/routes.xml new file mode 100644 index 0000000..bdd0f79 --- /dev/null +++ b/etc/adminhtml/routes.xml @@ -0,0 +1,17 @@ + + + + + + + + + diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml index c0b8f5e..3be21c3 100644 --- a/etc/adminhtml/system.xml +++ b/etc/adminhtml/system.xml @@ -183,6 +183,10 @@ If you use other currencies visible on the website and pay in PLN, turn it on/off Magento\Config\Model\Config\Source\Yesno + + + \Tpay\Magento2\Model\Config\Source\EmailTemplate + diff --git a/etc/config.xml b/etc/config.xml index ad9e4ad..fe7e7f8 100644 --- a/etc/config.xml +++ b/etc/config.xml @@ -31,6 +31,9 @@ 1 + + + 30 diff --git a/etc/email_templates.xml b/etc/email_templates.xml new file mode 100644 index 0000000..55bbbdd --- /dev/null +++ b/etc/email_templates.xml @@ -0,0 +1,10 @@ + + +