Ir al contenido
ReferenciaErrores
Sello del hash y3Pn1xVtk/6cnS0xW9UI/rGGNDE=ra-invoice · DIGESTVALUE · y3Pn1xVtk/6cnS0xW9UI/rGGNDE= ·

Ejemplos / Comunicación de baja (RA) / Caso 18 de 21

Comunicación de baja de una factura

La factura F001-123 con su motivo, «ERROR EN EL RUC DEL CLIENTE», la fecha en que se emitió y la fecha de la comunicación.

Firma este JSON con el certificado de prueba y tu DigestValue tiene que ser y3Pn1xVtk/6cnS0xW9UI/rGGNDE=. El sello es ese valor, dibujado.

Los tres archivos, en el repositorio: el JSON de entrada, el XML sin firmar y el XML firmado.

A diferencia de la factura, no vuelve con la CDR: sunat-sdk summary devuelve un ticket, y con sunat-sdk ticket preguntas hasta que la traiga; con 98 se pregunta otra vez, no se reenvía. Desde PHP, con summary() y ticket() (Paso a producción).

Entrada en JSON

Marcadas, las líneas que cambian respecto del caso más parecido, Comunicación de baja de tres facturas; lo igual queda plegado.

fixtures/ra-invoice.json
{  "kind": "voided",  "number": "1",
MostrarOcultar las líneas 4 a 22
  "generation_date": "2026-10-14",  "communication_date": "2026-10-15",  "issuer": {    "ruc": "20123456789",    "legal_name": "EMPRESA DEMO ORACULO S.A.C.",    "trade_name": "DEMO ORACULO",    "email": "facturacion@example.com",    "telephone": "014000000",    "address": {      "ubigeo": "150101",      "country_code": "PE",      "department": "LIMA",      "province": "LIMA",      "district": "LIMA",      "urbanization": "-",      "street": "AV. EJEMPLO 123",      "establishment_code": "0000"    }  },
  "lines": [    {      "document_type": "01",      "series": "F001",      "number": "123",      "reason": "ERROR EN EL RUC DEL CLIENTE"    }  ]}

XML sin firmar

Marcadas, las líneas que cambian respecto de Comunicación de baja de tres facturas.

tests/vectors/ra-invoice.unsigned.xml
<?xml version="1.0" encoding="utf-8"?><VoidedDocuments xmlns="urn:sunat:names:specification:ubl:peru:schema:xsd:VoidedDocuments-1" xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2" xmlns:sac="urn:sunat:names:specification:ubl:peru:schema:xsd:SunatAggregateComponents-1" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">  <ext:UBLExtensions>    <ext:UBLExtension>      <ext:ExtensionContent/>    </ext:UBLExtension>  </ext:UBLExtensions>  <cbc:UBLVersionID>2.0</cbc:UBLVersionID>  <cbc:CustomizationID>1.0</cbc:CustomizationID>  <cbc:ID>RA-20261015-1</cbc:ID>
MostrarOcultar las líneas 11 a 37
  <cbc:ReferenceDate>2026-10-14</cbc:ReferenceDate>  <cbc:IssueDate>2026-10-15</cbc:IssueDate>  <cac:Signature>    <cbc:ID>IDSignKG</cbc:ID>    <cac:SignatoryParty>      <cac:PartyIdentification>        <cbc:ID>20123456789</cbc:ID>      </cac:PartyIdentification>      <cac:PartyName>        <cbc:Name><![CDATA[EMPRESA DEMO ORACULO S.A.C.]]></cbc:Name>      </cac:PartyName>    </cac:SignatoryParty>    <cac:DigitalSignatureAttachment>      <cac:ExternalReference>        <cbc:URI>#signatureKG</cbc:URI>      </cac:ExternalReference>    </cac:DigitalSignatureAttachment>  </cac:Signature>  <cac:AccountingSupplierParty>    <cbc:CustomerAssignedAccountID>20123456789</cbc:CustomerAssignedAccountID>    <cbc:AdditionalAccountID>6</cbc:AdditionalAccountID>    <cac:Party>      <cac:PartyLegalEntity>        <cbc:RegistrationName><![CDATA[EMPRESA DEMO ORACULO S.A.C.]]></cbc:RegistrationName>      </cac:PartyLegalEntity>    </cac:Party>  </cac:AccountingSupplierParty>
  <sac:VoidedDocumentsLine>    <cbc:LineID>1</cbc:LineID>    <cbc:DocumentTypeCode>01</cbc:DocumentTypeCode>    <sac:DocumentSerialID>F001</sac:DocumentSerialID>    <sac:DocumentNumberID>123</sac:DocumentNumberID>    <sac:VoidReasonDescription><![CDATA[ERROR EN EL RUC DEL CLIENTE]]></sac:VoidReasonDescription>  </sac:VoidedDocumentsLine></VoidedDocuments>

Formateado para leerlo. «Copiar» copia el archivo tal como está en el repositorio, en una línea.

Firma

Firmado con el certificado de prueba del SDK, el que baja la guía de inicio.

Sello del hash y3Pn1xVtk/6cnS0xW9UI/rGGNDE=

y3Pn1xVtk/6cnS0xW9UI/rGGNDE=

Si tu DigestValue es este, tu XML es el mismo que el del SDK. Con el certificado de prueba el SignatureValue también coincide; con el tuyo cambia, porque depende de tu clave.

DigestValue
y3Pn1xVtk/6cnS0xW9UI/rGGNDE=
SignatureValue
MFTph6/pXJwOpSXNU1jTGusahDy4OH0M2id85Z+IoWtnWo1GaXpjYEt8rGr07Lw9AStilQkYf02YDOuehJamGRTNwrpcMrxMtcB0z1RmiV+v/bHg3iy7PDWlAID/ETTt7VP7AliXH1EI4fIbLQbRg1m0zoyTl5D6WLb+OwNkDlx9zdoCYSx2iLaaVTPcpvQnN+2NGrUVeja6CIR5DB8dc4p1bSrqVHA4jjqVb3rLedIbNAaf62eL0ch+3KzFPykepbkS7tFNagFYC/a1cQyeLeWNmoKLzl1o/T9zyStJFG1hibhAqMJ6SEwK1ARgu7tCMoSnel/VtypcWzBj2a3t1A==

XML firmado

tests/vectors/ra-invoice.signed.xml
<?xml version="1.0" encoding="utf-8"?><VoidedDocuments xmlns="urn:sunat:names:specification:ubl:peru:schema:xsd:VoidedDocuments-1" xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2" xmlns:sac="urn:sunat:names:specification:ubl:peru:schema:xsd:SunatAggregateComponents-1" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">  <ext:UBLExtensions>    <ext:UBLExtension>      <ext:ExtensionContent>        <ds:Signature Id="signatureKG">          <ds:SignedInfo>            <ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>            <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>            <ds:Reference URI="">              <ds:Transforms>                <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>              </ds:Transforms>              <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>              <ds:DigestValue>y3Pn1xVtk/6cnS0xW9UI/rGGNDE=</ds:DigestValue>            </ds:Reference>          </ds:SignedInfo>          <ds:SignatureValue>MFTph6/pXJwOpSXNU1jTGusahDy4OH0M2id85Z+IoWtnWo1GaXpjYEt8rGr07Lw9AStilQkYf02YDOuehJamGRTNwrpcMrxMtcB0z1RmiV+v/bHg3iy7PDWlAID/ETTt7VP7AliXH1EI4fIbLQbRg1m0zoyTl5D6WLb+OwNkDlx9zdoCYSx2iLaaVTPcpvQnN+2NGrUVeja6CIR5DB8dc4p1bSrqVHA4jjqVb3rLedIbNAaf62eL0ch+3KzFPykepbkS7tFNagFYC/a1cQyeLeWNmoKLzl1o/T9zyStJFG1hibhAqMJ6SEwK1ARgu7tCMoSnel/VtypcWzBj2a3t1A==</ds:SignatureValue>          <ds:KeyInfo>            <ds:X509Data>              <ds:X509Certificate>MIID8zCCAtugAwIBAgIUY968iRS4gHDjt9RwTaDaujmFLO0wDQYJKoZIhvcNAQELBQAwgYgxCzAJBgNVBAYTAlBFMS8wLQYDVQQKDCZURVNUIE9OTFkgLSBOT1QgVkFMSUQgRk9SIEFOWSBUQVhQQVlFUjESMBAGA1UECwwJVEVTVCBPTkxZMRQwEgYDVQQFEwsyMDAwMDAwMDAwMTEeMBwGA1UEAwwVVEVTVCBPTkxZIDIwMDAwMDAwMDAxMB4XDTI2MTAxNTIxMjc0NVoXDTM2MTAxMjIxMjc0NVowgYgxCzAJBgNVBAYTAlBFMS8wLQYDVQQKDCZURVNUIE9OTFkgLSBOT1QgVkFMSUQgRk9SIEFOWSBUQVhQQVlFUjESMBAGA1UECwwJVEVTVCBPTkxZMRQwEgYDVQQFEwsyMDAwMDAwMDAwMTEeMBwGA1UEAwwVVEVTVCBPTkxZIDIwMDAwMDAwMDAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6GZTtpFyih4C6ETakE6Q4+SFBFWJ/TQi2pbxJRD7GkQ1tKeB+ENcBk8EjnOocxdYWvSBpOd9UYkpc2C+jlbVWd04ey8psznwCHzJJ1+qgQqVI8PpH5A4eEw5LGXupHmnJSYpGXFGIJ6+tlJRqvZbq7RTh7Rpxs4DkCjUhUke/BKIZahYDzSGFLlsWx01Dq8Xeb6xF2sLlZXy/b0MvRZAe7I/xplIftS/rrDQ/rE5DfS0Dibayc/uNIRw1+NiKpT0wwY/VCzRQrM27dG7sTyhNAy6C3vtRmO5Bl9+0wrXldZcR4VSm1yrg65KRWv6DNcG2MkxRYBphaM+sJfkNECs6wIDAQABo1MwUTAdBgNVHQ4EFgQUE359gu7BEXWLRhx+VNBeec2Pp/kwHwYDVR0jBBgwFoAUE359gu7BEXWLRhx+VNBeec2Pp/kwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAzjWgukifoL9gZckM2jWW7a+N6+5W/0EkGJVFV9RbCceNpDpdMyVD4QyVm1nOJ/bQzOLdDnjyD3J34/1pEwo/hS/HehPy50twvf/uKEwPU4TNQTyjChnM3k+IX7cOusuPIBsC6trufeHOSky5lWiKWusMHo8VsPvVinE0n/RqTo47enHPFa6huF3egiQEJ6H+lxerXvWT8IkaGFA2YKjAGGsenlCSw9rRGX4tzQtUkJx0oFaEZGNpq+OYr334J3cZp9LskUFnrvRoAz3Fk8HdbVlfQTovFunFY9VzxbKjBfyWa6hymTxcvBR9x4ZfUKM9P3REeBKaTWdqe2oz4d6LLA==</ds:X509Certificate>            </ds:X509Data>          </ds:KeyInfo>        </ds:Signature>      </ext:ExtensionContent>    </ext:UBLExtension>  </ext:UBLExtensions>  <cbc:UBLVersionID>2.0</cbc:UBLVersionID>  <cbc:CustomizationID>1.0</cbc:CustomizationID>  <cbc:ID>RA-20261015-1</cbc:ID>  <cbc:ReferenceDate>2026-10-14</cbc:ReferenceDate>  <cbc:IssueDate>2026-10-15</cbc:IssueDate>  <cac:Signature>    <cbc:ID>IDSignKG</cbc:ID>    <cac:SignatoryParty>      <cac:PartyIdentification>        <cbc:ID>20123456789</cbc:ID>      </cac:PartyIdentification>      <cac:PartyName>        <cbc:Name><![CDATA[EMPRESA DEMO ORACULO S.A.C.]]></cbc:Name>
Mostrar las 25 líneas restantes (65 en total)
      </cac:PartyName>    </cac:SignatoryParty>    <cac:DigitalSignatureAttachment>      <cac:ExternalReference>        <cbc:URI>#signatureKG</cbc:URI>      </cac:ExternalReference>    </cac:DigitalSignatureAttachment>  </cac:Signature>  <cac:AccountingSupplierParty>    <cbc:CustomerAssignedAccountID>20123456789</cbc:CustomerAssignedAccountID>    <cbc:AdditionalAccountID>6</cbc:AdditionalAccountID>    <cac:Party>      <cac:PartyLegalEntity>        <cbc:RegistrationName><![CDATA[EMPRESA DEMO ORACULO S.A.C.]]></cbc:RegistrationName>      </cac:PartyLegalEntity>    </cac:Party>  </cac:AccountingSupplierParty>  <sac:VoidedDocumentsLine>    <cbc:LineID>1</cbc:LineID>    <cbc:DocumentTypeCode>01</cbc:DocumentTypeCode>    <sac:DocumentSerialID>F001</sac:DocumentSerialID>    <sac:DocumentNumberID>123</sac:DocumentNumberID>    <sac:VoidReasonDescription><![CDATA[ERROR EN EL RUC DEL CLIENTE]]></sac:VoidReasonDescription>  </sac:VoidedDocumentsLine></VoidedDocuments>

Formateado para leerlo. «Copiar» copia el archivo tal como está en el repositorio.

Reproducirlo

Con el SDK instalado como dice la guía de inicio, baja el caso y el certificado de prueba:

Terminal
curl -fsSL --remote-name-all \  https://fe.kembec.com/sdk/v0.1.0-beta.5/ra-invoice.json \  https://fe.kembec.com/sdk/v0.1.0-beta.5/test-cert.pem \  https://fe.kembec.com/sdk/v0.1.0-beta.5/test-key.pem

Fírmalo como en la guía: tu DigestValue tiene que ser el de arriba.

PHP

En firmar.php, la línea del JSON queda así:

firmar.php
$factura = file_get_contents(__DIR__ . '/ra-invoice.json');
Terminal
php firmar.php

JavaScript

En firmar.mjs, la línea del JSON queda así:

firmar.mjs
const built = JSON.parse(sdk.build(leer('ra-invoice.json')));
Terminal
node firmar.mjs

Python

En firmar.py, la línea del JSON queda así:

firmar.py
built = sunat_sdk.build(leer('ra-invoice.json'))
Terminal
python firmar.py

CLI

Terminal
sunat-sdk build < ra-invoice.json \  | sunat-sdk sign --cert test-cert.pem --key test-key.pem > firmada.jsongrep -o '"digest_value":"[^"]*"' firmada.jsongrep -q '"digest_value":"y3Pn1xVtk/6cnS0xW9UI/rGGNDE="' firmada.json && echo "digest ok"