Skip to main content

Consume Paybook Sync REST API without pain

Project description

Sync-Paybook-logo

SYNC-PY

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. Instalar mediante composer
  pip install sync-py

Requerimientos

  1. API Key:

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

api_key = 7767a4a04f990e9231bafc949e8ca08a

Al crear tu cuenta se te proporcionan dos API Keys: Producción & Sandbox. Las cuales tienen el mismo proposito, ambas nos permiten implementar Paybook Sync, pero Sandbox nos permite hacerlo sin la necesidad de tener credenciales reales de bancos o el SAT.

Este API key lo podemos visualizar como la contraseña o llave de acceso a los servicios de Paybook Sync. Solamente a través de ella podremos empezar a interactuar con las instituciones que sincronicemos.

Nota: Pasar de una API key a otra es tan sensillo como escribir la nueva API key correspondiente.

2.Webhook

Opcional pero altamente recomendable para lograr una integración completa de las funcionalidades de Paybook Sync.

Modelo de información

El modelo de información de Paybook Sync es bastante sencillo. Prácticamente podemos visualizar al API key como el elemento raíz del modelo, del cual se desglosan los usuarios, pero entendamos como usuarios a aquellas entidades (personas o empresas) a las cuales se les desea sincronizar las instituciones financieras que el servicio de Paybook Sync facilita, podemos apreciarlo gráficamente en este diagrama:

sync-model-image

Hay que mencionar la diferencia entre un usuario de Paybook Sync (usted, el developer) y un usuario del API key: Por cada usuario de Paybook Sync, hay un API key y cada API key puede tener N usuarios.

Users (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.

Catalogs/Sites (Catálogos)

Los catálogos son colecciones de endpoints que son importantes para la clasificación de otros endpoints. Dentro de estos se encuentran los sitios que nos permite consultar los sitios financieros disponibles para sincronizar a través de Paybook Sync.

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.

Es necesario tener al menos un usuario registrado para crear credenciales.

Accounts (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.

Transactions (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.

Attachments (Archivos Adjuntos)

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.

En Resumen:

A partir de los usuarios podemos crear credenciales, las cuales son únicas por cada usuario e institución. Una vez creada una credencial automáticamente se crea una cuenta correspondiente, esto permite manejar fácilmente diferentes cuentas de un mismo usuario de una misma institución.

Por último pero no menos importante, se encuentran las transacciones que dependen de su respectiva cuenta, algunas transacciones vienen con un documento el cual llamaremos Attachments o mejor dicho “documentos adjuntos”, los cuales son el último recurso en el modelo de de información de Paybook Sync.

Implementación

La librería

Incluye la librería y declara tu API Key.

from sync import Sync
from dotenv import load_dotenv

API_KEY = {
    'api_key': getenv('API_KEY') # Tu API_KEY aquí
}

¡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, es ideal para administrar la configuración de la aplicación durante el desarrollo y la producción utilizando principios de 12-factor

La librería incluye los métodos:

  • Sync.auth()
# Crear una sesión para un usuario
token = Sync.auth(
  API_KEY, # Tu API KEY
  {"id_user": id_user} # ID de ususario
)

Nota: Para realizar la autenticación es necesario tener creado un usuario, de donde se obtiene el id_user, vease este ejemplo.

  • Sync.run()
# Consumir un recurso de Sync
response = Sync.run(
  token, # Autenticación
  "/credentials", # Recurso
  None, # Parametros
  'GET' # Método HTTP
)

Y hace uso los siguientes métodos de HTTP:

Metodo Acción
GET Consultar
POST Crear
PUT Actualizar
DELETE Eliminar

Dependiendo del recurso y la acción a realizar, será el método de la librería, el método de HTTP y el elemento de autenticación (se explica en la sección de autenticación) a usar.

Puedes ver más acerca de cada uno en recursos y ejemplos.

Implementación de un Webhook

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 ayudarte a mantenerte al día con los últimos cambios en la información.

La ventaja principal es que te permite recibir las últimas actualizaciones de credenciales, transacciones y attachments directamente en tu aplicación sin necesidad de estar preguntando constantemente por ellas.

Para fines prácticos de desarrollo usaremos el servicio de ngrok, el cual nos permite crear URLs públicas para exponer nuestro servidor local a través de internet. Puedes consultar cómo instalarlo en su página de descargas.

Ahora crearemos un servidor sencillo con python y Flask.

Cabe mencionar que se hace uso de estas tecnologías con fines ilustrativos y el desarrollador es libre de implementar las que crea más convenientes.

Creando un archivo al que llamaremos server.py e incluiremos el siguiente código:

from flask import Flask, request
app = Flask(__name__)

@app.route('/webhook', methods=['POST'])
def webhook():
    if request.method == 'POST':
        return 'Hello from my webhook!'

Habiendo terminado lo anterior, instalamos Flask con el comando pip install Flask y luego iniciamos el servidor con los siguientes comandos:

export FLASK_APP=server.py
flask run

Warning: The built-in web server was designed to aid application development. It may also be useful for testing purposes or for application demonstrations that are run in controlled environments. It is not intended to be a full-featured web server. It should not be used on a public network.

Por último ejecutamos ngrok con el comando: <path-to>/ngrok http 5000 y tendremos nuestro servidor listo escuchando por actualizaciones del webhook.

La URL que nos proporcione ngrok es la misma que tendrás que mandar cuando creas un webhook como en este ejemplo.

Nota: ngrok solo debe ser usado durante el desarrollo y no se recomienda usarlo de esta forma en producción.

Sync Widget

El widget de Sync se puede usar para crear, actualizar y activar la sincronización de credenciales de forma sencilla con pocas líneas de código desde tu Front-end. Visita el repositorio oficial y la documentación oficial para implementarlo, ampliamente recomendado.

La ventaja principal es que te brinda una poderosa interfaz que te permite ahorrar pasos en la implementación.

Autenticación

En el API de Paybook Sync hay dos elementos de autenticación: API KEY & TOKEN.

  • API KEY: Es la llave maestra que se le otorga a un desarrollador cuando se registra en Paybook Sync, como se muestra en el apartado de requerimientos.

  • Token: El token es una llave de operación volátil, caduca luego de cinco minutos de inactividad, su alcance se limita a nivel User y fue diseñada para realizar operaciones a nivel FrontEnd. Va ligado directamente a un usuario y únicamente puede consultar o actualizar la información de éste (a diferencia de la API key con la que puedes consultar todo). Prácticamente es una combinación de tu API key y un usuario.

Por razones de seguridad se recomienda ampliamente utilizar el Token ya que así limitas el acceso de información solamente al usuario correspondiente.

Todas las peticiones al API de Paybook Sync deben ir autenticadas, dependerá del recurso con el que se va a operar la llave de autenticación a utilizar.

Recurso Auth
Usuarios API KEY
Webhooks API KEY
Catalogs Token
Credentials Token
Accounts Token
Transactions Token
Attachments Token

Obtener un Token de sesión:

token = Sync.auth(
  API_KEY, # Tu API KEY
  {"id_user": id_user} # ID de ususario
)

Respuesta:

  print(token)
  # Imprime: { token: "d5b33dcf996ac34fd2fa56782d72bff6"}

Puedes ver más acerca de cada uno en recursos y ejemplos.

Flujo de Información

En este apartado veremos un ejemplo del flujo ideal para obtener la información desde el API de Paybook Sync, aunque las posibilidades son muchas, este es el caso ideal para hacernos con la información.

data-flow-img

Para este punto, si decidiste hacer uso del Sync Widget, te habrás ahorrado los pasos 2, 3 y 4.

Los pasos en el diagrama son los siguientes:

  1. Crea un usuario. (ver ejemplo)
  2. Consulta los sitios y selecciona el sitio que deseas sincronizar. (ver ejemplo)
  3. Crea una credencial para ese usuario y sitio. (ver ejemplo)
  4. Monitorea el estatus de la nueva credencial. (ver ejemplo)
  5. Crea un webhook nuevo, indica un Endpoint en tu aplicación donde esperas las actualizaciones). (ver ejemplo)
  6. Espera y procesa las actualizaciones que recibas de Sync.
  7. Consulta la nueva información disponible en el recurso respectivo.

Recursos y Ejemplos

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

Usuarios

Recurso Acción Método Autenticación Parametros
/users Consulta usuarios para esa API Key GET
{ api_key: API_KEY }
{
    "id_external", // Opcional
    "fields", // Opcional
    "limit", // Opcional
    "skip", // Opcional
    "order" // Opcional
}
Crea un usuario nuevo POST
{
  "id_external", // Opcional
  "name"
}
/users/:id_user Actualiza un usuario PUT
Elimina un usuario DELETE {}

Consultar usuarios

response = Sync.run(
  API_KEY, 
  '/users', 
  None, 
  '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

response = Sync.run(
    API_KEY, 
    '/users', 
    {'id_external': 'KEMONITO09'}, 
    'GET'
)

Devuelve:

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

Crear un Usuario

response = Sync.run(
  API_KEY, 
  '/users', 
  {
      "id_external": 'MIST030794',
      "name": 'Rey Misterio'
  }, 
  'POST'
)
id_user = response['id_user']

Devuelve:

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

Actualizar un Usuario

response = Sync.run(
  API_KEY,
  f"/users/{id_user}", 
  {"name":  'Rey Misterio 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.

response = Sync.run(
  API_KEY,
  f"/users/{id_user}", 
  {},
  'DELETE'
)

Devuelve:

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

Catálogos

Recurso Acción Método Autenticación Parametros
/catalogues/account_types Consultar los tipos de cuentas GET
{ token: TOKEN }
{
    "fields", // opcional
    "limit", // opcional
    "skip", // opcional
    "order", // opcional
}
/catalogues/attachment_types Consulta los tipos de archivos adjuntos
/catalogues/countries Consulta los países disponibles
/catalogues/sites Consulta los sitios disponiles
{
  "id_site", //opcional
  "id_site_organization", //opcional
  "id_site_organization_type", //opcional
  "fields", //opcional
  "limit", //opcional
  "skip", //opcional
  "order", //opciona
}
/catalogues/site_organizations Consulta las organizaciones del sitio
/catalogues/organizations/sites Consulta los sitios agrupados por organización del sitio
{
  "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.

response = Sync.run(
  token,
  "/catalogues/sites", 
  None
  '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

Recurso Acción Método Autenticación Parametros
/credentials Consulta credenciales registradas GET
{ token: TOKEN }
{}
Crea o actualiza credenciales POST
{
  "id_site",
  "credentials"
}
/credentials/:id_credential Elimina un usuario DELETE
{}
/jobs/:id_job/status Consulta historial de cambios hechos a estas credenciales (últimos 15 días) GET

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.

Credenciales normales

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

  1. Crear credenciales normal
# Consultar catálogos
payload = {'id_site': "5da784f1f9de2a06483abec1"}
response = Sync.run(
  token,
  "/catalogues/sites", 
  payload,
  'GET'
)
site = response[0]    
print(site)
""" 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"
}
"""
# Crear credenciales
credentials = {}
credentials[site['credentials'][0]['name']] = 'ACM010101ABC'
credentials[site['credentials'][1]['name']] = 'test'
payload['credentials'] = credentials
response = Sync.run(
  token,
  "/credentials", 
  payload,
  'POST'
)

Devuelve:

{
   "id_credential":"5e17c432d7288d358a039141",
   "id_job_uuid":"5e17c4325d4f6077171c0253",
   "id_job":"5e17c4325d4f6077171c0254",
   "is_new":1,
   "username":"A**********C",
   "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"
}
  1. Monitoreo del estado de la credencial
# Consultar credenciales
response = Sync.run(
  token,
  "/credentials", 
  None,
  '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":"A**********C",
      "code":200,
      "keywords":null,
      "dt_authorized":1578615866,
      "dt_execute":1578615858,
      "dt_ready":1578702266,
      "dt_refresh":null
   }
]

Credenciales TWOFA

  1. Consulta el sitio Twofa del catálogo
# Consultar catálogos
payload = {"id_site": "56cf5728784806f72b8b4569"}
response = Sync.run(
  token,
  "/catalogues/sites", 
  payload,
  'GET'
)
  1. Crea las credencials
# Crear credenciales con Token o Autenticación de dos pasos
twofaSite = response[0]
credentials = {}
credentials[twofaSite['credentials'][0]['name']] = 'test'
credentials[twofaSite['credentials'][1]['name']] = 'test'
payload['credentials'] = credentials
response = Sync.run(
  token,
  "/credentials", 
  payload,
  'POST'
)
twofaCredential = response
""" 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
id_job = twofaCredential['id_job']
response = Sync.run(
  token,
  f"/jobs/{id_job}/status", 
  None,
  '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"
          }
      ]
  }
] """
is_twofa = False
if(response[len(response)-1]['code'] == 410):
  is_twofa = True
  1. Manda el TWOFA
# Manda TWOFA
twofa_token = {"twofa" :  {} }
twofa = response[2]['twofa']
for element in twofa:
  name = element['name']
  twofa_token["twofa"][name] = "123456"

twofa_response = Sync.run(
  token,
  f"/jobs/{id_job}/twofa", 
  twofa_token, 
  'POST'
)   

response = Sync.run(
  token,
  f"/jobs/{id_job}/status", 
  None,
  'GET'
)
""" Regresa:
{
  rid: "ea1e848d-6ec2-454d-b296-0fe2b6c958c2",
  code: 200,
  errors: null,
  status: true,
  message: null,
  response: true
} """
  1. Consulta nuevamente el status
id_job = twofaCredential['id_job']
response = Sync.run(
  token,
  f"/jobs/{id_job}/status", 
  None,
  '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
  }
] """

NOTA: El uso del Sync Widget nos ahorra completamente tener que lidiar con este escenario ya que nos proporciona toda la interfaz para realizar los retos de Twofa, en este ejemplo se usa Acme Sandbox pero ya en producción, los campos a enviar varían de institución a institución en el Twofa Challenge.

Consultar credenciales

response = Sync.run(
  token,
  "/credentials", 
  None,
  '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
   }
]

Eliminar una credencial

id_credential = satCredential['id_credential']
response = Sync.run(
  token,
  f"/credentials/{id_credential}", 
  None,
  '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)
id_job = satCredential['id_job']
response = Sync.run(
  token,
  f"/jobs/{id_job}/status", 
  None,
  'GET'
)

Devuelve:

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

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

Cuentas

Recurso Acción Método Autenticación Parametros
/accounts Consulta las cuentas de un usuario específico GET
{ 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

response = Sync.run(
  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

Recurso Acción Método Autenticación Parametros
/transactions Consulta las transacciones de un usuario específico GET
{ 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
}
/transactions/count Consulta el número de transacciones dados algunos parámetros de búsqueda GET
{
    "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

response = Sync.run(
  token,
  "/transactions", 
  {
    "id_credential": id_credential,
    "limit": 1
  },
  '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

response = Sync.run(
  token,
  "/transactions/count", 
  {"id_credential": satCredential['id_credential']},
  'GET'
)

Devuelve:

{
  "count": 140
}

Webhooks

Recurso Acción Método Autenticación Parametros
/webhooks Consulta los webhooks creados GET
{ api_key: API_KEY }
{}
Crear o actualizar un webhhook POST
{
    "url", 
    "events" //["credential_create","credential_update","refresh"]
}
Eliminar un webhhook DELETE
{}

Crear Webhook

response = Sync.run(
  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

# Consultar Webhook
response = Sync.run(
  API_KEY,
  "/webhooks", 
  None,
  '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

# Eliminar Webhook
response = Sync.run(
  API_KEY,
  f"/webhooks/{id_webhook}", 
  None,
  'DELETE'
)

Devuelve:

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

Archivos adjuntos (Attachments)

Recurso Acción Método Autenticación Parametros
/attachments Consulta los archivos adjuntos de un usuario específico GET
{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
}
/attachments/count Consultar el número de archivos adjuntos
{
  "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
}
/attachments/:id_attachment Regresa el archivo adjunto
{}
/attachments/:id_attachment/extra Regresa la información extraída del archivo adjunto
{}

Consulta los archivos adjuntos de un usuario específico

response = Sync.run(
  token,
  "/attachments", 
  {
      "id_credential": satCredential['id_credential'],
      "limit": 1
  },
  '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

attachment = response[0]
attachmentUrl = attachment['url']
response = Sync.run(
  token,
  attachmentUrl, 
  None,
  '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

attachment = response[0]
attachmentUrl = attachment['url']
response = Sync.run(
  token,
  attachmentUrl+"/extra", 
  None,
  '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

Versions used by the time this file was writted

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

Si crees que algo podría mejorar o no queda completamente claro, haznolos saber, estamos muy atentos a tus comentarios.

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


Made with :blue_heart: by Paybook family.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sync-py-1.0.4.tar.gz (48.9 kB view details)

Uploaded Source

Built Distribution

sync_py-1.0.4-py2.py3-none-any.whl (18.6 kB view details)

Uploaded Python 2 Python 3

File details

Details for the file sync-py-1.0.4.tar.gz.

File metadata

  • Download URL: sync-py-1.0.4.tar.gz
  • Upload date:
  • Size: 48.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/49.2.0 requests-toolbelt/0.9.1 tqdm/4.50.0 CPython/3.8.5

File hashes

Hashes for sync-py-1.0.4.tar.gz
Algorithm Hash digest
SHA256 06822f48761db909de313c9aa94988e80f75510a176cf819239c3559fb513dea
MD5 d7cea63fbb74a44d66ceccfd7a0ba914
BLAKE2b-256 6ae311baf2e2424ab3913dcec08e3c7eee05f080d87acebd6d5d5fbfe0fb68bc

See more details on using hashes here.

File details

Details for the file sync_py-1.0.4-py2.py3-none-any.whl.

File metadata

  • Download URL: sync_py-1.0.4-py2.py3-none-any.whl
  • Upload date:
  • Size: 18.6 kB
  • Tags: Python 2, Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/49.2.0 requests-toolbelt/0.9.1 tqdm/4.50.0 CPython/3.8.5

File hashes

Hashes for sync_py-1.0.4-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 eb0b6be51df778d0e509b356e797116e4f097e7ea51ce92c79ecf17a46ed9a9e
MD5 8a52d333f092e75b2e14c7fcd1d94e8a
BLAKE2b-256 b81a118e63d5dcc4df1eced80cf1adb4d7a33f9b689a02898a4b684fdada4a3b

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page