Snippet php para facturación electrónica DIAN con WooCommerce de WordPress.

Aquí tienes una guía completa para implementar facturación electrónica DIAN Colombia en WooCommerce usando snippets PHP a través de un plugin como Code Snippets:


Requisitos Previos

  1. Certificado DIAN (Archivos .p12 o .pfx con contraseña)
  2. Software de Facturación homologado por DIAN (Puedes implementar el tuyo)
  3. Plugin Code Snippets instalado
  4. Conocimiento de la Resolución 000042 de 2022 (Nuevo formato factura electrónica)

Paso 1: Añadir Campos Obligatorios en Checkout

// Añadir campo NIT/Cédula en checkout
add_action('woocommerce_after_checkout_billing_form', 'custom_checkout_field_nit');
function custom_checkout_field_nit($checkout) {
    woocommerce_form_field('billing_nit', array(
        'type' => 'text',
        'class' => array('form-row-wide'),
        'label' => __('NIT/Cédula'),
        'required' => true,
    ), $checkout->get_value('billing_nit'));
}

// Guardar campo NIT
add_action('woocommerce_checkout_update_order_meta', 'save_custom_checkout_nit');
function save_custom_checkout_nit($order_id) {
    if (!empty($_POST['billing_nit'])) {
        update_post_meta($order_id, '_billing_nit', sanitize_text_field($_POST['billing_nit']));
    }
}

Paso 2: Generar XML DIAN (Facturación Electrónica)

add_action('woocommerce_order_status_completed', 'generar_factura_electronica_dian');

function generar_factura_electronica_dian($order_id) {
    $order = wc_get_order($order_id);

    // Datos base DIAN
    $data = array(
        'cabecera' => array(
            'cude' => generar_cude($order_id), // Función para generar CUDE
            'fechaEmision' => date('c'),
            'tipoOperacion' => '10',
            'codigoTipoDocumento' => '01' // 01 = Factura electrónica
        ),
        'vendedor' => array(
            'nit' => '900123456-7', // Tu NIT empresa
            'dv' => '1',
            'razonSocial' => get_bloginfo('name'),
            'direccion' => get_option('woocommerce_store_address'),
            'telefono' => get_option('woocommerce_store_phone')
        ),
        'comprador' => array(
            'nit' => get_post_meta($order_id, '_billing_nit', true),
            'dv' => calcular_dv(get_post_meta($order_id, '_billing_nit', true)),
            'razonSocial' => $order->get_billing_first_name() . ' ' . $order->get_billing_last_name(),
            'direccion' => $order->get_billing_address_1(),
            'telefono' => $order->get_billing_phone()
        ),
        'items' => array()
    );

    // Agregar productos
    foreach ($order->get_items() as $item) {
        $data['items'][] = array(
            'codigo' => $item->get_product_id(),
            'descripcion' => $item->get_name(),
            'cantidad' => $item->get_quantity(),
            'precioUnitario' => $item->get_subtotal(),
            'iva' => calcular_iva($item->get_subtotal())
        );
    }

    // Generar XML
    $xml = new DOMDocument('1.0', 'UTF-8');
    $xml->formatOutput = true;

    $root = $xml->createElement('FacturaElectronica');
    $root->setAttribute('xmlns', 'urn:oasis:names:specification:ubl:schema:xsd:Invoice-2');
    $root->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');

    // Estructura DIAN
    $cabecera = $xml->createElement('cbc:CustomizationID', 'urn:cen:tech:xsd:ubl-2.1:FacturaElectronica:1.1');
    $root->appendChild($cabecera);

    // ... (Agregar todos los elementos según Resolución 000042 de 2022)

    $xml->appendChild($root);
    $xml_content = $xml->saveXML();

    // Firmar XML
    $xml_firmado = firmar_xml_dian($xml_content, $order_id);

    // Guardar y adjuntar
    $upload_dir = wp_upload_dir();
    file_put_contents($upload_dir['path'] . "/factura-$order_id.xml", $xml_firmado);
    update_post_meta($order_id, '_factura_dian', $upload_dir['url'] . "/factura-$order_id.xml");
}

Paso 3: Función para Firma Digital (DIAN)

function firmar_xml_dian($xml_content, $order_id) {
    $certificado = 'ruta/certificado.p12';
    $clave_certificado = 'tu_clave';

    // Cargar certificado
    openssl_pkcs12_read(file_get_contents($certificado), $cert_info, $clave_certificado);

    // Crear firma
    $signature = new DOMDocument();
    $signature->loadXML('<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"></ds:Signature>');

    // ... (Implementar firma XAdES según especificaciones DIAN)

    // Insertar firma en XML
    $xml = new DOMDocument();
    $xml->loadXML($xml_content);
    $xml->documentElement->appendChild($xml->importNode($signature->documentElement, true));

    return $xml->saveXML();
}

Paso 4: Generar CUDE y QR

function generar_cude($order_id) {
    $order = wc_get_order($order_id);
    $datos = array(
        'nit_emisor' => '900123456-7',
        'nit_comprador' => get_post_meta($order_id, '_billing_nit', true),
        'fecha' => date('Y-m-d'),
        'total' => $order->get_total(),
        'uuid' => wp_generate_uuid4()
    );

    $cadena = implode('|', $datos);
    return hash('sha384', $cadena);
}

// Shortcode para QR
add_shortcode('qr_factura', 'generar_qr_factura');
function generar_qr_factura() {
    $order_id = wc_get_order_id_by_order_key($_GET['order']);
    $cude = get_post_meta($order_id, '_cude', true);

    return '<img src="https://api.qrserver.com/v1/create-qr-code/?size=150x150&data=' . $cude . '">';
}

Paso 5: Validación DIAN (XSD)

function validar_xml_dian($xml_content) {
    $xsd_url = 'https://facturaelectronica.dian.gov.co/politicadevalidacion/ubl-2.1/maindoc/DIAN_UBL2_Invoice.xsd';

    libxml_use_internal_errors(true);
    $xml = new DOMDocument();
    $xml->loadXML($xml_content);

    if (!$xml->schemaValidate($xsd_url)) {
        $errors = libxml_get_errors();
        // Registrar errores en log
        error_log('Errores validación DIAN: ' . print_r($errors, true));
        return false;
    }
    return true;
}

Recomendaciones Esenciales

  1. Numeración DIAN: Implementa secuencia numérica única:
add_action('init', 'inicializar_consecutivo');
function inicializar_consecutivo() {
    if (!get_option('consecutivo_dian')) {
        update_option('consecutivo_dian', 900000000);
    }
}
  1. Adjuntar a Emails:
add_filter('woocommerce_email_attachments', 'adjuntar_factura_dian_email', 10, 3);
function adjuntar_factura_dian_email($attachments, $email_id, $order) {
    $file_url = get_post_meta($order->get_id(), '_factura_dian', true);
    if ($file_url && $email_id === 'customer_completed_order') {
        $attachments[] = str_replace(site_url('/'), ABSPATH, $file_url);
    }
    return $attachments;
}
  1. Registro en Logs DIAN:
function registrar_evento_dian($order_id, $evento) {
    $log = "Orden $order_id: $evento - " . date('Y-m-d H:i:s') . "\n";
    file_put_contents(WP_CONTENT_DIR . '/dian.log', $log, FILE_APPEND);
}

Consideraciones Clave

  1. Ambiente de Pruebas: Usa el ambiente de habilitación de DIAN primero
  2. Certificado Digital: Debes renovarlo anualmente
  3. Tiempo Límite: Genera la factura máximo 48 horas después de la venta
  4. Notificaciones DIAN: Implementa webhook para recibir respuestas de la DIAN

Este es un esquema básico. La implementación real requiere:

  • Validación estricta de todos los campos DIAN
  • Manejo de contingencia (Formatos PDF con QR)
  • Integración con el Web Service de la DIAN (SOAP)
  • Consulta de listados técnicos (Responsables de IVA, etc.)

Guía Paso a Paso para Implementar Facturación Electrónica DIAN Colombia en WooCommerce (2,000 palabras)
(Basado en Resolución 000042 de 2022 y Documentación Oficial DIAN)


1. Entender los Requisitos DIAN (Fuera de WordPress)

a) Documentación Obligatoria:

  • Resolución 000042 de 2022: Norma técnica para facturación electrónica (Descargar aquí).
  • Listados Técnicos DIAN: Campos obligatorios XML y validaciones (Consulta aquí).

b) Requisitos Técnicos Externos:

  • Certificado Digital (.p12): Debes obtenerlo en la DIAN (proceso presencial o virtual).
  • Software Homologado: Si usas tu propio desarrollo, debes registrarlo en la DIAN (Guía aquí).
  • Servidor con OpenSSL: Para firmar XMLs (compatible con PHP 7.4+).

c) Procesos Fuera de WordPress:

  1. Registro en Ambiente de Pruebas DIAN (Enlace).
  2. Configuración de Webhooks para recibir respuestas de la DIAN (necesitas un servidor externo).
  3. Renovación anual del certificado digital.

2. Estructura de Snippets PHP (Dentro de WordPress)

Total de Snippets Necesarios: 8 (cada uno con funciones específicas).


Snippet 1: Campos Obligatorios en Checkout

Objetivo: Capturar NIT/CI del cliente y tipo de responsabilidad fiscal.
“`php
// Añadir campos al checkout
add_action(‘woocommerce_after_checkout_billing_form’, ‘campos_fiscales_dian’);
function campos_fiscales_dian() {
woocommerce_form_field(‘billing_nit’, [
‘type’ => ‘text’,
‘label’ => __(‘NIT/Cédula’),
‘required’ => true,
‘class’ => [‘form-row-wide’]
]);

woocommerce_form_field('billing_tipo_responsable', [  
    'type' => 'select',  
    'label' => __('Tipo de Responsable'),  
    'options' => [  
        'O-13' => 'Responsable del IVA',  
        'R-99-PN' => 'No Responsable'  
    ],  
    'required' => true  
]);  

}

// Guardar datos
add_action(‘woocommerce_checkout_update_order_meta’, ‘guardar_campos_dian’);
function guardar_campos_dian($order_id) {
if (!empty($_POST[‘billing_nit’])) {
update_post_meta($order_id, ‘_billing_nit’, sanitize_text_field($_POST[‘billing_nit’]));
}
if (!empty($_POST[‘billing_tipo_responsable’])) {
update_post_meta($order_id, ‘_billing_tipo_responsable’, sanitize_text_field($_POST[‘billing_tipo_responsable’]));
}
}

---

#### **Snippet 2: Generación del XML DIAN (UBL 2.1)**  
**Objetivo:** Crear estructura XML según listados técnicos.  

php
add_action(‘woocommerce_order_status_completed’, ‘generar_xml_dian’);
function generar_xml_dian($order_id) {
$order = wc_get_order($order_id);

// Datos base  
$xml = new DOMDocument('1.0', 'UTF-8');  
$xml->formatOutput = true;  

// Raíz según UBL 2.1  
$Invoice = $xml->createElement('Invoice');  
$Invoice->setAttribute('xmlns', 'urn:oasis:names:specification:ubl:schema:xsd:Invoice-2');  
$Invoice->setAttribute('xmlns:cac', 'urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2');  
$Invoice->setAttribute('xmlns:cbc', 'urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2');  

// ID único DIAN (Ej: FE-900000001-1)  
$ID = $xml->createElement('cbc:ID', 'FE-' . get_option('consecutivo_dian'));  
$Invoice->appendChild($ID);  

// Fecha emisión  
$IssueDate = $xml->createElement('cbc:IssueDate', date('Y-m-d'));  
$Invoice->appendChild($IssueDate);  

// ... (Agregar todos los campos del Anexo 1.7 de la Resolución 000042)  

// Guardar XML  
$xml->appendChild($Invoice);  
$xml->save(WP_CONTENT_DIR . "/facturas/factura-$order_id.xml");  
update_post_meta($order_id, '_factura_xml', WP_CONTENT_DIR . "/facturas/factura-$order_id.xml");  

// Actualizar consecutivo  
update_option('consecutivo_dian', get_option('consecutivo_dian') + 1);  

}

---

#### **Snippet 3: Firma Digital con Certificado .p12**  
**Objetivo:** Firmar XML según estándar XAdES.  

php
function firmar_xml_dian($order_id) {
$cert_path = ‘/ruta/certificado.p12’;
$cert_pass = ‘clave_del_certificado’;

// Cargar certificado  
openssl_pkcs12_read(file_get_contents($cert_path), $cert_info, $cert_pass);  

// Firmar con OpenSSL  
$xml = file_get_contents(get_post_meta($order_id, '_factura_xml', true));  
$private_key = openssl_pkey_get_private($cert_info['pkey']);  
openssl_sign($xml, $signature, $private_key, OPENSSL_ALGO_SHA256);  

// Insertar firma en XML  
$xml_firmado = new DOMDocument();  
$xml_firmado->loadXML($xml);  

$Signature = $xml_firmado->createElement('Signature');  
// ... (Estructura XAdES para DIAN)  

$xml_firmado->documentElement->appendChild($Signature);  
$xml_firmado->save(WP_CONTENT_DIR . "/facturas/factura-firmada-$order_id.xml");  

}

---

#### **Snippet 4: Generación CUDE (Código Único de Documento Electrónico)**  
**Objetivo:** Crear CUDE según algoritmo DIAN.  

php
function generar_cude($order_id) {
$order = wc_get_order($order_id);
$nit_emisor = ‘900123456-7’;
$fecha = date(‘Y-m-d’);
$total = $order->get_total();
$uuid = wp_generate_uuid4();

// Cadena para hash  
$cadena = "$nit_emisor|$fecha|$total|$uuid";  
$hash = hash('sha384', $cadena);  

// Formato CUDE  
$cude = "CUDE-$hash-" . strtoupper($uuid);  
update_post_meta($order_id, '_cude', $cude);  
return $cude;  

}

---

#### **Snippet 5: Validación XSD**  
**Objetivo:** Verificar XML contra esquema DIAN.  

php
function validar_xml_dian($order_id) {
$xml = file_get_contents(get_post_meta($order_id, ‘_factura_xml’, true));
$xsd_url = ‘https://catalogo-vpfe.dian.gov.co/Documentos/XSD/UBL2.1/maindoc/DIAN_UBL2.1.xsd’;

$dom = new DOMDocument();  
$dom->loadXML($xml);  

if (!$dom->schemaValidate($xsd_url)) {  
    $errors = libxml_get_errors();  
    error_log("Error validación DIAN: " . print_r($errors, true));  
    return false;  
}  
return true;  

}

---

#### **Snippet 6: Envío a DIAN vía API**  
**Objetivo:** Transmitir XML a servidores DIAN (Requiere cURL).  

php
add_action(‘validar_xml_dian’, ‘enviar_a_dian’);
function enviar_a_dian($order_id) {
$xml_firmado = file_get_contents(get_post_meta($order_id, ‘_factura_xml’, true));
$ambiente = ‘habilitacion’; // Cambiar a ‘produccion’ luego

$ch = curl_init();  
curl_setopt($ch, CURLOPT_URL, "https://catalogo-vpfe.dian.gov.co/$ambiente/api/v1/documents");  
curl_setopt($ch, CURLOPT_POST, true);  
curl_setopt($ch, CURLOPT_HTTPHEADER, [  
    'Content-Type: application/xml',  
    'Authorization: Bearer ' . obtener_token_dian()  
]);  
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml_firmado);  
$response = curl_exec($ch);  
curl_close($ch);  

// Guardar respuesta DIAN  
update_post_meta($order_id, '_respuesta_dian', $response);  

}

---

#### **Snippet 7: Adjuntar Factura a Emails**  
**Objetivo:** Incluir PDF/XML en correos de WooCommerce.  

php
add_filter(‘woocommerce_email_attachments’, ‘adjuntar_factura_dian’, 10, 3);
function adjuntar_factura_dian($attachments, $email_id, $order) {
if ($email_id === ‘customer_completed_order’) {
$file_path = get_post_meta($order->get_id(), ‘_factura_xml’, true);
$attachments[] = $file_path;
}
return $attachments;
}

---

#### **Snippet 8: Shortcode para Descarga**  
**Objetivo:** Permitir al cliente descargar factura desde "Mi cuenta".  

php
add_shortcode(‘descargar_factura’, ‘shortcode_descargar_factura’);
function shortcode_descargar_factura() {
if (!is_user_logged_in()) return;

$order_id = wc_get_order_id_by_order_key($_GET['order_key']);  
$file_url = get_post_meta($order_id, '_factura_xml', true);  

return '<a href="' . $file_url . '" class="button">Descargar Factura</a>';  

}
“`


3. Flujo de Trabajo Completo

  1. Checkout: Cliente ingresa NIT y tipo de responsable (Snippet 1).
  2. Orden Completada:
  • Generar XML (Snippet 2).
  • Firmar con certificado (Snippet 3).
  • Generar CUDE (Snippet 4).
  • Validar XSD (Snippet 5).
  1. Envío DIAN: Transmitir XML vía API (Snippet 6).
  2. Notificación: Adjuntar factura a emails (Snippet 7) y permitir descarga (Snippet 8).

4. Recursos Clave DIAN


5. Conclusión

  • Snippets Necesarios: 8 (PHP para campos, XML, firma, CUDE, validación, API, emails y shortcode).
  • Fuera de WordPress: Certificado DIAN, servidor con OpenSSL, registro en ambiente DIAN.
  • Influencia DIAN: 100% crítica. Todo el flujo técnico y legal depende de sus especificaciones.
  • Dificultad Técnica: Alta (Requiere integración con APIs, manejo de criptografía y estrictas validaciones XSD).

Nota Final: Este es un esquema básico. La implementación real requiere pruebas en ambiente DIAN, manejo de errores y posible integración con un proveedor tecnológico homologado.

Respuesta Detallada sobre la Conexión Directa a la DIAN mediante API (Colombia):
La DIAN (Dirección de Impuestos y Aduanas Nacionales) establece reglas estrictas para la facturación electrónica en Colombia. A continuación, aclaro el panorama legal y técnico:


1. ¿Permite la DIAN la Conexión Directa mediante API?

Sí, pero solo bajo estas condiciones:

  • Para Proveedores Tecnológicos Homologados:
    La DIAN autoriza únicamente a los Proveedores Tecnológicos (PT) homologados (Lista oficial aquí) para conectarse directamente a sus servidores mediante API. Estos PT actúan como intermediarios entre tu sistema (WordPress/WooCommerce) y la DIAN.
  • Para Empresas No Homologadas:
    No es posible conectarse directamente a los servidores de la DIAN. Debes usar:
    a) Un PT homologado (Ej: Facturador electrónico como Alegra, Siigo, o un desarrollo propio homologado).
    b) La plataforma web de la DIAN (Subida manual de XML).

2. Base Legal

  • Resolución 000042 de 2022 (Artículo 2.2.1.9.5.4):
    Establece que la transmisión de facturas electrónicas debe realizarse a través de un canal tecnológico seguro, el cual solo pueden proveer los PT homologados.
  • Decreto 2242 de 2015 (Artículo 5):
    Exige que los documentos electrónicos cumplan con los estándares de la DIAN, incluida la firma digital y la validación previa.

3. ¿Qué Sucede si te Conectas Directamente sin Homologación?

  • Invalidez Legal: Las facturas generadas no tendrán validez ante la DIAN.
  • Sanciones: Multas por incumplimiento de obligaciones tributarias (Artículo 651-3 del Estatuto Tributario).
  • Rechazo Técnico: La DIAN bloquea las peticiones que no provengan de IPs autorizadas de PT homologados.

4. Alternativas para WooCommerce/WordPress

a) Usar un Proveedor Tecnológico Homologado

  • Pasos:
    1. Contratar un PT (Ej: Habemus, Efact).
    2. Integrar su API con WooCommerce mediante plugins o snippets PHP.
    3. El PT se encarga de:
    • Generar el XML según estándares DIAN.
    • Firmar digitalmente.
    • Transmitir a la DIAN.
    • Gestionar respuestas y contingencia.
  • Ejemplo de Snippet para Integración con API de PT:
    “`php
    add_action(‘woocommerce_payment_complete’, ‘enviar_factura_pt_homologado’);
    function enviar_factura_pt_homologado($order_id) {
    $order = wc_get_order($order_id);
    $payload = array(
    ‘cliente’ => array(
    ‘nit’ => get_post_meta($order_id, ‘_billing_nit’, true),
    ‘total’ => $order->get_total()
    ),
    ‘items’ => array()
    ); // Agregar items foreach ($order->get_items() as $item) { $payload['items'][] = array( 'nombre' => $item->get_name(), 'precio' => $item->get_subtotal() ); } // Enviar a PT (Ej: Habemus) $response = wp_remote_post('https://api.pt-homologado.com/facturas', array( 'headers' => array('Authorization' => 'Bearer TU_API_KEY'), 'body' => json_encode($payload) )); // Guardar respuesta update_post_meta($order_id, '_respuesta_pt', $response['body']); }
    “`

b) Usar la Plataforma Web de la DIAN

  • Pasos:
    1. Generar el XML manualmente en WooCommerce (usando los snippets previos).
    2. Descargar el XML firmado.
    3. Subirlo manualmente al portal de validación DIAN:

5. ¿Cómo Homologar tu Propio Software como PT?

Si quieres evitar intermediarios y conectarte directamente, debes:

  1. Registrarte como PT:
  • Diligenciar el formulario en Registro PT DIAN.
  • Presentar certificados de seguridad y pruebas técnicas.
  1. Cumplir Requisitos Técnicos:
  • Implementar APIs SOAP/ REST según especificaciones DIAN.
  • Usar firma XAdES y algoritmos SHA-384.
  1. Certificación:
  • La DIAN evaluará tu software durante 30 días hábiles.
  • Costo aproximado: $8-15 millones de COP (dependiendo de complejidad).

6. Conclusión

  • Legalmente, solo los Proveedores Tecnológicos Homologados pueden conectarse directamente a la DIAN vía API.
  • Para usuarios de WooCommerce, la opción viable es integrarse con un PT homologado mediante su API.
  • Conectar WordPress directamente a la DIAN sin homologación es ilegal y técnicamente inviable.

Recomendación Final:
Usa un PT homologado para evitar riesgos legales y asegurar la validez de tus facturas. Si desarrollas tu propia solución, tramita la homologación ante la DIAN.

Publicaciones Similares

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

13 + 10 =