Two-step flow
The two-step flow (
initiate → process) offers important advantages:
Display the fee before confirmation
Allowing the user to review the fee before confirming avoids surprises and reduces complaints.Confirmation example
Use expiration to your advantage
Initiation expires in 24 hours. This allows you to:- Save user intent without committing funds
- Resume the flow if user abandons the screen
- Validate data without balance impact
Time handling
Validate time on the client
Before calling the API, check if you’re within operating hours:Communicate clearly to user
If outside operating hours, inform when the transfer can be made:Consider holidays
The plugin doesn’t validate bank holidays, so keep an updated calendar.Idempotency
The TED plugin supports idempotency on three write endpoints: initiate, process, and cancel. Always send the
X-Idempotency-Key header on these requests to prevent duplicate processing. The server returns an X-Idempotency-Replayed response header (true or false) so you can distinguish fresh responses from cached replays.
For full details on retry strategies and idempotency behavior, see Retries and idempotency.
Use idempotency keys
For write operations, always send theX-Idempotency-Key header:
- User double-click
- Automatic retry on timeout
- Network failures that mask success responses
Check the replayed header
Always inspect theX-Idempotency-Replayed response header. When it returns true, the response is a cached replay of a previous request — do not process it as a new operation.
Generate keys on client
Generate the idempotency key before making the request and store it until confirming the result:Error handling
Map errors to friendly messages
Differentiate recoverable errors
| Code | Recoverable | Action |
|---|---|---|
BTF-0001 | No | Fix data and resubmit |
BTF-0010 | Yes | Wait for operating hours |
BTF-0011 | Yes | Wait for limit reset (midnight) |
BTF-0012 | No | Wait or use different combination |
BTF-2001 | Yes | Deposit funds and try again |
BTF-1000 | Yes | Retry with exponential backoff |
Implement smart retry
Security
Encryption in transit
All communications use TLS 1.2+ (TLS 1.3 preferred):- JD Consultores SPB (SOAP over HTTPS)
- Midaz Ledger (gRPC with TLS)
- CRM and Plugin Fees (HTTPS)
- Webhooks (HTTPS required)
Encryption at rest
Sensitive data is encrypted with AES-256-GCM:- JD credentials
- PII (name, CPF/CNPJ, bank details)
- Webhook secrets
Validate data on server
Never rely solely on client-side validation:Protect sensitive data
- Don’t log CPF/CNPJ in plain text
- Use keyed HMAC-SHA256 or per-record salted hashes (with proper salt management) for identification in logs — avoid unsalted hashes
- These outputs must be treated as pseudonymized PII and protected accordingly
- Rotate and secure HMAC keys and salts regularly
- Mask data in interface:
***.***.***-00 - Never log raw identifiers in functions or components that produce logs
Validate webhooks
Always verify HMAC-SHA256 signature before processing:Fraud prevention
Duplicate detection
The plugin implements configurable deduplication window (default: 60 seconds):- Key:
SHA256(organizationId + senderAccountId + recipient + amount) - Storage: Redis with configurable TTL
- Action: Duplicate requests return
409 Conflict
Rate limiting
Protection against abuse per tenant:| Configuration | Default value |
|---|---|
| Algorithm | Token Bucket |
| Limit | 100 requests/minute per organization |
| Response | 429 Too Many Requests with Retry-After header |
Multi-tenant isolation
All queries are filtered byorganization_id, ensuring a tenant never accesses another’s data. Redis cache also uses per-tenant prefixes.
User experience
Show progress
For TED OUT, keep the user informed:Use webhooks for real-time updates
Configure webhooks and use WebSocket or push notifications to update the interface:Offer receipt
After completion, allow receipt download with:- Transfer date and time
- Sender and recipient data
- Amount and fee
- Confirmation number
- Control code (for TED)
Reconciliation
Use consistent identifiers
| Field | Usage |
|---|---|
transferId | Internal identifier (Lerian) |
confirmationNumber | User-readable number |
controlNumber | SPB tracking (JD) |
Maintain local history
Periodically sync with API to ensure consistency:Limits and quotas
Monitor limit usage
Check current usage before initiating transfers:Communicate limits proactively
BACEN compliance
Operating hours
The system automatically validates BACEN hours for TED:- Business days: Monday to Friday
- Hours: 06:30 to 17:00 (Brasília time, UTC-3)
- Holidays: System queries national holiday calendar
P2P transfers are not subject to this restriction and work 24/7.
Transfer limits
The plugin respects limits configured per account and per organization:- Per-transaction limit: Configurable per tenant (default: R$ 50,000)
- Daily limit: Sum of all transfers for the day
- Monthly limit: Aggregate volume control
Audit and traceability
Every state change is recorded in theTransferStatusHistory table:
- Previous and new status: Complete transition
- Timestamp: Exact date and time of change
- Reason: Transition reason (especially for errors)
- Author: System, user, or administrator
Implement audit trail
Record all transfer-related actions:LGPD compliance
Data minimization
Collect only strictly necessary data. CPF/CNPJ are encrypted and used only for validation and compliance.Right to be forgotten
Administrative endpoint for personal data anonymization:Limited retention
| Data type | Retention period |
|---|---|
| Transaction data | 5 years (BACEN requirement) |
| Application logs | 90 days |
| Audit data | 5 years (anonymized after 2 years) |
Certifications and standards
The plugin was developed following industry best practices:
- OWASP Top 10: Mitigation of common vulnerabilities
- CIS Benchmarks: Secure infrastructure configuration
- ISO 27001: Information security management practices
- SOC 2 Type II: Security, availability, and confidentiality controls
Lerian follows SOC 2 Type II and ISO 27001 practices. For current certification status and audit reports, contact Lerian directly.

