41 lines
1.3 KiB
PHP
41 lines
1.3 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
namespace paygw_moneta\local\receipt;
|
||
|
||
use paygw_moneta\local\Money;
|
||
|
||
/**
|
||
* Денежные числа в JSON без `float`: спецификация требует «два знака после
|
||
* точки, даже если это нули», а `json_encode(100.0)` даст `100.0`. Сумма
|
||
* кодируется меткой и после `json_encode` заменяется на десятичную строку без
|
||
* кавычек — получается литерал `100.00`, валидный JSON-number.
|
||
*
|
||
* @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 JsonNumber
|
||
{
|
||
private const PREFIX = '__paygw_moneta_number:';
|
||
|
||
private function __construct() {}
|
||
|
||
public static function placeholder(Money $amount): string
|
||
{
|
||
return self::PREFIX . $amount->toDecimal();
|
||
}
|
||
|
||
/**
|
||
* @param array<string, mixed> $payload
|
||
* @throws \JsonException
|
||
*/
|
||
public static function encode(array $payload): string
|
||
{
|
||
$json = json_encode($payload, JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||
|
||
return preg_replace('/"' . preg_quote(self::PREFIX, '/') . '([0-9]+\.[0-9]{2})"/', '$1', $json) ?? $json;
|
||
}
|
||
}
|