# Guía de Integración — API de Partners > Flujo completo para integrar Firma Digital como partner — emitir códigos de compra, canjear identidad, y obtener el certificado. Esta guía cubre el ciclo de vida completo de un código de compra: emitirlo, canjearlo (validar la identidad del titular), y obtener el certificado ya emitido. Hay dos APIs separadas, en dos servidores distintos: - **API de Códigos de Compra** (`partner-pcode`, Cloudflare Worker, `/api/partner/v1`) — genera y lista códigos de compra. - **API de Partners** (`/api/partners/v1`) — canjea identidad y entrega certificados. ## 1. Tu configuración determina el flujo, no el endpoint A diferencia de versiones anteriores de esta API, **hay un solo endpoint de canje** (`certificate_request`). Su comportamiento se ajusta automáticamente según tu configuración de partner: | Tu configuración | Qué pasa en `certificate_request` | | --- | --- | | `require_cedula_serie = 0` (flujo completo, default) | Debes enviar `names`/`fLastname`/`phone`. Se valida contra Clave Única además de Registro Civil. | | `require_cedula_serie = 1` (flujo reducido) | **No** envíes `names`/`fLastname`/`phone` — se obtienen de Registro Civil. Debes enviar `serialNumber` (serie de la cédula). Sin Clave Única. | | `mode = 1` (B2C, default) | El certificado se entrega recién cuando llames `certificate_claim`. | | `mode = 2` (B2B) | El certificado se genera y se entrega automático (webhook/email) en la misma llamada a `certificate_request` — **no llames `certificate_claim`**, siempre te va a responder "ya emitido". | Estos dos ajustes son independientes entre sí — puedes tener flujo reducido + B2B, flujo completo + B2C, o cualquier otra combinación. Contacta a soporte para configurarlos. ## 2. Flujo B2C (el más común) 1. **Emitir un código de compra** — `POST /pcode` en la API de Códigos de Compra. ```bash curl -X POST https://partner-pcode.tsp.workers.dev/api/partner/v1/pcode \ -H "x-gw: $API_KEY" \ -H "Content-Type: application/json" \ -d '{"productCode": "FV01", "external_reference_id": "orden-12345"}' ``` Esta llamada puede fallar con `400` si tu partner no tiene ese `productCode` habilitado — cada partner puede tener restringido a qué productos (`FV00`-`FV03`) tiene acceso. Si no te queda claro qué productos tenés habilitados, contactá a soporte. 2. **Canjear el código de compra** — `POST /certificate_request`. Los campos varían según tu flujo (ver tabla arriba). Ejemplo con flujo reducido: ```bash curl -X POST https://api.firma.digital/api/partners/v1/certificate_request \ -H "x-gw: $API_KEY" \ -H "Content-Type: application/json" \ -d '{ "pCode": "MIPARTNER-26-FV01-A1B2C3D4", "referenceId": "orden-12345", "dni": "18925910-7", "serialNumber": "536463312", "email": "usuario@ejemplo.com", "pin": "1234" }' ``` La respuesta trae `status: "VALIDATED"` — el certificado **todavía no existe**, solo se verificó la identidad. 3. **Obtener el certificado** — `POST /certificate_claim`, con el mismo `pin` usado en el paso anterior (funciona como contraseña del PFX). ```bash curl -X POST https://api.firma.digital/api/partners/v1/certificate_claim \ -H "x-gw: $API_KEY" \ -H "Content-Type: application/json" \ -d '{"p_code": "MIPARTNER-26-FV01-A1B2C3D4", "dni": "18925910-7", "pin": "1234"}' ``` Esta llamada es **de una sola vez**: si la repites, responde `201` con `ALREADY_ISSUED` en vez de regenerar el certificado. Si necesitas recuperarlo después de reclamado, contacta a soporte. ## 3. Flujo B2B Igual al paso 1 y 2 de arriba, pero el paso 2 ya es el último: si tu configuración tiene `mode = 2`, la respuesta de `certificate_request` viene con `status: "EMITTED"` y el certificado se entrega automáticamente por el webhook y/o email que tengas configurado — pueden ser ambos a la vez, no es uno u otro. No hay paso 3. ## 4. Consultar estado `GET /status?p_code=...` — útil sobre todo si integraste vía **widget** (el usuario completa el flujo en su navegador, no en una sola llamada tuya) y necesitas saber en qué va sin escuchar los eventos del widget en tiempo real. ```bash curl "https://api.firma.digital/api/partners/v1/status?p_code=MIPARTNER-26-FV01-A1B2C3D4" \ -H "x-gw: $API_KEY" ``` Estados posibles, en orden de precedencia (el primero que aplica gana): | Estado | Significa | | --- | --- | | `CANCELLED` | Anulado (orden cancelada) — gana incluso sobre un certificado ya emitido. | | `EXPIRED` | El certificado se emitió pero ya venció. | | `EMITTED` | Certificado generado y entregado. | | `LOCKED` | Bloqueado antes de llegar a emitirse — si ya se había emitido, no aparece: sigue mostrando `EMITTED`. | | `IN_ONBOARDING` | El usuario está a mitad del flujo del widget. | | `VALIDATED` | Identidad verificada (solo B2C), falta llamar `certificate_claim`. | | `ACTIVE` | Existe, nadie lo canjeó todavía. | | `NOT_FOUND` | El código de compra no existe. | ## 5. Errores comunes | Código | Causa | | --- | --- | | `401` | API Key inválida o ausente. | | `404` | El código de compra no existe (o, en `certificate_claim`, existe pero nunca pasó por `certificate_request`). | | `406` | Rechazo de negocio — el mensaje (`message`) indica cuál: serie requerida, RUT no coincide, email duplicado, cédula no coincide con Registro Civil, fecha de vencimiento no coincide, etc. | | `423` | El código de compra está bloqueado de forma permanente (anulado). | | `429` | Rate limit — 10 emisiones por minuto por partner, o intentos de validación de cédula agotados (bloqueo de seguridad temporal). | Ver la [Referencia de la API de Partners](/api/partners/) y la [Referencia de la API de Códigos de Compra](/api/pcode/) para el detalle completo de cada endpoint.