1.0.0 • Published 4 years ago

@paybook/paybook-sync v1.0.0

Weekly downloads
-
License
ISC
Repository
github
Last release
4 years ago

Paybook-logo

SYNC-NODE

Sync recupera información de las cuentas y sus transacciones, de instituciones financieras autorizados por el usuario, y lo regresa a soluciones de terceros en un formato organizado, muy fácil de utilizar.

Tabla de contenidos

Instalación

  1. Agrega el código boilerplate de este archivo sync.js a tu código.

  2. Instala las dependencias via npm

  npm i request-promise request

Requerimientos

  1. API Key:

    Cuando creamos una cuenta de Paybook Sync se nos proporcionó una API Key, por ejemplo:

    api_key = 7767a4a04f990e9231bafc949e8ca08a

    Este API key lo podemos visualizar como la contraseña o llave de acceso a los servicios de Paybook Sync. Únicamente a través de ella podremos consultar la información de las instituciones que sincronicemos.

Implementación

La librería incluye los metodos: 1. Sync.auth()

Nota: Para realizar la autenticación es necesario tener creado un usuario, de donde se obtiene el id_user, vease este ejemplo. 2. Sync.run() Vease el apartado de recursos disponibles

Por ejemplo:

const API_KEY = TU_API_KEY;

// Crear una sesión para un usuario
let token = await Sync.auth(
  {api_key: API_KEY}, // Tu API KEY
  {id_user: id_user} // ID de usuario
);

// Consumir un recurso de Sync
let response = await Sync.run(
  {token: token}, // Autenticación
  '/credentials', // Recurso
  {}, // Parametros
  'GET' // Método HTTP
);

¡Importante!: No escribas tu API KEY directamente en tu código o en texto plano, ya que es una mala práctica de seguridad, te recomiendo que revises la libreria Dotenv.

Autenticación

Obtener un Token de sesión:

  let token = await Sync.auth(
    {api_key: API_KEY}, 
    {id_user: id_user}
  );

Respuesta:

  console.log(token);
  // #Imprime: { token: "d5b33dcf996ac34fd2fa56782d72bff6"}

Recursos y Ejemplos

Puedes consultar más información acerca de los parametros de cada recurso en la documentación oficial de paybook.

Usuarios

Los usuarios son segmentaciones lógicas para los usuarios finales. Una mejor práctica es registrar usuarios para tener su información agrupada y control en ambos extremos. Es necesario tener al menos un usuario registrado para crear credenciales.

{ api_key: API_KEY }
{
    "id_external", // Opcional
    "fields", // Opcional
    "limit", // Opcional
    "skip", // Opcional
    "order" // Opcional
}
{
  "id_external", // Opcional
  "name"
}

Consultar usuarios

let users = await Sync.run(
  {api_key: API_KEY}, 
  '/users', 
  {}, 
  'GET'
);

Devuelve:

[
  {
      "id_user": "5df859c4a7a6442757726ef4",
      "id_external": "ELSAN090909",
      "name": "El Santo",
      "dt_create": 1576556996,
      "dt_modify": null
  },
  {
      "id_user": "5e061a673e0acd77bf7d3c7b",
      "id_external": "BLDM140389",
      "name": "Blue Demon",
      "dt_create": 1577458279,
      "dt_modify": null
  }
]

Consultar un usuario en especifico

let user = await Sync.run(
  {api_key: API_KEY}, 
  '/users', 
  {id_external: 'ELSAN090909'}, 
  'GET'
);

Devuelve:

[
  {
      "id_user": "5df859c4a7a6442757726ef4",
      "id_external": "ELSAN090909",
      "name": "El Santo",
      "dt_create": 1576556996,
      "dt_modify": null
  }
]

Crear un Usuario

let user = await Sync.run(
  {api_key: API_KEY}, 
  '/users', 
  {
    id_external: 'MIST030794',
    name: 'Rey Misterio'
  }, 
  'POST'
);
let {id_user} = user;

Devuelve:

{
    "id_user": "5e06694b93f4a91cb218f28f",
    "id_external": "MIST030794",
    "name": "Rey Misterio",
    "dt_create": 1577478475,
    "dt_modify": null
}

Actualizar un Usuario

let user = await Sync.run(
  {api_key: API_KEY}, 
  `/users/${id_user}`, 
  {name: 'El Santo Jr.'}, 
  'PUT'
);

Devuelve:

  {
      "id_user": "5df859c4a7a6442757726ef4",
      "id_external": "ELSAN090909",
      "name": "El Santo Jr.",
      "dt_create": 1576556996,
      "dt_modify": 1576557005
  }

Eliminar un usuario

Nota: Esto eliminará toda la información del usuario.

let response = Sync.run(
  {api_key: API_KEY}, 
  `/users/${id_user}`, 
  {}, 
  'DELETE'
);

Devuelve:

{
  "rid": "d337e963-680f-4009-85dc-ab439bfdc771",
  "code": 200,
  "errors": null,
  "status": true,
  "message": null,
  "response": true
}

Catálogos

Los catálogos son colecciones de endpoints que son importantes para la clasificación de otros endpoints.

{ token: TOKEN }
{
    "fields", // opcional
    "limit", // opcional
    "skip", // opcional
    "order", // opcional
}
{
  "id_site", //opcional
  "id_site_organization", //opcional
  "id_site_organization_type", //opcional
  "fields", //opcional
  "limit", //opcional
  "skip", //opcional
  "order", //opciona
}
{
  "id_site", //opcional
  "id_site_organization", //opcional
  "id_site_organization_type", //opcional
}

Catálogos de Instituciones

Paybook Sync proporciona un catálogo de las instituciones que podemos sincronizar para los usuarios.

  // Consultar catálogos
  let sitesCatalog = await Sync.run(
    {token: token}, 
    '/catalogues/organizations/sites', 
    {}, 
    'GET'
  );

Devuelve:

[
  {
      "id_site": "56cf5728784806f72b8b4568",
      "id_site_organization": "56cf4ff5784806152c8b4567",
      "id_site_organization_type": "56cf4f5b784806cf028b4568",
      "id_site_type": "5b285177056f2911c13dbce1",
      "is_business": 1,
      "is_personal": 1,
      "version": 1,
      "name": "Normal",
      "credentials": [
          {
              "name": "username",
              "type": "text",
              "label": "Username",
              "required": true,
              "username": true,
              "token": false,
              "validation": null
          },
          {
              "name": "password",
              "type": "password",
              "label": "Password",
              "required": true,
              "username": false,
              "token": false,
              "validation": null
          }
      ],
      "endpoint": "/v1/credentials"
  },
  {
      "id_site": "56cf5728784806f72b8b4569",
      "id_site_organization": "56cf4ff5784806152c8b4567",
      "id_site_organization_type": "56cf4f5b784806cf028b4568",
      "id_site_type": "5b285177056f2911c13dbce1",
      "is_business": 1,
      "is_personal": 1,
      "version": 1,
      "name": "Token",
      "credentials": [
          {
              "name": "username",
              "type": "text",
              "label": "Username",
              "required": true,
              "username": true,
              "token": false,
              "validation": null
          },
          {
              "name": "password",
              "type": "password",
              "label": "Password",
              "required": true,
              "username": false,
              "token": false,
              "validation": null
          }
      ],
      "endpoint": "/v1/credentials"
  },
  {
      "id_site": "572ba390784806060f8b458b",
      "id_site_organization": "56cf4ff5784806152c8b4567",
      "id_site_organization_type": "56cf4f5b784806cf028b4568",
      "id_site_type": "5b285177056f2911c13dbce1",
      "is_business": 1,
      "is_personal": 1,
      "version": 1,
      "name": "Token & captcha",
      "credentials": [
          {
              "name": "username",
              "type": "text",
              "label": "Username",
              "required": true,
              "username": true,
              "token": false,
              "validation": null
          },
          {
              "name": "password",
              "type": "password",
              "label": "Password",
              "required": true,
              "username": false,
              "token": false,
              "validation": null
          }
      ],
      "endpoint": "/v1/credentials"
  }
  .
  .
  .
]

Credenciales

Las credenciales se refieren a la información de terceras personas que se necesita para autorizar el acceso a un sitio de terceros. Las credenciales se encriptan al momento de introducirse y no están disponibles en ningún endpoint. La información que se extrae de este endpoint, será sólo complementaria.

{ token: TOKEN }
{}
{
  "id_site",
  "credentials"
}
{}

Puedes consultar más acerca de los códigos de respuesta y su significado aquí.

Cada institución tiene sus propias credenciales, algunas instituciones requieren un paso de seguridad "Two factor authentication" o "TWOFA"; Los siguientes ejemplos cubren ambos casos.

Crear credenciales normal

Normal: Credenciales que sólo requieren user y password.

  // Consultar catálogos
  let sites = await Sync.run(
    {token: token}, 
    '/catalogues/organizations/sites', 
    {id_site: "56cf5728784806f72b8b4568"}, 
    'GET'
  );
  let normalSite = sites[0];
  console.log(normalSite);
  /* Algo como esto:
  {
      "id_site": "56cf5728784806f72b8b4568",
      .
      .
      .
      "credentials": [
          {
              "name": "username",
              "type": "text",
              "label": "Username",
              "required": true,
              "username": true,
              "token": false,
              "validation": null
          },
          {
              "name": "password",
              "type": "password",
              "label": "Password",
              "required": true,
              "username": false,
              "token": false,
              "validation": null
          }
      ],
      "endpoint": "/v1/credentials"
  }
  */
  let payload = {
    id_site = normalSite.id_site;
  }; 
  let credentials = {};
  credentials[normalSite.credentials[0].name] = 'test';
  credentials[normalSite.credentials[1].name] = 'test';
  payload['credentials'] = credentials;
  let normalCredential = await Sync.run(
    {token: token}, 
    '/credentials', 
    payload, 
    'POST'
  );

Devuelve:

{
   "id_credential":"5e17c432d7288d358a039141",
   "id_job_uuid":"5e17c4325d4f6077171c0253",
   "id_job":"5e17c4325d4f6077171c0254",
   "is_new":1,
   "username":"t**t",
   "ws":"wss://sync.paybook.com/v1/status/5e17c4325d4f6077171c0254",
   "status":"https://sync.paybook.com/v1/jobs/5e17c4325d4f6077171c0254/status",
   "twofa":"https://sync.paybook.com/v1/jobs/5e17c4325d4f6077171c0254/twofa"
}

Consultar credenciales

  let credentials = await Sync.run(
    {token: token}, 
    '/credentials', 
    {}, 
    'GET'
  );

Devuelve:

[
   {
      "id_credential":"5e17c432d7288d358a039141",
      "id_user":"5e17c430b021255889294af7",
      "id_environment":"574894bf7848066d138b4570",
      "id_external":"",
      "id_site":"56cf5728784806f72b8b4568",
      "id_site_organization":"56cf4ff5784806152c8b4567",
      "id_site_organization_type":"56cf4f5b784806cf028b4568",
      "id_organization":"56cf4ff5784806152c8b4567",
      "is_authorized":1,
      "is_locked":0,
      "is_twofa":0,
      "can_sync":0,
      "ready_in":86377,
      "username":"t**t",
      "code":200,
      "keywords":null,
      "dt_authorized":1578615866,
      "dt_execute":1578615858,
      "dt_ready":1578702266,
      "dt_refresh":null
   }
]

Crear credenciales TWOFA

  1. Consulta el sitio Twofa del catálogo
// Consultar catálogos
let sites = await Sync.run(
  {token: token}, 
  '/catalogues/organizations/sites', 
  {id_site: "56cf5728784806f72b8b4569"}, 
  'GET'
);
  1. Crea las credencials
// Crear credenciales con Token o Autenticación de dos pasos
let twofaSite = sites[0];
let payload = {}; 
payload['id_site'] = twofaSite.id_site;
let credentials = {};
credentials[twofaSite.credentials[0].name] = 'test';
credentials[twofaSite.credentials[1].name] = 'test';
payload['credentials'] = credentials;
let twofaCredentials = await Sync.run(
  {token: token}, 
  '/credentials', 
  payload, 
  'POST'
);
/* Regresa:
{
  id_credential: "5e27c17ca2fc48614c41b33e",
  id_job_uuid: "5e27c17ce6fea94c7c6b4193",
  id_job: "5e27c17ce6fea94c7c6b4194",
  is_new: 1,
  username: "t**t",
  ws: "wss://sync.paybook.com/v1/status/5e27c17ce6fea94c7c6b4194",
  status: "https://sync.paybook.com/v1/jobs/5e27c17ce6fea94c7c6b4194/status",
  twofa: "https://sync.paybook.com/v1/jobs/5e27c17ce6fea94c7c6b4194/twofa"
}
*/
  1. Consulta el status de las credenciales y valida que sea TWOFA
// Consulta Status Credenciales twofa
let id_job = twofaCredentials.id_job;
let status = await Sync.run(
  {token: token}, 
  `/jobs/${id_job}/status`, 
  {}, 
  'GET'
);
/* Regresa:
[
  {
      code: 100
  },
  {
      code: 101
  },
  {
      code: 410,
      address: "https://sync.paybook.com/v1/jobs/5e27c17ce6fea94c7c6b4194/twofa",
      twofa: [
          {
              name: "token",
              type: "text",
              label: "Enter any number sequence as a token"
          }
      ]
  }
]
*/
let is_twofa = false;
if(status[status.length].code == 410){
  is_twofa = true;
}
  1. Manda el TWOFA
// Manda TWOFA
let twofaToken = {
    twofa: {}
};
twofaToken["twofa"][status[2].twofa[0].name] = "123456";
let twofa = await Sync.run(
  {token: token}, 
  `/jobs/${id_job}/twofa`, 
  twofaToken, 
  'POST'
);
/* Regresa:
{
  rid: "ea1e848d-6ec2-454d-b296-0fe2b6c958c2",
  code: 200,
  errors: null,
  status: true,
  message: null,
  response: true
}
*/
  1. Consulta nuevamente el status
status = await Sync.run(
  {token: token}, 
  `/jobs/${id_job}/status`, 
  {}, 
  'GET'
);
/* Regresa:
[
  {
      code: 100
  },
  {
      code: 101
  },
  {
      code: 410,
      address: "https://sync.paybook.com/v1/jobs/5e27c17ce6fea94c7c6b4194/twofa",
      twofa: [
          {
              name: "token",
              type: "text",
              label: "Enter any number sequence as a token"
          }
      ]
  },
  {
      code: 102
  },
  {
      code: 200
  }
]
*/

Eliminar una credencial

let response = await Sync.run(
  {token: token}, 
  `/credentials/${id_credential}`, 
  {}, 
  'DELETE'
);

Devuelve:

{
   "rid":"c241efe0-03a6-41cb-9e8e-73d6e0a779c1",
   "code":200,
   "errors":null,
   "status":true,
   "message":null,
   "response":true
}

Consultar historial de cambios de la credencial

// Despues de crear una credencial (como en ejemplos anteriores)
let id_job = credential.id_job;
let status = await Sync.run(
  {token: token}, 
  `/jobs/${id_job}/status`, 
  {}, 
  'GET'
);

Devuelve:

[
   {
      "code":100
   },
   {
      "code":101
   },
   {
      "code":102
   },
   {
      "code":200
   }
]

Puedes consultar el significado de cada código aquí.

Cuentas

Las cuentas son repositorios de transacciones de usuarios finales, que normalmente se clasifican por alguna característica como tipo y/o número de cuenta. La cuenta y la información de las transacciones pueden recuperarse desde sitios de terceros y se actualizan hasta tres veces al día.

{ token: token }
{
    "id_account", //opcional
    "id_credential", //opcional
    "id_site", //opcional
    "id_site_organization", //opcional
    "id_site_organization_type", //opcional
    "is_disable", //opcional
    "fields", //opcional
    "limit", //opcional
    "skip", //opcional
    "order", //opcional
    "keywords", //opcional
    "skip_keywords" //opcional
}

Consulta las cuentas de un usuario específico

let accounts = Sync.run(
  {token: token}, 
  '/accounts', 
  {id_credential: id_credential}, 
  'GET'
);

Devuelve:

[
  {
    "id_account":"3406d3750b215b9a7f8b4523",
    "id_user":"15f98da7784606ef028b4598",
    "id_external":"37f98da4584806ef028b4567",
    "id_credential":"4806d33c0b234af8028b478b",
    "id_site":"98cf5728784839f72b8b449f",
    "id_site_organization":"29cf4ff5784806152c8b4548",
    "name":"My Bank Account",
    "number":null,
    "balance":1200,
    "site":{
        "id_site":"12cf5728784883f72b8b495f",
        "name":"The Bank",
        "avatar":"/images/8574c68f0b212a194a8c1819/avatar",
        "cover":"/images/5944c68f0b212a194a8c3949/cover",
        "small_cover":"/images/59454c68f0b212a194a8c5719/small_cover"
    },
    "dt_refresh":1460816581
  }
]

Transacciones

Las transacciones son los movimientos financieros que están relacionados con una cuenta, y reflejan el ingreso o egreso que el usuario final tiene en determinado sitio. La cantidad de información histórica que Sync puede recuperar, varía dependiendo de la fuente pero, por lo general, estarán disponibles las transacciones de 60 días.

{ token: token }
{
    "id_transaction", //opcional
    "id_account", //opcional
    "id_credential", //opcional
    "id_site", //opcional
    "id_site_organization", //opcional
    "id_site_organization_type", //opcional
    "has_attachment", //opcional
    "is_disable", //opcional
    "dt_refresh_from", //opcional
    "dt_refresh_to", //opcional
    "dt_transaction_from", //opcional
    "dt_transaction_to", //opcional
    "fields", //opcional
    "limit", //opcional
    "skip", //opcional
    "order", //opcional
    "keywords", //opcional
    "skip_keywords" //opcional
}
{
    "id_transaction", //opcional
    "id_account", //opcional
    "id_credential", //opcional
    "id_site", //opcional
    "id_site_organization", //opcional
    "id_site_organization_type", //opcional
    "is_disable", //opcional
    "dt_refresh_from", //opcional
    "dt_refresh_to", //opcional
    "dt_transaction_from", //opcional
    "dt_transaction_to", //opcional
    "keywords", //opcional
    "skip_keywords" //opcional
}

Consulta las transacciones de un usuario específico

let transactions = await Sync.run(
  {token: token}, 
  '/transactions', 
  {
    id_credential: id_credential, 
    limit: 5
  }, 
  'GET'
);

Devuelve:

[
  {
    "id_transaction": "5b64940bcaaf237edf60ce7a",
    "id_account": "5703f88223428348328b45db",
    "id_account_type": "520d3aa93b8e778e0d000000",
    "id_credential": "5e1d5734e849507b770c5007",
    "id_currency": "523a25953b8e77910e8b456c",
    "id_disable_type": "5bcff1e77d8b6b44380f6da2",
    "id_external": "",
    "id_site": "56cf5728784806f72b8b4568",
    "id_site_organization": "56cf4ff5784806152c8b4567",
    "id_site_organization_type": "56cf4f5b784806cf028b4568",
    "id_user": "5df7e5f40437a90a8d5037a0",
    "is_account_disable": 0,
    "is_deleted": 0,
    "is_disable": 1,
    "is_pending": 0,
    "description": "ACME Checking Transaction 20",
    "amount": 26,
    "currency": "MXN",
    "attachments": [],
    "extra": null,
    "reference": null,
    "keywords": null,
    "dt_transaction": 1533099600,
    "dt_refresh": 1561500261,
    "dt_disable": 1561500261,
    "dt_deleted": null
  },
  {
      "id_transaction": "5b686fd6caaf237ddc20304a",
      "id_account": "5703f88223428348328b45db",
      "id_account_type": "520d3aa93b8e778e0d000000",
      "id_credential": "5e1d5734e849507b770c5007",
      "id_currency": "523a25953b8e77910e8b456c",
      "id_disable_type": "5bcff1e77d8b6b44380f6da2",
      "id_external": "",
      "id_site": "56cf5728784806f72b8b4568",
      "id_site_organization": "56cf4ff5784806152c8b4567",
      "id_site_organization_type": "56cf4f5b784806cf028b4568",
      "id_user": "5df7e5f40437a90a8d5037a0",
      "is_account_disable": 0,
      "is_deleted": 0,
      "is_disable": 1,
      "is_pending": 0,
      "description": "ACME Checking Transaction 20",
      "amount": 49,
      "currency": "MXN",
      "attachments": [],
      "extra": null,
      "reference": null,
      "keywords": null,
      "dt_transaction": 1533099600,
      "dt_refresh": 1559007370,
      "dt_disable": 1559007370,
      "dt_deleted": null
  },
  .
  .
  .
]

Consulta el número de transacciones dados algunos parámetros de búsqueda

let countTransactions = await Sync.run(
  {token: token}, 
  '/transactions/count', 
  {id_credential: id_credential}, 
  'GET'
);

Devuelve:

{
  "count": 140
}

Webhooks

Un Webhook es una devolución de llamada HTTP a un URL especificado. Ellos se activan cada vez que se actualizan los datos de sincronización para ayudarle a mantenerse al día con los últimos cambios.

{ api_key: API_KEY }
{}
{
    "url", 
    "events" //["credential_create","credential_update","refresh"]
}
{}

Crear Webhook

const webhook_endpoint = 'http://mydomain.com/algun_endpoint'; // Tu endpoint donde recibiras la devolución de llamada
let response = Sync.run(
  {api_key: API_KEY}, 
  '/webhooks', 
  {
      url: webhook_endpoint, 
      events: ["credential_create","credential_update","refresh"]
  }, 
  'POST'
);

Devuelve:

{
   "id_webhook":"5e17c4746cee651e7b03df34",
   "id_user":null,
   "events":[
      "credential_create",
      "credential_update",
      "refresh"
   ],
   "url":"http://8e763e9e.ngrok.io/webhook",
   "delay":0,
   "dt_created":1578615924,
   "dt_modified":null
}

Consultar Webhooks

let response = Sync.run(
  {api_key: API_KEY}, 
  '/webhooks', 
  {}, 
  'GET'
);

Devuelve:

[
   {
      "id_webhook":"5e17c4746cee651e7b03df34",
      "id_user":null,
      "is_disabled":0,
      "events":[
         "credential_create",
         "credential_update",
         "refresh"
      ],
      "url":"http://8e763e9e.ngrok.io/webhook",
      "delay":0,
      "ct_failed":0,
      "dt_created":"2020-01-10T00:25:24+00:00",
      "dt_modified":null
   }
]

Eliminar Webhook

let response = Sync.run(
  {api_key: API_KEY}, 
  `/webhooks/${id_webhook}`, 
  {}, 
  'DELETE'
);

Devuelve:

{
   "rid":"faea7aad-5db5-4d8e-b0c3-57a975c18ea2",
   "code":200,
   "errors":null,
   "status":true,
   "message":null,
   "response":true
}

Archivos adjuntos (Attachments)

Los archivos adjuntos son archivos que están relacionados con las cuentas o las transacciones. La disponibilidad y el tipo de archivo adjunto varía de acuerdo a la fuente.

{token: TOKEN}
{
    "id_account", //opcional
    "id_attachment_type", //opcional
    "id_credential", //opcional
    "id_transaction", //opcional
    "is_valid", //opcional
    "dt_refresh_from", //opcional
    "dt_refresh_to", //opcional
    "fields", //opcional
    "limit", //opcional
    "skip", //opcional
    "order", //opcional
    "keywords", //opcional
    "skip_keywords" //opcional
}
{
  "id_account", //opcional
  "id_attachment_type", //opcional
  "id_credential", //opcional
  "id_transaction", //opcional
  "is_valid", //opcional
  "dt_refresh_from", //opcional
  "dt_refresh_to", //opcional
  "keywords", //opcional
  "skip_keywords" //opcional
}
{}
{}

Consulta los archivos adjuntos de un usuario específico

let attachments = Sync.run(
  {token: token}, 
  '/attachments', 
  {
    id_credential: id_credentia, 
    limit: 10
  }, 
  'GET'
);

Devuelve:

[
   {
      "id_attachment":"5db073b4caaf236a6a4c2eb5",
      "id_account":"5db073b1caaf236a6a4c2acc",
      "id_user":"5e17c430b021255889294af7",
      "id_external":"",
      "id_attachment_type":"56bcdfca784806d1378b4567",
      "id_transaction":"5db073b1caaf236a6a4c2acd",
      "is_valid":1,
      "file":"4B2B511C-A29E-4CDF-8AD3-143515CF6152.xml",
      "mime":null,
      "url":"/attachments/5db073b4caaf236a6a4c2eb5",
      "keywords":[
         "3.3",
         "emitidas",
         "i",
         "timbrefiscaldigital",
         "vigente"
      ],
      "dt_refresh":1571844997
   },
   {
      "id_attachment":"5db073b4caaf236a6a4c2eb6",
      "id_account":"5db073b1caaf236a6a4c2acc",
      "id_user":"5e17c430b021255889294af7",
      "id_external":"",
      "id_attachment_type":"56bcdfca784806d1378b4567",
      "id_transaction":"5db073b1caaf236a6a4c2ace",
      "is_valid":1,
      "file":"27D33E8C-0120-4F98-ACCD-1C0DBA9D794F.xml",
      "mime":null,
      "url":"/attachments/5db073b4caaf236a6a4c2eb6",
      "keywords":[
         "001",
         "002",
         "3.3",
         "i",
         "impuestos",
         "recibidas",
         "retenciones",
         "timbrefiscaldigital",
         "traslados",
         "vigente"
      ],
      "dt_refresh":1571844997
   },
   .
   .
   .
]

Regresa el archivo adjunto

let attachment = attachments[0].attachments[0];
let documentAttached = Sync.run(
  {token: token}, 
  attachment.url, 
  {}, 
  'GET'
);

Devuelve:

<?xml version="1.0" encoding="utf-8"?>
<cfdi:Comprobante xmlns:cfdi="http://www.sat.gob.mx/cfd/3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv33.xsd" Version="3.3" Serie="C" Folio="78" Fecha="2019-01-24T06:15:49" FormaPago="99" NoCertificado="0000100000040090000" Certificado="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" SubTotal="810.18" Descuento="0.00" Moneda="MXN" Total="810.18" TipoDeComprobante="I" MetodoPago="PUE" LugarExpedicion="00000" Sello="CjGJ6Uz6jWQ6wFyn8SEvRVCOCZq2sRtTAsUkLJjrs8vPSHfeEs+bMBhNnZ+7gLE5gSO+FU+IA64d+I9w98DEop24GRNDoWPxRGvX7SON4p47Ygna/rCWynyjCw8kYqRtBHxypwh0HGFLoNx+ulK+WcOXG7F3Nx2I+EPTg6jn1VvwBm1c1iat1Zgnhcna2ZJyZA3cRFOBhNONocr+qAF8zTtHSoJNYmolOlyIC9akyIPfrNl/ALgni4k1KwpEcr4HsyqVabUDW47vH5TqSNfFz+ZY3bZZZf7FLdTBn8So984+vbomWg/rP7OCBALI/u/+kIkgotm4TF/ImuGjUeKITw==">
    <cfdi:Emisor Rfc="ACM010101ABC" Nombre="ACME CORP" RegimenFiscal="601"/>
    <cfdi:Receptor Rfc="EKU9003173C9" Nombre="ESCUELA KEMPER URGATE SA DE CV" UsoCFDI="P01"/>
    <cfdi:Conceptos>
        <cfdi:Concepto ClaveProdServ="00195316" Cantidad="1" ClaveUnidad="H87" Unidad="PZA" Descripcion="PRODUCTO 1" ValorUnitario="810.18" Importe="810.18" Descuento="0"></cfdi:Concepto>
    </cfdi:Conceptos>
    <cfdi:Complemento>
        <tfd:TimbreFiscalDigital xmlns:tfd="http://www.sat.gob.mx/TimbreFiscalDigital" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sat.gob.mx/TimbreFiscalDigital http://www.sat.gob.mx/sitio_internet/cfd/timbrefiscaldigital/TimbreFiscalDigitalv11.xsd" Version="1.1" UUID="4B2B511C-A29E-4CDF-8AD3-143515CF6152" FechaTimbrado="2019-10-11T02:43:34" SelloCFD="CjGJ6Uz6jWQ6wFyn8SEvRVCOCZq2sRtTAsUkLJjrs8vPSHfeEs+bMBhNnZ+7gLE5gSO+FUz6jWQ6wFyn8SEvRVCOCZq2sWPxRGvX7SON4p47Ygna/rCWynyjCw8kYqRtBHxypwh0HGFLoNx+ulK+WcOXG7F3Nx2I+EPTg6jn1Vvz6jWQ6wFyn8SEvRVCOCZq2s3cRFOBhNONocr+qAF8zTtHSoJNYmolOlyIC9akyIPfrNl/ALgni4k1KwpEcr4HsyqVabz6jWQ6wFyn8SEvRVCOCZq2sf7FLdTBn8So984+vbomWg/rP7OCBALI/u/+kIkgotm4TF/ImuGjUeKITw==" NoCertificadoSAT="00001000000407657133" SelloSAT="W82etl3ZwAEDP7qT705tkK7jryQU5WCFUIOw1nmDyy5/iaxsOVuDPVyhK7fQMRG6A6x9WHGYjkMDZ0DkOnq1vcClr2Sn5yOLdWd9VYf6hg6e/RiLTn1mSUni/47rWNbyODfcom3hmKasclgBEYZL6unymQD2bsUfMc0L5ODZ5/AfK36/bYVeakauL1NxXMZ2Zc4RrX5Zd5AkF04VB6UWqDL2/zuCGDccA6/MsJR2BeXnq/hQ1I8WNSNGcy1OzBukQqRbhe9hIRit58F/ZtTtFnzyeT3Tknu9MIZFq/7D+tw0TxUziC+g2n86iiKRXnRJQvlowqKmkPGO8jMefrx8pg==" RfcProvCertif="ACM100625MC0"/>
    </cfdi:Complemento>
</cfdi:Comprobante>

Regresa la información extraída del archivo adjunto

let attachment = attachments[0].attachments[0];
let infoExtra = Sync.run(
  {token: token}, 
  `${attachment.url}/extra`,
  {}, 
  'GET'
);

Devuelve:

{
    "id_attachment": "5db073b4caaf236a6a4c2eb5",
    "id_user": "5df7e5f40437a90a8d5037a0",
    "id_external": "",
    "is_valid": 1,
    "file": "4B2B511C-A29E-4CDF-8AD3-143515CF6152.xml",
    "mime": null,
    "extra": [
        {
            "n": "CFDI:COMPROBANTE",
            "a": {
                "XMLNS:CFDI": "http://www.sat.gob.mx/cfd/3",
                "XMLNS:XSI": "http://www.w3.org/2001/XMLSchema-instance",
                "XSI:SCHEMALOCATION": "http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv33.xsd",
                "VERSION": "3.3",
                "SERIE": "C",
                "FOLIO": "78",
                "FECHA": "2019-01-24T06:15:49",
                "FORMAPAGO": "99",
                "NOCERTIFICADO": "0000100000040090000",
                "CERTIFICADO": "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",
                "SUBTOTAL": "810.18",
                "DESCUENTO": "0.00",
                "MONEDA": "MXN",
                "TOTAL": "810.18",
                "TIPODECOMPROBANTE": "I",
                "METODOPAGO": "PUE",
                "LUGAREXPEDICION": "00000",
                "SELLO": "CjGJ6Uz6jWQ6wFyn8SEvRVCOCZq2sRtTAsUkLJjrs8vPSHfeEs+bMBhNnZ+7gLE5gSO+FU+IA64d+I9w98DEop24GRNDoWPxRGvX7SON4p47Ygna/rCWynyjCw8kYqRtBHxypwh0HGFLoNx+ulK+WcOXG7F3Nx2I+EPTg6jn1VvwBm1c1iat1Zgnhcna2ZJyZA3cRFOBhNONocr+qAF8zTtHSoJNYmolOlyIC9akyIPfrNl/ALgni4k1KwpEcr4HsyqVabUDW47vH5TqSNfFz+ZY3bZZZf7FLdTBn8So984+vbomWg/rP7OCBALI/u/+kIkgotm4TF/ImuGjUeKITw=="
            },
            "c": [
                {
                    "n": "CFDI:EMISOR",
                    "a": {
                        "RFC": "ACM010101ABC",
                        "NOMBRE": "ACME CORP",
                        "REGIMENFISCAL": "601"
                    }
                },
                {
                    "n": "CFDI:RECEPTOR",
                    "a": {
                        "RFC": "EKU9003173C9",
                        "NOMBRE": "ESCUELA KEMPER URGATE SA DE CV",
                        "USOCFDI": "P01"
                    }
                },
                {
                    "n": "CFDI:CONCEPTOS",
                    "c": [
                        {
                            "n": "CFDI:CONCEPTO",
                            "a": {
                                "CLAVEPRODSERV": "00195316",
                                "CANTIDAD": "1",
                                "CLAVEUNIDAD": "H87",
                                "UNIDAD": "PZA",
                                "DESCRIPCION": "PRODUCTO 1",
                                "VALORUNITARIO": "810.18",
                                "IMPORTE": "810.18",
                                "DESCUENTO": "0"
                            }
                        }
                    ]
                },
                {
                    "n": "CFDI:COMPLEMENTO",
                    "c": [
                        {
                            "n": "TFD:TIMBREFISCALDIGITAL",
                            "a": {
                                "XMLNS:TFD": "http://www.sat.gob.mx/TimbreFiscalDigital",
                                "XMLNS:XSI": "http://www.w3.org/2001/XMLSchema-instance",
                                "XSI:SCHEMALOCATION": "http://www.sat.gob.mx/TimbreFiscalDigital http://www.sat.gob.mx/sitio_internet/cfd/timbrefiscaldigital/TimbreFiscalDigitalv11.xsd",
                                "VERSION": "1.1",
                                "UUID": "4B2B511C-A29E-4CDF-8AD3-143515CF6152",
                                "FECHATIMBRADO": "2019-10-11T02:43:34",
                                "SELLOCFD": "CjGJ6Uz6jWQ6wFyn8SEvRVCOCZq2sRtTAsUkLJjrs8vPSHfeEs+bMBhNnZ+7gLE5gSO+FUz6jWQ6wFyn8SEvRVCOCZq2sWPxRGvX7SON4p47Ygna/rCWynyjCw8kYqRtBHxypwh0HGFLoNx+ulK+WcOXG7F3Nx2I+EPTg6jn1Vvz6jWQ6wFyn8SEvRVCOCZq2s3cRFOBhNONocr+qAF8zTtHSoJNYmolOlyIC9akyIPfrNl/ALgni4k1KwpEcr4HsyqVabz6jWQ6wFyn8SEvRVCOCZq2sf7FLdTBn8So984+vbomWg/rP7OCBALI/u/+kIkgotm4TF/ImuGjUeKITw==",
                                "NOCERTIFICADOSAT": "00001000000407657133",
                                "SELLOSAT": "W82etl3ZwAEDP7qT705tkK7jryQU5WCFUIOw1nmDyy5/iaxsOVuDPVyhK7fQMRG6A6x9WHGYjkMDZ0DkOnq1vcClr2Sn5yOLdWd9VYf6hg6e/RiLTn1mSUni/47rWNbyODfcom3hmKasclgBEYZL6unymQD2bsUfMc0L5ODZ5/AfK36/bYVeakauL1NxXMZ2Zc4RrX5Zd5AkF04VB6UWqDL2/zuCGDccA6/MsJR2BeXnq/hQ1I8WNSNGcy1OzBukQqRbhe9hIRit58F/ZtTtFnzyeT3Tknu9MIZFq/7D+tw0TxUziC+g2n86iiKRXnRJQvlowqKmkPGO8jMefrx8pg==",
                                "RFCPROVCERTIF": "ACM100625MC0"
                            }
                        }
                    ]
                }
            ]
        }
    ]
}

Entorno

  1. NodeJs: 11.5.0
  2. NPM: 6.7.0
  3. Request: 2.88.0
  4. Request-promise: 4.2.5

Enlaces de interes

  1. Documentación oficial de Paybook Sync.
  2. Parametros para cada recurso.
  3. Códigos de respuesta y su significado.
  4. Consumiendo el API REST de Sync vía Postman paso a paso. Ampliamente recomendado para entender la estructura de una cuenta de Paybook Sync.

Comentarios y aportes

¡Sientete con la confianza de hacer un pull request! :ok_hand:


Made with :blue_heart: by Paybook family.

1.0.0

4 years ago