Merge branch 'main' into 'release'
fix: changed check response from xml to json See merge request products/cashier/cms/OpenCart4!6
This commit is contained in:
commit
a9bc7f315c
12
README.md
12
README.md
@ -5,7 +5,7 @@
|
||||

|
||||

|
||||
|
||||
> **📦 Версия модуля: 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
|
||||
|
||||
@ -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
|
||||
);
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 150 KiB After Width: | Height: | Size: 10 KiB |
@ -28,7 +28,7 @@
|
||||
{{ text_edit }}
|
||||
</div>
|
||||
<div class="card-header text-center">
|
||||
<a href="https://www.payanyway.ru/" target="_blank"><img src="../extension/payanyway/admin/view/image/payment/payanyway.png" alt="PayAnyWay" title="PayAnyWay" width="250" height="29" /></a>
|
||||
<a href="https://www.payanyway.ru/" target="_blank"><img src="../extension/payanyway/admin/view/image/payment/payanyway.png" alt="PayAnyWay" title="PayAnyWay" width="336" height="50" /></a>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form id="form-payment" action="{{ save }}" method="post" data-oc-toggle="ajax">
|
||||
|
||||
@ -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);
|
||||
|
||||
$isXml = str_starts_with($response, '<?xml') || str_contains($response, '<MNT_RESPONSE');
|
||||
header('Content-Type: ' . ($isXml ? 'application/xml' : 'text/plain; charset=UTF-8'));
|
||||
|
||||
if (is_string($response)) {
|
||||
header('Content-Type: ' . self::TEXT_CONTENT_TYPE);
|
||||
echo $response;
|
||||
exit;
|
||||
} else {
|
||||
header('Content-Type: ' . $response['contentType']);
|
||||
echo $response['data'];
|
||||
}
|
||||
|
||||
exit();
|
||||
}
|
||||
|
||||
/** @throws \Exception */
|
||||
private function handleCheckCallback(): void
|
||||
{
|
||||
if (!$this->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<string, mixed>
|
||||
* @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<string, mixed> $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<non-empty-string, mixed> $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<string, mixed> $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<string, mixed> $params */
|
||||
|
||||
@ -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');
|
||||
|
||||
$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() ?? '';
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
<?php
|
||||
// Text
|
||||
$_['text_locale'] = 'en';
|
||||
$_['text_title'] = 'PayAnyWay (MIR, VISA, MasterCard and 30+ other ways)';
|
||||
$_['text_ap_pay_with'] = 'Pay with';
|
||||
$_['text_ap_and_other'] = 'or another payment method';
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
<?php
|
||||
// Text
|
||||
$_['text_locale'] = 'ru';
|
||||
$_['text_title'] = 'PayAnyWay (МИР, Visa, MasterCard и более 30-и способов оплаты)';
|
||||
$_['text_ap_pay_with'] = 'Оплатить с';
|
||||
$_['text_ap_and_other'] = 'или другой способ оплаты';
|
||||
|
||||
@ -87,4 +87,25 @@ trait PayAnyWay
|
||||
$this->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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
<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_RETURN_URL" value="{{ MNT_RETURN_URL }}"/>
|
||||
<input type="hidden" name="moneta.locale" value="{{ moneta_locale }}"/>
|
||||
<input type="hidden" name="MNT_CMS" value="{{ MNT_CMS }}"/>
|
||||
<div class="buttons">
|
||||
<div class="{% if ap_use %} text-center {% else %} pull-right {% endif %}">
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"code": "payanyway",
|
||||
"name": "PayAnyWay",
|
||||
"version": "1.0.1",
|
||||
"version": "1.0.2",
|
||||
"author": "PayAnyWay",
|
||||
"link": "https://www.payanyway.ru/"
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user