Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
88.24% |
15 / 17 |
|
0.00% |
0 / 2 |
CRAP | |
0.00% |
0 / 1 |
| FiscalQr | |
88.24% |
15 / 17 |
|
0.00% |
0 / 2 |
9.13 | |
0.00% |
0 / 1 |
| buildUrl | |
90.91% |
10 / 11 |
|
0.00% |
0 / 1 |
5.02 | |||
| payloadGet | |
83.33% |
5 / 6 |
|
0.00% |
0 / 1 |
4.07 | |||
| 1 | <?php |
| 2 | |
| 3 | declare(strict_types=1); |
| 4 | |
| 5 | namespace UppServices\verifactu; |
| 6 | |
| 7 | /** |
| 8 | * VeriFactu AEAT ValidarQR URL (parity with client VeriFactu QR helpers). |
| 9 | * |
| 10 | * Domain helper: does not touch TICKETDATA.registry. Callers persist qr after generation. |
| 11 | */ |
| 12 | class FiscalQr |
| 13 | { |
| 14 | private const SANDBOX_BASE = 'https://prewww2.aeat.es/wlpl/TIKE-CONT/ValidarQR'; |
| 15 | private const PROD_BASE = 'https://www2.agenciatributaria.gob.es/wlpl/TIKE-CONT/ValidarQR'; |
| 16 | |
| 17 | /** |
| 18 | * Builds the AEAT QR validation URL from a VeriFactu payload shape. |
| 19 | * |
| 20 | * @param array<string, mixed> $payload |
| 21 | */ |
| 22 | public static function buildUrl(array $payload, ?bool $sandbox = null): string |
| 23 | { |
| 24 | if ($sandbox === null) { |
| 25 | $sandbox = class_exists(\AppConstants::class, false) && method_exists(\AppConstants::class, 'VFT_Sandbox') |
| 26 | ? (bool) \AppConstants::VFT_Sandbox() |
| 27 | : true; |
| 28 | } |
| 29 | |
| 30 | $base = $sandbox ? self::SANDBOX_BASE : self::PROD_BASE; |
| 31 | |
| 32 | $query = []; |
| 33 | $query[] = 'nif='.rawurlencode((string) self::payloadGet($payload, ['issuer', 'taxId'], '')); |
| 34 | $query[] = 'numserie='.rawurlencode((string) self::payloadGet($payload, ['invoice', 'number'], '')); |
| 35 | $query[] = 'fecha='.rawurlencode((string) self::payloadGet($payload, ['invoice', 'date'], '')); |
| 36 | $query[] = 'importe='.rawurlencode((string) self::payloadGet($payload, ['invoice', 'total'], '0.00')); |
| 37 | |
| 38 | return $base.'?'.implode('&', $query); |
| 39 | } |
| 40 | |
| 41 | /** |
| 42 | * @param array<string, mixed> $source |
| 43 | * @param list<string|int> $path |
| 44 | */ |
| 45 | private static function payloadGet(array $source, array $path, mixed $default = null): mixed |
| 46 | { |
| 47 | $cursor = $source; |
| 48 | foreach ($path as $key) { |
| 49 | if (!is_array($cursor) || !array_key_exists($key, $cursor)) { |
| 50 | return $default; |
| 51 | } |
| 52 | $cursor = $cursor[$key]; |
| 53 | } |
| 54 | return $cursor; |
| 55 | } |
| 56 | } |