Retail accounts from account-service. Use Use on a row to set session
context for wallet and dev flows, or create a new account.
Get / Create Deposit Address
POST /api/wallet/deposits/address
List Deposit Addresses
GET /api/wallet/deposits/addresses
List Deposits GET /api/wallet/deposits
Get Deposit by ID GET /api/wallet/deposits/{id}
List Withdrawals GET /api/wallet/withdrawals
Get Withdrawal by ID
GET /api/wallet/withdrawals/{id}
Withdrawal trace across services/databases
End-to-end evidence for one withdrawal: wallet record, Fireblocks history, transaction-service records, ledger entries, ledger balances, and account balances.
Rolling 24 hours, same as
ensure_withdrawal_limit in wallet-service: statuses
pending_approval → completed count toward the cap (failed /
cancelled / rejected do not). Spent is the sum of usdt_cost (Binance
USDT-equivalent notional — same numeric scale as a USD daily cap for
stable pricing; not a different “currency” from USD). The daily cap is read from
WITHDRAWAL_DAILY_LIMIT_USDT or WITHDRAWAL_DAILY_LIMIT_USD (must
match wallet-service; if unset, 1000 — same as lib-limits).
Withdrawal limit usage
GET /api/withdrawal-limit-usage
List Swaps GET /api/wallet/swaps
Create Swap POST /api/wallet/swaps
Get Swap Quote GET /api/wallet/swaps/quote
Binance Orders GET /api/swap/orders
Ledger Entries GET /api/ledger
Shows one row per (account, coin, reserve) that has ledger entries.
Leave filter empty to include every account (e.g. operational
00000000…).
Transaction service — transactions table
Direct read from the transaction-service Postgres database (same rows the service
persists). Use TRANSACTION_DATABASE_URL if your DB name differs from
transaction_service.
transactions.Project databases — tables and columns
Full schema read from configured backoffice DB connections. Column names are shown exactly as they exist in Postgres (no display formatting).
Table data preview for testing
Load sample rows from any table using its real identifier names. This helps verify migrations and data shape quickly during manual testing.
List Coins GET /api/coin/list
Get Coin GET /api/coin/get
Resolve Coin ID GET /api/coin/resolve
Resolve by Slug GET /api/coin/resolve-by-slug
Admin: Save Coin (Create or Update) POST /api/coin/admin/update
Uses name + network as key: updates existing coin when found, creates a new one when not
found.
Optional fields (expand)
Create Withdrawal POST /api/wallet/withdrawals
Fireblocks vault withdrawals are sourced from this vault. Ledger ffffffff…ffff is the treasury ledger mirror.
On-chain address optional: set BACKOFFICE_TREASURY_DEPOSIT_ADDRESS in
backoffice env (same process as FIREBLOCKS_TREASURY_VAULT_ID).
Company aggregate custody (debit-normal). Withdrawal balance checks use this ledger account.
Get Withdrawal Quote
GET /api/wallet/withdrawals/quote
Fireblocks webhook log
Rows come from webhook_events in the
wallet-service database — every payload received on
POST /webhooks/fireblocks is stored for audit and replay (see
wallet-service persist_webhook_event).
User Management
Create passwordless users, list existing users, and manage MFA via user-service (port 50058). Dev creation uses the OTP bypass token.
Create Passwordless User
User Actions
Register Phone on User (SMS notifications)
Sets phone_number on user-service (not account-service). Auto-verifies OTP in dev mode.
User List (from DB)
Account Management (Admin)
BackofficeAccountService (account-service :50052) — list, inspect, lock/suspend/reset PIN on accounts.
List Accounts
Account Actions
Reset PIN
Special Accounts
All Transactions (Backoffice)
BackofficeTransactionService — list, review, approve, cancel transactions. Review/Approve/Cancel require OTP (use "000000" in dev).
Account Transactions
Review Transaction
Approve Transaction
Cancel Transaction
Treasury & Operational
Treasury Transactions
Requires dev operator permissions. If you get "permission denied", go to and click "Grant All Permissions to Dev Operator".
Operational Transactions
BCR Institutions (config-service)
BCR participant banks for LBTR. config-service port 50060.
Create Institution
Get / Update Institution
Services Health
Live TCP + DB pool check for gRPC services. Ledger is a Kafka worker (process + migration + Kafka + ledger-db). Auto-refreshes every 15 s.
gRPC Services
Databases
Infrastructure
Dev Operator Permissions
Grant all backoffice permissions to the dev operator (00000000-0000-0000-0000-000000000001).
Required to access Treasury, Operational, and other permission-gated endpoints.
Safe to run multiple times — auth-service is idempotent on grants.
Operational Flags
Kill switches for BCR payment rails. Changes are persisted to the
user_service DB (global_feature_flags table) and
published to Kafka topic operational.flags with key global.
Auto-refreshes every 5 seconds.
Enables inbound/outbound Transfer365 (BCR) payments.
Enables LBTR settlement rail (BCR Real-Time Gross Settlement).
loading…
LBTR / BCR Mock Producer
Injects messages into Kafka to simulate the BCR network. transaction-service consumes
lbtr.transfer.received and creates transactions.
Kafka broker: localhost:9093
· BCR REST mock:
http://127.0.0.1:8088/api/bcr
① Inject Incoming Transfer (BCR → us)
Publishes to lbtr.transfer.received. transaction-service creates a new
transaction and credits the account.
② Inject Status Update (BCR → us)
Publishes to
lbtr.status.incoming. Simulates BCR confirming or returning a transaction.
Quick Scenarios
③ Track Resulting Transaction & All State Changes
After injecting a transfer, see the created transaction, its status progression, ledger entries (debit/credit), and account balance changes. Auto-refreshes on status inject.
④ BCR Gateway — Outgoing Instructions Received
When lbtr-service processes an outgoing payment (e.g. a LBTR transfer our users send), it
calls the BCR Java gateway at
POST /api/lbtr/instrucciones. In dev, the backoffice mocks that gateway — all instructions
land here.
Transfer365 Lab
Stepper · saldos origem/destino · Externo↔eNorQuem envia o pacs.008 para a eNor (lado BCR).
📱 Transfer365 Mobile Registration
Register an E.164 phone on the selected account and seed identity-service keys for email/SMS notifications (dev only).
▾ Aguardando confirmação na rede (mock)
Tesouraria (backoffice) e envios da carteira: aprovados com saldo em reserva e pacs.008 em
input/, sem resposta BCR final. Confirmar na rede arquiva o pacs.008; depois
aplique a resposta no stepper (aba Avançado ou Respostas BCR).
▸ Scenarios (one-click flows)
▸ PACS message tester
Dry run — valida XSD (mesma regra do
transfer365-service); nada é gravado em output/
▸ Advanced tools
Transfer365 Mock Producer
Injects messages into Kafka to simulate the Transfer365 network. transaction-service consumes
transfer365.received and creates transactions.
Kafka broker: localhost:9093
Inject Received Transfer (transfer365.received)
Simulates Transfer365 sending an incoming payment. transaction-service will process and credit the account.
Inject Status Update (transfer365.received.status)
Updates the transaction status in
transaction-service via Kafka.
transfer365-service will log an error for
mock-injected transactions because they bypass its internal file engine (redb has no record). This is
harmless — transaction-service correctly processes the status update.
Quick Scenarios
③ Track Resulting Transaction & All State Changes
After injecting a transfer above, see the transaction created, its current status, ledger entries, and account balance. Auto-refreshes when you inject a status update.
Simulador de transferências
Ferramenta de testes (não é o sistema real do cliente). Serve para simular pagamentos que chegam do banco ou que a eNor envia, e ver se tudo foi processado certo.
Caminho recomendado: aba Simulador (batch BCR) · testes manuais em Fazer um teste · checklist em Relatórios de teste.
Resumo: quantos pagamentos estão em cada etapa. Número grande = quantidade de arquivos. Use Atualizar no topo.
Últimos arquivos:
Simulador BCR unificado — cria transações reais (depósito + reserva + operacional),
aplica respostas BCR (pacs.002 / pacs.004) e gera relatório pass/fail para todos os cenários da matriz.
Pré-requisitos: stack local (transfer365-service, Kafka, transaction/ledger-service), seed dev,
T365_APP_DIR igual no console e no serviço.
Ledger global (diagnóstico avançado)
Não é saldo da conta. Conta operacional global (00000000-…) é débito-normal:
saldo bruto negativo = fundos já implantados nas contas (esperado após top-ups e liquidações).
Reserva espelho acompanha o depósito reservado da conta origem.
Depósito = account_balances (igual ao header/Lab). Disponível + reservado = total.
Configuração
Progresso
Pronto
Plano de cobertura Transfer365 — lista todos os cenários que devem ser executados para validar o simulador (inbound, outbound, BCR, fila pendente, regressões). Marque o status de cada execução e exporte o checklist (JSON, CSV, Markdown ou PDF). O Transfer365 Lab continua a gravar a sessão com XML; use a aba Simulador para batch automático ou marque manualmente aqui.
Receber (banco → eNor)
Crédito inbound (pacs.008 simulado).
Conta eNor que será creditada.
Enviar (eNor → destino)
Obrigatório: dry run lib-transfer-validate antes do envio
real.
Conta eNor que envia (reserva saldo).
Ainda não há mensagens. Rode um dos testes acima.
Pedido e resposta
Situação: aguardando teste
XML manual na aba .
output/ (XSD);
outbound simula resposta do banco (pacs.002/004). Envio eNor (initiate/confirm) só na
aba Fazer um teste com lib-transfer-validate.
Inbound — banco → eNor
Passos 1→2→3 · validação XSD (não é lib-transfer-validate).
Escolha o tipo e preencha os campos; depois gere o XML.
Outbound — resposta do banco
Passos 1→2→3 · após envio eNor na aba Fazer um teste.
Resposta do banco sem colar XML (cenário + MsgId).
Pedido e resposta
Situação: aguardando
Configure o que o BCR devolve ao eNor: pacs.002 (grupo ou liquidação), pacs.004 (devolução) ou atalho
Kafka.
Os XML gerados vão para output/. No fluxo tesouraria/carteira pendente, use
Avançado
(confirmar na rede → stepper abaixo da fila).
Escolha o formato ISO ou um preset nomeado.
Para backend / API externa: o simulador T365 no console expõe os mesmos fluxos via
HTTP.
Em produção a sua API chama transaction-service (gRPC) com sessão real; em
dev use estas rotas do console
(cargo run -p console → localhost:8088).
1 · Catálogo de bancos (bank_code)
O bank_code no validate/initiate é o id desta
lista — não o BIC.
curl -sS "$BASE/api/institutions" | jq .
2 · Dry run — lib-transfer-validate (obrigatório antes do envio)
Equivalente ao botão « Validar transferência » / Passo 1 do E2E. Substitua
ACCOUNT_UUID, conta destino e bank_code.
curl -sS -X POST "$BASE/api/discovery/transfer/validate" \
-H "Content-Type: application/json" \
-d '{
"account_id": "ACCOUNT_UUID",
"coin_id": "00000000-0000-0000-0000-000000000000",
"amount": 10000,
"counterpart_type": "external",
"name": "Beneficiary Test",
"customer_type": 1,
"account_type": 2,
"account_number": "1010000007",
"bank_code": 6,
"document": "041234567"
}' | jq .
3 · Initiate + confirm (envio real no ledger)
Mesmo body do validate + description e channel.
Guarde transaction_id da resposta do initiate.
curl -sS -X POST "$BASE/api/discovery/transfer/initiate" \
-H "Content-Type: application/json" \
-d '{
"account_id": "ACCOUNT_UUID",
"coin_id": "00000000-0000-0000-0000-000000000000",
"amount": 10000,
"counterpart_type": "external",
"name": "Beneficiary Test",
"customer_type": 1,
"account_type": 2,
"account_number": "1010000007",
"bank_code": 6,
"document": "041234567",
"description": "curl test outbound",
"channel": 1
}' | jq .
curl -sS -X POST "$BASE/api/discovery/transfer/confirm" \
-H "Content-Type: application/json" \
-d '{
"account_id": "ACCOUNT_UUID",
"transaction_id": "TX_UUID_FROM_INITIATE"
}' | jq .
4 · File gateway — injetar XML (BCR → eNor)
Validação XSD: /api/simulator/t365/validate. Envio:
/api/simulator/t365/submit (grava em output/).
curl -sS -X POST "$BASE/api/simulator/t365/validate" \
-H "Content-Type: application/json" \
-d '{"xml":"<Document xmlns=\"urn:iso:std:iso:20022:tech:xsd:pacs.008.001.07\">...</Document>"}' | jq .
curl -sS -X POST "$BASE/api/simulator/t365/submit" \
-H "Content-Type: application/json" \
-d '{"xml":"...","processing_mode":"ift","dry_run":false}' | jq .
5 · Resposta do banco (pacs.002) após outbound T365
curl -sS -X POST "$BASE/api/simulator/t365/respond" \
-H "Content-Type: application/json" \
-d '{"scenario":"liquidate","original_msg_id":"MSGID_FROM_INPUT","amount":10000}' | jq .
Variável BASE (copiar/colar no terminal)
export BASE="http://localhost:8088"
Erro « Invalid bank code »? O bank_code não existe no catálogo ou
config-service está parado.
Confira com o passo 1. Conta origem: UUID em GET /api/accounts (aba Accounts) — o console
cria sessão dev automaticamente para discovery.
Só para técnicos: formulários detalhados para criar cada tipo de mensagem bancária. Se não tiver certeza, use a aba Fazer um teste.
Aguardando confirmação na rede (mock)
Transferências outgoing aprovadas com saldo em reserva e pacs.008 em
input/, mas ainda sem resposta BCR final. Passo 1: Confirmar na rede
(arquiva o pacs.008). Passo 2: escolha a resposta no stepper abaixo (liquidação, RJCT, ACCP, etc.)
e
Aplicar resposta.
Lista de arquivos que o sistema guardou durante os testes. Pode clicar para ver o conteúdo ou apagar pastas antigas.
Lista de arquivos
Registo do sistema (técnicos)
Últimas linhas do diário interno — útil se algo falhou e a equipa técnica pedir detalhe.
Passos do pagamento
Mostra, passo a passo, se o dinheiro foi creditado e confirmado. Atualiza sozinha após um teste.
—
Detalhe da conta e do saldo
Depois de simular um pagamento recebido, informe o número da conta (ou deixe preencher sozinho) e aperte « Ver detalhes » para ver transação e saldo.
BCR Gateway Mock
This backoffice replaces the external Java lbtr-gateway app.
lbtr-service calls POST /api/bcr/lbtr/instrucciones here when processing
outgoing payments.
Click ↓ JSON on any row to download the exact payload sent to the gateway.
BCR Test Environment Reference (from docs/BCR_CONTEXT.md — for lbtr-gateway Java app, not this mock)
SOAP Endpoints (test)
| Instrucciones | lbtrdes.bcr.gob.sv/lbtr-ws/InstruccionServiceSoapHttpPort |
| Lote | lbtrdes.bcr.gob.sv/lbtr-ws/LoteServiceSoapHttpPort |
| SPM (T365) | lbtrdes.bcr.gob.sv/lbtr-ws/ServicioPagoServiceSoapHttpPort |
| Server IP | 192.168.11.56 |
| Notif server | notificacioneslbtrdes.bcr.gob.sv (192.168.11.69) |
⚠ BCR internal network only — VPN / dedicated line required
WS-Security & Certificates
| Protocol | SOAP/WSDL Document/Wrapped |
| Security | OASIS WS-Security V1.2 · X.509 |
| Policy | Wssp1.2-2007-Wss1.1-X509-Basic256Sha256 |
| Keystore | lbtrcliente.jks (pw: lbtrcliente) |
| Truststore | lbtrcliente_truststore.jks |
| Key alias | lbtrcliente |
TraceableReference format (25 chars)
YYYYMMDD{entity:03}{correlative:05}{internal_ref:09}
Entity 089 = our participant. Date must
match today — BCR rejects mismatches.
Auto-generated in LBTR mock above. Implemented in
lib-bcr::lbtr::types::TraceableReference.
Full specs → docs/BCR_CONTEXT.md
in repo · Also see dev/console/TEAM_REVIEW_BACKLOG.md §8