> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lerian.studio/llms.txt
> Use this file to discover all available pages before exploring further.

# Configuration

> Configure Bank Transfer across infrastructure, tenant, and account levels — limits, fee policies, and operating hours adjustable at runtime.

Bank Transfer plugin configuration is organized across three levels. Most business-related settings can be updated at runtime without requiring a service restart.

It's important to distinguish between **tenant identity** and **Midaz organization scope**, as they serve different purposes.

The tenant is resolved from the authenticated request context through the `tenantId` JWT claim. It is responsible for infrastructure-level isolation, including multi-tenancy platform database resolution and access to tenant-scoped secrets.

The `X-Organization-Id` header defines the Midaz organization scope within that tenant. It is required on all organization-scoped transfer routes, regardless of the deployment mode. Requests that omit this header or provide a value that is not a valid UUID return a `400` response.

Background processes, such as the TED IN poller and reconciliation workers, do not receive request headers. In single-tenant deployments, these processes use the `ORGANIZATION_ID` environment variable as the organization context.

## Configuration levels

***

Bank Transfer plugin configuration is divided into three levels:

* **Infrastructure configuration** (managed by DevOps) controls URLs, credentials, authentication settings, and timeouts. Changes require a service restart.
* **Tenant settings** (managed through the Admin API by the Product team) control transfer limits, fee policies, and operating-hours overrides. Changes take effect without restarting the service.
* **Account settings** (managed through the Admin API by the Product team) control limits and restrictions for individual accounts. Changes take effect without restarting the service.

## Business decisions you can configure

***

These are the settings GPMs and product teams care about. All of them are managed via the Admin API at runtime — no deploy required.

### Transfer limits

Set daily and monthly volume caps at two levels:

* **Per organization** — applies to transfers for one Midaz organization inside the resolved tenant
* **Per account** — applies to a specific end-user account (overrides organization defaults)

Limits cover both total amount and number of transactions. Set these to manage risk and comply with BACEN requirements.

### Fee policy

Control whether the plugin charges a fee on TED OUT, TED IN, and P2P transfers. Fee rules are defined in the Fees Engine and applied per organization. See [Fees Engine](/en/midaz/fees/fees-engine-overview) for configuration details.

### Fail-open vs. fail-closed

If the fee calculation service is unavailable at the moment of a transfer, you have two options:

* **Fail-open** — allow the transfer to proceed without charging a fee
* **Fail-closed** — block the transfer until the fee service is available again

The default fee-service policy is **fail-open** (`FEES_FAIL_CLOSED_DEFAULT=false`). Change this per organization via the Admin API when you need fee-service outages to block transfers. TED IN has its own safety switch, `BTF_FEES_TED_IN_FAIL_OPEN`, which defaults to `true` so inbound funds are credited with fee=0 if plugin-fees is unavailable.

### TED IN receiving

Incoming transfers are **disabled by default**. Enable TED IN per organization once your JD SPB credentials are configured and the polling worker is active.

### Operating hours overrides

The plugin enforces BACEN's TED operating window by default. You can configure custom windows per tenant policy — for example, restricting transfers to business hours only — within BACEN limits.

## Infrastructure configuration

***

Deploy-time environment variables (URLs, credentials, TLS, persistence, integrations, security keys) are set by DevOps and require a service restart. See the full reference in [Environment variables](/en/rails/ted/jd/ted-environment-variables).

## Runtime configuration (Admin API)

***

Tenant-level and account-level settings are managed via the Admin API — no restart required. Changes take effect immediately (subject to cache TTL for tenant settings).

Configurable settings include:

* Transfer limits (daily and monthly, per organization and per account)
* Fee behavior (fail-open or fail-closed when the fee service is unavailable)
* TED IN receiving (enabled or disabled per organization)
* Operating hours overrides (custom windows within BACEN limits)

See the Admin API reference for the full list of configurable fields and request format.

### Systemplane-managed settings

The settings below are managed at runtime through the systemplane (Admin API), not at deploy time. Each one has a corresponding environment variable name that still exists in the codebase, but the config loader **ignores** these env vars and emits a deprecation WARN if they are set — assigning them via the environment has no effect. Use the systemplane to change them.

| Area                          | Settings                                                                                                                                                                                       |
| ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Rate limiting                 | `RATE_LIMIT_ENABLED`, `RATE_LIMIT_MAX`, `RATE_LIMIT_EXPIRY_SEC`                                                                                                                                |
| CORS                          | `CORS_ALLOWED_ORIGINS`, `CORS_ALLOWED_METHODS`, `CORS_ALLOWED_HEADERS` (default origin is wildcard `*` when unconfigured; not validated at startup)                                            |
| Fee policy                    | `FEES_FAIL_CLOSED_DEFAULT`, `FEES_MAX_FEE_AMOUNT_CENTS`, `FEES_REFUND_ON_DEVOLUCAO`, `BTF_FEES_TED_IN_FAIL_OPEN`                                                                               |
| Usage limits                  | `USAGE_LIMITS_ENABLED`, `USAGE_LIMIT_DAILY_CENTS`, `USAGE_LIMIT_MONTHLY_CENTS`                                                                                                                 |
| Operating hours               | `TRANSFER_OPERATING_OPEN`, `TRANSFER_OPERATING_CLOSE`, `TRANSFER_OPERATING_TIMEZONE`                                                                                                           |
| Idempotency / duplicate guard | `IDEMPOTENCY_REQUIRE_REDIS`, `DUPLICATE_GUARD_TTL_SEC`                                                                                                                                         |
| Routing                       | `ROUTING_*` (all routing-rule settings)                                                                                                                                                        |
| JD timeout & retry tuning     | `JD_TIMEOUT_MS`, `JD_MAX_RETRIES`, `JD_VALIDATE_EXTERNAL_SIGNATURE`                                                                                                                            |
| JD polling tuning             | `JD_POLL_MAX_MESSAGES_PER_CYCLE`, `JD_POLL_RECOVERY_BATCH_SIZE`, `JD_POLL_DISABLE_OPERATING_HOURS_WINDOW`                                                                                      |
| Reconciliation tuning         | `BTF_RECONCILIATION_BATCH_SIZE`, `BTF_RECONCILIATION_MAX_ATTEMPTS`, `BTF_RECONCILIATION_STALE_AFTER_SEC`, `BTF_RECONCILIATION_TICK_DEADLINE_SECONDS`, `RECONCILIATION_PENDING_ALERT_THRESHOLD` |
| RabbitMQ publish tuning       | `RABBITMQ_MAX_RETRIES`, `RABBITMQ_PUBLISH_TIMEOUT_MS`, `RABBITMQ_RETRY_BACKOFF_MS`, `RABBITMQ_ROUTING_KEY_PREFIX`                                                                              |
| Webhook delivery tuning       | `WEBHOOK_TIMEOUT_MS`, `WEBHOOK_MAX_RETRIES`, `WEBHOOK_RETRY_BACKOFF_MS`, `WEBHOOK_ALLOW_UNSIGNED_BROKER_EVENTS`, `WEBHOOK_UNSIGNED_BROKER_EVENTS_GRACE_SEC`                                    |

<Note>
  Setting any of the names above via the environment has no effect and is WARN-logged as deprecated. They exist only as deprecated env twins of runtime/systemplane-managed settings.
</Note>

<Warning>
  When CORS is unconfigured, the default allowed origin is the wildcard `*` — any origin can call the API — and it is not validated at startup. For production, set explicit origins through the systemplane key `cors.allowed_origins` instead of leaving the wildcard.
</Warning>
