Saltearse al contenido

Crea un link de pago

POST
/v1/pagos/links

Genera un link de cobro: el comprador paga con tarjeta en una página segura externa y Host Factura registra el cobro cuando llega la confirmación.

Este endpoint NO emite ningún comprobante

Si mandás borradorCfe, el comprobante se valida ahora (ítems, CAE vigente, certificado, simulación de emisión) y se emite recién cuando el cobro se confirma. Es deliberado: un CFE quema su número aunque después se anule, y el retorno del navegador no es una confirmación de pago.

Si la validación del borrador falla, la respuesta es 422 con la lista de problemas en error.details.detalles. Corregilos y volvé a crear el link: es mucho más barato que descubrirlo cuando el cliente ya pagó.

Campos principales

CampoTipoObligatorioNotas
montostring decimalsí"1234.56". También se acepta número, pero el string evita perder precisión
monedaUYU | USDsíNo se procesa ninguna otra moneda (ver abajo)
returnUrlurl http(s)síA dónde vuelve el navegador del comprador
referenciaIntegradorstringnoTu identificador del cobro (orden, carrito, socio). Único por cuenta
clienteIduuidnoCliente de tu cuenta
cfeEmitidoIduuidnoFactura a crédito que este pago salda
facturasarraynoVarias facturas (hasta 40) con su monto por factura
borradorCfeobjetonoComprobante a emitir al confirmarse el cobro
politicaFiscalenumnofacturar_al_cobrar, recibo_al_cobrar, solo_registrar
mediosarraynoMedios habilitados en la página de pago: cards, banks, paynet
expiraEnfecha ISOnoVencimiento del link
descripcion, metadata, clientenoDatos de presentación y contacto

referenciaIntegrador: tu identificador del cobro

Se persiste verbatim y es única por cuenta: un segundo link con la misma referencia y otra clave de idempotencia se rechaza con 409 PAGOS_REFERENCIA_DUPLICADA. Es la defensa contra cobrar dos veces la misma orden desde dos procesos distintos.

Después se usa como filtro exacto en GET /v1/pagos/links?referenciaIntegrador=... y en GET /v1/pagos?referenciaIntegrador=.... En una cuenta sin facturación electrónica es el único identificador que el operador reconoce: no hay número de CFE con el que cruzar.

Forma: hasta 128 caracteres de A-Za-z0-9._:/-.

Idempotencia

La cabecera Idempotency-Key es opcional pero recomendada. Con la misma clave se reusa la solicitud ya creada y su referencia externa, y se devuelve 200 con meta.reusada: true en vez de 201. Sin la cabecera, cada llamada crea un link nuevo.

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.

Datos del link de cobro

object
Ejemplos
{
"monto": "1234.56",
"moneda": "UYU",
"returnUrl": "https://tienda.ejemplo.com/pago/retorno",
"referenciaIntegrador": "orden-12345",
"clienteId": "7e6d5c4b-3a2f-4e1d-9c8b-7a6f5e4d3c2b",
"politicaFiscal": "facturar_al_cobrar",
"medios": [
"cards"
],
"descripcion": "Orden 12345",
"expiraEn": "2026-09-19T23:59:59-03:00",
"metadata": {
"orden": "12345"
}
}

La solicitud ya existía para esa Idempotency-Key: se devuelve la misma

object
Ejemplos
{
"data": {},
"meta": {
"reusada": true
}
}

Link creado

object
Ejemplos
{
"data": {
"solicitud": {
"id": "8f14e45f-ceea-467a-9f5a-2b1c3d4e5f60",
"referenciaExterna": 1042,
"referenciaIntegrador": "orden-12345",
"estado": "pendiente",
"monto": "1234.56",
"moneda": "UYU",
"politicaFiscal": "facturar_al_cobrar",
"tieneBorrador": true
},
"redirectUrl": "https://pagos.ejemplo.com/checkout/abc123",
"gatewayToken": "abc123"
},
"meta": {
"reusada": false
}
}

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

Conflicto. La referenciaIntegrador ya está usada en la cuenta por otro link (PAGOS_REFERENCIA_DUPLICADA), la cuenta no tiene la conexión de cobros configurada (PAGOS_CONEXION_AUSENTE), los cobros están apagados (PAGOS_CONFIG_DESHABILITADA), la política fiscal exige facturación electrónica que la cuenta no tiene (PAGOS_POLITICA_REQUIERE_FACTURACION), o la Idempotency-Key ya se usó para otra operación.

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

Referencia del integrador repetida

{
"error": {
"code": "PAGOS_REFERENCIA_DUPLICADA",
"message": "Ya existe un link de cobro con la referencia 'orden-12345' en esta cuenta"
},
"requestId": "1e2f3a4b-5c6d-4e7f-8a9b-0c1d2e3f4a5b"
}

El borrador del comprobante no es emitible (ítem inexistente, CAE agotado, certificado vencido…) — la lista está en error.details.detalles —, o es una moneda que no se procesa.

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

Borrador inválido

{
"error": {
"code": "PAGOS_BORRADOR_INVALIDO",
"message": "El comprobante a emitir no es válido",
"details": {
"detalles": [
"No hay CAE vigente para el tipo 101 serie A"
]
}
},
"requestId": "2b7c1d3e-4f5a-6b7c-8d9e-0f1a2b3c4d5e"
}

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