diff --git a/experimental/facho-signer/src/Makefile.am b/experimental/facho-signer/src/Makefile.am
index 42357a3..ed4429b 100644
--- a/experimental/facho-signer/src/Makefile.am
+++ b/experimental/facho-signer/src/Makefile.am
@@ -1,4 +1,4 @@
 bin_PROGRAMS = facho_signer
-facho_signer_SOURCES = xades/xmlsec1/xmltree.c xades/xmlsec1/errors.c xades/templates.c xades/xades.c facho_signer.c
+facho_signer_SOURCES = xades/xmlsec1/xmltree.c xades/xmlsec1/errors.c xades/templates.c xades/xades.c facho_signer.c main.c
 facho_signer_CFLAGS = $(OPENSSL_CFLAGS) $(XMLSEC1_CFLAGS) -DXMLSEC_NOT_CRYPTO_DYNAMIC_LOADING
 facho_signer_LDADD = $(OPENSSL_LIBS) $(LIBLTDL) $(XMLSEC1_LIBS)
diff --git a/experimental/facho-signer/src/facho_signer.c b/experimental/facho-signer/src/facho_signer.c
index ce063bd..9693dd0 100644
--- a/experimental/facho-signer/src/facho_signer.c
+++ b/experimental/facho-signer/src/facho_signer.c
@@ -10,27 +10,24 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-
-#define print_error(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__)
-#define print_info(fmt, ...) fprintf(stdout, fmt, ##__VA_ARGS__)
+#define xmlFachoPrintError(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__)
+#define xmlFachoPrintInfo(fmt, ...) fprintf(stdout, fmt, ##__VA_ARGS__)
 
 const xmlChar ublExtensionDSigNs[] = "urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2";
 const xmlChar policyIdDescription[] = "Política de firma para facturas electrónicas de la República de Colombia.";
 const xmlChar policyIdIdentifier[] = "https://facturaelectronica.dian.gov.co/politicadefirma/v2/politicadefirmav2.pdf";
   
-char *basename = NULL;
-
 // crea elemento /Invoice/ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent
-xmlNodePtr
+static xmlNodePtr
 xmlFachoTmplUBLExtensionAddExtensionContent(xmlDocPtr doc);
 
 // FeC requiere que el digest value del policy identifier sea
 // apartir del contenido de la url.
-int
+static int
 xmlFachoPolicyIdentifierCtxFromFilename(const xmlChar *, xmlSecBufferPtr);
 
 
-int
+static int
 xmlFachoTmplXadesCreate(xmlDocPtr doc, xmlNodePtr signNode) {
   xmlNodePtr qualifyingPropertiesNode = NULL;
   xmlNodePtr signedPropertiesNode = NULL;
@@ -47,13 +44,13 @@ xmlFachoTmplXadesCreate(xmlDocPtr doc, xmlNodePtr signNode) {
   
   qualifyingPropertiesNode = xmlXadesTmplQualifyingPropertiesCreate(doc, signNode, BAD_CAST "xades-ref1");
   if (  qualifyingPropertiesNode == NULL ) {
-    print_error("error: failed to add QualifyingProperties node.\n");
+    xmlFachoPrintError("error: failed to add QualifyingProperties node.\n");
     goto fail;
   }
 
   signedPropertiesNode = xmlXadesTmplAddSignedProperties(qualifyingPropertiesNode, signedPropertiesId);
   if ( signedPropertiesNode == NULL ) {
-    print_error("error: xades failed to add signed properties node.\n");
+    xmlFachoPrintError("error: xades failed to add signed properties node.\n");
     goto fail;
   }
 
@@ -63,54 +60,54 @@ xmlFachoTmplXadesCreate(xmlDocPtr doc, xmlNodePtr signNode) {
                                             signedPropertiesRef,
                                             BAD_CAST "http://uri.etsi.org/01903#SignedProperties");
   if ( refNode == NULL ) {
-    print_error("error: failed to add reference to signature template xades.\n");
+    xmlFachoPrintError("error: failed to add reference to signature template xades.\n");
     goto fail;
   }
   if ( xmlSecTmplReferenceAddTransform(refNode, xmlSecTransformInclC14NId) == NULL ) {
-    print_error("error: failed to add enveloped transform to reference for xades\n");
+    xmlFachoPrintError("error: failed to add enveloped transform to reference for xades\n");
     goto fail;
   }
 
   const time_t now = time(NULL);
   signedSignaturePropertiesNode = xmlXadesTmplAddSignedSignatureProperties(signedPropertiesNode, localtime(&now));
   if ( signedSignaturePropertiesNode == NULL ) {
-    print_error("error: xades failed to add signed signature properties node.\n");
+    xmlFachoPrintError("error: xades failed to add signed signature properties node.\n");
     goto fail;
   }
 
   signingCertificateNode = xmlXadesTmplAddSigningCertificate(signedSignaturePropertiesNode, xmlSecTransformSha256Id);
   if ( signingCertificateNode == NULL ) {
-    print_error("error: failed to add SigningCertificate node \n");
+    xmlFachoPrintError("error: failed to add SigningCertificate node \n");
     goto fail;
   }
 
   signaturePolicyIdentifierNode = xmlXadesTmplAddSignaturePolicyIdentifier(signedSignaturePropertiesNode);
   if ( signaturePolicyIdentifierNode == NULL ) {
-    print_error("error: failed to add PolicyIdentifier node\n");
+    xmlFachoPrintError("error: failed to add PolicyIdentifier node\n");
     goto fail;
   }
 
   signaturePolicyIdNode = xmlXadesTmplAddSignaturePolicyId(signaturePolicyIdentifierNode);
   if ( signaturePolicyIdNode == NULL ) {
-    print_error("error: failed to add SignaturePolicyId node.\n");
+    xmlFachoPrintError("error: failed to add SignaturePolicyId node.\n");
     goto fail;
   }
 
   sigPolicyIdNode = xmlXadesTmplAddSigPolicyId(signaturePolicyIdNode, policyIdIdentifier, policyIdDescription);
   if ( sigPolicyIdNode == NULL ) {
-    print_error("error: failed to add SigPolicyId node.\n");
+    xmlFachoPrintError("error: failed to add SigPolicyId node.\n");
     goto fail;
   }
 
   sigPolicyHashNode = xmlXadesTmplAddSigPolicyHash(signaturePolicyIdNode, xmlSecTransformSha256Id);
   if ( sigPolicyHashNode == NULL ) {
-    print_error("error: failed to add SigPolicyHash node.\n");
+    xmlFachoPrintError("error: failed to add SigPolicyHash node.\n");
     goto fail;
   }
 
   signerRoleNode = xmlXadesTmplAddSignerRole(signedSignaturePropertiesNode, BAD_CAST "supplier");
   if ( signerRoleNode == NULL ) {
-    print_error("error: failed to add SignerRole node.\n");
+    xmlFachoPrintError("error: failed to add SignerRole node.\n");
     goto fail;
   }
 
@@ -122,18 +119,18 @@ xmlFachoTmplXadesCreate(xmlDocPtr doc, xmlNodePtr signNode) {
   return(-1);
 }
 
-static int
-xmlXadesAppInit() {
+int
+xmlFachoInit() {
   xmlInitParser();
   LIBXML_TEST_VERSION;
   
   if ( xmlSecInit() < 0 ) {
-    print_error("xmlsec initialization failed.\n");
+    xmlFachoPrintError("xmlsec initialization failed.\n");
     return(-1);
   }
 
   if ( xmlSecCheckVersion() != 1 ) {
-    print_error("loaded xmlsec library version is not compatible.\n");
+    xmlFachoPrintError("loaded xmlsec library version is not compatible.\n");
     return(-1);
   }
 
@@ -147,61 +144,39 @@ xmlXadesAppInit() {
 #endif /* XMLSEC_CRYPTO_DYNAMIC_LOADING */
    
   if ( xmlSecCryptoAppInit(NULL) < 0 ) {
-    print_error("crypto initialization failed.\n");
+    xmlFachoPrintError("crypto initialization failed.\n");
     return(-1);
   }
 
   if ( xmlSecCryptoInit() < 0 ) {
-    print_error("xmlsec-crypto initialization failed.\n");
+    xmlFachoPrintError("xmlsec-crypto initialization failed.\n");
     return(-1);
   }
 
   return(0);
 }
 
-static int
-xmlXadesAppShutdown() {
+int
+xmlFachoShutdown() {
 
   if ( xmlSecCryptoShutdown() < 0 ) {
-    print_error("xmlSecCryptoShutdown failed.\n");
+    xmlFachoPrintError("xmlSecCryptoShutdown failed.\n");
   }
 
   if ( xmlSecCryptoAppShutdown() < 0 ) {
-    print_error("xmlSecCryptoAppShutdown failed.\n");
+    xmlFachoPrintError("xmlSecCryptoAppShutdown failed.\n");
   }
   
   if ( xmlSecShutdown() < 0 ) {
-    print_error("xmlsec shutdown failed.\n");
+    xmlFachoPrintError("xmlsec shutdown failed.\n");
   }
 
   xmlCleanupParser();
   return(0);
 }
 
-/*    
-    X509 *cert = xmlSecOpenSSLKeyDataX509GetCert(keyData, 0);
-    if (cert == NULL) {
-      print_error("xmlSecOpenSSLKeyDataX509GetKeyCert fail\n");
-    }
-
-    char *issuer = X509_NAME_oneline(X509_get_issuer_name(cert), NULL, 0);
-
-    printf("x509 issuer: %s\n", issuer);
-
-    //https://stackoverflow.com/questions/9749560/how-to-calculate-x-509-certificates-sha-1-fingerprint-in-c-c-objective-c
-    unsigned char md[EVP_MAX_MD_SIZE];
-    unsigned int n;
-    const EVP_MD *digest = EVP_get_digestbyname("sha256");
-    X509_digest(cert, digest, md, &n);
-    printf("%s", "Fingerprint:");
-    for(int pos = 0; pos < 19 ; pos++) {
-      printf("%02x:", md[pos]);
-    }
-    printf("%02x\n", md[19]);
-*/
-
-static int
-xmlXadesSignFile(const char *filename, const char *pkcs12name, const char *password) {
+int
+xmlFachoSignFile(FILE *out, const char *filename, const char *pkcs12name, const char *password) {
   xmlDocPtr doc = NULL;
   xmlNodePtr signNode = NULL;
   xmlNodePtr refNode = NULL;
@@ -219,14 +194,14 @@ xmlXadesSignFile(const char *filename, const char *pkcs12name, const char *passw
 
   doc = xmlParseFile(filename);
   if ( (doc == NULL) || (xmlDocGetRootElement(doc) == NULL) ) {
-    print_error("error: unable to parse file %s\n", filename);
+    xmlFachoPrintError("error: unable to parse file %s\n", filename);
     goto done;
   }
 
   signNode = xmlSecTmplSignatureCreate(doc, xmlSecTransformInclC14NId,
                                        xmlSecTransformRsaSha256Id, NULL);
   if ( signNode == NULL ) {
-    print_error("error: failed to create signature template.\n");
+    xmlFachoPrintError("error: failed to create signature template.\n");
     goto done;
   }
 
@@ -238,11 +213,11 @@ xmlXadesSignFile(const char *filename, const char *pkcs12name, const char *passw
                                             BAD_CAST "", //uri
                                             NULL); //type
   if ( refNode == NULL ) {
-    print_error("error: failed to add reference to signature template.\n");
+    xmlFachoPrintError("error: failed to add reference to signature template.\n");
     goto done;
   }
   if ( xmlSecTmplReferenceAddTransform(refNode, xmlSecTransformEnvelopedId) == NULL ) {
-    print_error("error: failed to add enveloped transform to reference\n");
+    xmlFachoPrintError("error: failed to add enveloped transform to reference\n");
     goto done;
   }
 
@@ -252,72 +227,79 @@ xmlXadesSignFile(const char *filename, const char *pkcs12name, const char *passw
                                             BAD_CAST "#xmldsig-facho-KeyInfo",
                                             NULL);
   if ( refNode == NULL ) {
-    print_error("error: failed to add reference to signature template key-info.\n");
+    xmlFachoPrintError("error: failed to add reference to signature template key-info.\n");
     goto done;
   }
 
   keyInfoNode = xmlSecTmplSignatureEnsureKeyInfo(signNode, BAD_CAST "xmldsig-facho-KeyInfo");
   if ( keyInfoNode == NULL ) {
-    print_error("error: failed to add key info.\n");
+    xmlFachoPrintError("error: failed to add key info.\n");
     goto done;
   }
 
   x509DataNode = xmlSecTmplKeyInfoAddX509Data(keyInfoNode);
   if ( x509DataNode == NULL ) {
-    print_error("error: failde to add x509 DATA \n");
+    xmlFachoPrintError("error: failde to add x509 DATA \n");
     goto done;
   }
 
   if ( xmlSecTmplX509DataAddCertificate(x509DataNode) == NULL ) {
-    print_error("error: failde to add x509Certificate node\n");
+    xmlFachoPrintError("error: failde to add x509Certificate node\n");
     goto done;
   }
 
 
   if ( xmlFachoTmplXadesCreate(doc, signNode) < 0 ){
-    print_error("error: xmlFachoTmplXadesCreate failed.\n");
+    xmlFachoPrintError("error: xmlFachoTmplXadesCreate failed.\n");
     goto done;
   }
 
   dsigCtx = xmlSecDSigCtxCreate(NULL);
   if ( dsigCtx == NULL ) {
-    print_error("error: dsig context creating failed\n");
+    xmlFachoPrintError("error: dsig context creating failed\n");
     return(-1);
   }
-  
+
+  // cargamos el archivo pkcs12 con llave privado y certificados x509
   dsigCtx->signKey = xmlSecCryptoAppKeyLoad(pkcs12name,
                                             xmlSecKeyDataFormatPkcs12,
                                             password,
                                             NULL, NULL);
   if ( dsigCtx->signKey == NULL ) {
-    print_error("error: failed to load pkcs12\n");
+    xmlFachoPrintError("error: failed to load pkcs12\n");
     goto done;
   }
 
   xmlXadesPolicyIdentifierCtx policyIdCtx;
 
+  // por ahora el hash del identificador lo tomamos del pdf de la dian
   policyIdCtx.contentCallback = &xmlFachoPolicyIdentifierCtxFromFilename;
     
   xadesDsigCtx = xmlXadesDSigCtxCreate(dsigCtx, XADES_DIGEST_SHA256, &policyIdCtx);
   if ( xadesDsigCtx == NULL ) {
-    print_error("error: xades context creating failed.\n");
+    xmlFachoPrintError("error: xades context creating failed.\n");
     return(-1);
   }
 
-  if ( xmlXadesDSigCtxSign(xadesDsigCtx, signNode) < 0 ) {
-    print_error("error: signature failed\n");
+  // debe existir el elemento antes del firmado
+  node = xmlFachoTmplUBLExtensionAddExtensionContent(doc);
+  if ( node == NULL ) {
+    xmlFachoPrintError("error: failed to add UBLExtensions/UBLExtension/ExtensionContent\n");
     goto done;
   }
 
-  node = xmlFachoTmplUBLExtensionAddExtensionContent(doc);
-  if ( node == NULL ) {
-    print_error("error: failed to add UBLExtensions/UBLExtension/ExtensionContent\n");
+
+  // realizar firma de documento
+  if ( xmlXadesDSigCtxSign(xadesDsigCtx, signNode) < 0 ) {
+    xmlFachoPrintError("error: signature failed\n");
     goto done;
   }
+
+
   xmlUnlinkNode(signNode);
   xmlSecAddChildNode(node, signNode);
 
-  xmlDocDump(stdout, doc);
+  xmlDocDump(out, doc);
 
   res = 0;
 
@@ -336,32 +318,7 @@ xmlXadesSignFile(const char *filename, const char *pkcs12name, const char *passw
   return(res);
 }
 
-int main(int argc, char *argv[]) {
-  basename = argv[0];
-  int exitStatus = EXIT_SUCCESS;
-  
-  if (argc != 4) {
-    print_error("%s: <factura.xml> <pc12> <password>\n", basename);
-    return(EXIT_FAILURE);
-  }
-
-  if ( xmlXadesAppInit() < 0 ) {
-    print_error("initialization failed.\n");
-    return(EXIT_FAILURE);
-  }
-
-  if ( xmlXadesSignFile( argv[1], argv[2], argv[3] ) != 0 ) {
-    print_error("%s", "fail to sign file\n");
-    exitStatus = EXIT_FAILURE;
-  }
-
-  xmlXadesAppShutdown();  
-  return(exitStatus);
-}
-
-
-
-xmlNodePtr
+static xmlNodePtr
 xmlFachoTmplUBLExtensionAddExtensionContent(xmlDocPtr doc) {
   xmlNodePtr node = NULL;
   xmlNodePtr parent = NULL;
@@ -373,28 +330,30 @@ xmlFachoTmplUBLExtensionAddExtensionContent(xmlDocPtr doc) {
   if ( parent == NULL ) {
     parent = xmlSecAddChild(xmlDocGetRootElement(doc), ublExtensionsName,  ublExtensionDSigNs);
     if ( parent == NULL ) {
-      print_error("error: failed to cleate UBLExtensions.\n");
+      xmlFachoPrintError("error: failed to cleate UBLExtensions.\n");
       return(NULL);
     }
   }
 
+  // adicionamos nuevo elemento UBLExtension
   node = xmlSecAddChild(parent, ublExtensionName, ublExtensionDSigNs);
   if ( node == NULL ) {
-    print_error("error: failed to add UBLExtension\n");
+    xmlFachoPrintError("error: failed to add UBLExtension\n");
     xmlFreeNode(parent);
     return(NULL);
   }
 
+  // adicionamos nuevo elemento ExtensionContent
   node = xmlSecAddChild(node, extensionContentName, ublExtensionDSigNs);
   if ( node == NULL ) {
-    print_error("error: failed to add ExtensionContent");
+    xmlFachoPrintError("error: failed to add ExtensionContent");
     return(NULL);
   }
 
   return(node);
 }
 
-int
+static int
 xmlFachoPolicyIdentifierCtxFromFilename(const xmlChar *policyId, xmlSecBufferPtr buffer) {
   static unsigned char politicafirmav2[] = {
     /**
diff --git a/experimental/facho-signer/src/facho_signer.h b/experimental/facho-signer/src/facho_signer.h
new file mode 100644
index 0000000..81858da
--- /dev/null
+++ b/experimental/facho-signer/src/facho_signer.h
@@ -0,0 +1,15 @@
+#ifndef FACHO_SIGNER_H
+#define FACHO_SIGNER_H
+
+#include <stdio.h>
+
+int
+xmlFachoInit();
+
+int
+xmlFachoShutdown();
+
+int
+xmlFachoSignFile(FILE *out, const char *filename, const char *pkcs12name, const char *password);
+
+#endif /* FACHO_SIGNER_H */
diff --git a/experimental/facho-signer/src/main.c b/experimental/facho-signer/src/main.c
new file mode 100644
index 0000000..30d2fa9
--- /dev/null
+++ b/experimental/facho-signer/src/main.c
@@ -0,0 +1,32 @@
+#include "xades/xades.h"
+#include "facho_signer.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+
+static char *basename = NULL;
+
+int main(int argc, char *argv[]) {
+  int exitStatus = EXIT_SUCCESS;
+
+  basename = argv[0];
+  
+  if (argc != 4) {
+    fprintf(stderr, "%s: <factura.xml> <pc12> <password>\n", basename);
+    return(EXIT_FAILURE);
+  }
+
+  if ( xmlFachoInit() < 0 ) {
+    fprintf(stderr, "initialization failed.\n");
+    return(EXIT_FAILURE);
+  }
+
+  if ( xmlFachoSignFile( stdout, argv[1], argv[2], argv[3] ) != 0 ) {
+    fprintf(stderr, "fail to sign file\n");
+    exitStatus = EXIT_FAILURE;
+  }
+
+  xmlFachoShutdown();  
+  return(exitStatus);
+}