Files
Moodle/classes/local/protocol/MntResponseXml.php
T

80 lines
2.9 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\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));
}
}