diff --git a/README.md b/README.md index 6061e05..d4b4e49 100755 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ ![PHP](https://img.shields.io/badge/PHP-8.0%2B-purple) ![License](https://img.shields.io/badge/License-MIT-green) -> **📦 Версия модуля: 1.0.1** +> **📦 Версия модуля: 1.0.2** > **ℹ️ Совместимость версий OpenCart:** > 4.0.0.0, 4.0.1.0, 4.0.1.1, 4.0.2.0, 4.0.2.1, 4.0.2.2, 4.0.2.3, 4.1.0.0, 4.1.0.1, 4.1.0.2, 4.1.0.3 @@ -77,7 +77,7 @@ | **Тестовый режим** | `Нет` | | **Check URL** | `https://your_site_name/index.php?route=extension/payanyway/payment/callback` | | **Pay URL** | `https://your_site_name/index.php?route=extension/payanyway/payment/callback` | -| **HTTP method** | `GET` / `POST` | +| **HTTP method** | `GET` | | **Можно переопределять настройки в URL** | `Да` | | **Подпись формы оплаты обязательна** | `Да` | | **Код проверки целостности данных** | `ваш_код` (произвольный набор символов) | @@ -88,6 +88,14 @@ > ⚠️ **Важно!** Для кириллического домена PayURL и CheckURL должны быть указаны в кодировке [Punycode](https://2ip.ru/punycode/). +> ⚠️ **Важно!** В OpenCart 4 при возврате с сайта платежной системы (эквайринга) авторизация пользователя чаще всего слетает из-за конфликта cookie-атрибута SameSite. +Для решения проблемы выполните следующие действия: +> 1. Изменение настроек сессии в панели управления OpenCart по умолчанию использует для кук параметр `Lax` или `Strict`, + что вызывает разрыв сессии при возврате с внешнего сервера Настройки `SameSite`. + Перейдите в административную панель сайта. Откройте `Система (System)` > `Настройки (Settings)` и отредактируйте ваш магазин. +> 2. Перейдите на вкладку `Сервер (Server)`. Найдите настройку `Сессионный файл Cookie (Session Samesite Cookie)`. + Измените значение с `Lax/Strict` на `None (Нет)` (это разрешит отправку куки при переходе с другого сайта). + --- ## 📚 Полезные ресурсы OpenCart diff --git a/admin/controller/payment/payanyway.php b/admin/controller/payment/payanyway.php index 69bd912..5939e39 100755 --- a/admin/controller/payment/payanyway.php +++ b/admin/controller/payment/payanyway.php @@ -5,15 +5,13 @@ declare(strict_types=1); namespace Opencart\Admin\Controller\Extension\PayAnyWay\Payment; /** - * Class PayAnyWay - * * @package Opencart\Admin\Controller\Extension\PayAnyWay\Payment */ class PayAnyWay extends \Opencart\System\Engine\Controller { public const CMS_NAME = 'OpenCart'; public const MODULE_NAME = 'payanyway'; - public const MODULE_VERSION = '1.0.1'; + public const MODULE_VERSION = '1.0.2'; public const MODULE_DEFAULT_SORT_ORDER = 0; private const SUPPORTED_CURRENCIES = ['RUB']; @@ -320,9 +318,10 @@ class PayAnyWay extends \Opencart\System\Engine\Controller $cmsName = $this->detectCmsByPatterns($textFooter); $cmsVersion = defined('VERSION') ? constant('VERSION') : '.unknown'; - return sprintf('%s v%s | %s v%s', + return sprintf('%s v%s|PHP %s|%s v%s', $cmsName, $cmsVersion, + PHP_VERSION, self::MODULE_NAME, self::MODULE_VERSION ); diff --git a/admin/view/image/payment/payanyway.png b/admin/view/image/payment/payanyway.png index 724d34b..859c44f 100755 Binary files a/admin/view/image/payment/payanyway.png and b/admin/view/image/payment/payanyway.png differ diff --git a/admin/view/template/payment/payanyway.twig b/admin/view/template/payment/payanyway.twig index 0892d7f..3416193 100755 --- a/admin/view/template/payment/payanyway.twig +++ b/admin/view/template/payment/payanyway.twig @@ -28,7 +28,7 @@ {{ text_edit }}
- PayAnyWay + PayAnyWay
diff --git a/catalog/controller/payment/callback.php b/catalog/controller/payment/callback.php index 17405da..cc3712e 100755 --- a/catalog/controller/payment/callback.php +++ b/catalog/controller/payment/callback.php @@ -13,11 +13,18 @@ class Callback extends \Opencart\System\Engine\Controller { use \Opencart\Catalog\Library\Extension\PayAnyWay\Traits\PayAnyWay; - private const INVENTORY_ITEM_NAME_MAX_LENGTH = 128; - private const INVENTORY_ITEM_DEFAULT_VAT_TAG = '1105'; - private const INVENTORY_ITEM_DEFAULT_PAYMENT_METHOD = 'full_payment'; - private const INVENTORY_ITEM_DEFAULT_PAYMENT_OBJECT = 'commodity'; - private const INVENTORY_ITEM_DEFAULT_MEASURE = 'unit'; + private const FAIL_RESPONSE = 'FAIL'; + private const XML_CONTENT_TYPE = 'application/xml'; + private const JSON_CONTENT_TYPE = 'application/json'; + private const TEXT_CONTENT_TYPE = 'text/plain; charset=UTF-8'; + + public const DESCRIPTION_MAX_LENGTH = 500; + private const ITEM_NAME_MAX_LENGTH = 128; + private const ITEM_DEFAULT_VAT_TAG = '1105'; + private const DEFAULT_PAYMENT_METHOD = 'full_payment'; + private const DEFAULT_PAYMENT_OBJECT = 'commodity'; + private const SHIPPING_PAYMENT_OBJECT = 'service'; + private const DEFAULT_MEASURE = 'unit'; private const CANCEL_ORDER_STATUS_IDS = [7, 9, 16]; @@ -42,7 +49,7 @@ class Callback extends \Opencart\System\Engine\Controller parent::__construct($registry); if (!$this->validateOrder()) { - $this->sendResponse('FAIL'); + $this->sendResponse(self::FAIL_RESPONSE); } $this->initializeModule(); @@ -52,6 +59,8 @@ class Callback extends \Opencart\System\Engine\Controller /** @throws \Exception */ public function index(): void { + $this->validateCallback(); + ($this->callbackData['MNT_COMMAND'] === 'CHECK') ? $this->handleCheckCallback() : $this->handlePayCallback(); @@ -74,28 +83,53 @@ class Callback extends \Opencart\System\Engine\Controller ]; } - private function sendResponse(string $response, int $statusCode = 200): void + private function validateCallback(): void + { + if (empty($this->mntId) || empty($this->integrityCode)) { + $this->sendResponse(self::FAIL_RESPONSE); + } + + if ($this->mntId !== (int)$this->callbackData['MNT_ID']) { + $this->sendResponse(self::FAIL_RESPONSE); + } + } + + /** + * @param array|string $response + * @param int $statusCode + * @return void + */ + private function sendResponse(array|string $response, int $statusCode = 200): void { http_response_code($statusCode); + if (is_string($response)) { + header('Content-Type: ' . self::TEXT_CONTENT_TYPE); + echo $response; + } else { + header('Content-Type: ' . $response['contentType']); + echo $response['data']; + } - $isXml = str_starts_with($response, 'checkSignature($this->callbackData)) { - $this->sendResponse('FAIL'); + $this->sendResponse(self::FAIL_RESPONSE); } [$resultCode, $description] = $this->determineCheckResult(); - $responseData = $this->buildResponseData($resultCode, $description); + $responseData = $this->buildBaseResponseData($resultCode, $description); - $this->sendResponse($this->buildXMLResponse($responseData)); + $products = $this->getAccountOrderProducts(); + $deliveryInfo = $this->getDeliveryInfo(); + + $responseData['client'] = $this->getClientInfo(); + $responseData['items'] = $this->getCheckItems($products, $deliveryInfo); + + $this->sendResponse($this->buildJsonResponse($responseData)); } /** @@ -111,7 +145,7 @@ class Callback extends \Opencart\System\Engine\Controller $orderStatus = $this->getOrderStatusById($orderStatusId); if (empty($this->callbackData['MNT_AMOUNT'])) { - return [100, "Order status is '{$orderStatus}'"]; + return [100, "Order status is {$orderStatus}"]; } if ($this->successOrderStatusId === $orderStatusId) { @@ -119,7 +153,7 @@ class Callback extends \Opencart\System\Engine\Controller } if (in_array($orderStatusId, self::CANCEL_ORDER_STATUS_IDS, true)) { - return [500, "Order status is '{$orderStatus}'"]; + return [500, "Order status is {$orderStatus}"]; } return [402, 'Order created, but not paid']; @@ -139,7 +173,7 @@ class Callback extends \Opencart\System\Engine\Controller ]; if (!$this->checkSignature($shopData)) { - $this->sendResponse('FAIL'); + $this->sendResponse(self::FAIL_RESPONSE); } $isPayedOrder = $this->isOrderPaid(); @@ -150,9 +184,19 @@ class Callback extends \Opencart\System\Engine\Controller $resultCode = 200; $description = $isPayedOrder ? 'Order already paid' : 'Order success paid'; - $responseData = $this->buildResponseData($resultCode, $description); + $responseData = $this->buildBaseResponseData($resultCode, $description); - $this->sendResponse($this->buildXMLResponse($responseData)); + $products = $this->getAccountOrderProducts(); + $deliveryInfo = $this->getDeliveryInfo(); + + $payInventoryJson = $this->getPayInventoryJson($products, $deliveryInfo); + $responseData['inventory'] = $payInventoryJson ?: null; + $clientInfo = $this->getClientInfo(); + $responseData['client'] = $clientInfo + ? json_encode([$clientInfo], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) + : null; + + $this->sendResponse($this->buildXmlResponse($responseData)); } /** @@ -161,7 +205,7 @@ class Callback extends \Opencart\System\Engine\Controller * @return array * @throws \Exception */ - private function buildResponseData(int $resultCode, string $description): array + private function buildBaseResponseData(int $resultCode, string $description): array { $orderTotal = (float)($this->orderInfo['total'] ?? 0); @@ -169,7 +213,7 @@ class Callback extends \Opencart\System\Engine\Controller 'MNT_ID' => $this->mntId, 'MNT_TRANSACTION_ID' => $this->callbackData['MNT_TRANSACTION_ID'], 'MNT_RESULT_CODE' => $resultCode, - 'MNT_DESCRIPTION' => $description, + 'MNT_DESCRIPTION' => $this->validateString($description, self::DESCRIPTION_MAX_LENGTH), 'MNT_AMOUNT' => $this->formatPrice($orderTotal), 'MNT_CURRENCY_CODE' => $this->callbackData['MNT_CURRENCY_CODE'], ]; @@ -177,15 +221,6 @@ class Callback extends \Opencart\System\Engine\Controller $signatureSource = $resultCode . $this->mntId . $this->callbackData['MNT_TRANSACTION_ID'] . $this->integrityCode; $data['MNT_SIGNATURE'] = md5($signatureSource); - $this->load->model('account/order'); - $products = $this->model_account_order->getProducts($this->orderId); - $deliveryPrice = $this->getDeliveryPrice(); - - $data['inventory'] = $this->getInventoryJson($products) ?: null; - $data['client'] = $this->callbackData['MNT_SUBSCRIBER_ID']; - $data['sno'] = null; - $data['delivery'] = (null !== $deliveryPrice) ? $this->formatPrice($deliveryPrice) : null; - return $data; } @@ -218,39 +253,97 @@ class Callback extends \Opencart\System\Engine\Controller return hash_equals(md5($signatureString), $this->callbackData['MNT_SIGNATURE']); } - private function getDeliveryPrice(): ?float + private function getDeliveryInfo(): ?array { $this->load->model('account/order'); foreach ($this->model_account_order->getTotals($this->orderId) as $orderTotal) { if (($orderTotal['code'] ?? '') === 'shipping') { - $deliveryPrice = (float)($orderTotal['value'] ?? 0); - return $deliveryPrice !== 0.0 ? $deliveryPrice : null; + return $orderTotal; } } return null; } - /** - * @param array $products - * @return false|string - */ - private function getInventoryJson(array $products): false|string + private function getClientInfo(): array { - if (empty($products)) { + $clientInfo = []; + $name = $this->getClientName(); + if (null !== $name) { + $clientInfo['name'] = $name; + } + $email = $this->getClientEmail(); + if (null !== $email) { + $clientInfo['email'] = $email; + } + $phoneNumber = $this->getClientPhone(); + if (null !== $phoneNumber) { + $clientInfo['phone'] = $phoneNumber; + } + + return $clientInfo; + } + + private function getCheckItems(array $products, ?array $deliveryInfo): array + { + $checkItems = array(); + foreach ($products as $product) { + $checkItems[] = array( + 'name' => $this->validateString($product['name'] ?? '', self::ITEM_NAME_MAX_LENGTH), + 'price' => $this->formatPrice((float)($product['price'] ?? 0)), + 'quantity' => $this->formatQuantity((float)($product['quantity'] ?? 0)), + 'vat' => $this->getVat($this->vatRate), + 'measure' => self::DEFAULT_MEASURE, + 'paymentMethod' => self::DEFAULT_PAYMENT_METHOD, + 'paymentObject' => self::DEFAULT_PAYMENT_OBJECT, + ); + } + + if (null === $deliveryInfo) { + return $checkItems; + } + + $checkItems[] = array( + 'name' => $this->validateString($deliveryInfo['title'] ?? '', self::ITEM_NAME_MAX_LENGTH), + 'price' => $this->formatPrice((float)($deliveryInfo['value'] ?? 0)), + 'quantity' => 1, + 'vat' => $this->getVat($this->vatRate), + 'measure' => self::DEFAULT_MEASURE, + 'paymentMethod' => self::DEFAULT_PAYMENT_METHOD, + 'paymentObject' => self::SHIPPING_PAYMENT_OBJECT, + ); + + return $checkItems; + } + + private function getPayInventoryJson(array $products, ?array $deliveryInfo): false|string + { + if (empty($products) && empty($deliveryInfo)) { return false; } $inventory = []; foreach ($products as $product) { $inventory[] = [ - 'name' => $this->validateString($product['name'] ?? '', self::INVENTORY_ITEM_NAME_MAX_LENGTH), + 'name' => $this->validateString($product['name'] ?? '', self::ITEM_NAME_MAX_LENGTH), 'price' => $this->formatPrice((float)($product['price'] ?? 0)), 'quantity' => $this->formatQuantity((float)($product['quantity'] ?? 0)), 'vatTag' => $this->vatRate, - 'pm' => self::INVENTORY_ITEM_DEFAULT_PAYMENT_METHOD, - 'po' => self::INVENTORY_ITEM_DEFAULT_PAYMENT_OBJECT, - 'measure' => self::INVENTORY_ITEM_DEFAULT_MEASURE, + 'pm' => self::DEFAULT_PAYMENT_METHOD, + 'po' => self::DEFAULT_PAYMENT_OBJECT, + 'measure' => self::DEFAULT_MEASURE, + ]; + } + + if (null !== $deliveryInfo) { + $inventory[] = [ + 'name' => $this->validateString($deliveryInfo['title'] ?? '', self::ITEM_NAME_MAX_LENGTH), + 'price' => $this->formatPrice((float)($deliveryInfo['value'] ?? 0)), + 'quantity' => '1', + 'vatTag' => $this->vatRate, + 'pm' => self::DEFAULT_PAYMENT_METHOD, + 'po' => self::SHIPPING_PAYMENT_OBJECT, + 'measure' => self::DEFAULT_MEASURE, ]; } @@ -286,11 +379,39 @@ class Callback extends \Opencart\System\Engine\Controller return rtrim(rtrim($quantityString, '0'), '.'); } + /** + * @param array $data + * @return array + */ + public function buildJsonResponse(array $data): array + { + $jsonData = [ + 'id' => $data['MNT_ID'], + 'transactionId' => $data['MNT_TRANSACTION_ID'], + 'amount' => $data['MNT_AMOUNT'], + 'signature' => $data['MNT_SIGNATURE'], + 'resultCode' => $data['MNT_RESULT_CODE'], + 'description' => $data['MNT_DESCRIPTION'], + 'externalId' => $data['MNT_TRANSACTION_ID'], + 'receipt' => [ + 'client' => $data['client'], + 'items' => $data['items'], + ], + ]; + + $json = json_encode($jsonData, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); + + return [ + 'data' => $json ?: '', + 'contentType' => self::JSON_CONTENT_TYPE, + ]; + } + /** * @param array $data * @throws \Exception */ - private function buildXMLResponse(array $data): false|string + private function buildXmlResponse(array $data): array { $dom = new \DOMDocument('1.0', 'UTF-8'); $dom->formatOutput = false; @@ -334,7 +455,39 @@ class Callback extends \Opencart\System\Engine\Controller } $xml = $dom->saveXML(); - return (false !== $xml) ? $xml : 'FAIL'; + + return array( + 'data' => (false !== $xml) ? $xml : self::FAIL_RESPONSE, + 'contentType' => (false !== $xml) ? self::XML_CONTENT_TYPE : self::TEXT_CONTENT_TYPE, + ); + } + + public function getVat($vatRate): string + { + return match ($vatRate) { + '1104' => 'vat0', + '1108' => 'vat5', + '1109' => 'vat7', + '1103' => 'vat10', + '7000' => 'vat20', + '1113' => 'vat22', + '1110' => 'vat105', + '1111' => 'vat107', + '1107' => 'vat110', + '7001' => 'vat120', + '1114' => 'vat122', + default => 'none' + }; + } + + /** + * @return array + * @throws \Exception + */ + public function getAccountOrderProducts(): array + { + $this->load->model('account/order'); + return $this->model_account_order->getProducts($this->orderId); } /** @param array $params */ diff --git a/catalog/controller/payment/payanyway.php b/catalog/controller/payment/payanyway.php index f417540..43ab3da 100755 --- a/catalog/controller/payment/payanyway.php +++ b/catalog/controller/payment/payanyway.php @@ -4,8 +4,38 @@ declare(strict_types=1); namespace Opencart\Catalog\Controller\Extension\PayAnyWay\Payment; +use Opencart\Catalog\Model\Account\Customer as ModelAccountCustomer; +use Opencart\Catalog\Model\Account\Order as ModelAccountOrder; +use Opencart\Catalog\Model\Checkout\Order as ModelCheckoutOrder; +use Opencart\System\Engine\Config; +use Opencart\System\Engine\Loader; +use Opencart\System\Library\Cart\Currency; +use Opencart\System\Library\Cart\Customer; +use Opencart\System\Library\Document; +use Opencart\System\Library\Language; +use Opencart\System\Library\Request; +use Opencart\System\Library\Response; +use Opencart\System\Library\Session; +use Opencart\System\Library\Url; + require_once DIR_EXTENSION . '/payanyway/catalog/library/payanyway/traits/payanyway.php'; +/** + * @property Config $config + * @property Loader $load + * @property Request $request + * @property Response $response + * @property Document $document + * @property Session $session + * @property Language $language + * @property Url $url + * @property Currency $currency + * @property ModelCheckoutOrder $model_checkout_order + * @property ModelAccountOrder $model_account_order + * @property ModelAccountCustomer $model_account_customer + * @property Customer $customer + */ + class PayAnyWay extends \Opencart\System\Engine\Controller { use \Opencart\Catalog\Library\Extension\PayAnyWay\Traits\PayAnyWay; @@ -13,7 +43,8 @@ class PayAnyWay extends \Opencart\System\Engine\Controller private const PAYMENT_SERVER_PROD = 'prod'; private const PAYMENT_URL_PROD = 'https://www.payanyway.ru/assistant.htm'; private const PAYMENT_URL_DEMO = 'https://demo.moneta.ru/assistant.htm'; - private const DESCRIPTION_MAX_LENGTH = 500; + + public const DESCRIPTION_MAX_LENGTH = 500; private int $mntId; private string $integrityCode; @@ -71,14 +102,16 @@ class PayAnyWay extends \Opencart\System\Engine\Controller $this->integrityCode, ); $data['MNT_SIGNATURE'] = $signature; - $data['MNT_SUCCESS_URL'] = $this->url->link('extension/payanyway/payment/payanyway.success', 'language=' . $this->config->get('config_language'), true,); - $data['MNT_FAIL_URL'] = $this->url->link('extension/payanyway/payment/payanyway.fail', 'language=' . $this->config->get('config_language'), true,); - $data['MNT_RETURN_URL'] = $this->url->link('checkout/checkout', 'language=' . $this->config->get('config_language'), true,); + $customerToken = $this->session->data['customer_token']; + $data['MNT_SUCCESS_URL'] = $this->url->link('extension/payanyway/payment/payanyway.success', 'customer_token=' . $customerToken, true); + $data['MNT_FAIL_URL'] = $this->url->link('extension/payanyway/payment/payanyway.fail', 'customer_token=' . $customerToken, true); + $data['MNT_RETURN_URL'] = $this->url->link('checkout/checkout', 'customer_token=' . $customerToken, true); + $data['moneta_locale'] = $this->language->get('text_locale'); $data['MNT_CMS'] = $this->cmsModuleVersion; $data['btn_confirm'] = $this->language->get('text_paw_pay'); - $data['confirm_url'] = $this->url->link('extension/payanyway/payment/payanyway.confirm', 'language=' . $this->config->get('config_language'), true,); + $data['confirm_url'] = $this->url->link('extension/payanyway/payment/payanyway.confirm', 'customer_token=' . $customerToken, true,); return $this->load->view('extension/payanyway/payment/payanyway', $data); } @@ -86,7 +119,11 @@ class PayAnyWay extends \Opencart\System\Engine\Controller public function confirm(): void { $this->load->language('extension/payanyway/payment/payanyway'); - $this->addOrderHistory($this->orderId, $this->pendingOrderStatusId, $this->language->get('text_order_confirmed'),); + + $orderStatusId = isset($this->orderInfo['order_status_id']) ? (int)$this->orderInfo['order_status_id'] : null; + if ((null !== $orderStatusId) && ($orderStatusId !== $this->successOrderStatusId)) { + $this->addOrderHistory($this->orderId, $this->pendingOrderStatusId, $this->language->get('text_order_confirmed'),); + } $json['success'] = true; @@ -97,30 +134,41 @@ class PayAnyWay extends \Opencart\System\Engine\Controller public function success(): void { $this->load->language('extension/payanyway/payment/payanyway'); - $this->addOrderHistory($this->orderId, $this->pendingOrderStatusId, $this->language->get('text_payment_processing'),); - $this->response->redirect($this->url->link('checkout/success', '', true)); + + $orderStatusId = isset($this->orderInfo['order_status_id']) ? (int)$this->orderInfo['order_status_id'] : null; + if ((null !== $orderStatusId) && ($orderStatusId !== $this->successOrderStatusId)) { + $this->addOrderHistory($this->orderId, $this->pendingOrderStatusId, $this->language->get('text_payment_processing')); + } + + $customerToken = $this->request->get['customer_token'] ?? ''; + + $this->response->redirect($this->url->link('checkout/success', 'customer_token=' . $customerToken, true)); } public function fail(): void { $this->load->language('extension/payanyway/payment/payanyway'); - $this->addOrderHistory($this->orderId, $this->errorOrderStatusId, $this->language->get('text_payment_error'),); + + $orderStatusId = isset($this->orderInfo['order_status_id']) ? (int)$this->orderInfo['order_status_id'] : null; + if ((null !== $orderStatusId) && ($orderStatusId !== $this->successOrderStatusId)) { + $this->addOrderHistory($this->orderId, $this->errorOrderStatusId, $this->language->get('text_payment_error')); + } + $this->response->redirect($this->url->link('checkout/failure', '', true)); } private function getDescription(): string { - $clientName = trim(($this->orderInfo['firstname'] ?? '') . ' ' . ($this->orderInfo['lastname'] ?? '')); - $orderId = $this->orderInfo['order_id'] ?? null; $description = "Оплата заказа" . (!empty($orderId) ? " №{$orderId}" : ''); - if ('' !== $clientName) { - $description .= " от {$clientName}"; + $name = $this->getClientName(); + if (null !== $name) { + $description .= " от {$name}"; } $comment = $this->orderInfo['comment'] ?? ''; - if ($comment !== '') { + if ('' !== $comment) { $description .= ': ' . htmlspecialchars($comment, ENT_QUOTES, 'UTF-8'); } @@ -129,13 +177,6 @@ class PayAnyWay extends \Opencart\System\Engine\Controller private function getSubscriberId(): string { - $email = filter_var($this->orderInfo['email'] ?? '', FILTER_SANITIZE_EMAIL); - if ('' !== $email) { - return $email; - } - - $phoneNumber = preg_replace('/[^0-9+]/', '', $this->orderInfo['telephone'] ?? ''); - - return $phoneNumber ?: ''; + return $this->getClientEmail() ?? $this->getClientPhone() ?? ''; } } diff --git a/catalog/language/en-gb/payment/payanyway.php b/catalog/language/en-gb/payment/payanyway.php index b48dddf..beede39 100755 --- a/catalog/language/en-gb/payment/payanyway.php +++ b/catalog/language/en-gb/payment/payanyway.php @@ -1,5 +1,6 @@ load->model('checkout/order'); $this->model_checkout_order->addHistory($orderId, $orderStatusId, $comment); } + + /** @return non-empty-string|null */ + private function getClientName(): ?string + { + $name = trim(($this->orderInfo['firstname'] ?? '') . ' ' . ($this->orderInfo['lastname'] ?? '')); + return ('' !== $name) ? $name : null; + } + + /** @return non-empty-string|null */ + private function getClientEmail(): ?string + { + $email = trim((string)($this->orderInfo['email'] ?? '')); + return ('' !== $email) ? filter_var($email, FILTER_SANITIZE_EMAIL) : null; + } + + /** @return non-empty-string|null */ + private function getClientPhone(): ?string + { + $digits = preg_replace('/\D/', '', trim((string)($this->orderInfo['telephone'] ?? ''))); + return ('' !== $digits) ? '+' . $digits : null; + } } diff --git a/catalog/view/template/payment/payanyway.twig b/catalog/view/template/payment/payanyway.twig index d406ee1..d7be749 100755 --- a/catalog/view/template/payment/payanyway.twig +++ b/catalog/view/template/payment/payanyway.twig @@ -10,6 +10,7 @@ +
diff --git a/install.json b/install.json index 455ad68..9259bab 100755 --- a/install.json +++ b/install.json @@ -1,7 +1,7 @@ { "code": "payanyway", "name": "PayAnyWay", - "version": "1.0.1", + "version": "1.0.2", "author": "PayAnyWay", "link": "https://www.payanyway.ru/" }