feat: moneta 2.0, MONETA.Assistant payment module for PHPShop 6.7+
This commit is contained in:
@@ -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');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user