feat: paygw_moneta 1.0.0, MONETA.Assistant payment gateway for Moodle
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace paygw_moneta\local\protocol;
|
||||
|
||||
use DOMDocument;
|
||||
use DOMNode;
|
||||
use paygw_moneta\local\Money;
|
||||
|
||||
/**
|
||||
* Сборка `MNT_RESPONSE` (`MONETA.Assistant.ru.pdf`, гл. 4–5). Общая часть
|
||||
* ответов Check URL и Pay URL: обязательные элементы, подпись по формуле 3
|
||||
* и необязательные `MNT_ATTRIBUTES`.
|
||||
*
|
||||
* `MNT_CMS` в схеме ответа нет — это решение разработчика (2026-09-12,
|
||||
* `docs/moneta/_pdf/README.md`): идентификатор CMS передаётся везде, где
|
||||
* модуль отвечает Moneta; лишние элементы приёму не мешают.
|
||||
*
|
||||
* @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 MntResponseXml
|
||||
{
|
||||
private function __construct() {}
|
||||
|
||||
/**
|
||||
* @param array<string, string> $attributes пары KEY → VALUE для `MNT_ATTRIBUTES`
|
||||
* @throws \DOMException
|
||||
*/
|
||||
public static function build(
|
||||
string $accountId,
|
||||
string $transactionId,
|
||||
ResultCode $resultCode,
|
||||
Money $amount,
|
||||
string $signature,
|
||||
string $cms,
|
||||
array $attributes = [],
|
||||
): string {
|
||||
$document = new DOMDocument('1.0', 'UTF-8');
|
||||
$response = $document->appendChild($document->createElement('MNT_RESPONSE'));
|
||||
$elements = [
|
||||
'MNT_ID' => $accountId,
|
||||
'MNT_TRANSACTION_ID' => $transactionId,
|
||||
'MNT_RESULT_CODE' => (string) $resultCode->value,
|
||||
'MNT_DESCRIPTION' => $resultCode->description(),
|
||||
'MNT_AMOUNT' => $amount->toDecimal(),
|
||||
'MNT_SIGNATURE' => $signature,
|
||||
'MNT_CMS' => $cms,
|
||||
];
|
||||
foreach ($elements as $name => $value) {
|
||||
self::text($document, $response, $name, $value);
|
||||
}
|
||||
if ($attributes !== []) {
|
||||
$container = $response->appendChild($document->createElement('MNT_ATTRIBUTES'));
|
||||
foreach ($attributes as $key => $value) {
|
||||
$attribute = $container->appendChild($document->createElement('ATTRIBUTE'));
|
||||
self::text($document, $attribute, 'KEY', $key);
|
||||
self::text($document, $attribute, 'VALUE', $value);
|
||||
}
|
||||
}
|
||||
|
||||
$xml = $document->saveXML();
|
||||
if ($xml === false) {
|
||||
throw new \RuntimeException('Не удалось сериализовать MNT_RESPONSE.');
|
||||
}
|
||||
|
||||
return $xml;
|
||||
}
|
||||
|
||||
/**
|
||||
* Текстовый узел, а не `createElement($name, $value)`: второй не экранирует `&`.
|
||||
*/
|
||||
private static function text(DOMDocument $document, DOMNode $parent, string $name, string $value): void
|
||||
{
|
||||
$parent->appendChild($document->createElement($name))->appendChild($document->createTextNode($value));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user