Cobra con una tarjeta guardada
POST /v1/pagos/cobrar
Ejecuta un cobro desatendido contra una tarjeta que el cliente ya guardó.
Cobrar no es facturar
Sin el bloque factura, se cobra y no se emite ningún comprobante: el pago queda con facturado: false y lo podés facturar después con POST /v1/pagos/{id}/facturar. Si querés que el comprobante salga junto con el cobro, mandá factura: se valida antes de cobrar (si no se puede emitir, no se cobra) y se emite cuando el cobro se confirma.
Si tu empresa factura con Host Factura, un cobro sin
facturaes una venta que todavía no documentaste. Encontralos conGET /v1/pagos?estado=aprobado.
El cliente sale de la tarjeta: no hace falta mandarlo.
El bloque factura
tipo | Qué emite | Dato |
|---|---|---|
contado | e-Ticket o e-Factura por lo cobrado | borrador: la misma forma que el cuerpo de POST /v1/cfe/emitir (tipo, ítems, cliente…). |
recibo | e-Recibo que salda facturas ya emitidas | facturas: [{ cfeEmitidoId, monto }], hasta 40; la suma tiene que dar lo cobrado. |
Emitir consume numeración fiscal, así que pedir factura exige también el alcance cfe:emitir. En una empresa sin facturación electrónica responde 409 PAGOS_POLITICA_REQUIERE_FACTURACION.
La cabecera Idempotency-Key es OBLIGATORIA
Sin clave, cada llamada es un cobro nuevo: un reintento por timeout le cobraría dos veces al cliente. Sin cabecera responde 400 PAGOS_IDEMPOTENCY_KEY_REQUERIDA; con una de formato inválido (8 a 128 caracteres de A-Za-z0-9._:~-), 400 PAGOS_IDEMPOTENCY_KEY_INVALIDA. Reintentá siempre con la MISMA clave, y usá una clave distinta para cada cobro distinto: la clave de un cobro no vence.
Cómo leer el resultado
| HTTP | Significado | Qué hacer |
|---|---|---|
200 | Cobrado. Si data.yaEstabaCobrado es true, era el mismo cobro de un intento anterior | Tratarlo como éxito |
400 | Falta la clave o es inválida | Corregir el request |
422 | Rechazo definitivo (tarjeta rechazada, no elegible), o el factura no se puede emitir | No reintentar igual |
503 | Fallo transitorio de la red de pagos, o el cobro queda en_verificacion | Reintentar con la MISMA clave, o esperar el evento |
El estado en_verificacion NO es un fallo
Si la red de pagos no contesta la captura, se emite pago.en_verificacion: el cobro puede estar hecho. No entregues el producto, no lo declares impago y no reintentes con otra clave. Esperá pago.confirmado o pago.fallido, o reintentá con la misma clave.
Alcance requerido:
pagos:cobrar. Si la credencial no lo tiene, la respuesta es403 API_ALCANCE_INSUFICIENTEcon la lista enerror.requerido. Las credenciales creadas antes del modelo de alcances (alcances: null) conservan acceso total.
Monedas: los cobros se procesan sólo en
UYUyUSD. Cualquier otro ISO-4217 se rechaza con422 PAGOS_MONEDA_NO_SOPORTADA, que devuelve la lista admitida enerror.details.monedasAdmitidas. (La emisión de CFE sí admite el resto de las monedas de DGI: el límite es del cobro, no del comprobante.)
La empresa sale de la credencial. No hay ningún parámetro ni campo de cuerpo que la elija: cada API_KEY opera sobre su propia
EFacturaCuenta. La ÚNICA excepción es la cabecerax-cuenta-idde una credencial de revendedor, que apunta a una subcuenta de su cartera. Si integrás empresas que no son de tu cartera, usá una API_KEY por empresa.
La sucursal sale de la credencial y de los headers
x-branch-id/x-point-id, no del cuerpo. EnviarsucursalIdopuntoEmisionIden el JSON no tiene efecto.
Autorizaciones
Sección titulada «Autorizaciones »Parámetros
Sección titulada « Parámetros »Parámetros de header
Sección titulada «Parámetros de header »Ejemplo
orden-12345-cobro-1Clave de idempotencia de la operación (8 a 128 caracteres de A-Za-z0-9._:~-).
Con la misma clave y el mismo cuerpo, un reintento replica la respuesta original con meta.reusada: true y no vuelve a ejecutar nada. La misma clave con otro cuerpo —u otro endpoint— devuelve 409 PAGOS_IDEMPOTENCY_KEY_CONFLICTO; con la operación todavía en curso, 409 PAGOS_IDEMPOTENCY_EN_CURSO.
Sólo se cachean las respuestas 2xx: un 4xx/5xx libera la clave, así que podés corregir el cuerpo y reintentar con la MISMA clave. La ventana es de 24 horas.
Ejemplo
0199d1b0-0000-7000-8000-000000000000Sólo para credenciales de cuenta proveedora (revendedor). UUID de la subcuenta de la cartera sobre la que se quiere operar: la cuenta efectiva del request pasa a ser esa.
Una credencial que no es de proveedor, o una subcuenta que no está en su cartera, recibe 403 API_CUENTA_FUERA_DE_CARTERA. Sin la cabecera, la cuenta es siempre la de la credencial.
Sucursal contra la que operar, cuando la credencial es global. Si la credencial está fijada a una sucursal y esta cabecera indica otra, la respuesta es 403 API_ACCESS_BRANCH_MISMATCH. Sin la cabecera se asume la casa central.
Punto de emisión dentro de la sucursal resuelta. Obligatorio cuando la sucursal tiene 2 o más puntos activos (400 PUNTO_EMISION_REQUERIDO si falta); con uno solo se selecciona automáticamente.
Cuerpo de la solicitud
Sección titulada «Cuerpo de la solicitud »Cobro: tarjetaId, monto, moneda (UYU o USD) y, opcionales, descripcion y factura. Cualquier otro campo es un 422.
object
Ejemplos
{ "tarjetaId": "3a2f1e0d-9c8b-4a7f-8e6d-5c4b3a2f1e0d", "monto": "1500.00", "moneda": "UYU", "descripcion": "Mensualidad septiembre"}Cobrar y emitir el e-Ticket en el mismo paso
{ "tarjetaId": "3a2f1e0d-9c8b-4a7f-8e6d-5c4b3a2f1e0d", "monto": "1500.00", "moneda": "UYU", "factura": { "tipo": "contado", "borrador": { "tipo": 101, "moneda": "UYU", "items": [ { "name": "Mensualidad septiembre", "quantity": 1, "price": 1229.51, "billingIndex": 3 } ] } }}Cobrar una factura a crédito ya emitida (e-Recibo)
{ "tarjetaId": "3a2f1e0d-9c8b-4a7f-8e6d-5c4b3a2f1e0d", "monto": "1500.00", "moneda": "UYU", "factura": { "tipo": "recibo", "facturas": [ { "cfeEmitidoId": "1f2a3b4c-5d6e-4f7a-8b9c-0d1e2f3a4b5c", "monto": "1500.00" } ] }}Respuestas
Sección titulada « Respuestas »Cobro ejecutado (o recuperado por idempotencia)
object
Ejemplos
{ "data": { "solicitudId": "8f14e45f-ceea-467a-9f5a-2b1c3d4e5f60", "pagoId": "3c9a7b1d-2e4f-5a6b-7c8d-9e0f1a2b3c4d", "yaEstabaCobrado": false, "facturado": false }, "meta": { "idempotencyKey": "pedido-8812-cobro-1" }}Falta la cabecera Idempotency-Key, o su formato es inválido
object
object
Identificador estable del error en SCREAMING_SNAKE_CASE
Mensaje legible en español. No parsearlo: puede cambiar
object
object
Sólo en 403 API_ALCANCE_INSUFICIENTE: alcances que habilitan la operación
UUID de correlación; mismo valor que el header X-Request-ID
Ejemplos
Sin Idempotency-Key
{ "error": { "code": "PAGOS_IDEMPOTENCY_KEY_REQUERIDA", "message": "Falta la cabecera Idempotency-Key. Sin clave de idempotencia cada llamada es un cobro nuevo y un reintento por timeout cobraría dos veces." }, "requestId": "7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d"}No autenticado. La API_KEY no fue enviada, no es válida o la credencial está desactivada.
Códigos posibles: API_AUTH_HEADER_MISSING, API_AUTH_HEADER_INVALID, API_ACCESS_INVALID.
object
object
Identificador estable del error en SCREAMING_SNAKE_CASE
Mensaje legible en español. No parsearlo: puede cambiar
object
object
Sólo en 403 API_ALCANCE_INSUFICIENTE: alcances que habilitan la operación
UUID de correlación; mismo valor que el header X-Request-ID
Ejemplos
Falta header Authorization
{ "error": { "code": "API_AUTH_HEADER_MISSING", "message": "Se esperaba la cabecera Authorization con esquema Bearer" }, "requestId": "5b2c7c8a-1f6e-4d29-9a0b-7c3a8d1e2f4c"}Secret key inválida o revocada
{ "error": { "code": "API_ACCESS_INVALID", "message": "Acceso no autorizado" }, "requestId": "5b2c7c8a-1f6e-4d29-9a0b-7c3a8d1e2f4c"}El módulo de cobros no está habilitado para esta cuenta, o la credencial no tiene el alcance que la operación exige. Son dos cosas distintas y se corrigen distinto:
| Code | Qué pasó | Cómo se corrige |
|---|---|---|
PAGOS_NO_HABILITADO | La cuenta no tiene el módulo de cobros | Es una habilitación comercial: la hace administración, no se activa desde la API |
API_ALCANCE_INSUFICIENTE | La credencial no tiene el alcance (va en error.requerido) | Editar la credencial en Integraciones → API |
API_CUENTA_FUERA_DE_CARTERA | x-cuenta-id apunta a una cuenta ajena a la cartera | Revisar el UUID de la subcuenta |
Ninguno se arregla reintentando.
object
object
Identificador estable del error en SCREAMING_SNAKE_CASE
Mensaje legible en español. No parsearlo: puede cambiar
object
object
Sólo en 403 API_ALCANCE_INSUFICIENTE: alcances que habilitan la operación
UUID de correlación; mismo valor que el header X-Request-ID
Ejemplos
La cuenta no tiene el módulo de cobros
{ "error": { "code": "PAGOS_NO_HABILITADO", "message": "El módulo de pagos no está habilitado para esta cuenta. Es una habilitación comercial: la hace administración, no se activa desde la API." }, "requestId": "4c5d6e7f-8a9b-4c0d-1e2f-3a4b5c6d7e8f"}Falta el alcance
{ "error": { "code": "API_ALCANCE_INSUFICIENTE", "message": "La credencial de API no tiene ninguno de los alcances necesarios para esta operación (pagos:cobrar)", "requerido": [ "pagos:cobrar" ] }, "requestId": "7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d"}La tarjeta no sirve para cobro desatendido (PAGOS_MEDIO_NO_ELEGIBLE), los cobros de la empresa están apagados (PAGOS_CONFIG_DESHABILITADA), la empresa no emite comprobantes y el cobro trae factura (PAGOS_POLITICA_REQUIERE_FACTURACION), o la clave ya se usó para otro importe (PAGOS_IDEMPOTENCY_KEY_CONFLICTO).
object
object
Identificador estable del error en SCREAMING_SNAKE_CASE
Mensaje legible en español. No parsearlo: puede cambiar
object
object
Sólo en 403 API_ALCANCE_INSUFICIENTE: alcances que habilitan la operación
UUID de correlación; mismo valor que el header X-Request-ID
Ejemplos
La tarjeta no sirve para cobro desatendido
{ "error": { "code": "PAGOS_MEDIO_NO_ELEGIBLE", "message": "La tarjeta no esta habilitada para cobro recurrente" }, "requestId": "5b6a7988-9a0b-4c2d-8e4f-5a6b7c8d9e0f"}La empresa no emite comprobantes
{ "error": { "code": "PAGOS_POLITICA_REQUIERE_FACTURACION", "message": "Esta cuenta no tiene facturación electrónica habilitada: el cobro no puede pedir comprobante ni saldar facturas (borradorCfe). Cobrá sin datos fiscales." }, "requestId": "8b9c0d1e-2f3a-4b5c-6d7e-8f9a0b1c2d3e"}Rechazo definitivo del cobro (PAGOS_PROVEEDOR_DEFINITIVO), el comprobante de factura no se puede emitir (PAGOS_BORRADOR_INVALIDO, con la lista de problemas en error.details.detalles; no se cobró nada), o el cuerpo es inválido (VALIDATION_ERROR).
object
object
Identificador estable del error en SCREAMING_SNAKE_CASE
Mensaje legible en español. No parsearlo: puede cambiar
object
object
Sólo en 403 API_ALCANCE_INSUFICIENTE: alcances que habilitan la operación
UUID de correlación; mismo valor que el header X-Request-ID
Ejemplos
Tarjeta rechazada
{ "error": { "code": "PAGOS_PROVEEDOR_DEFINITIVO", "message": "El emisor rechazó el cobro", "details": { "codRespuesta": "05", "auditNumber": "A-99231" } }, "requestId": "1f2e3d4c-5b6a-7988-9a0b-1c2d3e4f5a6b"}El comprobante no se puede emitir (no se cobró)
{ "error": { "code": "PAGOS_BORRADOR_INVALIDO", "message": "El borrador del comprobante no es válido", "details": { "detalles": [ "No hay CAE vigente para el tipo 101" ] } }, "requestId": "2e3d4c5b-6a79-889a-0b1c-2d3e4f5a6b7c"}Moneda no admitida para cobros
{ "error": { "code": "PAGOS_MONEDA_NO_SOPORTADA", "message": "La pasarela de pagos no procesa la moneda 'EUR'. Monedas admitidas: UYU, USD", "details": { "monedasAdmitidas": [ "UYU", "USD" ] } }, "requestId": "3f6b1c2e-9a4d-4f80-bc11-7e2d5a8f0c31"}Rate limit excedido. Esperá los segundos del header Retry-After. La cuota va por credencial: 60 req/min en cuentas estándar, 600 en cuentas proveedor.
object
object
Identificador estable del error en SCREAMING_SNAKE_CASE
Mensaje legible en español. No parsearlo: puede cambiar
object
object
Sólo en 403 API_ALCANCE_INSUFICIENTE: alcances que habilitan la operación
UUID de correlación; mismo valor que el header X-Request-ID
Ejemplos
Excediste el rate limit
{ "error": { "code": "API_RATE_LIMITED", "message": "Se superó el límite de requests para esta API key" }, "requestId": "5b2c7c8a-1f6e-4d29-9a0b-7c3a8d1e2f4c"}Headers
Sección titulada «Headers »Ejemplo
42Segundos hasta que se libera la ventana de rate limit
No se pudo verificar la habilitación del módulo (PAGOS_ESTADO_INDETERMINADO), o falta la clave maestra de cifrado de secretos (PAGOS_CLAVE_MAESTRA_AUSENTE). Nada que corregir del lado del integrador: reintentar.
object
object
Identificador estable del error en SCREAMING_SNAKE_CASE
Mensaje legible en español. No parsearlo: puede cambiar
object
object
Sólo en 403 API_ALCANCE_INSUFICIENTE: alcances que habilitan la operación
UUID de correlación; mismo valor que el header X-Request-ID
Ejemplos
No se pudo leer el flag de pagos
{ "error": { "code": "PAGOS_ESTADO_INDETERMINADO", "message": "No se pudo verificar si el módulo de pagos está habilitado para esta cuenta. Reintentá." }, "requestId": "0f4a1c2e-5b6d-4e7f-8a9b-0c1d2e3f4a5b"}Clave maestra ausente
{ "error": { "code": "PAGOS_CLAVE_MAESTRA_AUSENTE", "message": "No está configurada la clave maestra de secretos de pagos" }, "requestId": "0f4a1c2e-5b6d-4e7f-8a9b-0c1d2e3f4a5b"}