brbank 0.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- brbank-0.0.1/.github/workflows/ci.yml +18 -0
- brbank-0.0.1/.github/workflows/publish.yml +16 -0
- brbank-0.0.1/.gitignore +11 -0
- brbank-0.0.1/CLAUDE.md +28 -0
- brbank-0.0.1/LICENSE +21 -0
- brbank-0.0.1/PKG-INFO +150 -0
- brbank-0.0.1/README.md +126 -0
- brbank-0.0.1/docs/bb-duvidas.md +83 -0
- brbank-0.0.1/docs/pinbank-duvidas.md +40 -0
- brbank-0.0.1/docs/pix-duvidas.md +82 -0
- brbank-0.0.1/docs/sicoob-duvidas.md +76 -0
- brbank-0.0.1/docs/sicredi-duvidas.md +68 -0
- brbank-0.0.1/pyproject.toml +63 -0
- brbank-0.0.1/src/brbank/__init__.py +51 -0
- brbank-0.0.1/src/brbank/adapter.py +53 -0
- brbank-0.0.1/src/brbank/adapters/__init__.py +0 -0
- brbank-0.0.1/src/brbank/adapters/bb.py +487 -0
- brbank-0.0.1/src/brbank/adapters/inter.py +350 -0
- brbank-0.0.1/src/brbank/adapters/pinbank.py +309 -0
- brbank-0.0.1/src/brbank/adapters/pix_bacen.py +721 -0
- brbank-0.0.1/src/brbank/adapters/sicoob.py +423 -0
- brbank-0.0.1/src/brbank/adapters/sicredi.py +425 -0
- brbank-0.0.1/src/brbank/auth.py +223 -0
- brbank-0.0.1/src/brbank/capacidades.py +18 -0
- brbank-0.0.1/src/brbank/documento.py +66 -0
- brbank-0.0.1/src/brbank/envelope.py +87 -0
- brbank-0.0.1/src/brbank/erros.py +55 -0
- brbank-0.0.1/src/brbank/mascara.py +106 -0
- brbank-0.0.1/src/brbank/modelos.py +158 -0
- brbank-0.0.1/src/brbank/orquestrador.py +111 -0
- brbank-0.0.1/src/brbank/registro.py +35 -0
- brbank-0.0.1/src/brbank/status.py +40 -0
- brbank-0.0.1/src/brbank/transporte.py +230 -0
- brbank-0.0.1/tests/__init__.py +0 -0
- brbank-0.0.1/tests/bb_falso.py +92 -0
- brbank-0.0.1/tests/conftest.py +59 -0
- brbank-0.0.1/tests/inter_falso.py +72 -0
- brbank-0.0.1/tests/pinbank_falso.py +86 -0
- brbank-0.0.1/tests/pix_falso.py +137 -0
- brbank-0.0.1/tests/sicoob_falso.py +91 -0
- brbank-0.0.1/tests/sicredi_falso.py +98 -0
- brbank-0.0.1/tests/test_auth.py +58 -0
- brbank-0.0.1/tests/test_bb.py +355 -0
- brbank-0.0.1/tests/test_contrato.py +247 -0
- brbank-0.0.1/tests/test_inter.py +168 -0
- brbank-0.0.1/tests/test_modelos.py +94 -0
- brbank-0.0.1/tests/test_orquestrador.py +120 -0
- brbank-0.0.1/tests/test_pinbank.py +388 -0
- brbank-0.0.1/tests/test_pix_bacen.py +392 -0
- brbank-0.0.1/tests/test_sicoob.py +232 -0
- brbank-0.0.1/tests/test_sicredi.py +371 -0
- brbank-0.0.1/tests/test_transporte.py +147 -0
- brbank-0.0.1/uv.lock +798 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
name: ci
|
|
2
|
+
on:
|
|
3
|
+
push:
|
|
4
|
+
branches: [main]
|
|
5
|
+
pull_request:
|
|
6
|
+
jobs:
|
|
7
|
+
test:
|
|
8
|
+
runs-on: ubuntu-latest
|
|
9
|
+
strategy:
|
|
10
|
+
matrix:
|
|
11
|
+
python: ["3.11", "3.12"]
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
- uses: astral-sh/setup-uv@v5
|
|
15
|
+
- run: uv sync --python ${{ matrix.python }}
|
|
16
|
+
- run: uv run ruff check .
|
|
17
|
+
- run: uv run ruff format --check .
|
|
18
|
+
- run: uv run pytest --cov=brbank
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
name: publish
|
|
2
|
+
on:
|
|
3
|
+
release:
|
|
4
|
+
types: [published]
|
|
5
|
+
jobs:
|
|
6
|
+
pypi:
|
|
7
|
+
runs-on: ubuntu-latest
|
|
8
|
+
environment: pypi
|
|
9
|
+
permissions:
|
|
10
|
+
id-token: write
|
|
11
|
+
contents: read
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
- uses: astral-sh/setup-uv@v5
|
|
15
|
+
- run: uv build
|
|
16
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
brbank-0.0.1/.gitignore
ADDED
brbank-0.0.1/CLAUDE.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
Biblioteca `brbank` (cobranca bancaria unificada). Nao importar nada do Odoo.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
uv sync # instala (inclui o entry point brbank.adapters)
|
|
7
|
+
uv run pytest # testes (sem rede: httpx.MockTransport)
|
|
8
|
+
uv run pytest --cov=brbank # cobertura (meta 80% no core)
|
|
9
|
+
uv run ruff check . # lint
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Layout
|
|
13
|
+
|
|
14
|
+
- `src/brbank/`: `modelos` (B1), `adapter` (B2), `capacidades` (B3), `registro` (B4),
|
|
15
|
+
`transporte` (B5), `auth` (B6), `envelope` (B7), `erros` (B8), `status` (B9),
|
|
16
|
+
`orquestrador` (B10), `mascara` (LGPD), `documento` (CPF/CNPJ).
|
|
17
|
+
- `src/brbank/adapters/<banco>.py`: um adapter por banco, registrado em
|
|
18
|
+
`[project.entry-points."brbank.adapters"]`.
|
|
19
|
+
- `tests/test_contrato.py`: suite comum registrar -> consultar -> baixar; adapter
|
|
20
|
+
novo entra em `FABRICAS` com um servidor falso.
|
|
21
|
+
|
|
22
|
+
## Regras
|
|
23
|
+
|
|
24
|
+
- Dinheiro sempre `Decimal`. Nunca logar nem guardar PII/segredo em claro: usar `mascarar`.
|
|
25
|
+
- CNPJ alfanumerico: A-Z sem letras vedadas, DV por ASCII-48.
|
|
26
|
+
- Adapter portado de modulo Odoo: citar a origem no docstring e listar divergencias.
|
|
27
|
+
- Texto sem travessao nem caractere tipografico (so teclado QWERTY). Commits:
|
|
28
|
+
`[ADD]`/`[FIX]` em portugues, sem Co-Authored-By, trailer `Assisted-by: Claude`.
|
brbank-0.0.1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 KMEE
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
brbank-0.0.1/PKG-INFO
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: brbank
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: Cobranca bancaria unificada (boleto e Pix) para bancos brasileiros, independente do Odoo
|
|
5
|
+
Project-URL: Homepage, https://github.com/kmee/brbank
|
|
6
|
+
Project-URL: Issues, https://github.com/kmee/brbank/issues
|
|
7
|
+
Author-email: KMEE <info@kmee.com.br>
|
|
8
|
+
License: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Keywords: asyncio,banco,boleto,brasil,cobranca,pix
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Framework :: AsyncIO
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Topic :: Office/Business :: Financial
|
|
19
|
+
Requires-Python: >=3.11
|
|
20
|
+
Requires-Dist: cryptography>=50.0.2
|
|
21
|
+
Requires-Dist: httpx[http2]>=0.27
|
|
22
|
+
Requires-Dist: pydantic>=2.6
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
|
|
25
|
+
# brbank
|
|
26
|
+
|
|
27
|
+
Biblioteca Python assincrona para emitir e acompanhar boletos e cobrancas Pix em
|
|
28
|
+
bancos brasileiros por uma interface unica. Nao importa nada do Odoo: o modulo
|
|
29
|
+
`l10n_br_payment_boleto` e uma das faces possiveis.
|
|
30
|
+
|
|
31
|
+
Licenca MIT. Python 3.11+. **Alfa:** nenhum adapter foi validado em sandbox de
|
|
32
|
+
banco (`validado_sandbox = False`); o contrato de cada banco vem da documentacao
|
|
33
|
+
publica e de fontes de terceiros, com as duvidas em `docs/<banco>-duvidas.md`.
|
|
34
|
+
Estado: primeira fatia (modelo canonico, contrato
|
|
35
|
+
de adapter, transporte, autenticacao, orquestrador e os adapters da tabela abaixo).
|
|
36
|
+
|
|
37
|
+
## Bancos suportados
|
|
38
|
+
|
|
39
|
+
Todos os adapters passam pela mesma suite de contrato (registrar, consultar, baixar) contra um
|
|
40
|
+
servidor falso. "Origem" diz de onde veio o contrato: **Odoo** = portado de um modulo que ja roda
|
|
41
|
+
em producao (o adapter da biblioteca ainda nao rodou contra o banco), **ACBr** = levantado por leitura
|
|
42
|
+
do ACBr, usado so como documentacao, e de fontes de terceiros.
|
|
43
|
+
|
|
44
|
+
| Banco | Adapter (entry point) | Produto | Capacidades declaradas | Origem |
|
|
45
|
+
| --- | --- | --- | --- | --- |
|
|
46
|
+
| Inter (077) | `inter` | Cobranca v3, boleto hibrido | hibrido, so hibrido, baixa, PDF, webhook | Odoo |
|
|
47
|
+
| PinBank | `pinbank` | Boleto, envelope AES-CBC | baixa | Odoo |
|
|
48
|
+
| Sicoob (756) | `sicoob` | Cobranca v3, boleto hibrido | hibrido, alteracao, baixa | ACBr |
|
|
49
|
+
| Sicredi (748) | `sicredi` | Cobranca v2 | hibrido, alteracao, baixa, webhook | ACBr |
|
|
50
|
+
| Banco do Brasil (001) | `bb` | Cobranca v2 | alteracao, baixa | ACBr |
|
|
51
|
+
|
|
52
|
+
Pix (BACEN `/cob`, `/cobv`, `/webhook`) por um adapter generico, `pix_bacen`, com um perfil por PSP
|
|
53
|
+
(host, escopos, headers e quirks): Inter, Banco do Brasil, Sicoob, Sicredi, Itau, Bradesco,
|
|
54
|
+
Santander e Efi. Capacidades: Pix cob e cobv, webhook, baixa.
|
|
55
|
+
|
|
56
|
+
Fora desta lista por enquanto: BNB (sem referencia de Pix confiavel), Caixa, Safra, Banrisul,
|
|
57
|
+
Unicred, BTG e C6 (planejados), gateways como Mercado Pago, PagBank e Stone (sob demanda) e a
|
|
58
|
+
variante ECOMM do Sicredi. Banco novo = um adapter com `BankAdapter` e um entry point em
|
|
59
|
+
`brbank.adapters`; veja `docs/` para o que cada banco ainda deixa em aberto.
|
|
60
|
+
|
|
61
|
+
**Nenhum adapter da biblioteca foi validado em sandbox.** Sicoob, Sicredi, Banco do Brasil e os
|
|
62
|
+
perfis Pix trazem `validado_sandbox = False` no codigo e so passam a `True` depois de rodar contra o
|
|
63
|
+
ambiente real do banco. Inter e PinBank herdam a logica de modulos Odoo em producao, mas o adapter
|
|
64
|
+
da biblioteca tambem ainda nao rodou contra o banco.
|
|
65
|
+
|
|
66
|
+
## Uso
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
from brbank import Orquestrador
|
|
70
|
+
from brbank.adapters.inter import InterAdapter, InterConfig
|
|
71
|
+
|
|
72
|
+
config = InterConfig(
|
|
73
|
+
conta="matriz",
|
|
74
|
+
client_id="...",
|
|
75
|
+
client_secret="...",
|
|
76
|
+
conta_corrente="123456",
|
|
77
|
+
ambiente="sandbox",
|
|
78
|
+
certificado_pem=cert_bytes,
|
|
79
|
+
chave_pem=chave_bytes, # vindos do cofre
|
|
80
|
+
)
|
|
81
|
+
adapter = InterAdapter(config)
|
|
82
|
+
orquestrador = Orquestrador(adapter, concorrencia=10)
|
|
83
|
+
|
|
84
|
+
registrado = await orquestrador.emitir(titulo) # idempotente por chave
|
|
85
|
+
resultados = await orquestrador.emitir_em_varios(lote) # falha isolada por titulo
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Um banco novo e um pacote que registra o adapter no entry point `brbank.adapters`:
|
|
89
|
+
|
|
90
|
+
```toml
|
|
91
|
+
[project.entry-points."brbank.adapters"]
|
|
92
|
+
inter = "brbank.adapters.inter:InterAdapter"
|
|
93
|
+
pinbank = "brbank.adapters.pinbank:PinbankAdapter"
|
|
94
|
+
sicoob = "brbank.adapters.sicoob:SicoobAdapter"
|
|
95
|
+
|
|
96
|
+
sicredi = "brbank.adapters.sicredi:SicrediAdapter"
|
|
97
|
+
|
|
98
|
+
pix_bacen = "brbank.adapters.pix_bacen:PixBacenAdapter"
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
O `PinbankAdapter` usa OAuth2 `password` e payload cifrado AES-CBC (`EnvelopeAesCbc`),
|
|
102
|
+
registra, consulta e baixa por `NossoNumero`, e nao tem webhook nem PDF. Contrato em
|
|
103
|
+
aberto: `docs/pinbank-duvidas.md`.
|
|
104
|
+
|
|
105
|
+
O `SicoobAdapter` (Cobranca Bancaria v3, boleto hibrido) usa OAuth2 `client_credentials`
|
|
106
|
+
sem `client_secret` (a identidade e o mTLS), header `client_id`, id do titulo = nosso
|
|
107
|
+
numero, registra, consulta, baixa e envia instrucao (prorrogacao, abatimento, protesto).
|
|
108
|
+
Sem PDF e sem webhook declarados. **`validado_sandbox = False`**: contrato montado de
|
|
109
|
+
documentacao de terceiros, nunca executado contra o Sicoob. Duvidas: `docs/sicoob-duvidas.md`.
|
|
110
|
+
|
|
111
|
+
O `BancoDoBrasilAdapter` (`bb`, API Cobranca v2, convenio de 6 ou 7 digitos) usa OAuth2
|
|
112
|
+
`client_credentials` e a chave `gw-dev-app-key` em query param; registra, consulta, baixa,
|
|
113
|
+
prorroga e abate, sem webhook nem PDF. Nasce com `validado_sandbox = False`: ver
|
|
114
|
+
`docs/bb-duvidas.md`.
|
|
115
|
+
|
|
116
|
+
O `SicrediAdapter` (API de Cobranca v2, OAuth2 `password`) registra, consulta, baixa e
|
|
117
|
+
altera (prorrogacao e abatimento); webhook sem assinatura exige reconsulta. Nasce com
|
|
118
|
+
`validado_sandbox = False`; contrato em aberto: `docs/sicredi-duvidas.md`.
|
|
119
|
+
|
|
120
|
+
O `PixBacenAdapter` fala a API Pix do BACEN (`/cob`, `/cobv`, `/webhook`, devolucao) e
|
|
121
|
+
muda de banco por `PerfilPsp`: `inter`, `bb`, `sicoob`, `sicredi`, `itau`, `bradesco`,
|
|
122
|
+
`santander` e `efi` (BNB sem perfil). Todos com `validado_sandbox = False` ate rodar no
|
|
123
|
+
sandbox. O `txid` vem da chave de idempotencia, o copia-e-cola e o `txid` chegam em
|
|
124
|
+
`TituloRegistrado`, e `CONCLUIDA` sem Pix na consulta nao liquida. Duvidas e quirks:
|
|
125
|
+
`docs/pix-duvidas.md`.
|
|
126
|
+
|
|
127
|
+
```python
|
|
128
|
+
config = PixBacenConfig(
|
|
129
|
+
perfil="sicoob",
|
|
130
|
+
conta="matriz",
|
|
131
|
+
chave_pix="...",
|
|
132
|
+
client_id="...",
|
|
133
|
+
ambiente="producao",
|
|
134
|
+
certificado_pem=cert,
|
|
135
|
+
chave_pem=chave,
|
|
136
|
+
)
|
|
137
|
+
adapter = PixBacenAdapter(config)
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
`brbank.criar_adapter("inter", config)` resolve pelo nome e
|
|
141
|
+
`adapter.suporta(Capacidade.PDF)` consulta as capacidades em runtime.
|
|
142
|
+
|
|
143
|
+
## Regras
|
|
144
|
+
|
|
145
|
+
- Valores em `Decimal` (float e recusado). Percentuais em unidade de percentual.
|
|
146
|
+
- Nome, documento e endereco ficam fora do `repr`; log, erro e resposta bruta
|
|
147
|
+
passam por `brbank.mascara.mascarar`.
|
|
148
|
+
- Retry so para 429, 5xx e erro de transporte. Status desconhecido no banco
|
|
149
|
+
levanta erro, nunca vira "pago".
|
|
150
|
+
- Webhook gera `EventoCanonico` e nao confirma nada: reconsulte antes de liquidar.
|
brbank-0.0.1/README.md
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# brbank
|
|
2
|
+
|
|
3
|
+
Biblioteca Python assincrona para emitir e acompanhar boletos e cobrancas Pix em
|
|
4
|
+
bancos brasileiros por uma interface unica. Nao importa nada do Odoo: o modulo
|
|
5
|
+
`l10n_br_payment_boleto` e uma das faces possiveis.
|
|
6
|
+
|
|
7
|
+
Licenca MIT. Python 3.11+. **Alfa:** nenhum adapter foi validado em sandbox de
|
|
8
|
+
banco (`validado_sandbox = False`); o contrato de cada banco vem da documentacao
|
|
9
|
+
publica e de fontes de terceiros, com as duvidas em `docs/<banco>-duvidas.md`.
|
|
10
|
+
Estado: primeira fatia (modelo canonico, contrato
|
|
11
|
+
de adapter, transporte, autenticacao, orquestrador e os adapters da tabela abaixo).
|
|
12
|
+
|
|
13
|
+
## Bancos suportados
|
|
14
|
+
|
|
15
|
+
Todos os adapters passam pela mesma suite de contrato (registrar, consultar, baixar) contra um
|
|
16
|
+
servidor falso. "Origem" diz de onde veio o contrato: **Odoo** = portado de um modulo que ja roda
|
|
17
|
+
em producao (o adapter da biblioteca ainda nao rodou contra o banco), **ACBr** = levantado por leitura
|
|
18
|
+
do ACBr, usado so como documentacao, e de fontes de terceiros.
|
|
19
|
+
|
|
20
|
+
| Banco | Adapter (entry point) | Produto | Capacidades declaradas | Origem |
|
|
21
|
+
| --- | --- | --- | --- | --- |
|
|
22
|
+
| Inter (077) | `inter` | Cobranca v3, boleto hibrido | hibrido, so hibrido, baixa, PDF, webhook | Odoo |
|
|
23
|
+
| PinBank | `pinbank` | Boleto, envelope AES-CBC | baixa | Odoo |
|
|
24
|
+
| Sicoob (756) | `sicoob` | Cobranca v3, boleto hibrido | hibrido, alteracao, baixa | ACBr |
|
|
25
|
+
| Sicredi (748) | `sicredi` | Cobranca v2 | hibrido, alteracao, baixa, webhook | ACBr |
|
|
26
|
+
| Banco do Brasil (001) | `bb` | Cobranca v2 | alteracao, baixa | ACBr |
|
|
27
|
+
|
|
28
|
+
Pix (BACEN `/cob`, `/cobv`, `/webhook`) por um adapter generico, `pix_bacen`, com um perfil por PSP
|
|
29
|
+
(host, escopos, headers e quirks): Inter, Banco do Brasil, Sicoob, Sicredi, Itau, Bradesco,
|
|
30
|
+
Santander e Efi. Capacidades: Pix cob e cobv, webhook, baixa.
|
|
31
|
+
|
|
32
|
+
Fora desta lista por enquanto: BNB (sem referencia de Pix confiavel), Caixa, Safra, Banrisul,
|
|
33
|
+
Unicred, BTG e C6 (planejados), gateways como Mercado Pago, PagBank e Stone (sob demanda) e a
|
|
34
|
+
variante ECOMM do Sicredi. Banco novo = um adapter com `BankAdapter` e um entry point em
|
|
35
|
+
`brbank.adapters`; veja `docs/` para o que cada banco ainda deixa em aberto.
|
|
36
|
+
|
|
37
|
+
**Nenhum adapter da biblioteca foi validado em sandbox.** Sicoob, Sicredi, Banco do Brasil e os
|
|
38
|
+
perfis Pix trazem `validado_sandbox = False` no codigo e so passam a `True` depois de rodar contra o
|
|
39
|
+
ambiente real do banco. Inter e PinBank herdam a logica de modulos Odoo em producao, mas o adapter
|
|
40
|
+
da biblioteca tambem ainda nao rodou contra o banco.
|
|
41
|
+
|
|
42
|
+
## Uso
|
|
43
|
+
|
|
44
|
+
```python
|
|
45
|
+
from brbank import Orquestrador
|
|
46
|
+
from brbank.adapters.inter import InterAdapter, InterConfig
|
|
47
|
+
|
|
48
|
+
config = InterConfig(
|
|
49
|
+
conta="matriz",
|
|
50
|
+
client_id="...",
|
|
51
|
+
client_secret="...",
|
|
52
|
+
conta_corrente="123456",
|
|
53
|
+
ambiente="sandbox",
|
|
54
|
+
certificado_pem=cert_bytes,
|
|
55
|
+
chave_pem=chave_bytes, # vindos do cofre
|
|
56
|
+
)
|
|
57
|
+
adapter = InterAdapter(config)
|
|
58
|
+
orquestrador = Orquestrador(adapter, concorrencia=10)
|
|
59
|
+
|
|
60
|
+
registrado = await orquestrador.emitir(titulo) # idempotente por chave
|
|
61
|
+
resultados = await orquestrador.emitir_em_varios(lote) # falha isolada por titulo
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Um banco novo e um pacote que registra o adapter no entry point `brbank.adapters`:
|
|
65
|
+
|
|
66
|
+
```toml
|
|
67
|
+
[project.entry-points."brbank.adapters"]
|
|
68
|
+
inter = "brbank.adapters.inter:InterAdapter"
|
|
69
|
+
pinbank = "brbank.adapters.pinbank:PinbankAdapter"
|
|
70
|
+
sicoob = "brbank.adapters.sicoob:SicoobAdapter"
|
|
71
|
+
|
|
72
|
+
sicredi = "brbank.adapters.sicredi:SicrediAdapter"
|
|
73
|
+
|
|
74
|
+
pix_bacen = "brbank.adapters.pix_bacen:PixBacenAdapter"
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
O `PinbankAdapter` usa OAuth2 `password` e payload cifrado AES-CBC (`EnvelopeAesCbc`),
|
|
78
|
+
registra, consulta e baixa por `NossoNumero`, e nao tem webhook nem PDF. Contrato em
|
|
79
|
+
aberto: `docs/pinbank-duvidas.md`.
|
|
80
|
+
|
|
81
|
+
O `SicoobAdapter` (Cobranca Bancaria v3, boleto hibrido) usa OAuth2 `client_credentials`
|
|
82
|
+
sem `client_secret` (a identidade e o mTLS), header `client_id`, id do titulo = nosso
|
|
83
|
+
numero, registra, consulta, baixa e envia instrucao (prorrogacao, abatimento, protesto).
|
|
84
|
+
Sem PDF e sem webhook declarados. **`validado_sandbox = False`**: contrato montado de
|
|
85
|
+
documentacao de terceiros, nunca executado contra o Sicoob. Duvidas: `docs/sicoob-duvidas.md`.
|
|
86
|
+
|
|
87
|
+
O `BancoDoBrasilAdapter` (`bb`, API Cobranca v2, convenio de 6 ou 7 digitos) usa OAuth2
|
|
88
|
+
`client_credentials` e a chave `gw-dev-app-key` em query param; registra, consulta, baixa,
|
|
89
|
+
prorroga e abate, sem webhook nem PDF. Nasce com `validado_sandbox = False`: ver
|
|
90
|
+
`docs/bb-duvidas.md`.
|
|
91
|
+
|
|
92
|
+
O `SicrediAdapter` (API de Cobranca v2, OAuth2 `password`) registra, consulta, baixa e
|
|
93
|
+
altera (prorrogacao e abatimento); webhook sem assinatura exige reconsulta. Nasce com
|
|
94
|
+
`validado_sandbox = False`; contrato em aberto: `docs/sicredi-duvidas.md`.
|
|
95
|
+
|
|
96
|
+
O `PixBacenAdapter` fala a API Pix do BACEN (`/cob`, `/cobv`, `/webhook`, devolucao) e
|
|
97
|
+
muda de banco por `PerfilPsp`: `inter`, `bb`, `sicoob`, `sicredi`, `itau`, `bradesco`,
|
|
98
|
+
`santander` e `efi` (BNB sem perfil). Todos com `validado_sandbox = False` ate rodar no
|
|
99
|
+
sandbox. O `txid` vem da chave de idempotencia, o copia-e-cola e o `txid` chegam em
|
|
100
|
+
`TituloRegistrado`, e `CONCLUIDA` sem Pix na consulta nao liquida. Duvidas e quirks:
|
|
101
|
+
`docs/pix-duvidas.md`.
|
|
102
|
+
|
|
103
|
+
```python
|
|
104
|
+
config = PixBacenConfig(
|
|
105
|
+
perfil="sicoob",
|
|
106
|
+
conta="matriz",
|
|
107
|
+
chave_pix="...",
|
|
108
|
+
client_id="...",
|
|
109
|
+
ambiente="producao",
|
|
110
|
+
certificado_pem=cert,
|
|
111
|
+
chave_pem=chave,
|
|
112
|
+
)
|
|
113
|
+
adapter = PixBacenAdapter(config)
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
`brbank.criar_adapter("inter", config)` resolve pelo nome e
|
|
117
|
+
`adapter.suporta(Capacidade.PDF)` consulta as capacidades em runtime.
|
|
118
|
+
|
|
119
|
+
## Regras
|
|
120
|
+
|
|
121
|
+
- Valores em `Decimal` (float e recusado). Percentuais em unidade de percentual.
|
|
122
|
+
- Nome, documento e endereco ficam fora do `repr`; log, erro e resposta bruta
|
|
123
|
+
passam por `brbank.mascara.mascarar`.
|
|
124
|
+
- Retry so para 429, 5xx e erro de transporte. Status desconhecido no banco
|
|
125
|
+
levanta erro, nunca vira "pago".
|
|
126
|
+
- Webhook gera `EventoCanonico` e nao confirma nada: reconsulte antes de liquidar.
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Banco do Brasil: duvidas em aberto do contrato
|
|
2
|
+
|
|
3
|
+
Fontes usadas, por ordem de confianca:
|
|
4
|
+
|
|
5
|
+
1. **Doc oficial (developers.bb.com.br / apoio.developers.bb.com.br):** NAO foi
|
|
6
|
+
possivel ler. A pagina de referencia carrega por JavaScript e o WebFetch devolveu
|
|
7
|
+
so "Aguarde...". WebSearch nao trouxe a pagina oficial. Tudo abaixo precisa ser
|
|
8
|
+
conferido contra ela e contra o sandbox antes de producao.
|
|
9
|
+
2. **Leitura (so como documentacao, sem portar codigo, licenca LGPL) do ACBrBoleto:**
|
|
10
|
+
`WS/ACBrBoletoW_BancoBrasil_API.pas`, `WS/ACBrBoletoRet_BancoBrasil_API.pas`,
|
|
11
|
+
`ACBrBancoBrasil.pas` e a secao 3.1 de `Particularidades.html`. Dela vem: URLs,
|
|
12
|
+
`gw-dev-app-key` em query, paths, nomes de campo do payload e da resposta, datas
|
|
13
|
+
`DD.MM.YYYY`, composicao do `numeroTituloCliente`, tabela de `codigoEstadoTituloCobranca`,
|
|
14
|
+
campos de alteracao (PATCH) e o header `x-bb-portal-devx-cnpj-parceiro`.
|
|
15
|
+
3. **Fonte de terceiro (wiki CIGAM, via WebSearch):** escopos
|
|
16
|
+
`cobrancas.boletos-requisicao` e `cobrancas.boletos-info`.
|
|
17
|
+
|
|
18
|
+
O adapter nasce com `validado_sandbox = False`.
|
|
19
|
+
|
|
20
|
+
## Risco do PRD: chave de desenvolvedor e header de parceiro
|
|
21
|
+
|
|
22
|
+
- `gw-dev-app-key` e **query param** em toda chamada de negocio (nao em header),
|
|
23
|
+
inclusive no PATCH e no POST de baixa. O adapter a monta em `_caminho`, mantem fora
|
|
24
|
+
do repr da config e o transporte nunca loga URL.
|
|
25
|
+
- O header `x-bb-portal-devx-cnpj-parceiro` (CNPJ da software house) e opcional
|
|
26
|
+
(`BBConfig.cnpj_parceiro`). Nao se sabe se o BB passara a exigi-lo.
|
|
27
|
+
|
|
28
|
+
## Duvidas
|
|
29
|
+
|
|
30
|
+
1. **Autenticacao do token.** O ACBr usa credenciais no corpo no sandbox e Basic
|
|
31
|
+
(`client_id:client_secret`) em producao. O adapter replica isso por padrao
|
|
32
|
+
(`BBConfig.credenciais_no_corpo=None`) e deixa forcar. Confirmar no oficial.
|
|
33
|
+
2. **Escopos.** Fonte de terceiro, nao oficial. O escopo depende dos servicos marcados
|
|
34
|
+
no app do portal.
|
|
35
|
+
3. **Nosso numero.** `numeroTituloCliente` = "000" + convenio (7 digitos, zeros a
|
|
36
|
+
esquerda) + nosso numero (10 digitos), pela montagem do ACBr. Para convenio de 6
|
|
37
|
+
digitos o ACBr aplica a mesma regra na API. O modelo canonico nao tem nosso numero:
|
|
38
|
+
quem chama passa `BBConfig.gerar_nosso_numero` ou usa `seu_numero` numerico de ate
|
|
39
|
+
10 digitos. Quem garante a unicidade da sequencia e o chamador. Convenios de 4 e 5
|
|
40
|
+
digitos (so CNAB) sao recusados.
|
|
41
|
+
4. **Duplicidade.** Nao se sabe qual codigo o BB devolve para `numeroTituloCliente`
|
|
42
|
+
repetido. So o 409 vira `Duplicado`; a idempotencia real e o cache por
|
|
43
|
+
`chave_idempotencia` (no processo) e o `Orquestrador`.
|
|
44
|
+
5. **Status do registro.** A resposta traz linha digitavel e codigo de barras, entao o
|
|
45
|
+
adapter devolve `REGISTRADO` (nao `PENDENTE_REGISTRO`). Nao confirmado.
|
|
46
|
+
6. **Tabela de status.** Mapeados: 1, 2, 3, 4, 5, 8, 9, 13 (REGISTRADO), 6 (LIQUIDADO),
|
|
47
|
+
7 (BAIXADO), 80 (transitorio, PENDENTE_REGISTRO). **Deliberadamente fora** (levantam
|
|
48
|
+
`Validacao`): 10 (baixado/pago em cartorio), 11 e 12 (liquidado com protesto ou
|
|
49
|
+
cartorio), 14 (em liquidacao), 15 e 21 (agendado), 16 (creditado), 17 (pago em
|
|
50
|
+
cheque), 18 e 19 (pago parcialmente). Sem a doc oficial nao da para saber se cada um
|
|
51
|
+
e dinheiro recebido; liquidar ou baixar por palpite e pior que recusar. Candidatos a
|
|
52
|
+
LIQUIDADO apos confirmacao: 11, 12, 16.
|
|
53
|
+
7. **Pagamento parcial.** `indicadorPermissaoRecebimentoParcial` nao e enviado. O
|
|
54
|
+
modelo canonico nao tem o conceito.
|
|
55
|
+
8. **Data de emissao.** O modelo nao tem `dataEmissao`; o adapter usa a data do dia
|
|
56
|
+
(`hoje` injetavel). Confirmar se o BB aceita emissao posterior a hoje ou anterior.
|
|
57
|
+
9. **Multa.** O BB exige data de inicio; o adapter usa vencimento + 1 dia (suposicao).
|
|
58
|
+
Tipo 2 = percentual. Juros: tipo 2 = taxa mensal. Desconto: tipo 2 = percentual ate
|
|
59
|
+
a data, `dataExpiracao` = vencimento menos `desconto_dias_antes`. Tipos vindos do ACBr.
|
|
60
|
+
10. **Baixa automatica.** `dias_baixa_automatica` e recusado: a equivalencia com
|
|
61
|
+
`numeroDiasLimiteRecebimento` (prazo de recebimento apos o vencimento) nao e
|
|
62
|
+
certa. Mensagem: o BB limita a 30 caracteres; acima disso o adapter recusa em vez
|
|
63
|
+
de truncar em silencio.
|
|
64
|
+
11. **CPF/CNPJ como inteiro.** `numeroInscricao` e `cep` vao como numero (como no
|
|
65
|
+
ACBr). CNPJ alfanumerico nao cabe: recusado com `Validacao`. Perguntar ao BB.
|
|
66
|
+
12. **Pix no boleto (`indicadorPix`).** Configuravel. Quando "S" a resposta de registro
|
|
67
|
+
traz `qrCode.emv/txId/url`, que o adapter expoe em `pix_copia_cola` e `txid`. A
|
|
68
|
+
consulta de detalhe nao traz o Pix (ha `GET /boletos/{id}/pix`, nao implementado), e
|
|
69
|
+
por isso `HIBRIDO` nao e declarada.
|
|
70
|
+
13. **Baixa.** Resposta com `dataBaixa` e `horarioBaixa`; o adapter devolve `BAIXADO`
|
|
71
|
+
direto, sem reconsultar.
|
|
72
|
+
14. **Alteracao (PATCH).** Implementados: nova data de vencimento
|
|
73
|
+
(`indicadorNovaDataVencimento` + `alteracaoData`) e abatimento (incluir se o titulo
|
|
74
|
+
nao tem `valorAbatimentoTituloCobranca`, alterar se tem; o adapter consulta antes).
|
|
75
|
+
Cancelar abatimento, desconto, juros, multa, valor nominal, protesto e negativacao
|
|
76
|
+
existem na API mas ficaram fora (o modelo `Instrucao` nao carrega os dados, ou o
|
|
77
|
+
efeito nao esta claro). PROTESTO e NEGATIVACAO levantam `NaoSuportado`.
|
|
78
|
+
15. **PDF.** Nao ha endpoint de segunda via no que foi lido; `PDF` nao e declarada.
|
|
79
|
+
16. **Webhook.** Nada no contrato lido. `parse_webhook` levanta `NaoSuportado`.
|
|
80
|
+
17. **Listagem (`GET /boletos` com filtros)** e a API de consulta por periodo ficaram
|
|
81
|
+
fora da primeira fatia.
|
|
82
|
+
18. **Homologacao.** O ACBr tem um terceiro ambiente (`api.hm.bb.com.br`); o adapter so
|
|
83
|
+
aceita `sandbox` e `producao`.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# PinBank: duvidas em aberto do contrato
|
|
2
|
+
|
|
3
|
+
Fonte unica usada: modulo Odoo `l10n_br_payment_boleto_pinbank` (kmee-odoo-addons,
|
|
4
|
+
branch 16.0). Nao ha documentacao oficial da API no repositorio. O que o modulo nao
|
|
5
|
+
esclarece ficou fora do adapter ou recusado com `Validacao`, em vez de inventado.
|
|
6
|
+
|
|
7
|
+
1. **Unidade de Juros e Multa.** O modulo envia `{"Valor": int(boleto_interest * 10000)}`
|
|
8
|
+
e `int(boleto_penalty * 10000)`; o vetor de teste usa `Valor: 100`. Nao se sabe se e
|
|
9
|
+
centesimos de percentual, fracao x 10000, nem se juros e ao dia ou ao mes. O adapter
|
|
10
|
+
recusa titulo com multa, juros, desconto, abatimento ou baixa automatica.
|
|
11
|
+
2. **Desconto, abatimento e baixa automatica.** O modulo nao envia. Mesmo tratamento.
|
|
12
|
+
3. **Endereco do sacado.** O modulo envia so `street_name` em `Endereco`; numero e
|
|
13
|
+
complemento nao vao em campo algum. O adapter segue o modulo (so o logradouro).
|
|
14
|
+
4. **CPF/CNPJ e CEP como inteiros.** O modulo envia `int(...)`, o que descarta zeros a
|
|
15
|
+
esquerda (o vetor mostra `Cep: 8473002` na ida e `"08473002"` na volta). O adapter
|
|
16
|
+
segue o modulo. CNPJ alfanumerico nao cabe em inteiro: e recusado com `Validacao`.
|
|
17
|
+
Confirmar com o PinBank se aceitam string e como tratarao o CNPJ alfanumerico.
|
|
18
|
+
5. **Idempotencia no banco.** O modulo nao manda identificador do cliente. A resposta
|
|
19
|
+
traz `IdentificadorCliente` (nulo no vetor), talvez aceito na geracao. Hoje a garantia
|
|
20
|
+
contra boleto em dobro e do adapter (cache e lock por `chave_idempotencia`, no
|
|
21
|
+
processo) e do `Orquestrador` (repositorio de chaves, entre processos).
|
|
22
|
+
6. **PDF.** `RetornarBase64` devolve o PDF so na geracao; nao ha endpoint de segunda via
|
|
23
|
+
no modulo e a consulta nao traz `Base64`. O adapter nao declara `PDF`. O PDF recebido
|
|
24
|
+
na geracao fica em `resposta_bruta` mascarado ("***"). Falta um campo no modelo
|
|
25
|
+
canonico para entrega-lo (decisao de produto) ou confirmar endpoint de segunda via.
|
|
26
|
+
7. **Webhook.** O modulo so faz polling (cron de consulta). Sem contrato: `parse_webhook`
|
|
27
|
+
levanta `NaoSuportado` e `WEBHOOK` nao e declarada.
|
|
28
|
+
8. **Resposta da baixa.** O modulo ignora o corpo da baixa e reconsulta. O adapter faz
|
|
29
|
+
igual e devolve o estado consultado, que pode ainda nao ser `BAIXADO`.
|
|
30
|
+
9. **Status.** Mapa extraido do modulo: PENDENTE, REGISTRADO, LIQUIDADO, BAIXA. Se o
|
|
31
|
+
banco tiver outros (vencido, protestado, rejeitado), o adapter levanta `Validacao`
|
|
32
|
+
(nunca assume "pago").
|
|
33
|
+
10. **Expiracao do token.** O campo e `expire_in` (sem "s"); o autenticador aceita os dois.
|
|
34
|
+
Sem escopo OAuth: o cache e por (conta, sem escopo).
|
|
35
|
+
11. **Chave AES = senha do usuario**, IV zero, como no modulo. O IV fixo torna o cifrado
|
|
36
|
+
deterministico: a protecao real e o TLS.
|
|
37
|
+
12. **Erro HTTP com corpo cifrado ou nao.** O modulo le `Message` em claro nos erros;
|
|
38
|
+
o adapter nao decifra respostas >= 400 e as repassa mascaradas.
|
|
39
|
+
13. **Valor do boleto como `Valor` em centavos e `ValorPago` em centavos** (vetor:
|
|
40
|
+
`Valor: 25875`). `ValorPago` so e lido quando LIQUIDADO.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Pix BACEN generico: duvidas em aberto e quirks
|
|
2
|
+
|
|
3
|
+
Fonte do contrato: OpenAPI oficial da API Pix do BACEN (/cob, /cobv, /webhook,
|
|
4
|
+
/pix/{e2eid}/devolucao), conhecido do padrao publico. O comportamento por PSP
|
|
5
|
+
(host, URL do token, escopos, headers, quirks) foi lido nos fontes do ACBr
|
|
6
|
+
(`ACBrPIXCD`, licenca LGPL) como documentacao, sem portar codigo. Nenhum perfil
|
|
7
|
+
foi testado contra sandbox real: todos nascem com `validado_sandbox = False`.
|
|
8
|
+
O que a leitura nao esclarece ficou de fora ou recusado, nao inventado.
|
|
9
|
+
|
|
10
|
+
## Perfis
|
|
11
|
+
|
|
12
|
+
| Perfil | Auth | Escopo | mTLS | Quirks aplicados |
|
|
13
|
+
|---|---|---|---|---|
|
|
14
|
+
| inter | form (id+segredo) | sim | sim | nenhum |
|
|
15
|
+
| bb (API v2) | Basic | sim | prod | header `x-bb-portal-devx-cnpj-parceiro`, query `gw-dev-app-key`, alias `textoImagemQRcode` |
|
|
16
|
+
| sicoob | so `client_id` (sandbox: token fixo do portal) | sim | prod | header `client_id`, alias `brcode` -> `pixCopiaECola` |
|
|
17
|
+
| sicredi | Basic | sim | sim | nenhum |
|
|
18
|
+
| itau | form (id+segredo) | nao | prod | header `x-correlationID` (UUID por chamada) |
|
|
19
|
+
| bradesco | Basic, HTTP/1.1 | nao | sim | nenhum |
|
|
20
|
+
| santander | form, `?grant_type` na URL | nao | prod | sandbox cria por POST, baixa (PATCH) em `/api/v2` na producao |
|
|
21
|
+
| efi (GerenciaNet) | Basic + corpo JSON, HTTP/1.1 | nao | sim | header opcional `x-partner-token` |
|
|
22
|
+
| bnb | sem perfil | | | ver abaixo |
|
|
23
|
+
|
|
24
|
+
## Duvidas
|
|
25
|
+
|
|
26
|
+
1. **BNB sem perfil.** O ACBr nao tem PSP do Banco do Nordeste. `obter_perfil("bnb")`
|
|
27
|
+
levanta `Validacao`. Falta documentacao do portal do BNB (host, token, escopos).
|
|
28
|
+
2. **Escopos.** O ACBr pede por padrao cob/cobv/pix/webhook (read e write). Nao ha
|
|
29
|
+
evidencia de qual conjunto cada banco aceita; se o banco recusar um escopo, o
|
|
30
|
+
token falha. Ajustar `escopos` no perfil quando o sandbox responder. Itau, Bradesco,
|
|
31
|
+
Santander e Efi nao mandam escopo (como no ACBr).
|
|
32
|
+
3. **Idempotencia do `txid`.** O `txid` sai do SHA-256 de `conta|chave_idempotencia`
|
|
33
|
+
(32 hex, dentro de 26-35). A OpenAPI nao diz qual HTTP um PSP devolve para PUT em
|
|
34
|
+
txid existente; o adapter so converte em consulta o 409 (`Duplicado`). Se algum
|
|
35
|
+
banco devolve 400 ou 422, o titulo falha como `Validacao` e o `Orquestrador` (que
|
|
36
|
+
guarda a chave) evita a repeticao. Confirmar por banco.
|
|
37
|
+
4. **PUT versus POST.** O adapter sempre cria por `PUT /cob(v)/{txid}`. O ACBr converte
|
|
38
|
+
POST em PUT para BB v1 e Santander, e o sandbox do Santander so aceita POST (perfil
|
|
39
|
+
`metodo_criar_sandbox`). `POST /cob` com txid gerado pelo banco nao e usado.
|
|
40
|
+
5. **BB API v1.** So a v2 tem perfil. A v1 (`api.bb.com.br/pix/v1`) tem `/cobqrcode`
|
|
41
|
+
no sandbox e delimitador `/` antes da query; nao implementado. Confirmar qual
|
|
42
|
+
versao usar.
|
|
43
|
+
6. **Santander pre-producao e sandbox.** Existe host de pre-producao
|
|
44
|
+
(`trust-pix-h.santander.com.br`), sem perfil. O sandbox devolve JSON fora do padrao
|
|
45
|
+
(lista `cobs[0]`/`pix[0]`); o ACBr corrige, o adapter nao.
|
|
46
|
+
7. **Itau sandbox.** Exige o header `x-sandbox-token` com o token obtido; o autenticador
|
|
47
|
+
atual nao expoe o token ao adapter. Nao implementado. O fluxo de certificado
|
|
48
|
+
(CSR/renovacao em `/seguranca/v1/certificado`) tambem fica fora.
|
|
49
|
+
8. **Sicoob em producao.** O ACBr manda so `client_id`, sem segredo, e a identidade vem
|
|
50
|
+
do mTLS. Confirmar que nao ha `client_secret`.
|
|
51
|
+
9. **HTTP/1.1.** O ACBr forca 1.1 so na chamada de token de Bradesco e Efi. Aqui o
|
|
52
|
+
cliente inteiro desses perfis usa 1.1 (`Transporte(http2=False)`), mais simples e
|
|
53
|
+
mais conservador. Confirmar se so o token precisa.
|
|
54
|
+
10. **Webhook sem assinatura.** O BACEN protege o callback por mTLS do PSP, nao por HMAC.
|
|
55
|
+
`parse_webhook` nao autentica nada: o receptor precisa validar o certificado do PSP
|
|
56
|
+
(fora da lib) e reconsultar antes de liquidar. A Efi documenta um header para pular
|
|
57
|
+
a checagem de mTLS no cadastro do webhook (`x-skip-mtls-checking`), do conhecimento
|
|
58
|
+
geral e nao da referencia: nao implementado.
|
|
59
|
+
11. **Webhook sem `txid`.** Pix de QR estatico chega sem `txid`; o adapter ignora (sem
|
|
60
|
+
titulo para baixar). Se o produto quiser conciliar Pix avulso, falta um evento
|
|
61
|
+
canonico proprio. Devolucoes dentro do corpo (`devolucoes`) tambem sao ignoradas.
|
|
62
|
+
12. **Valor pago parcial e devolucao.** `valor_pago` e a soma de `pix[].valor` da
|
|
63
|
+
consulta, sem descontar devolucoes. Cobranca com `modalidadeAlteracao` nao e
|
|
64
|
+
emitida (valor fixo), entao pagamento parcial nao e esperado.
|
|
65
|
+
13. **CNPJ alfanumerico.** O adapter envia `cnpj` com o valor normalizado (A-Z e digitos).
|
|
66
|
+
Nao se sabe quais PSPs ja aceitam letras no campo `devedor.cnpj` (o schema antigo
|
|
67
|
+
exigia 14 digitos).
|
|
68
|
+
14. **Endereco do devedor.** Em `cobv` o adapter manda logradouro (com numero), cidade,
|
|
69
|
+
UF e CEP quando o `Pessoa` tem endereco. Alguns PSPs podem exigir todos os campos;
|
|
70
|
+
nao e validado localmente.
|
|
71
|
+
15. **Mapeamento de encargos para `cobv`.** Multa = modalidade 2 (percentual); juros =
|
|
72
|
+
modalidade 3 (percentual ao mes, dias corridos); abatimento = modalidade 1 (valor
|
|
73
|
+
fixo); desconto = modalidade 2 (percentual ate a data, `vencimento - dias_antes`).
|
|
74
|
+
O `valorPerc` do abatimento e um valor em reais, nao percentual, apesar do nome do
|
|
75
|
+
campo no BACEN. Juros e multa em outras modalidades (dia util, ao dia) ficam fora.
|
|
76
|
+
16. **`REMOVIDA_PELO_PSP`.** Mapeada para `BAIXADO`. Pode ser expiracao; se o produto
|
|
77
|
+
quiser distinguir, falta um status canonico.
|
|
78
|
+
17. **`cob` imediata.** Recusa multa, juros, desconto e abatimento; a validade e
|
|
79
|
+
`expiracao_s` (padrao 86400), nao o vencimento do `Titulo`.
|
|
80
|
+
18. **Fora do escopo desta entrega:** consulta de Pix por `e2eid` e por periodo, listagem
|
|
81
|
+
de cobrancas, lote `cobv`, `payloadlocation`, recorrencia (`rec`, `cobr`), revisao
|
|
82
|
+
de valor (PATCH com `valor`) e `enviar_instrucao`.
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Sicoob (756) API de Cobranca v3: duvidas em aberto
|
|
2
|
+
|
|
3
|
+
`SicoobAdapter.validado_sandbox = False`. Nada foi executado contra o Sicoob.
|
|
4
|
+
|
|
5
|
+
## Fontes
|
|
6
|
+
|
|
7
|
+
- Referencia de comportamento LIDA (LGPL, nenhum codigo portado, usada so como
|
|
8
|
+
documentacao de endpoints, campos e quirks): ACBr, `ACBrBoletoW_Sicoob_V3.pas`,
|
|
9
|
+
`ACBrBoletoRet_Sicoob_V3.pas`, `ACBrBancoSicoob.pas` e `Particularidades`.
|
|
10
|
+
- Documentacao oficial: o portal `developers.sicoob.com.br` nao entrega a especificacao
|
|
11
|
+
sem login (WebFetch devolveu so o titulo da pagina). Nao foi possivel conferir o swagger.
|
|
12
|
+
- Terceiros lidos: thread do forum ACBr sobre a migracao para a v3 (URLs, mudancas de
|
|
13
|
+
formato) e README do `mangati/sicoob-sdk` (escopo `boletos_inclusao`, `pdfBoleto`).
|
|
14
|
+
|
|
15
|
+
Antes de usar em producao: obter o swagger v3 e rodar a suite contra o sandbox
|
|
16
|
+
(token fixo do sandbox fica no portal, entra em `SicoobConfig.token_sandbox`).
|
|
17
|
+
|
|
18
|
+
## Duvidas
|
|
19
|
+
|
|
20
|
+
1. **Corpo do POST /boletos: objeto ou lista?** O ACBr monta um objeto; o swagger v3 pode
|
|
21
|
+
exigir lista. O adapter envia objeto e aceita `resultado` como objeto ou lista (e
|
|
22
|
+
`resultado.boleto` aninhado). Confirmar.
|
|
23
|
+
2. **Escopos.** So `boletos_inclusao` tem o nome confirmado em fonte de terceiros.
|
|
24
|
+
`boletos_consulta` e `boletos_alteracao` sao suposicao, por isso ficam em
|
|
25
|
+
`SicoobConfig.escopos` (chaves `incluir`, `consultar`, `alterar`).
|
|
26
|
+
3. **Token sem `client_secret`.** O ACBr envia so `client_id`, `scope`, `grant_type`
|
|
27
|
+
(a autenticacao e o certificado mTLS, que tambem vale na chamada de token). Seguido.
|
|
28
|
+
Token expira em ~300s segundo o SDK de terceiros; o cache usa `expires_in` da resposta.
|
|
29
|
+
4. **Nosso numero como id.** Consulta, baixa e alteracao usam `nossoNumero` na URL. O
|
|
30
|
+
ACBr calcula e anexa o digito verificador antes de montar a URL; nao se sabe se o
|
|
31
|
+
`nossoNumero` devolvido no registro ja o inclui. O adapter usa o valor devolvido como
|
|
32
|
+
veio. Confirmar.
|
|
33
|
+
5. **Consulta.** `GET /boletos?numeroCliente&codigoModalidade&nossoNumero`; 204 (sem
|
|
34
|
+
conteudo) vira `Validacao`. Campo de situacao: `situacaoBoleto` com textos como
|
|
35
|
+
"Em Aberto", "Liquidado", "Baixado", "CANCELADO". Lista completa desconhecida.
|
|
36
|
+
6. **Status.** Mapeados so EM ABERTO, LIQUIDADO, BAIXADO, CANCELADO. `VENCIDO` e
|
|
37
|
+
`EXPIRADO` existem como constantes no ACBr sem uso: ficam fora (viram `Validacao`)
|
|
38
|
+
ate haver contrato. Um boleto vencido e em aberto ainda e cobravel? Confirmar.
|
|
39
|
+
7. **Valor e data do pagamento.** Nao ha campo numerico: o valor vem de texto em
|
|
40
|
+
`listaHistorico[tipoHistorico=6].descricaoHistorico` apos "R$". O adapter interpreta
|
|
41
|
+
formato pt-BR e, se falhar, devolve `valor_pago=None`. Formato real desconhecido.
|
|
42
|
+
8. **PDF.** Fora: o ACBr envia `gerarPdf=false` e so le `pdfBoleto` no registro. Existe
|
|
43
|
+
provavelmente um endpoint de segunda via, nao confirmado. `PDF` nao e declarada.
|
|
44
|
+
9. **Webhook.** Nao ha contrato conhecido para boleto. `WEBHOOK` nao declarada,
|
|
45
|
+
`parse_webhook` levanta `NaoSuportado`. O ACBr usa polling por movimentacao.
|
|
46
|
+
10. **Movimentacao (fora do escopo).** `POST /boletos/movimentacoes`, consulta da
|
|
47
|
+
solicitacao e download de arquivo zip em base64 (siglas ENTR, PROR, AVENC, VENC,
|
|
48
|
+
LIQUI, BAIX; janela de 2 dias). Util para conciliar em lote; nao implementado.
|
|
49
|
+
11. **Alteracao.** `PATCH /boletos/{nn}` com `prorrogacaoVencimento`, `abatimento` (e,
|
|
50
|
+
na referencia, `desconto`, `jurosMora`, `multa`, `seuNumero`); protesto em
|
|
51
|
+
`POST /boletos/{nn}/protestos`; negativacao em `/negativacoes` com verbos variados
|
|
52
|
+
(nao implementada). O adapter cobre PRORROGACAO, ABATIMENTO, PROTESTO e BAIXA e devolve
|
|
53
|
+
o estado reconsultado (a API nao devolve dados na alteracao).
|
|
54
|
+
12. **Desconto.** O modelo canonico traz percentual + dias antes; foi mapeado para
|
|
55
|
+
`tipoDesconto=2` (percentual ate a data informada), data = vencimento - dias. A
|
|
56
|
+
alternativa `5` (percentual por antecipacao em dias corridos) pode ser mais fiel.
|
|
57
|
+
13. **Multa e juros.** Percentual de multa = `tipoMulta 2`; juros mensal = `tipoJurosMora 2`.
|
|
58
|
+
Data de inicio (`dataMulta`, `dataJurosMora`) = vencimento + 1 dia, escolha do adapter
|
|
59
|
+
(o ACBr reaproveita a data de juros). Sem encargo: `tipoMulta 0`, `tipoJurosMora 3`.
|
|
60
|
+
14. **Campos obrigatorios nao deduzidos.** `codigoEspecieDocumento` (sem padrao: vem da
|
|
61
|
+
config, tabela do banco), `codigoModalidade` (padrao 1, simples com registro),
|
|
62
|
+
`numeroParcela` (1), `aceite` (false), emissao e distribuicao pelo banco
|
|
63
|
+
(`banco_emite_e_distribui`). `dataEmissao` e a data do dia, injetavel nos testes.
|
|
64
|
+
15. **Baixa automatica por dias** nao tem campo conhecido: o titulo com
|
|
65
|
+
`dias_baixa_automatica` e recusado. Protesto e negativacao no registro (`codigoProtesto`,
|
|
66
|
+
`numeroDiasProtesto`, `codigoNegativacao`) nao existem no modelo canonico.
|
|
67
|
+
16. **CPF/CNPJ.** Enviados sem mascara; se a API aceita CNPJ alfanumerico e
|
|
68
|
+
desconhecido. CEP so digitos. Endereco = logradouro + numero (a API nao tem campo
|
|
69
|
+
separado na referencia); complemento nao e enviado.
|
|
70
|
+
17. **Cota.** O ACBr limita a 2 envios por segundo; adotado como padrao
|
|
71
|
+
(`requisicoes_por_segundo=2.0`). Limite real desconhecido.
|
|
72
|
+
18. **Erros.** O corpo de erro traz `mensagens[{codigo, mensagem}]` segundo a referencia;
|
|
73
|
+
o adapter nao interpreta (o transporte mascara e repassa). Duplicidade nao
|
|
74
|
+
mapeada para `Duplicado` por falta de codigo conhecido.
|
|
75
|
+
19. **Hibrido.** `HIBRIDO` e declarada fixa, mas depende de `cadastrar_pix=True`
|
|
76
|
+
(`codigoCadastrarPIX=1`), que exige Pix habilitado na cooperativa. O QR vem em `qrCode`.
|