Pagos del API Bancario

API 1.0.0

Una herramienta del MCP envuelve esta operación: Herramientas bancarias.

El grupo Payments cubre el ciclo completo de un pago: crearlo, consultarlo por identificador, listarlo con filtros y buscarlo por cualquiera de sus referencias.

POST /api/public/v1/transactions/payments
GET  /api/public/v1/transactions/payments
GET  /api/public/v1/transactions/payments/{payment_id}
POST /api/public/v1/transactions/payments/search

Reglas del recurso#

Métodos. payment_method_code admite PIN y SINPE_MOVIL. Dirección. Al crear, direction solo admite OUT (salida); los pagos IN (entrada) siguen existiendo en listados y webhooks. Cuenta destino. se identifica por IBAN o por PHONE, según el método. Validala antes de transferir con la validación de cuentas.

Referencia propia. client_reference es tu identificador del pago y es único por tenant: dos pagos del mismo cliente no pueden compartirlo. Sirve para buscar el pago sin guardar el payment_id.

Reintentos seguros. La creación acepta Idempotency-Key; reenviar la misma llave con el mismo cuerpo devuelve el pago original en vez de crear otro. Ver reintentos seguros.

Estados#

Un pago recorre cinco estados: pending, processing, confirmed, posted y failed.

La reversión no es un estado: un pago revertido sigue en posted y se reconoce por result: reversed y has_reversal: true, además del evento payment.reversed. Consultá siempre esos dos campos antes de dar un pago por definitivo.

Operaciones#

Listar pagos del cliente

GET /api/public/v1/transactions/payments

Host: https://api-baas-sandbox.tilopay.com — requiere Authorization: Bearer <access_token>.

Lista REST simple de los pagos de una cuenta propia (IBAN).

Los filtros son parámetros de consulta. La titularidad (tenant_id, owner_type, owner_id) se deriva del token de acceso; no enviés filtros de titularidad.

Identificación de la cuenta (requerida): type + value (esquema de identificación + valor, ej. IBAN + el IBAN). No es la clasificación interna de la cuenta.

La paginación es por cursor (limit, cursor). Límite por defecto 20 (máximo 100).

status en la respuesta y como filtro usa el catálogo público en minúsculas (pending, processing, confirmed, posted, failed). Mismos valores que los webhooks. REST también devuelve status_detail (nombre operativo en mayúsculas).

Cada ítem incluye un result consolidado (succeeded, failed, reversed, pending) para conciliar cuando se perdió un webhook. status es solo el catálogo de procesamiento/ciclo de vida y no cambia a failed cuando un pago registrado se revierte después: usá result=reversed y has_reversal=true (webhook payment.reversed). error es null cuando no hay información de fallo; es un objeto solo cuando domain / platform está presente (result es failed o reversed), misma forma que payment.error del webhook payment.failed. source / destination usan null para account, name e identification desconocidos; los valores de cuenta son solo IBAN o PHONE (nunca UUID internos de cuenta). En pagos PIN, identification.number es el número público enviado por el comercio (sin guiones SINPE); los pagos antiguos aún pueden mostrar la forma SINPE con guiones.

Parámetros

ParámetroEnTipoObligatorioDescripción
X-Correlation-IdheaderstringnoId de correlación opcional que enviás para trazar la solicitud de punta a punta. Se devuelve como correlation_id en el sobre de respuesta. Si lo omitís, la API genera uno y igual lo devuelve.
typequerystringsíEsquema de identificación de la cuenta (ej. IBAN). No es la clasificación interna de la cuenta (ej. operativa).Valores: IBAN
valuequerystringsíValor del identificador de la cuenta (IBAN). Los espacios se ignoran.
statusquerystringnoFiltro opcional por estado del pago. El catálogo público es en minúsculas: pending, processing, confirmed, posted, failed. Se aceptan alias en mayúsculas de los mismos valores. Valores históricos como INITIATED equivalen a pending.Valores: pending, processing, confirmed, posted, failed
date_fromquerystring (date-time)noLímite inferior inclusivo para created_at. RFC 3339 (UTC Z u offset; fracciones de segundo opcionales).
date_toquerystring (date-time)noLímite superior inclusivo para created_at. RFC 3339 (UTC Z u offset; fracciones de segundo opcionales).
client_referencequerystringnoFiltro por la referencia de cliente del comercio (coincidencia exacta con el valor enviado al crear el pago).
currencyquerystringnoFiltro por moneda del pago (ISO 4217, ej. CRC).
payment_method_codequerystringnoFiltro por código público del método de pago.Valores: PIN, SINPE_MOVIL
directionquerystringnoFiltro por dirección del pago. Acepta los valores públicos OUT/IN o PAYOUT/PAYIN (se normalizan internamente a payout/payin).Valores: OUT, IN, PAYOUT, PAYIN
limitqueryintegernoTamaño de página (por defecto 20, máximo 100).
cursorquerystringnoCursor opaco de la pagination.next_cursor de una respuesta anterior.

Respuesta 200

La solicitud se procesó correctamente.

CampoTipoObligatorioDescripción
schema_versionstringsíMismo valor que el schema_version del sobre del webhook (1.0.0).
itemsarray<object>sí—
items[].schema_versionstringsíVersión del contrato de lectura de pagos. Mismo valor que el schema_version del sobre del webhook (1.0.0) para payment.succeeded / payment.failed.
items[].payment_idstring (uuid)síUUID del pago devuelto al crearlo. Llave del pago para el comercio en GET /transactions/payments/{payment_id} y en la búsqueda. No es un id interno de cuenta.
items[].public_idstringnoIdentificador público numérico del pago devuelto al crearlo. null si aún no se asigna. No es un UUID interno de cuenta. Es el mismo identificador: número en webhooks y texto en REST. Tratalo siempre como texto.Puede ser null.
items[].typestringsíTipo de pago derivado de la dirección (PAYIN / PAYOUT).
items[].payment_method_codestringsíCatálogo público de métodos de pago (PIN, SINPE_MOVIL). Mismos valores que en los webhooks.Valores: PIN, SINPE_MOVIL
items[].statusstringsíCatálogo público de estados del pago. Siempre en minúsculas. Mismos valores en REST (crear, listar, obtener) y en webhooks (payment.status). Los estados internos del ciclo de vida se consolidan: - pending: iniciado, validado, aceptado - processing: procesando, pendiente de procesamiento, registrando - confirmed: confirmado por el riel, aún no registrado en el ledger - posted: registrado en el ledger (se mantiene posted tras un reverso posterior) - failed: fallido, rechazado, posting_failed, cancelado, expirado Un reverso no es un estado. Usá result=reversed / has_reversal=true en REST y el webhook payment.reversed. El detalle operativo queda en status_detail (nombre interno en mayúsculas) en crear/listar/obtener de REST. El webhook payment.failed usa error.platform.code para distinguir fallos de registro de rechazos del proveedor.Valores: pending, processing, confirmed, posted, failed
items[].status_detailstringnoEstado operativo (interno) en mayúsculas, ej. VALIDATED, POSTED, POSTING_FAILED. Complemento del catálogo público status. Independiente de result (posted es el hito de débito/registro, no el éxito del proveedor).
items[].resultstringsíResultado de negocio consolidado para conciliación (respaldo de los webhooks). Independiente del status de procesamiento. Se deriva así: reversed cuando has_reversal es true (prioridad más alta); succeeded cuando succeeded_at está presente y no hay reverso; failed cuando el estado de procesamiento es failed o posting_failed; si no, pending. Un pago registrado (posted) que luego se revirtió tiene status=posted y result=reversed.Valores: succeeded, failed, reversed, pending
items[].succeeded_atstring (date-time)noMarca de tiempo de confirmación de éxito del proveedor (RFC 3339 UTC, precisión de segundos, Z). Null mientras el pago ya pueda estar posted internamente pero el proveedor no haya confirmado el éxito.Puede ser null.
items[].has_reversalbooleansíTrue cuando se aplicó un reverso. Independiente de status. Se correlaciona con el webhook payment.reversed.
items[].reversed_atstring (date-time)noCuándo se aplicó el reverso. Null cuando has_reversal es false.Puede ser null.
items[].created_atstring (date-time)noMarca de tiempo RFC 3339 en UTC con precisión de segundos y sufijo Z. Nunca se emiten fracciones de segundo. Ejemplo: 2026-01-15T12:00:00Z.
items[].updated_atstring (date-time)noMarca de tiempo RFC 3339 en UTC con precisión de segundos y sufijo Z. Nunca se emiten fracciones de segundo. Ejemplo: 2026-01-15T12:00:00Z.
items[].amountobjectnoMisma forma monetaria que la creación de pago (PaymentAmount).
items[].amount.amountstringsí—
items[].amount.currencystringsí—
items[].sourceobjectnoParte del pago en las lecturas del API. Los campos anidados siempre están presentes: null cuando el valor se desconoce. account es un identificador público (IBAN o PHONE); nunca se devuelven UUID internos de cuenta.
items[].source.accountobjectsíIdentificador público de la cuenta (type + value). null cuando el IBAN o el teléfono no pueden resolverse. Nunca un UUID interno de cuenta.Puede ser null.
items[].source.namestringsíNombre de la parte según los datos de procesamiento cuando está disponible; si no, null.Puede ser null.
items[].source.identificationobjectsíIdentificación de la parte (clave de catálogo type + number). Objeto solo cuando al menos un campo se conoce; si no, null. No expone los códigos internos de tipo de SINPE (0–9); los tipos sin equivalencia se omiten (type: null). number es el valor público enviado por el comercio (dígitos, sin guiones SINPE). Los pagos históricos aún pueden devolver la forma de visualización SINPE con guiones.Puede ser null.
items[].destinationobjectnoParte del pago en las lecturas del API. Los campos anidados siempre están presentes: null cuando el valor se desconoce. account es un identificador público (IBAN o PHONE); nunca se devuelven UUID internos de cuenta.
items[].destination.accountobjectsíIdentificador público de la cuenta (type + value). null cuando el IBAN o el teléfono no pueden resolverse. Nunca un UUID interno de cuenta.Puede ser null.
items[].destination.namestringsíNombre de la parte según los datos de procesamiento cuando está disponible; si no, null.Puede ser null.
items[].destination.identificationobjectsíIdentificación de la parte (clave de catálogo type + number). Objeto solo cuando al menos un campo se conoce; si no, null. No expone los códigos internos de tipo de SINPE (0–9); los tipos sin equivalencia se omiten (type: null). number es el valor público enviado por el comercio (dígitos, sin guiones SINPE). Los pagos históricos aún pueden devolver la forma de visualización SINPE con guiones.Puede ser null.
items[].client_referencestringnoReferencia del comercio enviada al crear el pago (estable después del procesamiento). Mismo campo que payment.client_reference del webhook.
items[].external_referencestringnoRail/SINPE transaction id. Same field, location, and meaning as webhook payment.external_reference on payment.succeeded / payment.failed Sibling of client_reference. null if none.Puede ser null.
items[].providerobjectnoFoto compartida del proveedor en las lecturas REST de pagos y en los sobres de webhook. La referencia del riel solo está en payment.external_reference, no se duplica aquí. Los provider_status_* coinciden con rejection.reason_code / message / code del webhook cuando el proveedor rechazó la operación. null cuando no hay rechazo.
items[].provider.correlation_idstringsíProvider transaction correlation identifier. Sent to SINPE as the correlation id. Not channel_reference (e.g. MOBILE_APP). Distinct from webhook event.correlation_id (HTTP request id for this delivery). null when unknown.Puede ser null.
items[].provider.occurred_atstring (date-time)síMarca de tiempo RFC 3339 en UTC con precisión de segundos y sufijo Z. Nunca se emiten fracciones de segundo. Ejemplo: 2026-01-15T12:00:00Z.
items[].provider.provider_status_codestringsíMotivo/código crudo del proveedor (ej. 31). Mismo significado que rejection.reason_code del webhook. null cuando no hay rechazo del proveedor.Puede ser null.
items[].provider.provider_status_descstringsíTexto Motivo del proveedor (prefiere Detalle). Mismo significado que rejection.message del webhook. null cuando no hay rechazo del proveedor.Puede ser null.
items[].provider.provider_status_semanticstringsíSemántica normalizada de la plataforma (ej. ACCOUNT_BLOCKED). Mismo significado que rejection.code del webhook. null cuando no hay rechazo del proveedor.Puede ser null.
items[].errorobjectnoSiempre presente. null cuando no hay información de fallo (succeeded, pending, o failed/reversed sin taxonomía). El objeto usa la misma forma domain / platform que el webhook payment.failed.Puede ser null.
items[].error.domainstringsíMismo catálogo que payment.error.domain del webhook.Valores: provider_rejection, platform_validation, platform_posting, platform_infra, platform_reversal
items[].error.platformobjectsí—
paginationobjectnoPaginación por cursor. Pasá next_cursor como cursor en la siguiente solicitud.
pagination.next_cursorstringnoCursor opaco de la página siguiente; se omite o va vacío cuando no hay más páginas
pagination.limitintegernoTamaño de página aplicado a esta respuesta

Ejemplo de respuesta

{
  "success": true,
  "http_status_code": 200,
  "response_code": "OK",
  "message": "The request was processed successfully.",
  "correlation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "data": {
    "schema_version": "1.0.0",
    "items": [
      {
        "schema_version": "1.0.0",
        "payment_id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
        "public_id": "10234",
        "type": "PAYOUT",
        "payment_method_code": "PIN",
        "status": "posted",
        "status_detail": "POSTED",
        "result": "succeeded",
        "succeeded_at": "2026-01-15T12:00:00Z",
        "has_reversal": false,
        "reversed_at": null,
        "created_at": "2026-01-15T12:00:00Z",
        "updated_at": "2026-01-15T12:00:00Z",
        "amount": {
          "amount": "1000.00",
          "currency": "CRC",
          "fees": "0.00",
          "taxes": "0.00"
        },
        "source": {
          "account": {
            "type": "IBAN",
            "value": "CR26036900101010588061",
            "currency": "CRC"
          },
          "name": "María González",
          "identification": {
            "type": "cedula",
            "number": "0205620043"
          }
        },
        "destination": {
          "account": {
            "type": "IBAN",
            "value": "CR16010400000000000031",
            "currency": "CRC"
          },
          "name": "Juan Perez",
          "identification": {
            "type": "cedula",
            "number": "0101010101"
          }
        },
        "client_reference": "INV-1001",
        "external_reference": "SINPE-20260115-000123",
        "provider": {
          "correlation_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
          "occurred_at": "2026-01-15T12:00:00Z",
          "provider_status_code": "00",
          "provider_status_desc": "Aprobada",
          "provider_status_semantic": "SUCCESS"
        },
        "error": null
      }
    ],
    "pagination": {
      "next_cursor": "",
      "limit": 20
    }
  }
}

Respuestas de error

HTTPresponse_codeDescripción
400INVALID_REQUESTInvalid request. Check the required fields and try again.
401UNAUTHORIZEDUnauthorized. Verify your session or credentials.
403FORBIDDENYou do not have permission to perform this action.
403ACCOUNT_ACCESS_DENIEDThe actor does not have access to the requested account.
500INTERNAL_ERRORAn unexpected error occurred. Please try again later.
502PROVIDER_ERRORUnable to complete the request with the payment provider. Please try again later.
503SERVICE_UNAVAILABLEA required service is temporarily unavailable. Please try again later.

Crear pago

POST /api/public/v1/transactions/payments

Host: https://api-baas-sandbox.tilopay.com — requiere Authorization: Bearer <access_token>. Acepta Idempotency-Key.

Crea un pago desde una cuenta origen interna autorizada. El procesamiento puede ser asíncrono; HTTP 201 no implica que el pago esté finalizado. source.identification.number y destination.identification.number se guardan en forma pública (los dígitos enviados, sin guiones SINPE) y se devuelven en las lecturas posteriores. La forma con guiones de SINPE solo se usa internamente y no es el contrato público. Idempotency-Key es opcional; si se omite, cada solicitud se trata como un intento nuevo. Un client_reference repetido devuelve 409 PAYMENT_DUPLICATE cuando un pago en curso o completado ya lo usa; un pago previo failed (o rechazado/cancelado/expirado) no bloquea reintentar con el mismo client_reference. Si se envía Idempotency-Key, la misma clave con el mismo cuerpo repite la respuesta anterior; un cuerpo distinto con la misma clave devuelve 409 IDEMPOTENCY_CONFLICT.

No hay doble control en la creación de pagos del API: el pago se procesa directamente si el token, los permisos y los datos son válidos. Solo se admite direction OUT. Aplican límites por transacción, diarios y mensuales, en monto y cantidad. Si se supera alguno, el procesamiento falla y el evento payment.failed notifica el resultado.

Parámetros

ParámetroEnTipoObligatorioDescripción
X-Correlation-IdheaderstringnoId de correlación opcional que enviás para trazar la solicitud de punta a punta. Se devuelve como correlation_id en el sobre de respuesta. Si lo omitís, la API genera uno y igual lo devuelve.
Idempotency-KeyheaderstringnoClave opaca opcional para reintentos seguros. Si la omitís, cada llamada es un intento nuevo (los duplicados se detectan por client_reference en pagos en curso o completados). Reutilizar la clave con un cuerpo distinto devuelve 409.

Cuerpo del request

CampoTipoObligatorioDescripción
payment_method_codestringsíCatálogo público de métodos de pago (PIN, SINPE_MOVIL).Valores: PIN, SINPE_MOVIL
directionstringsíLa creación solo acepta OUT (salida). Los pagos IN siguen disponibles en listados y webhooks.Valores: OUT
country_codestringnoPaís operativo cuando aplica multi-país
amountobjectsí—
amount.amountstringsíMonto como texto decimal con exactamente 2 decimales (ej. "1000.00").
amount.currencystringsíMoneda ISO 4217 del pago.Valores: CRC, USD
sourceobjectsí—
source.accountobjectsí—
source.account.typestringsíEsquema de identificación de la cuenta. Aquí solo se admite IBAN. No es la clasificación interna de la cuenta (ej. operativa).Valores: IBAN
source.account.valuestringsíIBAN (se permiten espacios; se normaliza en el servidor)
source.namestringsíNombre del titular
source.identificationobjectsíIdentificación del beneficiario al crear un pago. type usa las claves del catálogo de identificación de la plataforma (ej. cedula, juridica, dimex). Mismo vocabulario que holder.id_type de POST /accounts/validate. number es la identificación pública (dígitos, sin guiones SINPE). La plataforma puede reformatearlo internamente para SINPE; esa forma interna no se devuelve en las lecturas públicas de pagos. Para SINPE_MOVIL, la validación de cuenta puede devolver unknown porque la consulta del monedero no expone el tipo de identificación; no asumás un tipo confirmado.
source.identification.typestringnoClave del catálogo de identificación (minúsculas), ej. cedula, juridica. Puede copiarse de holder.id_type después de validar la cuenta. Para SINPE_MOVIL ese valor puede ser unknown (limitación esperada, no un error).Valores: cedula, juridica, dimex, gobierno, institucion_autonoma, didi, pasaporte
source.identification.numberstringnoNúmero de identificación público tal como lo envió el comercio. Solo dígitos; no enviés la forma con guiones de SINPE (ej. 01-1234-3005) ni tratés este campo como la forma interna de visualización SINPE. Los tipos admitidos incluyen cedula, juridica, dimex, gobierno, institucion_autonoma, didi y pasaporte.
destinationobjectsí—
destination.accountobjectsí—
destination.account.typestringsíEsquema de identificación de la cuenta del beneficiario (IBAN para PIN, PHONE para SINPE_MOVIL). No es la clasificación interna de la cuenta.Valores: IBAN, PHONE
destination.account.valuestringsíCuando type es PHONE (SINPE Móvil): 8 dígitos locales, sin prefijo de país (ej. "88887777"). Patrón para PHONE: ^\d{8}$.
destination.namestringsíNombre del beneficiario
destination.identificationobjectsíIdentificación del beneficiario al crear un pago. type usa las claves del catálogo de identificación de la plataforma (ej. cedula, juridica, dimex). Mismo vocabulario que holder.id_type de POST /accounts/validate. number es la identificación pública (dígitos, sin guiones SINPE). La plataforma puede reformatearlo internamente para SINPE; esa forma interna no se devuelve en las lecturas públicas de pagos. Para SINPE_MOVIL, la validación de cuenta puede devolver unknown porque la consulta del monedero no expone el tipo de identificación; no asumás un tipo confirmado.
destination.identification.typestringnoClave del catálogo de identificación (minúsculas), ej. cedula, juridica. Puede copiarse de holder.id_type después de validar la cuenta. Para SINPE_MOVIL ese valor puede ser unknown (limitación esperada, no un error).Valores: cedula, juridica, dimex, gobierno, institucion_autonoma, didi, pasaporte
destination.identification.numberstringnoNúmero de identificación público tal como lo envió el comercio. Solo dígitos; no enviés la forma con guiones de SINPE (ej. 01-1234-3005) ni tratés este campo como la forma interna de visualización SINPE. Los tipos admitidos incluyen cedula, juridica, dimex, gobierno, institucion_autonoma, didi y pasaporte.
detail_referencestringsíDescripción operativa / transaccional que se guarda en el pago
client_referencestringnoReferencia funcional del comercio. Única por comercio entre pagos en curso y completados; un intento fallido puede reintentarse con el mismo valor.
channel_referencestringno—
originatorobjectnoInformación opcional del ordenante (Ultimate Debtor / Travel Rule). Solo informativa en esta versión; no se aplica validación. Se guarda en los metadatos del pago cuando se envía.Puede ser null.
originator.companyobjectno—Puede ser null.
originator.company.legal_namestringno—
originator.company.id_typestringno—
originator.company.id_numberstringno—
originator.customerobjectno—Puede ser null.
originator.customer.namestringno—
originator.customer.id_typestringno—
originator.customer.id_numberstringno—

Ejemplo de request

{
  "payment_method_code": "PIN",
  "direction": "OUT",
  "country_code": "CR",
  "amount": {
    "amount": "1000.00",
    "currency": "CRC"
  },
  "source": {
    "account": {
      "type": "IBAN",
      "value": "CR26036900101010588061"
    },
    "name": "María González",
    "identification": {
      "type": "cedula",
      "number": "0205620043"
    }
  },
  "destination": {
    "account": {
      "type": "IBAN",
      "value": "CR16010400000000000031"
    },
    "name": "Juan Perez",
    "identification": {
      "type": "cedula",
      "number": "0101010101"
    }
  },
  "detail_reference": "Pago factura 1001",
  "client_reference": "INV-1001",
  "channel_reference": "MOBILE_APP"
}

Respuesta 201

El recurso se creó correctamente.

CampoTipoObligatorioDescripción
payment_idstring (uuid)noUUID interno del pago
public_idstringnoIdentificador público numérico del pago Es el mismo identificador: número en webhooks y texto en REST. Tratalo siempre como texto.
statusstringnoCatálogo público de estados del pago. Siempre en minúsculas. Mismos valores en REST (crear, listar, obtener) y en webhooks (payment.status). Los estados internos del ciclo de vida se consolidan: - pending: iniciado, validado, aceptado - processing: procesando, pendiente de procesamiento, registrando - confirmed: confirmado por el riel, aún no registrado en el ledger - posted: registrado en el ledger (se mantiene posted tras un reverso posterior) - failed: fallido, rechazado, posting_failed, cancelado, expirado Un reverso no es un estado. Usá result=reversed / has_reversal=true en REST y el webhook payment.reversed. El detalle operativo queda en status_detail (nombre interno en mayúsculas) en crear/listar/obtener de REST. El webhook payment.failed usa error.platform.code para distinguir fallos de registro de rechazos del proveedor.Valores: pending, processing, confirmed, posted, failed
status_detailstringnoDetalle operativo del estado (ej. PROCESSING)
payment_method_codestringnoCatálogo público de métodos de pago (PIN, SINPE_MOVIL).Valores: PIN, SINPE_MOVIL
created_atstring (date-time)noMarca de tiempo RFC 3339 en UTC con precisión de segundos y sufijo Z. Nunca se emiten fracciones de segundo. Ejemplo: 2026-01-15T12:00:00Z.

Ejemplo de respuesta

{
  "success": true,
  "http_status_code": 201,
  "response_code": "CREATED",
  "message": "The resource was created successfully.",
  "correlation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "data": {
    "payment_id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
    "public_id": "10234",
    "status": "pending",
    "status_detail": "PROCESSING",
    "payment_method_code": "PIN",
    "created_at": "2026-01-15T12:00:00Z"
  }
}

Respuestas de error

HTTPresponse_codeDescripción
400PAYMENT_INVALID_PAYLOADInvalid payment request payload.
400INVALID_PAYMENT_METHODInvalid or unsupported payment method.
400INVALID_ACCOUNT_TYPEUnsupported or invalid account type.
400ACCOUNT_INVALIDThe account is invalid or not enabled for the service.
400ACCOUNT_HOLDER_MISMATCHAccount holder does not match the provided identification or name.
401UNAUTHORIZEDUnauthorized. Verify your session or credentials.
403FORBIDDENYou do not have permission to perform this action.
403ACCOUNT_ACCESS_DENIEDThe actor does not have access to the requested account.
404ACCOUNT_NOT_FOUNDAccount not found.
409IDEMPOTENCY_CONFLICTIdempotency conflict: the same Idempotency-Key was reused with a different request body, or a previous request is still in progress.
409PAYMENT_DUPLICATEAn in-flight or completed payment with this client_reference already exists.
409CONFLICTThe request conflicts with the current state.
422INSUFFICIENT_FUNDSInsufficient funds to complete the payment.
422LIMIT_EXCEEDEDA transaction or accumulation limit was exceeded.
422UNPROCESSABLE_ENTITYThe request is well-formed but cannot be processed due to business rules.
500INTERNAL_ERRORAn unexpected error occurred. Please try again later.
502PROVIDER_ERRORUnable to complete the request with the payment provider. Please try again later.
503SERVICE_UNAVAILABLEA required service is temporarily unavailable. Please try again later.

Buscar pago por identificador

POST /api/public/v1/transactions/payments/search

Host: https://api-baas-sandbox.tilopay.com — requiere Authorization: Bearer <access_token>.

Busca un solo pago dentro de la cuenta del cliente indicada, por exactamente uno de:

  • payment_id (UUID interno)
  • public_id (identificador público numérico)
  • client_reference (referencia del comercio enviada al crear)

Enviar más de un identificador devuelve 400. La respuesta tiene la misma forma que la consulta por id (schema_version, external_reference a nivel de pago, objeto provider compartido, provider.provider_status_*, error alineado con el webhook). Mismo contrato público que GET /transactions/payments, incluido el identification.number público de los pagos PIN. Si varios pagos comparten un client_reference (intento fallido más reintento), se devuelve el pago en curso o completado cuando existe.

Parámetros

ParámetroEnTipoObligatorioDescripción
X-Correlation-IdheaderstringnoId de correlación opcional que enviás para trazar la solicitud de punta a punta. Se devuelve como correlation_id en el sobre de respuesta. Si lo omitís, la API genera uno y igual lo devuelve.

Cuerpo del request

CampoTipoObligatorioDescripción
accountobjectsí—
account.typestringsíEsquema de identificación de la cuenta (ej. IBAN, PHONE). No es la clasificación interna de la cuenta (ej. operativa).Valores: IBAN, PHONE
account.valuestringsíCuando type es PHONE (SINPE Móvil): 8 dígitos locales, sin prefijo de país (ej. "88887777").
account.currencystringnoMoneda opcional de la cuenta en las respuestas.
payment_idstring (uuid)noUUID interno del pago.
public_idstringnoIdentificador público numérico del pago. Es el mismo identificador: número en webhooks y texto en REST. Tratalo siempre como texto.
client_referencestringnoReferencia del comercio enviada al crear el pago.

Ejemplo de request

byPaymentId

{
  "account": {
    "type": "IBAN",
    "value": "CR08036900101010933608"
  },
  "payment_id": "11111111-1111-1111-1111-111111111111"
}

byPublicId

{
  "account": {
    "type": "IBAN",
    "value": "CR08036900101010933608"
  },
  "public_id": "134729"
}

byClientReference

{
  "account": {
    "type": "IBAN",
    "value": "CR08036900101010933608"
  },
  "client_reference": "INV-01082"
}

Respuesta 200

La solicitud se procesó correctamente.

CampoTipoObligatorioDescripción
schema_versionstringsíVersión del contrato de lectura de pagos. Mismo valor que el schema_version del sobre del webhook (1.0.0) para payment.succeeded / payment.failed.
payment_idstring (uuid)síUUID del pago devuelto al crearlo. Llave del pago para el comercio en GET /transactions/payments/{payment_id} y en la búsqueda. No es un id interno de cuenta.
public_idstringnoIdentificador público numérico del pago devuelto al crearlo. null si aún no se asigna. No es un UUID interno de cuenta. Es el mismo identificador: número en webhooks y texto en REST. Tratalo siempre como texto.Puede ser null.
typestringsíTipo de pago derivado de la dirección (PAYIN / PAYOUT).
payment_method_codestringsíCatálogo público de métodos de pago (PIN, SINPE_MOVIL). Mismos valores que en los webhooks.Valores: PIN, SINPE_MOVIL
statusstringsíCatálogo público de estados del pago. Siempre en minúsculas. Mismos valores en REST (crear, listar, obtener) y en webhooks (payment.status). Los estados internos del ciclo de vida se consolidan: - pending: iniciado, validado, aceptado - processing: procesando, pendiente de procesamiento, registrando - confirmed: confirmado por el riel, aún no registrado en el ledger - posted: registrado en el ledger (se mantiene posted tras un reverso posterior) - failed: fallido, rechazado, posting_failed, cancelado, expirado Un reverso no es un estado. Usá result=reversed / has_reversal=true en REST y el webhook payment.reversed. El detalle operativo queda en status_detail (nombre interno en mayúsculas) en crear/listar/obtener de REST. El webhook payment.failed usa error.platform.code para distinguir fallos de registro de rechazos del proveedor.Valores: pending, processing, confirmed, posted, failed
status_detailstringnoEstado operativo (interno) en mayúsculas, ej. VALIDATED, POSTED, POSTING_FAILED. Complemento del catálogo público status. Independiente de result (posted es el hito de débito/registro, no el éxito del proveedor).
resultstringsíResultado de negocio consolidado para conciliación (respaldo de los webhooks). Independiente del status de procesamiento. Se deriva así: reversed cuando has_reversal es true (prioridad más alta); succeeded cuando succeeded_at está presente y no hay reverso; failed cuando el estado de procesamiento es failed o posting_failed; si no, pending. Un pago registrado (posted) que luego se revirtió tiene status=posted y result=reversed.Valores: succeeded, failed, reversed, pending
succeeded_atstring (date-time)noMarca de tiempo de confirmación de éxito del proveedor (RFC 3339 UTC, precisión de segundos, Z). Null mientras el pago ya pueda estar posted internamente pero el proveedor no haya confirmado el éxito.Puede ser null.
has_reversalbooleansíTrue cuando se aplicó un reverso. Independiente de status. Se correlaciona con el webhook payment.reversed.
reversed_atstring (date-time)noCuándo se aplicó el reverso. Null cuando has_reversal es false.Puede ser null.
created_atstring (date-time)noMarca de tiempo RFC 3339 en UTC con precisión de segundos y sufijo Z. Nunca se emiten fracciones de segundo. Ejemplo: 2026-01-15T12:00:00Z.
updated_atstring (date-time)noMarca de tiempo RFC 3339 en UTC con precisión de segundos y sufijo Z. Nunca se emiten fracciones de segundo. Ejemplo: 2026-01-15T12:00:00Z.
amountobjectnoMisma forma monetaria que la creación de pago (PaymentAmount).
amount.amountstringsí—
amount.currencystringsí—
sourceobjectnoParte del pago en las lecturas del API. Los campos anidados siempre están presentes: null cuando el valor se desconoce. account es un identificador público (IBAN o PHONE); nunca se devuelven UUID internos de cuenta.
source.accountobjectsíIdentificador público de la cuenta (type + value). null cuando el IBAN o el teléfono no pueden resolverse. Nunca un UUID interno de cuenta.Puede ser null.
source.account.typestringsíEsquema de identificación de la cuenta (ej. IBAN, PHONE). No es la clasificación interna de la cuenta (ej. operativa).Valores: IBAN, PHONE
source.account.valuestringsíCuando type es PHONE (SINPE Móvil): 8 dígitos locales, sin prefijo de país (ej. "88887777").
source.account.currencystringnoMoneda opcional de la cuenta en las respuestas.
source.namestringsíNombre de la parte según los datos de procesamiento cuando está disponible; si no, null.Puede ser null.
source.identificationobjectsíIdentificación de la parte (clave de catálogo type + number). Objeto solo cuando al menos un campo se conoce; si no, null. No expone los códigos internos de tipo de SINPE (0–9); los tipos sin equivalencia se omiten (type: null). number es el valor público enviado por el comercio (dígitos, sin guiones SINPE). Los pagos históricos aún pueden devolver la forma de visualización SINPE con guiones.Puede ser null.
source.identification.typestringnoClave del catálogo de identificación (ej. cedula, juridica). null cuando se desconoce.Puede ser null.
source.identification.numberstringnoNúmero de identificación público. Los pagos PIN nuevos devuelven el valor enviado por el comercio (dígitos, sin guiones SINPE). Los pagos históricos aún pueden devolver la forma de visualización SINPE (con guiones, posiblemente con relleno).Puede ser null.
destinationobjectnoParte del pago en las lecturas del API. Los campos anidados siempre están presentes: null cuando el valor se desconoce. account es un identificador público (IBAN o PHONE); nunca se devuelven UUID internos de cuenta.
destination.accountobjectsíIdentificador público de la cuenta (type + value). null cuando el IBAN o el teléfono no pueden resolverse. Nunca un UUID interno de cuenta.Puede ser null.
destination.account.typestringsíEsquema de identificación de la cuenta (ej. IBAN, PHONE). No es la clasificación interna de la cuenta (ej. operativa).Valores: IBAN, PHONE
destination.account.valuestringsíCuando type es PHONE (SINPE Móvil): 8 dígitos locales, sin prefijo de país (ej. "88887777").
destination.account.currencystringnoMoneda opcional de la cuenta en las respuestas.
destination.namestringsíNombre de la parte según los datos de procesamiento cuando está disponible; si no, null.Puede ser null.
destination.identificationobjectsíIdentificación de la parte (clave de catálogo type + number). Objeto solo cuando al menos un campo se conoce; si no, null. No expone los códigos internos de tipo de SINPE (0–9); los tipos sin equivalencia se omiten (type: null). number es el valor público enviado por el comercio (dígitos, sin guiones SINPE). Los pagos históricos aún pueden devolver la forma de visualización SINPE con guiones.Puede ser null.
destination.identification.typestringnoClave del catálogo de identificación (ej. cedula, juridica). null cuando se desconoce.Puede ser null.
destination.identification.numberstringnoNúmero de identificación público. Los pagos PIN nuevos devuelven el valor enviado por el comercio (dígitos, sin guiones SINPE). Los pagos históricos aún pueden devolver la forma de visualización SINPE (con guiones, posiblemente con relleno).Puede ser null.
client_referencestringnoReferencia del comercio enviada al crear el pago (estable después del procesamiento). Mismo campo que payment.client_reference del webhook.
external_referencestringnoRail/SINPE transaction id. Same field, location, and meaning as webhook payment.external_reference on payment.succeeded / payment.failed Sibling of client_reference. null if none.Puede ser null.
providerobjectnoFoto compartida del proveedor en las lecturas REST de pagos y en los sobres de webhook. La referencia del riel solo está en payment.external_reference, no se duplica aquí. Los provider_status_* coinciden con rejection.reason_code / message / code del webhook cuando el proveedor rechazó la operación. null cuando no hay rechazo.
provider.correlation_idstringsíProvider transaction correlation identifier. Sent to SINPE as the correlation id. Not channel_reference (e.g. MOBILE_APP). Distinct from webhook event.correlation_id (HTTP request id for this delivery). null when unknown.Puede ser null.
provider.occurred_atstring (date-time)síMarca de tiempo RFC 3339 en UTC con precisión de segundos y sufijo Z. Nunca se emiten fracciones de segundo. Ejemplo: 2026-01-15T12:00:00Z.
provider.provider_status_codestringsíMotivo/código crudo del proveedor (ej. 31). Mismo significado que rejection.reason_code del webhook. null cuando no hay rechazo del proveedor.Puede ser null.
provider.provider_status_descstringsíTexto Motivo del proveedor (prefiere Detalle). Mismo significado que rejection.message del webhook. null cuando no hay rechazo del proveedor.Puede ser null.
provider.provider_status_semanticstringsíSemántica normalizada de la plataforma (ej. ACCOUNT_BLOCKED). Mismo significado que rejection.code del webhook. null cuando no hay rechazo del proveedor.Puede ser null.
errorobjectnoSiempre presente. null cuando no hay información de fallo (succeeded, pending, o failed/reversed sin taxonomía). El objeto usa la misma forma domain / platform que el webhook payment.failed.Puede ser null.
error.domainstringsíMismo catálogo que payment.error.domain del webhook.Valores: provider_rejection, platform_validation, platform_posting, platform_infra, platform_reversal
error.platformobjectsí—
error.platform.codestringsíCódigo público estable de la plataforma (igual que payment.error.platform.code del webhook).
error.platform.messagestringsíMensaje accionable (prefiere el Detalle del proveedor). Igual que payment.error.platform.message del webhook.

Ejemplo de respuesta

{
  "success": true,
  "http_status_code": 200,
  "response_code": "OK",
  "message": "The request was processed successfully.",
  "correlation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "data": {
    "schema_version": "1.0.0",
    "payment_id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
    "public_id": "10234",
    "type": "PAYOUT",
    "payment_method_code": "PIN",
    "status": "posted",
    "status_detail": "POSTED",
    "result": "succeeded",
    "succeeded_at": "2026-01-15T12:00:00Z",
    "has_reversal": false,
    "reversed_at": null,
    "created_at": "2026-01-15T12:00:00Z",
    "updated_at": "2026-01-15T12:00:00Z",
    "amount": {
      "amount": "1000.00",
      "currency": "CRC",
      "fees": "0.00",
      "taxes": "0.00"
    },
    "source": {
      "account": {
        "type": "IBAN",
        "value": "CR26036900101010588061",
        "currency": "CRC"
      },
      "name": "María González",
      "identification": {
        "type": "cedula",
        "number": "0205620043"
      }
    },
    "destination": {
      "account": {
        "type": "IBAN",
        "value": "CR16010400000000000031",
        "currency": "CRC"
      },
      "name": "Juan Perez",
      "identification": {
        "type": "cedula",
        "number": "0101010101"
      }
    },
    "client_reference": "INV-1001",
    "external_reference": "SINPE-20260115-000123",
    "provider": {
      "correlation_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
      "occurred_at": "2026-01-15T12:00:00Z",
      "provider_status_code": "00",
      "provider_status_desc": "Aprobada",
      "provider_status_semantic": "SUCCESS"
    },
    "error": null
  }
}

Respuestas de error

HTTPresponse_codeDescripción
400INVALID_REQUESTInvalid request. Check the required fields and try again.
401UNAUTHORIZEDUnauthorized. Verify your session or credentials.
403FORBIDDENYou do not have permission to perform this action.
403ACCOUNT_ACCESS_DENIEDThe actor does not have access to the requested account.
404PAYMENT_NOT_FOUNDPayment not found.
500INTERNAL_ERRORAn unexpected error occurred. Please try again later.
502PROVIDER_ERRORUnable to complete the request with the payment provider. Please try again later.
503SERVICE_UNAVAILABLEA required service is temporarily unavailable. Please try again later.

Obtener pago por id

GET /api/public/v1/transactions/payments/{payment_id}

Host: https://api-baas-sandbox.tilopay.com — requiere Authorization: Bearer <access_token>.

Devuelve un solo pago con el mismo contrato público del listado, incluidos el result consolidado, succeeded_at, has_reversal y error. error es null cuando no hay información de fallo; es un objeto solo cuando domain / platform está presente (result es failed o reversed), misma forma que payment.error del webhook payment.failed. source / destination usan null para campos anidados desconocidos y nunca exponen UUID internos de cuenta. identification.number en pagos PIN es el número público enviado por el comercio (dígitos, sin guiones SINPE). Los pagos antiguos aún pueden devolver la forma SINPE con guiones. Usalo como respaldo de los webhooks.

Busca un pago por cualquiera de estos identificadores:

  • payment_id (UUID interno)
  • public_id (identificador público numérico)

Para client_reference, usá POST /api/public/v1/transactions/payments/search.

Parámetros

ParámetroEnTipoObligatorioDescripción
X-Correlation-IdheaderstringnoId de correlación opcional que enviás para trazar la solicitud de punta a punta. Se devuelve como correlation_id en el sobre de respuesta. Si lo omitís, la API genera uno y igual lo devuelve.
payment_idpathstringsíUUID interno del pago o public_id numérico.

Respuesta 200

La solicitud se procesó correctamente.

CampoTipoObligatorioDescripción
schema_versionstringsíVersión del contrato de lectura de pagos. Mismo valor que el schema_version del sobre del webhook (1.0.0) para payment.succeeded / payment.failed.
payment_idstring (uuid)síUUID del pago devuelto al crearlo. Llave del pago para el comercio en GET /transactions/payments/{payment_id} y en la búsqueda. No es un id interno de cuenta.
public_idstringnoIdentificador público numérico del pago devuelto al crearlo. null si aún no se asigna. No es un UUID interno de cuenta. Es el mismo identificador: número en webhooks y texto en REST. Tratalo siempre como texto.Puede ser null.
typestringsíTipo de pago derivado de la dirección (PAYIN / PAYOUT).
payment_method_codestringsíCatálogo público de métodos de pago (PIN, SINPE_MOVIL). Mismos valores que en los webhooks.Valores: PIN, SINPE_MOVIL
statusstringsíCatálogo público de estados del pago. Siempre en minúsculas. Mismos valores en REST (crear, listar, obtener) y en webhooks (payment.status). Los estados internos del ciclo de vida se consolidan: - pending: iniciado, validado, aceptado - processing: procesando, pendiente de procesamiento, registrando - confirmed: confirmado por el riel, aún no registrado en el ledger - posted: registrado en el ledger (se mantiene posted tras un reverso posterior) - failed: fallido, rechazado, posting_failed, cancelado, expirado Un reverso no es un estado. Usá result=reversed / has_reversal=true en REST y el webhook payment.reversed. El detalle operativo queda en status_detail (nombre interno en mayúsculas) en crear/listar/obtener de REST. El webhook payment.failed usa error.platform.code para distinguir fallos de registro de rechazos del proveedor.Valores: pending, processing, confirmed, posted, failed
status_detailstringnoEstado operativo (interno) en mayúsculas, ej. VALIDATED, POSTED, POSTING_FAILED. Complemento del catálogo público status. Independiente de result (posted es el hito de débito/registro, no el éxito del proveedor).
resultstringsíResultado de negocio consolidado para conciliación (respaldo de los webhooks). Independiente del status de procesamiento. Se deriva así: reversed cuando has_reversal es true (prioridad más alta); succeeded cuando succeeded_at está presente y no hay reverso; failed cuando el estado de procesamiento es failed o posting_failed; si no, pending. Un pago registrado (posted) que luego se revirtió tiene status=posted y result=reversed.Valores: succeeded, failed, reversed, pending
succeeded_atstring (date-time)noMarca de tiempo de confirmación de éxito del proveedor (RFC 3339 UTC, precisión de segundos, Z). Null mientras el pago ya pueda estar posted internamente pero el proveedor no haya confirmado el éxito.Puede ser null.
has_reversalbooleansíTrue cuando se aplicó un reverso. Independiente de status. Se correlaciona con el webhook payment.reversed.
reversed_atstring (date-time)noCuándo se aplicó el reverso. Null cuando has_reversal es false.Puede ser null.
created_atstring (date-time)noMarca de tiempo RFC 3339 en UTC con precisión de segundos y sufijo Z. Nunca se emiten fracciones de segundo. Ejemplo: 2026-01-15T12:00:00Z.
updated_atstring (date-time)noMarca de tiempo RFC 3339 en UTC con precisión de segundos y sufijo Z. Nunca se emiten fracciones de segundo. Ejemplo: 2026-01-15T12:00:00Z.
amountobjectnoMisma forma monetaria que la creación de pago (PaymentAmount).
amount.amountstringsí—
amount.currencystringsí—
sourceobjectnoParte del pago en las lecturas del API. Los campos anidados siempre están presentes: null cuando el valor se desconoce. account es un identificador público (IBAN o PHONE); nunca se devuelven UUID internos de cuenta.
source.accountobjectsíIdentificador público de la cuenta (type + value). null cuando el IBAN o el teléfono no pueden resolverse. Nunca un UUID interno de cuenta.Puede ser null.
source.account.typestringsíEsquema de identificación de la cuenta (ej. IBAN, PHONE). No es la clasificación interna de la cuenta (ej. operativa).Valores: IBAN, PHONE
source.account.valuestringsíCuando type es PHONE (SINPE Móvil): 8 dígitos locales, sin prefijo de país (ej. "88887777").
source.account.currencystringnoMoneda opcional de la cuenta en las respuestas.
source.namestringsíNombre de la parte según los datos de procesamiento cuando está disponible; si no, null.Puede ser null.
source.identificationobjectsíIdentificación de la parte (clave de catálogo type + number). Objeto solo cuando al menos un campo se conoce; si no, null. No expone los códigos internos de tipo de SINPE (0–9); los tipos sin equivalencia se omiten (type: null). number es el valor público enviado por el comercio (dígitos, sin guiones SINPE). Los pagos históricos aún pueden devolver la forma de visualización SINPE con guiones.Puede ser null.
source.identification.typestringnoClave del catálogo de identificación (ej. cedula, juridica). null cuando se desconoce.Puede ser null.
source.identification.numberstringnoNúmero de identificación público. Los pagos PIN nuevos devuelven el valor enviado por el comercio (dígitos, sin guiones SINPE). Los pagos históricos aún pueden devolver la forma de visualización SINPE (con guiones, posiblemente con relleno).Puede ser null.
destinationobjectnoParte del pago en las lecturas del API. Los campos anidados siempre están presentes: null cuando el valor se desconoce. account es un identificador público (IBAN o PHONE); nunca se devuelven UUID internos de cuenta.
destination.accountobjectsíIdentificador público de la cuenta (type + value). null cuando el IBAN o el teléfono no pueden resolverse. Nunca un UUID interno de cuenta.Puede ser null.
destination.account.typestringsíEsquema de identificación de la cuenta (ej. IBAN, PHONE). No es la clasificación interna de la cuenta (ej. operativa).Valores: IBAN, PHONE
destination.account.valuestringsíCuando type es PHONE (SINPE Móvil): 8 dígitos locales, sin prefijo de país (ej. "88887777").
destination.account.currencystringnoMoneda opcional de la cuenta en las respuestas.
destination.namestringsíNombre de la parte según los datos de procesamiento cuando está disponible; si no, null.Puede ser null.
destination.identificationobjectsíIdentificación de la parte (clave de catálogo type + number). Objeto solo cuando al menos un campo se conoce; si no, null. No expone los códigos internos de tipo de SINPE (0–9); los tipos sin equivalencia se omiten (type: null). number es el valor público enviado por el comercio (dígitos, sin guiones SINPE). Los pagos históricos aún pueden devolver la forma de visualización SINPE con guiones.Puede ser null.
destination.identification.typestringnoClave del catálogo de identificación (ej. cedula, juridica). null cuando se desconoce.Puede ser null.
destination.identification.numberstringnoNúmero de identificación público. Los pagos PIN nuevos devuelven el valor enviado por el comercio (dígitos, sin guiones SINPE). Los pagos históricos aún pueden devolver la forma de visualización SINPE (con guiones, posiblemente con relleno).Puede ser null.
client_referencestringnoReferencia del comercio enviada al crear el pago (estable después del procesamiento). Mismo campo que payment.client_reference del webhook.
external_referencestringnoRail/SINPE transaction id. Same field, location, and meaning as webhook payment.external_reference on payment.succeeded / payment.failed Sibling of client_reference. null if none.Puede ser null.
providerobjectnoFoto compartida del proveedor en las lecturas REST de pagos y en los sobres de webhook. La referencia del riel solo está en payment.external_reference, no se duplica aquí. Los provider_status_* coinciden con rejection.reason_code / message / code del webhook cuando el proveedor rechazó la operación. null cuando no hay rechazo.
provider.correlation_idstringsíProvider transaction correlation identifier. Sent to SINPE as the correlation id. Not channel_reference (e.g. MOBILE_APP). Distinct from webhook event.correlation_id (HTTP request id for this delivery). null when unknown.Puede ser null.
provider.occurred_atstring (date-time)síMarca de tiempo RFC 3339 en UTC con precisión de segundos y sufijo Z. Nunca se emiten fracciones de segundo. Ejemplo: 2026-01-15T12:00:00Z.
provider.provider_status_codestringsíMotivo/código crudo del proveedor (ej. 31). Mismo significado que rejection.reason_code del webhook. null cuando no hay rechazo del proveedor.Puede ser null.
provider.provider_status_descstringsíTexto Motivo del proveedor (prefiere Detalle). Mismo significado que rejection.message del webhook. null cuando no hay rechazo del proveedor.Puede ser null.
provider.provider_status_semanticstringsíSemántica normalizada de la plataforma (ej. ACCOUNT_BLOCKED). Mismo significado que rejection.code del webhook. null cuando no hay rechazo del proveedor.Puede ser null.
errorobjectnoSiempre presente. null cuando no hay información de fallo (succeeded, pending, o failed/reversed sin taxonomía). El objeto usa la misma forma domain / platform que el webhook payment.failed.Puede ser null.
error.domainstringsíMismo catálogo que payment.error.domain del webhook.Valores: provider_rejection, platform_validation, platform_posting, platform_infra, platform_reversal
error.platformobjectsí—
error.platform.codestringsíCódigo público estable de la plataforma (igual que payment.error.platform.code del webhook).
error.platform.messagestringsíMensaje accionable (prefiere el Detalle del proveedor). Igual que payment.error.platform.message del webhook.

Ejemplo de respuesta

{
  "success": true,
  "http_status_code": 200,
  "response_code": "OK",
  "message": "The request was processed successfully.",
  "correlation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "data": {
    "schema_version": "1.0.0",
    "payment_id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
    "public_id": "10234",
    "type": "PAYOUT",
    "payment_method_code": "PIN",
    "status": "posted",
    "status_detail": "POSTED",
    "result": "succeeded",
    "succeeded_at": "2026-01-15T12:00:00Z",
    "has_reversal": false,
    "reversed_at": null,
    "created_at": "2026-01-15T12:00:00Z",
    "updated_at": "2026-01-15T12:00:00Z",
    "amount": {
      "amount": "1000.00",
      "currency": "CRC",
      "fees": "0.00",
      "taxes": "0.00"
    },
    "source": {
      "account": {
        "type": "IBAN",
        "value": "CR26036900101010588061",
        "currency": "CRC"
      },
      "name": "María González",
      "identification": {
        "type": "cedula",
        "number": "0205620043"
      }
    },
    "destination": {
      "account": {
        "type": "IBAN",
        "value": "CR16010400000000000031",
        "currency": "CRC"
      },
      "name": "Juan Perez",
      "identification": {
        "type": "cedula",
        "number": "0101010101"
      }
    },
    "client_reference": "INV-1001",
    "external_reference": "SINPE-20260115-000123",
    "provider": {
      "correlation_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
      "occurred_at": "2026-01-15T12:00:00Z",
      "provider_status_code": "00",
      "provider_status_desc": "Aprobada",
      "provider_status_semantic": "SUCCESS"
    },
    "error": null
  }
}

Respuestas de error

HTTPresponse_codeDescripción
400INVALID_REQUESTInvalid request. Check the required fields and try again.
401UNAUTHORIZEDUnauthorized. Verify your session or credentials.
403FORBIDDENYou do not have permission to perform this action.
403ACCOUNT_ACCESS_DENIEDThe actor does not have access to the requested account.
404PAYMENT_NOT_FOUNDPayment not found.
500INTERNAL_ERRORAn unexpected error occurred. Please try again later.
502PROVIDER_ERRORUnable to complete the request with the payment provider. Please try again later.
503SERVICE_UNAVAILABLEA required service is temporarily unavailable. Please try again later.

Procesamiento y límites#

La creación de pagos en el API no tiene doble control: el pago se procesa directamente si el token, los permisos y los datos son válidos. Aplican límites por transacción, diarios y mensuales, en monto y cantidad. Si se supera alguno, el pago falla durante el procesamiento y se notifica con el evento payment.failed.

El flujo de confirmación de transferencias del servidor MCP es independiente de esta creación directa del API.

Última verificación: 2026-10-22

Ver como Markdown crudo