80 lines
3.0 KiB
PHP
80 lines
3.0 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
namespace paygw_moneta\local\order;
|
||
|
||
use paygw_moneta\local\Money;
|
||
use stdClass;
|
||
|
||
/**
|
||
* Локальный заказ — строка `paygw_moneta_transactions` в типизированном виде.
|
||
* Создаётся до ухода покупателя на платёжную форму и живёт до Pay URL;
|
||
* у ядра Moodle записи о платеже до его подтверждения нет.
|
||
*
|
||
* Объект неизменяемый; переходы статусов делает {@see TransactionRepository}.
|
||
*
|
||
* @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 Order
|
||
{
|
||
public function __construct(
|
||
public readonly int $id,
|
||
public readonly int $accountId,
|
||
public readonly int $userId,
|
||
public readonly string $component,
|
||
public readonly string $paymentArea,
|
||
public readonly int $itemId,
|
||
public readonly string $merchantOrderId,
|
||
public readonly ?string $providerTransactionId,
|
||
public readonly ?int $paymentId,
|
||
public readonly Money $amount,
|
||
public readonly string $currency,
|
||
public readonly TransactionStatus $status,
|
||
public readonly OrderSnapshot $snapshot,
|
||
public readonly ?RejectionReason $lastError,
|
||
public readonly int $timeCreated,
|
||
public readonly int $timeModified,
|
||
public readonly ?int $timeCompleted,
|
||
) {}
|
||
|
||
public static function fromRecord(stdClass $record): self
|
||
{
|
||
return new self(
|
||
(int) $record->id,
|
||
(int) $record->accountid,
|
||
(int) $record->userid,
|
||
(string) $record->component,
|
||
(string) $record->paymentarea,
|
||
(int) $record->itemid,
|
||
(string) $record->merchantorderid,
|
||
$record->providertransactionid === null ? null : (string) $record->providertransactionid,
|
||
$record->paymentid === null ? null : (int) $record->paymentid,
|
||
// Единственное место, где сумма приходит из БД числом (NUMBER(20,5)).
|
||
Money::fromFloat((float) $record->amount),
|
||
(string) $record->currency,
|
||
TransactionStatus::from((string) $record->status),
|
||
OrderSnapshot::fromJson((string) $record->snapshot),
|
||
$record->lasterror === null ? null : RejectionReason::tryFrom((string) $record->lasterror),
|
||
(int) $record->timecreated,
|
||
(int) $record->timemodified,
|
||
$record->timecompleted === null ? null : (int) $record->timecompleted,
|
||
);
|
||
}
|
||
|
||
/**
|
||
* `MNT_SUBSCRIBER_ID`, с которым заказ ушёл на платёжную форму.
|
||
*/
|
||
public function subscriberId(): string
|
||
{
|
||
return $this->snapshot->subscriberId;
|
||
}
|
||
|
||
public function isPaid(): bool
|
||
{
|
||
return $this->status === TransactionStatus::Paid;
|
||
}
|
||
}
|