Ir al contenido principal

Obtener Cartera

Permite a una pasarela de pagos autenticada (por ejemplo, Palomma) consultar la registrarcartera el pagopagable de uno o varios ítems pagables en la inmobiliaria: una factura, un movimientotercero: (conceptofacturas /pendientes, interés)conceptos ofacturables, unaconceptos facturano juntofacturables con suse intereses adjuntos.de mora adjuntos a facturas de canon. El endpoint es idempotente, devuelve un cuerpo en formato de arreglo ysistema aplica automáticamente la configuración de filtros avanzados registrada para la pasarela (forma de pago, envío DIAN).autenticada.

¿Para qué sirve este servicio?
Está pensado exclusivamente para integraciones con pasarelas de pago. La pasarela lo invocaconsume cuandopara elmostrarle al deudor confirmalos elítems pagoque puede pagar en línea de(facturas, losconceptos ítemse devueltosintereses), previamente por GET /gateways/portfolio. El sistema persiste el pago, genera el recibo de caja y, cuandorespetando la configuración locomercial requiera, dispara el envío del documento electrónico ade la DIAN.inmobiliaria (qué incluir, qué excluir, qué resoluciones se admiten, etc.).

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.

POSTGET https://{{instancia}}/service/v2/public/gateways/paymentsportfolio

¿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?)

DebesEste enviarservicio unarequiere peticiónautenticación POSTmediante conun elToken detalleJWT delobtenido pagopor en el cuerpo de la solicitud en formato JSON.OAuth2. La pasarela se identifica automáticamente a partir del client_name del token; no debes enviar el nombre de la pasarela ni la forma de pagoenviarlo en el body ni como query string: ambos se derivan de la configuración registrada..

Método POSTGET
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.

CuerpoParámetros de la peticiónconsulta (Body)query string):

caracteres.
CampoParámetro Tipo RequeridoPor defecto Descripción
factura_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_comprobantedocumento string No Número de comprobantedocumento del tercero (deudor) cuya cartera se desea consultar. Si se omite, se devolverá la cartera 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: 1000.
pendientesbooleanNotrueSi es true, se devuelven únicamente ítems con estado = "pendiente" y saldo > 0.
incluir_borradorbooleanNofalseSi es true, incluye facturas en estado Borrador 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 a la pasarela.fecha Máximoactual (cobros anticipados).
100rango_conceptos_futuros_meses integer | 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 letras,se números,devuelven guiones,facturas guionesemitidas bajos,con puntosesas resoluciones.
agrupar_conceptos_periodobooleanNofalseSi es true, consolida los conceptos del mismo contrato, tercero y espacios.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. RecomendadoRequiere: garantizaque laal idempotenciamenos anteuno reintentos.de incluir_conceptos_no_factura o incluir_conceptos_futuros esté activo; en caso contrario el filtro se ignora.

ModosFiltros avanzados de operaciónla 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 propietario
El endpoint clasificaexcluye elautomáticamente pagolas facturas cuyos detalles estén asociados a movimientos de tipo FACTURA_PROPIETARIO (por ejemplo, comisiones del contrato facturadas al propietario). Estas facturas siguen una lógica contable distinta —generan EGRESO_PROPIETARIO en unolugar de cuatro modos según los campos enviadosINGRESO_INQUILINO y lano configuraciónson depagables lavía pasarela:
pasarela Modoen movimientoesta único:versión. factura_id = null y movimiento_id = [n].
Modo GROUP: factura_id = null y movimiento_id = [m1, m2, ...] con varios movimientos del mismo tercero. SoloNo 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 la factura X se ignoran (ya están cubiertos); los demás se procesan como intereses sueltosincluyen en la mismarespuesta transacción.ni en el conteo total.

Ejemplo 1: PagoEjemplos de una sola facturapeticiones:

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

Ejemplo

GET 2: Pago de un movimiento (concepto suelto)

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

Ejemplo

GET 3: Pago de una factura junto con sus intereses adjuntos

https://{{instancia}}/service/v2/public/gateways/portfolio?documento=1020304050&incluir_intereses_mora=true&incluir_conceptos_futuros=true&rango_conceptos_futuros_meses=3
GET https://{
    "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"
{instancia}}/service/v2/public/gateways/portfolio?documento=1020304050&resolucion_ids=3,7

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

El sistema respondedevolverá una respuesta JSON con HTTPlos 200ítems cuandopagables eldel pagotercero, los filtros realmente aplicados y la información de paginación. Cada ítem se registraentrega correctamente.con La clave body esla siempremisma unestructura arreglocanónica, inclusosin cuandoimportar elsi pago resulta en un solo registro. Cada elemento del arreglo describe un documento generado por la operación: la factura pagada,representa una factura nuevade creadacontrato, poruna factura de venta, un concepto facturable, un concepto no facturable o una factura con intereses facturables, o un anticipo si hubo excedente.adjuntos.

{
    "success": true,
    "status": 200,
    "message": "ElLa pagocartera de la pasarela fue registradoconsultada exitosamente.correctamente.",
    "body": [
        {
            "factura_id": 4521,
            "movimiento_id"factura_numero": null,"291",
            "pago_id"contrato_id": 87123,187,
            "recibo_id"contrato_numero": 56412,"C-000187",
            "documento_contable_id"tercero_id": 102345,272,
            "monto_pagado"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": 1750000.00,
            "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"saldo": 1750000.00,
            "saldo_actual": 0.00,
            "estado": "pagada",
            "mensaje": "El pago cubrió el total de la factura.",
            "estado_dian": "pendiente",
            "documento_contable_pdf"factura_pdf": "https://demo.nuby.app/contabilidad_documento.php?hash=x1y2z3a4b5"a1b2c3d4e5",
            "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"items": [
                {
                    "tipo"movimiento_id": 98231,
                    "descripcion": "recibo"Canon de arrendamiento - Canon abril 2026",
                    "id"valor_unitario": 56412,1600000.00,
                    "numero"cantidad": 1,
                    "REC-56412"valor_iva": 0.00,
                    "valor_retencion": 0.00,
                    "valor_reteiva": 0.00,
                    "valor_reteica": 0.00,
                    "valor_descuento": 0.00
                },
                {
                    "tipo"movimiento_id": 98232,
                    "descripcion": "factura"Administración - Cuota administración abril 2026",
                    "id"valor_unitario": 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": null,
            "pago_id": 87124,
            "recibo_id": 56413,
            "documento_contable_id": 102346,
            "monto_pagado": 1750000.150000.00,
                    "fecha_pago"cantidad": "2026-04-25 14:30:00",1,
                    "forma_pago_id": 7,
            "forma_pago": "Pasarela Palomma",
            "n_comprobante": "PALM-2026-04-25-998880",
            "saldo_anterior": 1750000.00,
            "saldo_actual"valor_iva": 0.00,
                    "estado"valor_retencion": 0.00,
                    "valor_reteiva": 0.00,
                    "valor_reteica": 0.00,
                    "valor_descuento": 0.00
                },
                {
                    "movimiento_id": 98410,
                    "descripcion": "pagada"Intereses de mora - Mora canon marzo 2026",
                    "mensaje"valor_unitario": "El pago cubrió el total de la factura.",35000.00,
                    "estado_dian"cantidad": "pendiente",1,
                    "documento_contable_pdf"valor_iva": "https://demo.nuby.app/contabilidad_documento.php?hash=x1y2z3a4b6",0.00,
                    "gateway"valor_retencion": "palomma",0.00,
                    "client_name"valor_reteiva": 0.00,
                    "palomma_inmobiliaria_xyz"valor_reteica": 0.00,
                    "valor_descuento": 0.00
                }
            ]
        },
        {
            "factura_id": null,
            "movimiento_id"factura_numero": null,
            "pago_id"contrato_id": null,187,
            "recibo_id"contrato_numero": null,"C-000187",
            "documento_contable_id"tercero_id": 102347,272,
            "monto_pagado"tercero_documento": 50000.00,"1020304050",
            "fecha_pago"tercero_nombre": "ANA MARÍA PÉREZ RODRÍGUEZ",
            "tercero_correo": "ana.perez@email.com",
            "tercero_telefono": "3001234567",
            "fecha_vencimiento": "2026-04-25 14:30:00"05-15",
            "forma_pago_id": 7,
            "forma_pago"observaciones": "PasarelaCosto Palomma"del Contrato C-000187",
            "n_comprobante"valor_total": "PALM-2026-04-25-998880",280000.00,
            "saldo_anterior"saldo": null,
            "saldo_actual": null,280000.00,
            "estado": "anticipo"pendiente",
            "mensaje"items": [
                {
                    "movimiento_id": 98515,
                    "descripcion": "SeReparación generólocativa un- anticipoReparación porlocativa valorbaño de 50000.00 con el excedente del pago."principal",
                    "estado_dian"valor_unitario": null,280000.00,
                    "gateway"cantidad": "palomma",1,
                    "client_name"valor_iva": 0.00,
                    "palomma_inmobiliaria_xyz"valor_retencion": 0.00,
                    "valor_reteiva": 0.00,
                    "valor_reteica": 0.00,
                    "valor_descuento": 0.00
                }
            ]
        }
    ],
    "alertas": [],
    "data"filters_applied": {
        "factura_id"documento": 4521,
        "pago_id": 87124,
        "recibo_id": 56413,
        "documento_contable_id": 102346,
        "anticipo_documento_contable_ids": [102347]1020304050",
        "confirm_pay_id"pendientes": 9922,true,
        "gateway"incluir_borrador": false,
        "palomma"incluir_conceptos_no_factura": true,
        "incluir_conceptos_futuros": false,
        "incluir_intereses_mora": true,
        "agrupar_conceptos_periodo": false
    },
    "client_name"pagination": {
        "palomma_inmobiliaria_xyz"total_records": 2,
        "total_pages": 1,
        "current_page": 1,
        "page_size": 10,
        "current_page_records": 2,
        "has_next_page": false,
        "has_previous_page": false
    }
}
Campos de la respuesta
Clave Descripción
success Indica si la operación fue exitosa (true) o no (false).
status Código HTTP devuelto.devuelto (debe coincidir con el código real de la respuesta).
message Mensaje descriptivo del resultado.resultado de la operación.
body Arreglo conde unoítems o más registros generados por la operaciónpagables (ver tabla detallada abajo). Puede ser vacío si no hay cartera.
alertasfilters_applied ArregloObjeto con los filtros realmente aplicados (combinación de alertaslos nofiltros bloqueantesdel generadascaller durante+ ella procesoconfiguración (porde ejemplo,la fallas en el envío DIAN)pasarela).
datapagination Objeto con la información consolidadade del pagopaginación (IDsver principales,tabla identificadordetallada de confirmación, gateway, cliente)abajo). Adicionalmente puede incluir documentos_generados: un arreglo de objetos {tipo, id, numero} que lista todos los documentos creados u afectados por el pago (recibo de caja 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 elementoítem de (body[])
correspondeaunconcepto
Clave Descripción
factura_id Identificador interno de la factura pagada(PK oen generada.base de datos). null paracuando registrosel deítem anticipo.
movimiento_id Identificadorsin factura emitida (concepto facturable o arreglono defacturable). IDs)No dees losel movimientosnúmero asociadosvisible al registro.usuario; Puede server nullfactura_numero.
pago_idfactura_numeroNúmero consecutivo visible de la factura (mismo valor que se muestra como "Factura N°" en la interfaz de nuby). null cuando el ítem es un concepto sin factura emitida.
contrato_id Identificador del pagocontrato creado en el sistema.asociado. null para anticipos.facturas de venta sin contrato.
recibo_idcontrato_numeroNúmero/código visible del contrato. null si no aplica.
tercero_id Identificador del recibotercero de(deudor) cajaal generado.que pertenece el ítem.
documento_contable_idtercero_documento IdentificadorNúmero de documento de identificación del documento contable asociado (recibo, anticipo, etc.).tercero.
monto_pagadotercero_nombre ValorNombre efectivamentecompleto aplicado(o arazón lasocial) factura/movimiento.del null para anticipos sin asignación específica.tercero.
fecha_pagotercero_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_vencimiento Fecha yde horavencimiento del pago.ítem. Formato: YYYY-MM-DD HH:MM:SS.
forma_pago_idobservaciones IdentificadorMensaje internogenérico que identifica 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).
  • "Factura de laVenta" forma— cuando el ítem es una factura de pagoventa contablesin (derivadacontrato asociado.
  • "Costo del Contrato {numero}" — cuando el ítem corresponde a un concepto/movimiento de laun configuracióncontrato sin factura emitida.
El detalle por concepto/producto se expone en el campo descripcion de lacada pasarela)renglón de items[].
forma_pagovalor_total NombreValor legibletotal original del ítem (suma de lalos formarenglones de pago.internos).
n_comprobanteNúmero de comprobante enviado por la pasarela.
saldo_anteriorsaldo Saldo pendiente por pagar a la fecha de la factura/movimiento antes de aplicar el pago.
saldo_actualSaldo restante después de aplicar el pago.consulta.
estado Estado del 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 resultadológico del 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.ítem. Valores posibles: "pendiente" (envío en cola o fallido) o, null"pagada", (no aplica)"anulada". ElLas detallefacturas con estados internos fuera de alcance se omiten del fallo se reporta en alertas.resultado.
documento_contable_pdffactura_pdf Enlace público firmado para la descarga segura del recibo de cajala generadofactura en formato PDF. Es válido de forma temporal y no se expone como nulldevuelve cuando lael filaítem corresponde arepresenta un anticipoconcepto/movimiento osin cuandofactura ocurre un fallo interno en la generación.emitida.
gatewayitems SlugArreglo de larenglones pasarela autenticada (por ejemplo, "palomma").
client_nameNombreinternos del clienteítem OAuth2(ver autenticado.tabla detallada abajo). Para facturas, contiene los movimientos que la componen y, si aplica, los intereses de mora adjuntos.
EscenariosMapeo especialesde 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 excluye del cuerporesultado.
Estructura de cada renglón interno (body[].items[])
quedapersistido(estado=alertascontieneunaentrada"factura_id":...}.
EscenarioClave Comportamiento del bodyDescripción
Pago simplemovimiento_id UnIdentificador únicodel elementomovimiento quede describecontrato elasociado reciboal generado.renglón. Puede ser null o 0 para renglones de facturas de venta sin movimiento.
Intereses facturablesdescripcion AlTexto menosdescriptivo dosdel elementos:renglón unocon porel formato "{producto} - {descripcion}", donde {producto} es el nombre del producto/concepto y {descripcion} es la facturadescripción originalpuntual pagadade yese unoítem por(mes lafacturado, facturaobservación nuevaespecífica, creadaetc.). paraSi alguno de los interesescomponentes facturables.no existe se incluye vacío respetando el separador.
Excedente / anticipovalor_unitario CuandoValor el 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 valorunitario del anticipo, 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 enviadorenglón (facturabase, y/osin movimientos)IVA yni solo el sobrante real se transforma en anticipo; nunca se desvía a anticipo el monto destinado a un movimiento explícitamente declarado.retenciones).
Falla en envío DIANcantidad ElCantidad pagofacturada.
valor_iva Valor "pagada"),del estado_dianIVA =aplicado "pendiente",al yrenglón.
valor_retencion Valor {de "level":la "warning",retención "code":en "DIAN_SEND_FAILED",la "message":fuente "...",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.

4. Idempotencia

El endpoint detecta automáticamente reintentosInformación de unpaginación mismo pago y responde (409 Conflictpagination sin volver a registrarlo. Las reglas de idempotencia son:

) previo.
DisparadorClave ComportamientoDescripción
Mismo n_comprobantetotal_records CuandoCantidad eltotal n_comprobantede yaítems fuepagables registradoque para la misma pasarela, se devuelve 409 con el registro previo.
Sin n_comprobante, mismos datos esencialesSicumplen los datosfiltros (factura_id,sin movimiento_ids ordenados, monto, fecha_pago, client_name) coinciden con un pago previo, se devuelve 409paginar).
n_comprobante distinto, mismos datos esencialestotal_pages SeCantidad aplica un hashtotal de respaldopáginas sobrecalculadas loscon datos esenciales y se devuelveel 409page_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_pagetrue si coincideexiste conuna unpágina pagosiguiente.
has_previous_pagetrue si existe una página anterior.

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 */ }
    }
}

5.4. Seguridad y Posibles Errores

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

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.Mensaje: 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 correspondeesta aautorizado unapara pasarelaconsumir registradaeste (error_code = endpoint."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 registrarresolver ella pago. error_code = "INTERNAL_ERROR".cartera. El detalle se registra en el canal de log PASARELAS. y al caller solo se le devuelve un mensaje genérico.

6.5. Ejemplos de integración

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

cURL
# PagoConsultar dela unacartera facturadel tercero con documento 1020304050
curl -X POSTGET "https://{{instancia}}/service/v2/public/gateways/payments"portfolio?documento=1020304050&pendientes=true&page=1&page_size=20" \
-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"
}'

# PagoCartera incluyendo intereses de unamora facturay juntoconceptos confuturos sus(3 intereses adjuntosmeses)
curl -X POSTGET "https://{{instancia}}/service/v2/public/gateways/payments"portfolio?documento=1020304050&incluir_intereses_mora=true&incluir_conceptos_futuros=true&rango_conceptos_futuros_meses=3" \
-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 deobtenido undel servicio Login (cliente OAuth registrado como pasarelapasarela)

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

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

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

$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 "PagoTotal registrado.ítems: Recibo:" . ($data['pagination']['total_records'] ?? 0) . "\n";
    foreach ($data['body'] as $item) {
        $tipo = $item['factura_id'] ? "Factura #{$item['factura_id']}" : "Concepto";
        echo "  [{$tipo}] {$data[item['data'tercero_nombre'][} - Saldo: {$item['recibo_id'saldo']} - Vence: {$item['fecha_vencimiento']}\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 registrandoconsultando ella pago:cartera:\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 ella bodydirección dely pagolos parámetros
url = f"https://{instancia}/service/v2/public/gateways/payments"portfolio"

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

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

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

    data = response.json()

    if response.status_code == 200:
        data = response.json()
        print(f"PagoTotal registrado. Recibo:ítems: {data['data'pagination']['recibo_id'total_records']}")
        eliffor response.status_codeitem in data['body']:
            tipo == 409:f"Factura #{item['factura_id']}" if item['factura_id'] else "Concepto"
            print(f"Pago  ya existía previamente. confirm_pay_id:[{tipo}] {data[item['data'tercero_nombre'][} - Saldo: {item['confirm_pay_id'saldo']} - Vence: {item['fecha_vencimiento']}")
        # No reintentar: el pago ya está registrado en nuby.
    else:
        print("Error registrandoconsultando ella pago.cartera.")
        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 ella bodydirección delcon pagoparámetros
const params = new URLSearchParams({
    documento: '1020304050',
    pendientes: 'true',
    incluir_intereses_mora: 'true',
    page: 1,
    page_size: 20,
});

const url = `https://${instancia}/service/v2/public/gateways/payments`;

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

// 3. Función para registrarconsultar ella pagocartera
async function registrarPago(consultarCartera() {
    try {
        const response = await fetch(url, {
            method: 'POST'GET',
            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();
            ifconsole.log(`Total (response.statusítems: ${data.pagination.total_records}`);
            data.body.forEach(item ==> {
                const tipo = 200)item.factura_id ? `Factura #${item.factura_id}` : 'Concepto';
                console.log(`Pago  registrado. Recibo:[${tipo}] ${data.data.recibo_id}item.tercero_nombre} - Saldo: ${item.saldo} - Vence: ${item.fecha_vencimiento}`);
            });
        } else if{
            (response.statusconst errorData === 409)await {
            console.log(`Pago ya existía previamente. confirm_pay_id: ${data.data.confirm_pay_id}`response.text();
            // No reintentar: el pago ya está registrado en nuby.
        } else {
            console.log('Error registrandoconsultando ella pago.cartera.');
            console.log(data)errorData);
        }
    } catch (error) {
        console.error(`Error de conexión: ${error}`);
    }
}

registrarPago(consultarCartera();