Skip to main content
The Pix Indirect Plugin (BTG) connects to multiple Lerian services and external providers to process Pix payments. To set it up, you configure the plugin’s connection to each service and prepare the data those services need. The plugin runs as two main layers. The Application exposes the Pix API and processes business logic. The Workers handle inbound webhooks from BTG, outbound event delivery to your system, DICT reconciliation with BACEN, and scheduled payments. Both layers share the same foundational configuration (license, Midaz, CRM, BTG) but have their own service-specific settings.

Prerequisites


Before you begin, make sure you have:
  • Your ISPB (Identificador do Sistema de Pagamentos Brasileiro): the 8-character identifier derived from your institution’s CNPJ
  • Access to your Midaz and CRM instances (deployed and running)
  • Access to BTG provider services (BTG provides the credentials)
The plugin uses PIX_ISPB to build and check end-to-end IDs. It detects intra-PSP (P2P) transfers from the payer’s alias account instead: see Intra-PSP transfers.

1. License


The plugin is an enterprise solution and requires a valid license to operate. Lerian provides the license key during onboarding.
Related documentation: Lerian’s License

2. Access Manager (optional)


Access Manager handles authentication for the plugin. When enabled, it validates incoming requests before they reach the plugin’s API.
When PLUGIN_AUTH_ENABLED=true, the plugin validates the Authorization header of each request to ensure:
  • The token belongs to an authorized user or application
  • The token grants access to the requested API endpoint and method
The Midaz and CRM client credentials (CLIENT_ID / CLIENT_SECRET) are required even when PLUGIN_AUTH_ENABLED=false. The Fee credentials are required when CASHIN_FEE_CALCULATION_TYPE=segment.
Related documentation: Access Manager

3. Midaz


Midaz is the core ledger for all Pix transactions the plugin processes. The plugin posts every cash-in, cash-out, and refund operation to Midaz as a double-entry transaction.

Connection


Asset requirements


Configure an asset in your organization and ledger with these properties: Link all accounts to your ledger using the BRL asset. The plugin rejects operations on accounts that don’t match this configuration.

Account setup


Before using the plugin, create an account in Midaz for each customer under your ISPB. Use the Create an Account endpoint to set up accounts. Each account must:
  • Belong to your configured organization and ledger
  • Use the BRL asset

X-Account-Id header


Many Pix operations require the X-Account-Id header to identify which account performs the action. This ID corresponds to the Midaz ledger account ID. When you call a plugin endpoint, the X-Account-Id value tells the plugin:
  • Which account to use for ledger operations
  • Which customer data to fetch from CRM
  • Which balance to validate and update

How the plugin uses the account ID

The plugin uses the account ID differently depending on the operation type:

Account compliance


The plugin does not enforce business-level account restrictions, such as blocked or suspended accounts. Your application must validate account status before it calls the plugin. To prevent Pix settlements on a specific account, block it directly in Midaz. The plugin receives a rejection when it attempts to post the transaction. Related documentation:

4. CRM


The CRM stores customer (holder) information and their associated bank accounts. Every Midaz account must have a corresponding holder and alias account in the CRM to perform Pix operations. The plugin queries CRM data to:
  • Register and validate Pix keys
  • Build payment messages for BACEN
  • Authorize incoming transactions
  • Process refund and dispute workflows

Connection


Holders


Holder data represents the customer who owns the account. Create each holder in the CRM before executing any Pix operation for that customer.

Required fields

Optional fields

Related documentation: Create a Holder

Alias accounts


Alias accounts link a Midaz account to its banking details. Each alias account must include the banking information that the Pix ecosystem requires for transaction processing.

Required fields

The bankingDetails.branch field must contain exactly 4 digits. Pad with leading zeros if necessary. For example, if the branch number is 1, register it as 0001. The plugin can only validate the account in the CRM when the branch code follows this format.

Supported account types

Related documentation: Create an Alias Account

5. BTG provider


BTG is the direct participant that connects your institution to BACEN’s Pix infrastructure. BTG provides the credentials directly when your institution signs up for indirect BACEN integration.

Connection


mTLS (webhook security)


Mutual TLS (mTLS) validates BTG’s certificate on webhook requests. It confirms that incoming webhooks originate from BTG. Your ingress forwards the certificate BTG presents in the MTLS_CERTIFICATE_HEADER header (default X-Client-Cert).
Always enable mTLS in production environments. Only disable it during local development.
To present a client certificate on the plugin’s own calls to BTG, set BTG_OUTBOUND_MTLS_ENABLED=true with CLIENT_TLS_CERT_FILE and CLIENT_TLS_KEY_FILE. See Environment variables.

6. Fee service (optional)


Enable fee calculation to automatically charge and distribute fees on incoming payments. This is optional. If you don’t configure it, the plugin processes transactions without fee calculation.

Connection


How it works


When you set CASHIN_FEE_CALCULATION_TYPE=segment, the plugin:
  1. Retrieves the segment associated with the receiving account
  2. Calculates applicable fees before processing the transaction in Midaz
  3. Distributes the incoming payment according to any package rules linked to that segment

Setup steps


  1. Create segments in Midaz: Define the account segments that determine fee rules
  2. Configure packages in Fees Engine: Link each segment to its fee calculation rules
  3. Assign segments to accounts: Create or update Midaz accounts with the appropriate segment ID
Related documentation:

7. DICT reconciliation (VSync)


VSync reconciles your local DICT data with BACEN by processing all key-related events from the day. This ensures your local state stays consistent with BACEN’s authoritative records.
During the window, the API rejects Pix key create, update, and delete requests to prevent data inconsistencies with BACEN. Plan the write block window during low-traffic periods.

Redis cache configuration


VSync uses Redis to cache BTG/DICT entries and CRM holders during reconciliation. In Helm deployments the default REDIS_HOST points to the built-in Valkey sidecar, so no extra setup is required for a standard install.
In Helm deployments, the default REDIS_HOST points to the built-in Valkey sidecar (<release-name>-valkey:6379). No additional Redis setup is needed unless you connect to an external instance.

Connection (always used)

Connection pool and retries (always used)

Authentication (optional, only used if set)

TLS (optional, only used if REDIS_TLS=true)

GCP IAM authentication (optional, only used if REDIS_USE_GCP_IAM=true)

VSync cache TTLs (always used)

8. Internal webhook security


The plugin uses an internal communication channel between the Worker and Application services. HMAC-SHA256 signatures secure this channel to prevent tampering and replay attacks.
Use the exact same INTERNAL_WEBHOOK_SECRET value in both the Application and Worker services. A mismatch causes the plugin to reject all internal webhooks.

9. Worker layers


The plugin operates with four workers, each handling a different part of the Pix lifecycle. Each worker runs as a separate service alongside the main application.

Inbound worker


The Application receives webhook notifications from BTG and stores them. The inbound worker then delivers each notification to the Application’s internal endpoints for processing.

Outbound worker


The outbound worker sends event notifications from the plugin to your application via webhooks. This is how your system stays informed about Pix events (transfers, refunds, claims, disputes).

URL resolution priority

The plugin resolves webhook URLs in this order, using the first match:
  1. Entity URL: A URL specific to the event type (e.g., WEBHOOK_DICT_CLAIM_URL)
  2. Flow URL: A URL for the broader category (e.g., WEBHOOK_DICT_URL)
  3. Default URL: The fallback URL (WEBHOOK_DEFAULT_URL)
Each entity needs its own WEBHOOK_<FLOW>_<ENTITY>_* variable. See Webhooks. For webhook event types, payloads, retry behavior, and best practices, see the Webhooks guide.

Reconciliation worker


The reconciliation worker needs the same credentials as the Application layer for these services:
  • CRM: URL and credentials
  • BTG: URL and credentials
  • Midaz: Organization ID
It also calls the Application API with its own client credentials: PLUGIN_PIX_BTG_BASE_URL, PLUGIN_PIX_BTG_CLIENT_ID, and PLUGIN_PIX_BTG_CLIENT_SECRET, with the token endpoint in PLUGIN_AUTH_URL. See the corresponding sections above for details on each configuration. You can restrict when the worker operates by configuring a specific time window. This is useful for scheduling reconciliation tasks during off-peak hours. The plugin supports time windows that span midnight.
If you leave both fields empty, the worker runs without time restrictions (24/7).
The worker always interprets the reconciliation window in the America/Sao_Paulo (BRT) timezone, whatever the container clock or the TZ variable. The worker embeds the IANA timezone data. The window stays aligned with the BACEN DICT write-block, even on minimal or distroless images. You do not need to set TZ.

Schedule worker


The schedule worker runs scheduled Pix payments when they are due. It is off by default. It calls the Application API with the same client-credential variables as the reconciliation worker.
Indirect Pix cashout and refund endpoints support idempotency through the X-Idempotency request header. The plugin keeps a replayable response for IDEMPOTENCY_RESPONSE_TTL seconds (default 86400, 24 hours). For retry strategies and implementation details, see Retries and idempotency.

10. Observability (OpenTelemetry)


The plugin ships with OpenTelemetry instrumentation (traces, metrics, and logs) across the Application and Worker layers. The plugin traces the Pix flows end to end: transfers (cash-in and cash-out), refunds, inbound and outbound webhooks, DICT reconciliation, and intra-PSP settlement. You can follow a single payment across the plugin, Midaz, CRM, and BTG calls. Telemetry is disabled by default. Enable it and point the OTLP exporter at your collector:
When ENABLE_TELEMETRY=true, OTEL_EXPORTER_OTLP_ENDPOINT is required. Set the same OTel variables on the Application and on each Worker so traces correlate across services.

Exporter: gRPC and TLS


The plugin exports traces, metrics, and logs over OTLP/gRPC. The endpoint scheme controls transport security:
When OTEL_RESOURCE_DEPLOYMENT_ENVIRONMENT is production or prod, the plugin refuses to start with an insecure exporter. Use an https:// endpoint, or set ALLOW_INSECURE_OTEL to a short justification only when you fully control the network path to the collector.

Example: collector endpoint


Point the plugin at any OTLP-compatible collector (the OpenTelemetry Collector, Grafana LGTM/Alloy, etc.) listening on the gRPC port:
The collector then fans telemetry out to your tracing, metrics, and logging backends.

11. Health and readiness


The Application and Workers expose a readiness probe at /readyz (alongside the standard liveness checks). Point your orchestrator’s readiness probe at this endpoint so traffic is only routed once the service and its dependencies are ready.

Transfer purpose (MED 2.0)


The cashout endpoint accepts an optional X-Purpose header that identifies the transaction purpose, used for MED 2.0 refund transfers. When omitted, it defaults to TRANSFER.
For the supported values, see Transfers.

Next steps


With the plugin configured, you can start operating Pix.