Files
Moodle/classes/local/order/OrderSnapshot.php
T

100 lines
3.7 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
namespace paygw_moneta\local\order;
use InvalidArgumentException;
use paygw_moneta\local\receipt\Receipt;
use paygw_moneta\local\receipt\Vat;
/**
* Снимок настроек счёта и данных чека на момент создания заказа.
*
* Колбэки сверяют уведомление с тем, что реально было запрошено (сумма, режим,
* данные чека, `MNT_SUBSCRIBER_ID`), а не с текущей ценой курса и профилем. Номер счёта в снимке —
* дополнительная защита: он обязан совпадать и с текущей настройкой, потому что
* ключ подписи всегда берётся из неё; заказы, созданные до смены счёта,
* оплатить нельзя. Секрет (код проверки целостности) в снимок не попадает.
*
* @package paygw_moneta
* @copyright 2026 Moneta Labs {@link https://moneta.ru/}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
final class OrderSnapshot
{
public function __construct(
public readonly string $accountNumber,
public readonly bool $testMode,
public readonly bool $fiscalization,
public readonly Vat $vat,
public readonly Receipt $receipt,
public readonly string $description,
public readonly string $subscriberId,
) {
if ($accountNumber === '') {
throw new InvalidArgumentException('В снимке заказа нет номера счёта.');
}
}
/**
* @return array<string, mixed>
*/
public function toArray(): array
{
return [
'accountnumber' => $this->accountNumber,
'testmode' => $this->testMode,
'fiscalization' => $this->fiscalization,
'vat' => $this->vat->value,
'receipt' => $this->receipt->toArray(),
'description' => $this->description,
'subscriberid' => $this->subscriberId,
];
}
public function toJson(): string
{
return json_encode($this->toArray(), JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE);
}
/**
* @param array<string, mixed> $data
*/
public static function fromArray(array $data): self
{
return new self(
accountNumber: (string) ($data['accountnumber'] ?? ''),
testMode: (bool) ($data['testmode'] ?? false),
fiscalization: (bool) ($data['fiscalization'] ?? false),
vat: Vat::from((string) ($data['vat'] ?? '')),
receipt: Receipt::fromArray(is_array($data['receipt'] ?? null) ? $data['receipt'] : []),
description: (string) ($data['description'] ?? ''),
subscriberId: (string) ($data['subscriberid'] ?? ''),
);
}
public static function fromJson(string $json): self
{
$data = json_decode($json, true, 512, JSON_THROW_ON_ERROR);
if (!is_array($data)) {
throw new InvalidArgumentException('Снимок заказа повреждён.');
}
return self::fromArray($data);
}
/**
* Совпадение реквизитов и чека; описание не сравнивается — оно не влияет
* на оплату и не должно плодить заказы.
*/
public function equals(self $other): bool
{
$mine = $this->toArray();
$theirs = $other->toArray();
unset($mine['description'], $theirs['description']);
return $mine === $theirs;
}
}