Skip to main content
The Bank Transfer plugin splits configuration across two levels. You can change most business settings at runtime, with no service restart. The tenant identity and the Midaz organization scope serve different purposes. Keep them distinct. On Lerian Cloud, the tenantId JWT claim in the authenticated request context identifies your tenant, and Lerian isolates your data. The X-Organization-Id header defines the Midaz organization scope inside that tenant. Every organization-scoped transfer route requires this header, in all deployment modes. A request returns 400 if it omits the header or sends a value that is not a valid UUID. Background processes, such as the TED IN poller and reconciliation workers, do not receive request headers. With TED IN polling on, these processes use the ORGANIZATION_ID environment variable as the organization context.

Configuration levels


The Bank Transfer plugin has two configuration levels:
  • Infrastructure configuration (DevOps manages it) controls URLs, credentials, authentication settings, and timeouts. Changes need a service restart.
  • Runtime settings (managed through the Admin API) control transfer limits, fee policies, operating hours, and ledger routing. Settings in the tenant_policy namespace apply to one tenant. Settings in the runtime_config namespace apply to the whole deployment. Changes take effect with no service restart.

Business decisions you can configure


GPMs and product teams care about these settings. You manage all of them through the Admin API at runtime, with no deploy.

Transfer limits

Set daily and monthly amount caps per tenant with usage_limits.enabled, usage_limits.daily_limit_cents, and usage_limits.monthly_limit_cents. The plugin applies the caps to each sender account, on amount + fee, when it processes a TED OUT or P2P transfer. The day and the month roll over at 00:00 UTC. A transfer over a cap is refused with 422 BTF-0011.

Fee policy

Control whether the plugin charges a fee on TED OUT, TED IN, and P2P transfers. The Fees Engine defines the fee rules and applies them per organization. See Fees Engine for configuration details. With BTF_FEE_ENABLED=false, the plugin does not call the Fees Engine, and every transfer runs with fee 0.

Fail-open vs. fail-closed

The tenant policy fees.fail_closed_default (default false) decides what a fee failure does:
  • TED OUT and P2P: when the Fees Engine is unavailable, the transfer proceeds with no fee (fail-open). With true, the plugin refuses the transfer (fail-closed). A fee that the Fees Engine refuses always refuses the transfer.
  • TED IN: any fee failure credits the funds with fee 0. With true, the plugin does not credit, and returns the transfer to the origin bank.

TED IN receiving

TED IN polling is off by default. DevOps turns it on for the deployment with JD_POLLING_ENABLED=true, after the JD SPB credentials are in place. When the plugin cannot find the recipient of a TED IN, the tenant policy jd_polling.auto_return_authorized (default false) decides whether it returns the funds to the origin bank or retains the message for an operator. See Receive (TED IN).

Operating hours

Each tenant has one TED OUT window: operating_hours.window (HH:MM-HH:MM, default 06:30-17:00) in operating_hours.timezone (default America/Sao_Paulo). The plugin refuses a TED OUT outside the window, on weekends, and on BACEN holidays with 422 BTF-0010. P2P ignores the window.

Ledger routing

The tenant policy routing.ledger_bindings is one JSON document that binds each Midaz organization, ledger, and transfer type to its accounting routes. A binding either names the Midaz transaction and operation routes to use, or sets mode: omit to post with no routes. There is no fallback from one binding to another. Without a binding:
  • TED OUT and P2P are refused with 503 BTF-9015. The error names the missing setting in systemplaneKey and the cause in reason.
  • A TED IN is retained with reason LEDGER_ROUTE_UNRESOLVED. The plugin processes it again on each poll cycle and credits it once the binding exists.
Before you move traffic, call Check Ledger Routing Readiness. ready is true only when every organization, ledger, and transfer type in use has a binding whose routes exist in Midaz.

Infrastructure configuration


DevOps sets the deploy-time environment variables (URLs, credentials, TLS, persistence, integrations, security keys). These variables require a service restart. See the full reference in Environment variables.

Runtime configuration (Admin API)


You manage runtime settings through the Admin API under /system/:namespace/:key, with no restart. Tenant policy keys live in the tenant_policy namespace. Deployment-wide keys live in runtime_config. Configurable settings include:
  • Transfer limits (daily and monthly, per tenant)
  • Fee behavior (fees.fail_closed_default, fees.max_fee_amount_cents)
  • Recipient-not-found returns for TED IN (jd_polling.auto_return_authorized)
  • Operating hours (operating_hours.window, operating_hours.timezone)
  • Ledger routing (routing.ledger_bindings)

Systemplane-managed settings

The systemplane (Admin API) manages the settings below at runtime, not at deploy time. The plugin ignores these environment variables: if you set one, it logs the WARN systemplane-managed environment variable is set and ignored. Use the systemplane to change them.
When CORS is unconfigured, the default allowed origin is the wildcard *. Any origin can then call the API, and the plugin does not validate it at startup. For production, set explicit origins through the systemplane key cors.allowed_origins instead of the wildcard.