Magento 2 · Adobe Commerce

VeriFactu en Magento. Cada pedido pagado, una factura registrada en AEAT.

No hay un módulo de Cofactu en el Marketplace de Magento, y no te vamos a decir lo contrario. Lo que hay es un webhook que factura y envía a AEAT cualquier pedido que le mandes, y Magento sabe mandarlo: un observer de veinte líneas o una receta de Make.

Flujo del pedido a AEAT

  1. 01 Pedido pagado en tu tienda

    Magento dispara su evento de pago, como ya hace hoy.

  2. 02 Un POST al webhook de Cofactu

    Desde el hook nativo o desde Make. JSON normalizado, API key en la cabecera.

  3. 03 Factura encadenada

    Cofactu numera, calcula la huella SHA-256 encadenada y genera el PDF con QR.

  4. 04 Registrada en AEAT

    Con tu certificado, el registro sale a AEAT en segundo plano y guarda el CSV de respuesta.

Con código · el hook nativo

Observer sobre sales_order_invoice_pay

Se dispara cuando Magento marca la factura del pedido como pagada. Si cobras contra reembolso, cambia al evento sales_order_save_after filtrando por estado complete.

php
<?php
// app/code/TuEmpresa/Cofactu/Observer/InvoicePay.php
namespace TuEmpresa\Cofactu\Observer;

use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\HTTP\Client\Curl;

class InvoicePay implements ObserverInterface
{
    public function __construct(private Curl $curl) {}

    public function execute(Observer $observer): void
    {
        $order = $observer->getEvent()->getInvoice()->getOrder();
        $lines = [];
        foreach ($order->getAllVisibleItems() as $item) {
            $lines[] = [
                'descripcion'    => $item->getName(),
                'cantidad'       => (float) $item->getQtyOrdered(),
                'precioUnitario' => (float) $item->getPrice(),      // sin IVA
                'tipoIva'        => (float) $item->getTaxPercent(),
            ];
        }
        $this->curl->addHeader('Authorization', 'Bearer ' . getenv('COFACTU_API_KEY'));
        $this->curl->addHeader('Content-Type', 'application/json');
        $this->curl->post('https://api.cofactu.com/api/webhooks/ecommerce-orders', json_encode([
            'platform'        => 'magento',
            'externalOrderId' => $order->getIncrementId(),
            'client'          => $order->getCustomerTaxvat()
                ? ['nif' => $order->getCustomerTaxvat(), 'nombre' => $order->getCustomerName(), 'email' => $order->getCustomerEmail()]
                : null,                                                // F2 simplificada
            'lines'           => $lines,
        ]));
    }
}

Sin código

Sin tocar código: Make o Zapier

  1. 1

    Crea una API key en Cofactu (Configuración → API keys) con permiso de escritura en facturas.

  2. 2

    En Make, escenario con el módulo «Magento 2 → Watch orders» (o en Zapier «Magento 2 → New Order»).

  3. 3

    Añade un módulo HTTP «Make a request»: POST a https://api.cofactu.com/api/webhooks/ecommerce-orders, cabecera Authorization: Bearer vf_live_….

  4. 4

    Mapea el pedido al JSON de abajo. externalOrderId = número de pedido: si Make reintenta, Cofactu no duplica la factura.

El JSON que espera Cofactu

Un solo formato para todas las tiendas

POST https://api.cofactu.com/api/webhooks/ecommerce-orders con Authorization: Bearer vf_live_…. Precios sin IVA y tipoIva por línea; client: null emite una factura simplificada F2; externalOrderId hace la llamada idempotente. Desde Configuración → Integraciones → Ecommerce se lanza un pedido de prueba y se ve cada pedido con su estado en AEAT.

json
{
  "platform": "magento",
  "externalOrderId": "2026-000123",
  "client": {
    "nif": "B12345678",
    "nombre": "Tienda Ejemplo SL",
    "email": "compras@ejemplo.com",
    "direccion": "C/ Mayor 1",
    "codigoPostal": "28001",
    "ciudad": "Madrid",
    "pais": "ES"
  },
  "lines": [
    {
      "descripcion": "Zapatillas running 42",
      "cantidad": 1,
      "precioUnitario": 79.34,
      "tipoIva": 21
    },
    {
      "descripcion": "Gastos de envío",
      "cantidad": 1,
      "precioUnitario": 4.13,
      "tipoIva": 21
    }
  ],
  "autoSubmit": true
}

Preguntas frecuentes

Magento y VeriFactu, en corto

¿Existe un módulo VeriFactu para Magento de Cofactu?

No, todavía no. Existe el webhook universal, que es lo que un módulo llamaría por dentro. Conectarlo es un observer PHP o un escenario de Make; el módulo empaquetado llegará cuando haya tiendas reales usándolo.

¿Vale para Magento 2 y Adobe Commerce?

Sí. Ambos exponen los mismos eventos de pedido y factura, y el POST al webhook es HTTP normal. Magento 1 está fuera de soporte desde 2020 y no lo cubrimos.

¿Qué pasa si Magento reenvía el mismo pedido dos veces?

Nada. El webhook es idempotente por platform + externalOrderId: la segunda llamada devuelve la factura ya creada, con su estado en AEAT, sin emitir otra.

¿Y si el cliente no me dio NIF?

Manda client: null y Cofactu emite una factura simplificada (tipo F2), que es lo que VeriFactu prevé para ventas a consumidor final sin identificar. El JSON es el mismo para las cuatro tiendas: platform, externalOrderId, client (o null para una factura simplificada F2) y lines con precio sin IVA y tipoIva por línea.

¿Qué hace falta en Cofactu para que llegue a AEAT?

Tu certificado digital cargado y VeriFactu activado en la organización. Sin certificado, la factura se crea igual y se queda en borrador para que la envíes cuando lo tengas; con autoSubmit: false se queda en borrador a propósito.

Tu tienda sigue siendo Magento. La factura, VeriFactu.

Cuenta gratis, API key en un minuto y un pedido de prueba para ver la primera factura encadenada.

¿Listo para facturar sin sustos?

Empieza gratis o mira los planes. Tu primera factura VeriFactu en menos de 10 minutos.

Sin tarjetaCancela en 1 clicExporta cuando quieras