feat: moneta 2.0, MONETA.Assistant payment module for PHPShop 6.7+
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace MonetaPhpShop\form;
|
||||
|
||||
use MonetaPhpShop\Money;
|
||||
|
||||
/**
|
||||
* ×èñëî ñóììû äëÿ ïîêóïàòåëÿ òàê æå, êàê åãî ïèøåò âèòðèíà PHPShop: çíàêîâ ïîñëå òî÷êè — ïî
|
||||
* íàñòðîéêå ìàãàçèíà «Çíàêîâ ïîñëå çàïÿòîé â öåíå» (`admoption.price_znak`), òûñÿ÷è ÷åðåç ïðîáåë.
|
||||
* Çíàê âàëþòû äîáàâëÿåò âèòðèíà ({@see \MonetaPhpShop\host\ShopContext::currencyIcon()}).
|
||||
*/
|
||||
final class AmountText
|
||||
{
|
||||
private function __construct() {}
|
||||
|
||||
/**
|
||||
* @param int $decimals çíàêîâ ïîñëå òî÷êè; âíå 0–2 — 0, êàê ó ÿäðà ïðè ïóñòîé íàñòðîéêå
|
||||
*/
|
||||
public static function format(Money $amount, int $decimals): string
|
||||
{
|
||||
$decimals = (($decimals >= 0) && ($decimals <= 2)) ? $decimals : 0;
|
||||
|
||||
return number_format((float) $amount->toDecimal(), $decimals, '.', ' ');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace MonetaPhpShop\form;
|
||||
|
||||
use DateTimeImmutable;
|
||||
use MonetaPhpShop\order\Order;
|
||||
use MonetaPhpShop\PhoneNumber;
|
||||
use MonetaPhpShop\protocol\AssistantProtocol;
|
||||
use MonetaPhpShop\protocol\TransactionId;
|
||||
use MonetaPhpShop\Settings;
|
||||
|
||||
/**
|
||||
* Ïëàò¸æíàÿ ôîðìà MONETA.Assistant.
|
||||
*
|
||||
* Êàæäûé ïîêàç ôîðìû — íîâûé `MNT_TRANSACTION_ID` (`<uid>_<ñóììà>_<YmdHis>UTC`): ïîâòîðíóþ îïëàòó
|
||||
* óæå îïëà÷åííîãî çàêàçà îñòàíàâëèâàåò Check URL.
|
||||
*/
|
||||
final class PaymentForm
|
||||
{
|
||||
/** Ïðåôèêñ ID ïîêóïàòåëÿ PHPShop â `MNT_SUBSCRIBER_ID`. */
|
||||
public const SUBSCRIBER_USER_PREFIX = 'USER_';
|
||||
|
||||
/** Òåêñò êíîïêè ïîñëå íàæàòèÿ; áåç êàâû÷åê è ðàçìåòêè — ïîäñòàâëÿåòñÿ â onsubmit. */
|
||||
private const REDIRECTING = 'Ïåðåõîäèì ê îïëàòå...';
|
||||
|
||||
/** @var string */
|
||||
private $action;
|
||||
|
||||
/** @var array<string, string> */
|
||||
private $fields;
|
||||
|
||||
/**
|
||||
* @param array<string, string> $fields
|
||||
*/
|
||||
private function __construct(string $action, array $fields)
|
||||
{
|
||||
$this->action = $action;
|
||||
$this->fields = $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $currency `MNT_CURRENCY_CODE` ({@see AssistantProtocol::normalizeCurrency()})
|
||||
* @param ReturnUrls $returnUrls àäðåñà âîçâðàòà ïîêóïàòåëÿ
|
||||
* @param string $description `MNT_DESCRIPTION` â êîäèðîâêå âèòðèíû
|
||||
* @param string $cms `MNT_CMS`
|
||||
* @param string $locale `moneta.locale` — ÿçûê ïëàò¸æíîé ôîðìû ({@see AssistantProtocol::normalizeLocale()})
|
||||
*/
|
||||
public static function create(
|
||||
Settings $settings,
|
||||
Order $order,
|
||||
string $currency,
|
||||
DateTimeImmutable $issuedAt,
|
||||
ReturnUrls $returnUrls,
|
||||
string $description,
|
||||
string $cms,
|
||||
string $locale
|
||||
): self {
|
||||
$amount = $order->getAmount();
|
||||
$transactionId = TransactionId::build($order->getUid(), $amount, $issuedAt);
|
||||
$subscriberId = self::subscriberId($order);
|
||||
$testMode = $settings->isTestMode();
|
||||
|
||||
$fields = [
|
||||
'MNT_ID' => $settings->getAccountId(),
|
||||
'MNT_TRANSACTION_ID' => $transactionId,
|
||||
'MNT_CURRENCY_CODE' => $currency,
|
||||
'MNT_AMOUNT' => $amount->toDecimal(),
|
||||
'MNT_TEST_MODE' => AssistantProtocol::testModeFlag($testMode),
|
||||
'MNT_SUBSCRIBER_ID' => $subscriberId,
|
||||
'MNT_SIGNATURE' => $settings->signature()->forPaymentForm(
|
||||
$settings->getAccountId(),
|
||||
$transactionId,
|
||||
$amount,
|
||||
$currency,
|
||||
$subscriberId,
|
||||
$testMode,
|
||||
),
|
||||
'MNT_DESCRIPTION' => $description,
|
||||
'MNT_SUCCESS_URL' => $returnUrls->getSuccess(),
|
||||
'MNT_FAIL_URL' => $returnUrls->getFail(),
|
||||
'MNT_INPROGRESS_URL' => $returnUrls->getInProgress(),
|
||||
'MNT_RETURN_URL' => $returnUrls->getReturn(),
|
||||
'MNT_CMS' => $cms,
|
||||
'moneta.locale' => $locale,
|
||||
];
|
||||
|
||||
return new self($settings->getPaymentServer()->url(), $fields);
|
||||
}
|
||||
|
||||
/**
|
||||
* `MNT_SUBSCRIBER_ID`: email -> òåëåôîí (`+öèôðû`) -> ID ïîêóïàòåëÿ PHPShop; ïóñòî — äàííûõ íåò
|
||||
*/
|
||||
public static function subscriberId(Order $order): string
|
||||
{
|
||||
if ($order->getEmail() !== '') {
|
||||
return $order->getEmail();
|
||||
}
|
||||
|
||||
$phone = PhoneNumber::normalize($order->getPhone());
|
||||
if ($phone !== null) {
|
||||
return $phone;
|
||||
}
|
||||
|
||||
return ($order->getUserId() > 0) ? self::SUBSCRIBER_USER_PREFIX . $order->getUserId() : '';
|
||||
}
|
||||
|
||||
public function getAction(): string
|
||||
{
|
||||
return $this->action;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function getFields(): array
|
||||
{
|
||||
return $this->fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* HTML ôîðìû ñ îäíîé êíîïêîé; ñòðîêè â êîäèðîâêå âèòðèíû (cp1251).
|
||||
*
|
||||
* `accept-charset="UTF-8"`: áðàóçåð ïåðåêîäèðóåò çíà÷åíèÿ èç cp1251 ñòðàíèöû â UTF-8,
|
||||
* êîòîðóþ æä¸ò Ìîíåòà. Êíîïêà ïîñëå íàæàòèÿ áëîêèðóåòñÿ (îò äâîéíîé îòïðàâêè), ïîêà îòêðûâàåòñÿ ñòðàíèöà Ìîíåòû.
|
||||
*/
|
||||
/**
|
||||
* @param string $buttonTitle òåêñò êíîïêè, ýêðàíèðóåòñÿ
|
||||
* @param string $buttonSuffixHtml ãîòîâûé HTML ïîñëå òåêñòà (çíàê âàëþòû âèòðèíû), íå ýêðàíèðóåòñÿ
|
||||
*/
|
||||
public function toHtml(string $buttonTitle, string $buttonSuffixHtml = ''): string
|
||||
{
|
||||
$html = '<form class="moneta-payment-form" method="post" action="' . self::escape($this->action) . '"'
|
||||
. ' accept-charset="UTF-8"'
|
||||
. ' onsubmit="var b=this.querySelector(\'button\');if(b){b.disabled=true;'
|
||||
. 'b.textContent=\'' . self::REDIRECTING . '\';}">';
|
||||
foreach ($this->fields as $name => $value) {
|
||||
$html .= '<input type="hidden" name="' . self::escape($name) . '" value="' . self::escape($value) . '">';
|
||||
}
|
||||
$html .= '<button type="submit" class="btn btn-primary moneta-payment-button">'
|
||||
. self::escape($buttonTitle) . $buttonSuffixHtml . '</button>';
|
||||
|
||||
return $html . '</form>';
|
||||
}
|
||||
|
||||
private static function escape(string $value): string
|
||||
{
|
||||
return htmlspecialchars($value, ENT_QUOTES | ENT_SUBSTITUTE, 'Windows-1251');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace MonetaPhpShop\form;
|
||||
|
||||
use MonetaPhpShop\callback\OrderGateway;
|
||||
use MonetaPhpShop\order\Order;
|
||||
use MonetaPhpShop\protocol\TransactionId;
|
||||
|
||||
/**
|
||||
* Ìîæíî ëè ïîêàçàòü ïîêóïàòåëþ ñòàòóñ çàêàçà íà ñòðàíèöå âîçâðàòà. `MNT_TRANSACTION_ID`
|
||||
* (`<uid>_<ñóììà>_<âðåìÿ>UTC`) óãàäûâàåòñÿ, ïîýòîìó îäíîãî åãî ìàëî — çàêàç äîëæåí ïðèíàäëåæàòü
|
||||
* òîìó, êòî ñìîòðèò:
|
||||
* - âîøåäøèé ïîêóïàòåëü — âëàäåëåö çàêàçà (`phpshop_orders.user`);
|
||||
* - èëè ôîðìà îïëàòû ýòîãî çàêàçà ïîêàçûâàëàñü â ýòîé æå ñåññèè áðàóçåðà: òàê âèäèò ñòàòóñ
|
||||
* ãîñòü, êîòîðûé îôîðìèë çàêàç áåç âõîäà (PHPShop çàâîäèò åìó ïîëüçîâàòåëÿ, íî íå âõîäèò).
|
||||
*/
|
||||
final class ReturnAccess
|
||||
{
|
||||
/** Êëþ÷ `$_SESSION`: çàêàçû, ôîðìà îïëàòû êîòîðûõ ïîêàçûâàëàñü â ýòîé ñåññèè. */
|
||||
public const SESSION_KEY = 'moneta_payable_orders';
|
||||
|
||||
/** Ñêîëüêî çàêàçîâ ïîìíèòü â ñåññèè. */
|
||||
public const SESSION_LIMIT = 20;
|
||||
|
||||
private function __construct() {}
|
||||
|
||||
/**
|
||||
* @param int $sessionUserId `$_SESSION['UsersId']`; 0 — ïîêóïàòåëü íå âîø¸ë
|
||||
* @param mixed $sessionOrders `$_SESSION[SESSION_KEY]`
|
||||
*/
|
||||
public static function findOrder(
|
||||
string $transactionId,
|
||||
OrderGateway $orders,
|
||||
int $sessionUserId,
|
||||
$sessionOrders
|
||||
): ?Order {
|
||||
$parsed = TransactionId::parse($transactionId);
|
||||
$order = ($parsed === null) ? null : $orders->findByUid($parsed->getOrderUid());
|
||||
|
||||
return ($order !== null && self::canView($order, $sessionUserId, $sessionOrders)) ? $order : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $sessionUserId `$_SESSION['UsersId']`; 0 — ïîêóïàòåëü íå âîø¸ë
|
||||
* @param mixed $sessionOrders `$_SESSION[SESSION_KEY]`
|
||||
*/
|
||||
public static function canView(Order $order, int $sessionUserId, $sessionOrders): bool
|
||||
{
|
||||
if (self::isOwner($order, $sessionUserId)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return is_array($sessionOrders) && in_array($order->getId(), $sessionOrders, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Çàêàç âîøåäøåãî ïîêóïàòåëÿ. Ó ãîñòÿ ID 0 — ñîâïàë áû ñ çàêàçàìè áåç ïîëüçîâàòåëÿ.
|
||||
*
|
||||
* @param int $sessionUserId `$_SESSION['UsersId']`; 0 — ïîêóïàòåëü íå âîø¸ë
|
||||
*/
|
||||
public static function isOwner(Order $order, int $sessionUserId): bool
|
||||
{
|
||||
return $sessionUserId > 0 && $order->getUserId() === $sessionUserId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Çàïîìíèòü çàêàç, ôîðìà îïëàòû êîòîðîãî ïîêàçàíà ïîêóïàòåëþ; ñòàðûå âûòåñíÿþòñÿ.
|
||||
*
|
||||
* @param mixed $sessionOrders `$_SESSION[SESSION_KEY]`
|
||||
*
|
||||
* @return array<int, int>
|
||||
*/
|
||||
public static function remember($sessionOrders, int $orderId): array
|
||||
{
|
||||
$orders = is_array($sessionOrders) ? array_values(array_filter($sessionOrders, 'is_int')) : [];
|
||||
$orders = array_values(array_diff($orders, [$orderId]));
|
||||
$orders[] = $orderId;
|
||||
|
||||
return array_slice($orders, -self::SESSION_LIMIT);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,207 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace MonetaPhpShop\form;
|
||||
|
||||
use MonetaPhpShop\order\Order;
|
||||
use MonetaPhpShop\order\PaymentEligibility;
|
||||
use MonetaPhpShop\Settings;
|
||||
|
||||
/**
|
||||
* Ñòðàíèöà âîçâðàòà `/moneta/`: ÷òî ïîêàçàòü ïîêóïàòåëþ. Âîçâðàò — íå ïîäòâåðæäåíèå îïëàòû:
|
||||
* ñòàòóñ çàêàçà ìåíÿåò òîëüêî Pay URL, ïîýòîìó «îïëà÷åí» ïèøåì òîëüêî ïî çàêàçó.
|
||||
*
|
||||
* - Çàêàç èçâåñòåí (íîìåð èç `MNT_TRANSACTION_ID` íàéäåí, è çàêàç ïðèíàäëåæèò ïîêóïàòåëþ —
|
||||
* {@see ReturnAccess}): ðåøàåò åãî ñòàòóñ. Îïëà÷åí èëè îòìåí¸í — òàê
|
||||
* è ïèøåì, ÷òî áû íè ñêàçàë àäðåñ âîçâðàòà. Íå îïëà÷åí, à ïîêóïàòåëü âåðíóëñÿ ñ óñïåõîì —
|
||||
* æä¸ì Pay URL: ñòðàíèöà ñàìà ïåðåçàïðàøèâàåò ñòàòóñ {@see self::MAX_ATTEMPTS} ðàç.
|
||||
* - Íîìåð îïåðàöèè ïåðåäàí, íî çàêàçà íåò èëè îí ÷óæîé — «Çàêàç íå íàéäåí»: ÷óæîé çàêàç
|
||||
* íåîòëè÷èì îò íåñóùåñòâóþùåãî, ïåðåáîðîì íîìåðîâ ñòàòóñ íå óçíàòü.
|
||||
* - Íîìåðà îïåðàöèè íåò — òîëüêî òî, ÷òî ñäåëàë ïîêóïàòåëü íà ñòîðîíå MONETA.RU.
|
||||
*/
|
||||
final class ReturnMessage
|
||||
{
|
||||
/** Íàçâàíèå ïëàò¸æíîãî ñåðâèñà â òåêñòàõ ïîêóïàòåëþ. */
|
||||
private const SERVICE_NAME = '«Ìîíåòà»';
|
||||
|
||||
/** Èêîíêè ñòðàíèöû — êëàññû `moneta-result--<èêîíêà>` â `templates/moneta.css`. */
|
||||
public const ICON_SUCCESS = 'success';
|
||||
public const ICON_ERROR = 'error';
|
||||
public const ICON_WAIT = 'wait';
|
||||
public const ICON_INFO = 'info';
|
||||
public const ICON_WARNING = 'warning';
|
||||
|
||||
/** Ñêîëüêî ðàç ñòðàíèöà ïåðåçàïðàøèâàåò ñòàòóñ, îæèäàÿ Pay URL. */
|
||||
public const MAX_ATTEMPTS = 20;
|
||||
|
||||
/** Ïàóçà ìåæäó ïåðåçàïðîñàìè, ìñ: âìåñòå ñ {@see self::MAX_ATTEMPTS} — îêîëî ìèíóòû. */
|
||||
public const REFRESH_DELAY_MS = 3000;
|
||||
|
||||
/** Òåêñòû áåç çàêàçà: òîëüêî ïî àäðåñó âîçâðàòà. */
|
||||
private const TEXTS = [
|
||||
ReturnUrls::RESULT_SUCCESS => [
|
||||
self::ICON_INFO,
|
||||
'Ñïàñèáî, Âàø ïëàò¸æ ïðèíÿò',
|
||||
'Ñòàòóñ çàêàçà îáíîâèòñÿ, êàê òîëüêî ' . self::SERVICE_NAME . ' ïîäòâåðäèò îïëàòó.',
|
||||
],
|
||||
ReturnUrls::RESULT_IN_PROGRESS => [
|
||||
self::ICON_INFO,
|
||||
'Ïëàò¸æ îáðàáàòûâàåòñÿ',
|
||||
self::SERVICE_NAME . ' åù¸ ïðîâåðÿåò ïëàò¸æ. Ñòàòóñ çàêàçà îáíîâèòñÿ àâòîìàòè÷åñêè.',
|
||||
],
|
||||
ReturnUrls::RESULT_FAIL => [
|
||||
self::ICON_ERROR,
|
||||
'Ïëàò¸æ íå ïðîø¸ë',
|
||||
'Îïëàòó ìîæíî ïîâòîðèòü â ðàçäåëå «Ìîè çàêàçû» èëè ñâÿæèòåñü ñ ìàãàçèíîì.',
|
||||
],
|
||||
ReturnUrls::RESULT_RETURN => [
|
||||
self::ICON_INFO,
|
||||
'Îïëàòà íå çàâåðøåíà',
|
||||
'Âû âåðíóëèñü â ìàãàçèí áåç îïëàòû. Îïëàòèòü çàêàç ìîæíî â ðàçäåëå «Ìîè çàêàçû».',
|
||||
],
|
||||
];
|
||||
|
||||
/** @var string */
|
||||
private $icon;
|
||||
|
||||
/** @var string */
|
||||
private $title;
|
||||
|
||||
/** @var string */
|
||||
private $text;
|
||||
|
||||
/** @var string */
|
||||
private $orderUid;
|
||||
|
||||
/** @var bool */
|
||||
private $waiting;
|
||||
|
||||
private function __construct(
|
||||
string $icon,
|
||||
string $title,
|
||||
string $text,
|
||||
string $orderUid = '',
|
||||
bool $waiting = false
|
||||
) {
|
||||
$this->icon = $icon;
|
||||
$this->title = $title;
|
||||
$this->text = $text;
|
||||
$this->orderUid = $orderUid;
|
||||
$this->waiting = $waiting;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $result çíà÷åíèå `?result=` àäðåñà âîçâðàòà
|
||||
* @param bool $transactionGiven â àäðåñå åñòü `MNT_TRANSACTION_ID`
|
||||
* @param Order|null $order çàêàç ïî `MNT_TRANSACTION_ID`, óæå ïðîâåðåííûé {@see ReturnAccess}
|
||||
* @param bool $paidByJournal ïî çàêàçó åñòü çà÷ò¸ííàÿ îïëàòà â æóðíàëå ìîäóëÿ
|
||||
* @param int $attempt íîìåð ïåðåçàïðîñà ñòàòóñà, ñ 0
|
||||
*
|
||||
* @return self|null null — íåèçâåñòíûé `result`, ñòðàíèöà îòâå÷àåò 404
|
||||
*/
|
||||
public static function resolve(
|
||||
string $result,
|
||||
bool $transactionGiven,
|
||||
?Order $order,
|
||||
bool $paidByJournal,
|
||||
Settings $settings,
|
||||
int $attempt = 0
|
||||
): ?self {
|
||||
if (!isset(self::TEXTS[$result])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($order === null) {
|
||||
if ($transactionGiven) {
|
||||
return new self(
|
||||
self::ICON_WARNING,
|
||||
'Çàêàç íå íàéäåí',
|
||||
'Ñòàòóñ îïëàòû ìîæíî ïðîâåðèòü â ðàçäåëå «Ìîè çàêàçû». Åñëè äåíüãè ñïèñàíû, à çàêàç'
|
||||
. ' íå îïëà÷åí, ñâÿæèòåñü ñ ìàãàçèíîì.',
|
||||
);
|
||||
}
|
||||
[$icon, $title, $text] = self::TEXTS[$result];
|
||||
|
||||
return new self($icon, $title, $text);
|
||||
}
|
||||
|
||||
$uid = $order->getUid();
|
||||
if ($paidByJournal || PaymentEligibility::isPaid($settings, $order)) {
|
||||
return new self(self::ICON_SUCCESS, 'Îïëàòà ïðîøëà óñïåøíî', 'Çàêàç ¹' . $uid . ' îïëà÷åí. Ñïàñèáî!', $uid);
|
||||
}
|
||||
if ($order->getStatusId() === PaymentEligibility::STATUS_CANCELLED) {
|
||||
return new self(
|
||||
self::ICON_ERROR,
|
||||
'Çàêàç ¹' . $uid . ' îòìåí¸í',
|
||||
'Åñëè äåíüãè ñïèñàíû, ñâÿæèòåñü ñ ìàãàçèíîì.',
|
||||
$uid,
|
||||
);
|
||||
}
|
||||
if ($result === ReturnUrls::RESULT_FAIL) {
|
||||
return new self(
|
||||
self::ICON_ERROR,
|
||||
'Ïëàò¸æ íå ïðîø¸ë',
|
||||
'Çàêàç ¹' . $uid . ' íå îïëà÷åí. Îïëàòó ìîæíî ïîâòîðèòü â ðàçäåëå «Ìîè çàêàçû»'
|
||||
. ' èëè ñâÿæèòåñü ñ ìàãàçèíîì.',
|
||||
$uid,
|
||||
);
|
||||
}
|
||||
if ($result === ReturnUrls::RESULT_RETURN) {
|
||||
return new self(
|
||||
self::ICON_INFO,
|
||||
'Îïëàòà íå çàâåðøåíà',
|
||||
'Çàêàç ¹' . $uid . ' íå îïëà÷åí. Îïëàòèòü åãî ìîæíî â ðàçäåëå «Ìîè çàêàçû».',
|
||||
$uid,
|
||||
);
|
||||
}
|
||||
if ($attempt < self::MAX_ATTEMPTS) {
|
||||
return new self(
|
||||
self::ICON_WAIT,
|
||||
'Îæèäàåì ïîäòâåðæäåíèå îïëàòû',
|
||||
'Çàêàç ¹' . $uid . '. Íå çàêðûâàéòå ñòðàíèöó - ñòàòóñ îáíîâèòñÿ àâòîìàòè÷åñêè.',
|
||||
$uid,
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
return new self(
|
||||
self::ICON_INFO,
|
||||
'Îïëàòà åù¸ íå ïîäòâåðæäåíà',
|
||||
'Çàêàç ¹' . $uid . '. ' . self::SERVICE_NAME . ' ïîêà íå ïðèñëàëà ïîäòâåðæäåíèå. Ñòàòóñ'
|
||||
. ' çàêàçà îáíîâèòñÿ àâòîìàòè÷åñêè - ïðîâåðüòå åãî â ðàçäåëå «Ìîè çàêàçû» ïîçæå.',
|
||||
$uid,
|
||||
);
|
||||
}
|
||||
|
||||
public function getIcon(): string
|
||||
{
|
||||
return $this->icon;
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
public function getText(): string
|
||||
{
|
||||
return $this->text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Íîìåð çàêàçà äëÿ ññûëêè «Ïîäðîáíåå î çàêàçå»; ïóñòîé — çàêàç ïîêóïàòåëþ íå ïîêàçûâàåì.
|
||||
*/
|
||||
public function getOrderUid(): string
|
||||
{
|
||||
return $this->orderUid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ñòðàíèöà æä¸ò Pay URL è äîëæíà ïåðåçàïðîñèòü ñòàòóñ.
|
||||
*/
|
||||
public function isWaiting(): bool
|
||||
{
|
||||
return $this->waiting;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace MonetaPhpShop\form;
|
||||
|
||||
/**
|
||||
* Àäðåñà, êóäà Ìîíåòà âîçâðàùàåò ïîêóïàòåëÿ (`MNT_SUCCESS_URL`, `MNT_FAIL_URL`,
|
||||
* `MNT_INPROGRESS_URL`, `MNT_RETURN_URL`). Âñå âåäóò íà ñòðàíèöó ìîäóëÿ `/moneta/`;
|
||||
* âîçâðàò — íå ïîäòâåðæäåíèå îïëàòû, ñòàòóñ çàêàçà ìåíÿåò òîëüêî Pay URL.
|
||||
*/
|
||||
final class ReturnUrls
|
||||
{
|
||||
public const RESULT_SUCCESS = 'success';
|
||||
public const RESULT_FAIL = 'fail';
|
||||
public const RESULT_IN_PROGRESS = 'inprogress';
|
||||
public const RESULT_RETURN = 'return';
|
||||
|
||||
public const RESULTS = [
|
||||
self::RESULT_SUCCESS,
|
||||
self::RESULT_FAIL,
|
||||
self::RESULT_IN_PROGRESS,
|
||||
self::RESULT_RETURN,
|
||||
];
|
||||
|
||||
/** @var string */
|
||||
private $pageUrl;
|
||||
|
||||
/**
|
||||
* @param string $pageUrl àäðåñ ñòðàíèöû ìîäóëÿ: àáñîëþòíûé äëÿ ôîðìû îïëàòû
|
||||
* (`https://shop.example/moneta/`), ïóòü îò êîðíÿ ñàéòà äëÿ ðåäèðåêòà (`/moneta/`)
|
||||
*/
|
||||
public function __construct(string $pageUrl)
|
||||
{
|
||||
$this->pageUrl = $pageUrl;
|
||||
}
|
||||
|
||||
public function getSuccess(): string
|
||||
{
|
||||
return $this->withResult(self::RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
public function getFail(): string
|
||||
{
|
||||
return $this->withResult(self::RESULT_FAIL);
|
||||
}
|
||||
|
||||
public function getInProgress(): string
|
||||
{
|
||||
return $this->withResult(self::RESULT_IN_PROGRESS);
|
||||
}
|
||||
|
||||
public function getReturn(): string
|
||||
{
|
||||
return $this->withResult(self::RESULT_RETURN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Àäðåñ ñòðàíèöû ìîäóëÿ äëÿ ïîêóïàòåëÿ, êîòîðîãî MONETA.RU âåðíóëà íà `/success` èëè `/fail`
|
||||
* ÿäðà: òàê íàñòðîåíû ñ÷åòà ìåð÷àíòîâ ñî âñòðîåííûì ìîäóëåì, à áåç ôëàãà «Ìîæíî
|
||||
* ïåðåîïðåäåëÿòü íàñòðîéêè â URL» íàøè `MNT_*_URL` èãíîðèðóþòñÿ (MONETA.Assistant.ru.pdf,
|
||||
* ïàðàìåòðû `MNT_SUCCESS_URL`, `MNT_FAIL_URL`).
|
||||
*
|
||||
* @param mixed $transactionId `MNT_TRANSACTION_ID` èç àäðåñà âîçâðàòà
|
||||
*
|
||||
* @return string|null null — âîçâðàò íå îò MONETA.RU (íåò íîìåðà îïåðàöèè), ñòðàíèöà ÿäðà
|
||||
* îáðàáàòûâàåò åãî ñàìà
|
||||
*/
|
||||
public function withTransaction(string $result, $transactionId): ?string
|
||||
{
|
||||
if ($transactionId === ''
|
||||
|| !is_string($transactionId)
|
||||
|| !in_array($result, self::RESULTS, true)
|
||||
|| strlen($transactionId) > 255
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->withResult($result) . '&MNT_TRANSACTION_ID=' . rawurlencode($transactionId);
|
||||
}
|
||||
|
||||
private function withResult(string $result): string
|
||||
{
|
||||
return $this->pageUrl . '?result=' . $result;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user