Files

526 lines
22 KiB
PHP

<?php
declare(strict_types=1);
require_once dirname(__DIR__) . '/class/autoload.php';
use MonetaPhpShop\host\Database;
use MonetaPhpShop\host\ErrorLogLogger;
use MonetaPhpShop\host\HostCharset;
use MonetaPhpShop\host\HostVatRates;
use MonetaPhpShop\host\SettingsRepository;
use MonetaPhpShop\host\ShopContext;
use MonetaPhpShop\order\OrderStatusOptions;
use MonetaPhpShop\protocol\PaymentServer;
use MonetaPhpShop\receipt\PaymentMethod;
use MonetaPhpShop\receipt\PaymentObject;
use MonetaPhpShop\receipt\TaxSystem;
use MonetaPhpShop\receipt\VatRateWarnings;
use MonetaPhpShop\receipt\VatSetting;
use MonetaPhpShop\SelectOptions;
use MonetaPhpShop\Settings;
use MonetaPhpShop\SettingsWriteGuard;
$PHPShopOrm = new PHPShopOrm($PHPShopModules->getParam('base.moneta.moneta_system'));
/**
* Ïðàâî «Ìîäóëè: ðåäàêòèðîâàíèå» è çàïðîñ ñî ñòðàíèöû ìàãàçèíà — äî ëþáîé çàïèñè íàñòðîåê.
* ßäðî ñàìî ïðîâåðÿåò ïðàâà, òîëüêî åñëè êëèåíò ïðèñëàë ñóôôèêñ `.modules.edit` â èìåíè
* äåéñòâèÿ, ïîýòîìó ïðîâåðÿåì çäåñü ({@see SettingsWriteGuard}). Ïðè îòêàçå âûâîäèò ñîîáùåíèå,
* êàê ÿäðî ïðè íåõâàòêå ïðàâ.
*/
function monetaSettingsWriteAllowed(): bool
{
global $PHPShopBase;
$reason = SettingsWriteGuard::denialReason(
(bool) $PHPShopBase->Rule->CheckedRules('modules', 'edit'),
$_SERVER,
);
if ($reason === null) {
return true;
}
$reasons = [
SettingsWriteGuard::DENIED_RIGHTS => 'ó àäìèíèñòðàòîðà íåò ïðàâà «Ìîäóëè: ðåäàêòèðîâàíèå»',
SettingsWriteGuard::DENIED_METHOD => 'çàïðîñ íå POST (ïåðåõîä ïî ññûëêå)',
SettingsWriteGuard::DENIED_ORIGIN => 'çàïðîñ îòïðàâëåí íå ñî ñòðàíèöû ìàãàçèíà (Origin/Referer)',
];
(new ErrorLogLogger())->error('Íàñòðîéêè íå ñîõðàíåíû: ' . ($reasons[$reason] ?? $reason) . '.');
if (isset($_REQUEST['ajax'])) {
exit(json_encode(['success' => false]));
}
if ($reason === SettingsWriteGuard::DENIED_RIGHTS) {
$PHPShopBase->Rule->BadUserFormaWindow();
} else {
echo '<div class="alert alert-danger" role="alert">' . HostCharset::toPage(
'Íàñòðîéêè íå ñîõðàíåíû: çàïðîñ ïðèø¸ë íå ñî ñòðàíèöû ýòîãî ìàãàçèíà. '
. 'Îòêðîéòå íàñòðîéêè ìîäóëÿ çàíîâî è íàæìèòå «Ïðèìåíèòü».',
) . '</div>';
}
return false;
}
/**
* Êíîïêà «Îáíîâèòü ìîäóëü»: SQL èç updates/<âåðñèÿ â ÁÄ>/ è íîâàÿ âåðñèÿ èç module.xml.
*/
function actionBaseUpdate()
{
global $PHPShopModules, $PHPShopOrm;
if (!monetaSettingsWriteAllowed()) {
return true;
}
$PHPShopOrm->clean();
$option = $PHPShopOrm->select();
$newVersion = $PHPShopModules->getUpdate($option['version']);
$PHPShopOrm->clean();
$action = $PHPShopOrm->update(['version_new' => $newVersion]);
header('Location: ?path=modules&id=' . urlencode((string) $_GET['id']));
return $action;
}
function actionUpdate()
{
global $PHPShopOrm, $PHPShopModules;
if (!monetaSettingsWriteAllowed()) {
return true;
}
// Çàùèòà íà âðåìÿ ìåæäó çàìåíîé ôàéëîâ è êíîïêîé «Îáíîâèòü ìîäóëü». Ïîêà îíà íå íàæàòà,
// òàáëèöà íàñòðîåê — åù¸ îò âñòðîåííîãî ìîäóëÿ «Ìîíåòà» 1.0: êîëîíîê account_id,
// integrity_code è îñòàëüíûõ íåò (èõ äîáàâëÿåò updates/1.2/update_module.sql). UPDATE ïî íèì
// óïàë áû, à ÿäðî íå ïîêàçûâàåò îøèáêó — ââåä¸ííîå ïðîïàëî áû. Ïîýòîìó ñîõðàíåíèå
// ïðîïóñêàåì; íà âêëàäêå «Îñíîâíîå» â ýòî âðåìÿ âèñèò ïðåäóïðåæäåíèå (actionStart()).
// Ïîñëå ìèãðàöèè ïðîâåðêà âñåãäà ïðîõîäèò: ýòî îäèí SELECT ñòðîêè íàñòðîåê íà «Ïðèìåíèòü».
// clean() — ñáðîñ ñîñòîÿíèÿ ORM ÿäðà äî è ïîñëå select(), êàê â actionBaseUpdate().
$PHPShopOrm->clean();
$row = $PHPShopOrm->select();
if (!is_array($row) || SettingsRepository::needsUpgrade($row)) {
header('Location: ?path=modules&id=' . urlencode((string) $_GET['id']));
return false;
}
$PHPShopOrm->clean();
// Âèòðèíû ìóëüòèñàéòà, íà êîòîðûõ âêëþ÷¸í ìîäóëü.
$PHPShopModules->updateOption($_GET['id'], $_POST['servers'] ?? null);
$post = static function (string $name): string {
$value = $_POST[$name] ?? '';
return is_string($value) ? trim($value) : '';
};
$update = [
'payment_server_new' => PaymentServer::fromSetting($post('payment_server_new'))->getValue(),
'test_mode_new' => $post('test_mode_new') === '1' ? '1' : '0',
'title_end_new' => strip_tags($post('title_end_new')),
'fiscalization_new' => $post('fiscalization_new') === '1' ? '1' : '0',
'sno_new' => TaxSystem::fromSetting($post('sno_new'))->getValue(),
'payment_method_new' => PaymentMethod::fromSetting($post('payment_method_new'))->getValue(),
'payment_object_new' => PaymentObject::fromSetting($post('payment_object_new'))->getValue(),
'goods_vat_new' => VatSetting::fromSetting($post('goods_vat_new'))->getValue(),
'delivery_vat_new' => VatSetting::fromSetting($post('delivery_vat_new'))->getValue(),
'status_new' => (int) $post('status_new'),
'paid_status_new' => (int) $post('paid_status_new') > 0
? (int) $post('paid_status_new')
: Settings::STATUS_PAID_BY_GATEWAY,
];
$receiptEmail = $post('receipt_email_new');
$update['receipt_email_new'] = strlen($receiptEmail) <= 64
&& filter_var($receiptEmail, FILTER_VALIDATE_EMAIL) !== false
? $receiptEmail
: '';
$accountId = preg_replace('/[^0-9]/', '', $post('account_id_new')) ?? '';
if ($accountId !== '') {
$update['account_id_new'] = $accountId;
}
$integrityCode = $post('integrity_code_new');
if ($integrityCode !== '') {
$update['integrity_code_new'] = $integrityCode;
}
// «Email äëÿ ÷åêîâ» îáÿçàòåëåí ïðè ôèñêàëèçàöèè: áåç àäðåñà âêëþ÷åíèå íå ñîõðàíÿåòñÿ, à óæå
// âêëþ÷¸ííàÿ ôèñêàëèçàöèÿ ìîë÷à íå âûêëþ÷àåòñÿ — î ïóñòîì àäðåñå ïðåäóïðåæäàåò actionStart().
if ($update['fiscalization_new'] === '1' && $update['receipt_email_new'] === '') {
$update['fiscalization_new'] = ((string) ($row['fiscalization'] ?? '0') === '1') ? '1' : '0';
}
$PHPShopOrm->debug = false;
$action = $PHPShopOrm->update($update);
header('Location: ?path=modules&id=' . urlencode((string) $_GET['id']));
return $action;
}
function actionStart()
{
global $PHPShopGUI, $PHPShopOrm;
PHPShopObj::loadClass('order');
$data = $PHPShopOrm->select();
$statuses = (new PHPShopOrderStatusArray())->getArray();
$statuses = is_array($statuses) ? $statuses : [];
$settings = Settings::fromRow(is_array($data) ? $data : []);
$context = new ShopContext();
// Íà ìàãàçèíå ñ áàçîé utf-8 ÿäðî ïåðåêîäèðóåò òîëüêî ñòðîêè, êîòîðûå ñàìî ïðîïóñêàåò ÷åðåç
// __() (ïîäïèñè ïîëåé, ïîäñêàçêè, âêëàäêè). Òåêñòû setAlert(..., false), ïóíêòû setSelect()
// è ñîáñòâåííàÿ ðàçìåòêà âûâîäÿòñÿ êàê åñòü — èõ ïåðåêîäèðóåò ìîäóëü. Ñòðîêè èç ÁÄ
// (ñòàòóñû çàêàçà) óæå â êîäèðîâêå ñòðàíèöû.
$page = static function (string $text): string {
return HostCharset::toPage($text);
};
$Tab1 = '';
$needsUpgrade = is_array($data) && SettingsRepository::needsUpgrade($data);
// Êíîïêà «Îáíîâèòü ìîäóëü» ÿäðà îòïðàâëÿåò ýòó æå ôîðìó: ïóñòûå îáÿçàòåëüíûå ïîëÿ ñòàðîé
// ñõåìû áðàóçåð íå ïðîïóñòèë áû, è êíîïêà íå ñðàáàòûâàëà áû.
$requiredText = $needsUpgrade ? 'text' : 'text.required';
if ($needsUpgrade) {
$Tab1 .= $PHPShopGUI->setAlert(
HostCharset::toPage(
'Ôàéëû ìîäóëÿ îáíîâëåíû, à íàñòðîéêè åù¸ îò âñòðîåííîãî ìîäóëÿ «Ìîíåòà». Íàæìèòå «Îáíîâèòü ìîäóëü»'
. ' íà âêëàäêå «Î ìîäóëå» - íîìåð ñ÷¸òà è êîä ïðîâåðêè öåëîñòíîñòè ïåðåíåñóòñÿ. Äî ýòîãî ïðè¸ì'
. ' îïëàò âûêëþ÷åí, à èçìåíåíèÿ íà ýòîé âêëàäêå íå ñîõðàíÿþòñÿ.',
),
'warning',
false,
);
}
$Tab1 .= $PHPShopGUI->setField(
'Íîìåð ñ÷¸òà',
$PHPShopGUI->setInput($requiredText, 'account_id_new', $settings->getAccountId(), false, 300)
. $PHPShopGUI->setHelp('Âàø íîìåð ðàñøèðåííîãî ñ÷¸òà'),
);
// Ñîõðàí¸ííûé êîä â HTML íå âûâîäèòñÿ: ïóñòîå ïîëå ïðè ñîõðàíåíèè — «íå ìåíÿòü» (actionUpdate()).
// Ðàçìåòêà ñâîÿ: setInput() ÿäðà íå óìååò autocomplete, à áåç new-password áðàóçåð ïîäñòàâèë áû
// ñþäà ñîõðàí¸ííûé ïàðîëü àäìèíèñòðàòîðà è ïðè ñîõðàíåíèè çàò¸ð áû èì êîä.
$hasIntegrityCode = is_array($data) && (string) ($data['integrity_code'] ?? '') !== '';
$Tab1 .= $PHPShopGUI->setField(
'Êîä ïðîâåðêè öåëîñòíîñòè äàííûõ',
'<input class="form-control input-sm" type="password" name="integrity_code_new" value=""'
. ' autocomplete="new-password" style="width:300px"'
. ($hasIntegrityCode ? ' placeholder="' . HostCharset::toPage('Ñîõðàí¸í') . '"' : '')
. (($hasIntegrityCode || $needsUpgrade) ? '' : ' required')
. '>'
. $PHPShopGUI->setHelp(
'Êîä ïðîâåðêè öåëîñòíîñòè äàííûõ, óêàçàííûé â íàñòðîéêàõ ðàñøèðåííîãî ñ÷¸òà'
. ($hasIntegrityCode ? '. Ñîõðàí¸ííûé êîä íå ïîêàçûâàåòñÿ — îñòàâüòå ïîëå ïóñòûì, ÷òîáû åãî íå ìåíÿòü' : ''),
),
);
$servers = [
[HostCharset::toPage('Áîåâîé'), PaymentServer::PROD, $settings->getPaymentServer()->getValue()],
[HostCharset::toPage('Äåìî'), PaymentServer::DEMO, $settings->getPaymentServer()->getValue()],
];
$Tab1 .= $PHPShopGUI->setField('Ñåðâåð ïëàòåæåé', $PHPShopGUI->setSelect('payment_server_new', $servers, 300));
$Tab1 .= $PHPShopGUI->setField(
'Òåñòîâûé ðåæèì',
$PHPShopGUI->setCheckbox('test_mode_new', '1', '', $settings->isTestMode() ? 1 : 0)
. $PHPShopGUI->setHelp('Äîëæåí ñîâïàäàòü ñ ôëàãîì «Òåñòîâûé ðåæèì» â íàñòðîéêàõ ðàñøèðåííîãî ñ÷¸òà'),
);
// Òîëüêî äëÿ ÷òåíèÿ, ñ êíîïêîé êîïèðîâàíèÿ: navigator.clipboard åñòü ëèøü íà HTTPS è localhost,
// íà HTTP-àäìèíêå — çàïàñíîé ïóòü ÷åðåç âûäåëåíèå ïîëÿ è execCommand('copy').
$callbackUrl = htmlspecialchars($context->callbackUrl(), ENT_QUOTES, 'Windows-1251');
$Tab1 .= $PHPShopGUI->setField(
'URL äëÿ óâåäîìëåíèé',
HostCharset::toPage(
'<div class="input-group" style="max-width:600px">'
. '<input class="form-control input-sm" type="text" id="moneta_callback_url" value="',
)
// Àäðåñ — èç èìåíè ñåðâåðà, íå ëèòåðàë ìîäóëÿ: â êîäèðîâêå ñòðàíèöû, íå ïåðåêîäèðóåòñÿ.
. $callbackUrl
. HostCharset::toPage(
'"'
. ' readonly onfocus="this.select()">'
. '<span class="input-group-btn"><button type="button" class="btn btn-default btn-sm" onclick="'
. "var f=document.getElementById('moneta_callback_url'),b=this,t=b.textContent,"
. "d=function(){b.textContent='Ñêîïèðîâàíî';setTimeout(function(){b.textContent=t;},1500);},"
. "c=function(){f.select();try{document.execCommand('copy');d();}catch(e){}};"
. "if(navigator.clipboard&&window.isSecureContext){navigator.clipboard.writeText(f.value).then(d,c);}else{c();}"
. '">Êîïèðîâàòü</button></span></div>',
)
. $PHPShopGUI->setHelp(
'Óêàæèòå ýòîò àäðåñ â íàñòðîéêàõ ðàñøèðåííîãî ñ÷¸òà êàê Check URL è Pay URL',
),
);
$Tab1 .= $PHPShopGUI->setField(
'Îïèñàíèå îïëàòû',
$PHPShopGUI->setTextarea(
'title_end_new',
htmlspecialchars($settings->getPaymentDescription(), ENT_QUOTES, 'Windows-1251'),
false,
300,
80,
)
. $PHPShopGUI->setHelp(
'Òåêñò íàä ñóììîé è êíîïêîé îïëàòû íà ñòðàíèöå «Çàêàç îôîðìëåí» è â ëè÷íîì êàáèíåòå. Ïóñòî — áåç òåêñòà',
),
);
$Tab1 .= $PHPShopGUI->setField(
'Ôèñêàëèçàöèÿ ÷åêîâ',
$PHPShopGUI->setCheckbox('fiscalization_new', '1', '', $settings->isFiscalization() ? 1 : 0)
. $PHPShopGUI->setHelp('Ôèñêàëèçàöèÿ ÷åêîâ ïî 54-ÔÇ ñðåäñòâàìè ñèñòåìû ÌÎÍÅÒÀ ñåðâèñîì kassa.payanyway.ru'),
);
// Ïîëÿ ÷åêà äëÿ êàññû âèäíû òîëüêî ïðè âêëþ÷¸ííîé ôèñêàëèçàöèè; çíà÷åíèÿ
// ñîõðàíÿþòñÿ è ïðè ñêðûòûõ ïîëÿõ.
$fiscal = 'moneta-fiscal';
if ($settings->isFiscalization() && $settings->getReceiptEmail() === '') {
$Tab1 .= $PHPShopGUI->setAlert(
HostCharset::toPage(
'Ôèñêàëèçàöèÿ âêëþ÷åíà, à «Email äëÿ ÷åêîâ» íå çàïîëíåí. Óêàæèòå àäðåñ: íà íåãî ïðèä¸ò ÷åê,'
. ' åñëè ó ïîêóïàòåëÿ íåò íè email, íè òåëåôîíà.',
),
'warning',
false,
);
}
$Tab1 .= $PHPShopGUI->setField(
'Email äëÿ ÷åêîâ',
$PHPShopGUI->setInput(
'email',
'receipt_email_new',
htmlspecialchars($settings->getReceiptEmail(), ENT_QUOTES, 'Windows-1251'),
false,
300,
)
. $PHPShopGUI->setHelp(
'Ïîäñòàâëÿåòñÿ â ÷åê, åñëè ó ïîêóïàòåëÿ íåò íè email, íè òåëåôîíà — ÷åê ïðèä¸ò íà ýòîò àäðåñ, à ÔÈÎ ïîêóïàòåëÿ â ÷åêå ñîõðàíèòñÿ',
),
1,
null,
$fiscal,
);
$Tab1 .= $PHPShopGUI->setField(
'Ñèñòåìà íàëîãîîáëîæåíèÿ',
$PHPShopGUI->setSelect(
'sno_new',
SelectOptions::fromLabels(array_map($page, TaxSystem::LABELS), $settings->getTaxSystem()->getValue()),
300,
)
. $PHPShopGUI->setHelp('Åñëè íå ïåðåäàâàòü, êàññà âîçüì¸ò ñèñòåìó íàëîãîîáëîæåíèÿ èç ñâîèõ íàñòðîåê'),
1,
null,
$fiscal,
);
// Ñòàâêè PHPShop íå èç ïåðå÷íÿ êàññû (ñâîáîäíîå ÷èñëî, íàïðèìåð îïå÷àòêà 23): ïîçèöèè ñ íèìè
// óõîäÿò â ÷åê «áåç ÍÄÑ», î êàæäîé òàêîé ïîçèöèè ìîäóëü ïèøåò è â æóðíàë PHP.
$vatWarnings = [];
try {
$vatRates = new HostVatRates(Database::fromHost());
$vatWarnings = VatRateWarnings::find(
$settings->isFiscalization(),
$vatRates->isEnabled(),
$settings->getGoodsVat(),
$settings->getDeliveryVat(),
$vatRates->systemPercent(),
$vatRates->enabledDeliveries(),
);
} catch (\Throwable $exception) {
(new ErrorLogLogger())->error('Ñòàâêè ÍÄÑ PHPShop íå ïðîâåðåíû: ' . $exception->getMessage());
}
if ($vatWarnings !== []) {
$escape = static function (string $text): string {
return htmlspecialchars($text, ENT_QUOTES, 'Windows-1251');
};
$Tab1 .= $PHPShopGUI->setAlert(
HostCharset::toPage(
'Ñòàâêè ÍÄÑ íå èç ïåðå÷íÿ êàññû — ýòè ïîçèöèè óõîäÿò â ÷åê «áåç ÍÄÑ»: '
. implode('; ', array_map($escape, $vatWarnings))
. '. Èñïðàâüòå «Çíà÷åíèå ÍÄÑ» â ðàçäåëå «Íàñòðîéêà öåí» èëè â ñïîñîáå äîñòàâêè'
. ' ëèáî âûáåðèòå ñòàâêó â ïîëÿõ íèæå.',
),
'warning',
false,
);
}
$Tab1 .= $PHPShopGUI->setField(
'ÍÄÑ íà òîâàðû',
$PHPShopGUI->setSelect(
'goods_vat_new',
SelectOptions::fromLabels(
array_map($page, VatSetting::labels('Èç íàñòðîåê ðàçäåëà «Íàñòðîéêà öåí»')),
$settings->getGoodsVat()->getValue(),
),
300,
)
. $PHPShopGUI->setHelp('Îäíà ñòàâêà íà âñå òîâàðû èëè «Çíà÷åíèå ÍÄÑ» èç ðàçäåëà «Íàñòðîéêà öåí»'),
1,
null,
$fiscal,
);
$Tab1 .= $PHPShopGUI->setField(
'ÍÄÑ íà äîñòàâêó',
$PHPShopGUI->setSelect(
'delivery_vat_new',
SelectOptions::fromLabels(
array_map($page, VatSetting::labels('Èç íàñòðîåê ñïîñîáà äîñòàâêè')),
$settings->getDeliveryVat()->getValue(),
),
300,
)
. $PHPShopGUI->setHelp('Îäíà ñòàâêà íà äîñòàâêó èëè «Çíà÷åíèå ÍÄÑ» ñïîñîáà äîñòàâêè.'),
1,
null,
$fiscal,
);
$Tab1 .= $PHPShopGUI->setField(
'Ïðèçíàê ñïîñîáà ðàñ÷¸òà',
$PHPShopGUI->setSelect(
'payment_method_new',
SelectOptions::fromLabels(array_map($page, PaymentMethod::LABELS), $settings->getPaymentMethod()->getValue()),
300,
)
. $PHPShopGUI->setHelp('Ó âñåõ ïîçèöèé ÷åêà, âêëþ÷àÿ äîñòàâêó'),
1,
null,
$fiscal,
);
$Tab1 .= $PHPShopGUI->setField(
'Ïðèçíàê ïðåäìåòà ðàñ÷¸òà',
$PHPShopGUI->setSelect(
'payment_object_new',
SelectOptions::fromLabels(array_map($page, PaymentObject::LABELS), $settings->getPaymentObject()->getValue()),
300,
)
. $PHPShopGUI->setHelp('Ó òîâàðîâ; äîñòàâêà â ÷åêå — âñåãäà «Óñëóãà»'),
1,
null,
$fiscal,
);
// Ñêðûòîå ïîëå email ñ îøèáêîé áðàóçåð íå äàë áû îòïðàâèòü, à ïîäñêàçêó íå ïîêàçàë áû —
// íà âðåìÿ ñêðûòèÿ îíî ñòàíîâèòñÿ òåêñòîâûì è íåîáÿçàòåëüíûì (àäðåñ âñ¸ ðàâíî ïðîâåðÿåò
// actionUpdate()); ïðè ôèñêàëèçàöèè «Email äëÿ ÷åêîâ» îáÿçàòåëåí.
$Tab1 .= '<script>jQuery(function ($) {
const box = $("#fiscalization_new");
const sync = function () {
const on = box.is(":checked");
$(".' . $fiscal . '").toggle(on);
$("[name=receipt_email_new]").attr("type", on ? "email" : "text").prop("required", on);
};
box.on("change", sync);
sync();
});</script>';
$Tab1 .= $PHPShopGUI->setField(
'Îïëàòà ïðè ñòàòóñå',
$PHPShopGUI->setSelect(
'status_new',
OrderStatusOptions::build($statuses, $settings->getPayableStatus(), $page('Íîâûé çàêàç'), Settings::STATUS_NEW),
300,
),
);
$Tab1 .= $PHPShopGUI->setField(
'Ñòàòóñ ïîñëå îïëàòû',
$PHPShopGUI->setSelect(
'paid_status_new',
OrderStatusOptions::build(
$statuses,
$settings->getPaidStatus(),
$page('Îïëà÷åíî ïëàòåæíûìè ñèñòåìàìè'),
Settings::STATUS_PAID_BY_GATEWAY,
),
300,
),
);
// Òîëüêî ñèìâîëû cp1251: ñáîðêà ïåðåêîäèðóåò ôàéë. Ïàíåëü ñîáèðàåòñÿ çäåñü, à íå ÷åðåç
// setInfo(): òîò íà UTF-8-áàçå ïðîïóñêàåò áëîê ÷åðåç __() ñî strip_tags è âûðåçàåò òàáëèöó.
$link = static function (string $url, string $text): string {
return '<a href="' . $url . '" target="_blank" rel="noopener noreferrer">' . $text . '</a>';
};
$kassa = $link('https://kassa.payanyway.ru/', 'kassa.payanyway.ru');
$accountRows = [
['Ïñåâäîíèì', 'ëþáîé, íàïðèìåð <code>Ìîíåòà</code>'],
['Òåñòîâûé ðåæèì', 'êàê â íàñòðîéêå ìîäóëÿ'],
['Check URL è Pay URL', '<code>' . $callbackUrl . '</code>'],
['HTTP-ìåòîä (Check URL, Pay URL)', '<code>POST</code> èëè <code>GET</code>'],
[
'Êîä ïðîâåðêè öåëîñòíîñòè äàííûõ',
'ïðîèçâîëüíûé íàáîð ñèìâîëîâ; òîò æå êîä óêàæèòå â íàñòðîéêàõ ìîäóëÿ',
],
['Ïîäïèñü ôîðìû îïëàòû îáÿçàòåëüíà', '<code>Äà</code>'],
['Ìîæíî ïåðåîïðåäåëÿòü íàñòðîéêè â URL', '<code>Äà</code>'],
['Success URL', 'îñòàâèòü ïóñòûì'],
['Fail URL', 'îñòàâèòü ïóñòûì'],
['InProgress URL', 'îñòàâèòü ïóñòûì'],
['Return URL', 'îñòàâèòü ïóñòûì'],
];
$accountTable = '';
foreach ($accountRows as [$field, $value]) {
$accountTable .= '<tr><td>' . $field . '</td><td>' . $value . '</td></tr>';
}
$info = '<h4>Íàñòðîéêà ñ÷¸òà â ëè÷íîì êàáèíåòå ' . $link('https://moneta.ru/', 'MONETA.RU') . '</h4>
<ol>
<li>' . $link('https://payanyway.ru/partnerRegistration.htm', 'Çàðåãèñòðèðóéòåñü') . '
â ïëàò¸æíîé ñèñòåìå PayAnyWay è çàïîëíèòå âñå íåîáõîäèìûå äàííûå. Äîæäèòåñü ïðîâåðêè àêêàóíòà
è ñîçäàéòå ðàñøèðåííûé ñ÷¸ò.</li>
<li>Çàïîëíèòå íàñòðîéêè ðàñøèðåííîãî ñ÷¸òà â ëè÷íîì êàáèíåòå: «Ìîé ñ÷¸ò» -> «Óïðàâëåíèå
ñ÷åòàìè» -> «Ðåäàêòèðîâàòü ñ÷¸ò» -> «Ïîêàçàòü äîïîëíèòåëüíûå ïîëÿ».
<table class="table table-bordered table-condensed" style="margin-top:10px">
<thead><tr><th>Ïîëå â ëè÷íîì êàáèíåòå</th><th>Çíà÷åíèå</th></tr></thead>
<tbody>' . $accountTable . '</tbody>
</table>
</li>
<li>Íà âêëàäêå «Îñíîâíîå» óêàæèòå íîìåð ñ÷¸òà è òîò æå êîä ïðîâåðêè öåëîñòíîñòè äàííûõ.
Íà äåìî-ïëîùàäêå demo.moneta.ru íîìåð ñ÷¸òà ñâîé.</li>
<li>Äëÿ ôèñêàëèçàöèè ÷åêîâ ïî 54-ÔÇ ñðåäñòâàìè çà ðàìêàìè PHPShop íàñòðîéòå âàøó êàññó â ñåðâèñå
' . $kassa . ', â íàñòðîéêàõ ðàñøèðåííîãî ñ÷¸òà â MONETA.RU óñòàíîâèòå Pay URL
<code>https://kassa.payanyway.ru/index.php?do=invoicepayurl</code>, à â íàñòðîéêàõ êàññû
ïðîïèøèòå Pay URL âàøåãî èíòåðíåò-ìàãàçèíà ' . '<code>' . $callbackUrl . '</code>' . '.  ýòîì ñëó÷àå ÷åê ïî 54-ÔÇ
áóäåò ïðîáèâàòüñÿ ÷åðåç ' . $kassa . ', à çàïðîñ íà Pay URL ìàãàçèíà áóäåò ïðîõîäèòü
÷åðåç ýòîò ñåðâèñ òðàíçèòîì.</li>
</ol>
<p><span class="text-danger">Âàæíî!</span> Äëÿ êèðèëëè÷åñêîãî äîìåíà Check URL è Pay URL óêàæèòå
â êîäèðîâêå ' . $link('https://2ip.ru/punycode/', 'Punycode') . '.</p>
<h4>Âûêëþ÷åíèå ìîäóëÿ</h4>
<p>Âûêëþ÷åíèå ìîäóëÿ â PHPShop óäàëÿåò åãî òàáëèöû: íàñòðîéêè ïðèä¸òñÿ ââåñòè çàíîâî.</p>';
$Tab2 = '<div class="panel panel-default"><div class="panel-body">' . HostCharset::toPage($info) . '</div></div>';
$Tab3 = $PHPShopGUI->setPay(false, false, $data['version'], true);
$PHPShopGUI->setTab(['Îñíîâíîå', $Tab1, true], ['Èíñòðóêöèÿ', $Tab2], ['Î ìîäóëå', $Tab3]);
$ContentFooter = $PHPShopGUI->setInput('hidden', 'rowID', $data['id'])
. $PHPShopGUI->setInput('submit', 'saveID', 'Ïðèìåíèòü', 'right', 80, '', 'but', 'actionUpdate.modules.edit');
$PHPShopGUI->setFooter($ContentFooter);
return true;
}
// Îáðàáîòêà ñîáûòèé
$PHPShopGUI->getAction();
// Âûâîä ôîðìû ïðè ñòàðòå
$PHPShopGUI->setLoader($_POST['saveID'] ?? null, 'actionStart');