Tcl
Tcl
Sign Bolivia Invoice XML
See more XML Digital Signatures Examples
Demonstrates how to create an XML digital signature (XmlDSig) for a Bolivia invoice (factura).Chilkat Tcl Downloads
load ./chilkat.dll
set success 0
# This example assumes the Chilkat API to have been previously unlocked.
# See Global Unlock Sample for sample code.
set success 1
# Create the following XML to be signed:
# <?xml version="1.0" encoding="UTF-8"?>
# <facturaElectronicaCompraVenta xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="facturaElectronicaCompraVenta.xsd">
# <cabecera>
# <nitEmisor>99999999</nitEmisor>
# <razonSocialEmisor>Abc Xyz</razonSocialEmisor>
# <municipio>Cochabamba - Cochabamba</municipio>
# <telefono>4444444</telefono>
# <numeroFactura>417</numeroFactura>
# <cuf>ABABABABABABABABABABABABABABABABABABABABABABABABABABABABA</cuf>
# <cufd>xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</cufd>
# <codigoSucursal>0</codigoSucursal>
# <direccion>aaa aaa aaa</direccion>
# <codigoPuntoVenta>1</codigoPuntoVenta>
# <fechaEmision>2023-04-13T22:43:22.417</fechaEmision>
# <nombreRazonSocial>xyz</nombreRazonSocial>
# <codigoTipoDocumentoIdentidad>1</codigoTipoDocumentoIdentidad>
# <numeroDocumento>1234567</numeroDocumento>
# <complemento xsi:nil="true"/>
# <codigoCliente>1234567</codigoCliente>
# <codigoMetodoPago>1</codigoMetodoPago>
# <numeroTarjeta xsi:nil="true"/>
# <montoTotal>22.00</montoTotal>
# <montoTotalSujetoIva>22.00</montoTotalSujetoIva>
# <codigoMoneda>1</codigoMoneda>
# <tipoCambio>1.00</tipoCambio>
# <montoTotalMoneda>22.00</montoTotalMoneda>
# <montoGiftCard xsi:nil="true"/>
# <descuentoAdicional>0.00</descuentoAdicional>
# <codigoExcepcion>1</codigoExcepcion>
# <cafc xsi:nil="true"/>
# <leyenda>Ley N� 453: El proveedor de servicios debe habilitar medios e instrumentos para efectuar consultas y reclamaciones.</leyenda>
# <usuario>nromero</usuario>
# <codigoDocumentoSector>1</codigoDocumentoSector>
# </cabecera>
# <detalle>
# <actividadEconomica>620100</actividadEconomica>
# <codigoProductoSin>123456</codigoProductoSin>
# <codigoProducto>1</codigoProducto>
# <descripcion>Economicos</descripcion>
# <cantidad>1.00</cantidad>
# <unidadMedida>58</unidadMedida>
# <precioUnitario>22.00</precioUnitario>
# <montoDescuento>0.00</montoDescuento>
# <subTotal>22.00</subTotal>
# <numeroSerie xsi:nil="true"/>
# <numeroImei xsi:nil="true"/>
# </detalle>
# </facturaElectronicaCompraVenta>
# Use this online tool to generate code from sample XML:
# Generate Code to Create XML
set xml [new_CkXml]
CkXml_put_Tag $xml "facturaElectronicaCompraVenta"
CkXml_AddAttribute $xml "xmlns:xsi" "http://www.w3.org/2001/XMLSchema-instance"
CkXml_AddAttribute $xml "xsi:noNamespaceSchemaLocation" "facturaElectronicaCompraVenta.xsd"
CkXml_UpdateChildContent $xml "cabecera|nitEmisor" "99999999"
CkXml_UpdateChildContent $xml "cabecera|razonSocialEmisor" "Abc Xyz"
CkXml_UpdateChildContent $xml "cabecera|municipio" "Cochabamba - Cochabamba"
CkXml_UpdateChildContent $xml "cabecera|telefono" "4444444"
CkXml_UpdateChildContent $xml "cabecera|numeroFactura" "417"
CkXml_UpdateChildContent $xml "cabecera|cuf" "ABABABABABABABABABABABABABABABABABABABABABABABABABABABABA"
CkXml_UpdateChildContent $xml "cabecera|cufd" "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
CkXml_UpdateChildContent $xml "cabecera|codigoSucursal" "0"
CkXml_UpdateChildContent $xml "cabecera|direccion" "aaa aaa aaa"
CkXml_UpdateChildContent $xml "cabecera|codigoPuntoVenta" "1"
CkXml_UpdateChildContent $xml "cabecera|fechaEmision" "2023-04-13T22:43:22.417"
CkXml_UpdateChildContent $xml "cabecera|nombreRazonSocial" "xyz"
CkXml_UpdateChildContent $xml "cabecera|codigoTipoDocumentoIdentidad" "1"
CkXml_UpdateChildContent $xml "cabecera|numeroDocumento" "1234567"
CkXml_UpdateAttrAt $xml "cabecera|complemento" 1 "xsi:nil" "true"
CkXml_UpdateChildContent $xml "cabecera|codigoCliente" "1234567"
CkXml_UpdateChildContent $xml "cabecera|codigoMetodoPago" "1"
CkXml_UpdateAttrAt $xml "cabecera|numeroTarjeta" 1 "xsi:nil" "true"
CkXml_UpdateChildContent $xml "cabecera|montoTotal" "22.00"
CkXml_UpdateChildContent $xml "cabecera|montoTotalSujetoIva" "22.00"
CkXml_UpdateChildContent $xml "cabecera|codigoMoneda" "1"
CkXml_UpdateChildContent $xml "cabecera|tipoCambio" "1.00"
CkXml_UpdateChildContent $xml "cabecera|montoTotalMoneda" "22.00"
CkXml_UpdateAttrAt $xml "cabecera|montoGiftCard" 1 "xsi:nil" "true"
CkXml_UpdateChildContent $xml "cabecera|descuentoAdicional" "0.00"
CkXml_UpdateChildContent $xml "cabecera|codigoExcepcion" "1"
CkXml_UpdateAttrAt $xml "cabecera|cafc" 1 "xsi:nil" "true"
CkXml_UpdateChildContent $xml "cabecera|leyenda" "Ley N� 453: El proveedor de servicios debe habilitar medios e instrumentos para efectuar consultas y reclamaciones."
CkXml_UpdateChildContent $xml "cabecera|usuario" "nromero"
CkXml_UpdateChildContent $xml "cabecera|codigoDocumentoSector" "1"
CkXml_UpdateChildContent $xml "detalle|actividadEconomica" "620100"
CkXml_UpdateChildContent $xml "detalle|codigoProductoSin" "123456"
CkXml_UpdateChildContent $xml "detalle|codigoProducto" "1"
CkXml_UpdateChildContent $xml "detalle|descripcion" "Economicos"
CkXml_UpdateChildContent $xml "detalle|cantidad" "1.00"
CkXml_UpdateChildContent $xml "detalle|unidadMedida" "58"
CkXml_UpdateChildContent $xml "detalle|precioUnitario" "22.00"
CkXml_UpdateChildContent $xml "detalle|montoDescuento" "0.00"
CkXml_UpdateChildContent $xml "detalle|subTotal" "22.00"
CkXml_UpdateAttrAt $xml "detalle|numeroSerie" 1 "xsi:nil" "true"
CkXml_UpdateAttrAt $xml "detalle|numeroImei" 1 "xsi:nil" "true"
set gen [new_CkXmlDSigGen]
CkXmlDSigGen_put_SigLocation $gen "facturaElectronicaCompraVenta"
CkXmlDSigGen_put_SigLocationMod $gen 0
CkXmlDSigGen_put_SigNamespacePrefix $gen ""
CkXmlDSigGen_put_SigNamespaceUri $gen "http://www.w3.org/2000/09/xmldsig#"
CkXmlDSigGen_put_SignedInfoCanonAlg $gen "C14N"
CkXmlDSigGen_put_SignedInfoDigestMethod $gen "sha256"
CkXmlDSigGen_AddSameDocRef $gen "" "sha256" "C14N_WithComments" "" ""
# Provide your certificate + private key. (PFX password is test123)
set cert [new_CkCert]
set success [CkCert_LoadPfxFile $cert "qa_data/pfx/cert_test123.pfx" "test123"]
if {$success != 1} then {
puts [CkCert_lastErrorText $cert]
delete_CkXml $xml
delete_CkXmlDSigGen $gen
delete_CkCert $cert
exit
}
CkXmlDSigGen_SetX509Cert $gen $cert 1
CkXmlDSigGen_put_KeyInfoType $gen "X509Data"
CkXmlDSigGen_put_X509Type $gen "Certificate"
CkXmlDSigGen_put_Behaviors $gen "EnvelopedTransformFirst"
# Load XML to be signed...
set sbXml [new_CkStringBuilder]
CkXml_put_EmitCompact $xml 1
CkXml_GetXmlSb $xml $sbXml
# Sign the XML...
set success [CkXmlDSigGen_CreateXmlDSigSb $gen $sbXml]
if {$success != 1} then {
puts [CkXmlDSigGen_lastErrorText $gen]
delete_CkXml $xml
delete_CkXmlDSigGen $gen
delete_CkCert $cert
delete_CkStringBuilder $sbXml
exit
}
# -----------------------------------------------
# Save the signed XML to a file.
set success [CkStringBuilder_WriteFile $sbXml "qa_output/signedXml.xml" "utf-8" 1]
puts [CkStringBuilder_getAsString $sbXml]
# ----------------------------------------
# Verify the signatures we just produced...
set verifier [new_CkXmlDSig]
set success [CkXmlDSig_LoadSignatureSb $verifier $sbXml]
if {$success != 1} then {
puts [CkXmlDSig_lastErrorText $verifier]
delete_CkXml $xml
delete_CkXmlDSigGen $gen
delete_CkCert $cert
delete_CkStringBuilder $sbXml
delete_CkXmlDSig $verifier
exit
}
set numSigs [CkXmlDSig_get_NumSignatures $verifier]
set verifyIdx 0
while {$verifyIdx < $numSigs} {
CkXmlDSig_put_Selector $verifier $verifyIdx
set verified [CkXmlDSig_VerifySignature $verifier 1]
if {$verified != 1} then {
puts [CkXmlDSig_lastErrorText $verifier]
delete_CkXml $xml
delete_CkXmlDSigGen $gen
delete_CkCert $cert
delete_CkStringBuilder $sbXml
delete_CkXmlDSig $verifier
exit
}
set verifyIdx [expr $verifyIdx + 1]
}
puts "All signatures were successfully verified."
delete_CkXml $xml
delete_CkXmlDSigGen $gen
delete_CkCert $cert
delete_CkStringBuilder $sbXml
delete_CkXmlDSig $verifier