Dónde encaja esto
Observa lo que Fluz absorbe en medio de ese diagrama: creación de cuenta, inicio de sesión, autenticación de dos factores y verificación de identidad si el usuario aún no ha sido verificado. Tú no construyes nada de eso y nunca ves las credenciales.
Antes de comenzar
1
Tu app está configurada
Permisos seleccionados en la pestaña Permissions, URI de redirección registrado en la pestaña OAuth,
client_id y client_secret en tu almacén de secretos. Consulta Configure OAuth App.2
Tu ruta de callback existe y puede llegar a tu almacén de sesión
Debe leer
state y compararlo contra algo que persististe antes de la redirección.3
Tu pestaña Permissions contiene exactamente los scopes que este flujo necesita
La pantalla de consentimiento se construye a partir de la configuración de tu app, no de la solicitud de authorize. Lo que esté seleccionado en la pestaña Permissions es lo que se le pide aprobar al usuario, así que recórtalo antes de enviar a nadie por el flujo: este es tu paso con mayor deserción y su longitud proviene enteramente de esa pestaña. Consulta Application Scopes para el catálogo completo.
Paso 1 — Construye la URL de authorize
Dirige al usuario al endpoint/authorize con los siguientes parámetros de consulta.
No existe un parámetro
scopes. Versiones anteriores de este flujo aceptaban un parámetro de consulta scopes y lo intersectaban con la configuración de tu app. Ese parámetro ahora se ignora: los permisos que muestra la pantalla de consentimiento se derivan enteramente de la pestaña Permissions de tu app. Quitar scopes de una URL de authorize existente produce una pantalla de consentimiento idéntica — puedes eliminarlo cuando te resulte conveniente.Entornos
Reglas de codificación
Codifica en URL los valores deredirect_uri y external_id. Construye la cadena de consulta con el codificador de URL de tu lenguaje en lugar de concatenación de cadenas y esto se resuelve solo.
Un ejemplo completo en staging:
Lo que ve el usuario
El nombre, el avatar y la descripción de tu app provienen directamente de la pestaña Overview, y las líneas de permisos son tus scopes seleccionados agrupados bajo encabezados legibles. Si esta pantalla se ve incorrecta, la solución está en Configure OAuth App, no en tu código.
La lista de permisos es de solo lectura. El usuario la revisa y acepta el conjunto completo, o no completa la autorización — no hay casillas por scope para excluir ninguno. La selección de cuenta de gasto, cuando tu app la usa, es un control aparte y sigue apareciendo.
Selección de cuenta
Antes de la pantalla de consentimiento, se le puede preguntar al usuario a qué cuenta de Fluz aplica esta autorización: su cuenta personal, una cuenta de empresa existente o una nueva empresa que quiera registrar. Cuál de ellas ocurre depende de la configuración de la app y de las cuentas que el usuario ya tenga. Para una integración solo de consumidor nada cambia: el usuario tiene una sola cuenta, el selector se omite y el flujo se ve exactamente como siempre. Si envíasexternal_id y este ya resuelve a una cuenta de una autorización previa, el selector también se omite.
Si tu app está habilitada para empresas, lee Business Accounts in OAuth antes de construir: la URL de authorize es la misma, pero la cuenta a la que resuelve el código puede no ser la personal del usuario.
Paso 2 — Protege el flujo con state
La tabla de referencia marca state como opcional. En un flujo de autorización basado en redirección es tu única defensa contra que se plante el código de autorización de otra persona en la sesión de tu usuario, así que intégralo desde el primer commit en lugar de agregarlo después.
1
Genera un valor imposible de adivinar
Al menos 128 bits de una fuente criptográficamente segura. No un timestamp, no un ID de usuario, no un contador.
2
Almacénalo del lado del servidor, vinculado a la sesión del navegador
Almacén de sesión, cookie firmada o cache con TTL corto asociada a la sesión. No en una variable global.
3
Compara a la vuelta y rechaza si no coincide
state faltante, no reconocido o ya usado significa abandonar la solicitud — no intercambies el código. Usa una comparación de tiempo constante.4
Consúmelo
Elimínalo tras una coincidencia exitosa para que el mismo callback no pueda reproducirse.
state viaja a través del navegador del usuario. Está bien usarlo para llevar una clave de búsqueda — qué usuario, qué flujo, a qué página regresar — pero nunca coloques nada sensible o confiable en el valor en sí.Paso 3 — Maneja el callback
Tras la aprobación, Fluz redirige al usuario a turedirect_uri con:
Si la solicitud estuvo mal configurada, la redirección lleva un mensaje de error que describe lo que no coincidió.
Paso 4 — Conciliar lo que realmente obtuviste
La respuesta del intercambio incluye el arreglo de scopes que el usuario aprobó. Ese arreglo, no tus suposiciones, es la verdad sobre lo que tu integración puede hacer. El consentimiento ahora es todo o nada, así que la causa habitual de un scope faltante ya no es que el usuario lo haya rechazado: es que no está habilitado en la pestaña Permissions de tu app, en cuyo caso nunca se le ofreció. El flujo se completa igualmente y tus llamadas al API fallan después. Una concesión emitida antes de que ampliaras la pestaña Permissions tampoco incluirá los scopes nuevos hasta que ese usuario vuelva a autorizar. Lee los scopes devueltos, persístelos junto con los tokens y condiciona tus funcionalidades a ellos. Si falta algo esencial, díselo claramente al usuario y ofrece volver a ejecutar el flujo.Diseñando el momento
La pantalla de consentimiento convierte mucho mejor cuando el usuario entiende por qué la está viendo.- Explica antes de redirigir. Una oración en tu propia página — “Conecta tu cuenta de Fluz para que podamos enviar tus pagos” — supera dejar a alguien caer en frío en una pantalla de permisos.
- Dispáralo en contexto. En el punto del primer pago o la primera tarjeta, no enterrado en la configuración de la cuenta.
- Redirección a página completa en lugar de popup. Los popups se bloquean, y el flujo incluye 2FA y posiblemente verificación de identidad, lo cual es incómodo en una ventana pequeña. Si necesitas permanecer en la página, usa un embedded widget en su lugar, que está hecho exactamente para eso.
- Maneja el viaje de regreso. Haz que el usuario llegue a donde estaba, con lo que intentaba hacer ya funcionando.
statees cómo sabes dónde estaba. - Ten una ruta de re-autorización. Los refresh tokens expiran y los usuarios revocan el acceso. Construye el flujo de “reconectar” al mismo tiempo que el de conectar, no después del primer ticket de soporte.
- Considera omitirlo. Si tus usuarios aún no tienen cuentas Fluz, un widget maneja registro, verificación y consentimiento en un flujo hospedado en página sin redirección. Consulta Embedded Widgets.
Resolución de problemas
Próximos pasos
Intercambiar un código de autorización
Convierte el código en un access token y refresh token.
Refrescar un access token
Mantente conectado sin volver a enviar al usuario por consentimiento.
Configurar la app OAuth
Corrige cualquier cosa que la pantalla de consentimiento haya mostrado mal.
Widgets embebidos
Omite la redirección por completo con un flujo hospedado en la página.