Validación técnica de la API de BIND contra producción (GET-only)
Plan A del saldo CONFIRMADO (Total − Payments − CreditNotes, misma fila); flujo MVP sostenible 100% en lectura; PDF del CFDI por API. Hallazgo duro: sin recurso de pagos individuales ni REP (escalar a Pedro). Cliente extendido (Quotes, Currencies, Locations, pdf/xml, GET por ID estilo REST) y tipos reales en types.real.ts. Detalle en bind-api-sandbox/VALIDACION-API.md; reporte crudo y token gitignoreados.
This commit is contained in:
+41
-18
@@ -7,21 +7,31 @@ Está pensado para que tú (Johann), Pedro (Balam) o un futuro dev puedan:
|
||||
2. Probar el cliente tipado contra un mock que replica los headers, el formato OData y el rate-limit observable de BIND.
|
||||
3. Cuando Pedro entregue las credenciales reales, **cambiar dos variables de entorno** y apuntar el mismo código a `https://api.bind.com.mx` sin reescribir nada.
|
||||
|
||||
> ✅ **ACTUALIZACIÓN 6-jul-2026 — validación contra el API real EJECUTADA.**
|
||||
> Con el token entregado por Pedro (usuario de Arturo Rosas) se corrió la validación
|
||||
> técnica de solo lectura (117 peticiones GET). Resultados completos, tabla de
|
||||
> cobertura de endpoints, inventario de campos y veredicto del saldo en
|
||||
> **[VALIDACION-API.md](VALIDACION-API.md)**. Los hallazgos clave ya están
|
||||
> reconciliados en el cliente (`types.real.ts`, `BindClient` con `idStyle`).
|
||||
> El mock conserva el schema aproximado previo — sigue siendo útil para CI/demo,
|
||||
> pero el contrato real es el de `types.real.ts`.
|
||||
|
||||
---
|
||||
|
||||
## TL;DR del API de BIND (lo que descubrí del discovery)
|
||||
## TL;DR del API de BIND (reconciliado con la validación del 6-jul)
|
||||
|
||||
| Tema | Hallazgo |
|
||||
|---|---|
|
||||
| **Base URL** | `https://api.bind.com.mx` |
|
||||
| **Estilo** | REST con sintaxis **OData v3** (filtros `$filter`, `$top`, `$skip`, `$orderby`, `$count`, IDs como `guid'...'`) |
|
||||
| **Auth** | Dos headers: `Authorization: Bearer <API_KEY>` + `Ocp-Apim-Subscription-Key: <SUBSCRIPTION_KEY>` (este último cuando aplica) |
|
||||
| **Origen del API key** | Cuenta BIND → Perfil de usuario → pestaña *Integraciones* |
|
||||
| **Rate limit** | **20,000 peticiones / día** (confirmado por Noe, 25-may-2026) |
|
||||
| **Sandbox oficial** | **No existe.** BIND recomienda Postman contra producción → razón #1 de este sandbox |
|
||||
| **Portal dev** | [developers.bind.com.mx](https://developers.bind.com.mx) (login requerido para ver schemas detallados) |
|
||||
| **PAC para CFDI** | Integrado dentro del propio BIND — la plataforma de Balam **no toca el SAT**, solo orquesta |
|
||||
| **Recursos confirmados** | `Activities`, `Customers`, `Products` (y según el discovery doc: `Invoices`, `Payments`, `Quotes` muy probables) |
|
||||
| **Base URL** | `https://api.bind.com.mx` ✅ confirmado |
|
||||
| **Estilo** | REST con filtros OData v3 (`$filter`, `$top`≤100, `$skip`, `$orderby`). ⚠️ `$select` NO funciona (500); conteo total inaccesible; **GET por ID es REST `/{id}`, no `(guid'...')`** |
|
||||
| **Auth** | ✅ **Solo** `Authorization: Bearer <token>` — la `Ocp-Apim-Subscription-Key` no se requiere. ⚠️ Token inválido → **500** (no 401) |
|
||||
| **Origen del API key** | Cuenta BIND → Perfil de usuario → pestaña *Integraciones* (el de Balam salió del usuario de **Arturo Rosas**) |
|
||||
| **Rate limit** | **20,000 peticiones / día** — no observable en headers; llevar contador local |
|
||||
| **Sandbox oficial** | **No existe.** Este mock local sigue siendo la única red de pruebas sin efecto fiscal |
|
||||
| **PAC para CFDI** | Integrado en BIND; el PDF del CFDI se descarga vía `GET /api/Invoices/{id}/pdf` ✅ |
|
||||
| **Recursos confirmados (200)** | `Invoices`, **`Clients`** (no Customers), **`Quotes`**, `Products`, `Currencies`, `Warehouses`, `Locations`, `Activities`, `PriceLists`, `Orders`, `Providers`, `Banks`, `BankAccounts`, `Users` |
|
||||
| **Recursos que NO existen** | **`Payments`** (≈20 nombres probados → 404 — el acumulado pagado viene DENTRO de cada factura), `Customers`, `Series`, `CreditNotes`, `Companies`… |
|
||||
| **Saldo por factura** | ✅ **Plan A operativo:** `Total − Payments − CreditNotes` en la misma fila de `/api/Invoices` (verificado aritméticamente) |
|
||||
|
||||
### Por qué un sandbox propio y no Postman
|
||||
|
||||
@@ -75,18 +85,26 @@ Stats del cliente
|
||||
{ requestsToday: 6, quota: 20000, remaining: 19994, mode: 'read-only' }
|
||||
```
|
||||
|
||||
### Apuntar a producción (cuando llegue el API key)
|
||||
### Apuntar a producción (token real)
|
||||
|
||||
Solo cambiar variables de entorno — el código no se modifica:
|
||||
Solo cambiar variables de entorno — el código no se modifica (el cliente detecta
|
||||
el estilo de ID; contra el API real usa `/{id}`):
|
||||
|
||||
```powershell
|
||||
$env:BIND_BASE_URL = "https://api.bind.com.mx"
|
||||
$env:BIND_API_KEY = "<key del perfil de usuario de Balam>"
|
||||
$env:BIND_SUBSCRIPTION_KEY = "<si aplica>"
|
||||
$env:BIND_API_TOKEN = "<token del perfil de Arturo — NUNCA versionarlo>"
|
||||
$env:BIND_MODE = "read-only" # mantenlo así hasta tener autorización para escribir
|
||||
npm run demo
|
||||
```
|
||||
|
||||
> ⚠️ La demo fue escrita contra el schema del mock (`types.ts` aproximados);
|
||||
> contra producción algunos escenarios no aplican (p. ej. `Customers` → 404 real).
|
||||
> Para explorar el API real usa el script de validación:
|
||||
>
|
||||
> ```powershell
|
||||
> npm run validate:real # solo GET, presupuesto de peticiones, reporte sanitizado
|
||||
> ```
|
||||
|
||||
---
|
||||
|
||||
## Mapeo a la arquitectura de Balam
|
||||
@@ -151,9 +169,14 @@ Estos son los puntos del `03_Anexo_Tecnico_Integraciones_Discovery_Balam.docx` y
|
||||
|
||||
## Limitaciones honestas de este sandbox
|
||||
|
||||
- **El schema de `Invoice`, `Customer`, etc. es una aproximación** — está modelado a partir de la doc pública y del flujo que necesita Balam, no del SDK oficial. Cuando salga el primer `GET` real contra producción, hay que reconciliar nombres de campos (especialmente capitalización y campos opcionales).
|
||||
- **El mock acepta cualquier Bearer**, solo valida que exista. No es un servidor de auth real, es un placeholder.
|
||||
- **El parser de OData del mock solo cubre lo que el cliente genera** (`eq, ne, gt, lt, ge, le, and, or`, paréntesis). No soporta `contains`, `startswith`, funciones, lambdas. Suficiente para el MVP.
|
||||
- **No reproduce la lógica de `$expand`** — si BIND lo soporta para traer `Lines` o `Customer` embebidos, hay que extender.
|
||||
- **El schema del MOCK (`types.ts`) sigue siendo la aproximación previa** — el contrato
|
||||
confirmado contra producción vive en **`src/client/types.real.ts`** y en
|
||||
[VALIDACION-API.md](VALIDACION-API.md). Pendiente (opcional): regenerar el seed del
|
||||
mock con los shapes reales para que la demo ejercite el contrato confirmado.
|
||||
- **El mock acepta cualquier Bearer**, solo valida que exista. No es un servidor de auth real.
|
||||
- **El mock implementa el GET por ID estilo OData `(guid'...')`** — el API real usa `/{id}`;
|
||||
el cliente lo resuelve con `idStyle`, el mock quedó intacto.
|
||||
- **El parser de OData del mock solo cubre lo que el cliente genera** (`eq, ne, gt, lt, ge, le, and, or`, paréntesis).
|
||||
- **No reproduce la lógica de `$expand`** — y el API real ni siquiera soporta `$select`, así que el payload completo es la norma.
|
||||
|
||||
Cuando alguno de estos límites se vuelva una piedra en el zapato, se extiende. Hoy es deliberadamente mínimo.
|
||||
|
||||
Reference in New Issue
Block a user