Ir al contenido principal

Obtener Cartera

Permite a una pasarela de pagos autenticada (por ejemplo, Palomma) consultarregistrar lael cartera pagablepago de uno o varios ítems pagables en la inmobiliaria: una factura, un tercero:movimiento facturas(concepto pendientes,/ conceptosinterés) facturables,o conceptosuna nofactura facturablesjunto econ sus intereses deadjuntos. moraEl adjuntosendpoint aes facturasidempotente, devuelve un cuerpo en formato de canon.arreglo El sistemay aplica automáticamente la configuración de filtros avanzados registrada para la pasarela autenticada.(forma de pago, envío DIAN).

¿Para qué sirve este servicio?
Está pensado exclusivamente para integraciones con pasarelas de pago. La pasarela lo consumeinvoca paracuando mostrarle alel deudor confirma el pago en línea de los ítems quedevueltos puedepreviamente pagarpor enGET línea/gateways/portfolio. (facturas,El conceptossistema epersiste intereses),el respetandopago, genera el recibo de caja y, cuando la configuración comerciallo derequiera, dispara el envío del documento electrónico a la inmobiliaria (qué incluir, qué excluir, qué resoluciones se admiten, etc.).DIAN.

Endpoint restringido a pasarelas registradas
Este endpoint solo puede ser consumido por clientes OAuth2 cuyo client_name esté registrado como una pasarela activa en la inmobiliaria. Cualquier otro cliente recibirá 403 Forbidden.


1. El Endpoint (La dirección web)

Apunta tu sistema a la siguiente dirección. Recuerda reemplazar {{instancia}} por la dirección web completa que utilizas para ingresar a tu plataforma.

GETPOST https://{{instancia}}/service/v2/public/gateways/portfoliopayments

¿Qué debes colocar en {{instancia}}?
Es muy sencillo: corresponde a la dirección web principal que utilizas a diario para ingresar a tu plataforma (incluyendo la terminación .nuby.app o .arrendasoft.co).
Por ejemplo, si para entrar a tu sistema escribes inmobiliaria.nuby.app o inmobiliaria.arrendasoft.co en tu navegador, esa será exactamente tu instancia. Solo asegúrate de no incluir el "https://" ni barras diagonales ("/") al final.

2. La Petición (¿Qué debes enviarnos?)

EsteDebes servicioenviar requiereuna autenticaciónpetición mediantePOST uncon Tokenel JWTdetalle obtenidodel porpago OAuth2.en el cuerpo de la solicitud en formato JSON. La pasarela se identifica automáticamente a partir del client_name del token; no debes enviarloenviar el nombre de la pasarela ni la forma de pago en el body: niambos comose queryderivan string.de la configuración registrada.

Método GETPOST
Content-Type application/json
Authorization Bearer token, Token obtenido al consumir el servicio Login con un cliente OAuth2 registrado como pasarela activa.

Autenticación requerida
Este servicio requiere un Token de autenticación válido. Debes incluir el encabezado Authorization: Bearer TU_TOKEN en cada petición. El token se obtiene consumiendo el servicio de Login. El cliente OAuth además debe estar registrado como pasarela activa; en caso contrario el endpoint responderá 403.

ParámetrosCuerpo de consultala petición (query string)Body):

caracteres.Sololetras,números,guiones,guiones
ParámetroCampo Tipo RequeridoPor defecto Descripción
documentofactura_idintegerCondicionalIdentificador de la factura a pagar. Debe existir en el sistema. Es obligatorio si no se envía movimiento_id.
movimiento_idinteger | arrayCondicionalIdentificador (o lista de identificadores) de los movimientos a pagar. Es obligatorio si no se envía factura_id. Cuando se envía sin factura_id, por defecto solo se admite un único movimiento; sin embargo, si la pasarela tiene activo el filtro «Agrupar conceptos del mismo periodo», se aceptan varios movimientos del mismo tercero y se procesan en modo GROUP (un solo recibo de caja + cuando aplique una factura agrupada por contrato).
montonumberValor pagado por el deudor. Debe ser un número mayor a cero. Si excede el saldo adeudado, el excedente se registra como anticipo.
fecha_pagostringFecha y hora del pago. Formato estricto: YYYY-MM-DD HH:MM:SS.
n_comprobante string No Número de documentocomprobante del tercero (deudor) cuya cartera se desea consultar. Si se omite, se devolveráde la carterapasarela. de todos los terceros que cumplan los demás filtros.
pageintegerNo1Número de página de resultados que se desea recuperar.
page_sizeintegerNo10Número máximo de ítems por página. Valor máximo permitido:Máximo 1000100.
pendientes boolean No true Sibajos, es true, se devuelven únicamente ítems con estado = "pendiente"puntos y saldo > 0.
incluir_borradorbooleanNofalseSi es true, incluye facturas en estadoespacios. BorradorRecomendado: en el resultado.
incluir_conceptos_no_facturabooleanNofalseSi es true, incluye conceptos pagables que aún no tienen factura emitida.
incluir_conceptos_futurosbooleanNofalseSi es true, incluye conceptos cuyo periodo de aplicación es posterior agarantiza la fechaidempotencia actualante (cobros anticipados).
rango_conceptos_futuros_mesesinteger | stringNonullCantidad de meses hacia adelante en los que se admite incluir conceptos futuros (solo aplica si incluir_conceptos_futuros = true). Admite un entero positivo, el valor null para no acotar, o la cadena especial "current_month" para limitar la inclusión únicamente al mes actual.
incluir_intereses_morabooleanNofalseSi es true, los intereses de mora de una factura se devuelven adjuntos como ítems internos de su factura padre.
resolucion_idsarray | stringNoLista de IDs de resoluciones de facturación admitidas. Acepta un arreglo o una cadena separada por comas (por ejemplo: "3,7,12"). Solo se devuelven facturas emitidas con esas resoluciones.
agrupar_conceptos_periodobooleanNofalseSi es true, consolida los conceptos del mismo contrato, tercero y periodo (mismas fechas de inicio y fin) en un único ítem pagable. Los conceptos negativos del periodo solo se descuentan si existe un concepto positivo con saldo suficiente. Requiere que al menos uno de incluir_conceptos_no_factura o incluir_conceptos_futuros esté activo; en caso contrario el filtro se ignora.reintentos.

Filtros avanzadosModos de la pasarela
Los filtros enviados por el caller se combinan con la configuración de filtros avanzados registrada para la pasarela autenticada en la inmobiliaria. Si la pasarela no tiene configuración propia, se aplica el comportamiento por defecto (solo facturas con estado pendiente, sin borradores, sin conceptos sueltos ni intereses adjuntos). Los filtros realmente aplicados se devuelven en la respuesta dentro de filters_applied.

Exclusión de facturas a propietariooperación
El endpoint clasifica el pago en uno de cuatro modos según los campos enviados y la configuración de la pasarela:
excluyeModo automáticamentemovimiento único: lasfactura_id facturas= cuyosnull detallesy esténmovimiento_id asociados= [n].
Modo GROUP: factura_id = null y movimiento_id = [m1, m2, ...] con varios movimientos del mismo tercero. Solo se admite cuando la pasarela tiene activo el filtro avanzado «Agrupar conceptos del mismo periodo». Genera un único recibo de caja y, cuando aplique, una factura agrupada por contrato.
Modo factura: factura_id = X y movimiento_id = [] o ausente.
Modo factura + intereses adjuntos: factura_id = X y movimiento_id = [m1, m2, ...]. Los movimientos que pertenezcan a movimientosla defactura tipo FACTURA_PROPIETARIO (por ejemplo, comisiones del contrato facturadas al propietario). Estas facturas siguen una lógica contable distinta —generan EGRESO_PROPIETARIO en lugar de INGRESO_INQUILINO— y no son pagables vía pasarela en esta versión. NoX se incluyenignoran (ya están cubiertos); los demás se procesan como intereses sueltos en la respuestamisma ni en el conteo total.transacción.

EjemplosEjemplo 1: Pago de peticiones:una sola factura

GET{
    https://{{instancia}"factura_id": 4521,
    "monto": 1750000.00,
    "fecha_pago": "2026-04-25 14:30:00",
    "n_comprobante": "PALM-2026-04-25-998877"
}/service/v2/public/gateways/portfolio

Ejemplo 2: Pago de un movimiento (concepto suelto)

GET{
    https://{{instancia}"movimiento_id": 98515,
    "monto": 280000.00,
    "fecha_pago": "2026-04-25 14:30:00",
    "n_comprobante": "PALM-2026-04-25-998878"
}/service/v2/public/gateways/portfolio?documento=1020304050
GET

Ejemplo https://{{instancia}}/service/v2/public/gateways/portfolio?documento=1020304050&pendientes=true&page=1&page_size=20

3: Pago de una factura junto con sus intereses adjuntos

GET{
    https://{{instancia}"factura_id": 4521,
    "movimiento_id": [98410, 98411],
    "monto": 1820000.00,
    "fecha_pago": "2026-04-25 14:30:00",
    "n_comprobante": "PALM-2026-04-25-998879"
}/service/v2/public/gateways/portfolio?documento=1020304050&incluir_intereses_mora=true&incluir_conceptos_futuros=true&rango_conceptos_futuros_meses=3
GET https://{{instancia}}/service/v2/public/gateways/portfolio?documento=1020304050&resolucion_ids=3,7

3. La Respuesta (¿Qué te entregaremos?)

El sistema devolverá una respuesta JSONresponde con losHTTP ítems200 pagablescuando el pago se registra correctamente. La clave body es siempre un arreglo, incluso cuando el pago resulta en un solo registro. Cada elemento del tercero,arreglo losdescribe filtrosun realmentedocumento aplicadosgenerado ypor la información de paginación. Cada ítem se entrega conoperación: la mismafactura estructura canónica, sin importar si representapagada, una factura denueva contrato,creada unapor facturaintereses defacturables, venta,o un conceptoanticipo facturable,si unhubo concepto no facturable o una factura con intereses adjuntos.excedente.

{
    "success": true,
    "status": 200,
    "message": "LaEl cartera de la pasarelapago fue consultadaregistrado correctamente.exitosamente.",
    "body": [
        {
            "factura_id": 4521,
            "factura_numero"movimiento_id": "291",null,
            "contrato_id"pago_id": 187,87123,
            "contrato_numero"recibo_id": "C-000187",56412,
            "tercero_id"documento_contable_id": 272,102345,
            "tercero_documento": "1020304050",
            "tercero_nombre": "ANA MARÍA PÉREZ RODRÍGUEZ",
            "tercero_correo": "ana.perez@email.com",
            "tercero_telefono": "3001234567",
            "fecha_vencimiento": "2026-04-30",
            "observaciones": "Factura 291 del Contrato C-000187",
            "valor_total"monto_pagado": 1750000.00,
            "saldo"fecha_pago": "2026-04-25 14:30:00",
            "forma_pago_id": 7,
            "forma_pago": "Pasarela Palomma",
            "n_comprobante": "PALM-2026-04-25-998877",
            "saldo_anterior": 1750000.00,
            "saldo_actual": 0.00,
            "estado": "pagada",
            "mensaje": "El pago cubrió el total de la factura.",
            "estado_dian": "pendiente",
            "factura_pdf"documento_contable_pdf": "https://demo.nuby.app/contabilidad_documento.php?hash=a1b2c3d4e5"x1y2z3a4b5",
            "items"gateway": "palomma",
            "client_name": "palomma_inmobiliaria_xyz"
        }
    ],
    "alertas": [],
    "data": {
        "factura_id": 4521,
        "pago_id": 87123,
        "recibo_id": 56412,
        "documento_contable_id": 102345,
        "confirm_pay_id": 9921,
        "gateway": "palomma",
        "client_name": "palomma_inmobiliaria_xyz",
        "documentos_generados": [
            { "movimiento_id": 98231,
                    "descripcion"tipo": "Canon de arrendamiento - Canon abril 2026"recibo", "valor_unitario"id": 1600000.00,56412, "cantidad"numero": 1,
                    "valor_iva": 0.00,
                    "valor_retencion": 0.00,
                    "valor_reteiva": 0.00,
                    "valor_reteica": 0.00,
                    "valor_descuento": 0.00REC-56412" },
            { "tipo": "factura", "id": 4521, "numero": "FAC-4521" }
        ]
    }
}

Ejemplo de respuesta con excedente (anticipo):

{
    "success": true,
    "status": 200,
    "message": "El pago fue registrado exitosamente.",
    "body": [
        {
            "factura_id": 4521,
            "movimiento_id": 98232,null,
            "descripcion"pago_id": 87124,
            "recibo_id": 56413,
            "documento_contable_id": 102346,
            "monto_pagado": 1750000.00,
            "fecha_pago": "Administración2026-04-25 - Cuota administración abril 2026"14:30:00",
            "valor_unitario"forma_pago_id": 150000.7,
            "forma_pago": "Pasarela Palomma",
            "n_comprobante": "PALM-2026-04-25-998880",
            "saldo_anterior": 1750000.00,
            "cantidad": 1,
                    "valor_iva"saldo_actual": 0.00,
            "valor_retencion": 0.00,
                    "valor_reteiva": 0.00,
                    "valor_reteica": 0.00,
                    "valor_descuento": 0.00
                },
                {
                    "movimiento_id": 98410,
                    "descripcion"estado": "Interesespagada",
            "mensaje": "El pago cubrió el total de morala - Mora canon marzo 2026"factura.",
            "valor_unitario"estado_dian": 35000.00,"pendiente",
            "cantidad"documento_contable_pdf": 1,"https://demo.nuby.app/contabilidad_documento.php?hash=x1y2z3a4b6",
            "valor_iva"gateway": 0.00,"palomma",
            "valor_retencion"client_name": 0.00,
                    "valor_reteiva": 0.00,
                    "valor_reteica": 0.00,
                    "valor_descuento": 0.00
                }
            ]palomma_inmobiliaria_xyz"
        },
        {
            "factura_id": null,
            "factura_numero"movimiento_id": null,
            "contrato_id"pago_id": 187,null,
            "contrato_numero"recibo_id": "C-000187",null,
            "tercero_id"documento_contable_id": 272,102347,
            "tercero_documento"monto_pagado": "1020304050",50000.00,
            "tercero_nombre": "ANA MARÍA PÉREZ RODRÍGUEZ",
            "tercero_correo": "ana.perez@email.com",
            "tercero_telefono": "3001234567",
            "fecha_vencimiento"fecha_pago": "2026-05-15"04-25 14:30:00",
            "observaciones"forma_pago_id": 7,
            "forma_pago": "CostoPasarela del Contrato C-000187"Palomma",
            "valor_total"n_comprobante": 280000.00,"PALM-2026-04-25-998880",
            "saldo"saldo_anterior": 280000.00,null,
            "saldo_actual": null,
            "estado": "pendiente"anticipo",
            "items": [
                {
                    "movimiento_id": 98515,
                    "descripcion"mensaje": "ReparaciónSe locativageneró -un Reparaciónanticipo locativapor bañovalor principal"de 50000.00 con el excedente del pago.",
            "valor_unitario"estado_dian": 280000.00,null,
            "cantidad"gateway": 1,"palomma",
            "valor_iva"client_name": 0.00,
                    "valor_retencion": 0.00,
                    "valor_reteiva": 0.00,
                    "valor_reteica": 0.00,
                    "valor_descuento": 0.00
                }
            ]palomma_inmobiliaria_xyz"
        }
    ],
    "filters_applied"alertas": [],
    "data": {
        "documento"factura_id": 4521,
        "pago_id": 87124,
        "recibo_id": 56413,
        "documento_contable_id": 102346,
        "anticipo_documento_contable_ids": [102347],
        "confirm_pay_id": 9922,
        "gateway": "1020304050"palomma",
        "pendientes"client_name": true,
        "incluir_borrador": false,
        "incluir_conceptos_no_factura": true,
        "incluir_conceptos_futuros": false,
        "incluir_intereses_mora": true,
        "agrupar_conceptos_periodo": false
    },
    "pagination": {
        "total_records": 2,
        "total_pages": 1,
        "current_page": 1,
        "page_size": 10,
        "current_page_records": 2,
        "has_next_page": false,
        "has_previous_page": falsepalomma_inmobiliaria_xyz"
    }
}
Campos de la respuesta
Clave Descripción
success Indica si la operación fue exitosa (true) o no (false).
status Código HTTP devuelto (debe coincidir con el código real de la respuesta).devuelto.
message Mensaje descriptivo del resultado de la operación.resultado.
body Arreglo decon ítemsuno pagableso más registros generados por la operación (ver tabla detallada abajo). Puede ser vacío si no hay cartera.
filters_appliedalertas Objeto con los filtros realmente aplicados (combinaciónArreglo de losalertas filtrosno delbloqueantes callergeneradas +durante lael configuraciónproceso de(por laejemplo, pasarela)fallas en el envío DIAN).
paginationdata Objeto con la información consolidada del pago (IDs principales, identificador de paginaciónconfirmación, gateway, cliente). Adicionalmente puede incluir documentos_generados: un arreglo de objetos {tipo, id, numero} que lista todos los documentos creados u afectados por el pago (verrecibo tablade detalladacaja abajo)y factura(s)). El campo tipo puede ser "recibo" o "factura"; numero es el consecutivo legible para el usuario final.
error_codeSolo presente en respuestas de error. Códigos posibles: "DUPLICATE_PAYMENT", "VALIDATION_ERROR", "GATEWAY_NOT_FOUND", "GATEWAY_NOT_ACTIVE", "GATEWAY_PAYMENT_METHOD_REQUIRED", "INTERNAL_ERROR".
duplicateSolo presente en respuestas 409 Conflict. Contiene el snapshot del pago previamente registrado.
Estructura de cada ítemelemento (de body[])
aunconceptosin factura emitida
Clave Descripción
factura_id Identificador interno de la factura (PKpagada eno base de datos).generada. null cuandopara elregistros ítemde correspondeanticipo.
movimiento_id Identificador (concepto facturable o noarreglo facturable).de NoIDs) esde ellos númeromovimientos visibleasociados al usuario;registro. verPuede ser factura_numeronull.
factura_numeropago_id NúmeroIdentificador consecutivodel visiblepago de la factura (mismo valor que se muestra como "Factura N°"creado en lael interfaz de nuby).sistema. null cuandopara el ítem es un concepto sin factura emitida.anticipos.
contrato_idrecibo_id Identificador del contrato asociado. null para facturasrecibo de ventacaja sin contrato.generado.
contrato_numerodocumento_contable_id Número/código visibleIdentificador del contrato.documento nullcontable siasociado no(recibo, aplica.anticipo, etc.).
tercero_idmonto_pagado IdentificadorValor delefectivamente terceroaplicado (deudor)a alla quefactura/movimiento. pertenecenull elpara ítem.anticipos sin asignación específica.
tercero_documentoNúmero de documento de identificación del tercero.
tercero_nombreNombre completo (o razón social) del tercero.
tercero_correoCorreo electrónico del tercero (deudor). Es null si no tiene correo registrado en la inmobiliaria.
tercero_telefonoNúmero de teléfono/celular del tercero. Es null si no tiene teléfono registrado.
fecha_vencimientofecha_pago Fecha dey vencimientohora del ítem.pago. Formato: YYYY-MM-DD HH:MM:SS.
observacionesforma_pago_id MensajeIdentificador genéricointerno que identificade la naturaleza del ítem. Valores posibles:
  • "Factura del Contrato {numero}" — cuando el ítem es una factura asociada a un contrato (reemplaza {numero} por el consecutivo del contrato).
  • "Facturaforma de Venta"pago contable cuando el ítem es una factura(derivada de ventala sin contrato asociado.
  • "Costo del Contrato {numero}" — cuando el ítem corresponde a un concepto/movimientoconfiguración de unla contrato sin factura emitida.
El detalle por concepto/producto se expone en el campo descripcion de cada renglón de items[]pasarela).
valor_totalforma_pago ValorNombre total original del ítem (sumalegible de losla renglonesforma internos).de pago.
saldon_comprobanteNúmero de comprobante enviado por la pasarela.
saldo_anterior Saldo pendiente por pagar a la fecha de la consulta.factura/movimiento antes de aplicar el pago.
saldo_actualSaldo restante después de aplicar el pago.
estado Estado lógicodel registro tras la operación. Valores posibles:
  • "pagada": el monto cubrió el saldo total de la factura (saldo_actual = 0).
  • "pendiente": el monto fue inferior al saldo y la factura sigue con saldo pendiente. El campo mensaje describe el saldo restante.
  • "anticipo": la fila representa un excedente registrado como anticipo (sin factura asociada).
mensajeMensaje legible que describe el resultado del ítem.pago a nivel de cada fila. Valores típicos:
  • "El pago cubrió el total de la factura." cuando estado = "pagada".
  • "El pago fue registrado parcialmente. La factura aún tiene un saldo pendiente de {monto}." cuando estado = "pendiente".
  • "Se generó un anticipo por valor de {monto} con el excedente del pago." cuando estado = "anticipo".
estado_dianEstado del envío DIAN. Valores posibles: "pendiente", (envío en cola o fallido) o "pagada"null, "anulada"(no aplica). LasEl facturasdetalle condel estados internos fuera de alcancefallo se omitenreporta delen resultado.alertas.
factura_pdfdocumento_contable_pdf Enlace público firmado para la descarga segura del recibo de lacaja facturagenerado en formato PDF. Es válido de forma temporal y no se devuelveexpone como null cuando ella ítemfila representacorresponde a un concepto/movimientoanticipo sino facturacuando emitida.ocurre un fallo interno en la generación.
itemsgateway ArregloSlug de renglonesla internospasarela autenticada (por ejemplo, "palomma").
client_nameNombre del ítemcliente (verOAuth2 tabla detallada abajo). Para facturas, contiene los movimientos que la componen y, si aplica, los intereses de mora adjuntos.autenticado.
MapeoEscenarios de estados de factura
Estado internoEstado expuestoDescripción
1 (Facturada)"pendiente"Factura emitida y aún sin pagar.
5 (Borrador)"pendiente"Factura en estado borrador. Solo aparece si incluir_borrador = true.
2 (Anulada)"anulada"Factura anulada manualmente.
6 (Anulada por NC)"anulada"Factura anulada por nota crédito.
3 (Pagada)"pagada"Factura ya cancelada en su totalidad.
4, 7Estados fuera de alcance. La factura se excluyeespeciales del resultado.
Estructura de cada renglón interno (body[].items[])cuerpo
pagoquedapersistido(estado y alertas contiene una "...", "factura_id": ...
ClaveEscenario DescripciónComportamiento del body
movimiento_idPago simple IdentificadorUn delúnico movimientoelemento deque contratodescribe asociadoel alrecibo renglón. Puede ser null o 0 para renglones de facturas de venta sin movimiento.generado.
descripcionIntereses facturables TextoAl descriptivomenos deldos renglónelementos: conuno elpor formatola "{producto}factura -original {descripcion}", donde {producto} es el nombre del producto/conceptopagada y {descripcion}uno espor la descripciónfactura puntualnueva decreada ese ítem (mes facturado, observación específica, etc.). Si alguno depara los componentesintereses no existe se incluye vacío respetando el separador.facturables.
valor_unitarioExcedente / anticipo ValorCuando unitarioel monto pagado supera el saldo de los ítems enviados, el sistema genera un anticipo con el sobrante. La respuesta incluirá una fila adicional con estado = "anticipo", documento_contable_id poblado, monto_pagado con el valor del renglónanticipo, y los campos fecha_pago, forma_pago_id, forma_pago y n_comprobante heredados del pago original. Los campos factura_id, movimiento_id, pago_id, recibo_id, saldo_anterior y saldo_actual serán null. Importante: el sistema garantiza que primero se cubre el saldo de cada item enviado (base,factura siny/o IVAmovimientos) niy retenciones).solo el sobrante real se transforma en anticipo; nunca se desvía a anticipo el monto destinado a un movimiento explícitamente declarado.
cantidadFalla en envío DIAN CantidadEl facturada.
valor_ivaValor= del"pagada"), IVAestado_dian aplicado= al"pendiente", renglón.
valor_retencionValorentrada de{ la"level": retención"warning", en"code": la"DIAN_SEND_FAILED", fuente"message": aplicada.
valor_reteivaValor de la retención de IVA aplicada.
valor_reteicaValor de la retención de ICA aplicada.
valor_descuentoValor del descuento aplicado al renglón.}.

Información4. Idempotencia

El endpoint detecta automáticamente reintentos de paginaciónun (mismo pago y responde pagination409 Conflict) sin volver a registrarlo. Las reglas de idempotencia son:

pago
ClaveDisparador DescripciónComportamiento
total_recordsMismo n_comprobante CantidadCuando totalel den_comprobante ítemsya pagablesfue queregistrado cumplenpara la misma pasarela, se devuelve 409 con el registro previo.
Sin n_comprobante, mismos datos esencialesSi los filtrosdatos (sinfactura_id, paginar)movimiento_ids ordenados, monto, fecha_pago, client_name) coinciden con un pago previo, se devuelve 409.
total_pagesn_comprobante distinto, mismos datos esenciales CantidadSe totalaplica un hash de páginasrespaldo calculadassobre conlos eldatos esenciales y se devuelve page_size solicitado.
current_pagePágina actualmente devuelta.
page_sizeTamaño de página efectivamente aplicado.
current_page_recordsCantidad de ítems devueltos en la página actual.
has_next_pagetrue409 si existecoincide unacon páginaun siguiente.
has_previous_pagetrue si existe una página anterior.previo.

Cómo interpretar el 409
Una respuesta 409 Conflict de este endpoint no es un fallo: significa que el pago ya existe en nuby. La pasarela debe tratarla como confirmación idempotente y no reintentar. El cuerpo incluye error_code = "DUPLICATE_PAYMENT", is_business_error = true y, en data, los identificadores del pago original (confirm_pay_id, confirm_pay_reference_code, factura_id, pago_id, recibo_id, documento_contable_id).

Ejemplo de respuesta 409:

{
    "success": false,
    "status": 409,
    "message": "El pago ya fue registrado previamente para la pasarela palomma_inmobiliaria_xyz.",
    "body": [ /* snapshot del body original */ ],
    "error_code": "DUPLICATE_PAYMENT",
    "data": {
        "factura_id": 4521,
        "pago_id": 87123,
        "recibo_id": 56412,
        "documento_contable_id": 102345,
        "confirm_pay_id": 9921,
        "confirm_pay_reference_code": "PALM-2026-04-25-998877",
        "gateway": "palomma",
        "client_name": "palomma_inmobiliaria_xyz"
    },
    "duplicate": {
        "payload": { /* payload original recibido en el primer intento */ }
    }
}

4.5. Seguridad y Posibles Errores

El sistema realiza validaciones de autenticación, autorización por pasarelapasarela, configuración y parámetros.consistencia del payload. Si alguna falla, devolverá un error con su respectivo código HTTP. La estructura del cuerpo de error siempre incluye success: false, status, message yy, cuando aplica, body: []error_code.

Mensaje:
Código HTTP Descripción
400 Token faltante o inválido. Posibles causas:
— No se envió el encabezado Authorization.
— El encabezado no tiene el formato Bearer {token}.
— El token no fue encontrado en el sistema.

Parámetros inválidos. Posibles causas:
page no es un entero positivo.
page_size no es un entero positivo.
401 El token ha expirado. Debes generar uno nuevo consumiendo el servicio de Login.
403 El cliente OAuth autenticado no está registrado como pasarela activa en la inmobiliaria.
409Pago duplicado. El pago ya fue registrado previamente. error_code = "DUPLICATE_PAYMENT". La pasarela debe tratar la respuesta como confirmación idempotente y no reintentar. Ver sección de Idempotencia.
422Error de validación. error_code = "VALIDATION_ERROR". Posibles causas:
— No se envió ni factura_id ni movimiento_id.
factura_id no es un entero positivo o no existe.
— Algún movimiento_id no es un entero positivo o no existe.
— Sin factura_id se envió más de un movimiento_id.
monto no es numérico o es menor o igual a cero.
fecha_pago no cumple el formato YYYY-MM-DD HH:MM:SS.
n_comprobante supera los 100 caracteres o contiene caracteres no permitidos.
— La factura_id y los movimiento_id pertenecen a terceros distintos.
— La pasarela no tiene una forma de pago configurada (error_code = "GATEWAY_PAYMENT_METHOD_REQUIRED").
El cliente autenticado no estacorresponde autorizadoa parauna consumirpasarela esteregistrada endpoint.(error_code = "GATEWAY_NOT_FOUND") o la pasarela está inactiva (error_code = "GATEWAY_NOT_ACTIVE").
— Errores de negocio retornados por el motor de ingresos (por ejemplo, factura ya pagada).
500 Error interno al resolverregistrar lael cartera.pago. error_code = "INTERNAL_ERROR". El detalle se registra en el canal de log PASARELAS y al caller solo se le devuelve un mensaje genérico..

5.6. Ejemplos de integración

Aquí tienes ejemplos de código listos para que tus desarrolladores los adapten:

cURL
# ConsultarPago lade carterauna del tercero con documento 1020304050factura
curl -X GETPOST "https://{{instancia}}/service/v2/public/gateways/portfolio?documento=1020304050&pendientes=true&page=1&page_size=20"payments" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer TU_TOKEN_AQUI" \
-d '{
  "factura_id": 4521,
  "monto": 1750000.00,
  "fecha_pago": "2026-04-25 14:30:00",
  "n_comprobante": "PALM-2026-04-25-998877"
}'

# CarteraPago incluyendode una factura junto con sus intereses de mora y conceptos futuros (3 meses)adjuntos
curl -X GETPOST "https://{{instancia}}/service/v2/public/gateways/portfolio?documento=1020304050&incluir_intereses_mora=true&incluir_conceptos_futuros=true&rango_conceptos_futuros_meses=3"payments" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer TU_TOKEN_AQUI" \
-d '{
  "factura_id": 4521,
  "movimiento_id": [98410, 98411],
  "monto": 1820000.00,
  "fecha_pago": "2026-04-25 14:30:00",
  "n_comprobante": "PALM-2026-04-25-998879"
}'
PHP
<?php

$instance = 'tu_instancia';
// Reemplaza con tu instancia real
$token = 'TU_TOKEN_AQUI'; // Token obtenidode delun servicio Login (cliente OAuth registrado como pasarela)

$queryParams = http_build_query([
    'documento' => '1020304050',
    'pendientes' => 'true',
    'incluir_intereses_mora' => 'true',
    'page' => 1,
    'page_size' => 20,
]);pasarela

$url = "https://{$instance}/service/v2/public/gateways/portfolio?{payments";

$queryParams}"payload = [
    'factura_id'     => 4521,
    'monto'          => 1750000.00,
    'fecha_pago'     => '2026-04-25 14:30:00',
    'n_comprobante'  => 'PALM-2026-04-25-998877',
];

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    "Authorization: Bearer {$token}",
]);

$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

echo "Código HTTP: {$http_code}\n";
$data = json_decode($response, true);

if ($http_code === 200) {
    $data = json_decode($response, true);
    echo "TotalPago ítems:registrado. "Recibo: . ({$data['pagination'data']['total_records'] ?? 0) . "\n";
    foreach ($data['body'] as $item) {
        $tipo = $item['factura_id'] ? "Factura #{$item['factura_id']}" : "Concepto";
        echo "  [{$tipo}] {$item['tercero_nombre']} - Saldo: {$item['saldo']} - Vence: {$item['fecha_vencimiento'recibo_id']}\n";
} elseif ($http_code === 409) {
    echo "Pago ya existía previamente. confirm_pay_id: {$data['data']['confirm_pay_id']}\n";
    // No reintentar: el pago ya está registrado en nuby.
} else {
    echo "Error consultandoregistrando lael cartera:pago:\n{$response}\n";
}

?>
Python
import requests

# 1. Configura tus datos de acceso
instancia = 'mi-inmobiliaria.nuby.app'
token = 'TU_TOKEN_AQUI'  # Token de un cliente OAuth registrado como pasarela

# 2. Prepara lael direcciónbody ydel los parámetrospago
url = f"https://{instancia}/service/v2/public/gateways/portfolio"payments"

paramspayload = {
    "documento"factura_id": 4521,
    "monto": 1750000.00,
    "fecha_pago": "1020304050"2026-04-25 14:30:00",
    "pendientes"n_comprobante": "true"PALM-2026-04-25-998877",
    "incluir_intereses_mora": "true",
    "page": 1,
    "page_size": 20,
}

headers = {
    "Content-Type": "application/json",
    "Authorization": f"Bearer {token}",
}

# 3. Envía la petición GETPOST y procesa la respuesta
try:
    response = requests.get(post(url, params=params,json=payload, headers=headers)
    print(f"Código HTTP: {response.status_code}")
    data = response.json()

    if response.status_code == 200:
        data = response.json()
        print(f"TotalPago ítems:registrado. Recibo: {data['pagination'data']['total_records'recibo_id']}")
    forelif item in data['body']:
            tiporesponse.status_code == f"Factura #{item['factura_id']}" if item['factura_id'] else "Concepto"409:
        print(f"Pago [{tipo}]ya existía previamente. confirm_pay_id: {item[data['tercero_nombre'data']} - Saldo: {item[['saldo']} - Vence: {item['fecha_vencimiento'confirm_pay_id']}")
        # No reintentar: el pago ya está registrado en nuby.
    else:
        print("Error consultandoregistrando lael cartera.pago.")
        print(response.text)
except Exception as e:
    print(f"Error de conexión: {e}")
JavaScript
// 1. Configura tus datos de acceso
const instancia = 'mi-inmobiliaria.nuby.app';
const token = 'TU_TOKEN_AQUI'; // Token de un cliente OAuth registrado como pasarela

// 2. Prepara lael direcciónbody condel parámetros
const params = new URLSearchParams({
    documento: '1020304050',
    pendientes: 'true',
    incluir_intereses_mora: 'true',
    page: 1,
    page_size: 20,
});pago
const url = `https://${instancia}/service/v2/public/gateways/portfolio?$payments`;

const payload = {params}`
    factura_id: 4521,
    monto: 1750000.00,
    fecha_pago: '2026-04-25 14:30:00',
    n_comprobante: 'PALM-2026-04-25-998877',
};

// 3. Función para consultarregistrar lael carterapago
async function consultarCartera(registrarPago() {
    try {
        const response = await fetch(url, {
            method: 'GET'POST',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': `Bearer ${token}`,
            },
            body: JSON.stringify(payload),
        });

        console.log(`Código HTTP: ${response.status}`);
        if (response.ok) {
            const data = await response.json();

        if (response.status === 200) {
            console.log(`TotalPago ítems:registrado. Recibo: ${data.pagination.total_records}data.recibo_id}`);
            data.body.forEach(item => {
                const tipo = item.factura_id ? `Factura #${item.factura_id}` : 'Concepto';
                console.log(`  [${tipo}] ${item.tercero_nombre} - Saldo: ${item.saldo} - Vence: ${item.fecha_vencimiento}`);
            });
        } else if (response.status === 409) {
            constconsole.log(`Pago errorDataya =existía awaitpreviamente. response.text(confirm_pay_id: ${data.data.confirm_pay_id}`);
            // No reintentar: el pago ya está registrado en nuby.
        } else {
            console.log('Error consultandoregistrando lael cartera.pago.');
            console.log(errorData)data);
        }
    } catch (error) {
        console.error(`Error de conexión: ${error}`);
    }
}

consultarCartera(registrarPago();