Convenciones
Los cinco endpoints comparten la misma envoltura de respuesta y el mismo modo de identificar al cliente: el subdominio determina la base de datos.
URL base
Las rutas cuelgan de la raíz del host, sin prefijo /api.
https://{empresa}.gosoft.app/api-multipagos-...
Envoltura de respuesta
Toda respuesta —éxito o error— devuelve HTTP 200 con este
cuerpo. El estado real de la operación viaja en el campo code, no en el
código HTTP.
{
"msj": "Success", // texto legible: "Success" o "Error: ..."
"data": { }, // carga util; en error suele ser {"NULO": null}
"code": 200 // 200 | 404 | 409 | 500 <-- este es el estado a evaluar
}
No uses el status HTTP para decidir si el pago se registró. Evalúa siempre
body.code === 200. Un fallo de validación llega igualmente como HTTP 200
con code: 404.
Autenticación
Los cinco endpoints están publicados sin filtro de sesión ni token: no
requieren cabecera Authorization. El control de acceso depende hoy de la red y
del host, por lo que conviene restringir por IP de origen del lado de Multi Pagos.
Cabeceras
| Cabecera | Valor | Nota |
|---|---|---|
| Content-Type | application/json | Obligatoria en los cuatro POST. Sin ella el cuerpo se lee vacío y la API responde 404. |
| Accept | application/json | Recomendada. |
Flujo de integración
El orden importa: el código de cuota que se envía al cobrar sólo se obtiene del paso 2, y sólo es válido mientras la cuota siga con saldo.
Identificar al cliente
Se busca por carnet, número de contrato o celular y se obtienen sus contratos vigentes.
Listar cuotas
Para el contrato elegido se piden las cuotas con saldo, ya con la mora calculada al día.
Confirmar el cobro
Se envían las cuotas cobradas y el número de transacción. GoSoft genera el comprobante.
Anular si corresponde
Con el mismo número de transacción se revierte el comprobante y todo lo derivado.
Forma de búsqueda
Handshake inicial. Confirma el código de comercio y devuelve el modo de búsqueda por defecto.
Parámetros (query string)
| Campo | Tipo | Descripción | |
|---|---|---|---|
| proyecto_id | string | req | Código de comercio o proyecto asignado a Multi Pagos. |
Ejemplo de llamada
curl "https://demo.gosoft.app/api-multipagos-forma-busqueda?proyecto_id=1042"
{
"msj": "Success",
"data": {
"searchType": "1",
"searchField": "",
"commerceInfo": {
"proyecto_id": "1042"
}
},
"code": 200
}
{
"msj": "Error: No código de proyecto",
"data": { "NULO": null },
"code": 404
}
searchType: "1" significa «buscar por documento de identidad».
El valor es fijo: la API no valida el proyecto_id contra la base, sólo
lo devuelve.
Buscar contratos
Devuelve los contratos de venta asociados a un cliente. Acepta tres criterios de búsqueda.
Cuerpo (JSON)
| Campo | Tipo | Descripción | |
|---|---|---|---|
| searchType | int | req | 1 documento de identidad · 2 número de contrato · 3 celular |
| searchField | string | req | Valor a buscar. Coincidencia exacta, sin comodines. |
| commerceInfo | object | opc | Se acepta y se ignora. Sirve para trazabilidad del lado de Multi Pagos. |
Ejemplo de llamada
curl -X POST "https://demo.gosoft.app/api-multipagos-buscar-contrato" \
-H "Content-Type: application/json" \
-d '{
"searchType": 1,
"searchField": "6842193",
"commerceInfo": { "proyecto_id": "1042" }
}'
{
"msj": "Success",
"data": {
"clientName": "MARIA FERNANDA GUTIERREZ ROJAS",
"Clientdocument": "6842193",
"contracts": [
{
"id": "4821",
"uen": "INMOBILIARIA NORTE",
"project": "Urbanizacion Los Tajibos",
"uen_id": "7",
"uv": "12",
"mzno": "34",
"number": "07",
"lote": "07",
"description": "Lote 07 - 360 m2",
"person_id": "9134",
"person": "Maria Fernanda Gutierrez Rojas",
"document": "6842193",
"movil": "71234567",
"email": "mf.gutierrez@gmail.com",
"status_det": "Vigente",
"codproyecto": "1042",
"codgrupo": "URB-TAJIBOS",
"penalty_value": "0.50",
"penalty_calculation": "1"
}
]
},
"code": 200
}
Campos de contracts[]
| Campo | Descripción |
|---|---|
| id | Número de contrato. Es el contractCode / contractNumber de los endpoints siguientes. |
| uen | Unidad de negocio propietaria del proyecto. |
| project | Nombre del proyecto o urbanización. |
| uv · mzno · number · lote | Ubicación del inmueble: unidad vecinal, manzano y lote. lote repite number. |
| person · document · movil · email | Datos del titular del contrato. |
| status_det | Estado legible: Vigente, Finalizado, Pendiente, Pagado, Reservado. |
| codproyecto · codgrupo | Identificadores del proyecto contenedor. |
| uen_id · penalty_value · penalty_calculation | Sólo se incluyen cuando searchType = 2. |
{
"msj": "Success",
"data": {
"clientName": null,
"Clientdocument": null,
"contracts": []
},
"code": 200
}
{
"msj": "Error: Tiene que enviar: searchType y searchField",
"data": { "NULO": null },
"code": 404
}
Un cliente sin contratos devuelve code: 200 con contracts: [],
no un error. Valida siempre que el arreglo tenga elementos antes de continuar.
Los contratos revertidos, retenidos, devueltos, anulados y eliminados nunca aparecen en la lista.
Ver cuotas
Lista las cuotas con saldo pendiente del plan de pagos vigente, con la mora ya calculada al día de hoy.
Cuerpo (JSON)
| Campo | Tipo | Descripción | |
|---|---|---|---|
| contractCode | int | string | req | Número de contrato obtenido en el endpoint 02 (contracts[].id). |
Ejemplo de llamada
curl -X POST "https://demo.gosoft.app/api-multipagos-ver-cuotas" \
-H "Content-Type: application/json" \
-d '{ "contractCode": 4821 }'
{
"msj": "Success",
"data": {
"fees": [
{
"code": "118742",
"date": "2026-06-05",
"name": "Periodo 14, Proyecto: Urbanizacion Los Tajibos, UV 12, Mzno 34, Nro 07",
"pagado_usd": "0.00",
"amount": "187.75",
"currency": "USD"
},
{
"code": "118743",
"date": "2026-07-05",
"name": "Periodo 15, Proyecto: Urbanizacion Los Tajibos, UV 12, Mzno 34, Nro 07",
"pagado_usd": "50.00",
"amount": "135.00",
"currency": "USD"
}
]
},
"code": 200
}
Campos de fees[]
| Campo | Descripción |
|---|---|
| code | Código de cuota. Es el feeCode que se envía al confirmar el pago. |
| date | Fecha de vencimiento de la cuota (YYYY-MM-DD). |
| name | Etiqueta lista para mostrar al cliente en pantalla o recibo. |
| pagado_usd | Lo ya abonado a esa cuota. Mayor a cero indica un pago parcial previo. |
| amount | Saldo a cobrar en USD, con mora incluida si corresponde. |
| currency | Siempre USD. |
{
"msj": "Success",
"data": { "fees": [] },
"code": 200
}
{
"msj": "Error: No existe contrato",
"data": { "NULO": null },
"code": 404
}
Sólo se devuelven cuotas con saldo mayor a 0.9 USD; los redondeos
residuales se consideran pagados. El amount se recalcula en cada llamada
porque la mora crece con los días: no lo caches.
Confirmar pago
Registra el cobro: genera el comprobante de ingreso, imputa las cuotas, calcula IVA y comisiones. Todo dentro de una transacción de base de datos.
Cuerpo (JSON)
| Campo | Tipo | Descripción | |
|---|---|---|---|
| payer | object | req | Datos de quien paga en ventanilla. Se guardan como glosa del comprobante. |
| payer.name | string | req | Nombre completo. |
| payer.idNumber | string | req | Carnet de identidad. |
| payer.phone | string | req | Celular de contacto. |
| contractNumber | int | string | req | Número de contrato. |
| paymentDetails | array | req | Cuotas cobradas. Al menos un elemento. |
| paymentDetails[].feeCode | int | req | fees[].code del endpoint 03. |
| paymentDetails[].feeAmount | decimal | req | Monto cobrado en USD. Puede ser menor al saldo (pago parcial). |
| transactionNumber | string | req | Identificador único de Multi Pagos. Es la llave para anular después. |
| tc | decimal | opc | Tipo de cambio USD→BOB. Si se omite se usa el del último pago registrado. |
Ejemplo de llamada
curl -X POST "https://demo.gosoft.app/api-multipagos-confirmar-pago" \
-H "Content-Type: application/json" \
-d '{
"payer": {
"name": "Maria Fernanda Gutierrez Rojas",
"idNumber": "6842193",
"phone": "71234567"
},
"contractNumber": 4821,
"paymentDetails": [
{ "feeCode": 118742, "feeAmount": 187.75 },
{ "feeCode": 118743, "feeAmount": 135.00 }
],
"transactionNumber": "MP-2026-0000184523",
"tc": 6.97
}'
{
"msj": "Success",
"data": {
"transactionNumber": 90412,
"persisted": true
},
"code": 200
}
No es el número que enviaste: es el número de comprobante interno
de GoSoft (voucher). Guárdalo para conciliación. Para anular, en
cambio, se usa el transactionNumber original de Multi Pagos.
persisted: true garantiza que el comprobante fue verificado en la base
antes de confirmar la transacción.
Pago duplicado
Antes de escribir nada, la API busca un comprobante con el mismo número de transacción, tipo de documento, fondo y fecha. Si lo encuentra rechaza el pago y devuelve el comprobante existente.
{
"msj": "Error: Ya existe un pago con ese nro_document/document_type/fondo/fecha",
"data": {
"duplicates": [
{
"voucher_id": 90412,
"contract_id": 4821,
"document_type": "Transaccion",
"nro_document": "MP-2026-0000184523",
"fullname": "Maria Fernanda Gutierrez Rojas - CI:6842193 - CEL:71234567",
"date": "2026-08-20",
"amount_bob": 2249.53,
"amount_usd": 322.75
}
]
},
"code": 409
}
El 409 es la señal de que el cobro ya está registrado:
trátalo como éxito idempotente y toma el voucher_id de
duplicates[0].
La detección incluye la fecha, así que un mismo
transactionNumber reenviado al día siguiente
generaría un segundo comprobante. No reintentes cruzando la medianoche.
Errores de configuración y fallos
{
"msj": "Error: No se encontraron contratos",
"data": { "NULO": null },
"code": 404
}
{
"msj": "Error: Parametros contables de realty no configurados (uen_id=7)",
"data": { "NULO": null },
"code": 500
}
{
"msj": "Error interno: Undefined property: stdClass::activo_id",
"data": {
"error_class": "ErrorException",
"error_msg": "Undefined property: stdClass::activo_id",
"error_file": "RealtyPaymentProcessor.php",
"error_line": 148,
"rollback": "ejecutado - 0 cambios"
},
"code": 500
}
Toda la escritura vive dentro de una transacción. Si algo falla
—validación, contabilidad o una excepción de PHP— se ejecuta
rollback y no queda ninguna fila insertada. El campo rollback lo
confirma. Un 500 siempre puede reintentarse con el mismo
transactionNumber.
Anular pago
Reversa el cobro: anula el comprobante, libera las cuotas imputadas y cancela en cascada las comisiones que ese pago hubiera generado.
Cuerpo (JSON)
| Campo | Tipo | Descripción | |
|---|---|---|---|
| multipagoTransaction | string | req | El transactionNumber enviado al confirmar el pago. Coincidencia exacta. |
| reason | string | opc | Motivo de la anulación. Queda registrado en el comprobante. |
| user | string | int | opc | Usuario que anula. Si es un username o id existente, se usa para trazar la cascada de comisiones. |
Ejemplo de llamada
curl -X POST "https://demo.gosoft.app/api-multipagos-anular-pago" \
-H "Content-Type: application/json" \
-d '{
"multipagoTransaction": "MP-2026-0000184523",
"reason": "Reverso solicitado por el cliente en ventanilla",
"user": "multipagos"
}'
{
"msj": "Success",
"data": {
"Control": "Comprobantes de ingresos anulados: 90412 - (1)",
"Status": true
},
"code": 200
}
{
"msj": "Success",
"data": {
"Control": "No se encontrato Comprobantes con ese numero de multipagoTransaction",
"Status": true
},
"code": 200
}
Status es true siempre que Control traiga texto,
incluso cuando no encontró comprobantes. La verificación fiable es leer
Control: si empieza con «Comprobantes de ingresos anulados», la
reversión ocurrió.
Anular dos veces la misma transacción es seguro: la segunda llamada no encuentra comprobantes activos y no hace nada.
El comprobante de ingreso y sus detalles pasan a anulado · se eliminan las imputaciones a las cuotas, con lo que el saldo vuelve a quedar pendiente · se anulan las comisiones generadas y sus cuentas por pagar · si alguna comisión ya se había pagado al promotor, se anula también ese egreso.
Tabla de errores
Todos llegan como HTTP 200; el valor de la columna code es el del cuerpo de la respuesta.
| code | msj | Causa y qué hacer |
|---|---|---|
| 404 | Error: No código de proyecto | Falta proyecto_id en la query string. |
| 404 | Error: Tiene que enviar: searchType y searchField | Cuerpo incompleto o sin cabecera Content-Type: application/json. |
| 404 | Error: Tiene que enviar: contractCode | Falta el número de contrato. |
| 404 | Error: No existe contrato | El contrato no existe, o está anulado, revertido, retenido, devuelto o eliminado. |
| 404 | Error: Tiene que enviar: payer, contractNumber, paymentDetails, transactionNumber | Falta alguno de los cuatro campos obligatorios del cobro. |
| 404 | Error: No se encontraron contratos | El contractNumber no corresponde a un contrato cobrable. |
| 409 | Error: Ya existe un pago con ese nro_document... | Cobro ya registrado hoy. Idempotente: usa el voucher_id devuelto. |
| 500 | Error: Usuario de sistema no configurado | Falta el usuario interno que firma los cobros por API. Reportar a GoSoft. |
| 500 | Error: Parámetros contables de realty no configurados | La UEN del contrato no tiene cuenta de activo definida. Reportar a GoSoft. |
| 500 | Error: company_id=... no existe en la DB | Configuración inconsistente de la empresa. Reportar a GoSoft. |
| 500 | Error interno: ... | Excepción no prevista. Se hizo rollback: se puede reintentar tal cual. |
Reglas de negocio
Comportamientos del lado de GoSoft que conviene conocer para integrar sin sorpresas.
Tipo de cambio
Las cuotas están en USD y la contabilidad en BOB. El tipo de cambio se resuelve en este orden:
paymentDetails[0].tc, si viene dentro del detalle;tcdel cuerpo principal;- el tipo de cambio del último pago registrado en el sistema;
6.97como último recurso.
Enviar tc explícitamente es lo recomendable: deja el cobro autocontenido y auditable.
Pagos parciales
Si feeAmount es menor al saldo de la cuota, GoSoft prorratea automáticamente
capital e IVA en la misma proporción y deja la cuota con saldo. La glosa del comprobante
pasa a decir «Parcial Periodo N» sin que Multi Pagos tenga que indicarlo.
Detalles descartados
Un elemento con feeCode menor o igual a cero, con feeAmount no
positivo, o cuyo código de cuota no exista, se ignora en silencio y el resto del pago
continúa. Verifica que el monto del comprobante coincida con lo cobrado en caja.
Valores fijos del comprobante
| Concepto | Valor |
|---|---|
| Tipo de documento | Transaccion |
| Número de documento | = transactionNumber |
| Origen del comprobante | source_comp = 3 |
| Fondo de ingreso | fondo_id = 292 |
| Cuenta de activo | según parámetros de la UEN |
| Fecha del comprobante | fecha del servidor (La Paz) |
| Descripción | Generado desde Multi Pagos |
Recomendaciones de integración
- Pide las cuotas (endpoint 03) inmediatamente antes de cobrar: la mora se recalcula cada día.
- Usa un
transactionNumberúnico e inmutable por cobro; es la única llave para anular. - Registra siempre el
voucher_iddevuelto: es el número que aparece en los reportes contables del cliente. - Ante un timeout sin respuesta, reintenta el mismo cobro el mismo día: el
409evita el duplicado. - Evalúa
body.code, nunca el status HTTP.