feat: paygw_moneta 1.0.0, MONETA.Assistant payment gateway for Moodle

This commit is contained in:
2026-09-25 16:42:38 +03:00
parent 70464af858
commit 14b386a550
65 changed files with 5377 additions and 59 deletions
+79
View File
@@ -0,0 +1,79 @@
<?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;
}
}