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.
TED plugin configuration happens at three levels. Most business decisions can be changed at runtime without restarting the service.
Configuration levels
| Level | Who manages | What it controls | Requires restart? |
|---|
| Infrastructure (env vars) | DevOps | URLs, credentials, authentication, timeouts | Yes |
| Tenant settings (Admin API) | Product team | Limits, fee policy, operating hours overrides | No |
| Account settings (Admin API) | Product team | Per-account limits and restrictions | No |
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 tenant — applies to all transfers across the organization
- Per account — applies to a specific end-user account (overrides tenant 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 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 is fail-closed. Change this per organization via the Admin API.
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 — for example, restricting transfers to business hours only — within BACEN limits.
Infrastructure configuration
This section is for DevOps teams. These variables are set at deployment time and require a service restart to take effect.
Application
| Variable | Default | Required | Description |
|---|
ENV_NAME | development | No | Environment (development, staging, production) |
LOG_LEVEL | info | No | Log verbosity (debug, info, warn, error) |
DEPLOYMENT_MODE | byoc | No | Deployment flavor. byoc = Bring Your Own Cloud (single-tenant, operator-managed). Toggles internal SaaS vs. BYOC behaviors. |
SERVER_ADDRESS | :8080 | No | HTTP server address and port |
HTTP_BODY_LIMIT_BYTES | 1048576 | No | Maximum HTTP request body size in bytes |
INFRA_CONNECT_TIMEOUT_SEC | 30 | No | Infrastructure services connection timeout in seconds |
ALLOW_PRIVATE_UPSTREAMS | false | No | ⚠️ Allow outbound adapters (CRM, Fees, JD, Midaz) to resolve to RFC1918/loopback IPs. Default false is fail-closed: production blocks DNS pivoting into private space. Enable in dev or in-cluster BYOC where upstreams legitimately live on private IPs. Cloud metadata endpoints stay blocked regardless of this flag. |
TLS
| Variable | Default | Required | Description |
|---|
SERVER_TLS_CERT_FILE | - | No | Path to TLS certificate file. Must be set together with SERVER_TLS_KEY_FILE. |
SERVER_TLS_KEY_FILE | - | No | Path to TLS private key file. Must be set together with SERVER_TLS_CERT_FILE. |
TLS_TERMINATED_UPSTREAM | false | No | Set to true when TLS is terminated by a load balancer or reverse proxy. |
Used when the service runs behind a load balancer or reverse proxy. Required to extract the real client IP for rate limiting and audit logs.
| Variable | Default | Required | Description |
|---|
SERVER_PROXY_HEADER | - | No | HTTP header carrying the real client IP (e.g. X-Forwarded-For, X-Real-IP). Empty disables proxy header parsing. |
SERVER_TRUSTED_PROXIES | - | If proxy header set | Comma-separated list of trusted proxy IPs/CIDRs. Required when SERVER_PROXY_HEADER is set to prevent IP spoofing. |
CORS
| Variable | Default | Required | Description |
|---|
CORS_ALLOWED_ORIGINS | http://localhost:3000 | No | Comma-separated list of allowed origins. Wildcards (*) and localhost origins are rejected in production. |
CORS_ALLOWED_METHODS | GET,POST,PUT,PATCH,DELETE,OPTIONS | No | Allowed HTTP methods. |
CORS_ALLOWED_HEADERS | Origin,Content-Type,Accept,Authorization,X-Request-ID,X-Organization-Id,X-Idempotency | No | Allowed request headers. |
Authentication
This plugin delegates authorization to plugin-auth. Configure the connection with the variables below.
| Variable | Default | Required | Description |
|---|
PLUGIN_AUTH_ENABLED | false | No | Enable authorization via plugin-auth. Set to true in production. |
PLUGIN_AUTH_ADDRESS | - | If enabled | URL of the plugin-auth service. Must use HTTPS in production. |
PLUGIN_AUTH_CLIENT_ID | plugin-br-bank-transfer | If enabled | OAuth client ID used by this plugin. |
PLUGIN_AUTH_CLIENT_SECRET | - | If enabled | OAuth client secret used by this plugin. |
AUTH_CACHE_TTL_SEC | 60 | No | Duration (in seconds) for caching authorization decisions. Denied decisions are cached for TTL/4. |
When PLUGIN_AUTH_ENABLED=true, PLUGIN_AUTH_ADDRESS must use HTTPS in production environments. HTTP addresses are rejected at startup.
Test admin (non-production only)
BTF_TEST_ADMIN_ENABLED must remain false in production. It exposes test-only admin endpoints (e.g. POST /admin/test/circuit-breakers/reset) that are tenant-less and bypass production authentication. Enabled only by docker-compose mock-lane for E2E tests; any deployment with this flag true outside a sealed test network is a misconfiguration.
| Variable | Default | Required | Description |
|---|
BTF_TEST_ADMIN_ENABLED | false | No | ⚠️ Expose test-only admin endpoints. Must remain false in production. |
BTF_TEST_ADMIN_TOKEN | - | If admin enabled | Token required when BTF_TEST_ADMIN_ENABLED=true. Sent in the X-Test-Admin-Token header. Intentionally separate from production auth (test-only surface, no tenant). |
Rate limiting
| Variable | Default | Required | Description |
|---|
RATE_LIMIT_ENABLED | true | No | Enable per-client rate limiting. Forced to true in production. |
RATE_LIMIT_MAX | 100 | No | Maximum requests per window per client. |
RATE_LIMIT_EXPIRY_SEC | 60 | No | Sliding window duration in seconds. |
Idempotency
| Variable | Default | Required | Description |
|---|
IDEMPOTENCY_RETRY_WINDOW_SEC | 300 | No | Time window (in seconds) during which an idempotency key is considered valid. |
IDEMPOTENCY_REQUIRE_REDIS | false | No | When true, reject requests if Redis is unavailable rather than falling back. |
DUPLICATE_GUARD_TTL_SEC | 300 | No | TTL (in seconds) for the Redis duplicate-guard window. Complements IDEMPOTENCY_RETRY_WINDOW_SEC; this TTL controls the duplicate-guard entry lifetime. |
Multi-tenancy
| Variable | Default | Required | Description |
|---|
MULTI_TENANT_ENABLED | false | No | Enable infrastructure-level multi-tenancy with tenant-isolated databases. |
DEFAULT_TENANT_ID | 11111111-1111-1111-1111-111111111111 | No | Fallback tenant UUID when auth is disabled. Must be a valid UUID. |
DEFAULT_TENANT_SLUG | default | No | Default tenant slug identifier. |
DEFAULT_ORGANIZATION_ID | - | No | Organization ID used in single-tenant mode (when MULTI_TENANT_ENABLED=false). Complements DEFAULT_TENANT_ID. |
AWS_REGION | - | If AWS secrets backend | AWS region for per-tenant secret reads from Secrets Manager. Required when MULTI_TENANT_ENABLED=true and the secrets backend is AWS. |
MULTI_TENANT_INTEGRATION_SECRET_NAME_TEMPLATE | tenants/{env}/{tenantId}/{applicationName}/integration/configuration | No | Template for the AWS Secrets Manager secret name. Placeholders: {env}, {tenantId}, {applicationName}. |
TENANT_IDS | - | No | Comma-separated list of allowed tenant UUIDs. This single variable serves two purposes: (1) request allowlisting — requests from any tenant not in this list are rejected, and (2) licensing scope — only these tenants are considered licensed. Leave unset to allow all configured tenants. Also referenced under License. |
MULTI_TENANT_URL | - | Yes (when enabled) | Tenant Manager HTTP API URL. |
MULTI_TENANT_REDIS_HOST | - | No | Redis host for Pub/Sub event-driven tenant discovery. |
MULTI_TENANT_REDIS_PORT | 6379 | No | Redis port for Pub/Sub. |
MULTI_TENANT_REDIS_PASSWORD | - | No | Redis password for Pub/Sub. |
MULTI_TENANT_REDIS_TLS | false | No | Enable TLS for Redis Pub/Sub connection. |
MULTI_TENANT_TIMEOUT | 30 | No | HTTP timeout in seconds for Tenant Manager API calls. |
MULTI_TENANT_MAX_TENANT_POOLS | 100 | No | Maximum concurrent tenant database connection pools. |
MULTI_TENANT_IDLE_TIMEOUT_SEC | 300 | No | Idle timeout in seconds before evicting a tenant pool. |
MULTI_TENANT_CIRCUIT_BREAKER_THRESHOLD | 5 | No | Number of failures before the circuit breaker opens. |
MULTI_TENANT_CIRCUIT_BREAKER_TIMEOUT_SEC | 30 | No | Recovery timeout in seconds for the circuit breaker. |
MULTI_TENANT_SERVICE_API_KEY | - | Yes (when enabled) | API key for the Tenant Manager /settings endpoint. |
MULTI_TENANT_CACHE_TTL_SEC | 120 | No | In-memory tenant config cache TTL in seconds. Hot-reloadable via systemplane API. |
MULTI_TENANT_CONNECTIONS_CHECK_INTERVAL_SEC | 30 | No | Async interval in seconds for revalidating pool settings. Bootstrap-only (not hot-reloadable). |
BYOC single-tenant:
DEFAULT_TENANT_ID=<your-tenant-uuid>
# Optional: restrict to specific tenant UUIDs
TENANT_IDS=<uuid1>,<uuid2>
SaaS multi-tenant:
MULTI_TENANT_ENABLED=true
MULTI_TENANT_URL=http://tenant-manager:4003
MULTI_TENANT_SERVICE_API_KEY=your-api-key
MULTI_TENANT_REDIS_HOST=redis.example.com
PostgreSQL
| Variable | Default | Required | Description |
|---|
POSTGRES_HOST | localhost | Yes | Primary PostgreSQL host. |
POSTGRES_PORT | 5432 | No | Primary PostgreSQL port. |
POSTGRES_USER | plugin-br-bank-transfer | Yes | Database user. |
POSTGRES_PASSWORD | - | Yes | Database password. Required in production. |
POSTGRES_DB | plugin-br-bank-transfer | Yes | Database name. |
POSTGRES_SSLMODE | require | No | SSL mode. disable is rejected in production. |
POSTGRES_MAX_OPEN_CONNS | 25 | No | Maximum open connections. |
POSTGRES_MAX_IDLE_CONNS | 5 | No | Maximum idle connections. |
POSTGRES_CONN_MAX_LIFETIME_MINS | 30 | No | Connection max lifetime in minutes. |
POSTGRES_CONN_MAX_IDLE_TIME_MINS | 5 | No | Connection max idle time in minutes. |
POSTGRES_CONNECT_TIMEOUT_SEC | 10 | No | Connection timeout in seconds. |
MIGRATIONS_PATH | migrations | No | Path to database migration files. |
PostgreSQL replica
Configure a read replica for query offloading. All fields fall back to primary values when unset.
| Variable | Default | Required | Description |
|---|
POSTGRES_REPLICA_HOST | - | No | Replica host. Unset = no replica. |
POSTGRES_REPLICA_PORT | - | No | Replica port. |
POSTGRES_REPLICA_USER | - | No | Replica user. |
POSTGRES_REPLICA_PASSWORD | - | No | Replica password. |
POSTGRES_REPLICA_DB | - | No | Replica database name. |
POSTGRES_REPLICA_SSLMODE | - | No | Replica SSL mode. |
MongoDB
MongoDB is required for transfer audit event persistence. The service will not start without a valid MongoDB connection.
| Variable | Default | Required | Description |
|---|
MONGO_ENABLED | true | Yes | Enable MongoDB connection. Must be true in all environments. |
MONGO_URI | - | Yes | MongoDB connection string (e.g. mongodb://user:pass@host:27017). Must include credentials and TLS in production. |
MONGO_DATABASE | - | Yes | MongoDB database name. |
MONGO_MAX_POOL_SIZE | 25 | No | Maximum connection pool size. |
MONGO_SERVER_SELECTION_TIMEOUT_MS | 3000 | No | Server selection timeout in milliseconds. |
MONGO_HEARTBEAT_INTERVAL_MS | 10000 | No | Heartbeat interval in milliseconds. |
MONGO_TLS_CA_CERT | - | No | Base64-encoded CA certificate for MongoDB TLS. Use when MongoDB requires TLS with a custom CA (e.g. Atlas, private instances with self-signed certs). |
Redis
| Variable | Default | Required | Description |
|---|
REDIS_HOST | localhost:6379 | Yes | Redis host and port. |
REDIS_MASTER_NAME | - | No | Redis Sentinel master name (if using Sentinel). |
REDIS_PASSWORD | - | No | Redis password (if auth enabled). |
REDIS_DB | 0 | No | Redis database number. |
REDIS_PROTOCOL | 3 | No | Redis protocol version (2 or 3). |
REDIS_TLS | false | No | Enable TLS for Redis connections. |
REDIS_CA_CERT | - | No | CA certificate for Redis TLS. |
REDIS_POOL_SIZE | 10 | No | Connection pool size. |
REDIS_MIN_IDLE_CONNS | 2 | No | Minimum idle connections. |
REDIS_READ_TIMEOUT_MS | 3000 | No | Read timeout in milliseconds. |
REDIS_WRITE_TIMEOUT_MS | 3000 | No | Write timeout in milliseconds. |
REDIS_DIAL_TIMEOUT_MS | 5000 | No | Dial timeout in milliseconds. |
Redis is a mandatory dependency. If Redis is unavailable at startup or becomes unreachable at runtime, the service reports as DOWN on the Check readiness endpoint and stops accepting requests. Redis is required for idempotency key caching and duplicate detection.
JD SPB connection
These variables are required for BYOC deployments. In SaaS mode, Lerian manages the JD connection.
| Variable | Default | Required | Description |
|---|
JD_BASE_URL | - | If BYOC | JD SPB API base URL. |
JD_SOAP_PATH | /soap | No | JD SOAP endpoint path. |
JD_ORIGIN_ISPB | - | If BYOC | Originating ISPB code. |
JD_LEGACY_CODE | - | If BYOC | JD legacy system code (max 10 chars). |
JD_USER_CODE | - | If BYOC | JD user code (max 10 chars). |
JD_PASSWORD | - | If BYOC | JD password (encrypted at rest). |
JD_PRIVATE_KEY_PEM | - | If BYOC | RSA private key PEM content for XML signature. |
JD_PUBLIC_KEY_PEM | - | No | Public key PEM for validating signatures on JD responses. Required when JD_VALIDATE_EXTERNAL_SIGNATURE=true. |
JD_PRIVATE_KEY_KEYINFO | - | No | XML <KeyInfo> block embedded in the SOAP signature (e.g. base64-encoded X509 cert). Required for the WS-Security envelope when JD demands certificate identification. |
JD_SIGNING_MODE | local_pem | No | SOAP signing mode. local_pem signs locally with JD_PRIVATE_KEY_PEM; external_signer delegates to a remote service via JD_EXTERNAL_SIGNER_URL. |
JD_VALIDATE_EXTERNAL_SIGNATURE | true | No | Validate signatures on responses from JD (or the external signer). Default true keeps validation active. Set false only for debug/sandbox without configured PKI. |
JD_EXTERNAL_SIGNER_URL | - | If JD_SIGNING_MODE=external_signer | Base URL of the external signing service. |
JD_EXTERNAL_SIGNER_AUTH_TOKEN | - | No | Bearer token sent in the Authorization header for external-signer calls. |
JD_EXTERNAL_SIGNER_TIMEOUT_MS | 5000 | No | Timeout (in milliseconds) for external-signer calls. |
JD_BACEN_ROUTING_ISPB | 00038166 | No | BACEN routing ISPB (the JD/JDSPB ISPB). Default 00038166 is the JD bank ISPB. Change only if the operator routes through a different PSP. |
JD_TIMEOUT_MS | 8000 | No | SOAP request timeout in milliseconds. |
JD_MAX_RETRIES | 3 | No | Maximum retry attempts for JD requests. |
JD_SANDBOX_MODE | false | No | Enable JD sandbox mode. Rejected in production. |
JD polling
| Variable | Default | Required | Description |
|---|
JD_POLLING_ENABLED | false | No | Enable TED IN polling worker. |
JD_POLL_INTERVAL_SECONDS | 30 | No | How often (in seconds) the plugin polls for incoming TEDs. |
JD_POLL_MAX_MESSAGES_PER_CYCLE | 50 | No | Maximum messages to process per polling cycle. |
JD_POLL_MAX_RETRIES | 3 | No | Maximum retry attempts per polling cycle. |
JD_POLL_RECOVERY_BATCH_SIZE | 200 | No | Batch size for recovery polling. |
JD_POLL_DISABLE_OPERATING_HOURS_WINDOW | true | No | When true, the RecebeMensagem poller ignores the operating-hours window (TRANSFER_OPERATING_OPEN/CLOSE) and runs continuously. Default true because JD can deliver messages outside the operator’s transfer window. |
BTF_TED_IN_RETORNO_FILTER | - | No | Comma-separated TpRetorno filter applied server-side by RecebeMensagem. Empty = no filter (pulls P/R/E/C). Note: the JD spec encodes TpRetorno as a single element, so only the first value is honored today. |
JD_POLLING_ENABLED defaults to false for safer deployments. Before enabling it, ensure DEFAULT_TENANT_ID (or Pool Manager) is configured with a valid UUID. JD polling is not supported when MULTI_TENANT_ENABLED=true.
External services (Midaz)
| Variable | Default | Required | Description |
|---|
MIDAZ_BASE_URL | - | Yes | Midaz base service URL. |
MIDAZ_TRANSACTION_URL | - | Yes | Midaz transaction service URL. |
MIDAZ_TIMEOUT_MS | 3000 | No | Midaz request timeout in milliseconds. |
MIDAZ_MAX_RETRIES | 3 | No | Retry attempts on Midaz failure. |
MIDAZ_OTEL_ENABLED | true | No | Enable OpenTelemetry tracing for Midaz calls. |
MIDAZ_DEBUG | false | No | Enable debug logging for Midaz calls. Rejected in production. |
MIDAZ_AUTH_ENABLED | false | No | Enable M2M authentication for Midaz. |
MIDAZ_AUTH_ADDRESS | - | If auth | Auth service URL for Midaz M2M tokens. |
MIDAZ_CLIENT_ID | - | If auth | OAuth client ID for Midaz M2M. |
MIDAZ_CLIENT_SECRET | - | If auth | OAuth client secret for Midaz M2M. |
MIDAZ_BREAKER_FAILURES | 3 | No | Circuit breaker failure threshold. |
MIDAZ_BREAKER_TIMEOUT_SECONDS | 30 | No | Circuit breaker recovery timeout in seconds. |
BTF_MIDAZ_CB_ENABLED | true | No | Kill switch for the Midaz client circuit breaker. When false, Midaz calls bypass the breaker (timeouts and retries remain active). Useful when intermittent flakes are amplifying into sustained 500s. |
External services (CRM)
| Variable | Default | Required | Description |
|---|
CRM_BASE_URL | - | Yes | CRM service URL. |
CRM_TIMEOUT_MS | 2000 | No | CRM request timeout in milliseconds. |
CRM_MAX_RETRIES | 2 | No | Retry attempts on CRM failure. |
CRM_AUTH_ENABLED | false | No | Enable M2M authentication for CRM. |
CRM_CLIENT_ID | - | If auth | OAuth client ID for CRM M2M. |
CRM_CLIENT_SECRET | - | If auth | OAuth client secret for CRM M2M. |
CRM_SENDER_LOOKUP_PATH_TEMPLATE | - | No | Path template for sender lookup in the CRM (e.g. /api/v1/accounts/{accountId}). Placeholders are defined by the operator’s CRM. |
CRM_RECIPIENT_LOOKUP_PATH_TEMPLATE | - | No | Path template for recipient lookup in the CRM. |
CRM_HOLDER_LOOKUP_PATH_TEMPLATE | - | No | Path template for account-holder lookup in the CRM. |
External services (Fees)
BTF_FEE_ENABLED is the master switch. When false (default), no Fees adapter is constructed and every transfer proceeds with fee=0 with no HTTP call. The other FEES_* variables only take effect when BTF_FEE_ENABLED=true.
| Variable | Default | Required | Description |
|---|
BTF_FEE_ENABLED | false | No | Master switch for plugin-fees integration. When false, no Fees adapter is built and all transfers run with fee=0 without HTTP calls. Operators running plugin-fees must set this to true explicitly. |
FEES_BASE_URL | - | If enabled | Fees Engine service URL. |
FEES_TIMEOUT_MS | 2000 | No | Fee request timeout in milliseconds. |
FEES_MAX_RETRIES | 2 | No | Retry attempts on fee service failure. |
FEES_FAIL_CLOSED_DEFAULT | false | No | Default fee fail mode. true = block transfer when fees unavailable. |
FEES_MAX_FEE_AMOUNT_CENTS | 99999999 | No | Maximum fee amount in cents. Responses exceeding this value are rejected. |
FEES_REFUND_ON_DEVOLUCAO | false | No | When true, charged fees are refunded on TED returns/reversals. Default false keeps the fee retained even on devolução. |
FEES_AUTH_ENABLED | false | No | Enable M2M authentication for Fees. |
FEES_CLIENT_ID | - | If auth | OAuth client ID for Fees M2M. |
FEES_CLIENT_SECRET | - | If auth | OAuth client secret for Fees M2M. |
Fees resilience
BTF_FEES_TED_IN_FAIL_OPEN defaults to true. When plugin-fees is unavailable, inbound TEDs are credited with fee=0 (fail-open) so funds reach customers. Operators with an SLA that requires charging on every inbound credit must set this to false (fail-closed). TED OUT is unconditionally fail-closed regardless of this flag — the sender debit is authoritative.
| Variable | Default | Required | Description |
|---|
BTF_FEES_TED_IN_FAIL_OPEN | true | No | ⚠️ When true, TED IN proceeds with fee=0 if plugin-fees is unreachable. When false, TED IN is blocked until fees recover. TED OUT is always fail-closed. |
Reconciliation
The reconciliation worker reaps pending transfers that never received a JD return and reconciles them against the ledger.
| Variable | Default | Required | Description |
|---|
BTF_RECONCILIATION_ENABLED | true | No | Enable the internal reconciliation engine. When false, transfers without a JD return are never reconciled automatically. |
BTF_RECONCILIATION_INTERVAL_SEC | 30 | No | Interval (in seconds) between reconciliation cycles. |
BTF_RECONCILIATION_BATCH_SIZE | 20 | No | Maximum number of transfers processed per reconciliation cycle. |
BTF_RECONCILIATION_MAX_ATTEMPTS | 10 | No | Maximum reconciliation attempts before marking a transfer as permanently failed. |
BTF_RECONCILIATION_STALE_AFTER_SEC | 60 | No | Time (in seconds) after which a pending transfer is considered stale and eligible for reconciliation. |
BTF_DLQ_ENABLED | true | No | Persist unparseable JD messages in the jd_incoming_parse_failures dead-letter table. Default true because dropping messages silently is never safe under at-most-once delivery. |
Holiday calendar (BACEN/ANBIMA)
Drives the BACEN banking-holiday calendar used by the operating-hours gate and the initiation TTL clamp. The database is the source of truth; these variables only govern the scheduled refresher.
| Variable | Default | Required | Description |
|---|
ANBIMA_HOLIDAY_SOURCE_URL | https://www.anbima.com.br/feriados/arqs/feriados_nacionais.xls | No | Upstream URL for BACEN/ANBIMA holidays. The live fetcher is not yet wired (a static seed for 2026–2028 is used); operators may repoint to an internal mirror. |
ANBIMA_FETCHER_ENABLED | true | No | Toggle the scheduled holiday refresher. When false, the plugin relies on a pre-populated bacen_holidays table. |
ANBIMA_FETCHER_SCHEDULE | 03:00 | No | Daily fire time (HH:MM) for the refresher. 03:00 sits outside BACEN hours and before the 06:30 window opens, avoiding mid-refresh snapshots. |
HOLIDAY_CACHE_TTL | 1h | No | TTL of the in-process holiday calendar cache (time.ParseDuration format: 1h, 30m, etc.). Lower this when manual UPSERTs need to propagate faster. |
RabbitMQ
Transfer lifecycle events can be published to RabbitMQ for downstream consumers.
| Variable | Default | Required | Description |
|---|
RABBITMQ_ENABLED | false | No | Enable transfer lifecycle event publishing. |
RABBITMQ_URL | - | If enabled | AMQP connection URL. Must use amqps:// outside development. |
RABBITMQ_EXCHANGE | bank_transfer.lifecycle | No | Exchange name for lifecycle events. |
RABBITMQ_ROUTING_KEY_PREFIX | transfer | No | Routing key prefix for published events. |
RABBITMQ_EVENT_SIGNING_SECRET | - | If enabled | HMAC secret for signing published events. Minimum 32 characters. |
RABBITMQ_PUBLISH_TIMEOUT_MS | 5000 | No | Publish timeout in milliseconds. |
RABBITMQ_MAX_RETRIES | 3 | No | Maximum publish retry attempts. |
RABBITMQ_RETRY_BACKOFF_MS | 200 | No | Backoff between publish retries in milliseconds. |
Webhook delivery
Outbound webhook delivery requires RabbitMQ to be enabled. The webhook worker consumes events from a RabbitMQ queue and delivers them to the configured endpoint.
| Variable | Default | Required | Description |
|---|
WEBHOOK_ENABLED | false | No | Enable outbound webhook delivery. Requires RABBITMQ_ENABLED=true. |
WEBHOOK_ENDPOINT_URL | - | If enabled | Destination URL. Must use HTTPS; loopback/private IPs are rejected. |
WEBHOOK_SIGNING_SECRET | - | If enabled | HMAC secret for signing webhook payloads. Minimum 32 characters. |
WEBHOOK_BROKER_EVENT_SIGNING_SECRET | - | No | Separate HMAC secret for verifying broker events. Falls back to WEBHOOK_SIGNING_SECRET. |
WEBHOOK_ALLOW_UNSIGNED_BROKER_EVENTS | false | No | Temporarily accept unsigned broker events during migration. |
WEBHOOK_UNSIGNED_BROKER_EVENTS_GRACE_SEC | 0 | No | Grace period (in seconds) for unsigned events. Must be > 0 when unsigned events are allowed. |
WEBHOOK_QUEUE_NAME | transfer.webhook.delivery | No | RabbitMQ queue name for webhook events. |
WEBHOOK_DLQ_NAME | transfer.webhook.dlq | No | Dead-letter queue for failed webhook deliveries. |
WEBHOOK_CONSUMER_TAG | plugin-br-bank-transfer-webhook | No | RabbitMQ consumer tag. |
WEBHOOK_PREFETCH_COUNT | 20 | No | RabbitMQ prefetch count. |
WEBHOOK_DELIVERY_CONCURRENCY | 8 | No | Maximum concurrent webhook deliveries per worker. |
WEBHOOK_TIMEOUT_MS | 5000 | No | HTTP delivery timeout in milliseconds. |
WEBHOOK_MAX_RETRIES | 3 | No | Maximum delivery retry attempts. |
WEBHOOK_RETRY_BACKOFF_MS | 500 | No | Backoff between delivery retries in milliseconds. |
Usage limits
| Variable | Default | Required | Description |
|---|
USAGE_LIMITS_ENABLED | false | No | Enable per-account usage limit enforcement. |
USAGE_LIMIT_DAILY_CENTS | 0 | No | Default daily transfer limit in cents. At least one limit must be > 0 when enabled. |
USAGE_LIMIT_MONTHLY_CENTS | 0 | No | Default monthly transfer limit in cents. |
Operating hours
| Variable | Default | Required | Description |
|---|
TRANSFER_OPERATING_OPEN | 06:30 | No | Transfer acceptance window open time (HH:MM). |
TRANSFER_OPERATING_CLOSE | 17:00 | No | Transfer acceptance window close time (HH:MM). |
TRANSFER_OPERATING_TIMEZONE | America/Sao_Paulo | No | Timezone for operating hours evaluation. |
Telemetry (OpenTelemetry)
| Variable | Default | Required | Description |
|---|
ENABLE_TELEMETRY | false | No | Enable OpenTelemetry tracing and metrics. |
OTEL_RESOURCE_SERVICE_NAME | plugin-br-bank-transfer | No | OTel service name. |
OTEL_LIBRARY_NAME | github.com/LerianStudio/plugin-br-bank-transfer | No | OTel instrumentation library name. |
OTEL_RESOURCE_SERVICE_VERSION | 1.0.0 | No | OTel service version. |
OTEL_RESOURCE_DEPLOYMENT_ENVIRONMENT | development | No | OTel deployment environment. |
OTEL_EXPORTER_OTLP_ENDPOINT | localhost:4317 | No | OTel collector gRPC endpoint. |
DB_METRICS_INTERVAL_SEC | 15 | No | Database metrics collection interval in seconds. |
RECONCILIATION_PENDING_ALERT_THRESHOLD | 5 | No | Alert threshold for pending reconciliation items. |
OTEL_TRACES_SAMPLER_ARG | - | No | Trace sampling ratio (0.0–1.0). Unset uses the default sampler resolved at telemetry init: 0.1 in production, 1.0 elsewhere. Values outside (0,1] are clamped to 1.0 so misconfiguration cannot silently disable production tracing. |
BTF_METRICS_PROMETHEUS_ENABLED | false | No | Expose a dedicated Prometheus scrape endpoint for btf.* metrics. When true, the listener at BTF_METRICS_PROMETHEUS_ADDRESS is started. |
BTF_METRICS_PROMETHEUS_ADDRESS | 127.0.0.1:9090 | No | Listen address for the Prometheus /metrics endpoint. Default binds to loopback so a misconfigured pod does not expose unauthenticated metrics to the cluster network. Override (e.g. 0.0.0.0:9090) only behind a NetworkPolicy or sidecar. |
License
| Variable | Default | Required | Description |
|---|
LICENSE_KEY | - | In production | License key. Required in production environments. |
LICENSE_SERVICE_ADDRESS | - | No | License validation service URL. |
TENANT_IDS | - | No | Same variable as in Multi-tenancy. Comma-separated list of tenant UUIDs used for both request allowlisting and licensing scope. |
Encryption
Field-level encryption for sensitive data at rest. Each key must be a base64-encoded 32-byte AES-256 key. Leave empty to disable encryption for that field.
| Variable | Default | Required | Description |
|---|
JD_INCOMING_RAW_XML_ENCRYPTION_KEY | - | No | AES-256 key for encrypting incoming JD XML payloads. |
RECIPIENT_DETAILS_ENCRYPTION_KEY | - | No | AES-256 key for encrypting recipient details at rest. |
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 tenant 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.