# Monetarie SPB -- Partner Integration Guide

**Version:** 1.0
**Date:** 2026-02-07
**Classification:** Confidential -- Partner Distribution Only
**Contact:** integracoes@fluxiq.com.br

---

## Table of Contents

1. [Overview](#1-overview)
2. [Prerequisites](#2-prerequisites)
3. [Authentication](#3-authentication)
4. [API Reference](#4-api-reference)
5. [Message Types](#5-message-types)
6. [IBM MQ Integration](#6-ibm-mq-integration)
7. [Security Requirements](#7-security-requirements)
8. [Error Handling](#8-error-handling)
9. [Webhooks & Events](#9-webhooks--events)
10. [Testing with Simulator](#10-testing-with-simulator)
11. [Onboarding Checklist](#11-onboarding-checklist)
12. [Appendix A -- NATS Topic Reference](#appendix-a--nats-topic-reference)
13. [Appendix B -- XML Envelope Examples](#appendix-b--xml-envelope-examples)

---

## 1. Overview

Monetarie SPB is a cloud-native integration platform for the Brazilian Central Bank's Sistema de Pagamentos Brasileiro (SPB). It provides a complete gateway between financial institutions and BACEN's RSFN (Rede do Sistema Financeiro Nacional) network.

### What Monetarie SPB Does

- Sends and receives all 1,222 BACEN message types across 36 categories
- Routes messages through 5 IBM MQ domains with priority-based delivery
- Signs and verifies XML messages with ICP-Brasil certificates (XMLDSig, RSA-SHA256)
- Provides a REST API for programmatic message submission and tracking
- Distributes internal events via NATS JetStream for real-time processing
- Maintains a complete audit trail for compliance with BACEN regulations

### Architecture Summary

```
Partner System                     Monetarie SPB                         BACEN/RSFN
+--------------+     REST API     +-------------------+   IBM MQ    +----------+
|              | ----------------> |  API Gateway      | ----------> |          |
|  Your        |     HTTPS/JWT    |  (port 4000)      |  AMQP 1.0  |  RSFN    |
|  Application | <--------------- |                   | <---------- |  Network |
|              |                  +-------------------+   mTLS      |          |
+--------------+                  |  BACEN Gateway    |             +----------+
                                  |  (port 4002)      |
                                  +-------------------+
                                  |  NATS JetStream   |
                                  |  (port 4222)      |
                                  +-------------------+
```

### Key Numbers

| Metric | Value |
|--------|-------|
| Supported message types | 1,222 |
| Message categories | 36 (STR, LPI, PAG, SEL, LDL, CAM, CIR, CTP, DDA, etc.) |
| IBM MQ domains | 5 (SPB01, SPB02, MES01, MES02, MES03) |
| Error codes mapped | 5,306+ |
| Financial institutions indexed | 494+ |
| Domain values indexed | 7,541+ |
| Max message size | 4 MB (4,194,304 bytes) |
| Max queue depth per queue | 1,000,000 messages |

### Monetarie ISPB

Monetarie operates under ISPB **12345678**. All message routing, queue naming, and channel configurations reference this ISPB. BACEN's ISPB is **00038166**.

---

## 2. Prerequisites

Before integrating with Monetarie SPB, your institution must have the following:

### 2.1 BACEN Registration

- **Valid ISPB** (Identificador do Sistema de Pagamentos Brasileiro): An 8-digit code assigned by BACEN to your institution. This is used in all queue names, channel definitions, and message routing.
- **Active participant status** in the SPB. Your institution must be registered and active with BACEN to exchange messages.

### 2.2 Digital Certificates

- **ICP-Brasil A1 or A3 certificate** issued by a BACEN-authorized Certificate Authority. This certificate is used for:
  - mTLS authentication on IBM MQ channels
  - XMLDSig signing of outbound messages
  - Verification of inbound message signatures
- The certificate must be issued to your institution's CNPJ and must not be expired or revoked.

### 2.3 Network Access

- **RSFN network access**: Either a dedicated leased line (link dedicado) or an approved VPN connection to the RSFN network. Monetarie runs within this network perimeter.
- **Firewall rules**: Your institution must allow outbound connections to the following ports on the Monetarie MQ host:

| Port | Protocol | Purpose |
|------|----------|---------|
| 1414 | TCP/TLS | SPB01 domain (STR/LPI -- Platina priority) |
| 5672 | TCP/TLS | AMQP 1.0 service (default) |
| 12422 | TCP/TLS | MES01 domain (Reserved -- Platina) |
| 13422 | TCP/TLS | MES02 domain (General -- Prata) |
| 14422 | TCP/TLS | MES03 domain (General -- Bronze) |
| 15422 | TCP/TLS | SPB02 domain (Settlement -- Ouro) |

### 2.4 IBM MQ Client

- IBM MQ client library version 9.3+ with AMQP 1.0 support, or any AMQP 1.0-compatible client library. Monetarie uses the `amqp10_client` Erlang library internally.
- The client must support TLS 1.2 or higher with the cipher suite `ECDHE_RSA_AES_256_GCM_SHA384`.

### 2.5 API Client (Optional)

If you plan to use the REST API rather than direct MQ integration:

- An HTTP client capable of making TLS-secured requests
- Support for Bearer token authentication (JWT)
- JSON parsing capability for request/response bodies

---

## 3. Authentication

### 3.1 API Authentication (REST)

The Monetarie API uses JWT (JSON Web Token) Bearer authentication. Tokens are issued by the Auth Service (port 4001) and validated by the API Gateway (port 4000).

#### Login

```http
POST /api/auth/login
Content-Type: application/json

{
  "email": "operator@yourbank.com.br",
  "password": "your-secure-password"
}
```

**Response (200 OK):**

```json
{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "user": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "email": "operator@yourbank.com.br",
    "role": "operator",
    "institution_ispb": "12345678"
  },
  "expires_in": 86400
}
```

#### Using the Token

Include the token in the `Authorization` header for all subsequent requests:

```http
GET /api/messages
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
```

#### Token Refresh

```http
POST /api/auth/refresh
Content-Type: application/json
Authorization: Bearer <current-token>
```

**Response (200 OK):**

```json
{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...<new-token>",
  "expires_in": 86400
}
```

#### Token Verification

To check if a token is still valid without making a full API request:

```http
POST /api/auth/verify
Content-Type: application/json

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
```

**Response (200 OK):**

```json
{
  "valid": true,
  "user_id": "550e8400-e29b-41d4-a716-446655440000",
  "role": "operator",
  "expires_at": "2026-02-08T12:00:00Z"
}
```

#### Token Validity

- Tokens are valid for **24 hours** (86,400 seconds) by default
- Tokens can be refreshed at any time before expiry
- After expiry, a new login is required
- Invalid or expired tokens return `401 Unauthorized`

### 3.2 SSO Integration

Monetarie supports Single Sign-On through a shared secret mechanism. If your institution uses the Monetarie Backoffice, SSO tokens are generated using the `MONETARIE_SSO_SECRET` environment variable. The SSO flow is:

1. User authenticates in your institution's portal
2. Your portal generates an SSO token using the shared secret
3. The token is passed to Monetarie SPB via the `/api/auth/sso` endpoint
4. Monetarie validates the token and issues a standard JWT

Contact the Monetarie integration team to obtain your SSO shared secret.

### 3.3 IBM MQ Authentication

IBM MQ connections use mutual TLS (mTLS) with ICP-Brasil certificates. No username/password is required for MQ connections -- authentication is certificate-based.

**Certificate requirements:**

- Format: PEM (X.509)
- Key algorithm: RSA 2048-bit or higher
- Signature algorithm: SHA-256 or higher
- Chain: Full certificate chain including intermediate CAs
- TLS cipher: `ECDHE_RSA_AES_256_GCM_SHA384`

**Connection flow:**

1. Client presents ICP-Brasil certificate during TLS handshake
2. Queue Manager validates certificate against the ICP-Brasil CA chain
3. Channel Authentication (CHLAUTH) rules verify the client certificate subject
4. On successful authentication, the client session is bound to the `app` MCA user

---

## 4. API Reference

All API endpoints are served by the API Gateway at `https://spbapi-dev.fluxiq.com.br` (development) or your production URL.

### 4.1 Health & Status

#### GET /api/health

System health check. Returns current operational status.

```http
GET /api/health
```

**Response (200 OK):**

```json
{
  "status": "healthy",
  "timestamp": "2026-02-07T10:30:00Z",
  "services": {
    "database": "connected",
    "nats": "connected",
    "ibm_mq": {
      "spb01": "connected",
      "spb02": "connected",
      "mes01": "connected",
      "mes02": "connected",
      "mes03": "connected"
    }
  },
  "version": "1.0.0"
}
```

#### GET /api/ready

Kubernetes readiness probe. Returns 200 when the service is ready to accept traffic.

```http
GET /api/ready
```

**Response (200 OK):**

```json
{
  "ready": true
}
```

#### GET /metrics

Prometheus metrics endpoint. No authentication required (intended for GMP scraping).

```http
GET /metrics
```

**Response (200 OK):**

```
# HELP spb_messages_total Total messages processed
# TYPE spb_messages_total counter
spb_messages_total{category="STR",status="confirmed"} 1523
spb_messages_total{category="STR",status="failed"} 12
...
```

### 4.2 Messages API

#### POST /api/messages

Submit a new BACEN message for processing.

```http
POST /api/messages
Authorization: Bearer <token>
Content-Type: application/json

{
  "message_type": "STR0004",
  "xml_content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?><BCMSG>...</BCMSG>",
  "destination_ispb": "00038166",
  "priority": "high",
  "metadata": {
    "reference_id": "your-internal-ref-001",
    "department": "treasury"
  }
}
```

**Response (201 Created):**

```json
{
  "id": "a3f2b5c7-89d4-4e6f-b123-456789abcdef",
  "message_type": "STR0004",
  "status": "pending",
  "destination_ispb": "00038166",
  "domain": "spb01",
  "created_at": "2026-02-07T10:35:00Z",
  "state_history": [
    {
      "status": "pending",
      "timestamp": "2026-02-07T10:35:00Z",
      "detail": "Message accepted for processing"
    }
  ]
}
```

**Error Responses:**

| Code | Description |
|------|-------------|
| 400 | Invalid request body or message format |
| 401 | Missing or invalid authentication token |
| 422 | Validation error (invalid message type, missing fields) |
| 503 | Target MQ domain unavailable |

#### GET /api/messages

List messages with optional filters.

```http
GET /api/messages?status=confirmed&category=STR&from=2026-02-01&to=2026-02-07&page=1&per_page=50
Authorization: Bearer <token>
```

**Query Parameters:**

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| status | string | No | Filter by status: pending, processing, sent, confirmed, failed, timeout |
| category | string | No | Filter by message category: STR, LPI, PAG, SEL, LDL, CAM, etc. |
| message_type | string | No | Filter by specific message type: STR0004, PAG0101, etc. |
| from | date | No | Start date (ISO 8601) |
| to | date | No | End date (ISO 8601) |
| destination_ispb | string | No | Filter by destination ISPB |
| page | integer | No | Page number (default: 1) |
| per_page | integer | No | Results per page (default: 25, max: 100) |

**Response (200 OK):**

```json
{
  "data": [
    {
      "id": "a3f2b5c7-89d4-4e6f-b123-456789abcdef",
      "message_type": "STR0004",
      "category": "STR",
      "status": "confirmed",
      "destination_ispb": "00038166",
      "domain": "spb01",
      "created_at": "2026-02-07T10:35:00Z",
      "updated_at": "2026-02-07T10:35:02Z"
    }
  ],
  "meta": {
    "page": 1,
    "per_page": 25,
    "total": 1523,
    "total_pages": 61
  }
}
```

#### GET /api/messages/:id

Get a single message with its full state history.

```http
GET /api/messages/a3f2b5c7-89d4-4e6f-b123-456789abcdef
Authorization: Bearer <token>
```

**Response (200 OK):**

```json
{
  "id": "a3f2b5c7-89d4-4e6f-b123-456789abcdef",
  "message_type": "STR0004",
  "category": "STR",
  "status": "confirmed",
  "xml_content": "<?xml version=\"1.0\"?>...",
  "destination_ispb": "00038166",
  "source_ispb": "12345678",
  "domain": "spb01",
  "priority": "platina",
  "metadata": {
    "reference_id": "your-internal-ref-001"
  },
  "state_history": [
    {"status": "pending", "timestamp": "2026-02-07T10:35:00Z", "detail": "Message accepted"},
    {"status": "processing", "timestamp": "2026-02-07T10:35:00Z", "detail": "Signing and routing"},
    {"status": "sent", "timestamp": "2026-02-07T10:35:01Z", "detail": "Sent via SPB01 domain"},
    {"status": "confirmed", "timestamp": "2026-02-07T10:35:02Z", "detail": "BACEN confirmation received"}
  ],
  "created_at": "2026-02-07T10:35:00Z",
  "updated_at": "2026-02-07T10:35:02Z"
}
```

#### PUT /api/messages/:id

Update a message record (limited to metadata changes on pending messages).

```http
PUT /api/messages/a3f2b5c7-89d4-4e6f-b123-456789abcdef
Authorization: Bearer <token>
Content-Type: application/json

{
  "metadata": {
    "reference_id": "updated-ref-001",
    "department": "treasury"
  }
}
```

#### DELETE /api/messages/:id

Cancel a pending message (only messages in `pending` status can be cancelled).

```http
DELETE /api/messages/a3f2b5c7-89d4-4e6f-b123-456789abcdef
Authorization: Bearer <token>
```

#### GET /api/messages/categories

List all available message categories with counts.

```http
GET /api/messages/categories
Authorization: Bearer <token>
```

**Response (200 OK):**

```json
{
  "categories": [
    {"code": "STR", "name": "Reserve Transfer System", "message_count": 77},
    {"code": "LPI", "name": "Instant Payment Liquidity", "message_count": 15},
    {"code": "CAM", "name": "Foreign Exchange", "message_count": 111},
    {"code": "CIR", "name": "Cash/Currency", "message_count": 100}
  ]
}
```

#### GET /api/messages/states

List all possible message states.

```http
GET /api/messages/states
Authorization: Bearer <token>
```

**Response (200 OK):**

```json
{
  "states": [
    {"name": "pending", "description": "Message accepted, awaiting processing"},
    {"name": "processing", "description": "Message being signed and routed"},
    {"name": "sent", "description": "Message sent to BACEN via IBM MQ"},
    {"name": "confirmed", "description": "BACEN acknowledged receipt"},
    {"name": "failed", "description": "Message processing failed"},
    {"name": "timeout", "description": "No BACEN response within timeout"}
  ]
}
```

### 4.3 Payments API

#### POST /api/payments

Create a payment transaction (STR transfer, TED, or DOC).

```http
POST /api/payments
Authorization: Bearer <token>
Content-Type: application/json

{
  "type": "STR",
  "amount": 150000.00,
  "currency": "BRL",
  "sender": {
    "ispb": "12345678",
    "account": "00001234-5",
    "name": "MONETARIE INSTITUICAO DE PAGAMENTO",
    "document": "12345678000100"
  },
  "receiver": {
    "ispb": "00038166",
    "account": "00009876-1",
    "name": "Banco do Brasil S.A.",
    "document": "00000000000191"
  },
  "purpose_code": "01",
  "description": "Interbank reserve transfer"
}
```

**Response (201 Created):**

```json
{
  "id": "b4e3c6d8-90e5-5f7a-c234-567890bcdef0",
  "type": "STR",
  "status": "pending",
  "amount": 150000.00,
  "currency": "BRL",
  "message_id": "a3f2b5c7-89d4-4e6f-b123-456789abcdef",
  "created_at": "2026-02-07T10:40:00Z"
}
```

#### GET /api/payments

List payments with optional filters. Supports the same query parameters as `/api/messages` plus `type` (STR, TED, DOC).

```http
GET /api/payments?type=STR&status=confirmed&page=1
Authorization: Bearer <token>
```

#### GET /api/payments/:id

Get payment detail with associated message information.

```http
GET /api/payments/b4e3c6d8-90e5-5f7a-c234-567890bcdef0
Authorization: Bearer <token>
```

### 4.4 Transactions API

The Transactions API is an alias for the Payments API. All endpoints under `/api/transactions` map to the same underlying functionality as `/api/payments`.

| Transactions Endpoint | Equivalent Payments Endpoint |
|-----------------------|------------------------------|
| POST /api/transactions | POST /api/payments |
| GET /api/transactions | GET /api/payments |
| GET /api/transactions/:id | GET /api/payments/:id |

### 4.5 Dashboard API

#### GET /api/dashboard/stats

Returns aggregated statistics for the dashboard.

```http
GET /api/dashboard/stats
Authorization: Bearer <token>
```

**Response (200 OK):**

```json
{
  "total_messages": 15230,
  "messages_today": 342,
  "success_rate": 97.8,
  "active_domains": 5,
  "by_status": {
    "pending": 12,
    "processing": 3,
    "sent": 45,
    "confirmed": 14850,
    "failed": 180,
    "timeout": 140
  },
  "by_category": {
    "STR": 3200,
    "PAG": 4100,
    "LDL": 2800,
    "CAM": 1900,
    "SEL": 1500,
    "CIR": 800,
    "other": 930
  },
  "throughput": {
    "messages_per_minute": 23.5,
    "avg_response_time_ms": 145
  }
}
```

#### GET /api/dashboard/recent-activity

Returns the most recent message activity.

```http
GET /api/dashboard/recent-activity?limit=20
Authorization: Bearer <token>
```

**Response (200 OK):**

```json
{
  "activities": [
    {
      "id": "a3f2b5c7-89d4-4e6f-b123-456789abcdef",
      "message_type": "STR0004",
      "status": "confirmed",
      "destination_ispb": "00038166",
      "timestamp": "2026-02-07T10:35:02Z"
    }
  ]
}
```

### 4.6 Statistics API

#### GET /api/stats/by-state

Message count grouped by current state.

```http
GET /api/stats/by-state
Authorization: Bearer <token>
```

#### GET /api/stats/by-category

Message count grouped by category (STR, PAG, LDL, etc.).

```http
GET /api/stats/by-category
Authorization: Bearer <token>
```

### 4.7 Message Templates API

#### GET /api/message-templates

List all available message templates (1,222 types).

```http
GET /api/message-templates?category=STR
Authorization: Bearer <token>
```

**Response (200 OK):**

```json
{
  "templates": [
    {
      "message_type": "STR0004",
      "category": "STR",
      "description": "Requisicao de transferencia de reservas bancarias",
      "catalog_version": "5.11",
      "xml_template": "<?xml version=\"1.0\"?>..."
    }
  ]
}
```

### 4.8 Users & Groups API

#### Users

| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | /api/users | List all users |
| GET | /api/users/:id | Get user detail |
| POST | /api/users | Create user |
| PUT | /api/users/:id | Update user |
| DELETE | /api/users/:id | Delete user |

#### Groups

| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | /api/groups | List all groups |
| GET | /api/groups/:id | Get group detail |
| POST | /api/groups | Create group |
| PUT | /api/groups/:id | Update group |
| DELETE | /api/groups/:id | Delete group |

---

## 5. Message Types

### 5.1 Category Reference

Monetarie SPB supports all 36 BACEN message categories encompassing 1,222 individual message types. Each category is routed to a specific MQ domain based on its priority classification.

| Category | Full Name | Description | Priority | Domain |
|----------|-----------|-------------|----------|--------|
| BMA | B3 Market | B3 stock exchange market operations | Bronze | MES03 |
| BMC | Collection Messages | Banking collection and billing operations | Bronze | MES03 |
| BVF | B3 Funds | B3 investment fund operations | Bronze | MES03 |
| CAM | Foreign Exchange | Foreign exchange and currency operations | Bronze | MES03 |
| CBL | B3 Clearing | B3 clearing house settlement operations | Ouro | SPB02 |
| CCR | Reciprocal Credit | International reciprocal credit agreements | Prata | MES02 |
| CCS | SFN Client Registry | Financial system client registry operations | Prata | MES02 |
| CIR | Cash/Currency | Cash and currency circulation operations | Bronze | MES03 |
| CLI | B3 Client | B3 client management operations | Bronze | MES03 |
| CMP | Reserve Requirements | Compulsory reserve requirement operations | Platina | SPB01 |
| COR | Correspondence | Inter-institutional correspondence messages | Prata | MES02 |
| CQL | LDL Quality Control | Deferred settlement quality control | Ouro | SPB02 |
| CSD | System/Domain Registry | System and domain configuration registry | Prata | MES02 |
| CTP | Securities Custody | Securities custody and safekeeping operations | Ouro | SPB02 |
| DDA | Direct Debit Auth | Direct debit authorization and processing | Prata | MES02 |
| ECR | Credit Execution | Credit execution and settlement operations | Ouro | SPB02 |
| GEN | Generic Control | Generic system control and status messages | Platina | SPB01 |
| HDT | Host Data Transfer | Host-to-host data transfer operations | Prata | MES02 |
| LDL | Deferred Settlement | Deferred net settlement operations | Ouro | SPB02 |
| LEI | Auction | Public auction and bidding operations | Prata | MES02 |
| LFL | Financial Settlement | Financial settlement through STR | Platina | SPB01 |
| LPI | Instant Payment Liquidity | Instant payment reserve and liquidity operations | Platina | SPB01 |
| LTR | Security Auction | Government securities auction operations | Ouro | SPB02 |
| PAG | Payments | Payment processing -- TED, DOC, and Boleto | Bronze | MES03 |
| PTX | Transaction Protocol | Transaction protocol control messages | Prata | MES02 |
| RCO | Reserve Collection | Compulsory reserve collection operations | Platina | SPB01 |
| RDC | Rediscount | Central bank rediscount operations | Platina | SPB01 |
| RGT | Registry | Entity and participant registry operations | Prata | MES02 |
| SCG | Security Configuration | Security parameter configuration | Prata | MES02 |
| SEL | SELIC Settlement | SELIC government securities settlement | Ouro | SPB02 |
| SLB | Bilateral Settlement | Bilateral clearing and settlement operations | Ouro | SPB02 |
| SLC | Card Settlement | Card payment settlement operations | Ouro | SPB02 |
| SME | Secondary Market | Secondary market securities operations | Ouro | SPB02 |
| SML | Local Currency Payment | Cross-border local currency payment operations | Prata | MES02 |
| SRC | Reserve and Exchange | Reserve account and exchange operations | Platina | SPB01 |
| STR | Reserve Transfer | Interbank reserve transfer operations | Platina | SPB01 |
| TES | National Treasury | National Treasury securities operations | Ouro | SPB02 |

### 5.2 Message Structure (ISO 20022)

All BACEN messages use an XML envelope structure compliant with ISO 20022. The envelope has three nested layers:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<BCMSG xmlns="http://www.bcb.gov.br/SPB">
  <!-- BACEN Message Envelope -->
  <IdentdEmissor>12345678</IdentdEmissor>       <!-- Sender ISPB -->
  <IdentdDesworko>00038166</IdentdDesworko>     <!-- Receiver ISPB -->
  <IdentdMsgNegWorko>MSG2026020712350001</IdentdMsgNegWorko>
  <DtHrMsgNeg>2026-02-07T12:35:00</DtHrMsgNeg>  <!-- Timestamp -->

  <SISMSG>
    <!-- System Message Layer -->
    <CodMsg>STR0004</CodMsg>                      <!-- Message type code -->
    <NumCtrlIF>CTRL2026020700001</NumCtrlIF>       <!-- Institution control number -->
    <DtHrMsg>2026-02-07T12:35:00</DtHrMsg>

    <!-- Message Body (varies by type) -->
    <DOC xmlns="http://www.bcb.gov.br/SPB/STR0004">
      <InfTransf>
        <ISPBIfDeworko>00038166</ISPBIfDeworko>
        <VlrTransf>150000.00</VlrTransf>
        <FinlddSTR>01</FinlddSTR>
        <DtMovto>2026-02-07</DtMovto>
      </InfTransf>
    </DOC>
  </SISMSG>

  <!-- XMLDSig Signature Block -->
  <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
    <SignedInfo>
      <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
      <SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
      <Reference URI="#KeyInfo">...</Reference>
      <Reference URI="#AppHdr">...</Reference>
      <Reference URI="#Document">...</Reference>
    </SignedInfo>
    <SignatureValue>...</SignatureValue>
    <KeyInfo Id="KeyInfo">
      <X509Data>
        <X509Certificate>...</X509Certificate>
      </X509Data>
    </KeyInfo>
  </Signature>
</BCMSG>
```

**Key elements:**

| Element | Location | Description |
|---------|----------|-------------|
| `IdentdEmissor` | BCMSG | Sender ISPB (8 digits) |
| `IdentdDesworko` | BCMSG | Receiver ISPB (8 digits) |
| `CodMsg` | SISMSG | Message type code (e.g., STR0004, PAG0101) |
| `NumCtrlIF` | SISMSG | Unique institution control number for idempotency |
| `DtHrMsg` | SISMSG | Message creation timestamp (ISO 8601) |
| `DOC` | SISMSG | Message body -- schema varies by message type |
| `Signature` | BCMSG | XMLDSig signature with 3 references |

### 5.3 Message States

Messages transition through the following states:

```
pending --> processing --> sent --> confirmed
                |              |
                v              v
              failed        timeout
```

| State | Description | NATS Event |
|-------|-------------|------------|
| pending | Message accepted and queued for processing | `messages.new` |
| processing | Message being validated, signed, and routed | `messages.processing` |
| sent | Message dispatched to BACEN via IBM MQ | `messages.sent` |
| confirmed | BACEN acknowledged successful receipt | `messages.confirmed` |
| failed | Processing failed (see error code) | `messages.failed` |
| timeout | No BACEN response within timeout period | `messages.timeout` |

**Retry policy:**

- Messages in `failed` state with retryable error codes are automatically retried up to 3 times with exponential backoff (5s, 15s, 45s).
- Messages in `timeout` state are retried once after 60 seconds.
- Messages that exhaust all retries are moved to the Dead Letter Queue (DLQ).

### 5.4 Catalog Versions

Most message types use catalog version **5.11** (the current BACEN standard). Some older message types use earlier versions. The system maintains a version map for all 1,222 types. When creating messages, the appropriate catalog version is automatically applied based on the message type. Notable non-5.11 versions include:

| Category | Version Range | Notes |
|----------|---------------|-------|
| BMA | 4.11 | B3 Market messages use older schema |
| BVF | 3.06 -- 5.01 | B3 Funds mixed versions |
| CAM | 3.03 -- 5.06 | Foreign Exchange mixed versions |
| CBL | 4.08 -- 4.11 | B3 Clearing older schemas |
| CLI | 4.13 | B3 Client management |
| PAG | 3.03 -- 3.06 | Payment messages on older schemas |

---

## 6. IBM MQ Integration

### 6.1 Domain Architecture

Monetarie SPB connects to BACEN through 5 independent IBM MQ domains, each with its own Queue Manager, port, channel, and priority level. This multi-domain architecture follows BACEN's Manual de Redes v9.3 specification.

| Domain | Queue Manager | Port | Channel | Priority | Message Types |
|--------|--------------|------|---------|----------|---------------|
| SPB01 | QM.{ISPB}.01 | 1414 | C{ISPB}.00038166.1 | Platina | STR, LPI, GEN, LFL, CMP, RCO, RDC, SRC |
| SPB02 | QM.{ISPB}.05 | 15422 | C{ISPB}.00038166.2 | Ouro | SEL, LDL, CTP, CBL, ECR, LTR, SLB, SLC, SME, TES |
| MES01 | QM.{ISPB}.02 | 12422 | C{ISPB}.00038166.3 | Platina | Reserved for future BACEN use |
| MES02 | QM.{ISPB}.03 | 13422 | C{ISPB}.00038166.4 | Prata | CCR, CCS, COR, CSD, DDA, HDT, LEI, PTX, RGT, SCG, SML |
| MES03 | QM.{ISPB}.04 | 14422 | C{ISPB}.00038166.5 | Bronze | BMA, BMC, BVF, CAM, CIR, CLI, PAG |

Replace `{ISPB}` with your institution's 8-digit ISPB code. For Monetarie, this is `12345678`.

**Example for Monetarie (ISPB 12345678):**

| Domain | Queue Manager | Channel |
|--------|--------------|---------|
| SPB01 | QM.12345678.01 | C12345678.00038166.1 |
| SPB02 | QM.12345678.05 | C12345678.00038166.2 |
| MES01 | QM.12345678.02 | C12345678.00038166.3 |
| MES02 | QM.12345678.03 | C12345678.00038166.4 |
| MES03 | QM.12345678.04 | C12345678.00038166.5 |

### 6.2 Queue Naming Convention

Each domain has 4 queues plus a shared Dead Letter Queue:

| Queue Pattern | Direction | Purpose |
|---------------|-----------|---------|
| `QL.REQ.{ISPB_DEST}.{ISPB_ORIG}.{seq}` | Outbound | Send requests to BACEN |
| `QL.RSP.{ISPB_ORIG}.{ISPB_DEST}.{seq}` | Inbound | Receive responses from BACEN |
| `QR.REQ.{ISPB_DEST}.{ISPB_ORIG}.{seq}` | Outbound | Retry queue for requests |
| `QR.RSP.{ISPB_ORIG}.{ISPB_DEST}.{seq}` | Inbound | Retry queue for responses |
| `QL.DLQ.{ISPB}` | N/A | Dead Letter Queue (shared across domains) |

**Sequence numbers by domain:**

| Domain | Sequence |
|--------|----------|
| SPB01 | 01 |
| SPB02 | 02 |
| MES01 | 03 |
| MES02 | 04 |
| MES03 | 05 |

**Complete queue list for Monetarie (ISPB 12345678, BACEN ISPB 00038166):**

```
# SPB01 (seq 01) - Platina
QL.REQ.00038166.12345678.01    # Outbound requests
QL.RSP.00038166.12345678.01    # Inbound responses
QR.REQ.00038166.12345678.01    # Request retry
QR.RSP.12345678.00038166.01    # Response retry

# SPB02 (seq 02) - Ouro
QL.REQ.00038166.12345678.02
QL.RSP.00038166.12345678.02
QR.REQ.00038166.12345678.02
QR.RSP.12345678.00038166.02

# MES01 (seq 03) - Platina (Reserved)
QL.REQ.00038166.12345678.03
QL.RSP.00038166.12345678.03
QR.REQ.00038166.12345678.03
QR.RSP.12345678.00038166.03

# MES02 (seq 04) - Prata
QL.REQ.00038166.12345678.04
QL.RSP.00038166.12345678.04
QR.REQ.00038166.12345678.04
QR.RSP.12345678.00038166.04

# MES03 (seq 05) - Bronze
QL.REQ.00038166.12345678.05
QL.RSP.00038166.12345678.05
QR.REQ.00038166.12345678.05
QR.RSP.12345678.00038166.05

# Dead Letter Queue (shared)
QL.DLQ.12345678
```

### 6.3 Security Header (588 bytes)

Every IBM MQ message must be preceded by a 588-byte security header. This header is a fixed-format binary block placed at the beginning of the MQ message payload, before the XML content.

| Field | Offset (bytes) | Size (bytes) | Description | Example |
|-------|----------------|--------------|-------------|---------|
| C01 | 0 | 1 | Header version | `02` |
| C02 | 1 | 2 | Message type: 01=normal, 02=emergency, 03=GEN0001 | `01` |
| C03 | 3 | 8 | Sender ISPB | `12345678` |
| C04 | 11 | 8 | Receiver ISPB | `00038166` |
| C05 | 19 | 1 | Protocol type: 1=RSFN, 2=MES | `1` |
| C06 | 20 | 2 | Domain code: 01-05 | `01` |
| C07 | 22 | 20 | Message control number (unique per message) | `MSG2026020712350001` |
| C08 | 42 | 14 | Timestamp (YYYYMMDDHHmmss) | `20260207123500` |
| C09 | 56 | 7 | Message type code (padded right with spaces) | `STR0004` |
| C10 | 63 | 5 | Catalog version | `05.11` |
| C11 | 68 | 10 | Message size in bytes (zero-padded left) | `0000004523` |
| C12 | 78 | 256 | Digital signature hash (SHA-256 hex) | `a1b2c3d4...` |
| C13 | 334 | 128 | Certificate serial number (hex) | `01ab23cd...` |
| C14 | 462 | 64 | Certificate issuer DN hash (SHA-256 hex, first 64 chars) | `e5f6a7b8...` |
| C15 | 526 | 62 | Reserved (spaces) | `                    ...` |

**Total: 588 bytes**

The security header is automatically constructed by the Monetarie BACEN Gateway when sending messages. Partners receiving messages from Monetarie will see this header prefixed to the XML payload.

### 6.4 MQSC Configuration

Below is the complete MQSC script to configure IBM MQ queues for a partner institution. Replace `{ISPB}` with the partner's ISPB.

```
* IBM MQ Configuration for BACEN/RSFN/SPB Integration
* ISPB Local: {ISPB}, ISPB BACEN: 00038166
* Ref: BACEN Manual de Redes v9.3

* Enable AMQP 1.0 Service
START SERVICE(SYSTEM.AMQP.SERVICE)
ALTER CHANNEL(SYSTEM.DEF.AMQP) CHLTYPE(AMQP) MCAUSER('app')

* Queue Manager properties
ALTER QMGR MAXMSGL(4194304)
ALTER QMGR DEADQ('QL.DLQ.{ISPB}')
ALTER QMGR ADOPTNEWMCA(ALL)
ALTER QMGR CHLAUTH(ENABLED)

* ---- Domain SPB01 (seq 01) - STR/LPI (Platina) ----
DEFINE QLOCAL('QL.REQ.00038166.{ISPB}.01') MAXDEPTH(1000000) MAXMSGL(4194304) DEFPSIST(YES) REPLACE
DEFINE QLOCAL('QL.RSP.00038166.{ISPB}.01') MAXDEPTH(1000000) MAXMSGL(4194304) DEFPSIST(YES) REPLACE
DEFINE QLOCAL('QR.REQ.00038166.{ISPB}.01') MAXDEPTH(1000000) MAXMSGL(4194304) DEFPSIST(YES) REPLACE
DEFINE QLOCAL('QR.RSP.{ISPB}.00038166.01') MAXDEPTH(1000000) MAXMSGL(4194304) DEFPSIST(YES) REPLACE

* ---- Domain SPB02 (seq 02) - CIP/Settlement (Ouro) ----
DEFINE QLOCAL('QL.REQ.00038166.{ISPB}.02') MAXDEPTH(1000000) MAXMSGL(4194304) DEFPSIST(YES) REPLACE
DEFINE QLOCAL('QL.RSP.00038166.{ISPB}.02') MAXDEPTH(1000000) MAXMSGL(4194304) DEFPSIST(YES) REPLACE
DEFINE QLOCAL('QR.REQ.00038166.{ISPB}.02') MAXDEPTH(1000000) MAXMSGL(4194304) DEFPSIST(YES) REPLACE
DEFINE QLOCAL('QR.RSP.{ISPB}.00038166.02') MAXDEPTH(1000000) MAXMSGL(4194304) DEFPSIST(YES) REPLACE

* ---- Domain MES01 (seq 03) - Reserved (Platina) ----
DEFINE QLOCAL('QL.REQ.00038166.{ISPB}.03') MAXDEPTH(1000000) MAXMSGL(4194304) DEFPSIST(YES) REPLACE
DEFINE QLOCAL('QL.RSP.00038166.{ISPB}.03') MAXDEPTH(1000000) MAXMSGL(4194304) DEFPSIST(YES) REPLACE
DEFINE QLOCAL('QR.REQ.00038166.{ISPB}.03') MAXDEPTH(1000000) MAXMSGL(4194304) DEFPSIST(YES) REPLACE
DEFINE QLOCAL('QR.RSP.{ISPB}.00038166.03') MAXDEPTH(1000000) MAXMSGL(4194304) DEFPSIST(YES) REPLACE

* ---- Domain MES02 (seq 04) - General (Prata) ----
DEFINE QLOCAL('QL.REQ.00038166.{ISPB}.04') MAXDEPTH(1000000) MAXMSGL(4194304) DEFPSIST(YES) REPLACE
DEFINE QLOCAL('QL.RSP.00038166.{ISPB}.04') MAXDEPTH(1000000) MAXMSGL(4194304) DEFPSIST(YES) REPLACE
DEFINE QLOCAL('QR.REQ.00038166.{ISPB}.04') MAXDEPTH(1000000) MAXMSGL(4194304) DEFPSIST(YES) REPLACE
DEFINE QLOCAL('QR.RSP.{ISPB}.00038166.04') MAXDEPTH(1000000) MAXMSGL(4194304) DEFPSIST(YES) REPLACE

* ---- Domain MES03 (seq 05) - General (Bronze) ----
DEFINE QLOCAL('QL.REQ.00038166.{ISPB}.05') MAXDEPTH(1000000) MAXMSGL(4194304) DEFPSIST(YES) REPLACE
DEFINE QLOCAL('QL.RSP.00038166.{ISPB}.05') MAXDEPTH(1000000) MAXMSGL(4194304) DEFPSIST(YES) REPLACE
DEFINE QLOCAL('QR.REQ.00038166.{ISPB}.05') MAXDEPTH(1000000) MAXMSGL(4194304) DEFPSIST(YES) REPLACE
DEFINE QLOCAL('QR.RSP.{ISPB}.00038166.05') MAXDEPTH(1000000) MAXMSGL(4194304) DEFPSIST(YES) REPLACE

* ---- Dead Letter Queue ----
DEFINE QLOCAL('QL.DLQ.{ISPB}') MAXDEPTH(1000000) MAXMSGL(4194304) DEFPSIST(YES) REPLACE

* ---- Channel definitions per domain ----
DEFINE CHANNEL('C{ISPB}.00038166.1') CHLTYPE(SVRCONN) TRPTYPE(TCP) MAXMSGL(4194304) +
  MCAUSER('app') SSLCIPH(ECDHE_RSA_AES_256_GCM_SHA384) SSLCAUTH(REQUIRED) REPLACE
DEFINE CHANNEL('C{ISPB}.00038166.2') CHLTYPE(SVRCONN) TRPTYPE(TCP) MAXMSGL(4194304) +
  MCAUSER('app') SSLCIPH(ECDHE_RSA_AES_256_GCM_SHA384) SSLCAUTH(REQUIRED) REPLACE
DEFINE CHANNEL('C{ISPB}.00038166.3') CHLTYPE(SVRCONN) TRPTYPE(TCP) MAXMSGL(4194304) +
  MCAUSER('app') SSLCIPH(ECDHE_RSA_AES_256_GCM_SHA384) SSLCAUTH(REQUIRED) REPLACE
DEFINE CHANNEL('C{ISPB}.00038166.4') CHLTYPE(SVRCONN) TRPTYPE(TCP) MAXMSGL(4194304) +
  MCAUSER('app') SSLCIPH(ECDHE_RSA_AES_256_GCM_SHA384) SSLCAUTH(REQUIRED) REPLACE
DEFINE CHANNEL('C{ISPB}.00038166.5') CHLTYPE(SVRCONN) TRPTYPE(TCP) MAXMSGL(4194304) +
  MCAUSER('app') SSLCIPH(ECDHE_RSA_AES_256_GCM_SHA384) SSLCAUTH(REQUIRED) REPLACE

* Security
REFRESH SECURITY TYPE(CONNAUTH)
REFRESH SECURITY TYPE(AUTHSERV)

* Start listeners
START LISTENER('SYSTEM.DEFAULT.LISTENER.TCP')
```

### 6.5 AMQP 1.0 Connection Example

Monetarie uses the Erlang `amqp10_client` library for AMQP 1.0 connections. Here is the equivalent connection configuration for reference:

```python
# Python example using python-qpid-proton (AMQP 1.0 client)
import proton
from proton.handlers import MessagingHandler

class BacenSender(MessagingHandler):
    def __init__(self, host, port, queue, cert_file, key_file, ca_file):
        super().__init__()
        self.url = f"amqps://{host}:{port}/{queue}"
        self.ssl_domain = proton.SSLDomain(proton.SSLDomain.MODE_CLIENT)
        self.ssl_domain.set_credentials(cert_file, key_file, "")
        self.ssl_domain.set_trusted_ca_db(ca_file)
        self.ssl_domain.set_peer_authentication(proton.SSLDomain.VERIFY_PEER)

    def on_start(self, event):
        conn = event.container.connect(
            self.url,
            ssl_domain=self.ssl_domain,
            allowed_mechs="PLAIN"
        )
        event.container.create_sender(conn, "QL.REQ.00038166.12345678.01")

    def on_sendable(self, event):
        msg = proton.Message(body=xml_content)
        msg.content_type = "application/xml"
        msg.properties = {
            "message_type": "STR0004",
            "ispb_sender": "12345678",
            "ispb_receiver": "00038166",
            "domain": "spb01"
        }
        event.sender.send(msg)
```

---

## 7. Security Requirements

### 7.1 ICP-Brasil Certificate

All production communication with BACEN requires a valid ICP-Brasil digital certificate. The certificate must be:

- **Type:** A1 (software-based) or A3 (hardware token)
- **Issuer:** A BACEN-authorized Certificate Authority within the ICP-Brasil PKI hierarchy
- **Subject:** Must contain your institution's CNPJ
- **Key:** RSA 2048-bit minimum
- **Validity:** Must not be expired or revoked

**Certificate file locations (in the Monetarie deployment):**

```
/etc/ssl/certs/bacen-ca.pem        # BACEN CA chain (trust store)
/etc/ssl/certs/bacen-cert.pem      # Your institution's ICP-Brasil certificate
/etc/ssl/private/bacen-key.pem     # Corresponding private key
```

### 7.2 XMLDSig Signing

All outbound messages must be signed using XML Digital Signatures (XMLDSig) per the W3C specification. Monetarie automatically signs all messages before sending to BACEN.

**Signature configuration:**

| Parameter | Value |
|-----------|-------|
| Canonicalization | Exclusive XML Canonicalization (xml-exc-c14n#) |
| Signature Algorithm | RSA-SHA256 (xmldsig-more#rsa-sha256) |
| Digest Algorithm | SHA-256 (xmlenc#sha256) |
| Number of References | 3 |

**References:**

1. **KeyInfo** -- Signs the KeyInfo element containing the X.509 certificate
2. **AppHdr** -- Signs the application header (BCMSG envelope)
3. **Document** -- Signs the message body (DOC element within SISMSG)

All three references must be present and valid for BACEN to accept the message.

### 7.3 TLS Requirements

| Requirement | Value |
|-------------|-------|
| Minimum TLS version | 1.2 |
| Supported cipher suite | ECDHE_RSA_AES_256_GCM_SHA384 |
| Client authentication | Required (mTLS) |
| Certificate chain validation | Full chain verification |
| OCSP checking | Recommended |

### 7.4 Security Header

Every IBM MQ message must include the 588-byte security header (see Section 6.3) containing the SHA-256 hash of the message and certificate identification data.

### 7.5 Audit Trail

BACEN requires a complete audit trail of all message exchanges. Monetarie maintains:

- Every message sent and received with full XML content
- State transition history with timestamps
- Error details and retry attempts
- User actions (API requests, manual overrides)
- Certificate events (signing operations, validation results)

Audit records are retained for a minimum of **10 years** for ICOM messages and **5 years** for all other messages, in compliance with BACEN regulations.

---

## 8. Error Handling

### 8.1 Error Code Ranges

Monetarie SPB uses structured error codes organized by category. The system maintains 5,306+ error codes mapped from the BACEN specification.

| Code Range | Category | Retryable | Description |
|-----------|----------|-----------|-------------|
| 1001--1020 | Validation | No | Message format and schema errors |
| 2001--2015 | Authentication | No | Certificate and credential errors |
| 3001--3010 | Authorization | No | Permission and access errors |
| 4001--4020 | Business Logic | Partially | Domain-specific business rule errors |
| 5001--5015 | System | Yes | Internal system and infrastructure errors |
| 6001--6010 | Network | Yes | Connection and network errors |
| 7001--7010 | Timeout | Yes | Various timeout conditions |
| 9001--9010 | TED/DOC | Partially | TED/DOC specific errors |

### 8.2 Validation Errors (1000-1999)

These errors indicate problems with the message format or content. They are never retryable -- the message must be corrected before resubmission.

| Code | Description | Resolution |
|------|-------------|------------|
| 1001 | Invalid message format | Check message structure against ISO 20022 schema |
| 1002 | Missing required field | Verify all required fields are present |
| 1003 | Invalid field value | Check field value format and constraints |
| 1004 | Message size exceeds limit | Reduce message size (max 4 MB) |
| 1005 | Invalid XML structure | Validate XML against BACEN schema |
| 1006 | Schema validation failed | Ensure message conforms to published schema version |
| 1007 | Invalid character encoding | Use UTF-8 encoding |
| 1008 | Malformed XML | Check XML syntax and well-formedness |
| 1009 | Invalid namespace | Use correct XML namespace for message type |
| 1010 | Invalid message version | Update to supported message version |
| 1011 | Invalid date format | Use ISO 8601 date format (YYYY-MM-DD) |
| 1012 | Invalid time format | Use ISO 8601 time format (HH:MM:SS) |
| 1013 | Invalid datetime format | Use ISO 8601 datetime format |
| 1014 | Invalid amount format | Use decimal format with 2 decimal places |
| 1015 | Invalid currency code | Use ISO 4217 currency code (BRL) |
| 1016 | Invalid CPF format | CPF must be 11 digits with valid check digits |
| 1017 | Invalid CNPJ format | CNPJ must be 14 digits with valid check digits |
| 1018 | Invalid ISPB code | ISPB must be 8 digits |
| 1019 | Invalid account number format | Check account number format requirements |
| 1020 | Invalid routing number | Check routing number format |

### 8.3 Authentication Errors (2000-2999)

These errors indicate certificate or credential problems. They are not retryable and require certificate or credential remediation.

| Code | Description | Resolution |
|------|-------------|------------|
| 2001 | Invalid certificate | Renew or update digital certificate |
| 2002 | Certificate expired | Renew digital certificate |
| 2003 | Certificate revoked | Obtain new valid certificate |
| 2004 | Invalid digital signature | Regenerate digital signature with valid certificate |
| 2005 | Signature verification failed | Verify signature algorithm and certificate chain |
| 2006 | Certificate not trusted | Use ICP-Brasil certified certificate |
| 2007 | Invalid certificate chain | Verify complete certificate chain |
| 2008 | Certificate not yet valid | Check certificate validity period |
| 2009 | Invalid signature algorithm | Use RSA-SHA256 algorithm |
| 2010 | Missing digital signature | Add required digital signature |
| 2011 | Invalid authentication token | Regenerate authentication token |
| 2012 | Authentication token expired | Request new authentication token |
| 2013 | Invalid credentials | Verify username and password |
| 2014 | Account locked | Contact administrator to unlock account |
| 2015 | Too many authentication attempts | Wait before retrying (retryable) |

### 8.4 Authorization Errors (3000-3999)

| Code | Description | Resolution |
|------|-------------|------------|
| 3001 | Insufficient permissions | Request necessary permissions from administrator |
| 3002 | Institution not authorized | Register institution with BACEN |
| 3003 | Service not available for institution | Request service activation |
| 3004 | Operation not permitted | Check operation permissions |
| 3005 | Access denied | Verify access credentials and permissions |
| 3006 | Invalid ISPB for operation | Verify ISPB code authorization |
| 3007 | Operation requires higher privilege level | Request privilege elevation |
| 3008 | Institution not registered | Complete institution registration |
| 3009 | Service subscription required | Subscribe to required service |
| 3010 | Participant not active | Activate participant status |

### 8.5 Business Logic Errors (4000-4999)

These errors are partially retryable depending on the specific condition.

| Code | Description | Retryable | Resolution |
|------|-------------|-----------|------------|
| 4001 | Insufficient funds | No | Verify account balance |
| 4002 | Duplicate transaction | No | Check for already processed transaction |
| 4003 | Invalid account | No | Verify account number and routing information |
| 4004 | Account blocked | No | Contact account holder or administrator |
| 4005 | Transaction limit exceeded | No | Reduce transaction amount or split |
| 4006 | Invalid operation time | Yes | Retry during operating hours |
| 4007 | Account closed | No | Account is no longer active |
| 4008 | Invalid beneficiary account | No | Verify beneficiary account details |
| 4009 | Transaction not allowed for account type | No | Check account type restrictions |
| 4010 | Daily limit exceeded | No | Transaction exceeds daily limit |
| 4011 | Monthly limit exceeded | No | Transaction exceeds monthly limit |
| 4012 | Invalid transaction amount | No | Amount must be positive and within limits |
| 4013 | Future dated transaction not allowed | No | Transaction date cannot be in future |
| 4014 | Transaction already reversed | No | Transaction has already been reversed |
| 4015 | Reversal not allowed | No | Transaction cannot be reversed |
| 4016 | Settlement window closed | Yes | Submit during next settlement window |
| 4017 | Invalid payment purpose code | No | Use valid payment purpose code |
| 4018 | Mandatory information missing | No | Provide all required information |
| 4019 | Invalid transaction type for account | No | Account does not support this transaction type |
| 4020 | Beneficiary blacklisted | No | Cannot process transaction to blacklisted beneficiary |

### 8.6 System Errors (5000-5999)

System errors are generally retryable. They indicate infrastructure or service-level issues.

| Code | Description | Resolution |
|------|-------------|------------|
| 5001 | Internal server error | Contact system administrator |
| 5002 | Database error | Database operation failed -- retry or contact support |
| 5003 | Service unavailable | Service temporarily unavailable -- retry later |
| 5004 | Queue full | Retry after brief delay |
| 5005 | Processing error | Internal processing error -- contact support |
| 5006 | Resource exhausted | System resources exhausted -- retry later |
| 5007 | Configuration error | System misconfiguration -- contact administrator (not retryable) |
| 5008 | Invalid system state | System in invalid state for operation |
| 5009 | Dependency unavailable | Required dependency service unavailable |
| 5010 | Storage error | Failed to store data -- retry or contact support |
| 5011 | Cache error | Cache operation failed -- may impact performance |
| 5012 | Encryption error | Failed to encrypt data (not retryable) |
| 5013 | Decryption error | Failed to decrypt data (not retryable) |
| 5014 | Serialization error | Failed to serialize data |
| 5015 | Deserialization error | Failed to deserialize data |

### 8.7 Network Errors (6000-6999)

All network errors are retryable.

| Code | Description | Resolution |
|------|-------------|------------|
| 6001 | Connection timeout | Check network connectivity and retry |
| 6002 | Connection refused | Target service unavailable or refusing connections |
| 6003 | Network unreachable | Network path to service unavailable |
| 6004 | SSL/TLS error | Secure connection failed -- check certificates (not retryable) |
| 6005 | DNS resolution failed | Cannot resolve hostname |
| 6006 | Connection reset | Connection reset by peer |
| 6007 | Network congestion | Network congestion detected -- retry |
| 6008 | Bandwidth limit exceeded | Network bandwidth limit exceeded |
| 6009 | Invalid response received | Received invalid response from service |
| 6010 | Connection pool exhausted | No available connections -- retry |

### 8.8 Timeout Errors (7000-7999)

All timeout errors are retryable except session timeout (7007).

| Code | Description | Resolution |
|------|-------------|------------|
| 7001 | Request timeout | Retry with longer timeout |
| 7002 | Response timeout | No response received within timeout period |
| 7003 | Processing timeout | Processing exceeded maximum time limit |
| 7004 | Database query timeout | Database query timed out -- optimize or retry |
| 7005 | External service timeout | External service did not respond in time |
| 7006 | Lock timeout | Could not acquire lock within timeout |
| 7007 | Session timeout | Session expired -- re-authenticate (not retryable) |
| 7008 | Transaction timeout | Transaction exceeded maximum duration |
| 7009 | Idle timeout | Connection idle for too long |
| 7010 | Read timeout | Read operation timed out |

### 8.9 API Error Response Format

All API errors follow a consistent JSON format:

```json
{
  "error": {
    "code": 1005,
    "category": "validation",
    "message": "Invalid XML structure",
    "detail": "Element 'IdentdEmissor' expected at position 2",
    "retryable": false,
    "suggested_action": "Validate XML against BACEN schema",
    "timestamp": "2026-02-07T10:35:00Z",
    "request_id": "req-a3f2b5c7-89d4"
  }
}
```

---

## 9. Webhooks & Events

### 9.1 NATS JetStream Topics

Monetarie SPB publishes events to NATS JetStream for real-time message tracking. Partner systems that have NATS access can subscribe to these topics for immediate notifications.

**Stream name:** `SPB_MESSAGES`

| Topic | Trigger | Payload |
|-------|---------|---------|
| `messages.new` | New message submitted | `{id, message_type, status: "pending", timestamp}` |
| `messages.processing` | Message being signed/routed | `{id, message_type, status: "processing", domain, timestamp}` |
| `messages.sent` | Message dispatched to BACEN | `{id, message_type, status: "sent", domain, mq_delivery_tag, timestamp}` |
| `messages.confirmed` | BACEN confirmed receipt | `{id, message_type, status: "confirmed", bacen_response_id, timestamp}` |
| `messages.failed` | Processing failed | `{id, message_type, status: "failed", error_code, error_message, timestamp}` |
| `messages.timeout` | Response timeout | `{id, message_type, status: "timeout", domain, timeout_ms, timestamp}` |
| `messages.retry` | Message being retried | `{id, message_type, retry_count, max_retries, timestamp}` |
| `messages.dlq` | Message moved to DLQ | `{id, message_type, reason, timestamp}` |

**NATS connection details (internal):**

```
URL: nats://nats.spb.svc.cluster.local:4222
Stream: SPB_MESSAGES
Max payload: 8 MB
JetStream storage: File-backed, 50 GB limit
```

### 9.2 NATS Subscription Example

```python
import nats
from nats.js.api import ConsumerConfig, DeliverPolicy

async def main():
    nc = await nats.connect("nats://nats.spb.svc.cluster.local:4222")
    js = nc.jetstream()

    # Subscribe to all message events
    sub = await js.subscribe(
        "messages.>",
        stream="SPB_MESSAGES",
        config=ConsumerConfig(
            durable_name="partner-consumer",
            deliver_policy=DeliverPolicy.NEW,
        ),
    )

    async for msg in sub.messages:
        print(f"Topic: {msg.subject}, Data: {msg.data.decode()}")
        await msg.ack()
```

### 9.3 Webhook Configuration (Planned)

Webhook support for HTTP callbacks is planned for a future release. When available, partners will be able to register webhook URLs to receive HTTP POST notifications for message state changes without requiring direct NATS access.

---

## 10. Testing with Simulator

### 10.1 Simulator Overview

Monetarie SPB includes a built-in BACEN simulator that emulates BACEN's message processing behavior. The simulator supports all 1,222 message types and provides 10 configurable test scenarios for validating your integration.

**Access points:**

| Environment | Simulator URL | Dashboard |
|-------------|--------------|-----------|
| Local (Docker) | http://localhost:4001 | http://localhost:4001 (LiveView) |
| GKE Dev | simulator-dev.fluxiq.com.br | simulator-dev.fluxiq.com.br |

### 10.2 Simulator Scenarios

The simulator provides 10 pre-configured scenarios, each with different success rates, response delays, and error injection patterns:

| # | Scenario Key | Name | Success Rate | Avg Delay | Error Codes Injected | Purpose |
|---|-------------|------|-------------|-----------|---------------------|---------|
| 1 | `normal_operations` | Normal Operations | 98% | 150ms +/-50ms | None | Default happy path testing |
| 2 | `stress_test` | Stress Test | 95% | 500ms +/-200ms | 5001, 5003, 7001 | Performance and load testing |
| 3 | `error_testing` | Error Testing | 50% | 100ms +/-50ms | 1001, 1002, 1003, 2004, 4001, 4002, 5001 | Error handling validation |
| 4 | `timeout_testing` | Timeout Testing | 70% | 2000ms +/-1000ms | 7001, 7002, 7003 | Timeout handling verification |
| 5 | `validation_errors` | Validation Errors | 60% | 100ms +/-30ms | 1001, 1002, 1003, 1004, 1005, 1006 | Input validation testing |
| 6 | `network_issues` | Network Issues | 80% | 800ms +/-400ms | 6001, 6002, 6003 | Network resilience testing |
| 7 | `business_errors` | Business Errors | 85% | 200ms +/-100ms | 4001, 4002, 4003, 4004, 4005 | Business rule validation |
| 8 | `high_performance` | High Performance | 99% | 50ms +/-20ms | None | Maximum throughput testing |
| 9 | `authentication_failures` | Authentication Failures | 40% | 150ms +/-50ms | 2001, 2002, 2003, 2004, 2005 | Auth error handling |
| 10 | `authorization_issues` | Authorization Issues | 50% | 120ms +/-40ms | 3001, 3002, 3003, 3004 | Permission testing |

### 10.3 Simulator API Reference

#### GET /api/scenarios

List all available scenarios.

```bash
curl http://localhost:4001/api/scenarios
```

**Response:**

```json
{
  "scenarios": [
    {
      "name": "normal_operations",
      "display_name": "Normal Operations",
      "description": "Standard testing and development scenario",
      "success_rate": 0.98,
      "avg_response_time_ms": 150,
      "error_codes": [],
      "enabled": true
    }
  ]
}
```

#### POST /api/scenarios/:name/activate

Activate a scenario by name.

```bash
curl -X POST http://localhost:4001/api/scenarios/stress_test/activate
```

**Response:**

```json
{
  "activated": "stress_test",
  "previous": "normal_operations"
}
```

#### GET /api/scenarios/current

Get the currently active scenario.

```bash
curl http://localhost:4001/api/scenarios/current
```

#### POST /api/mq/send

Send a test message to the simulator's MQ queue.

```bash
curl -X POST http://localhost:4001/api/mq/send \
  -H "Content-Type: application/json" \
  -d '{
    "message_type": "STR0004",
    "xml_content": "<?xml version=\"1.0\"?><BCMSG>...</BCMSG>",
    "destination_ispb": "00038166"
  }'
```

#### GET /api/mq/receive

Receive the next message from the simulator's response queue.

```bash
curl http://localhost:4001/api/mq/receive
```

#### GET /api/mq/status

Check the status of simulator MQ queues.

```bash
curl http://localhost:4001/api/mq/status
```

#### GET /api/statistics

Get simulator processing statistics.

```bash
curl http://localhost:4001/api/statistics
```

**Response:**

```json
{
  "total_requests": 1523,
  "successful_responses": 1492,
  "failed_responses": 31,
  "errors_by_code": {
    "5001": 12,
    "7001": 8,
    "4001": 6,
    "1001": 5
  },
  "avg_response_time": 148
}
```

#### POST /api/statistics/reset

Reset all simulator statistics to zero.

```bash
curl -X POST http://localhost:4001/api/statistics/reset
```

#### POST /api/messages/process

Process a message directly through the simulator (bypassing MQ).

```bash
curl -X POST http://localhost:4001/api/messages/process \
  -H "Content-Type: application/json" \
  -d '{
    "message_type": "STR0004",
    "xml_content": "<?xml version=\"1.0\"?><BCMSG>...</BCMSG>"
  }'
```

#### GET /api/messages/templates/:type

Get the XML template for a specific message type.

```bash
curl http://localhost:4001/api/messages/templates/STR0004
```

### 10.4 Simulator Dashboard (LiveView)

The simulator includes a real-time LiveView dashboard accessible via browser:

| Page | URL | Description |
|------|-----|-------------|
| Dashboard | / | Real-time statistics, throughput charts, scenario status |
| Scenarios | /scenarios | Scenario management -- activate, configure, monitor |
| Message Log | /messages | Live log of all processed messages with details |
| Configuration | /config | Simulator settings, response behavior tuning |

### 10.5 GEN0001 Connection Test

The GEN0001 message is the standard BACEN connectivity test. To verify your integration:

1. Set the simulator to `normal_operations` scenario
2. Send a GEN0001 message via the API:

```bash
# Step 1: Login and get token
TOKEN=$(curl -s -X POST https://spbapi-dev.fluxiq.com.br/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"admin@monetarie.com.br","password":"Monetarie#Adm@2026"}' | jq -r '.token')

# Step 2: Send GEN0001
curl -X POST https://spbapi-dev.fluxiq.com.br/api/messages \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "message_type": "GEN0001",
    "xml_content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?><BCMSG xmlns=\"http://www.bcb.gov.br/SPB\"><IdentdEmissor>12345678</IdentdEmissor><IdentdDesworko>00038166</IdentdDesworko><SISMSG><CodMsg>GEN0001</CodMsg></SISMSG></BCMSG>",
    "destination_ispb": "00038166"
  }'
```

3. Check for GEN0001E (response):

```bash
# Step 3: Verify the response
curl https://spbapi-dev.fluxiq.com.br/api/messages?message_type=GEN0001E \
  -H "Authorization: Bearer $TOKEN"
```

A successful test produces a GEN0001E response with status `confirmed`.

---

## 11. Onboarding Checklist

Follow this checklist in order to integrate your institution with Monetarie SPB.

### Phase 1: Administrative Setup

- [ ] **1.1** Obtain your ISPB (8-digit code) from BACEN if not already assigned
- [ ] **1.2** Obtain an ICP-Brasil A1 or A3 certificate from an authorized CA
- [ ] **1.3** Request RSFN network access (dedicated link or VPN) from BACEN
- [ ] **1.4** Contact Monetarie integration team (integracoes@fluxiq.com.br) to begin onboarding
- [ ] **1.5** Receive Monetarie API credentials (email/password for test environment)
- [ ] **1.6** Receive SSO shared secret (if using SSO integration)

### Phase 2: Technical Configuration

- [ ] **2.1** Configure firewall rules for Monetarie MQ ports (1414, 5672, 12422-15422)
- [ ] **2.2** Install ICP-Brasil certificate on your MQ client
- [ ] **2.3** Configure IBM MQ queues using the MQSC script from Section 6.4 (replace `{ISPB}` with your ISPB)
- [ ] **2.4** Set up MQ channel definitions for all 5 domains
- [ ] **2.5** Configure TLS with cipher `ECDHE_RSA_AES_256_GCM_SHA384`
- [ ] **2.6** Set up NATS client connection (optional -- for event subscription)
- [ ] **2.7** Configure your HTTP client for REST API access

### Phase 3: Connectivity Testing

- [ ] **3.1** Login to Monetarie SPB test environment (spbadmin-dev.fluxiq.com.br)
- [ ] **3.2** Verify API health endpoint returns 200 OK
- [ ] **3.3** Activate `normal_operations` simulator scenario
- [ ] **3.4** Send GEN0001 connectivity test message
- [ ] **3.5** Verify GEN0001E response received (status: confirmed)
- [ ] **3.6** Verify MQ connectivity on all 5 domains

### Phase 4: Integration Testing

- [ ] **4.1** Send test STR0004 message (reserve transfer)
- [ ] **4.2** Send test PAG0101 message (TED payment)
- [ ] **4.3** Verify message state transitions (pending -> processing -> sent -> confirmed)
- [ ] **4.4** Test error handling with `error_testing` scenario
- [ ] **4.5** Test timeout handling with `timeout_testing` scenario
- [ ] **4.6** Verify NATS event delivery (if subscribed)
- [ ] **4.7** Run stress test with `stress_test` scenario (1,000+ messages)
- [ ] **4.8** Verify DLQ handling for permanently failed messages

### Phase 5: Security Validation

- [ ] **5.1** Verify XMLDSig signatures on all outbound messages
- [ ] **5.2** Verify 588-byte security header is correctly constructed
- [ ] **5.3** Test with expired certificate (expect error 2002)
- [ ] **5.4** Test with revoked certificate (expect error 2003)
- [ ] **5.5** Verify audit trail records all message exchanges

### Phase 6: Production Go-Live

- [ ] **6.1** Replace test certificates with production ICP-Brasil certificates
- [ ] **6.2** Update MQ channel definitions for production Queue Managers
- [ ] **6.3** Update API URL to production endpoint
- [ ] **6.4** Perform final GEN0001 connectivity test on production
- [ ] **6.5** Enable production message routing
- [ ] **6.6** Monitor first 24 hours of production traffic
- [ ] **6.7** Sign off on integration completion with Monetarie team

---

## Appendix A -- NATS Topic Reference

Complete NATS JetStream configuration for the SPB namespace:

```
# JetStream Configuration
Port: 4222
HTTP Monitor: 8222
Max memory: 2 GB
Max file storage: 50 GB
Max connections: 10,000
Max payload: 8 MB (8,388,608 bytes)
Max pending: 64 MB (67,108,864 bytes)
Ping interval: 120s
Write deadline: 10s
```

**Stream: SPB_MESSAGES**

| Subject Pattern | Description |
|----------------|-------------|
| messages.new | New message submitted |
| messages.processing | Message being processed |
| messages.sent | Message sent to BACEN |
| messages.confirmed | BACEN confirmation |
| messages.failed | Processing failure |
| messages.timeout | Response timeout |
| messages.retry | Retry attempt |
| messages.dlq | Dead letter queue |

**Stream: SPB_DOMAINS**

| Subject Pattern | Description |
|----------------|-------------|
| domains.connected | MQ domain connected |
| domains.disconnected | MQ domain disconnected |
| domains.error | MQ domain error |
| domains.reconnecting | MQ domain reconnecting |

**Stream: SPB_AUDIT**

| Subject Pattern | Description |
|----------------|-------------|
| audit.api.request | API request received |
| audit.api.response | API response sent |
| audit.mq.send | MQ message sent |
| audit.mq.receive | MQ message received |
| audit.auth.login | User login |
| audit.auth.logout | User logout |

---

## Appendix B -- XML Envelope Examples

### B.1 STR0004 -- Reserve Transfer Request

```xml
<?xml version="1.0" encoding="UTF-8"?>
<BCMSG xmlns="http://www.bcb.gov.br/SPB">
  <IdentdEmissor>12345678</IdentdEmissor>
  <IdentdDesworko>00038166</IdentdDesworko>
  <IdentdMsgNegWorko>MSG20260207123500000001</IdentdMsgNegWorko>
  <DtHrMsgNeg>2026-02-07T12:35:00</DtHrMsgNeg>

  <SISMSG>
    <CodMsg>STR0004</CodMsg>
    <NumCtrlIF>CTRL2026020700001</NumCtrlIF>
    <IdentdOpworko>OP2026020700001</IdentdOpworko>
    <DtHrMsg>2026-02-07T12:35:00</DtHrMsg>

    <DOC xmlns="http://www.bcb.gov.br/SPB/STR0004">
      <InfTransf>
        <ISPBIfDeworko>00038166</ISPBIfDeworko>
        <VlrTransf>150000.00</VlrTransf>
        <FinlddSTR>01</FinlddSTR>
        <CodMoeda>BRL</CodMoeda>
        <DtMovto>2026-02-07</DtMovto>
        <NomIfOrig>MONETARIE INSTITUICAO DE PAGAMENTO E SERVICOS LTDA</NomIfOrig>
        <NomIfDest>Banco do Brasil S.A.</NomIfDest>
      </InfTransf>
    </DOC>
  </SISMSG>
</BCMSG>
```

### B.2 GEN0001 -- Connectivity Test

```xml
<?xml version="1.0" encoding="UTF-8"?>
<BCMSG xmlns="http://www.bcb.gov.br/SPB">
  <IdentdEmissor>12345678</IdentdEmissor>
  <IdentdDesworko>00038166</IdentdDesworko>
  <IdentdMsgNegWorko>MSG20260207100000000001</IdentdMsgNegWorko>
  <DtHrMsgNeg>2026-02-07T10:00:00</DtHrMsgNeg>

  <SISMSG>
    <CodMsg>GEN0001</CodMsg>
    <NumCtrlIF>GENTEST2026020700001</NumCtrlIF>
    <DtHrMsg>2026-02-07T10:00:00</DtHrMsg>
    <DOC xmlns="http://www.bcb.gov.br/SPB/GEN0001">
      <InfConect>
        <DtHrBC>2026-02-07T10:00:00</DtHrBC>
      </InfConect>
    </DOC>
  </SISMSG>
</BCMSG>
```

### B.3 PAG0101 -- TED Payment

```xml
<?xml version="1.0" encoding="UTF-8"?>
<BCMSG xmlns="http://www.bcb.gov.br/SPB">
  <IdentdEmissor>12345678</IdentdEmissor>
  <IdentdDesworko>00038166</IdentdDesworko>
  <IdentdMsgNegWorko>MSG20260207140000000001</IdentdMsgNegWorko>
  <DtHrMsgNeg>2026-02-07T14:00:00</DtHrMsgNeg>

  <SISMSG>
    <CodMsg>PAG0101</CodMsg>
    <NumCtrlIF>TED2026020700001</NumCtrlIF>
    <DtHrMsg>2026-02-07T14:00:00</DtHrMsg>

    <DOC xmlns="http://www.bcb.gov.br/SPB/PAG0101">
      <InfPagto>
        <TpPgto>TED</TpPgto>
        <ISPBIfBenworko>60701190</ISPBIfBenworko>
        <VlrPgto>25000.00</VlrPgto>
        <CodMoeda>BRL</CodMoeda>
        <DtMovto>2026-02-07</DtMovto>
        <FinlddPgto>01</FinlddPgto>
        <DadosOrig>
          <TpPessoa>J</TpPessoa>
          <CNPJ_CPF>12345678000100</CNPJ_CPF>
          <Ag>0001</Ag>
          <Ct>0001234-5</Ct>
          <NomOrig>MONETARIE INSTITUICAO DE PAGAMENTO E SERVICOS LTDA</NomOrig>
        </DadosOrig>
        <DadosDest>
          <TpPessoa>F</TpPessoa>
          <CNPJ_CPF>12345678901</CNPJ_CPF>
          <ISPBIfBenworko>60701190</ISPBIfBenworko>
          <Ag>1234</Ag>
          <Ct>0009876-1</Ct>
          <NomDest>JOAO DA SILVA</NomDest>
        </DadosDest>
      </InfPagto>
    </DOC>
  </SISMSG>
</BCMSG>
```

---

**Document Version History:**

| Version | Date | Author | Changes |
|---------|------|--------|---------|
| 1.0 | 2026-02-07 | Monetarie Engineering | Initial release |

**Support Contact:**

- Technical integration: integracoes@fluxiq.com.br
- Emergency (production issues): suporte@fluxiq.com.br
- Documentation updates: docs@fluxiq.com.br
