Skip to main content
Para liquidar un Pix en el Banco Central, una institución tiene que estar conectada a la infraestructura del Sistema Financiero Nacional. Eso es caro y lento, y no todas las instituciones lo hacen. Una institución que no lo hace usa la conexión de otra: se convierte en participante indirecto, y un participante directo liquida por ella y la hospeda. Un tenant que hospeda participantes indirectos es primero un participante directo. Todo lo que está en Configurar el riel — el vínculo del ISPB, la organización, el ledger, el activo, las cuentas, los registros del CRM, las veinte rutas contables — se aprovisiona exactamente como está escrito allí. Llama a eso la cadena del participante directo, pasos 1 a 6. Esta página es lo que agregas encima, y su numeración continúa desde ahí. Si tu despliegue liquida solo el Pix de sus propios clientes, omite esta página.
El paso 7 va antes del paso 9, no después: sin la clave de cifrado, todo registro del paso 9 falla. Los pasos 7 y 8 son independientes entre sí — la postura no valida la clave, y la postura tampoco lee la clave.
Esta página es el aprovisionamiento. Qué es una participación hospedada, cómo le llega un crédito entrante, cómo se comporta su ciclo de vida y cada rechazo que puede responder están en Participantes indirectos.

Paso 7: la clave de cifrado del secreto de entrega

Por qué existe este paso. Cuando registras un participante indirecto, entregas un secreto de entrega. El plugin firma con él cada aviso que envía al endpoint de esa institución, y así la institución sabe que el aviso realmente vino de ti. Ese secreto se almacena cifrado, y la clave que lo cifra no viene de la base de datos. Viene de afuera. Si la clave no está configurada, todo registro que lleve un secreto falla. Esto no es un caso límite — es toda la superficie de escritura del flujo indirecto.
Lee la garantía en medio de esa frase: no secret was stored. El cifrado falla antes de cualquier escritura, así que no hay una fila a medio crear con un secreto en texto plano que haya que ir a limpiar. Corregir la clave y repetir el POST es toda la recuperación.
Aquí 409 significa “aprovisiónala”, no “vuelve a intentarlo más tarde”. El riel buscó la clave y estableció que no está, y solo un operador puede ponerla ahí — así que repetir la llamada sin ese cambio falla de forma idéntica. Por eso el código es un 409 y no dice nada sobre reintentar.Su hermano es 503 PIX-0123, “Indirect delivery key source unavailable”, que es lo que obtienes cuando la clave no se pudo leer: el backend de custodia la rechazó o no respondió. Ahí no se sabe que la clave falte — la lectura misma no se completó — por lo que la respuesta nombra la dependencia que falla y reintentar es la jugada correcta. Ambos rechazan el registro y no almacenan nada; el par existe para que puedas distinguir una configuración incompleta de una caída.
El plugin arranca sin la clave. No hay rechazo en el arranque: el proceso escribe una advertencia en el log al iniciar y levanta sano, porque nada en el arranque distingue un despliegue que va a hospedar participantes indirectos de uno que nunca registra ninguno — la clave se lee en cada solicitud, no una sola vez al arrancar. Así que el síntoma llega en el primer registro, no en el despliegue. Si no leíste el log de arranque, el rechazo es tu primer aviso.
Dónde vive, y por qué no está en el systemplane. Este contraste explica dónde va cada tipo de valor en este riel.
No pongas la clave de cifrado en el systemplane. El systemplane es el plano de configuración en vivo, legible por la API de administración, y ese es el hogar correcto para todo lo que no es un secreto. El material de credenciales no va ahí, y el riel separa los dos a propósito.Tampoco la guardes en un commit — ni en un .env versionado, ni en un values.yaml, ni en un archivo de compose.
El formato: exactamente 64 caracteres hexadecimales. Es una clave AES-256 — 32 bytes — codificada en hexadecimal. Eso es 64 caracteres hexadecimales, ni 63 ni 65.
Genera una por despliegue. No copies la clave de otro entorno y no reutilices la de otro servicio.
Un valor ausente, en blanco o mal formado producen todos el mismo 409 PIX-0107. No hay valor predeterminado ni degradación a guardar el secreto en claro. Eso es deliberado: un valor predeterminado silencioso aquí guardaría los secretos de los clientes cifrados con una clave que todo el mundo conoce.
En single-tenant, define la variable de despliegue:
Ese marcador de posición deliberadamente no es una clave válida: pegado tal cual, falla en modo cerrado con el rechazo anterior en lugar de cifrar los secretos de tus clientes con un valor publicado en una página de documentación. Se lee al arrancar, así que cambiarla necesita reiniciar el proceso. Eso es distinto del vínculo del ISPB, que se lee en cada llamada y se sana sin reinicio.
No escribas el valor en una línea de comandos. Termina en el historial de tu shell y en los logs de CI. Léelo de un vault, o escríbelo con read -rs, que no hace eco.
Cómo verificar que quedó aplicada. Ninguna ruta lee la clave de vuelta, y así debe ser — es un secreto. Hay dos señales. El log de arranque. Con la clave resoluble, la advertencia “key unavailable” no aparece. Si aparece, ningún registro que lleve un secreto pasará. El comportamiento. Registra un participante indirecto: la respuesta pasa de 409 PIX-0107 a 201.
Piensa antes de usar la verificación por comportamiento. Un registro es permanente — no hay ruta de eliminación, y la única salida es close, que conserva la fila y retiene el ISPB. No gastes un registro desechable para probar la clave en un entorno de producción; usa un ISPB que realmente pienses operar. El log de arranque te ahorra ese costo.

Paso 8: declara que este tenant hospeda participantes indirectos

plugin-br-pix-jd.indirects/enabled tiene que ser true.
204 cuando se acepta. Es un booleano JSON, sin comillas: {"value":"true"} responde 400. La API de gestión funciona con la postura apagada, así que puedes registrar participantes antes de habilitarla — lo que la postura controla son las rutas del dinero. El desglose completo de lo que hace cada mitad está en Antes de registrar a nadie.
La lectura falla en modo cerrado. Si el systemplane no responde, si la clave no se resuelve, o si el valor vuelve con el tipo equivocado, el plugin lo lee como apagado — nunca encendido por accidente. Una ruta del dinero que “volvió a comportarse como una directa” sin que nadie haya tocado la clave es este mecanismo. Mira el systemplane.

Paso 9: registra un participante indirecto

Una sola llamada ejecuta todo el ensamblado: verifica el ISPB, crea la cuenta de liquidación @pi_{ispb} en Midaz y marca la participación como activa.
Un 201 significa que la participación está lista para usar: el registro es atómico, status siempre es ACTIVE, y no hay nada por lo que hacer polling.
No escribas el ISPB de un participante indirecto en tenancy/jd_integration_binding. Esa clave es la identidad que el plugin presenta a JD, así que el ISPB de un tercero ahí hace que el plugin se presente como otra institución — y nada te avisa, porque 8 dígitos válidos se aceptan y la escritura responde 204. La clave es una por participante directo, no una por participante indirecto: cada participante indirecto que hospedas llega al SPI a través de tu ISPB.
El registro es permanente. No hay DELETE en /v1/indirects, y CLOSED es terminal. Un participante indirecto registrado por error en un tenant en vivo no vuelve a salir, y su ISPB queda retenido contra la regla de unicidad hasta que alguien lo cierre. Revisa el nombre, el ISPB y el endpoint antes de llamar. Ensaya en un entorno desechable.
Los rechazos, las acciones del ciclo de vida y cómo leer el registro de vuelta están en Participantes indirectos.

Las claves del systemplane del namespace indirects

Cinco claves, todas en plugin-br-pix-jd.indirects, y todas existen siempre. Las tres claves de entrega y de resolución solo tienen efecto una vez que enabled es true, porque ajustan las rutas del dinero. validate_ispb_on_jd es la excepción: controla un paso del registro, que funciona mientras enabled sigue en false.
204 cuando se acepta, 400 cuando el validador rechaza. Los booleanos y los enteros van sin comillas, y un valor fuera del rango responde 400 en lugar de recortarse en silencio.
Ninguno de los dos pasos que por sí solos rompen el flujo indirecto vive en este namespace. La identidad es la clave del systemplane tenancy/jd_integration_binding, y sin ella todo pago rechaza con 409 PIX-0092. La clave de cifrado vive en una variable de despliegue o en un almacén de secretos, y sin ella todo registro rechaza con 409 PIX-0107.