3
0

Feature/merge main to release

This commit is contained in:
Ivan Sadovin 2026-07-03 15:11:52 +03:00 committed by Git Moneta
parent 83f1d8d101
commit c3189d2439
No known key found for this signature in database
GPG Key ID: 72A746BD7C9C5031
9 changed files with 88 additions and 24 deletions

View File

@ -4,7 +4,7 @@
![PHP](https://img.shields.io/badge/PHP-5.6%2B-purple) ![PHP](https://img.shields.io/badge/PHP-5.6%2B-purple)
![License](https://img.shields.io/badge/License-MIT-green) ![License](https://img.shields.io/badge/License-MIT-green)
> **📦 Версия модуля: 1.0.1** > **📦 Версия модуля: 1.0.2**
> ** Совместимость версий OpenCart:** > ** Совместимость версий OpenCart:**
> 3.0.0.0, 3.0.1.1, 3.0.1.2, 3.0.2.0, 3.0.3.0, 3.0.3.1, 3.0.3.2, 3.0.3.3, 3.0.3.4, 3.0.3.5, 3.0.3.6, 3.0.3.7, 3.0.3.8, 3.0.3.9, 3.0.4.0, 3.0.4.1, 3.0.5.0 > 3.0.0.0, 3.0.1.1, 3.0.1.2, 3.0.2.0, 3.0.3.0, 3.0.3.1, 3.0.3.2, 3.0.3.3, 3.0.3.4, 3.0.3.5, 3.0.3.6, 3.0.3.7, 3.0.3.8, 3.0.3.9, 3.0.4.0, 3.0.4.1, 3.0.5.0
@ -76,7 +76,7 @@
| **Тестовый режим** | `Нет` | | **Тестовый режим** | `Нет` |
| **Check URL** | `https://your_site_name/index.php?route=extension/payment/payanyway/callback` | | **Check URL** | `https://your_site_name/index.php?route=extension/payment/payanyway/callback` |
| **Pay URL** | `https://your_site_name/index.php?route=extension/payment/payanyway/callback` | | **Pay URL** | `https://your_site_name/index.php?route=extension/payment/payanyway/callback` |
| **HTTP method** | `GET` / `POST` | | **HTTP method** | `GET` |
| **Можно переопределять настройки в URL** | `Да` | | **Можно переопределять настройки в URL** | `Да` |
| **Подпись формы оплаты обязательна** | `Да` | | **Подпись формы оплаты обязательна** | `Да` |
| **Код проверки целостности данных** | аш_код` (произвольный набор символов) | | **Код проверки целостности данных** | аш_код` (произвольный набор символов) |

View File

@ -2,7 +2,7 @@
<modification> <modification>
<name>PayAnyWay</name> <name>PayAnyWay</name>
<code>payanyway</code> <code>payanyway</code>
<version>1.0.1</version> <version>1.0.2</version>
<author>PayAnyWay</author> <author>PayAnyWay</author>
<link>https://payanyway.ru/</link> <link>https://payanyway.ru/</link>
</modification> </modification>

View File

@ -9,7 +9,7 @@
class ControllerExtensionPaymentPayanyway extends Controller { class ControllerExtensionPaymentPayanyway extends Controller {
const CMS_NAME = 'OpenCart'; const CMS_NAME = 'OpenCart';
const MODULE_NAME = 'payanyway'; const MODULE_NAME = 'payanyway';
const MODULE_VERSION = '1.0.1'; const MODULE_VERSION = '1.0.2';
const MODULE_DEFAULT_SORT_ORDER = 0; const MODULE_DEFAULT_SORT_ORDER = 0;
private $supportedCurrencies = array('RUB'); private $supportedCurrencies = array('RUB');
@ -289,9 +289,10 @@ class ControllerExtensionPaymentPayanyway extends Controller {
$cmsName = $this->detectCmsByPatterns($textFooter); $cmsName = $this->detectCmsByPatterns($textFooter);
$cmsVersion = defined('VERSION') ? constant('VERSION') : '.unknown'; $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, $cmsName,
$cmsVersion, $cmsVersion,
PHP_VERSION,
self::MODULE_NAME, self::MODULE_NAME,
self::MODULE_VERSION self::MODULE_VERSION
); );

BIN
upload/admin/view/image/payment/payanyway.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 150 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -27,7 +27,7 @@
</div> </div>
<div class="panel-heading text-center"> <div class="panel-heading text-center">
<a href="https://www.payanyway.ru/" target="_blank"> <a href="https://www.payanyway.ru/" target="_blank">
<img src="view/image/payment/payanyway.png" alt="PayAnyWay" title="PayAnyWay" width="250" height="29"/> <img src="view/image/payment/payanyway.png" alt="PayAnyWay" title="PayAnyWay" width="336" height="50"/>
</a> </a>
</div> </div>
<div class="panel-body"> <div class="panel-body">

View File

@ -13,6 +13,7 @@ class ControllerExtensionPaymentPayanyway extends Controller {
const TRANSACTION_ID_STRING_DELIMITER = '|'; const TRANSACTION_ID_STRING_DELIMITER = '|';
const DESCRIPTION_MAX_LENGTH = 500; const DESCRIPTION_MAX_LENGTH = 500;
const CLIENT_NAME_MAX_LENGTH = 256;
const INVENTORY_ITEM_NAME_MAX_LENGTH = 128; const INVENTORY_ITEM_NAME_MAX_LENGTH = 128;
const INVENTORY_ITEM_DEFAULT_PAYMENT_METHOD = 'full_payment'; const INVENTORY_ITEM_DEFAULT_PAYMENT_METHOD = 'full_payment';
const INVENTORY_ITEM_DEFAULT_PAYMENT_OBJECT = 'commodity'; const INVENTORY_ITEM_DEFAULT_PAYMENT_OBJECT = 'commodity';
@ -91,14 +92,15 @@ class ControllerExtensionPaymentPayanyway extends Controller {
$this->integrityCode $this->integrityCode
); );
$data['MNT_SIGNATURE'] = $signature; $data['MNT_SIGNATURE'] = $signature;
$data['MNT_SUCCESS_URL'] = $this->url->link('extension/payment/payanyway/success', 'language=' . $this->config->get('config_language'), true); $data['MNT_SUCCESS_URL'] = $this->url->link('extension/payment/payanyway/success', '', true);
$data['MNT_FAIL_URL'] = $this->url->link('extension/payment/payanyway/fail', 'language=' . $this->config->get('config_language'), true); $data['MNT_FAIL_URL'] = $this->url->link('extension/payment/payanyway/fail', '', true);
$data['MNT_RETURN_URL'] = $this->url->link('checkout/checkout', 'language=' . $this->config->get('config_language'), true); $data['MNT_RETURN_URL'] = $this->url->link('checkout/checkout', '', true);
$data['moneta_locale'] = $this->language->get('text_locale');
$data['MNT_CMS'] = $this->cmsModuleVersion; $data['MNT_CMS'] = $this->cmsModuleVersion;
$data['btn_confirm'] = $this->language->get('text_paw_pay'); $data['btn_confirm'] = $this->language->get('text_paw_pay');
$data['confirm_url'] = $this->url->link('extension/payment/payanyway/confirm', 'language=' . $this->config->get('config_language'), true); $data['confirm_url'] = $this->url->link('extension/payment/payanyway/confirm', '', true);
return $this->load->view('extension/payment/payanyway', $data); return $this->load->view('extension/payment/payanyway', $data);
} }
@ -125,7 +127,11 @@ class ControllerExtensionPaymentPayanyway extends Controller {
*/ */
public function success() { public function success() {
$this->load->language('extension/payment/payanyway'); $this->load->language('extension/payment/payanyway');
$this->addOrderHistory($this->pendingOrderStatusId, $this->language->get('text_payment_processing'));
$orderStatusId = isset($this->orderInfo['order_status_id']) ? (int)$this->orderInfo['order_status_id'] : null;
if ((null !== $orderStatusId) && ($orderStatusId !== $this->successOrderStatusId)) {
$this->addOrderHistory($this->pendingOrderStatusId, $this->language->get('text_payment_processing'));
}
$this->response->redirect($this->url->link('checkout/success', '', true)); $this->response->redirect($this->url->link('checkout/success', '', true));
} }
@ -180,14 +186,11 @@ class ControllerExtensionPaymentPayanyway extends Controller {
/** @return string */ /** @return string */
private function getDescription() { private function getDescription() {
$clientFirstName = isset($this->orderInfo['firstname']) ? $this->orderInfo['firstname'] : '';
$clientLastName = isset($this->orderInfo['lastname']) ? $this->orderInfo['lastname'] : '';
$clientName = trim($clientFirstName . ' ' . $clientLastName);
$orderId = isset($this->orderInfo['order_id']) ? $this->orderInfo['order_id'] : null; $orderId = isset($this->orderInfo['order_id']) ? $this->orderInfo['order_id'] : null;
$description = "Оплата заказа" . (!empty($orderId) ? "{$orderId}" : ''); $description = "Оплата заказа" . (!empty($orderId) ? "{$orderId}" : '');
if ('' !== $clientName) { $clientName = $this->getClientName();
if (null !== $clientName) {
$description .= " от {$clientName}"; $description .= " от {$clientName}";
} }
@ -230,16 +233,14 @@ class ControllerExtensionPaymentPayanyway extends Controller {
/** @return string */ /** @return string */
private function getSubscriberId() { private function getSubscriberId() {
$email = isset($this->orderInfo['email']) $email = $this->getClientEmail();
? filter_var($this->orderInfo['email'], FILTER_SANITIZE_EMAIL) if (null !== $email) {
: '';
if ('' !== $email) {
return $email; return $email;
} }
return isset($this->orderInfo['telephone']) $phone = $this->getClientPhone();
? preg_replace('/[^0-9+]/', '', $this->orderInfo['telephone'])
: ''; return (null !== $phone) ? $phone : '';
} }
/** /**
@ -428,7 +429,7 @@ class ControllerExtensionPaymentPayanyway extends Controller {
$deliveryPrice = $this->getDeliveryPrice(); $deliveryPrice = $this->getDeliveryPrice();
$data['inventory'] = $this->getInventoryJson($products) ?: null; $data['inventory'] = $this->getInventoryJson($products) ?: null;
$data['client'] = $callbackData['MNT_SUBSCRIBER_ID']; $data['client'] = $this->getClientInfoJson() ?: null;
$data['sno'] = null; $data['sno'] = null;
$data['delivery'] = (null !== $deliveryPrice) ? $this->formatPrice($deliveryPrice) : null; $data['delivery'] = (null !== $deliveryPrice) ? $this->formatPrice($deliveryPrice) : null;
@ -516,6 +517,30 @@ class ControllerExtensionPaymentPayanyway extends Controller {
return json_encode($inventory, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); return json_encode($inventory, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
} }
/** @return false|string */
private function getClientInfoJson()
{
$clientInfo = array();
$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;
}
if (empty($clientInfo)) {
return false;
}
return json_encode(array($clientInfo), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
}
/** /**
* @param int $orderStatusId * @param int $orderStatusId
* @return string * @return string
@ -599,6 +624,41 @@ class ControllerExtensionPaymentPayanyway extends Controller {
return (false !== $xml) ? $xml : 'FAIL'; return (false !== $xml) ? $xml : 'FAIL';
} }
/**
* @return non-empty-string|null
*/
private function getClientName()
{
$firstname = isset($this->orderInfo['firstname']) ? $this->orderInfo['firstname'] : '';
$lastname = isset($this->orderInfo['lastname']) ? $this->orderInfo['lastname'] : '';
$name = trim($firstname . ' ' . $lastname);
return ('' !== $name) ? $this->validateString($name, self::CLIENT_NAME_MAX_LENGTH) : null;
}
/**
* @return non-empty-string|null
*/
private function getClientEmail()
{
$email = isset($this->orderInfo['email']) ? $this->orderInfo['email'] : '';
$email = trim((string)$email);
return ('' !== $email) ? filter_var($email, FILTER_SANITIZE_EMAIL) : null;
}
/**
* @return non-empty-string|null
*/
private function getClientPhone()
{
$telephone = isset($this->orderInfo['telephone']) ? $this->orderInfo['telephone'] : '';
$digits = preg_replace('/\D/', '', trim((string)$telephone));
return ('' !== $digits) ? '+' . $digits : null;
}
/** /**
* @param array<string, mixed> $params * @param array<string, mixed> $params
* @param string $key * @param string $key

View File

@ -1,5 +1,6 @@
<?php <?php
// Text // Text
$_['text_locale'] = 'en';
$_['text_title'] = 'PayAnyWay (MIR, VISA, MasterCard and 30+ other ways)'; $_['text_title'] = 'PayAnyWay (MIR, VISA, MasterCard and 30+ other ways)';
$_['text_ap_pay_with'] = 'Pay with'; $_['text_ap_pay_with'] = 'Pay with';
$_['text_ap_and_other'] = 'or another payment method'; $_['text_ap_and_other'] = 'or another payment method';

View File

@ -1,5 +1,6 @@
<?php <?php
// Text // Text
$_['text_locale'] = 'ru';
$_['text_title'] = 'PayAnyWay (МИР, Visa, MasterCard и более 30-и способов оплаты)'; $_['text_title'] = 'PayAnyWay (МИР, Visa, MasterCard и более 30-и способов оплаты)';
$_['text_ap_pay_with'] = 'Оплатить с'; $_['text_ap_pay_with'] = 'Оплатить с';
$_['text_ap_and_other'] = 'или другой способ оплаты'; $_['text_ap_and_other'] = 'или другой способ оплаты';

View File

@ -10,6 +10,7 @@
<input type="hidden" name="MNT_SUCCESS_URL" value="{{ MNT_SUCCESS_URL }}"/> <input type="hidden" name="MNT_SUCCESS_URL" value="{{ MNT_SUCCESS_URL }}"/>
<input type="hidden" name="MNT_FAIL_URL" value="{{ MNT_FAIL_URL }}"/> <input type="hidden" name="MNT_FAIL_URL" value="{{ MNT_FAIL_URL }}"/>
<input type="hidden" name="MNT_RETURN_URL" value="{{ MNT_RETURN_URL }}"/> <input type="hidden" name="MNT_RETURN_URL" value="{{ MNT_RETURN_URL }}"/>
<input type="hidden" name="moneta.locale" value="{{ moneta_locale }}"/>
<input type="hidden" name="MNT_CMS" value="{{ MNT_CMS }}"/> <input type="hidden" name="MNT_CMS" value="{{ MNT_CMS }}"/>
<div class="buttons"> <div class="buttons">
<div class="{% if ap_use %} text-center {% else %} pull-right {% endif %}"> <div class="{% if ap_use %} text-center {% else %} pull-right {% endif %}">