# Registro de cambios

## Septiembre de 2026

### 10 de septiembre

**El formulario HTML ahora envía un contenedor firmado.** En lugar de campos de factura separados —`data` (base64url del JSON) y `signature` (HMAC-SHA256 de la cadena `data`). El endpoint cambió de `invoices/createFromForm` a `invoices/form`. Los formularios antiguos ya no funcionan y deben reconstruirse: consulta [Firma del formulario HTML](./creating-invoices/html-forms/form-signature.md).

### 8 de septiembre

**Los campos numéricos del cuerpo del webhook ahora son números.** Seis campos que antes se enviaban como cadenas ahora se envían como números: `project.commissionRate`, `invoice.commissionFiatUSD`, `invoice.amountFiatUSD`, `invoice.amountFiat`, `invoice.calcAmountFiat`, `payment.amount`. El conjunto de campos, sus nombres y su orden no han cambiado.

Ten en cuenta: los ceros finales se descartan, así que un importe de 10.00 llega como 10. Los importes por debajo de 0.0001 llegan en notación exponencial, por ejemplo 1.0e-6 —el análisis JSON estándar devuelve el número correcto; solo el análisis manual de cadenas falla.

Las notificaciones construidas antes del despliegue y aún no entregadas llegan en el formato antiguo. El receptor debe aceptar ambas variantes hasta que la cola se vacíe —esto no lleva más de dos días.

### 6 de septiembre

**Los campos numéricos de las respuestas de la API ahora son números.** Afecta a `invoices/list`, `payments/list` e `invoices/create`.

| Campo               | Antes            | Después |
| ------------------- | ---------------- | ------- |
| `commissionFiatUSD` | `"0.10"`         | `0.1`   |
| `amountFiatUSD`     | `"10.00"`        | `10`    |
| `amountFiat`        | `"1000.00"`      | `1000`  |
| `views`             | `"0"`            | `0`     |
| `payment.amount`    | `"10.500000000"` | `10.5`  |

**Una clave restringida a un proyecto ahora aplica la restricción en todos los métodos.** Antes, algunos métodos ignoraban el proyecto. Ahora es un filtro en los métodos de listado, y una solicitud por la factura o billetera de otro proyecto se rechaza con `Restricted project`. Un método que no puede respetar la restricción por proyecto queda cerrado para esa clave. Los detalles están en la sección «Alcance de la clave».

**La lista de pagos ahora devuelve los pagos sin asociar.** Antes, `payments/list` devolvía solo los pagos vinculados a una factura. Ahora los resultados incluyen todos los pagos de tus billeteras; uno sin asociar no tiene el bloque `invoice`. Son exactamente los pagos que hacen falta para la asociación manual con `invoices/bindPayment`.

**La cancelación de facturas ahora distingue los motivos de rechazo.** Antes, tanto una factura inexistente como las condiciones no cumplidas devolvían un genérico `Invoice not found`. Ahora `Invoice not found` significa solo que la factura no existe, y las condiciones no cumplidas devuelven `Invoice cannot be canceled`.

**Los identificadores mal formados ahora se rechazan.** `invoices/list` valida `invoiceId`, `invoiceUid` y `projectId`; `payments/list` —`walletId` e `invoiceId`. Un valor que no encaja devuelve `Parameter is filled in incorrectly` con el nombre del campo. Antes, ese parámetro se descartaba en silencio y los resultados volvían sin filtrar.

**Los límites del período ahora incluyen el día completo indicado.** `startDate` y `endDate` se interpretan de `00:00:00` a `23:59:59`. Antes, el día final se cortaba por completo, y una consulta de un solo día devolvía únicamente los registros creados exactamente a medianoche. Afecta a `invoices/list`, `payments/list`, `statistics/invoices` y `statistics/payments`.

**Se añadió un campo de proyecto al historial del saldo.** Cada operación del método `billing/history` ahora lleva un campo `projectId`. Para las operaciones a nivel de cuenta —recargas y bonos— es `null`.

### 4 de septiembre

**La descripción y los datos de servicio vuelven en su forma original.** Los campos `description` y `serviceData` antes se guardaban codificados, y en las respuestas de la API una comilla llegaba como `&quot;` y un signo menor que como `<`. Ahora se devuelve exactamente lo que envió el comercio. Al mostrarlo en HTML, escapa el valor en tu lado.

**Los formularios HTML solo aceptan POST.** Crear una factura siguiendo un enlace con parámetros en la barra de direcciones ya no funciona —los parámetros se leen solo del cuerpo de la solicitud. Si usabas enlaces, sustitúyelos por un formulario con `method="post"`.

### 3 de septiembre

**Las notificaciones del webhook ahora van firmadas.** Se añadieron los encabezados `X-Timestamp` y `X-Signature`; la firma se calcula con HMAC-SHA256 sobre el secreto del webhook. Verificar la firma permite distinguir una notificación genuina de una falsificación. La mecánica y los ejemplos están en la sección «Verificación de la firma del webhook».

El cambio es retrocompatible: si no añades la comprobación, tu gestor sigue funcionando como antes.
