# Introducción

El API de Acertia le permite a tus usuarios hacer todo lo que pueden hacer en [acertia.mx](https://acertia.mx) pero con el flujo controlado por ti.&#x20;

La implementación general funcionaría de la siguiente manera:

1. Tu servidor envía el documento a Acertia. Ya sea enviándolo directamente o utilizando un template
2. Acertia responde con la URL del documento listo para ser firmado.
3. Presentas la URL del documento a tu usuario. Puede ser que se la envíes por algún medio o que la abra dando click a algún botón dentro de tu sistema.
4. Tu usuario firma el documento dentro del portal de Acertia y es redirigido a la URL que proporciones.
5. Acertia te avisa que el documento ha sido firmado por medio de un webhook.


# Autenticación

Para comenzar a usar el API por favor contacta a <developers@acertia.com> y te asignaremos un WebId y un API Key.

El WebId es público y lo puedes guardar en cualquier lugar, pero el API Key equivale a tu contraseña y le puede permitir a terceros solicitar documentos a tus usuarios. Guárdalo en un lugar seguro.

Credenciales de ejemplo:

```
WebId: mBS73C5TdTjthjF0
API Key: 521026f468b9dadc2419e476356934d0
```


# SDK y Uso del API directamente

### SDK

El SDK esconde la implementación de las solicitudes y la autenticación, haciendo que te sea más fácil usar nuestros servicios. Actualmente está disponible en: Java, PHP, .NET2, .NET4, Python y Node

Los ejemplos de este documento están en Node pero son muy parecidos para los demás lenguajes, te proporcionaremos varios ejemplos para que puedas comenzar a probar rápidamente.

```javascript
//esto es sólo para pruebas
//te recomendamos que cargues tus credenciales
//desde un archivo externo o desde el ambiente
//de producción
const webId = "mBS73C5TdTjthjF0"
const apiKey = "521026f468b9dadc2419e476356934d0"

const AcertiaServices = AcertiaServices(webId, apiKey);
```

Si el SDK no está implementado en el lenguaje de programación que utilizas, puedes llamar al API directamente (ve "Usando el API directamente"), o contáctanos en <developers@acertia.com> para más información.

### Uso del API directamente

Si el SDK no está implementado en el lenguaje de programación que utilizas, puedes mandar llamar al API directamente. El API es un grupo de endpoints que aceptan solicitudes JSON que contienen un encabezado de autenticación. Abajo se encuentra una descripción básica de como trabaja, pero nos puedes contactar en <developers@acertia.com> para cualquier duda que tengas

#### Encabezado de autenticación

Cada solicitud al API debe tener un `Content-Type:application/json` y un encabezado de autenticación que nos permite verificar que eres un usuario autorizado y que la solicitud no ha sido cambiada por un tercero. El encabezado está formado de la siguiente manera:

1. **Identificador**: el encabezado tiene que iniciar con "Authorization: signmage".
2. **WebId**: el WebId que te fue asignado como desarrollador.
3. **Separador**: entre el WebId y el HMAC tiene que haber un símbolo ":".
4. **HMAC**: un SHA-256 HMAC en base64 generado con los parámetros JSON de la solicitud y el API Key como el secreto. El JSON debe ser válido y sin espacios.

#### API endpoints

1. <https://acertia.mx/developers/button>: Para todas las solicitudes que resulten en un documento para ser firmado.
2. <https://acertia.mx/developers/template/save>: Para guardar un template y poder utilizarlo después para generar un documento.
3. <https://acertia.mx/developers/webhook>: Para solicitar más información al momento de recibir una notificación a un webhook.
4. <https://acertia.mx/developers/docs>: Para acciones que apliquen sobre un documento en específico.


# Solicitudes

## Haciendo una solicitud

1. Prepárate para llamar al API. Revisa "Usando el SDK" or "Usando el API directamente".
2. Construye el JSON de la solicitud con las opciones que requieras. Para las solicitudes de PDF, es obligatorio que incluyan un documento, pero también pueden incluir cualquiera de las demás opciones:
   1. PDF
   2. Alta de documento
   3. Stickers
   4. Flujos
   5. Código QR
   6. Estampilla de tiempo
3. Procesa la respuesta y recibe notificaciones:
   1. Descripción de la respuesta de solicitud de un documento
   2. Descargar documento
   3. Información del documento
   4. Eliminar documento
   5. Restaurar documento&#x20;
   6. Webhooks
4. Expedientes de documentos.


# Altas

## Alta de documento

El uso más simple es simplemente enviar el documento a Acertia sin especificar firmantes ni ninguna otra opción. A esta opción se le van agregando las demás como código QR, stickers, flujo, etc.

Para subir el documento puedes:

### Enviar la URL directamente

Si tu documento puede ser accedido públicamente a través de una URL, puedes simplemente mandarnos esa URL

```javascript
// puedes mandar el nombre junto con la url
const response = await services.request({
    url_doc : {
        url: 'https://www.dropbox.com/s/sxvgq1uhb4k3s4w/contrato.pdf?dl=0',
        name: 'contrato.pdf'
    },        
})

// o en este caso el nombre del documento se extraerá del parámetro "filename"
// del header "Content-Disposition". De no encontrarse, el documento 
// se guardará con el nombre de "default.pdf"
const response = await services.request({
    url_doc : 'https://www.dropbox.com/s/sxvgq1uhb4k3s4w/contrato.pdf?dl=0'        
})
```

### Enviar el documento en base64

Si tu documento no es accesible por una URL, puedes mandarlo a Acertia codificado en base64

```javascript
const response = await services.request({
    b64_doc: {
        // documento codificado en base64
        data: 'documento codificado en base64',
        // nombre con el que se guardará el documento
        name: 'ejemplo.pdf'
    }
})
```

### Utilizar un template

Si estarás usando el mismo documento sólo cambiando unos datos. Puedes darlo de alta como un template HTML y sólo estar mandando los datos que quieres que inyectemos. Nosotros inyectamos los datos y generamos el documento PDF.

Para dar de alta el template, el primer paso es definir el HTML con su CSS inline.

El HTML puede contener **campos** y **tablas** dinámicos para inyectar los datos mas adelante.

Un **campo** puede ser cualquier elemento HTML que contenga texto. Para declarar un campo en tu página HTML agrega la clase *"signmage-template-field"* y un id único al elemento:

```markup
<p style="text-align:justify;">
    <span class="signmage-template-field" id="full-name"></span>
    is the owner of this document.
</p>
```

Cuando generes el documento, el valor que especifiques será insertado en el campo:

```markup
<p style="text-align:justify;">
    <span class="signmage-template-field" id="full-name">John Doe</span>
    is the owner of this document.
</p>
```

Las **tablas** son tablas HTML con la clase *"signmage-template-table"* y un id único:

```markup
<table 
    class="signmage-template-table" 
    id="directory" 
    style="border: 1px solid black;">

    <theader>
        <tr style="height: 31px;">
            <th>
                <strong>NAME</strong>
            </th>
            <th>
                <strong>PHONE</strong>
            </th>
            <th>
                <strong>ADDRESS</strong>
            </th>
        </tr>
    </theader>
    <tbody>

    </tbody>

</table>
```

De igual manera que con los campos, cuando el documento sea generado, los valores que especifiques serán insertados en su lugar correspondiente:

```markup
<table 
    class="signmage-template-table" 
    id="directory" 
    style="border: 1px solid black; width:100%;">

    <theader>
        <tr style="height: 31px;">
            <th>
                <strong>NAME</strong>
            </th>
            <th>
                <strong>PHONE</strong>
            </th>
            <th>
                <strong>ADDRESS</strong>
            </th>
        </tr>
    </theader>
    <tbody>
        <tr>
            <td>
                <p>John Doe</p>
            </td>
            <td>
                <p>843 James Lane 
                    Lake Mary, FL 32746</p>
            </td>
            <td>
                <p>202-555-0141</p>
            </td>
        </tr>
                <tr>
            <td>
                <p>Amy Rose</p>
            </td>
            <td>
                <p>7189 East Acacia St. 
                    Dundalk, MD 21222</p>
            </td>
            <td>
                <p>202-555-0141</p>
            </td>
        </tr>
    </tbody>

</table>
```

Una vez que ya tienes el template definido en HTML, el siguiente paso es darlo de alta en Acertia:

```javascript
const templateData = 'html del documento';

const response = await services.saveTemplate({
        template_type:'html',
                    // el template tiene que mandarse codificado en base64
        template_data: Buffer.from(templateData).toString('base64'),
                 // nombre con el que se guardará el template
        template_name: 'ejemplo1'
    })
```

\
&#x20;Acertia contestará con los campos dinámicos que encontró en tu template: <br>

```javascript
{
  tables: [ { id: 'directory', rows: [] } ],
  template_title: 'ejemplo1',
  fields: [
    { id: 'full-name', value: '' }
  ]
}
```

\
&#x20;Y de ahí en adelante, cada vez que quieras utilizarlo, sólo es necesario que mandes los datos correspondientes: <br>

```javascript
const response = await services.request({
        template_title: 'ejemplo1',
        fields: [
            {"id":"full-name","value":"John Doe"}
        ],
        tables: [{
            id: 'directory',
            rows: [
                ['John Doe', 
                                    '843 James Lane Lake Mary, FL 32746', 
                                    '202-555-0141'],
            ]
        }]
    })
```

### Stickers

Los stickers te permiten especificar quién puede firmar el documento y dónde puede hacerlo. Sólo los usuarios que se especifiquen en los stickers podrán firmar el documento, y sólo pueden firmar en la posición del sticker que hayas definido.

Hay tres maneras diferentes de colocar un sticker:

1. A través del API:

   ```javascript
    const response = await services.request({
        //La URL, base64 o template de tu documento
        url_doc: 'https://acertia.com/assets/files/signmage.pdf',
        //stickers es un arreglo de firmantes
        stickers: [
            {
                //el emisor del certificado que puede firmar 
                //este sticker
                //(el default es SAT)
                //las opciones son:
                //'SAT' para certificados del SAT
                //'Vinculada a Correo Electronico'
                //'Vinculada a SMS'
                //'Vincualda a Correo Electronico por Liga'
                authority: 'SAT',
                //el tipo de sticker
                //puede ser 'line': la firma se coloca en el sticker de 
                //manera relativa al fondo de la posición proporcionada
                //o 'rect': centra la firma en la posición dada
                stickerType: 'line',
                //tipo de dato
                //el tipo de dato con el cual se validará al firmante
                //actualmente, el sticker se puede validar a través
                //de: correo, teléfono o RFC
                //(email, phone, rfc)
                dataType: 'rfc',
                //el dato a utilizar para validar al firmante
                data: 'ARCX9012226P8',        
                //tipo de imagen
                //opcional
                //puedes especificar el tipo de imagen que el usuario 
                //usará para firmar este sticker
                //las opciones disponibles son:
                //'desc': una imagen con el texto: "Firma realizada con 
                //certificado emitido por [emisor] para: [nombre]"
                //'name': nombre del firmante tal como se encuentra en 
                //su certificado escrito con una fuente de 
                //escritura a mano
                //'hash': el base64 del sha256 del documento antes 
                //de ser firmado 
                //seguido por el nombre del firmante
                //'stroke': la firma dibujada dentro del app
                imageType: 'hash',
                //el correo del firmante
                //si quieres que Acertia maneje el flujo de firma,
                //este campo
                //es mandatorio
                email: 'jhon@gmail.com',
                //página donde se debe encontrar la firma (comenzando 
                //desde 0)
                page: 0,
                //posición de la firma dentro de la página
                //ESTAS SON COORDENADAS PDF. 
                //EL (0,0) ES LA ESQUINA INFERIOR IZQUIERDA
                rect: {
                    //x inferior izquierda
                    lx:388,
                    //y inferior izquierda
                    ly:400,
                    //x superior derecha
                    tx: 496,
                    //y superior derecha
                    ty: 480
                }
            }
        ]
    })
   ```
2. Colocando un recuadro de firma en tu PDF

   Cuando se recibe un PDF, Acertia analiza el documento en busca de áreas de firma. Un área de firma es cualquier rectángulo que dentro tenga la palabra "Acertia" seguida de un RFC o un correo electrónico. Acertia elimina estos rectángulos y coloca un sticker en su lugar de manera automática.

   Además del RFC o correo del firmante, también puedes especificar los otros parámetros del sticker. Por ejemplo:

   Acertia GOCF9002226A7

   Acertia GOCF9002226A7 <fernando@acertia.mx>

   Acertia GOCF9002226A7 <fernando@acertia.mx> centrada hash

   Todas se refieren a la firma amparada con certificado del SAT para GOCF9002226A7. El correo es opcional a menos que se desee usar el flujo de Acertia, en cuyo caso es obligatorio.

   Se puede incluir la palabra "Linea" o "Centrada", para alinear la firma a la línea inferior o para centrarla al sticker.

   También se pueden incluir las palabras: "Cualquiera", "Descriptiva", "Nombre", o "Hash", para definir la imagen que se asocia a la firma.

   Si se omite un parámetro se aplica el default establecido en su configuración.
3. Colocando un recuadro de firma en tu template HTML

   Puedes colocar un recuadro en tu template HTML en la posición donde quieres que aparezca la firma. Al momento de solicitar tu documento, inyectas en este recuadro los datos del sticker como se pueden ver en el punto anterior (Colocando un recuadro de firma en tu PDF). Por ejemplo:

Defines el recuadro como parte del template en HTML:

```markup
<div 
    style="
    border:1px solid black; 
    float:right; 
    width:200px; 
    height:120px; 
    margin:auto; 
    color:white; 
    word-break:break-all; 
    font-size:2px;
">
        <span class="signmage-template-field" id="signer1"></span>
    </div>
```

Y al momento de utilizarlo inyectas en ese campo los valores del sticker:

```javascript
const response = await services.request({
        template_title: 'ejemploSticker',
        fields: [
            {"id":"signer1","value":"Acertia GOCF9002226A7 dibujo"},
        ],
        tables: []
    })
```

&#x20;  4\. Líneas de firma

Si estás generando tu PDF a través de Microsoft Word, puedes colocar una línea horizontal con un ALT text siguiendo las mismas reglas que se utilizan para colocar recuadros de firma. Acertia detectará esta línea y colocará un sticker en su lugar.

### Flujos

Un flujo de firmas toma un documento con stickers, lo manda a todos los firmantes y te notifica cuando todos lo han firmado.

```javascript
const response = services.await({
    //URL, base64 o template de tu documento
    url_doc: 'https://acertia.mx/assets/files/signmage.pdf',
    //para iniciar un flujo de firmas el documento debe contener al
    //menos un sticker
    stickers: [
        {
            email: 'jhon@gmail.com',
            dataType: 'rfc',
            data: 'ARCX9012226P8',
            stickerType: 'line',
            page: 0,
            rect: {
                lx:388,
                ly:400,
                tx: 496,
                ty: 480
            }
        }
    ],
    //flujo de firma
    workflow: {
        //opcional
        //especifica la fecha de expiración del flujo de firma. El
        //flujo será cancelado si no se ha completado antes de esta
        //fecha. Por default se fijan 3 meses desde la fecha en la 
        //que el flujo fue creado
        //formato de la fecha: dd/MM/yyyy
        expiration_date: '12/11/2016',
        //opcional
        //define que tan seguido debe recordar a los firmantes que
        //firmen este documento
        //los valores permitidos son:
        //12h, 1d, 2d, 3d, 4d, 5d, 6d or 7d
        remind_every: '1d',
        //opcional
        //lenguaje en el que los firmantes recibiarán la invitación
        //en sus correos
        //por default es 'es'
        //los valores permitidos son: 'es' (Español), 'en' (Inglés)
        language: 'es',
        //opcional
        //si se encuentra presente, define el orden en el que las firmas
        //serán solicitadas
        //DEBE SER DEL MISMO TAMAÑO QUE EL NÚMERO DE STICKERS EN EL DOCUMENTO
        ordered: [
            {
                //dato del firmante (debe corresponder a un sticker)
                data: 'ARCX9012226P8'
            }
        ]
    }
})
```

### Código QR

Puedes agregar un código QR al documento que apunta a la versión firmada del mismo en nuestros servidores. De tal manera que si alguien recibe el documento por cualquier medio, incluso impreso, podrá validarlo usando la liga incrustada en el código QR.

Para agregar un código QR manda en la solicitud la página y posición en donde quieres que aparezca:

```javascript
const response = await services.request({
        //URL, base64 o template de tu documento
        url_doc: 'https://acertia.mx/assets/files/signmage.pdf',
        //posición del código QR
        //esto agregará un código QR en la esquina
        //inferior izquierda de la primera página
        qr: {
            width:    150,
            height: 150,
            x: 0,
            y: 0,
            page: 1
        }
    })
```

### Descripción de la respuesta de solicitud de un documento

Cada vez que subas un documento, Acertia contestará con la información básica del documento que se dio de alta. Por ejemplo:

```javascript
{
    // el ticket es el id del documento en Acertia. Te será
    // util cuando recibas notificaciones sobre las firmas del 
    // documento o para realizar acciones sobre el mismo
  document_ticket: '6c46b879-42e1-4b3e-a1c4-dcf959178821',
    // indica si se inicio o no un flujo de firmas para el documento
  document_flow: false,
    // indica la cantidad de stickers que se dieron de alta con el documento
  sticker_count: 1,
    // muestra los detalles de los stickers que se dieron de alta
  stickers: [
    {
      sticker_index: 0,
      sticker_email: null,
      sticker_data: 'GOCF9002226A711',
      sticker_page: 0,
      sticker_coordinates: [Object],
      sticker_type: 'RFC',
      sticker_image_type: 'desc',
      sticker_authorities: [Array]
    }
  ],
    // URL del documento listo para ser firmado
  document_url: 'https://acertia.mx/pdf/6c46b879-42e1-4b3e-a1c4-dcf959178821/?child=true&inv=true'
}
```

### Descargar documento

Una vez que ya diste de alta el documento, puedes descargarlo en cualquier momento utilizando su id e indicando si quieres descargar el documento "original" o el "universal".

```javascript
// response contendrá el base64 del documento correspondiente
const response = await services.getDocument(
    'original', 
    '04c0c65d-a06c-4f43-9a17-63b375b0106b')
```

### Información del documento

Puedes consultar en cualquier momento el estatus de un documento (además de las notificaciones que recibirás cuando se firme un documento).

```javascript
const response = await services.getReport(
    '5b31583e ac48-4bb3-8066-5a84c648bdad')
```

Esto devolverá como respuesta:

```javascript
{
  InkSignatures: [],
  firmas: [],
  certificationLevel: 0,
  metaData: {},
  ticket: '5b31583e-ac48-4bb3-8066-5a84c648bdad',
  fileDigest: '/zUDQrKJkdXhtjgP5TTZUhcjEEqe3U4pPa3Wjiut3Qk=',
  originalName: 'contrato',
  signable: true,
  haveForm: false,
  withQR: false,
  boxes: [
    {
      fromDocumentBox: false,
      lx: 355,
      ly: 102,
      width: 200,
      line: true,
      height: 100,
      data: 'GOCF9002226A711',
      email: null,
      customData: null,
      simple: false,
      authority: [Object],
      page: 0,
      signed: false,
      imageType: 'desc',
      authorities: []
    }
  ],
  allSigned: false
}
```

### Eliminar documento

**Endpoint:** <https://acertia.mx/developers/docs>

Puedes eliminar documentos que **tu hayas subido y que no hayan sido firmados**. Para hacer esto, envía el id del documento (Acertia\_id) y la acción "delete":

```javascript
const response = await services.docs({
    ticket: '7481782e-391a-445d-995c-5e759290ad54',
    action: 'delete'
});
```

### Restaurar documento

**Endpoint:** <https://acertia.mx/developers/docs>

Puedes restaurar documentos que hayas eliminado. Para hacerlo, envía el id del documento (Acertia\_id) y la acción "restore":

```javascript
const response = await services.docs({
    ticket: '7481782e-391a-445d-995c-5e759290ad54',
    action: 'restore'
});
```


# Webhooks

## Webhooks

Puedes especificar un webhook para recibir notificaciones en tu servidor cuando un documento ha sido firmado, revisarlo, y continuar con tu proceso.

Para especificar un webhook, inicia sesión en tu cuenta de desarrollador en [https://acertia.mx/developers/login](https://app.gitbook.com/s/-M7jrLqXFJxQhfJYDw7G/acertia.mx/developers/login). La URL que proporciones debe aceptar solicitudes HTTP POST con un JSON Content Type (`application/json`).

Cada vez que se firme un documento que tu generaste, Acertia hará un POST a tu webhook con esta información:

```javascript
{
    //el id de la notificación, puedes usar este id para solicitar
    //más información sobre este documento
    notification_id: 32,
    //el título del documento que fue firmado
    document_title: 'terms_of_service.pdf',
    //un id único para el documento (tal como se encuentra en la url)
    //url: https://Acertia.com/pdf/94a9398d-e0b6-40cf-9334-5f7f24fb883s/
    Acertia_id: '94a9398d-e0b6-40cf-9334-5f7f24fb883s',
    //descripción del evento
    text: 'Document just signed',
    //tipo de notificación, existen tres tipos posibles:
    //1. original_signed: un usuario ha firmado este documento
    //2. universal_signed: la firma ha sido encapsulada
    //3. document_completed: se han firmado todos los stickers
    notification_type: 'original_signed',
    //el correo del firmante
    signer_email:'john@gmail.com',
    //fingerprint del certificado del firmante
    signer_fingerprint: 'ae5e5f0846658e05d6afr2fad84f10ba5fb71d328'
    // informacion adicional del firmante
    signer_data: {}
}
```

Si la cuenta de tu organización tiene activados los sellos NOM151 de manera automática, además de las anteriores recibirás otras dos notificaciones

```javascript
{
    //1. original_nom151_stamped: se ha realizado el sello nom151 
    //   sobre el documento original
    //2. universal_nom151_stamped: se ha realizado el sello nom151
    //   sobre el documento universal
    notification_type: 'original_nom151_stamped',
    meta: {
        hash: 'hash del documento con el que se generó el sello',
        tsa: 'nombre de la autoridad que firmó el sello',
        policy: 'policy id de la autoridad',
        genTime: 'fecha de generación del sello'
    }
}
```

### Confirmación de Webhook

Acertia espera recibir un código HTTP 200 como respuesta a la notificación. Si no lo recibe, asume que hay un problema y se comportará de la siguiente manera:

1. URL inválida: si el webhook es una URL inválida, no volverá a intentar
2. Si no se obtiene respuesta de una URL válida: Acertia volverá a intentar utilizando *exponential backoff*. Esto quiere decir que programará su ejecución de acuerdo a la siguiente fórmula:

**10 segundos + min((2 ^ intentos), 600) + Random(0-1)ms**

Por lo que el tiempo irá incrementando entre cada intento hasta llegar a un máximo de 600 segundos (10 minutos) y 30 intentos.

### Consultas

Con el `notification_id` puedes solicitar más detalles sobre un documento. La solicitud tiene que contener la siguiente información:

```javascript
{
    //el id de la notificación que recibiste
    notification_id: 32
    //la acción que quieres realizar
    //(ve más abajo para más información)
    action: 'download_document'
}
```

#### Acciones disponibles

Actualmente hay cuatro acciones disponibles

**1.download\_document**. Descarga un JSON con el documento con las firmas encapsuladas

```javascript
const response = await services.getData({
    notification_id: 5,
    action: 'download_document'
})
```

Esto regresará un JSON con la siguiente información:

```javascript
{
    //nombre del documento
    name: "default.pdf",
    //número actual de firmas en el documento
    signatures_count: 1,
    //PDF codificado en base64
    data:"base64data"
}
```

**2. download\_document\_bytes**. Descarga el documento con las firmas encapsuladas

**3. download\_original\_document**. Descarga un JSON con el documento con las firmas originales.&#x20;

**4. download\_original\_bytes**. Descarga el documento con las firmas originales.


# Expedientes

## Expedientes de documentos

Un expediente de documentos es un conjunto de documentos que se manejan en un sólo flujo. Se envía una sola invitación a cada persona involucrada y desde esa invitación puede ver y firmar los documentos que contenga el expediente.

El manejo del expediente se maneja en 3 pasos:

1. Crear el expediente
2. Agregar documentos al expediente
3. Cerrar expediente

### Crear un expediente

Esta función crea un expediente vacío. Recibe como parámetro un nombre para el expediente y responde con un identificador único.

```javascript
const {documentSet} = 
    await services.createDocumentSet('nombre para el expediente')
```

### Agregar documentos al expediente

Con el expediente creado, el siguiente paso es agregar documentos. Para agregar un documento puedes utilizar las mismas funciones que están disponibles para generar un documento normalmente: stickers, recuadros, qr, templates, etc. Pero agregando el identificador para el expediente.

**Notas importantes**

* La única opción que no se puede utilizar en esta función es la de flujo (workflow), ya que el flujo se manejará a nivel expediente
* Cada firmante debe contener un dato de contacto. Esto significa que para las firmas por SAT, es obligatorio agregar el campo de correo ("email")

Por ejemplo, aquí estamos agregando un documento con un sticker al expediente que acabamos de crear:

```javascript
const {documentSet} = 
    await services.createDocumentSet('nombre del expediente')
await services.request({        
    url_doc: {
        "url":"https://www.dropbox.com/s/sxvgq1uhb4k3s4w/test.pdf?dl=0",  
        "name":"contrato.pdf"
    },
    documentSet: documentSet,
    stickers: [{
        "authority": "SAT"
        "stickerType":"rect",
        "dataType":"RFC"
        "imageType":"stroke",
        "data":"GOCF9002225A711",
        "email": "fernando@acertia.mx",
        "page":0,
        "rect": {
            "lx":330,
            "ly":300,
            "tx":530,
            "ty": 400
        }
    }]
})
```

### Cerrar expediente

El último paso sería cerrar el expediente, un expediente cerrado ya no permite que se agreguen más documentos.

Para cerrar el expediente, es necesario que envíes el identificador del expediente y las opciones del flujo de firmas (workflow). Estas opciones son las mismas que se utilizan para crear un flujo de firmas de un documento (ver sección de Flujos), con la limitante de que **tiene** que ser un flujo ordenado.

```javascript
await services.closeDocumentSet({
        documentSet: documentSet,
        workflow: {
            remind_every: '1d',
            language: 'es',
            // los firmantes del expediente. Solo es necesario que 
            // se agreguen una sola vez aunque se les este 
            // solicitando mas de una firma
            ordered: [
                'GOCF9002225A711',
                'fernando@acertia.mx'
            ]
        }
    })
```

### Consultar expediente

Puedes consultar el estatus del expediente en cualquier momento para verificar los documentos y firmantes que han sido agregados.

```javascript
const documentSetData = await services.getDocumentSet(documentSet);
```

Ejemplo de respuesta:

```javascript
 {
   "uuid":"9v3d6a47-e4e8-48ef-b9b3-7af45c8207dn",
   "status":"CLOSED",
   "documents":[
      "4a3d6a47-e4e8-48ef-b9b3-7af45c8207de",
      "5d08eabe-ecd0-46ad-9dbd-5d54098aca70"
   ],
   "signers":[
      "GOCF9002226A511",
      "fernando@acertia.mx",
      ...
   ]
}
```


# NOM-151

## Sello de tiempo NOM-151

El sello de tiempo se puede solicitar de dos maneras:

1. Incrustado dentro de un PDF: si se van a sellar documentos PDF recomendamos utilizar esta manera. El sello queda incrustado dentro de la metadata del documento y después se agrega una firma para que no se pueda modificar. Sirve como una manera de cerrar el documento y no se tienen que mantener dos archivos.
2. Sello para cualquier tipo de archivo: La otra opción es generar el sello como un archivo independiente. Esto permite que se puedan generar sellos para cualquier tipo de archivo, como fotos, videos, docx, xlsx, etc.

Además de los métodos para obtener el sello de tiempo, están disponibles los métodos para validar el sello generado. La validación revisa que:

1. El hash del documento corresponda al hash que se encuentra en el sello
2. Que el status del sello sea válido
3. Que la firma del sello sea válida

### Estampilla incrustada dentro de un PDF

#### Generación

Para generar el sello e incrustarlo dentro de un PDF, solicitamos el binario del documento:

```javascript
    const file = fs.readFileSync('./ejemplo.pdf');
    const response = await services.nom151Stamp(file)
```

La respuesta contiene la siguiente información:

```javascript
{
    "status": "success" o "error",
    "document":"base64 del documento PDF",
    "timestampData":{
        "genTime":"fecha de generacion del sello",
        "hash":"hash que fue sellado",
        "status":"status contenido dentro de la respuesta de la TSA",
        "tsa":"nombre de la TSA que firmó el sello de tiempo"
    },
    "error":"si 'status' es 'error', contendra una descripción del error",
}
```

#### Validación

Después de obtener un documento sellado, se puede validar en cualquier momento. Este proceso extrae el sello del documento y lo valida, sólo acepta documentos con el sello de tiempo incrustado.

```javascript
    const stampedFile = fs.readFileSync('./stampedFile.pdf');
    const validationResult = await services.nom151Validate(stampedFile);
```

La respuesta contiene la siguiente información:

```javascript
{
    "status": "success" o "error",
    "document":"base64 del documento PDF",
    "timestamp":"el timestamp en base64 que se extrajo del documento PDF",
    "timestampData":{
        "genTime":"fecha de generacion del sello",
        "hash":"hash que fue sellado",
        "status":"status contenido dentro de la respuesta de la TSA",
        "tsa":"nombre de la TSA que firmó el sello de tiempo"
    },
    "error":"si 'status' es 'error', contendra una descripción del error",
}
```

### Sello para cualquier tipo de PDF

#### Generación

Para generar un sello para cualquier tipo de archivo, enviamos el hash 256 en hexadecimal del archivo:

```javascript
    // genera un hash256 de los datos para los que quieres
    // una estampilla de tiempo
    const hash = crypto.createHash('sha256')
      hash.update('datos a estampillar');

    // manda el hash como un string hexadecimal
     const response = await services.timestamp({
      hash: hash.digest('hex')
  })
```

La respuesta contiene la siguiente información:

```javascript
{
    "status": "success" o "error",
    "timestamp":"el timestamp en base64 generado para el archivo",
    "timestampData":{
        "genTime":"fecha de generacion del sello",
        "hash":"hash que fue sellado",
        "status":"status contenido dentro de la respuesta de la TSA",
        "tsa":"nombre de la TSA que firmó el sello de tiempo"
    },
    "error":"si 'status' es 'error', contendra una descripción del error",
}
```

### Validación

Después de obtener el sello, se puede validar en cualquier momento enviando el sello junto con el archivo original o el hash con el que se generó

```javascript
    const validationResultFile = await services.timestampValidate({
        file: binaryFile, 
        timestamp: binaryTimestamp
    })

    const validationResultFile = await services.timestampValidate({
        hash: 'hexHash',
        timestamp: binaryTimestamp
    })
```

La respuesta para cualquiera de las dos opciones contendrá la siguiente información:

```javascript
{
    "status": "success" o "error",
    "timestampData":{
        "genTime":"fecha de generacion del sello",
        "hash":"hash que fue sellado",
        "status":"status contenido dentro de la respuesta de la TSA",
        "tsa":"nombre de la TSA que firmó el sello de tiempo"
    },
    "error":"si 'status' es 'error', contendra una descripción del error",
}
```


# Contacto

Para más información, contáctanos en <developers@acertia.mx>


