Saltearse al contenido

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 factura es una venta que todavía no documentaste. Encontralos con GET /v1/pagos?estado=aprobado.

El cliente sale de la tarjeta: no hace falta mandarlo.

El bloque factura

tipoQué emiteDato
contadoe-Ticket o e-Factura por lo cobradoborrador: la misma forma que el cuerpo de POST /v1/cfe/emitir (tipo, ítems, cliente…).
reciboe-Recibo que salda facturas ya emitidasfacturas: [{ 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

HTTPSignificadoQué hacer
200Cobrado. Si data.yaEstabaCobrado es true, era el mismo cobro de un intento anteriorTratarlo como éxito
400Falta la clave o es inválidaCorregir el request
422Rechazo definitivo (tarjeta rechazada, no elegible), o el factura no se puede emitirNo reintentar igual
503Fallo transitorio de la red de pagos, o el cobro queda en_verificacionReintentar 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 es 403 API_ALCANCE_INSUFICIENTE con la lista en error.requerido. Las credenciales creadas antes del modelo de alcances (alcances: null) conservan acceso total.

Monedas: los cobros se procesan sólo en UYU y USD. Cualquier otro ISO-4217 se rechaza con 422 PAGOS_MONEDA_NO_SOPORTADA, que devuelve la lista admitida en error.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 cabecera x-cuenta-id de 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. Enviar sucursalId o puntoEmisionId en el JSON no tiene efecto.

Idempotency-Key
string
>= 8 characters <= 128 characters /^[A-Za-z0-9._:~-]{8,128}$/
Ejemplo
orden-12345-cobro-1

Clave 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.

x-cuenta-id
string format: uuid
Ejemplo
0199d1b0-0000-7000-8000-000000000000

Só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.

x-branch-id
string format: uuid

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.

x-point-id
string format: uuid

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.

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"
}

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
error
required
object
code
required

Identificador estable del error en SCREAMING_SNAKE_CASE

string
message
required

Mensaje legible en español. No parsearlo: puede cambiar

string
details
Any of:
object
requerido

Sólo en 403 API_ALCANCE_INSUFICIENTE: alcances que habilitan la operación

Array<string>
Allowed values: cfe:emitir cfe:leer recibidos:leer consultas clientes:leer clientes:escribir pagos:leer pagos:cobrar pagos:tarjetas pagos:suscripciones pagos:configurar webhooks:gestionar
requestId

UUID de correlación; mismo valor que el header X-Request-ID

string format: uuid
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
error
required
object
code
required

Identificador estable del error en SCREAMING_SNAKE_CASE

string
message
required

Mensaje legible en español. No parsearlo: puede cambiar

string
details
Any of:
object
requerido

Sólo en 403 API_ALCANCE_INSUFICIENTE: alcances que habilitan la operación

Array<string>
Allowed values: cfe:emitir cfe:leer recibidos:leer consultas clientes:leer clientes:escribir pagos:leer pagos:cobrar pagos:tarjetas pagos:suscripciones pagos:configurar webhooks:gestionar
requestId

UUID de correlación; mismo valor que el header X-Request-ID

string format: uuid
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"
}

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:

CodeQué pasóCómo se corrige
PAGOS_NO_HABILITADOLa cuenta no tiene el módulo de cobrosEs una habilitación comercial: la hace administración, no se activa desde la API
API_ALCANCE_INSUFICIENTELa credencial no tiene el alcance (va en error.requerido)Editar la credencial en Integraciones → API
API_CUENTA_FUERA_DE_CARTERAx-cuenta-id apunta a una cuenta ajena a la carteraRevisar el UUID de la subcuenta

Ninguno se arregla reintentando.

object
error
required
object
code
required

Identificador estable del error en SCREAMING_SNAKE_CASE

string
message
required

Mensaje legible en español. No parsearlo: puede cambiar

string
details
Any of:
object
requerido

Sólo en 403 API_ALCANCE_INSUFICIENTE: alcances que habilitan la operación

Array<string>
Allowed values: cfe:emitir cfe:leer recibidos:leer consultas clientes:leer clientes:escribir pagos:leer pagos:cobrar pagos:tarjetas pagos:suscripciones pagos:configurar webhooks:gestionar
requestId

UUID de correlación; mismo valor que el header X-Request-ID

string format: uuid
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"
}

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
error
required
object
code
required

Identificador estable del error en SCREAMING_SNAKE_CASE

string
message
required

Mensaje legible en español. No parsearlo: puede cambiar

string
details
Any of:
object
requerido

Sólo en 403 API_ALCANCE_INSUFICIENTE: alcances que habilitan la operación

Array<string>
Allowed values: cfe:emitir cfe:leer recibidos:leer consultas clientes:leer clientes:escribir pagos:leer pagos:cobrar pagos:tarjetas pagos:suscripciones pagos:configurar webhooks:gestionar
requestId

UUID de correlación; mismo valor que el header X-Request-ID

string format: uuid
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"
}

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
error
required
object
code
required

Identificador estable del error en SCREAMING_SNAKE_CASE

string
message
required

Mensaje legible en español. No parsearlo: puede cambiar

string
details
Any of:
object
requerido

Sólo en 403 API_ALCANCE_INSUFICIENTE: alcances que habilitan la operación

Array<string>
Allowed values: cfe:emitir cfe:leer recibidos:leer consultas clientes:leer clientes:escribir pagos:leer pagos:cobrar pagos:tarjetas pagos:suscripciones pagos:configurar webhooks:gestionar
requestId

UUID de correlación; mismo valor que el header X-Request-ID

string format: uuid
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"
}

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
error
required
object
code
required

Identificador estable del error en SCREAMING_SNAKE_CASE

string
message
required

Mensaje legible en español. No parsearlo: puede cambiar

string
details
Any of:
object
requerido

Sólo en 403 API_ALCANCE_INSUFICIENTE: alcances que habilitan la operación

Array<string>
Allowed values: cfe:emitir cfe:leer recibidos:leer consultas clientes:leer clientes:escribir pagos:leer pagos:cobrar pagos:tarjetas pagos:suscripciones pagos:configurar webhooks:gestionar
requestId

UUID de correlación; mismo valor que el header X-Request-ID

string format: uuid
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"
}
Retry-After
integer
Ejemplo
42

Segundos 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
error
required
object
code
required

Identificador estable del error en SCREAMING_SNAKE_CASE

string
message
required

Mensaje legible en español. No parsearlo: puede cambiar

string
details
Any of:
object
requerido

Sólo en 403 API_ALCANCE_INSUFICIENTE: alcances que habilitan la operación

Array<string>
Allowed values: cfe:emitir cfe:leer recibidos:leer consultas clientes:leer clientes:escribir pagos:leer pagos:cobrar pagos:tarjetas pagos:suscripciones pagos:configurar webhooks:gestionar
requestId

UUID de correlación; mismo valor que el header X-Request-ID

string format: uuid
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"
}