La obligación para incorporar los siguientes complementos inicia a partir del 1 de noviembre del 2018.
Complementos para Consorcios en materia de Hidrocarburos.
El complemento para “Gastos del consorcio derivados de la Ejecución de un Contrato de Exploración o Extracción de Hidrocarburos”, incorpora la información sobre los gastos, costos e inversiones realizados por el operador del consorcio en la ejecución de un contrato de exploración o extracción de hidrocarburos.
El complemento para “Ingresos atribuibles a los Integrantes de un Consorcio derivados de la Contraprestación de un Contrato de Exploración o Extracción de Hidrocarburos”, incorpora la información sobre los ingresos atribuibles a los integrantes de un consorcio que fueron entregados al operador, los cuales derivan de la contraprestación de un contrato de exploración o extracción de hidrocarburos.
En el siguiente liga encontrará información referente al nuevo complemento para consorcios en materia de hidrocarburos 1.0, además podrá consultar el estándar en donde se encuentra el apartado “Validaciones adicionales a realizar por el Proveedor” para la implementación del complemento de acuerdo a las especificaciones del SAT.
| Nombre | Documento |
|---|---|
| Estándar técnico: | 📥 Descargar |
| Catálogos: | 📥 Descargar |
| Esquema XSD: | 📥 Descargar |
| Utilerías XSLT: | 📥 Descargar |
<cfdi:Comprobante xmlns:cfdi="http://www.sat.gob.mx/cfd/4" xmlns:gceh="http://www.sat.gob.mx/GastosHidrocarburos10" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sat.gob.mx/cfd/4 http://www.sat.gob.mx/sitio_internet/cfd/4/cfdv40.xsd http://www.sat.gob.mx/GastosHidrocarburos10 http://www.sat.gob.mx/sitio_internet/cfd/GastosHidrocarburos10/GastosHidrocarburos10.xsd" Certificado="MIIFsDCCA5igAwIBAgIUMzAwMDEwMDAwMDA1MDAwMDM0MTYwDQYJKoZIhvcNAQELBQAwggErMQ8wDQYDVQQDDAZBQyBVQVQxLjAsBgNVBAoMJVNFUlZJQ0lPIERFIEFETUlOSVNUUkFDSU9OIFRSSUJVVEFSSUExGjAYBgNVBAsMEVNBVC1JRVMgQXV0aG9yaXR5MSgwJgYJKoZIhvcNAQkBFhlvc2Nhci5tYXJ0aW5lekBzYXQuZ29iLm14MR0wGwYDVQQJDBQzcmEgY2VycmFkYSBkZSBjYWxpejEOMAwGA1UEEQwFMDYzNzAxCzAJBgNVBAYTAk1YMRkwFwYDVQQIDBBDSVVEQUQgREUgTUVYSUNPMREwDwYDVQQHDAhDT1lPQUNBTjERMA8GA1UELRMIMi41LjQuNDUxJTAjBgkqhkiG9w0BCQITFnJlc3BvbnNhYmxlOiBBQ0RNQS1TQVQwHhcNMjMwNTE4MTE0MzUxWhcNMjcwNTE4MTE0MzUxWjCB1zEnMCUGA1UEAxMeRVNDVUVMQSBLRU1QRVIgVVJHQVRFIFNBIERFIENWMScwJQYDVQQpEx5FU0NVRUxBIEtFTVBFUiBVUkdBVEUgU0EgREUgQ1YxJzAlBgNVBAoTHkVTQ1VFTEEgS0VNUEVSIFVSR0FURSBTQSBERSBDVjElMCMGA1UELRMcRUtVOTAwMzE3M0M5IC8gVkFEQTgwMDkyN0RKMzEeMBwGA1UEBRMVIC8gVkFEQTgwMDkyN0hTUlNSTDA1MRMwEQYDVQQLEwpTdWN1cnNhbCAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtmecO6n2GS0zL025gbHGQVxznPDICoXzR2uUngz4DqxVUC/w9cE6FxSiXm2ap8Gcjg7wmcZfm85EBaxCx/0J2u5CqnhzIoGCdhBPuhWQnIh5TLgj/X6uNquwZkKChbNe9aeFirU/JbyN7Egia9oKH9KZUsodiM/pWAH00PCtoKJ9OBcSHMq8Rqa3KKoBcfkg1ZrgueffwRLws9yOcRWLb02sDOPzGIm/jEFicVYt2Hw1qdRE5xmTZ7AGG0UHs+unkGjpCVeJ+BEBn0JPLWVvDKHZAQMj6s5Bku35+d/MyATkpOPsGT/VTnsouxekDfikJD1f7A1ZpJbqDpkJnss3vQIDAQABox0wGzAMBgNVHRMBAf8EAjAAMAsGA1UdDwQEAwIGwDANBgkqhkiG9w0BAQsFAAOCAgEAFaUgj5PqgvJigNMgtrdXZnbPfVBbukAbW4OGnUhNrA7SRAAfv2BSGk16PI0nBOr7qF2mItmBnjgEwk+DTv8Zr7w5qp7vleC6dIsZFNJoa6ZndrE/f7KO1CYruLXr5gwEkIyGfJ9NwyIagvHHMszzyHiSZIA850fWtbqtythpAliJ2jF35M5pNS+YTkRB+T6L/c6m00ymN3q9lT1rB03YywxrLreRSFZOSrbwWfg34EJbHfbFXpCSVYdJRfiVdvHnewN0r5fUlPtR9stQHyuqewzdkyb5jTTw02D2cUfL57vlPStBj7SEi3uOWvLrsiDnnCIxRMYJ2UA2ktDKHk+zWnsDmaeleSzonv2CHW42yXYPCvWi88oE1DJNYLNkIjua7MxAnkNZbScNw01A6zbLsZ3y8G6eEYnxSTRfwjd8EP4kdiHNJftm7Z4iRU7HOVh79/lRWB+gd171s3d/mI9kte3MRy6V8MMEMCAnMboGpaooYwgAmwclI2XZCczNWXfhaWe0ZS5PmytD/GDpXzkX0oEgY9K/uYo5V77NdZbGAjmyi8cE2B2ogvyaN2XfIInrZPgEffJ4AB7kFA2mwesdLOCh0BLD9itmCve3A1FGR4+stO2ANUoiI3w3Tv2yQSg4bjeDlJ08lXaaFCLW2peEXMXjQUk7fmpb5MNuOUTW6BE=" Exportacion="01" Fecha="2026-03-24T10:06:57" Folio="3000" FormaPago="99" LugarExpedicion="85000" MetodoPago="PPD" Moneda="MXN" NoCertificado="30001000000500003416" Sello="VdHALWei4QlCfnat+5f9uU9b8XKWKw3FNAmwg/QN7c59OzntiOpeql7IPA1e5eD75rZhqAUS26Q91+IZ3eW+gyiq3BPUZwuoIFd7EsoPEXdFWO/jdxghg0K50wFN1g+fz3+UGT/9uhF3iu/4IrbXEMCHzraMSyWdWe3+gewkWRBABW6s58HCNopJSOIooc/qto4VRzeaxn3BQmWm14uEesS/GijEOMGboaRNYhOpRay30aDETa1hpYMrIzTXSHF+1QJpNuptcxdP7jK74PsPXc+ZKM4e9jli3Tmb1P+sEof5t5GzDxyHAZQa8EuIOLBe/f+D26glXYSCOIXQMCCa9Q==" Serie="Serie" SubTotal="150.00" TipoCambio="1" TipoDeComprobante="E" Total="150.00" Version="4.0" >
<cfdi:Emisor Nombre="ESCUELA KEMPER URGATE" RegimenFiscal="603" Rfc="EKU9003173C9"/>
<cfdi:Receptor DomicilioFiscalReceptor="22000" Nombre="ALBERCAS MONTAÑO" RegimenFiscalReceptor="616" Rfc="AMO8905171T1" UsoCFDI="S01"/>
<cfdi:Conceptos>
<cfdi:Concepto Cantidad="1" ClaveProdServ="71121200" ClaveUnidad="E48" Descripcion="Servicios de extracción de muestras" Importe="150.00" ObjetoImp="01" ValorUnitario="150.00"/>
</cfdi:Conceptos>
<cfdi:Complemento>
<gceh:GastosHidrocarburos NumeroContrato="987654321" Version="1.0">
<gceh:Erogacion MontocuErogacion="120.00" Porcentaje="4.00" TipoErogacion="Costo">
<gceh:DocumentoRelacionado FechaFolioFiscalVinculado="2020-05-01" FolioFiscalVinculado="280D01FF-C984-547B-910F-523631FF24FB" Mes="05" MontoTotalErogaciones="69600.00" MontoTotalIVA="9600.00" OrigenErogacion="Nacional" RFCProveedor="TUCA2107035N9"/>
<gceh:CentroCostos Campo="Coahuila XX">
<gceh:Yacimientos Yacimiento="Rio I">
<gceh:Pozos Pozo="Pozo G1"/>
</gceh:Yacimientos>
</gceh:CentroCostos>
</gceh:Erogacion>
</gceh:GastosHidrocarburos>
</cfdi:Complemento>
</cfdi:Comprobante>
<?php
date_default_timezone_set("America/Mexico_City");
error_reporting(E_ALL & ~E_WARNING);
// Rutas
$rutaCer = "/home/user/CSD/EKU9003173C9.cer";
$rutaKey = "/home/user/Llave.pem";
$rutaXML = "/home/user/gastoshidr.xml";
$rutaCadena = "/home/user/CadenaOriginal.txt";
$rutaXSLT = "/home/user/XSLT/cadenaoriginal_4_0.xslt";
// Crear carpeta destino si no existe
if (!file_exists(dirname($rutaXML))) mkdir(dirname($rutaXML), 0777, true);
// Certificado Base64
$certificado = base64_encode(file_get_contents($rutaCer));
// Obtener NoCertificado con HEX2BIN
$certDer = file_get_contents($rutaCer);
$certPem = "-----BEGIN CERTIFICATE-----\n" .
chunk_split(base64_encode($certDer), 64, "\n") .
"-----END CERTIFICATE-----\n";
$parsed = @openssl_x509_parse($certPem);
if ($parsed !== false && !empty($parsed['serialNumberHex'])) {
$hex = preg_replace('/\s+/', '', $parsed['serialNumberHex']);
$noCertificado = strtoupper(hex2bin($hex));
}
$ns = "http://www.sat.gob.mx/cfd/4";
$nsGasto10 = "http://www.sat.gob.mx/GastosHidrocarburos10";
// === CREAR XML === //
$xml = new DOMDocument("1.0", "UTF-8");
$xml->formatOutput = true;
// Nodo Comprobante
$comprobante = $xml->createElementNS($ns, "cfdi:Comprobante");
$xml->appendChild($comprobante);
// Declarar namespace del complemento
$comprobante->setAttributeNS(
"http://www.w3.org/2000/xmlns/",
"xmlns:gceh",
$nsGasto10
);
// Namespaces obligatorios
$comprobante->setAttribute("xmlns:cfdi", $ns);
$comprobante->setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
$comprobante->setAttribute("xsi:schemaLocation",
"$ns http://www.sat.gob.mx/sitio_internet/cfd/4/cfdv40.xsd " .
"$nsGasto10 http://www.sat.gob.mx/sitio_internet/cfd/GastosHidrocarburos10/GastosHidrocarburos10.xsd"
);
// Atributos CFDI
$comprobante->setAttribute("Version", "4.0");
$comprobante->setAttribute("Serie", "A");
$comprobante->setAttribute("Folio", "167ABC");
$comprobante->setAttribute("Fecha", date('Y-m-d\TH:i:s'));
$comprobante->setAttribute("SubTotal", "1000.00");
$comprobante->setAttribute("Total", "1120.00");
$comprobante->setAttribute("Moneda", "MXN");
$comprobante->setAttribute("TipoCambio", "1");
$comprobante->setAttribute("TipoDeComprobante", "I");
$comprobante->setAttribute("LugarExpedicion", "58000");
$comprobante->setAttribute("FormaPago", "03");
$comprobante->setAttribute("MetodoPago", "PUE");
$comprobante->setAttribute("Exportacion", "01");
if (!empty($noCertificado)) {
$comprobante->setAttribute("NoCertificado", $noCertificado);
}
$comprobante->setAttribute("Certificado", $certificado);
// Emisor
$emisor = $xml->createElementNS($ns, "cfdi:Emisor");
$emisor->setAttribute("Rfc", "EKU9003173C9");
$emisor->setAttribute("Nombre", "ESCUELA KEMPER URGATE");
$emisor->setAttribute("RegimenFiscal", "601");
$comprobante->appendChild($emisor);
// Receptor
$receptor = $xml->createElementNS($ns, "cfdi:Receptor");
$receptor->setAttribute("Rfc", "ICV060329BY0");
$receptor->setAttribute("Nombre", "INMOBILIARIA CVA");
$receptor->setAttribute("UsoCFDI", "G03");
$receptor->setAttribute("RegimenFiscalReceptor", "601");
$receptor->setAttribute("DomicilioFiscalReceptor", "33826");
$comprobante->appendChild($receptor);
// Conceptos
$conceptos = $xml->createElementNS($ns, "cfdi:Conceptos");
$concepto = $xml->createElementNS($ns, "cfdi:Concepto");
$concepto->setAttribute("ClaveProdServ", "78101802");
$concepto->setAttribute("Cantidad", "1.00");
$concepto->setAttribute("ClaveUnidad", "E48");
$concepto->setAttribute("Descripcion", "servicios de transporte");
$concepto->setAttribute("ValorUnitario", "1000.00");
$concepto->setAttribute("Importe", "1000.00");
$concepto->setAttribute("ObjetoImp", "02");
$conceptos->appendChild($concepto);
$comprobante->appendChild($conceptos);
// Impuestos del concepto
$impC = $xml->createElementNS($ns, "cfdi:Impuestos");
$tras = $xml->createElementNS($ns, "cfdi:Traslados");
$t = $xml->createElementNS($ns, "cfdi:Traslado");
$t->setAttribute("Base", "1000.00");
$t->setAttribute("Impuesto", "002");
$t->setAttribute("TipoFactor", "Tasa");
$t->setAttribute("TasaOCuota", "0.160000");
$t->setAttribute("Importe", "160.00");
$tras->appendChild($t);
// Retenciones
$retC = $xml->createElementNS($ns, "cfdi:Retenciones");
$r = $xml->createElementNS($ns, "cfdi:Retencion");
$r->setAttribute("Base", "1000.00");
$r->setAttribute("Impuesto", "002");
$r->setAttribute("TipoFactor", "Tasa");
$r->setAttribute("TasaOCuota", "0.040000");
$r->setAttribute("Importe", "40.00");
$retC->appendChild($r);
$impC->appendChild($tras);
$impC->appendChild($retC);
$concepto->appendChild($impC);
// Impuestos totales
$impTotal = $xml->createElementNS($ns, "cfdi:Impuestos");
$impTotal->setAttribute("TotalImpuestosRetenidos", "40.00");
$impTotal->setAttribute("TotalImpuestosTrasladados", "160.00");
$retencionesTotal = $xml->createElementNS($ns, "cfdi:Retenciones");
$retencionTotal = $xml->createElementNS($ns, "cfdi:Retencion");
$retencionTotal->setAttribute("Impuesto", "002");
$retencionTotal->setAttribute("Importe", "40.00");
$retencionesTotal->appendChild($retencionTotal);
$impTotal->appendChild($retencionesTotal);
$trasladosTotal = $xml->createElementNS($ns, "cfdi:Traslados");
$trasladoTotal = $xml->createElementNS($ns, "cfdi:Traslado");
$trasladoTotal->setAttribute("Base", "1000.00");
$trasladoTotal->setAttribute("Impuesto", "002");
$trasladoTotal->setAttribute("TipoFactor", "Tasa");
$trasladoTotal->setAttribute("TasaOCuota", "0.160000");
$trasladoTotal->setAttribute("Importe", "160.00");
$trasladosTotal->appendChild($trasladoTotal);
$impTotal->appendChild($trasladosTotal);
$comprobante->appendChild($impTotal);
// =================================================================
$Complemento = $xml->createElementNS($ns, "cfdi:Complemento");
$comprobante->appendChild($Complemento);
// Nodo principal del complemento
$Gasto = $xml->createElementNS($nsGasto10, "gceh:GastosHidrocarburos");
$Gasto->setAttribute("NumeroContrato", "123456789");
$Gasto->setAttribute("Version", "1.0");
$Complemento->appendChild($Gasto);
// Erogación
$Ero = $xml->createElementNS($nsGasto10, "gceh:Erogacion");
$Ero->setAttribute("MontocuErogacion", "1200.00");
$Ero->setAttribute("Porcentaje", "80.00");
$Ero->setAttribute("TipoErogacion", "Costo");
$Gasto->appendChild($Ero);
// DocumentoRelacionado
$DoctoR = $xml->createElementNS($nsGasto10, "gceh:DocumentoRelacionado");
$DoctoR->setAttribute("FechaFolioFiscalVinculado", "2018-05-10");
$DoctoR->setAttribute("FolioFiscalVinculado", "A39DA66B-52CA-49E3-879B-5C05185B0EF7");
$DoctoR->setAttribute("Mes", "05");
$DoctoR->setAttribute("MontoTotalErogaciones", "69600.00");
$DoctoR->setAttribute("MontoTotalIVA", "9600.00");
$DoctoR->setAttribute("OrigenErogacion", "Nacional");
$DoctoR->setAttribute("RFCProveedor", "TUCA2107035N9");
$Ero->appendChild($DoctoR);
// CentroCostos
$Centro = $xml->createElementNS($nsGasto10, "gceh:CentroCostos");
$Centro->setAttribute("Campo", "Guerrero XX");
$Ero->appendChild($Centro);
// Yacimientos
$Yac = $xml->createElementNS($nsGasto10, "gceh:Yacimientos");
$Yac->setAttribute("Yacimiento", "Pacifico I");
$Centro->appendChild($Yac);
// Pozos
$Pozo = $xml->createElementNS($nsGasto10, "gceh:Pozos");
$Pozo->setAttribute("Pozo", "Pozo G1");
$Yac->appendChild($Pozo);
// === CADENA ORIGINAL ===
$xsl = new DOMDocument();
$xsl->load($rutaXSLT);
$proc = new XSLTProcessor();
$proc->importStylesheet($xsl);
$cadenaOriginal = trim($proc->transformToXML($xml));
file_put_contents($rutaCadena, $cadenaOriginal);
// === SELLO DIGITAL ===
$privKey = openssl_pkey_get_private(file_get_contents($rutaKey));
if (!$privKey) {
die("ERROR cargando la llave privada:\n" . openssl_error_string());
}
if (!openssl_sign($cadenaOriginal, $sello, $privKey, OPENSSL_ALGO_SHA256)) {
die("ERROR al firmar:\n" . openssl_error_string());
}
$sello = base64_encode($sello);
$comprobante->setAttribute("Sello", $sello);
// === GUARDAR XML ===
$xml->save($rutaXML);
@file_put_contents('/tmp/debug_gastoshidr.xml', $xml->saveXML());
echo "\nXML sellado generado correctamente:\n$rutaXML\n";
echo "\nCadena Original generada:\n$cadenaOriginal\n";
?>
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from lxml import etree
from datetime import datetime
from lxml import etree
from lxml import etree as ET
from datetime import datetime
import os
import hashlib
import base64
import uuid
import base64
import hashlib
import xml.etree.ElementTree as ET
import sys
import importlib
from M2Crypto.RSA import load_key_string
importlib.reload(sys)
class crear_cadena40(object):
def __init__(self):
#breakpoint
archivo = self.creacionXML()
self.now = datetime.now().replace(microsecond=0).isoformat('T')
self.XSLT_STYLE = etree.parse("/home/XSLT/cadenaoriginal_4_0.xslt")
self.xml_string = open('XML/hidro.xml', 'rb').read()
xml_etree = etree.fromstring(self.xml_string)
self.cadena_original = self.obtener_cadena_original(xml_etree)
self.sello = self.obtener_sello(self.cadena_original) # Obtener el sello
self.agregar_sello_al_xml(xml_etree) # Agregar el sello al XML
def creacionXML(self):
"""relelnar atributos del XML"""
import os
# Definir ruta absoluta a la carpeta XML
ruta_xml_dir = '/home/CrearCFDI4.0/XML'
# Crear carpeta si no existe
if not os.path.exists(ruta_xml_dir):
os.makedirs(ruta_xml_dir)
certificado_file = '/home/CSD/EKU9003173C9.cer'
with open(certificado_file, 'rb') as f:
certificado_data = f.read()
certificado_base64 = base64.b64encode(certificado_data).decode('utf-8').replace('\n', '').replace('\r', '')
os.system('openssl x509 -inform DER -in '+ certificado_file + ' -noout -serial > "numero.txt"')
with open('numero.txt', 'r') as serial_file:
serial = serial_file.read()
no_certificado = serial[::2][4:]
ET.register_namespace('cfdi', "http://www.sat.gob.mx/cfd/4")
ET.register_namespace('gceh', 'http://www.sat.gob.mx/GastosHidrocarburos10')
namespace = {'xmlns:gceh':'http://www.sat.gob.mx/GastosHidrocarburos10',
'xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance', 'xsi:schemaLocation':'http://www.sat.gob.mx/cfd/4 http://www.sat.gob.mx/sitio_internet/cfd/4/cfdv40.xsd http://www.sat.gob.mx/GastosHidrocarburos10 http://www.sat.gob.mx/sitio_internet/cfd/GastosHidrocarburos10/GastosHidrocarburos10.xsd'}
Comprobante = ET.Element("{http://www.sat.gob.mx/cfd/4}Comprobante", namespace,
Version="4.0",
Folio="167ABC",
Fecha=datetime.now().replace(microsecond=0).isoformat('T'),
SubTotal="1000.00",
NoCertificado=no_certificado,
Certificado=certificado_base64,
Total="1120.00" ,
Moneda="MXN",
TipoCambio="1",
TipoDeComprobante="I" ,
LugarExpedicion="58000",
CondicionesDePago="CONDICIONES",
FormaPago="03",
Serie="A",
MetodoPago="PUE",
Exportacion="01"
)
Emisor = ET.SubElement(Comprobante, '{http://www.sat.gob.mx/cfd/4}Emisor',
Rfc="EKU9003173C9" ,
Nombre="ESCUELA KEMPER URGATE",
RegimenFiscal="601"
)
Receptor = ET.SubElement(Comprobante, '{http://www.sat.gob.mx/cfd/4}Receptor',
Rfc="ICV060329BY0" ,
Nombre="INMOBILIARIA CVA" ,
UsoCFDI="G03",
RegimenFiscalReceptor="601",
DomicilioFiscalReceptor="33826"
)
Conceptos=ET.SubElement(Comprobante, '''cfdi:Conceptos''')
Concepto = ET.SubElement(Conceptos, '''cfdi:Concepto''',
Cantidad="1.00",
ClaveProdServ="78101802",
ClaveUnidad="E48",
Descripcion="servicios de transporte",
#Descuento="22500.00",
Importe="1000.00",
#NoIdentificacion="0001",
Unidad="Servicio",
ValorUnitario="1000.00",
ObjetoImp="02" )
#IMPUESTOS CONCEPTO
Impuestos=ET.SubElement(Concepto, '''cfdi:Impuestos''')
Traslados=ET.SubElement(Impuestos, '''cfdi:Traslados''')
Traslado=ET.SubElement(Traslados, '''cfdi:Traslado''',
Base="1000.00",
Importe="160.00",
Impuesto="002",
TasaOCuota="0.160000",
TipoFactor="Tasa")
Retenciones=ET.SubElement(Impuestos, '''cfdi:Retenciones''')
Retencion=ET.SubElement(Retenciones, '''cfdi:Retencion''',
Base="1000.00",
Importe="40.00",
Impuesto="002",
TasaOCuota="0.040000",
TipoFactor="Tasa")
#IMPUESTOS COMPROBANTE
Impuestos=ET.SubElement(Comprobante, '''cfdi:Impuestos''',
TotalImpuestosRetenidos="40.00",
TotalImpuestosTrasladados="160.00")
Retenciones=ET.SubElement(Impuestos, '''cfdi:Retenciones''')
Retencion=ET.SubElement(Retenciones, '''cfdi:Retencion''',
Importe="40.00",
Impuesto="002")
Traslados=ET.SubElement(Impuestos, '''cfdi:Traslados''')
Traslado=ET.SubElement(Traslados, '''cfdi:Traslado''',
Importe="160.00",
Base="1000.00",
Impuesto="002",
TasaOCuota="0.160000",
TipoFactor="Tasa")
# COMPLEMENTO GASTOS HIDROCARBUROS
Complemento=ET.SubElement(Comprobante, '''cfdi:Complemento''')
GastoHidro = ET.SubElement(Complemento,'gceh:GastosHidrocarburos',
Version="1.0",
NumeroContrato="123456789"
)
Erogacion = ET.SubElement(GastoHidro,'gceh:Erogacion',
MontocuErogacion="1200.00",
Porcentaje="80.00",
TipoErogacion="Costo"
)
ET.SubElement(Erogacion,'gceh:DocumentoRelacionado',
FechaFolioFiscalVinculado="2018-05-10",
FolioFiscalVinculado="A39DA66B-52CA-49E3-879B-5C05185B0EF7",
Mes="05",
MontoTotalErogaciones="69600.00",
MontoTotalIVA="9600.00",
OrigenErogacion="Nacional",
RFCProveedor="TUCA2107035N9"
)
CentroCostos = ET.SubElement(Erogacion,'gceh:CentroCostos',
Campo="Guerrero XX"
)
Yacimientos = ET.SubElement(CentroCostos,'gceh:Yacimientos',
Yacimiento="Pacifico I"
)
ET.SubElement(Yacimientos,'gceh:Pozos',
Pozo="Pozo G1"
)
xml_str = ET.tostring(Comprobante, encoding='utf-8', method='xml').decode('utf-8')
with open('XML/gastoshidro.xml', 'w', encoding='utf-8') as archivo:
archivo.truncate(0)
archivo.write(xml_str)
archivo.close()
def obtener_cadena_original(self, xml_etree):
result = etree.XSLT(self.XSLT_STYLE)
result = result(xml_etree)
original_string = str(result)
original_string = original_string.replace('<?xml version="1.0" encoding="UTF-8"?>\n', '')
original_string = original_string.replace("\n", "")
original_string = original_string.replace(""", '"')
original_string = original_string.replace("<", "<")
original_string = original_string.replace(">", ">")
original_string = original_string.replace("&", "&")
original_string = original_string.strip()
print(original_string)
self.original_string_result = original_string
return self.original_string_result
def obtener_sello(self, cadena_original):
"""Generar sello del XML"""
key_file_path = '/home/jbueno/Documentos/Timbrado_WSDL/CrearCFDI4.0/CSD/EKU9003173C9Key.pem'
# Verificar si el archivo de clave privada existe
if os.path.exists(key_file_path):
key_file = open(key_file_path).read()
key_pem = bytes(key_file, encoding='utf8')
rsa = load_key_string(key_pem)
assert len(rsa) in (1024, 2048)
assert rsa.e == b'\000\000\000\003\001\000\001'
cadena_original_encode = cadena_original.encode('utf-8')
md5_digest = hashlib.sha256(cadena_original_encode).digest()
rsa_signature = rsa.sign(md5_digest, 'sha256')
signature = base64.b64encode(rsa_signature)
return signature
else:
raise FileNotFoundError(f"Archivo de clave privada no encontrado en la ruta: {key_file_path}")
def agregar_sello_al_xml(self, xml_etree):
"""insertar sello al XML"""
comprobante = xml_etree
if comprobante is None:
print("Error: No se encontró el elemento Comprobante en el XML.")
return
# Agregar el sello al elemento Comprobante
comprobante.set("Sello", self.sello.decode('utf-8')) # Utilizar self.sello
#print(etree.tostring(comprobante))
xml_str = ET.tostring(comprobante, encoding='utf-8', method='xml').decode('utf-8')
with open('XML/gastoshidro.xml', 'w', encoding='utf-8') as archivo:
archivo.truncate(0)
archivo.write(xml_str)
print("XML SELLADO DE FORMA EXITOSA!!")
instancia = crear_cadena40()