Skip to main content

Tupana Link

El widget que abres en tu app para que tu usuario final conecte su empresa. La clave del SII (o del facturador, o del banco) viaja a Tupana. Tu backend nunca la ve. En v2 la clave no se manda por API: conectas con este widget y guardas el connection_id (cred_…), que es lo único que tu SaaS conoce de la empresa.
Tupana Link — SII gratuito

Esto ve tu usuario. Tú solo recibes el cred_….

Integra en tres llamadas

1

Tu backend abre una sesión

POST /api/v2/connect-sessions/ con tu API key. Te devuelve un client_token de 30 minutos. Si ya conoces el RUT, mándalo como tax_id y el widget no lo vuelve a pedir.
2

Tu frontend abre el widget

Iframe o ventana. El token es el client_token. tax_id en la URL gana sobre el de la sesión.
Igual que el widget de Fintoc: success y exit solo mueven tu interfaz. La conexión existe cuando tu backend recibe connection.active o GET /api/v2/connections/enrollments/{enrollment_id}/ la muestra lista.
3

Tu backend guarda la conexión

Cuando el SII valida la clave, el webhook trae el cred_…. Con eso emites. También puedes listarlas con GET /connections/.

Body de la sesión

Query del widget

El client_token es de un solo uso y dura 30 minutos. Créalo cuando el usuario va a conectar, no antes. Una API key de sandbox no abre producción.

Lo que ve tu usuario

Widget: RUT de la empresa
  1. RUT de la empresa — no aparece si mandaste tax_id.
Widget: SII gratuito
  1. Detectamos SII. El RUT del representante se formatea solo.

Cuándo el enrolamiento es exitoso

El widget de Fintoc no avisa éxito al recibir la clave. Se queda en pantalla mientras el banco responde. Si la clave está mala, el error queda adentro y el usuario reintenta: no hay onSuccess. onSuccess sale cuando el flujo terminó (el banco aceptó y existe el Link). onExit sale solo si la persona cierra antes. Fintoc pide no usar esos callbacks para saber si el Link existe: eso lo confirma el webhook link.created en el webhookUrl, que trae el link_token. Tupana Link funciona igual. El postMessage mueve tu modal. El webhook dice si la credencial quedó.

SII

El login no termina en el request. La respuesta trae status: "connecting" y un enrollment_id (cenr_…). El widget espera en ws/connect/{client_token}/ y manda success solo con valid.
Puedes esperar el webhook o consultar GET /api/v2/connections/enrollments/{enrollment_id}/ hasta valid, invalid o error.

Banco

El widget no manda success cuando guarda la clave. Se queda en “estamos leyendo tus cuentas” hasta que el banco contesta.
  • El banco aceptó y hay cuentas: el widget las muestra y ahí manda success con el cred_…. Tu backend recibe connection.active.
  • La clave es inválida: el error queda en el widget, el usuario puede corregirla, y no hay success. Tu backend recibe connection.requires_action.
  • El usuario cierra antes: exit. Eso no confirma la conexión. Si el banco igual acepta la clave, llega connection.active.
Guardar la clave con estado interno VALID no es la confirmación. La confirmación es connection.active, cuando el banco ya listó las cuentas. Los movimientos no vienen en ese aviso. Cuando la cartola está sincronizada se leen como documentos tipo 100: GET /api/v2/documents/?master_entity_id={empresa}&dte_type__code__in=100. Responde 2xx al webhook y procesa después. Puede llegarte dos veces. Para ver o cortar conexiones usa GET /connections/ y DELETE /connections/{connection_id}/, que la deja inactive y suelta la clave.

Qué viaja por tu app