Quick start

Siga o exemplo e crie um fluxo de assinatura pela API

Nessa sessão você irá aprender como fazer login na API, subir um documento, iniciar um fluxo de assinatura com dois usuários de exemplo e verificar se a pessoa realizou a assinatura ou se o fluxo foi cancelado.

Ambiente de produção e homologação

Todos o tutorial e exemplos nesta documentação faz referência ao ambiente de produção, mas no desenvolvimento da sua integração é importante que use o ambiente de homologação. São os links:

  • API de homologação: https://api-hom.assine.online

  • Frontend de homologação: https://hom.assine.online

  • API de produção: https://api.assine.online

  • Frontend de produção: https://app.assine.online

Adquirindo um token de acesso

Para obtermos acesso aos endpoints da API, precisamos adquirir um token de acesso para autorizar as demais requisições. Utilizamos o método de password do OAuth2 para adquirir este token.

Antes de tudo, garanta que tenha uma conta criada em nosso ambiente de sandbox, caso não tenha, faça o cadastro pela url: https://hom.assine.online/register. O domínio do ambiente sandbox é https://api-hom.assine.online.

Quando for utilizar em produção, o domínio do frontend será https://app.assine.online e a api será https://api.assine.online. Durante nossos tutoriais, usaremos o domínio de produção como exemplo.

Com o cadastro concluído, pegamos então o token de sessão:

cURL
JavaScript
PHP
cURL
curl -X POST -H "Content-Type: application/json" \
https://api.assine.online/oauth -d '
{
"grant_type": "password",
"client_id": "app",
"client_secret": "app",
"username": "INFORME_USUARIO",
"password": "INFORME_SENHA"
}
'
JavaScript
const payload = {
grant_type:'password',
client_id: 'app',
client_secret: 'app',
username: 'INFORME_USUARIO',
password: 'INFORME_SENHA'
};
const response = await fetch('https://api.assine.online/oauth', {
method: 'POST',
body: JSON.stringify(payload),
headers: {
'Content-Type': 'application/json'
}
});
const data = await response.json();
PHP
$client = new GuzzleHttp\Client();
$res = $client->request('POST', 'https://api.assine.online/oauth', [
'json' => [
'grant_type' => 'password',
'client_id' => 'app',
'client_secret' => 'app',
'username' => 'INFORME_USUARIO',
'password' => 'INFORME_SENHA'
]
]);
echo $res->getBody();

POST https://api.assine.online/oauth

Resposta:

{
"access_token": "41f7ff53c1dc5cf4f3db1f33e026b2908cdf88b4",
"expires_in": "86400",
"token_type": "Bearer",
"scope": "",
"refresh_token": "5fa76dd7427c6aa55cc7ca6297bbbb8c32d2d9d8"
}

Guarde o access_token pois com ele teremos autorização para utilizar os demais endpoints da API.

Caso precise de um token de acesso com um tempo de vida maior, faça a geração de um token para aplicações.

Fazendo upload do documento PDF

Antes de iniciarmos um fluxo de assinatura, precisamos subir o arquivo que será assinado pelas pessoas.

Baixe aqui um pdf de exemplo ou defina um que desejar. Supondo que este documento esteja do mesmo diretório que o cursor, podemos usar o endpoint de upload com o verbo POST e passamos o token de acesso no header Authorization no formato Authorization: Bearer <token>:

cURL
JavaScript
PHP
cURL
curl -X POST \
-H "Authorization: Bearer 41f7ff53c1dc5cf4f3db1f33e026b2908cdf88b4" \
-F "file=@file-sample.pdf" https://api.assine.online/v1/file
JavaScript
const token = '41f7ff53c1dc5cf4f3db1f33e026b2908cdf88b4';
// Suponha que existe um campo de input[file] com o id "file"
const file = document.getElementById('file').files[0];
const response = await fetch('https://api.assine.online/v1/file', {
method: 'POST',
headers: {
Authorization: `Bearer ${token}`
},
body: file
});
const data = await response.json();
PHP
$token = '41f7ff53c1dc5cf4f3db1f33e026b2908cdf88b4';
$client = new GuzzleHttp\Client();
$body = fopen('./file-sample.pdf', 'r');
$res = $client->request('POST', 'https://api.assine.online/v1/file', [
'headers' => [
'Authorization' => 'Bearer ' . $token
],
'body' => $body
]);
echo $res->getBody();

POST https://api.assine.online/v1/file

Resposta:

{
"id": 5571,
"name": "file-sample.pdf",
"mimeType": "application/pdf",
"description": null,
"checksum": "6703901978dcb3dbf2d9915e1d3e066cfe712b0a",
"size": 142786,
"uuid": "e2dvb2RfbG9va137ImRhdGEiOnsidXVpZCI6IjBhYzM2ZTY0LTUzNTctMTFlYS05OWUzLTAyNDJhYzE0MDAwNyJ9LCJobWFjIjoiZGRjMGIxMDgzNzA5ZmI4MWNhNjI5MWEzOWNjZjA2NTdlNTBiMmIyNTNjMjM4N2YyNjdlOTJjMmNiZjJkMTU4MCIsIm5vbmNlIjoiODE3NDE1ODIxNDQzODkifQ==",
"_links": {
"self": {
"href": "https://api.assine.online/v1/file/5571"
}
}
}

A propriedade uuid é um token único para acesso futuro de forma pública ao arquivo, lembrando que nesse momento o arquivo não possui assinatura.

Fluxo de assinatura

Antes de criarmos o fluxo de assinatura e fazer a requisição ao backend, precisamos criar uma estrutura de JSON em que irá conter: uma mensagem de identificação do fluxo, a validade desse fluxo, os arquivos que devem ser assinados, os assinantes de cada arquivo e em que local do documento essa assinatura deve aparecer.

A estrutura final é relativamente grande e pode se tornar um pouco complexa de início, portanto vamos por partes.

Caso prefira, utilize nossa página que fornece um fluxo para integração facilitando a inclusão de campos e posições de assinatura clicando aqui.

Configuração geral do fluxo

Vamos começar criando a primeira parte do corpo do payload que iremos enviar, nele precisa conter na raiz as seguintes propriedades:

{
"autoRemind": 0,
"autoInitiate": 0,
"dueDate": "2023-01-01 00:00:00",
"message": "Uma mensagem de identificação",
"priority": 0,
"sla": 1,
"files": [...]
}
  • autoRemind: Notificações de email quando está pendente de assinatura de alguém.

    • 0 desativa

    • 1 ativa.

  • autoInitiate: Além de criar o fluxo, já também inicia o fluxo, fazendo os envios de emails para os assinantes.

    • 0 desativa;

    • 1 ativa.

  • dueDate: Data de vencimento do fluxo, não será possível assinar os documentos após esta data definida.

  • message: Uma mensagem para identificar este fluxo.

  • priority: Simboliza uma prioridade para o fluxo.

    • 0 é prioridade normal;

    • 1 é alta e;

    • 2 muito alta.

  • sla: Valor em horas em que será notificado a pendência de assinatura à pessoa. O valor 1 significa uma hora, 2 significa duas horas, sendo o valor máximo 720 horas (30 dias).

  • files: um array de arquivos que vamos escolher para este fluxo, faremos isso no próximo passo.

Definição dos arquivos

Continuamos então construindo nosso payload que iremos enviar para criar o fluxo, agora informando quais arquivos queremos utilizar. Definiremos o arquivo de id 5571 que fizemos upload no passo anterior, adicione o conteúdo dentro da propriedade files do nosso payload:

{
...
"files": [
{
"idFile": 5571,
"name": "Um documento de exemplo",
"specialFields": [],
"workflowSteps": [...]
}
]
}
  • idFile: é o id do arquivo que nos foi retornado ao fazermos upload no passo anterior.

  • name(opcional) : Um nome para o documento como forma de identificação.

  • specialFields: São campos especiais que podemos colocar no documento que não dependem de um assinante específico. Um exemplo seria um campo de QR Code que possui um link em que valida se o documento é legitimo, outro exemplo é um campo de texto em que é possível preencher com dados da pessoa como CPF, datas de nascimento e etc. No nosso exemplo não usaremos estes campos, mas você pode conferir alguns exemplos de como utilizá-los neste link.

  • workflowSteps: Este define quem serão os nossos assinantes, na ordem que definimos e qual tipo de assinatura iremos pegar deste usuário, faremos isso no próximo passo.

Caso você queira informar uma pasta para este arquivo, você pode incluir a propriedade idFolder conforme:

{
...
"files": [
{
"idFile": 5571,
"idFolder": 10,
[...]
}
]
}

Confira aqui como criar as pastas.

Definição dos assinantes

Faremos um exemplo com dois assinantes: Jõao Carlos Santos e Maria das Neves. Vamos adicionar um workflowStep ao nosso array do payload com o João como primeiro assinante:

{
...
"files": [
{
...
"workflowSteps": [
{
"user": {
"name": "João Carlos Santos",
"email": "joaocarlossantos@webbamail.com"
},
"action": 0,
"signatureType": 0,
"fields": [...]
}
]
}
]
}
  • user: Dados do assinante

    • name: Nome do assinante, este nome irá aparecer no email que a pessoa receberá.

    • email: Endereço de email da pessoa usado para enviar o documento pedindo a assinatura.

  • action: Ação desta pessoa perante o documento, ou seja, se ela deve assinar, aprovar ou visualizar.

    • 0 define como pessoa assinante;

    • 1 como aprovador do documento;

    • 2 como visualizador.

  • signatureType: Tipo de assinatura que queremos que essa pessoa faça, os tipos são:

  • field: Campos para este usuário, ou seja, aqui vamos definir a posição em que a assinatura irá ficar dentro do documento, como também podemos definir outros campos para a pessoa preencher. Faremos isso no próximo passo.

Definindo a posição da assinatura de João Carlos Santos

No passo anterior definimos que João Carlos Santos será o primeiro assinante e que queremos uma assinatura eletrônica dele, agora precisamos definir em que lugar do documento essa assinatura ficará. Para isso definiremos a field que essa assinatura ficará:

{
...
"files": [
{
...
"workflowSteps": [
{
...
"fields": [
{
"type": 8,
"x": 51,
"y": 29,
"height": 46,
"width": 200,
"page": 1
}
]
}
]
}
]
}
  • type: O tipo do campo que estamos adicionando. Aqui vale algumas regras:

    • Para cada usuário adicionado, deve existir ao menos um field do tipo 8 , 16 ou 17 , não podendo ter ambos e nem dois do mesmo tipo.

    • Os demais campos entre 0 e 15, exceto o 8, podem se repetir.

    • Os campos são:

      • 0: O nome do assinante;

      • 1: O email do assinante;

      • 4: Um campo de data;

      • 6: Um campo de input de texto de preenchimento opcional;

      • 7: Um campo de input de texto de preenchimento obrigatório;

      • 8: A assinatura visível, ou seja, o desenho da assinatura da pessoa;

      • 11: Um campo de data da assinatura;

      • 16: Uma assinatura invisível, ou seja, que consta do documento final mas não existe uma representação visual no documento.

      • 17: A assinatura visível, porém esta ficará na última página do documento no rodapé do lado direito, com essa assinatura não é necessário informar os eixos x e y.

  • x: Distância do eixo X em relação à página em que o campo deve aparecer;

  • y: Distância do eixo Y em relação à página em que o campo deve aparecer;

  • height: Altura que o campo terá em seu tamanho;

  • width: Largura que o campo terá em seu tamanho;

  • page: Em qual página do documento estará este campo.

Caso queira exemplos de como definir os demais campos, veja neste link.

Segue uma imagem de exemplo do que esses valores representam:

Posição da assinatura de João Carlos Santos

Aqui estamos dizendo que queremos um campo de assinatura eletrônica (type: 8), que esteja a 29 pixels do topo do documento (y: 29) e 51 pixels da esquerda do documento (x: 51). Tenha 200 pixels de largura (width: 200) e 46 pixels de altura (height: 46) e que queremos este campo na primeira página do documento (page: 1).

Com isso temos o nosso primeiro assinante definido, agora vamos duplicar e adicionar a Maria das Neves como segunda assinante.

Caso tenha dificuldades em definir as posições das assinaturas no documento, temos a opção de usar templates em uma página de configuração, veja neste link como você pode fazer isso.

Definindo Maria das Neves como segundo assinante

Assim como o processo anterior, basta criar uma segunda posição no array com os dados de Maria:

{
...
"files": [
{
...
"workflowSteps": [
{
"user": {
"name": "João Carlos Santos",
"email": "joaocarlossantos@webbamail.com"
},
"action": 0,
"signatureType": 0,
"fields": [
{
"type": 8,
"x": 51,
"y": 29,
"height": 46,
"width": 200,
"page": 1
}
]
},
{
"user": {
"name": "Maria das Neves",
"email": "mariadasneves@webbamail.com"
},
"action": 0,
"signatureType": 0,
"fields": [
{
"type": 8,
"x": 490,
"y": 29,
"height": 46,
"width": 200,
"page": 1
}
]
}
]
}
]
}

Note que adicionamos também um campo do tipo assinatura eletrônica (type: 8) na mesma distância y da assinatura de João, porém colocamos que ela irá assinar mais para esquerda, à 490 pixels (x: 490).

Posição da assinatura de Maria das Neves

Concluindo o payload

Com isso concluímos a construção do nosso payload e podemos então criar um fluxo, do qual nomeamos de workflow. Então o seu payload final será algo parecido com:

{
"autoRemind": 0,
"autoInitiate": 0,
"dueDate": "2023-01-01 00:00:00",
"message": "Uma mensagem de identificação",
"priority": 0,
"sla": 1,
"files": [
{
"idFile": 5571,
"name": "Um documento de exemplo",
"specialFields": [],
"workflowSteps": [
{
"user": {
"name": "João Carlos Santos",
"email": "joaocarlossantos@webbamail.com"
},
"action": 0,
"signatureType": 0,
"fields": [
{
"type": 8,
"x": 51,
"y": 29,
"height": 46,
"width": 200,
"page": 1
}
]
},
{
"user": {
"name": "Maria das Neves",
"email": "mariadasneves@webbamail.com"
},
"action": 0,
"signatureType": 0,
"fields": [
{
"type": 8,
"x": 490,
"y": 29,
"height": 46,
"width": 200,
"page": 1
}
]
}
]
}
]
}

Criando o fluxo (workflow)

Agora que temos nosso payload de workflow, vamos criá-lo:

cURL
JavaScript
PHP
cURL
curl -X POST \
-H 'Authorization: Bearer 41f7ff53c1dc5cf4f3db1f33e026b2908cdf88b4' \
-H "Content-Type: application/json" \
https://api.assine.online/v1/workflow -d '
{
"autoRemind": 0,
"autoInitiate": 0,
"dueDate": "2023-01-01 00:00:00",
"message": "Uma mensagem de identificação",
"priority": 0,
"sla": 1,
"files": [
{
"idFile": 5571,
"name": "Um documento de exemplo",
"specialFields": [],
"workflowSteps": [
{
"user": {
"name": "João Carlos Santos",
"email": "joaocarlossantos@webbamail.com"
},
"action": 0,
"signatureType": 0,
"fields": [
{
"type": 8,
"x": 51,
"y": 29,
"height": 46,
"width": 200,
"page": 1
}
]
},
{
"user": {
"name": "Maria das Neves",
"email": "mariadasneves@webbamail.com"
},
"action": 0,
"signatureType": 0,
"fields": [
{
"type": 8,
"x": 490,
"y": 29,
"height": 46,
"width": 200,
"page": 1
}
]
}
]
}
]
}
'
JavaScript
const token = '41f7ff53c1dc5cf4f3db1f33e026b2908cdf88b4';
const payload = {
autoRemind: 0,
autoInitiate: 0,
dueDate: '2023-01-01 00:00:00',
message: 'Uma mensagem de identificação',
priority: 0,
sla: 1,
files: [
{
idFile: 5571,
name: 'Um documento de exemplo',
specialFields: [],
workflowSteps: [
{
user: {
name: 'João Carlos Santos',
email: 'joaocarlossantos@webbamail.com'
},
action: 0,
signatureType: 0,
fields: [
{
type: 8,
x: 51,
y: 29,
height: 46,
width: 200,
page: 1
}
]
},
{
user: {
name: 'Maria das Neves',
email: 'mariadasneves@webbamail.com'
},
action: 0,
signatureType: 0,
fields: [
{
type: 8,
x: 490,
y: 29,
height: 46,
width: 200,
page: 1
}
]
}
]
}
]
};
const response = await fetch('https://api.assine.online/v1/workflow', {
method: 'POST',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(payload),
});
const data = await response.json();
PHP
$token = '41f7ff53c1dc5cf4f3db1f33e026b2908cdf88b4';
$client = new GuzzleHttp\Client();
$res = $client->request('POST', 'https://api.assine.online/v1/workflow', [
'headers' => [
'Authorization' => 'Bearer ' . $token
],
'json' => [
"autoRemind" => 0,
"autoInitiate" => 0,
"dueDate" => "2023-01-01 00:00:00",
"message" => "Uma mensagem de identificação",
"priority" => 0,
"sla" => 1,
"files" => [
[
"idFile" => 5571,
"name" => "Um documento de exemplo",
"specialFields" => [],
"workflowSteps" => [
[
"user" => [
"name" => "João Carlos Santos",
"email" => "joaocarlossantos@webbamail.com"
],
"action" => 0,
"signatureType" => 0,
"fields" => [
[
"type" => 8,
"x" => 51,
"y" => 29,
"height" => 46,
"width" => 200,
"page" => 1
]
]
],
[
"user" => [
"name" => "Maria das Neves",
"email" => "mariadasneves@webbamail.com"
],
"action" => 0,
"signatureType" => 0,
"fields" => [
[
"type" => 8,
"x" => 490,
"y" => 29,
"height" => 46,
"width" => 200,
"page" => 1
]
]
]
]
]
]
]
]);
echo $res->getBody();

POST https://api.assine.online/v1/workflow

Resposta:

{
"id": 1232,
"autoRemind": 0,
"dueDate": {
"date": "2023-01-01 00:00:00.000000",
"timezone_type": 3,
"timezone": "UTC"
},
"name": null,
"message": "Uma mensagem de identificação",
"priority": 0,
"sla": 1,
"status": 0,
"_embedded": {
"user": {
"id": 474,
"username": "siletic225@xhyemail.com",
"password": "$2y$10$Vw9uEiHuza.CaPHvmqXmi..PXIKQe/uyuDCnqkJOYWNpagU3X6IWm",
"status": "1",
"name": "Jhon Doe",
"email": "siletic225@xhyemail.com",
"cellphone": "+5562991838359",
"document": "12312312312",
"country": "Brazil",
"state": "GO",
"city": "Goiânia",
"address": "Av 136, Ed. New York Square 19/20",
"zipCode": "74000000",
"dateCreated": {
"date": "2020-02-20 13:28:28.000000",
"timezone_type": 3,
"timezone": "UTC"
},
"dateLastUpdated": {
"date": "2020-02-20 13:29:10.000000",
"timezone_type": 3,
"timezone": "UTC"
},
"_embedded": {
"businessUnit": {
"id": 24,
"name": "Soluti Soluções em negocios inteligentes",
"document": "cnpj",
"status": null,
"country": "Brazil",
"state": "GO",
"city": "Goiânia",
"address": "Av 136, Ed. New York Square 19/20",
"zipCode": "74000000",
"_links": {
"self": {
"href": "https://api.assine.online/v1/business-unit/24"
}
}
}
},
"_links": {
"self": {
"href": "https://api.assine.online/v1/user/474"
}
}
}
},
"_links": {
"self": {
"href": "https://api.assine.online/v1/workflow/1232"
}
}
}

Muitas informações retornadas são configurações que foram feitas no momento da criação da qual nós mesmos definimos, mas vamos observar a propriedade status da qual foi retornada com o valor 0 , o que significa que este workflow de id 1232 ainda não foi iniciado. Os status que um workflow pode ter são:

  • 0: Rascunho, ou seja, ainda não iniciou-se.

  • 1: Circulando, ou seja, o fluxo se iniciou e está aguardando que as pessoas assinem.

  • 2: Cancelado, ou seja, a pessoa que criou o fluxo cancelou.

  • 3: Expirado, ou seja, o fluxo passou da data de vencimento definida.

  • 4: Processando, ou seja, o documento está sendo processado com o cálculo de criptografia da assinatura.

  • 5: Rejeitado, ou seja, algum dos assinantes rejeitou assinar este workflow.

  • 6: Completado, ou seja, todos os assinantes efetuaram a assinatura e o documento está totalmente assinado.

Neste momento, o fluxo está apenas criado mas não iniciado, vamos então para o próximo passo que é de iniciar o workflow e aguardar as assinaturas.

Iniciando o workflow e aguardando as assinaturas

Agora que temos nosso id do fluxo, ou workflow, vamos iniciá-lo para que o Assine Online comece a enviar os emails para os assinantes na ordem que definimos, alterando o status do workflow para 1 (Circulando):

cURL
JavaScript
PHP
cURL
curl -X PATCH \
-H "Authorization: Bearer 41f7ff53c1dc5cf4f3db1f33e026b2908cdf88b4" \
-H "Content-Type: application/json" \
https://api.assine.online/v1/workflow/1232 -d '
{
"status": 1
}'
JavaScript
const token = '41f7ff53c1dc5cf4f3db1f33e026b2908cdf88b4';
const workflowId = 1232;
const payload = {
status: 1
};
const response = await fetch(`https://api.assine.online/v1/workflow/${workflowId}`, {
method: 'PATCH',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(payload),
});
const data = await response.json();
PHP
$token = '41f7ff53c1dc5cf4f3db1f33e026b2908cdf88b4';
$workflowId = 1232;
$client = new GuzzleHttp\Client();
$res = $client->request('PATCH', 'https://api.assine.online/v1/workflow/' . $workflowId, [
'headers' => [
'Authorization' => 'Bearer ' . $token
],
'json' => [
'status' => 1
]
]);
echo $res->getBody();

PATCH https://api.assine.online/v1/workflow/:workflowId

Resposta:

{
"id": 1232,
"autoRemind": 0,
"dueDate": {
"date": "2023-01-01 00:00:00.000000",
"timezone_type": 3,
"timezone": "UTC"
},
"name": null,
"message": "Uma mensagem de identificação",
"priority": 0,
"sla": 1,
"status": 1,
"_embedded": {
"user": {
"id": 474,
"username": "siletic225@xhyemail.com",
"status": "1",
"name": "Jhon Doe",
"email": "siletic225@xhyemail.com",
"cellphone": "+5562991838359",
"document": "12312312312",
"country": "Brazil",
"state": "GO",
"city": "Goiânia",
"address": "Av 136, Ed. New York Square 19/20",
"zipCode": "74000000",
"dateCreated": {
"date": "2020-02-20 13:28:28.000000",
"timezone_type": 3,
"timezone": "UTC"
},
"dateLastUpdated": {
"date": "2020-02-20 13:29:10.000000",
"timezone_type": 3,
"timezone": "UTC"
},
"_embedded": {
"businessUnit": {
"id": 24,
"name": "Soluti Soluções em negocios inteligentes",
"document": "cnpj",
"status": null,
"country": "Brazil",
"state": "GO",
"city": "Goiânia",
"address": "Av 136, Ed. New York Square 19/20",
"zipCode": "74000000",
"_links": {
"self": {
"href": "https://api.assine.online/v1/business-unit/24"
}
}
}
},
"_links": {
"self": {
"href": "https://api.assine.online/v1/user/474"
}
}
}
},
"_links": {
"self": {
"href": "https://api.assine.online/v1/workflow/1232"
}
}
}

Notamos que a resposta é a mesma da criação do workflow, com a diferença que agora o status é 1. Se verificarmos a caixa de entrada de João, veremos que ele recebeu um pedido de assinatura:

Email recebido na caixa de entrada de João Carlos Santos

Perceba que estamos aguardando a assinatura de João e de Maria, porém Maria ainda não recebeu o pedido de assinatura, do qual será feito após João assinar.

Validando status de assinatura

Primeiramente, vamos pedir para a API nos trazer os detalhes de como está nosso workflow. Para isso fazemos:

cURL
JavaScript
PHP
cURL
curl -X GET \
-H "Authorization: Bearer 41f7ff53c1dc5cf4f3db1f33e026b2908cdf88b4" \
-H "Content-Type: application/json" \
https://api.assine.online/v1/workflow/1232
JavaScript
const token = '41f7ff53c1dc5cf4f3db1f33e026b2908cdf88b4';
const workflowId = 1232;
const response = await fetch(`https://api.assine.online/v1/workflow/${workflowId}`, {
method: 'GET',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json'
}
});
const data = await response.json();
PHP
$token = '41f7ff53c1dc5cf4f3db1f33e026b2908cdf88b4';
$workflowId = 1232;
$client = new GuzzleHttp\Client();
$res = $client->request('GET', 'https://api.assine.online/v1/workflow/' . $workflowId, [
'headers' => [
'Authorization' => 'Bearer ' . $token
]
]);
echo $res->getBody();

GET https://api.assine.online/v1/workflow/:workflowId

Resposta:

{
"id": 1232,
"autoRemind": 0,
"dueDate": {
"date": "2023-01-01 00:00:00.000000",
"timezone_type": 3,
"timezone": "UTC"
},
"name": null,
"message": "Uma mensagem de identificação",
"priority": 0,
"sla": 1,
"status": 1,
"dateCreated": {
"date": "2020-02-20 18:11:10.000000",
"timezone_type": 3,
"timezone": "UTC"
},
"dateStatus": {
"date": "2020-02-20 18:49:41.000000",
"timezone_type": 3,
"timezone": "UTC"
},
"dateFinished": null,
"_embedded": {
"documents": [
{
"id": 1325,
"name": "Um documento de exemplo",
"status": 0,
"dueDate": null,
"specialFields": [],
"workflowSteps": [
{
"id": 1446,
"action": 0,
"signatureType": 0,
"status": 1,
"extraMetadata": null,
"dateStatus": {
"date": "2020-02-20 18:49:41.000000",
"timezone_type": 3,
"timezone": "UTC"
},
"latitude": null,
"longitude": null,
"reason": null,
"fields": [
{
"type": 8,
"x": 51,
"y": 29,
"height": 46,
"width": 200,
"page": 1,
"value": "",
"name": ""
}
],
"_embedded": {
"user": {
"id": 475,
"name": "João Carlos Santos",
"email": "joaocarlossantos@webbamail.com"
}
}
},
{
"id": 1447,
"action": 0,
"signatureType": 0,
"status": 0,
"extraMetadata": null,
"dateStatus": null,
"latitude": null,
"longitude": null,
"reason": null,
"fields": [
{
"type": 8,
"x": 490,
"y": 29,
"height": 46,
"width": 200,
"page": 1,
"value": "",
"name": ""
}
],
"_embedded": {
"user": {
"id": 476,
"name": "Maria das Neves",
"email": "mariadasneves@webbamail.com"
}
}
}
],
"_embedded": {
"folder": {
"id": 174,
"name": "default",
"path": "default"
},
"originalFile": {
"id": 5575,
"checksum": "6703901978dcb3dbf2d9915e1d3e066cfe712b0a",
"_links": {
"download": {
"href": "https://api.assine.online/v1/file?q=e2dvb2RfbG9va317ImRhdGEiOnsidXVpZCI6IjVhOGQyMjcyLTU0MGMtMTFlYS04ZjgyLTAyNDJhYzE0MDAwNyJ9LCJobWFjIjoiMWVkMTc5NTI2ODk2MmFhNTU1NzhhODI1MjI0OWYyM2EyNjhiNDRlM2Q5NmEyY2Q3ZTViMTM1NGE3YmU1NjE4NCIsIm5vbmNlIjoiMDczNzE1ODIyMjU1NTUifQ=="
}
}
},
"file": null
}
}
]
},
"_links": {
"self": {
"href": "https://api.assine.online/v1/workflow/1232"
}
}
}

Vamos dar uma atenção maior para o conteúdo que está dentro de workflowStep :

{
...,
"workflowSteps": [
{
"id": 1446,
"action": 0,
"signatureType": 0,
"status": 1,
"extraMetadata": null,
"dateStatus": {
"date": "2020-02-20 18:49:41.000000",
"timezone_type": 3,
"timezone": "UTC"
},
"latitude": null,
"longitude": null,
"reason": null,
"fields": [
{
"type": 8,
"x": 51,
"y": 29,
"height": 46,
"width": 200,
"page": 1,
"value": "",
"name": ""
}
],
"_embedded": {
"user": {
"id": 475,
"name": "João Carlos Santos",
"email": "joaocarlossantos@webbamail.com"
}
}
},
...
],
...
}

O workflowSteps são os passos do fluxo necessário para que o documento seja assinado por completo, ou seja, cada passo é um pedido de assinatura. No nosso caso temos dois passos, sendo o primeiro o pedido de assinatura de Jõao e o segundo de Maria, onde o passo do João tem como id o número 1446 do qual podemos usar para consultar diretamente. Note que nesse primeiro step destacado acima temos as propriedades:

  • status: O status em que se encontra esse passo, ou seja, informa se João já assinou ou não.

    • 0: Não iniciado, ou seja, o fluxo ainda não se iniciou e a pessoa ainda não recebeu o email pedindo a assinatura.

    • 1: Aguardando assinatura, ou seja, aguardando que o assinante peça para assinar.

    • 2: Na fila de processamento, ou seja, está na fila para processar a assinatura.

    • 3: Processando, ou seja, está no processo de gerar as chaves e cálculos para realizar a assinatura.

    • 4: Aprovado, ou seja, já foi processado e o usuário aprovou que o documento possa ser assinado, podendo avançar para o próximo passo que no nosso caso, o próximo passo é pedir a assinatura de Maria.

    • 5: Rejeitado, ou seja, o assinante rejeitou assinar o documento, abortando todo o fluxo.

  • latitude: Latitude planetária em que o assinante estava no momento da assinatura.

  • longitude: Longitude planetária em que o assinante estava no momento da assinatura.

Vamos supor que somos João e aprovaremos o pedido de assinatura do documento. No email do qual João recebeu, ao clicar no link de Ver documento que está no corpo do email, ele será redirecionado para a tela de assinatura do Assine Online:

Visão de Jõao Carlos Santos para assinar o documento

Depois que João clicar em assinar, vamos verificar o status do step de João no workflow:

cURL
JavaScript
PHP
cURL
curl -X GET \
-H "Authorization: Bearer 41f7ff53c1dc5cf4f3db1f33e026b2908cdf88b4" \
-H "Content-Type: application/json" \
https://api.assine.online/v1/workflow/1232
JavaScript
const token = '41f7ff53c1dc5cf4f3db1f33e026b2908cdf88b4';
const workflowId = 1232;
const response = await fetch(`https://api.assine.online/v1/workflow/${workflowId}`, {
method: 'GET',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json'
}
});
const data = await response.json();
PHP
$token = '41f7ff53c1dc5cf4f3db1f33e026b2908cdf88b4';
$workflowId = 1232;
$client = new GuzzleHttp\Client();
$res = $client->request('GET', 'https://api.assine.online/v1/workflow/' . $workflowId, [
'headers' => [
'Authorization' => 'Bearer ' . $token
]
]);
echo $res->getBody();

GET https://api.assine.online/v1/workflow/:workflowId

Resposta:

{
"id": 1232,
// Status do workflow em geral ainda está aguardando que
// todos os assinem. 1 = Circulando
"status": 1,
...,
"_embedded": {
"documents": [
{
...,
"workflowSteps": [
{
"id": 1446,
"action": 0,
"signatureType": 0,
// Status 4 (aprovado) depois da assinatura de João.
"status": 4,
"extraMetadata": null,
"dateStatus": {
"date": "2020-02-20 19:59:29.000000",
"timezone_type": 3,
"timezone": "UTC"
},
"latitude": "-16.702237",
"longitude": "-49.2537428",
"reason": ".",
"fields": [...],
"_embedded": {
"user": {
"id": 475,
"name": "João Carlos Santos",
"email": "joaocarlossantos@webbamail.com"
}
}
},
{
"id": 1447,
"action": 0,
"signatureType": 0,
// Maria ainda está aguardando a assinatura
"status": 1,
"extraMetadata": null,
"dateStatus": {
"date": "2020-02-20 19:59:29.000000",
"timezone_type": 3,
"timezone": "UTC"
},
"latitude": null,
"longitude": null,
"reason": null,
"fields": [...],
"_embedded": {
"user": {
"id": 476,
"name": "Maria das Neves",
"email": "mariadasneves@webbamail.com"
}
}
}
],
...
}
]
},
...
}

Agora é a vez de Maria assinar, quando João fez sua assinatura, Maria recebeu o email na caixa de entrada:

Email recebido na caixa de entrada de Maria das Neves

Perceba que no email já informa que João já assinou e agora falta somente a assinatura de Maria. Depois que maria assinar, vamos verificar novamente o workflow:

cURL
JavaScript
PHP
cURL
curl -X GET \
-H "Authorization: Bearer 41f7ff53c1dc5cf4f3db1f33e026b2908cdf88b4" \
-H "Content-Type: application/json" \
https://api.assine.online/v1/workflow/1232
JavaScript
const token = '41f7ff53c1dc5cf4f3db1f33e026b2908cdf88b4';
const workflowId = 1232;
const response = await fetch(`https://api.assine.online/v1/workflow/${workflowId}`, {
method: 'GET',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json'
}
});
const data = await response.json();
PHP
$token = '41f7ff53c1dc5cf4f3db1f33e026b2908cdf88b4';
$workflowId = 1232;
$client = new GuzzleHttp\Client();
$res = $client->request('GET', 'https://api.assine.online/v1/workflow/' . $workflowId, [
'headers' => [
'Authorization' => 'Bearer ' . $token
]
]);
echo $res->getBody();

GET https://api.assine.online/v1/workflow/:workflowId

Resposta:

{
"id": 1232,
// Agora que todos assinaram, o status do workflow
// fica como 6 (completado)
"status": 6,
...,
"_embedded": {
"documents": [
{
...,
"workflowSteps": [
{
"id": 1446,
"action": 0,
"signatureType": 0,
// Aprovado
"status": 4,
"extraMetadata": null,
"dateStatus": {
"date": "2020-02-20 19:59:29.000000",
"timezone_type": 3,
"timezone": "UTC"
},
"latitude": "-16.702237",
"longitude": "-49.2537428",
"reason": ".",
"fields": [...],
"_embedded": {
"user": {
"id": 475,
"name": "João Carlos Santos",
"email": "joaocarlossantos@webbamail.com"
}
}
},
{
"id": 1447,
"action": 0,
"signatureType": 0,
// Aprovado
"status": 4,
"extraMetadata": null,
"dateStatus": {
"date": "2020-02-20 19:59:29.000000",
"timezone_type": 3,
"timezone": "UTC"
},
"latitude": "-16.702237",
"longitude": "-49.2537428",
"reason": ".",
"fields": [...],
"_embedded": {
"user": {
"id": 476,
"name": "Maria das Neves",
"email": "mariadasneves@webbamail.com"
}
}
}
],
...
}
]
},
...
}

Download do documento assinado

Depois que é feito a assinatura, você pode fazer o download do documento assinado pelos links fornecidos no workflow, vamos buscar o workflow novamente:

cURL
JavaScript
PHP
cURL
curl -X GET \
-H "Authorization: Bearer 41f7ff53c1dc5cf4f3db1f33e026b2908cdf88b4" \
-H "Content-Type: application/json" \
https://api.assine.online/v1/workflow/1232
JavaScript
const token = '41f7ff53c1dc5cf4f3db1f33e026b2908cdf88b4';
const workflowId = 1232;
const response = await fetch(`https://api.assine.online/v1/workflow/${workflowId}`, {
method: 'GET',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json'
}
});
const data = await response.json();
PHP
$token = '41f7ff53c1dc5cf4f3db1f33e026b2908cdf88b4';
$workflowId = 1232;
$client = new GuzzleHttp\Client();
$res = $client->request('GET', 'https://api.assine.online/v1/workflow/' . $workflowId, [
'headers' => [
'Authorization' => 'Bearer ' . $token
]
]);
echo $res->getBody();

GET https://api.assine.online/v1/workflow/:workflowId

Resposta:

{
"id": 1232,
"status": 1,
...,
"dateFineshed": null,
"_embedded": {
"documents": [
{
"id": 1325,
...,
"_embedded": {
"folder": {
"id": 174,
"name": "default",
"path": "default"
},
// O documento original sem assinatura
"originalFile": {
"id": 5575,
"checksum": "6703901978dcb3dbf2d9915e1d3e606cfe712b0a",
"_links": {
"download": {
"href": "https://api.assine.online/v1/file?q=e2dvb2RfbG9va317ImRhdGEiOnsidXVpCZI6IjVhOGQyMjcyLTU0MGMtMTFlYS04ZjgyLTAyNDJhYzE0MDAwNyJ9LCJobWFjIjoiMDczYTA0NzdkNTE3ZTE1YTNlY2IyNGMzYTQwYzM5YTE3M2VmOTcwZDc0Mjc0ODNiY2I1YmEwYTZlNjJiNWQxNyIsIm5vbmNlIjoiMzg1MDE1ODI3MjMyODMifQ=="
}
}
},
// O documento com as assinaturas
"file": {
"id": 5576,
"checksum": "103994b4da4634f0b304d8c0ab50addcdd0050d0",
"_links": {
"download": {
"href": "https://api.assine.online/v1/file?q=e2dvb2RfbG9va317ImRhdGEiOnsidXVpCZI6IjgxMGUyODI0LTU0MWItMTFlYS1iZGI5LTAyNDJhYzE0MDAwNyJ9LCJobWFjIjoiOGRlNDBlNTU1NmFmMzRlMzMxYjBiMzZmZDhjNGRmZmI5NDM5YTY0MGVlZGU2MWQwNzVkYTEzZTY5MGYzNDk3YiIsIm5vbmNlIjoiOTQyMDE1ODI3MjMyODMifQ=="
}
}
}
}
}
]
},
...
}

Na resposta é fornecido dois links:

  • _embedded.documents[0]._embedded.originalFile._links.download.href: link de download do documento original sem as assinaturas.

  • _embedded.documents[0]._embedded.file._links.download.href: link de download do documento com as assinaturas.

Com isso concluímos o fluxo completo de uma assinatura.