Solicitud de descarga correcta

This commit is contained in:
Mauricio Baeza 2021-07-14 15:32:30 -05:00
parent 48155488c3
commit 82033da207
4 changed files with 43 additions and 16 deletions

View File

@ -37,6 +37,10 @@ def _process_command_line_arguments():
help = "Día de la descarga, de forma predeterminada no se usa"
parser.add_argument('-d', '--dia', help=help, dest='day', default=0, type=int, choices=range(32))
help = 'Verificar estatus de descarga'
parser.add_argument('-ve', '--fiel-validar', help=help,
action='store_true', default=False, required=False)
args = parser.parse_args()
return args
@ -44,3 +48,10 @@ def _process_command_line_arguments():
if __name__ == '__main__':
args = _process_command_line_arguments()
main(args)
# ~ {
# ~ 'IdSolicitud': '307a22f0-1259-479c-96b1-2852f9072c58',
# ~ 'CodEstatus': '5000',
# ~ 'Mensaje': 'Solicitud Aceptada'
# ~ }

View File

@ -28,6 +28,7 @@ class SATCertificate(object):
def _init_values(self):
self._rfc = ''
self._serial_number = ''
self._serial_number2 = ''
self._not_before = None
self._not_after = None
self._is_fiel = False
@ -66,6 +67,7 @@ class SATCertificate(object):
obj = x509.load_der_x509_certificate(cer, default_backend())
self._rfc = obj.subject.get_attributes_for_oid(
NameOID.X500_UNIQUE_IDENTIFIER)[0].value.split(' ')[0]
self._serial_number2 = obj.serial_number
self._serial_number = '{0:x}'.format(obj.serial_number)[1::2]
self._not_before = obj.not_valid_before
self._not_after = obj.not_valid_after
@ -167,6 +169,10 @@ class SATCertificate(object):
def serial_number(self):
return self._serial_number
@property
def serial_number2(self):
return self._serial_number2
@property
def not_before(self):
return self._not_before

View File

@ -16,9 +16,10 @@ class SATWebService():
'REQ': f'{BASE}/SolicitaDescargaService.svc',
}
XMLNS = 'http://DescargaMasivaTerceros.gob.mx'
XMLNS2 = 'http://DescargaMasivaTerceros.sat.gob.mx'
ACTIONS = {
'AUTH': f'{XMLNS}/IAutenticacion/Autentica',
'REQ': f'{XMLNS}/ISolicitaDescargaService/SolicitaDescarga',
'REQ': f'{XMLNS2}/ISolicitaDescargaService/SolicitaDescarga',
}
HEADERS = {
'Content-type': 'text/xml;charset="utf-8"',
@ -33,6 +34,7 @@ class SATWebService():
'xd': 'http://www.w3.org/2000/09/xmldsig#',
}
NS_RESULT = {'s': NS['s'], None: XMLNS}
NS_RESULT2 = {'s': NS['s'], None: XMLNS2}
def __init__(self, cert):
self._cert = cert
@ -169,7 +171,8 @@ class SATWebService():
'RfcSolicitante': self._cert.rfc,
'FechaFinal': date_end.strftime(FORMAT),
'FechaInicial': date_start.strftime(FORMAT),
'TipoSolicitud': 'cfdi',
'TipoSolicitud': 'CFDI',
'RfcEmisor': self._cert.rfc,
}
request = ET.SubElement(request_down, node_name, attr)
# ~ if rfc_emisor is not None:
@ -183,7 +186,7 @@ class SATWebService():
node_name = 'CanonicalizationMethod'
attr1 = {'Algorithm': 'http://www.w3.org/2001/10/xml-exc-c14n#'}
canonicalization = ET.SubElement(signed_info, node_name, attr)
canonicalization = ET.SubElement(signed_info, node_name, attr1)
node_name = 'SignatureMethod'
attr = {'Algorithm': 'http://www.w3.org/2000/09/xmldsig#rsa-sha1'}
@ -192,24 +195,30 @@ class SATWebService():
attr = {'URI': '#_0'}
reference = ET.SubElement(signed_info, 'Reference', attr)
transforms = ET.SubElement(reference, 'Transforms')
ET.SubElement(transforms, 'Transform')
ET.SubElement(transforms, 'Transform', attr1)
attr = {'Algorithm': 'http://www.w3.org/2000/09/xmldsig#sha1'}
ET.SubElement(reference, 'DigestMethod', attr)
dvalue = ET.tostring(request_down, method='c14n', exclusive=1)
dvalue = base64.b64encode(hashlib.new('sha1', dvalue).digest())
ET.SubElement(reference, 'DigestValue').text = dvalue
signature_value = ET.tostring(signed_info, method='c14n', exclusive=1)
signature_value = self._cert.sign_sha1(signature_value)
ET.SubElement(signature, 'SignatureValue').text = signature_value
digest_value = ET.SubElement(reference, 'DigestValue')
signature_value = ET.SubElement(signature, 'SignatureValue')
key_info = ET.SubElement(signature, 'KeyInfo')
x_data = ET.SubElement(key_info, 'X509Data')
x_issuer_serial = ET.SubElement(x_data, 'X509IssuerSerial')
ET.SubElement(x_issuer_serial, 'X509IssuerName').text = self._cert.issuer
ET.SubElement(x_issuer_serial, 'X509SerialNumber').text = self._cert.serial_number
ET.SubElement(x_data, 'X509Certificate').text = self._cert.cer_txt
x_issuer = ET.SubElement(x_issuer_serial, 'X509IssuerName')
x_serial_number = ET.SubElement(x_issuer_serial, 'X509SerialNumber')
x_cert = ET.SubElement(x_data, 'X509Certificate')
dvalue = ET.tostring(request_down, method='c14n', exclusive=1)
dvalue = base64.b64encode(hashlib.new('sha1', dvalue).digest())
digest_value.text = dvalue
sign = ET.tostring(signed_info, method='c14n', exclusive=1)
sign = self._cert.sign_sha1(sign)
signature_value.text = sign
x_issuer.text = self._cert.issuer
x_serial_number.text = str(self._cert.serial_number2)
x_cert.text = self._cert.cer_txt
# ~ soap = ET.tostring(root, pretty_print=True, encoding='utf-8')
soap = ET.tostring(root)
@ -229,7 +238,7 @@ class SATWebService():
result = ET.fromstring(response.text)
node_name = 's:Body/SolicitaDescargaResponse/SolicitaDescargaResult'
node = result.find(node_name, namespaces=self.NS_RESULT)
node = result.find(node_name, namespaces=self.NS_RESULT2)
data = dict(node.attrib)
return data

View File

@ -100,6 +100,7 @@ def fiel_validar(args):
log.info(f'\n{cert}')
msg = 'Ya puedes descargar del SAT'
log.info(msg)
return