Guía para Desarrolladores M2M

API Factura Electrónica y VeriFactu
para Sistemas Legacy

Si programas en FileMaker, Microsoft Access, Visual Basic o PHP, sabes que firmar un XML criptográficamente en local (XADES-EPES) o conectar con el hub de VeriFactu es una pesadilla técnica de cientos de horas.

Nuestra API REST B2B soluciona esto en 1 sola petición HTTP. Envías un JSON simple, nuestra nube desencripta tu certificado delegado (P12), firma el XML bajo la normativa española vigente y te lo devuelve instantáneamente.

1 Autenticación M2M

Toda comunicación de tu servidor/ERP con DataPilot Tax se realiza mediante una X-API-KEY estática que obtienes desde el Dashboard de Empresa en el plan Agencia/ERP.

Cabecera Requerida
X-API-KEY: txp_live_xxxxxxxxxxxxxxxxxxxxxx

2 Generar y Firmar Factura XML

Usa este endpoint para convertir tus datos de facturación brutos en un FacturaE XML legalmente válido.

POSThttps://api.datapilotax.es/api/v1/facturae/json

Headers

  • Content-Type: application/json
  • X-API-KEY: <tu_api_key>
  • X-Certificate-Password: <pin_del_p12_delegado>

* El PIN viaja por HTTPS TLS 1.3 directo a RAM y nunca se almacena.

JSON Body Payload

{
  "series": "F2024",
  "number": "001",
  "issueDate": "2024-02-15",
  "currency": "EUR",
  "issuer": {
    "taxId": { "number": "B12345678", "countryCode": "ESP" },
    "legalName": "La Sastrería Digital SL",
    "address": {
      "address": "Calle Falsa 123",
      "postCode": "28001",
      "town": "Madrid",
      "province": "Madrid",
      "countryCode": "ESP"
    }
  },
  "receiver": {
    "taxId": { "number": "B98765432", "countryCode": "ESP" },
    "legalName": "Cliente Ejemplo SA"
  },
  "items": [
    {
      "description": "Desarrollo Módulo ERP Integración",
      "quantity": 1,
      "unitPriceWithoutTax": 1500.00,
      "totalAmountWithoutTax": 1500.00,
      "taxRate": 21.0
    }
  ],
  "totals": {
    "totalGrossAmount": 1500.00,
    "totalTaxAmount": 315.00,
    "totalPayableAmount": 1815.00
  }
}

Snippets de Integración para Sistemas Legacy

Copia y pega estos ejemplos funcionales en tu lenguaje o base de datos favorita.

⚡ cURL (Línea de Comandos)

Prueba rápida desde terminal. Compatible con macOS, Linux y Git Bash en Windows.

bash
curl -X POST https://api.datapilotax.es/api/v1/facturae/json \
  -H "Content-Type: application/json" \
  -H "X-API-KEY: txp_live_xxxxxxxxxxxxxxxx" \
  -H "X-Certificate-Password: mi_pin_p12" \
  -d '{
    "series": "F2024",
    "number": "001",
    "issueDate": "2024-02-15",
    "currency": "EUR",
    "issuer": { "taxId": { "number": "B12345678", "countryCode": "ESP" } },
    "receiver": { "taxId": { "number": "B98765432", "countryCode": "ESP" } },
    "items": [{ "description": "Servicio", "quantity": 1, "unitPriceWithoutTax": 1000, "taxRate": 21 }],
    "totals": { "totalGrossAmount": 1000, "totalTaxAmount": 210, "totalPayableAmount": 1210 }
  }'

📦 FileMaker (Insertar desde URL)

Paso de guion (Script Step): Insertar desde URL. Usa la variable $json_data calculada previamente con Establecer Variable.

Opciones cURL (Calculado)
// ── Script de FileMaker Pro ──
// Paso 1: Establecer Variable [ $url ; Valor: "https://api.datapilotax.es/api/v1/facturae/json" ]
// Paso 2: Establecer Variable [ $api_key ; Valor: "txp_live_xxxxxxxxxxxxxxxx" ]
// Paso 3: Establecer Variable [ $pin ; Valor: "mi_pin_p12" ]
// Paso 4: Establecer Variable [ $json_data ; Valor: JSONSetElement ( "{}" ;
//     [ "series" ; "F2024" ; JSONString ] ;
//     [ "number" ; "001" ; JSONString ] ;
//     ... más campos ...
//   ) ]
//
// Paso 5: Insertar desde URL [ Seleccionar ; Con diálogo: Desactivado ;
//   Destino: $resultado ;
//   $url ;
//   Opciones cURL:
"-X POST " &
"--header \"Content-Type: application/json\" " &
"--header \"X-API-KEY: " & $api_key & "\" " &
"--header \"X-Certificate-Password: " & $pin & "\" " &
"-d @$json_data"

// Paso 6: Si [ PatternCount ( $resultado ; "<Facturae" ) > 0 ]
//   Mostrar diálogo: "Factura XML generada con éxito"
// Si no
//   Mostrar diálogo: "Error: " & $resultado
// Fin Si

📊 Microsoft Access API (VBA)

Ejemplo usando MSXML2.ServerXMLHTTP.6.0 (Recomendado para HTTPS TLS 1.2+ en Windows).

VBA Access Module
' ── Módulo VBA para Microsoft Access ──
' Agregar referencia: Microsoft XML, v6.0

Sub GenerarFacturaXML()
    Dim http As Object
    Set http = CreateObject("MSXML2.ServerXMLHTTP.6.0")

    Dim url As String
    url = "https://api.datapilotax.es/api/v1/facturae/json"

    Dim jsonPayload As String
    jsonPayload = "{" & _
        """series"": ""F2024""," & _
        """number"": ""001""," & _
        """issueDate"": ""2024-02-15""," & _
        """currency"": ""EUR""," & _
        """issuer"": { ""taxId"": { ""number"": ""B12345678"", ""countryCode"": ""ESP"" } }," & _
        """receiver"": { ""taxId"": { ""number"": ""B98765432"", ""countryCode"": ""ESP"" } }," & _
        """items"": [{ ""description"": ""Servicio"", ""quantity"": 1, ""unitPriceWithoutTax"": 1000, ""taxRate"": 21 }]," & _
        """totals"": { ""totalGrossAmount"": 1000, ""totalTaxAmount"": 210, ""totalPayableAmount"": 1210 }" & _
    "}"

    http.Open "POST", url, False
    http.setRequestHeader "Content-Type", "application/json"
    http.setRequestHeader "X-API-KEY", "txp_live_xxxxxxxxxxxxxxxx"
    http.setRequestHeader "X-Certificate-Password", "mi_pin_p12"

    http.send jsonPayload

    If http.Status = 200 Then
        Debug.Print "XML Generado: " & http.responseText
        ' Guardar en archivo:
        ' Open "C:\facturas\factura.xml" For Output As #1
        ' Print #1, http.responseText
        ' Close #1
    Else
        MsgBox "Error " & http.Status & ": " & http.responseText
    End If

    Set http = Nothing
End Sub

🐘 PHP puro / API cURL

Perfecto para backends antiguos en PHP, CodeIgniter o plugins a medida de WordPress / WooCommerce.

PHP Script
<?php
// ── Script PHP para WordPress / WooCommerce / Laravel ──

$url = "https://api.datapilotax.es/api/v1/facturae/json";

$payload = [
    'series' => 'F2024',
    'number' => '001',
    'issueDate' => '2024-02-15',
    'currency' => 'EUR',
    'issuer' => [
        'taxId' => ['number' => 'B12345678', 'countryCode' => 'ESP'],
        'legalName' => 'Mi Empresa SL'
    ],
    'receiver' => [
        'taxId' => ['number' => 'B98765432', 'countryCode' => 'ESP'],
        'legalName' => 'Cliente Ejemplo SA'
    ],
    'items' => [[
        'description' => 'Servicio de consultoría',
        'quantity' => 1,
        'unitPriceWithoutTax' => 1500.00,
        'totalAmountWithoutTax' => 1500.00,
        'taxRate' => 21.0
    ]],
    'totals' => [
        'totalGrossAmount' => 1500.00,
        'totalTaxAmount' => 315.00,
        'totalPayableAmount' => 1815.00
    ]
];

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'X-API-KEY: txp_live_xxxxxxxxxxxxxxxx',
    'X-Certificate-Password: mi_pin_p12'
]);

$response = curl_exec($ch);
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($httpcode === 200) {
    // Guardar el XML firmado
    file_put_contents('factura_firmada.xml', $response);
    echo "Firma exitosa. XML guardado.";
} else {
    echo "Error API ($httpcode): " . $response;
}
?>