openapi: 3.1.0
info:
  title: API Products
  version: 1.0.0
  description: >+
    API para integraciones con SPIDI.

     ##  Navegación en Móvil

    Si estás en un dispositivo móvil, recuerda usar el menú de hamburguesa en la
    esquina superior izquierda para ver todos los endpoints disponibles.


    ##  Entornos


    Para información detallada sobre entornos (Sandbox y Producción), consulta
    la página dedicada:

     **[Entornos](../../env)**

    ##  Webhooks


    SPIDI utiliza webhooks para notificar en tiempo real sobre eventos
    importantes (pagos completados, sesiones expiradas, etc.). Para información
    completa sobre:


    - Eventos disponibles

    - Estructura de webhooks

    - Reintentos automáticos

    - Seguridad y validación

    - Ejemplos de implementación


    Consulta la página dedicada:

     **[Webhooks](../../concepts/webhooks.mdx)**

servers:
  - url: https://sandbox.api.spidipagos.com
    description: Sandbox - Entorno de pruebas para desarrollo e integración
tags:
  - name: Endpoints Comunes
    description: Endpoints que siempre se deben utilizar
  - name: Endpoints Botón
    description: Endpoints relacionados con los botones de pago
  - name: Endpoints Solicitud
    description: Endpoints relacionados con las solicitudes de pago
  - name: Endpoints Parada
    description: >-
      Endpoints para gestionar Paradas SPIDI.


      ## ¿Qué son las Paradas SPIDI?


      Las Paradas SPIDI son espacios únicos y permanentes asociados a cada
      cliente, donde este puede consultar, gestionar y pagar todas sus
      solicitudes de pago activas o históricas, sin necesidad de recibir nuevos
      enlaces cada vez.


      **Beneficios clave:**

      - **URL permanente**: Punto de acceso constante y trazable

      - **Gestión centralizada**: Todas las solicitudes de pago en un solo lugar

      - **Ideal para**: Relaciones comerciales continuas, suscripciones, pagos
      recurrentes

      - **Experiencia simplificada**: Para el pagador y la empresa


      **Estados de una Parada:**

      - **Active**: Con solicitudes de pago activas disponibles

      - **Empty**: Sin solicitudes de pago activas, muestra mensaje
      personalizado

      - **Disabled**: Deshabilitada temporalmente, puede reactivarse

      - **Deleted**: Eliminada definitivamente
  - name: Endpoints Publicar
    description: Endpoints relacionados con la publicacion de solicitudes en las paradas
  - name: Endpoints Especiales
    description: Endpoints especiales
  - name: Endpoints Legacy
    description: >-
      Endpoints de versiones anteriores de la API que se mantienen por
      compatibilidad.
paths:
  /api/spidipagos/login:
    post:
      summary: Login
      description: >-
        Permite autenticar un usuario en el sistema SPIDI utilizando
        credenciales de acceso. Este endpoint es fundamental para obtener el
        token de autorización necesario para realizar operaciones posteriores en
        la API.


        ### Funcionalidades principales:


        * **Autenticación segura:** Valida las credenciales del usuario
        (`short_name` y `password`).

        * **Generación de token JWT:** Retorna un token de acceso que debe
        utilizarse en requests posteriores.

        * **Control de sesión:** El token tiene un tiempo de expiración definido
        para mayor seguridad.


        ### Casos de uso típicos:


        * Inicio de sesión de usuarios comercio.

        * Obtención de token para operaciones API.

        * Renovación de credenciales de acceso.

        * Autenticación en aplicaciones integradas.


        Una vez autenticado exitosamente, el token JWT debe incluirse en el
        header `Authorization: Bearer {token}` de todas las requests posteriores
        a la API.
      operationId: login
      tags:
        - Endpoints Comunes
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - short_name
                - password
              properties:
                short_name:
                  type: string
                  nullable: false
                  description: Nombre de usuario o identificador único del comercio.
                password:
                  type: string
                  nullable: false
                  description: Contraseña de acceso del usuario.
            example:
              short_name: spidiusuario1
              password: clavesecreta
      responses:
        '200':
          description: Autenticación exitosa
          content:
            application/json:
              schema:
                type: object
                required:
                  - token
                properties:
                  token:
                    type: string
                    nullable: false
                    description: >-
                      Token de autorización **JWT** para autenticar requests
                      posteriores. 


                      * El token es un **JWT (JSON Web Token)** codificado en
                      Base64.

                      * Debe incluirse en el header `Authorization: Bearer
                      {token}` de requests posteriores.

                      * Tiene un tiempo de expiración definido por seguridad.

                      * Contiene información del usuario autenticado y permisos.
              example:
                token: >-
                  eyJhbGciOiJlUzI1NilsInR5cCI6IkpXVCJ9.eyJzaG9ydF9uYW1lljoiZGInaXRlbClslmlhdCI6MTc2MDY0NTU4OCwiZXhwljoxNzYwNjQ2MTg4fQ.ZZaXHRfa57i4frCFIKLsRHU9Z7tI7JfU_o-TbEcwkN8
        '400':
          description: Solicitud inválida - Campos requeridos faltantes
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    example: false
                    description: Indica si la operación fue exitosa.
                  message:
                    type: string
                    example: Invalid credentials
                    description: Mensaje descriptivo del error.
                  errors:
                    type: object
                    nullable: true
                    description: Detalles específicos de los errores de validación.
                    properties:
                      short_name:
                        type: string
                        nullable: true
                        example: This field is required.
                        description: Error relacionado con el campo short_name.
                      password:
                        type: string
                        nullable: true
                        example: This field is required.
                        description: Error relacionado con el campo password.
                      authentication:
                        nullable: true
                        type: string
                        example: The provided credentials are incorrect
                        description: Error general de autenticación.
              example:
                success: false
                message: Missing required fields
                errors:
                  short_name: This field is required.
                  password: This field is required.
        '401':
          description: No autorizado - Credenciales incorrectas
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    example: false
                    description: Indica si la operación fue exitosa.
                  message:
                    type: string
                    example: Invalid credentials
                    description: Mensaje descriptivo del error.
                  errors:
                    type: object
                    nullable: true
                    description: Detalles específicos de los errores de validación.
                    properties:
                      short_name:
                        type: string
                        nullable: true
                        example: This field is required.
                        description: Error relacionado con el campo short_name.
                      password:
                        type: string
                        nullable: true
                        example: This field is required.
                        description: Error relacionado con el campo password.
                      authentication:
                        nullable: true
                        type: string
                        example: The provided credentials are incorrect
                        description: Error general de autenticación.
              example:
                success: false
                message: Invalid credentials
                errors:
                  authentication: The provided credentials are incorrect
        '422':
          description: Entidad no procesable - Datos de entrada inválidos
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    example: false
                    description: Indica si la operación fue exitosa.
                  message:
                    type: string
                    example: Invalid credentials
                    description: Mensaje descriptivo del error.
                  errors:
                    type: object
                    nullable: true
                    description: Detalles específicos de los errores de validación.
                    properties:
                      short_name:
                        type: string
                        nullable: true
                        example: This field is required.
                        description: Error relacionado con el campo short_name.
                      password:
                        type: string
                        nullable: true
                        example: This field is required.
                        description: Error relacionado con el campo password.
                      authentication:
                        nullable: true
                        type: string
                        example: The provided credentials are incorrect
                        description: Error general de autenticación.
              example:
                success: false
                message: Invalid input data
                errors:
                  short_name: Invalid format for short_name
                  password: Password must be at least 8 characters
        '429':
          description: Límite de intentos excedido
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    example: false
                    description: Indica si la operación fue exitosa.
                  message:
                    type: string
                    example: Invalid credentials
                    description: Mensaje descriptivo del error.
                  errors:
                    type: object
                    nullable: true
                    description: Detalles específicos de los errores de validación.
                    properties:
                      short_name:
                        type: string
                        nullable: true
                        example: This field is required.
                        description: Error relacionado con el campo short_name.
                      password:
                        type: string
                        nullable: true
                        example: This field is required.
                        description: Error relacionado con el campo password.
                      authentication:
                        nullable: true
                        type: string
                        example: The provided credentials are incorrect
                        description: Error general de autenticación.
              example:
                success: false
                message: Rate limit exceeded
                errors:
                  retry_after: '60'
        '500':
          description: Error interno del servidor
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    example: false
                    description: Indica si la operación fue exitosa.
                  message:
                    type: string
                    example: Invalid credentials
                    description: Mensaje descriptivo del error.
                  errors:
                    type: object
                    nullable: true
                    description: Detalles específicos de los errores de validación.
                    properties:
                      short_name:
                        type: string
                        nullable: true
                        example: This field is required.
                        description: Error relacionado con el campo short_name.
                      password:
                        type: string
                        nullable: true
                        example: This field is required.
                        description: Error relacionado con el campo password.
                      authentication:
                        nullable: true
                        type: string
                        example: The provided credentials are incorrect
                        description: Error general de autenticación.
              example:
                success: false
                message: Internal server error
  /api/v1/ext/agreements:
    post:
      summary: Crear Acuerdo de Pago
      description: >-
        Permite crear un nuevo **agreement de pago** que define las reglas de
        distribución y liquidación de las transacciones.


        ---


        ### **⚙️ Funcionalidades principales**


        * **Distribución de pagos (Split):** Define cómo se repartirán los
        fondos entre el comercio (owner) y sus partners o afiliados. El owner
        **siempre existe** y recibe automáticamente la diferencia no asignada a
        terceros.

        * **Liquidación bancaria inteligente:** Permite dirigir los pagos hacia
        distintas cuentas bancarias de destino dependiendo del banco de origen
        del pagador.

        * **Medios de pago configurables:** Determina qué tipos de pago acepta
        el acuerdo (`immediate_debit`, `crypto`, `mobile_payment`).

        * **`split`:**
          * **`false`:** No aplica distribución; el owner recibe el 100 % del pago.
          * **`true`:** Usa porcentajes predefinidos que se aplican de manera uniforme en todas las transacciones. Solo se definen las participaciones de los terceros receptores; la diferencia restante se asigna automáticamente al **owner**, quien siempre debe recibir una parte del pago.

        ### **Casos de uso típicos**


        * Comercios que trabajan con partners y necesitan distribuir comisiones
        automáticamente.

        * Marketplaces que deben dividir los pagos entre vendedores y la
        plataforma.

        * Servicios que liquidan fondos en distintas cuentas según el banco de
        origen.

        * Plataformas que requieren flexibilidad para definir la distribución
        por cada transacción.


        ### **Reutilización**


        Una vez creado, el *agreement* puede emplearse en múltiples sesiones de
        pago, asegurando **consistencia en la distribución**, **control sobre la
        liquidación bancaria**, y **trazabilidad completa** en todos los
        movimientos de fondos.
      operationId: createAgreement
      tags:
        - Endpoints Comunes
      security:
        - bearerAuth: []
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - title
                - payment_methods
                - default_bank_account_id
                - split
              properties:
                title:
                  type: string
                  nullable: false
                  description: 'Título visible. '
                description:
                  type: string
                  nullable: true
                  description: >-
                    Descripción del acuerdo o del concepto de pago asociado a
                    una sesión.
                  maxLength: 500
                payment_methods:
                  type: object
                  required:
                    - immediate_debit
                    - crypto
                    - mobile_payment
                  properties:
                    immediate_debit:
                      type: boolean
                      description: Indica si permite pagos con débito inmediato.
                    crypto:
                      type: boolean
                      description: >-
                        Indica si se permiten pagos con criptomonedas en la
                        configuración correspondiente. La liquidación siempre
                        ocurre en bolívares.
                    mobile_payment:
                      type: boolean
                      description: Indica si permite pagos móviles.
                default_bank_account_id:
                  type: string
                  format: uuid
                  nullable: false
                  description: >-
                    UUID de la cuenta bancaria por defecto que se utilizará para
                    la liquidación. 
                rules:
                  type: array
                  nullable: true
                  description: |-
                    (**En Desarrollo**) Reglas de acuerdo. 
                     En caso de usar origin_bank_code y destination_bank_account_id, se aplicará una regla de ruteo por banco de origen. Cada regla define a qué cuenta bancaria se debe enviar el dinero según el banco del pagador.
                  items:
                    type: object
                    properties:
                      origin_bank_code:
                        type: string
                        nullable: false
                        description: 'Código oficial del banco de origen. '
                      destination_bank_account_id:
                        type: string
                        nullable: true
                        description: >-
                          UUID de la cuenta bancaria de destino para un banco de
                          origen específico. 
                split:
                  type: boolean
                  description: >-
                    Modo de split: false (sin distribución) o true (permite
                    split por sesión).
            examples:
              Sin Split:
                summary: Acuerdo sin Split
                value:
                  title: Acuerdo sin Split
                  description: Sin distribución de fondos
                  split: false
                  payment_methods:
                    immediate_debit: true
                    crypto: false
                    mobile_payment: true
                  default_bank_account_id: uuid_sofitasa_001
                  rules:
                    - origin_bank_code: '0105'
                      destination_bank_account_id: uuid_mercantil_007
              Con Split:
                summary: Acuerdo con Split Flexible
                value:
                  title: Acuerdo Flexible
                  description: Split configurable por sesión de pago
                  split: true
                  payment_methods:
                    immediate_debit: true
                    crypto: false
                    mobile_payment: true
                  default_bank_account_id: uuid_sofitasa_001
                  rules:
                    - origin_bank_code: '0105'
                      destination_bank_account_id: uuid_mercantil_007
      responses:
        '200':
          description: Acuerdo creado exitosamente
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - data
                properties:
                  success:
                    type: boolean
                    nullable: false
                    description: >-
                      Indica si la operación fue exitosa. True si el endpoint se
                      procesó de forma exitosa. False de lo contrario
                    example: true
                  data:
                    type: object
                    required:
                      - agreement_id
                      - title
                      - split
                      - payment_methods
                      - default_bank_account_id
                      - status
                      - created_at
                      - created_by
                    properties:
                      agreement_id:
                        type: string
                        format: uuid
                        nullable: true
                        description: >-
                          Identificador único del acuerdo de liquidación. Debe
                          ser UUID v4. 
                      title:
                        type: string
                        nullable: false
                        description: 'Título visible. '
                      description:
                        type: string
                        nullable: true
                        description: >-
                          Descripción del acuerdo o del concepto de pago
                          asociado a una sesión.
                        maxLength: 500
                      split:
                        type: boolean
                        description: Modo de split configurado en el acuerdo.
                      payment_methods:
                        type: object
                        required:
                          - immediate_debit
                          - crypto
                          - mobile_payment
                        properties:
                          immediate_debit:
                            type: boolean
                            description: Indica si permite pagos con débito inmediato.
                          crypto:
                            type: boolean
                            description: >-
                              Indica si se permiten pagos con criptomonedas en
                              la configuración correspondiente. La liquidación
                              siempre ocurre en bolívares.
                          mobile_payment:
                            type: boolean
                            description: Indica si permite pagos móviles.
                      default_bank_account_id:
                        type: string
                        format: uuid
                        nullable: false
                        description: >-
                          UUID de la cuenta bancaria por defecto que se
                          utilizará para la liquidación. 
                      rules:
                        type: array
                        nullable: true
                        description: |-
                          (**En Desarrollo**) Reglas de acuerdo. 
                           En caso de usar origin_bank_code y destination_bank_account_id, se aplicará una regla de ruteo por banco de origen. Cada regla define a qué cuenta bancaria se debe enviar el dinero según el banco del pagador.
                        items:
                          type: object
                          properties:
                            origin_bank_code:
                              type: string
                              nullable: false
                              description: 'Código oficial del banco de origen. '
                            destination_bank_account_id:
                              type: string
                              nullable: true
                              description: >-
                                UUID de la cuenta bancaria de destino para un
                                banco de origen específico. 
                      status:
                        type: string
                        nullable: false
                        enum:
                          - pending
                          - paid
                          - failed
                          - expired
                        description: >-
                          Estado actual de la sesión. El valor failed solo se
                          aplica para sesiones creadas con botón de pago.
                      created_at:
                        type: string
                        nullable: true
                        format: date-time
                        description: >-
                          Fecha y hora de creación del recurso en formato ISO
                          8601.
                      created_by:
                        type: string
                        nullable: true
                        description: >-
                          Identificador del usuario que creó el recurso
                          administrable.
              examples:
                Sin Split:
                  summary: 'Response - split: false'
                  value:
                    success: true
                    data:
                      agreement_id: agr_none_01
                      title: Acuerdo sin Split
                      type: button
                      description: >-
                        Sin distribución de fondos; el owner recibe el 100% de
                        los pagos
                      split: false
                      payment_methods:
                        immediate_debit: true
                        crypto: false
                        mobile_payment: true
                      default_bank_account_id: uuid_sofitasa_001
                      rules:
                        - origin_bank_code: '0105'
                          destination_bank_account_id: uuid_mercantil_007
                      status: active
                      created_at: '2024-01-15T10:30:00Z'
                      created_by: user_123
                Con Split:
                  summary: 'Response - split: true'
                  value:
                    success: true
                    data:
                      agreement_id: agr_by_session_01
                      title: Acuerdo Flexible
                      type: request
                      description: Split configurable por sesión de pago
                      split: true
                      payment_methods:
                        immediate_debit: true
                        crypto: false
                        mobile_payment: true
                      default_bank_account_id: uuid_sofitasa_001
                      rules:
                        - origin_bank_code: '0105'
                          destination_bank_account_id: uuid_mercantil_007
                      status: active
                      created_at: '2024-01-15T10:30:00Z'
                      created_by: user_123
        '400':
          description: Solicitud inválida - Campo faltante
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    example: false
                    description: Indica si la operación fue exitosa.
                  message:
                    type: string
                    example: 'Missing required field: title'
                    description: Mensaje descriptivo del error.
                  errors:
                    type: object
                    nullable: true
                    description: Detalles específicos de los errores de validación.
                    properties:
                      type:
                        type: string
                        example: Invalid value. Must be button or request
                        description: Error relacionado con el campo type.
                      split:
                        type: boolean
                        example: Invalid value. Must be true or false
                        description: Error relacionado con el modo de split.
                      spidi_id:
                        type: string
                        example: The credentials are incorrect
                        description: Error de autenticación.
                      field:
                        type: string
                        example: Invalid field value
                        description: Error genérico de campo.
              example:
                success: false
                message: 'Missing required field: title'
                errors:
                  title: This field is required.
        '401':
          description: No autorizado - Token inválido
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    example: false
                    description: Indica si la operación fue exitosa.
                  message:
                    type: string
                    example: 'Missing required field: title'
                    description: Mensaje descriptivo del error.
                  errors:
                    type: object
                    nullable: true
                    description: Detalles específicos de los errores de validación.
                    properties:
                      type:
                        type: string
                        example: Invalid value. Must be button or request
                        description: Error relacionado con el campo type.
                      split:
                        type: boolean
                        example: Invalid value. Must be true or false
                        description: Error relacionado con el modo de split.
                      spidi_id:
                        type: string
                        example: The credentials are incorrect
                        description: Error de autenticación.
                      field:
                        type: string
                        example: Invalid field value
                        description: Error genérico de campo.
              example:
                success: false
                message: Unauthorized.
                errors:
                  spidi_id: The credentials are incorrect
        '403':
          description: Prohibido - Sin permisos
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    example: false
                    description: Indica si la operación fue exitosa.
                  message:
                    type: string
                    example: 'Missing required field: title'
                    description: Mensaje descriptivo del error.
                  errors:
                    type: object
                    nullable: true
                    description: Detalles específicos de los errores de validación.
                    properties:
                      type:
                        type: string
                        example: Invalid value. Must be button or request
                        description: Error relacionado con el campo type.
                      split:
                        type: boolean
                        example: Invalid value. Must be true or false
                        description: Error relacionado con el modo de split.
                      spidi_id:
                        type: string
                        example: The credentials are incorrect
                        description: Error de autenticación.
                      field:
                        type: string
                        example: Invalid field value
                        description: Error genérico de campo.
              example:
                success: false
                message: Forbidden. You don't have permission for this operation.
        '409':
          description: Conflicto - Acuerdo duplicado
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    example: false
                    description: Indica si la operación fue exitosa.
                  message:
                    type: string
                    example: 'Missing required field: title'
                    description: Mensaje descriptivo del error.
                  errors:
                    type: object
                    nullable: true
                    description: Detalles específicos de los errores de validación.
                    properties:
                      type:
                        type: string
                        example: Invalid value. Must be button or request
                        description: Error relacionado con el campo type.
                      split:
                        type: boolean
                        example: Invalid value. Must be true or false
                        description: Error relacionado con el modo de split.
                      spidi_id:
                        type: string
                        example: The credentials are incorrect
                        description: Error de autenticación.
                      field:
                        type: string
                        example: Invalid field value
                        description: Error genérico de campo.
              example:
                success: false
                message: Duplicate agreement
        '422':
          description: Entidad no procesable - Datos inválidos
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    example: false
                    description: Indica si la operación fue exitosa.
                  message:
                    type: string
                    example: 'Missing required field: title'
                    description: Mensaje descriptivo del error.
                  errors:
                    type: object
                    nullable: true
                    description: Detalles específicos de los errores de validación.
                    properties:
                      type:
                        type: string
                        example: Invalid value. Must be button or request
                        description: Error relacionado con el campo type.
                      split:
                        type: boolean
                        example: Invalid value. Must be true or false
                        description: Error relacionado con el modo de split.
                      spidi_id:
                        type: string
                        example: The credentials are incorrect
                        description: Error de autenticación.
                      field:
                        type: string
                        example: Invalid field value
                        description: Error genérico de campo.
              examples:
                invalid_split:
                  summary: Configuración de split inválida
                  value:
                    success: false
                    message: Unprocessable entity.
                    errors:
                      split: INVALID_SPLIT_CONFIGURATION
                invalid_bank_code:
                  summary: Código de banco inválido
                  value:
                    success: false
                    message: Unprocessable entity.
                    errors:
                      origin_bank_code: INVALID_BANK_CODE
                destination_bank_not_found:
                  summary: Cuenta bancaria de destino no encontrada
                  value:
                    success: false
                    message: Unprocessable entity.
                    errors:
                      destination_bank_account_id: BANK_ACCOUNT_NOT_FOUND
                origin_bank_not_found:
                  summary: Cuenta bancaria de origen no encontrada
                  value:
                    success: false
                    message: Unprocessable entity.
                    errors:
                      origin_bank_code: BANK_ACCOUNT_NOT_FOUND
        '429':
          description: Límite de requests excedido
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    example: false
                    description: Indica si la operación fue exitosa.
                  message:
                    type: string
                    example: 'Missing required field: title'
                    description: Mensaje descriptivo del error.
                  errors:
                    type: object
                    nullable: true
                    description: Detalles específicos de los errores de validación.
                    properties:
                      type:
                        type: string
                        example: Invalid value. Must be button or request
                        description: Error relacionado con el campo type.
                      split:
                        type: boolean
                        example: Invalid value. Must be true or false
                        description: Error relacionado con el modo de split.
                      spidi_id:
                        type: string
                        example: The credentials are incorrect
                        description: Error de autenticación.
                      field:
                        type: string
                        example: Invalid field value
                        description: Error genérico de campo.
              example:
                success: false
                message: Rate limit exceeded
        '500':
          description: Error interno del servidor
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    example: false
                    description: Indica si la operación fue exitosa.
                  message:
                    type: string
                    example: 'Missing required field: title'
                    description: Mensaje descriptivo del error.
                  errors:
                    type: object
                    nullable: true
                    description: Detalles específicos de los errores de validación.
                    properties:
                      type:
                        type: string
                        example: Invalid value. Must be button or request
                        description: Error relacionado con el campo type.
                      split:
                        type: boolean
                        example: Invalid value. Must be true or false
                        description: Error relacionado con el modo de split.
                      spidi_id:
                        type: string
                        example: The credentials are incorrect
                        description: Error de autenticación.
                      field:
                        type: string
                        example: Invalid field value
                        description: Error genérico de campo.
              example:
                success: false
                message: Internal server error.
  /api/v1/ext/partner:
    post:
      tags:
        - Endpoints Especiales
      summary: Generar Partner
      description: Endpoint para la creación de un nuevo partner en el sistema.
      operationId: createPartner
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - name
                - identification
                - contact_email
                - contact_phone
                - bank_code
                - payment_phone_or_cnta
                - user_type
              properties:
                name:
                  type: string
                  nullable: true
                  description: Nombre o razón social del partner
                identification:
                  type: string
                  nullable: true
                  description: RIF del partner
                contact_email:
                  type: string
                  format: email
                  description: Correo electrónico del partner.
                contact_phone:
                  type: string
                  description: Teléfono del partner.
                bank_code:
                  type: string
                  nullable: false
                  description: >-
                    Código del banco. Solo acepta 3–4 dígitos (p.ej., 105 o
                    0137).
                payment_phone_or_cnta:
                  type: string
                  description: Teléfono o número de cuenta para el pago.
                user_type:
                  type: string
                  description: Tipo de usuario.
                  enum:
                    - personal
                    - comercial
      responses:
        '201':
          description: Partner creado exitosamente.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    nullable: false
                    description: >-
                      Indica si la operación fue exitosa. True si el endpoint se
                      procesó de forma exitosa. False de lo contrario
                    example: true
                  message:
                    type: string
                    nullable: true
                    description: Mensaje de confirmación o error legible.
                  data:
                    type: object
                    properties:
                      partner_id:
                        type: string
                        format: uuid
                        description: Identificador único del partner.
                      short_name:
                        type: string
                        description: >-
                          Nombre corto del partner. Se genera automáticamente a
                          partir del owner que lo crea seguido de p1 p2 p3 etc
                      name:
                        type: string
                        nullable: true
                        description: Nombre o razón social del partner
                      identification:
                        type: string
                        nullable: true
                        description: RIF del partner
                      email:
                        type: string
                        format: email
                        description: Correo electrónico del partner.
                      phone:
                        type: string
                        description: Teléfono del partner.
                      user_type:
                        type: string
                        description: Tipo de usuario.
                        enum:
                          - personal
                          - comercial
                      bank_account_id:
                        type: string
                        format: uuid
                        description: >-
                          Identificador único de la cuenta bancaria en nuestros
                          sistemas.
                      split_recipient_agreement_id:
                        type: string
                        nullable: false
                        format: uuid
                        description: >-
                          UUID global SPIDI del agreement de recepción. Este ID
                          se usará en acuerdos de distribución para identificar
                          al receptor del split. (Requerido en distribution)
              example:
                success: true
                message: Partner created successfully
                data:
                  partner_id: cc3014e7-f7ea-427d-8f2f-f38592786e58
                  short_name: miempresa_p2
                  name: Mi Empresa
                  identification: J123456789
                  email: mi empresa
                  phone: '04992362571'
                  user_type: comercial
                  bank_account_id: 22086f69-076e-4592-a06c-33995afd7bba
                  split_recipient_agreement_id: rcv_859f0e4f694f5f5a
  /api/v1/ext/payment-sessions/buttons:
    post:
      summary: Crear Sesión
      description: >-
        Permite crear una **sesión de pago** a través del botón de pago de
        SPIDI.Incluye el `agreement_id` para determinar las reglas de
        **liquidación** y **split**.
      operationId: createPaymentSessionButton
      tags:
        - Endpoints Botón
      security:
        - bearerAuth: []
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - agreement_id
                - amount_reference
                - currency_reference
                - identifier_label
                - identifier
                - description
                - success_url
                - failure_url
              properties:
                agreement_id:
                  type: string
                  format: uuid
                  nullable: true
                  description: >-
                    Identificador único del acuerdo de liquidación. Debe ser
                    UUID v4. 
                amount_reference:
                  description: >-
                    Monto de referencia en la moneda especificada en
                    currencyReference con 2 decimales.
                  type: number
                  nullable: false
                  format: double
                  example: '100.001'
                currency_reference:
                  type: string
                  nullable: false
                  enum:
                    - USD
                    - EUR
                    - COP
                    - USDT
                    - VES
                  description: >-
                    Moneda de referencia que se fija para el pago. Usada para
                    calcular el monto en bolívares con la tasa vigente.
                identifier_label:
                  type: string
                  nullable: true
                  description: >-
                    Etiqueta que indica cómo debe interpretarse el valor enviado
                    en identifier (ej. 'Nro de orden').
                identifier:
                  type: string
                  nullable: false
                  description: >-
                    Identificador del pagador, interpretado según el valor de
                    identifier_label. Ejemplo: Nro de orden, Nombre, etc.
                description:
                  type: string
                  nullable: true
                  description: >-
                    Descripción del acuerdo o del concepto de pago asociado a
                    una sesión.
                  maxLength: 500
                success_url:
                  type: string
                  nullable: true
                  format: uri
                  description: >-
                    URL de redirección que se utiliza cuando un intento de pago
                    es exitoso.
                  pattern: ^[a-z1-9]+://[^\s]*$
                failure_url:
                  type: string
                  nullable: true
                  format: uri
                  description: >-
                    URL de redirección que se utiliza cuando un intento de pago
                    falle. 
                  pattern: ^[a-z1-9]+://[^\s]*$
                webhook_url:
                  type: string
                  nullable: true
                  format: uri
                  description: 'URL para recibir notificaciones de webhook. '
                split:
                  type: object
                  nullable: true
                  description: >-
                    Configuración de división de pagos (Request) / Eco del
                    request del split (Response).
                  properties:
                    document:
                      type: object
                      nullable: true
                      description: >-
                        Información del documento proporcionado por el owner a
                        los partners para dejar evidencia del split.


                        **Notas importantes:**

                        - Esta información **no implica cálculo fiscal** por
                        parte de SPIDI; es solo comunicación entre owner y
                        partners.

                        - `splitDocument_url` puede ser público con hash o una
                        URL autenticada.

                        - SPIDI **no interpreta ni calcula IVA** a partir de
                        esta información; solo lo transporta.
                      properties:
                        name:
                          type: string
                          nullable: true
                          description: >-
                            Nombre del documento asociado a la transacción split
                            (por ejemplo: factura/recibo/contrato
                            D001-00045678).
                        type:
                          type: string
                          nullable: true
                          description: >-
                            Formato libre del owner donde especifica el tipo de
                            documento.
                          examples:
                            - Factura
                            - Contrato
                            - Recibo
                        date:
                          type: string
                          nullable: true
                          format: date
                          description: >-
                            Fecha de emisión del documento en formato ISO 8601
                            (YYYY-MM-DD).
                        url:
                          type: string
                          nullable: true
                          format: uri
                          description: >-
                            Enlace para visualizar/descargar el documento del
                            split. Puede ser público con hash o una URL
                            autenticada.
                        observations:
                          type: string
                          nullable: true
                          maxLength: 500
                          description: >-
                            Observaciones libres del owner (máx. 500
                            caracteres).
                    distribution:
                      type: array
                      nullable: false
                      description: >-
                        Lista de reglas/destinatarios del split. Debe tener ≥ 1
                        ítem. La suma de amount_reference debe ser menor al
                        amount total de la sesión, porque la diferencia restante
                        se asigna automáticamente al owner, quien siempre debe
                        recibir una parte del pago. (Requerido cuando
                        split=true)
                      items:
                        type: object
                        required:
                          - split_recipient_agreement_id
                          - amount_reference
                          - observations
                        properties:
                          split_recipient_agreement_id:
                            type: string
                            nullable: false
                            format: uuid
                            description: >-
                              UUID global SPIDI del agreement de recepción. Este
                              ID se usará en acuerdos de distribución para
                              identificar al receptor del split. (Requerido en
                              distribution)
                          label:
                            type: string
                            nullable: true
                            description: >-
                              Etiqueta descriptiva del receptor en un split.
                              (Opcional en distribution, Eco del request: sí)
                          amount_reference:
                            description: >-
                              Monto de referencia en la moneda especificada en
                              currencyReference con 2 decimales.
                            type: number
                            nullable: false
                            format: double
                            example: '100.001'
                          observations:
                            type: string
                            nullable: false
                            maxLength: 500
                            description: >-
                              Mensaje libre para el partner (máx. 500
                              caracteres). (Requerido en distribution, Eco del
                              request: sí)
                config:
                  type: array
                  description: >-
                    Configuración dinámica opcional para personalizar la
                    experiencia comercial del botón de pago.
                  items:
                    type: object
                    properties:
                      type:
                        type: string
                        description: >-
                          Identificador de la configuración a aplicar. Por
                          ejemplo, 'initial_currency' sirve para priorizar qué
                          método de pago (fiat o cripto) se muestra por defecto
                          al usuario.
                      value:
                        description: >-
                          Valor asociado a la configuración. Para
                          'initial_currency', debe seguir el estándar ISO 4217
                          para monedas fiduciarias o 'CRYPTO' para activos
                          digitales.
                        enum:
                          - VES
                          - CRYPTO
                    required:
                      - type
                      - value
                    example:
                      type: initial_currency
                      value: CRYPTO
                duration_minutes:
                  type: integer
                  nullable: true
                  description: Duración en minutos de la sesión.
                  minimum: 5
                  maximum: 20
                  example: 5
            examples:
              Sin Split:
                summary: Sesión sin Split con duración de 5 minutos
                value:
                  agreement_id: '2432434'
                  amount_reference: 50
                  currency_reference: USD
                  identifier_label: Nombre del cliente
                  identifier: Juan Pérez
                  description: Pago de membresía
                  success_url: https://miapp.com/pago-exitoso
                  failure_url: https://miapp.com/pago-fallido
                  webhook_url: https://miapi.com/spidi/webhook
                  duration_minutes: 5
              Con Split:
                summary: Sesión con Split
                value:
                  currency_reference: USD
                  amount_reference: 30
                  agreement_id: stl_session_01
                  identifier_label: Nombre del cliente
                  identifier: Juan Pérez
                  description: Pago de servicio de internet
                  success_url: miapp://pago/exitoso
                  failure_url: miapp://pago/fallido
                  webhook_url: https://miapi.com/spidi/webhook
                  split:
                    document:
                      document_name: D001-00045678
                      document_type: Factura
                      document_date: '2025-10-20'
                      document_url: https://owner.com/document/D001-00045678
                      document_observations: any observation to owner
                    distribution:
                      - split_recipient_agreement_id: rcv_014…723c1a2
                        label: Partner 1
                        amount_reference: 10
                        observations: any observation to communicate to Partner 1
                      - split_recipient_agreement_id: rcv_016…112dde3
                        label: Partner 2
                        amount_reference: 20
                        observations: any observation to communicate to Partner 2
              Priorización Cripto:
                summary: Sesión con Priorización de Interfaz (Cripto)
                value:
                  agreement_id: '2432434'
                  amount_reference: 50
                  currency_reference: USD
                  identifier_label: Nombre del cliente
                  identifier: Juan Pérez
                  description: Pago con preferencia en activos digitales
                  success_url: https://miapp.com/pago-exitoso
                  failure_url: https://miapp.com/pago-fallido
                  webhook_url: https://miapi.com/spidi/webhook
                  config:
                    - type: initial_currency
                      value: CRYPTO
      responses:
        '200':
          description: Sesión de pago creada exitosamente
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                  - data
                properties:
                  success:
                    type: boolean
                    nullable: false
                    description: >-
                      Indica si la operación fue exitosa. True si el endpoint se
                      procesó de forma exitosa. False de lo contrario
                    example: true
                  message:
                    type: string
                    example: Payment session created successfully.
                    description: Mensaje de confirmación de la creación.
                  data:
                    type: object
                    required:
                      - session_id
                      - session_origin
                      - payment_url
                      - currency_reference
                      - amount_reference
                      - identifier_label
                      - identifier
                      - description
                      - success_url
                      - failure_url
                      - created_at
                    properties:
                      session_id:
                        type: string
                        nullable: false
                        description: >-
                          Identificador único de la sesión de pago, accedible a
                          través del payment_url.
                      session_origin:
                        type: string
                        nullable: false
                        enum:
                          - button
                          - request
                        description: >-
                          Origen de la sesión: 'button' (Botón de pago) o
                          'request' (Solicitud SPIDI).
                      payment_url:
                        type: string
                        nullable: true
                        description: >-
                          URL de la página segura SPIDI donde quien paga realiza
                          el pago.
                        example: '{{base_url}}/?id=3ddc4cfb-c09a-43de-92c1-e4a069732e90'
                      currency_reference:
                        type: string
                        nullable: false
                        enum:
                          - USD
                          - EUR
                          - COP
                          - USDT
                          - VES
                        description: >-
                          Moneda de referencia que se fija para el pago. Usada
                          para calcular el monto en bolívares con la tasa
                          vigente.
                      amount_reference:
                        description: >-
                          Monto de referencia en la moneda especificada en
                          currencyReference con 2 decimales.
                        type: number
                        nullable: false
                        format: double
                        example: '100.001'
                      identifier_label:
                        type: string
                        nullable: true
                        description: >-
                          Etiqueta que indica cómo debe interpretarse el valor
                          enviado en identifier (ej. 'Nro de orden').
                      identifier:
                        type: string
                        nullable: false
                        description: >-
                          Identificador del pagador, interpretado según el valor
                          de identifier_label. Ejemplo: Nro de orden, Nombre,
                          etc.
                      description:
                        type: string
                        nullable: true
                        description: >-
                          Descripción del acuerdo o del concepto de pago
                          asociado a una sesión.
                        maxLength: 500
                      success_url:
                        type: string
                        nullable: true
                        format: uri
                        description: >-
                          URL de redirección que se utiliza cuando un intento de
                          pago es exitoso.
                        pattern: ^[a-z1-9]+://[^\s]*$
                      failure_url:
                        type: string
                        nullable: true
                        format: uri
                        description: >-
                          URL de redirección que se utiliza cuando un intento de
                          pago falle. 
                        pattern: ^[a-z1-9]+://[^\s]*$
                      webhook_url:
                        type: string
                        nullable: true
                        format: uri
                        description: 'URL para recibir notificaciones de webhook. '
                      created_at:
                        type: string
                        nullable: true
                        format: date-time
                        description: >-
                          Fecha y hora de creación del recurso en formato ISO
                          8601.
                      split:
                        type: object
                        nullable: true
                        description: >-
                          Configuración de división de pagos (Request) / Eco del
                          request del split (Response).
                        properties:
                          document:
                            type: object
                            nullable: true
                            description: >-
                              Información del documento proporcionado por el
                              owner a los partners para dejar evidencia del
                              split.


                              **Notas importantes:**

                              - Esta información **no implica cálculo fiscal**
                              por parte de SPIDI; es solo comunicación entre
                              owner y partners.

                              - `splitDocument_url` puede ser público con hash o
                              una URL autenticada.

                              - SPIDI **no interpreta ni calcula IVA** a partir
                              de esta información; solo lo transporta.
                            properties:
                              name:
                                type: string
                                nullable: true
                                description: >-
                                  Nombre del documento asociado a la transacción
                                  split (por ejemplo: factura/recibo/contrato
                                  D001-00045678).
                              type:
                                type: string
                                nullable: true
                                description: >-
                                  Formato libre del owner donde especifica el
                                  tipo de documento.
                                examples:
                                  - Factura
                                  - Contrato
                                  - Recibo
                              date:
                                type: string
                                nullable: true
                                format: date
                                description: >-
                                  Fecha de emisión del documento en formato ISO
                                  8601 (YYYY-MM-DD).
                              url:
                                type: string
                                nullable: true
                                format: uri
                                description: >-
                                  Enlace para visualizar/descargar el documento
                                  del split. Puede ser público con hash o una
                                  URL autenticada.
                              observations:
                                type: string
                                nullable: true
                                maxLength: 500
                                description: >-
                                  Observaciones libres del owner (máx. 500
                                  caracteres).
                          distribution:
                            type: array
                            nullable: false
                            description: >-
                              Lista de reglas/destinatarios del split. Debe
                              tener ≥ 1 ítem. La suma de amount_reference debe
                              ser menor al amount total de la sesión, porque la
                              diferencia restante se asigna automáticamente al
                              owner, quien siempre debe recibir una parte del
                              pago. (Requerido cuando split=true)
                            items:
                              type: object
                              required:
                                - split_recipient_agreement_id
                                - amount_reference
                                - observations
                              properties:
                                split_recipient_agreement_id:
                                  type: string
                                  nullable: false
                                  format: uuid
                                  description: >-
                                    UUID global SPIDI del agreement de
                                    recepción. Este ID se usará en acuerdos de
                                    distribución para identificar al receptor
                                    del split. (Requerido en distribution)
                                label:
                                  type: string
                                  nullable: true
                                  description: >-
                                    Etiqueta descriptiva del receptor en un
                                    split. (Opcional en distribution, Eco del
                                    request: sí)
                                amount_reference:
                                  description: >-
                                    Monto de referencia en la moneda
                                    especificada en currencyReference con 2
                                    decimales.
                                  type: number
                                  nullable: false
                                  format: double
                                  example: '100.001'
                                observations:
                                  type: string
                                  nullable: false
                                  maxLength: 500
                                  description: >-
                                    Mensaje libre para el partner (máx. 500
                                    caracteres). (Requerido en distribution, Eco
                                    del request: sí)
              examples:
                Sin Split:
                  summary: Response - Sin Split
                  value:
                    success: true
                    message: Payment session created successfully.
                    data:
                      session_id: 3ddc4cfb-c09a-43de-92c1-e4a069732e90
                      session_origin: button
                      payment_url: '{{base_url}}/?id=3ddc4cfb-c09a-43de-92c1-e4a069732e90'
                      currency_reference: USD
                      amount_reference: 50
                      identifier_label: Nombre del cliente
                      identifier: Juan Pérez
                      description: Pago de membresía
                      success_url: https://miapp.com/pago-exitoso
                      failure_url: https://miapp.com/pago-fallido
                      webhook_url: https://miapi.com/spidi/webhook
                      created_at: '2025-10-13T14:10:00Z'
                Con Split:
                  summary: Response - Con Split
                  value:
                    success: true
                    message: Payment session created successfully.
                    data:
                      session_id: 3ddc4cfb-c09a-43de-92c1-e4a069732e90
                      session_origin: button
                      payment_url: '{{base_url}}/?id=3ddc4cfb-c09a-43de-92c1-e4a069732e90'
                      currency_reference: USD
                      amount_reference: 30
                      identifier_label: Nombre del cliente
                      identifier: Juan Pérez
                      description: Pago de membresía
                      success_url: https://miapp.com/pago-exitoso
                      failure_url: https://miapp.com/pago-fallido
                      webhook_url: https://miapi.com/spidi/webhook
                      created_at: '2025-10-13T14:10:00Z'
                      split:
                        document:
                          document_name: D001-00045678
                          document_type: Factura
                          document_date: '2025-10-20'
                          document_url: https://owner.com/document/D001-00045678
                          document_observations: any observation to owner
                        distribution:
                          - split_recipient_agreement_id: rcv_014…723c1a2
                            label: Partner 1
                            amount_reference: 10
                            observations: any observation to communicate to Partner 1
                          - split_recipient_agreement_id: rcv_016…112dde3
                            label: Partner 2
                            amount_reference: 20
                            observations: any observation to communicate to Partner 2
                Priorización Cripto:
                  summary: Response - Con Priorización Cripto
                  value:
                    success: true
                    message: Payment session created successfully.
                    data:
                      session_id: 3ddc4cfb-c09a-43de-92c1-e4a069732e90
                      session_origin: button
                      payment_url: '{{base_url}}/?id=3ddc4cfb-c09a-43de-92c1-e4a069732e90'
                      currency_reference: USD
                      amount_reference: 50
                      identifier_label: Nombre del cliente
                      identifier: Juan Pérez
                      description: Pago con preferencia en activos digitales
                      success_url: https://miapp.com/pago-exitoso
                      failure_url: https://miapp.com/pago-fallido
                      webhook_url: https://miapi.com/spidi/webhook
                      created_at: '2025-10-13T14:10:00Z'
                      config:
                        - type: initial_currency
                          value: CRYPTO
        '400':
          description: Solicitud inválida - Parámetros incorrectos
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    example: false
                    description: Indica si la operación fue exitosa.
                  message:
                    type: string
                    example: Invalid request parameters
                    description: Mensaje descriptivo del error.
                  errors:
                    type: object
                    nullable: true
                    description: Detalles específicos de los errores de validación.
                    properties:
                      agreement_id:
                        type: string
                        example: agreement ID is required
                        description: Error relacionado con el campo agreement_id.
                      amount_reference:
                        type: string
                        example: Amount must be greater than 0
                        description: Error relacionado con el campo amount_reference.
                      authorization:
                        type: string
                        example: Invalid or missing Bearer token
                        description: Error de autorización.
                      idempotency_key:
                        type: string
                        example: This idempotency key has already been used
                        description: Error relacionado con la clave de idempotencia.
                      field:
                        type: string
                        example: Invalid field value
                        description: Error genérico de campo.
              example:
                success: false
                message: Invalid request parameters
                errors:
                  agreement_id: agreement ID is required
                  amount_reference: Amount must be greater than 0
        '401':
          description: No autorizado - Token inválido o faltante
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    example: false
                    description: Indica si la operación fue exitosa.
                  message:
                    type: string
                    example: Invalid request parameters
                    description: Mensaje descriptivo del error.
                  errors:
                    type: object
                    nullable: true
                    description: Detalles específicos de los errores de validación.
                    properties:
                      agreement_id:
                        type: string
                        example: agreement ID is required
                        description: Error relacionado con el campo agreement_id.
                      amount_reference:
                        type: string
                        example: Amount must be greater than 0
                        description: Error relacionado con el campo amount_reference.
                      authorization:
                        type: string
                        example: Invalid or missing Bearer token
                        description: Error de autorización.
                      idempotency_key:
                        type: string
                        example: This idempotency key has already been used
                        description: Error relacionado con la clave de idempotencia.
                      field:
                        type: string
                        example: Invalid field value
                        description: Error genérico de campo.
              example:
                success: false
                message: Unauthorized access
                errors:
                  authorization: Invalid or missing Bearer token
        '422':
          description: Entidad no procesable - Clave de idempotencia ya utilizada
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    example: false
                    description: Indica si la operación fue exitosa.
                  message:
                    type: string
                    example: Invalid request parameters
                    description: Mensaje descriptivo del error.
                  errors:
                    type: object
                    nullable: true
                    description: Detalles específicos de los errores de validación.
                    properties:
                      agreement_id:
                        type: string
                        example: agreement ID is required
                        description: Error relacionado con el campo agreement_id.
                      amount_reference:
                        type: string
                        example: Amount must be greater than 0
                        description: Error relacionado con el campo amount_reference.
                      authorization:
                        type: string
                        example: Invalid or missing Bearer token
                        description: Error de autorización.
                      idempotency_key:
                        type: string
                        example: This idempotency key has already been used
                        description: Error relacionado con la clave de idempotencia.
                      field:
                        type: string
                        example: Invalid field value
                        description: Error genérico de campo.
              example:
                success: false
                message: Idempotency key already used
                errors:
                  idempotency_key: This idempotency key has already been used
        '500':
          description: Error interno del servidor
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    example: false
                    description: Indica si la operación fue exitosa.
                  message:
                    type: string
                    example: Invalid request parameters
                    description: Mensaje descriptivo del error.
                  errors:
                    type: object
                    nullable: true
                    description: Detalles específicos de los errores de validación.
                    properties:
                      agreement_id:
                        type: string
                        example: agreement ID is required
                        description: Error relacionado con el campo agreement_id.
                      amount_reference:
                        type: string
                        example: Amount must be greater than 0
                        description: Error relacionado con el campo amount_reference.
                      authorization:
                        type: string
                        example: Invalid or missing Bearer token
                        description: Error de autorización.
                      idempotency_key:
                        type: string
                        example: This idempotency key has already been used
                        description: Error relacionado con la clave de idempotencia.
                      field:
                        type: string
                        example: Invalid field value
                        description: Error genérico de campo.
              example:
                success: false
                message: Internal server error
  /api/v1/ext/payment-sessions/status/{session_id}:
    get:
      summary: Consultar Sesión
      description: >-
        Este endpoint permite consultar el estado actual de una sesión de pago y
        sus datos esenciales, generada mediante una solicitud de pago o botón de
        pago.


        Este endpoint es la fuente oficial y confiable para verificar si la
        sesión de pago fue completada con éxito (`paid`), rechazada (`failed`),
        expirada (`expired`) o está pendiente (`pending`).


        ### Origen de la Sesión


        Una sesión de pago puede crearse mediante un **Botón de pago** o una
        **Solicitud de pago**, cada una con su propio endpoint de creación. Sin
        embargo, para **consultar** una sesión de pago —sin importar cómo haya
        sido creada— se utiliza **el mismo endpoint** de consulta. En la
        respuesta, existe un campo `session_origin` que revelará si fue creada
        por botón de pago (`button`) o por solicitud (`request`).


        En los casos donde la sesión fue creada a través de un **Botón de
        pago**, el campo `status` puede tener un valor adicional: `failed`.


        ## Notas Importantes


        ### Verificación de Pagos (Backend Obligatorio)


        **No asumas `paid` solo por redirección**; **consulta este endpoint**
        desde tu servidor antes de liberar servicios o productos.


        ### Liquidación al Receptor


        Tras `paid`, la liquidación al receptor puede tardar unos segundos; en
        ese caso `receiver_credits` y `receiver_credits_summary` pueden venir
        `null` temporalmente. 


        **Independientemente de si la liquidación al receptor aún no ha
        ocurrido**, se considera en todo su concepto amplio que el pago fue
        realizado exitosamente, por lo que se debe continuar con la entrega del
        servicio o producto sin ningún problema.


        La liquidación al receptor es un proceso interno y, aunque puede demorar
        pocos segundos o hasta 2 minutos, no existe riesgo de fallo. En los
        términos y condiciones se especifica esta garantía, que constituye un
        derecho causado e irrevocable según los términos acordados.


        **Por lo tanto**: En caso de que tengas control, **no retengas ni
        retrases** la prestación del servicio al pagador mientras esperas la
        liquidación.


        ### Consulta de Datos de Liquidación


        Si necesitas mostrar o procesar datos de la liquidación, consulta el
        endpoint de status periódicamente hasta que los campos de
        `receiver_credits` estén presentes. 


        Opcionalmente, si implementaste un **webhook**, recibirás una
        notificación automática en tu API cuando la liquidación se haya
        completado y los datos estén disponibles (eventos `payment.paid` /
        `payment.settled`).


        ### URL del Comprobante


        Recuerda que se incluye el URL del comprobante exitoso
        (`spidi_transaction_url`), que debe ser mostrado al usuario de una forma
        u otra.


        ## Pagos con Criptomonedas


        - Si `payment_method` es `"crypto"`, el objeto `crypto_details`
        contendrá información específica del pago cripto

        - Si `payment_method` es distinto a `"crypto"`, entonces
        `crypto_details` será `null`

        - En caso de pago con crypto, si está en `"paid_pending"`, entonces los
        objetos `payment_details`, `receiver_credits` y
        `receiver_credits_summary` estarán presentes con valores `null`


        ## Split de Pagos


        - Si no se generó un split, entonces el objeto de `receiver_credits`
        tiene un solo elemento

        - Si existió el split, deben haber al menos dos elementos en
        `receiver_credits`


        ## Estados Vigentes


        - `pending`: Sesión creada, esperando que el usuario complete el pago

        - `paid`: Pago completado exitosamente

        - `expired`: Sesión expirada por inactividad o manualmente

        - `failed`: Pago fallido (solo para sesiones creadas con botón de pago)
      operationId: getPaymentSessionStatus
      tags:
        - Endpoints Botón
        - Endpoints Solicitud
      security:
        - bearerAuth: []
      parameters:
        - name: session_id
          in: path
          description: ID de la sesión de pago generada
          required: true
          schema:
            type: string
            format: uuid
            example: 3ddc4cfb-c09a-43de-92c1-e4a069732e90
      responses:
        '200':
          description: Consulta exitosa del estado de la sesión
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                  - data
                properties:
                  success:
                    type: boolean
                    nullable: false
                    description: >-
                      Indica si la operación fue exitosa. True si el endpoint se
                      procesó de forma exitosa. False de lo contrario
                    example: true
                  message:
                    type: string
                    example: Successful query.
                    description: Mensaje de confirmación de la consulta.
                  data:
                    type: object
                    required:
                      - session_id
                      - session_origin
                      - agreement_id
                      - status
                      - currency_reference
                      - amount_reference
                      - identifier_label
                      - identifier
                      - description
                      - created_at
                      - session_payment
                    properties:
                      session_id:
                        type: string
                        nullable: false
                        description: >-
                          Identificador único de la sesión de pago, accedible a
                          través del payment_url.
                      session_origin:
                        type: string
                        nullable: false
                        enum:
                          - button
                          - request
                        description: >-
                          Origen de la sesión: 'button' (Botón de pago) o
                          'request' (Solicitud SPIDI).
                      agreement_id:
                        type: string
                        format: uuid
                        nullable: true
                        description: >-
                          Identificador único del acuerdo de liquidación. Debe
                          ser UUID v4. 
                      status:
                        type: string
                        nullable: false
                        enum:
                          - pending
                          - paid
                          - failed
                          - expired
                        description: >-
                          Estado actual de la sesión. El valor failed solo se
                          aplica para sesiones creadas con botón de pago.
                      currency_reference:
                        type: string
                        nullable: false
                        enum:
                          - USD
                          - EUR
                          - COP
                          - USDT
                          - VES
                        description: >-
                          Moneda de referencia que se fija para el pago. Usada
                          para calcular el monto en bolívares con la tasa
                          vigente.
                      amount_reference:
                        description: >-
                          Monto de referencia en la moneda especificada en
                          currencyReference con 2 decimales.
                        type: number
                        nullable: false
                        format: double
                        example: '100.001'
                      identifier_label:
                        type: string
                        nullable: true
                        description: >-
                          Etiqueta que indica cómo debe interpretarse el valor
                          enviado en identifier (ej. 'Nro de orden').
                      identifier:
                        type: string
                        nullable: false
                        description: >-
                          Identificador del pagador, interpretado según el valor
                          de identifier_label. Ejemplo: Nro de orden, Nombre,
                          etc.
                      description:
                        type: string
                        nullable: true
                        description: >-
                          Descripción del acuerdo o del concepto de pago
                          asociado a una sesión.
                        maxLength: 500
                      created_at:
                        type: string
                        nullable: true
                        format: date-time
                        description: >-
                          Fecha y hora de creación del recurso en formato ISO
                          8601.
                      session_payment:
                        type: object
                        nullable: true
                        description: Detalles del pago y estado de la sesión.
                        properties:
                          payment_method:
                            type: string
                            description: >-
                              Método de pago: "crypto", "immediate_debit" o
                              "mobile_payment".
                          spidi_transaction_id:
                            type: integer
                            nullable: true
                            description: >-
                              ID de la transacción en Spidi (null si no se ha
                              completado).
                          spidi_transaction_url:
                            type: string
                            nullable: true
                            description: >-
                              URL del comprobante de pago (null si no se ha
                              completado).
                          due_date_session:
                            type: string
                            description: Fecha límite para completar el pago (ISO 8601).
                          due_date_reached_behavior:
                            type: string
                            description: >-
                              Comportamiento al expirar: "keep_active" o
                              "expire".
                          late_notice_message:
                            type: string
                            description: Mensaje para mostrar cuando el pago está atrasado.
                          expired_at:
                            type: string
                            description: Fecha hora ISO 8601 de la expiración más reciente.
                          last_expired_by:
                            type: string
                            nullable: true
                            enum:
                              - api
                              - system
                            description: 'Origen de la expiración: api o system.'
                          reason:
                            type: string
                            nullable: true
                            enum:
                              - api
                              - system
                            description: 'Origen de la expiración: api o system.'
                          user_message:
                            type: string
                            description: Último Mensaje para el usuario.
                          crypto_details:
                            type: object
                            nullable: true
                            description: >-
                              Detalles de pago con criptomonedas (null si no
                              aplica).
                            properties:
                              provider_name:
                                type: string
                                nullable: true
                                description: >-
                                  Nombre de la entidad o plataforma financiera
                                  que custodia los activos del usuario.
                                  Representa el ecosistema o 'banco digital'
                                  donde reside el saldo original (ej. Binance,
                                  Crixto).
                                examples:
                                  - Binance
                                  - Crixto
                              crypto_order_id:
                                type: string
                                nullable: true
                                description: >-
                                  Identificador de la orden cripto generada por
                                  el proveedor.
                              payment_method_name:
                                type: string
                                description: >-
                                  Nombre del método de pago (ej. Binance Pay,
                                  Crixto Pay).
                                examples:
                                  - Binance Pay
                                  - Crixto Pay
                              amount_transaction_ves:
                                type: number
                                format: double
                                nullable: true
                                description: >-
                                  Monto con 3 decimales de la transacción en la
                                  moneda VES. Note que es el monto original sin
                                  incluir la comisión por el pago.
                                example: 157.783
                              amount_pay_by_user_crypto:
                                type: number
                                format: double
                                nullable: true
                                description: >-
                                  Monto con 3 decimales del pago realizado por
                                  el usuario en la moneda cripto. Note que puede
                                  variar del monto original si se aplica una
                                  comisión por el pago.
                                example: 157.783
                              currency_crypto:
                                type: string
                                nullable: true
                                description: >-
                                  Moneda cripto utilizada en el pago (por
                                  ejemplo, USDT).
                                enum:
                                  - USDT
                              exchange_rate:
                                type: number
                                format: double
                                description: >-
                                  Tasa Cripto/Fiat usada durante la conversión
                                  de cripto-fiat, especificada 4 decimales
                                example: 157.7837
                              paid_at:
                                type: string
                                nullable: true
                                format: date-time
                                description: >-
                                  Fecha y hora en que se confirmó el pago
                                  cripto, en formato ISO 8601.
                          payment_details:
                            type: object
                            nullable: true
                            description: Detalles del pago bancario (null si no aplica).
                            properties:
                              action_date:
                                type: string
                                format: date-time
                                nullable: true
                                description: >-
                                  Fecha y hora de la acción del pagador, en
                                  formato ISO 8601 con sufijo Z (UTC).
                              bank_name:
                                type: string
                                nullable: true
                                description: >-
                                  Nombre comercial del banco. Eco del request:
                                  no.
                              bank_reference_id:
                                type: string
                                nullable: true
                                description: >-
                                  Referencia bancaria del pago. Eco del request:
                                  no.
                              amount_ves:
                                type: number
                                description: Monto en bolívares con 2 decimales.
                                format: double
                              bcv_rate_usd_ves:
                                type: number
                                nullable: true
                                format: decimal(10,4)
                                description: >-
                                  Tasa oficial BCV de USD a VES usada en el
                                  cálculo del monto en bolívares. Eco del
                                  request: no.
                              bcv_rate_eur_ves:
                                type: number
                                nullable: true
                                format: decimal(10,4)
                                description: >-
                                  Tasa oficial BCV de EUR a VES usada en el
                                  cálculo del monto en bolívares. Eco del
                                  request: no.
                              rate_usdt_ves:
                                type: number
                                format: decimal(10,4)
                                nullable: true
                                description: Tasa de cambio USDT a VES.
                              rate_col_ves:
                                type: number
                                format: decimal(10,4)
                                nullable: true
                                description: Tasa de cambio COP a VES.
                          receiver_credits:
                            type: object
                            nullable: true
                            description: >-
                              Detalles de la liquidación de créditos (Owner y
                              Partners).
                            properties:
                              owner:
                                type: object
                                description: >-
                                  Crédito asignado al dueño de la cuenta
                                  principal.
                                properties:
                                  receiver_id:
                                    type: string
                                    nullable: true
                                    description: Identificador del receptor del crédito.
                                  memo:
                                    type: string
                                    nullable: true
                                    description: Nota o referencia interna para el crédito.
                                  spidi_credit_id:
                                    type: string
                                    nullable: true
                                    description: ID de la liquidación al receptor del pago.
                                  amount_ves_credited:
                                    type: number
                                    nullable: true
                                    description: >-
                                      Monto neto acreditado al receptor en
                                      bolívares, luego de aplicar las comisiones
                                      correspondientes. Siempre tiene 2
                                      decimales.
                                    format: double
                                    example: '100.01'
                                  bank_commissions_ves:
                                    type: number
                                    nullable: true
                                    format: decimal(12,2)
                                    description: >-
                                      Comisión bancaria total cobrada en
                                      bolívares para la liquidación. Eco del
                                      request: no.
                                  receive_date:
                                    type: string
                                    format: date-time
                                    nullable: true
                                    description: >-
                                      Fecha y hora en que se acreditó el pago
                                      (ISO 8601).
                                  bank_name:
                                    type: string
                                    nullable: true
                                    description: >-
                                      Nombre comercial del banco. Eco del
                                      request: no.
                                  bank_reference_id:
                                    type: string
                                    nullable: true
                                    description: >-
                                      Referencia bancaria del pago. Eco del
                                      request: no.
                              partners:
                                type: array
                                nullable: true
                                description: >-
                                  Lista de créditos asignados a partners
                                  (split).
                                items:
                                  type: object
                                  properties:
                                    receiver_id:
                                      type: string
                                      nullable: true
                                      description: Identificador del receptor del crédito.
                                    memo:
                                      type: string
                                      nullable: true
                                      description: >-
                                        Nota o referencia interna para el
                                        crédito.
                                    partner_rif_name:
                                      type: string
                                      nullable: true
                                      description: Nombre o razón social del partner
                                    partner_rif_number:
                                      type: string
                                      nullable: true
                                      description: RIF del partner
                                    split_recipient_agreement_id:
                                      type: string
                                      nullable: false
                                      format: uuid
                                      description: >-
                                        UUID global SPIDI del agreement de
                                        recepción. Este ID se usará en acuerdos
                                        de distribución para identificar al
                                        receptor del split. (Requerido en
                                        distribution)
                                    spidi_credit_id:
                                      type: string
                                      nullable: true
                                      description: >-
                                        ID de la liquidación al receptor del
                                        pago.
                                    amount_ves_credited:
                                      type: number
                                      nullable: true
                                      description: >-
                                        Monto neto acreditado al receptor en
                                        bolívares, luego de aplicar las
                                        comisiones correspondientes. Siempre
                                        tiene 2 decimales.
                                      format: double
                                      example: '100.01'
                                    bank_commissions_ves:
                                      type: number
                                      nullable: true
                                      format: decimal(12,2)
                                      description: >-
                                        Comisión bancaria total cobrada en
                                        bolívares para la liquidación. Eco del
                                        request: no.
                                    receive_date:
                                      type: string
                                      format: date-time
                                      nullable: true
                                      description: >-
                                        Fecha y hora en que se acreditó el pago
                                        (ISO 8601).
                                    bank_name:
                                      type: string
                                      nullable: true
                                      description: >-
                                        Nombre comercial del banco. Eco del
                                        request: no.
                                    bank_reference_id:
                                      type: string
                                      nullable: true
                                      description: >-
                                        Referencia bancaria del pago. Eco del
                                        request: no.
                                    observations:
                                      type: string
                                      nullable: false
                                      maxLength: 500
                                      description: >-
                                        Mensaje libre para el partner (máx. 500
                                        caracteres). (Requerido en distribution,
                                        Eco del request: sí)
                          receiver_credits_summary:
                            type: object
                            nullable: true
                            description: >-
                              Resumen agregado de liquidaciones al o los
                              receptores.
                            properties:
                              total_credits:
                                type: integer
                                nullable: false
                                description: >-
                                  Número total de créditos/liquidaciones
                                  realizados.
                              total_amount_ves_credited:
                                type: number
                                nullable: true
                                format: double
                                description: Monto total acreditado en VES.
                              total_bank_commissions_ves:
                                type: number
                                nullable: true
                                format: double
                                description: Total de comisiones bancarias en VES.
              examples:
                Pago pendiente con botón de pago:
                  summary: 'Status: pending'
                  value:
                    success: true
                    message: Successful query.
                    data:
                      session_id: 3ddc4cfb-c09a-43de-92c1-e4a069732e90
                      session_origin: button
                      agreement_id: c4cfb-c-43deb-c09a-4-92c109a
                      status: pending
                      currency_reference: USD
                      amount_reference: 50.01
                      identifier_label: Nombre y Apellido
                      identifier: Federico Coppola
                      description: ''
                      created_at: '2025-09-18T20:45:00Z'
                      session_payment:
                        user_message: Esperando que completes el pago
                        due_date_session: '2025-10-31T23:59:59Z'
                        due_date_reached_behavior: expire
                        late_notice_message: null
                Pago en tránsito con solicitud de pago:
                  summary: 'Status: paid (liquidación en tránsito)'
                  value:
                    success: true
                    message: Successful query.
                    data:
                      session_id: 3ddc4cfb-c09a-43de-92c1-e4a069732e90
                      session_origin: request
                      agreement_id: c4cfb-c-43deb-c09a-4-92c109a
                      status: paid
                      currency_reference: USD
                      amount_reference: 50
                      identifier_label: Nombre y Apellido
                      identifier: Federico Coppola
                      description: ''
                      created_at: '2025-09-18T20:45:00Z'
                      session_payment:
                        payment_method: immediate_debit
                        spidi_transaction_id: 643
                        spidi_transaction_url: >-
                          https://mispidi.com/success?id=0ff89338-0ba5-4d3f-c999-8aa71e560d4a
                        user_message: Pago exitoso
                        crypto_details: null
                        payment_details:
                          action_date: '2025-09-18T21:00:08Z'
                          bank_name: BANCO PLAZA
                          bank_reference_id: '00001440'
                          amount_ves: 6100.56
                          bcv_rate_usd_ves: 122.0112
                          bcv_rate_eur_ves: 145.2414
                          rate_usdt_ves: 183.1112
                          rate_col_ves: 0.0501
                          paid_via: container
                          paid_origin:
                            container_session_id: 2ac…ff0
                        receiver_credits: null
                        receiver_credits_summary: null
                Pago completado para una solicitud de pago con split:
                  summary: 'Status: paid (liquidación completada)'
                  value:
                    success: true
                    message: Successful query.
                    data:
                      session_id: 3ddc4cfb-c09a-43de-92c1-e4a069732e90
                      session_origin: request
                      agreement_id: c4cfb-c-43deb-c09a-4-92c109a
                      status: paid
                      currency_reference: USD
                      amount_reference: 50.01
                      identifier_label: Nombre y Apellido
                      identifier: Federico Coppola
                      description: ''
                      created_at: '2025-09-18T20:45:00Z'
                      session_payment:
                        payment_method: immediate_debit
                        spidi_transaction_id: 643
                        spidi_transaction_url: >-
                          https://mispidi.com/success?id=0ff89338-0ba5-4d3f-c999-8aa71e560d4a
                        user_message: Pago exitoso
                        crypto_details: null
                        payment_details:
                          action_date: '2025-09-18T21:00:08Z'
                          bank_name: BANCO PLAZA
                          bank_reference_id: '00001440'
                          amount_ves: 6100.56
                          bcv_rate_usd_ves: 122.0112
                          bcv_rate_eur_ves: 145.2414
                          rate_usdt_ves: 183.1112
                          rate_col_ves: 0.0501
                          paid_via: direct
                        receiver_credits:
                          owner:
                            receiver_id: owner
                            memo: propio
                            spidi_credit_id: '1122'
                            amount_ves_credited: 5090.56
                            bank_commissions_ves: 8.01
                            receive_date: '2025-09-18T21:00:10Z'
                            bank_name: BANESCO
                            bank_reference_id: '4555111'
                          partners:
                            - receiver_id: partner_1
                              memo: ''
                              partner_rif_name: Restaurante Los Sabores C.A.
                              partner_rif_number: J-40011223-5
                              split_recipient_agreement_id: rcv_014…723c1a2
                              spidi_credit_id: '1122'
                              amount_ves_credited: 1000.12
                              bank_commissions_ves: 2.32
                              receive_date: '2025-09-18T21:00:10Z'
                              bank_name: BANESCO
                              bank_reference_id: '4555111'
                              observations: any observation to Partner 1
                        receiver_credits_summary:
                          split: true
                          total_credits: 2
                          total_amount_ves_credited: 6090.56
                          total_bank_commissions_ves: 10.3
                          split_general_info:
                            document_name: D001-00045678
                            document_date: '2025-10-20'
                            document_url: https://owner.com/document/F001-00045678
                            document_observations: any observation to owner
                Pago completado para una solicitud de pago sin split:
                  summary: 'Status: paid (liquidación completada sin split)'
                  value:
                    success: true
                    message: Successful query.
                    data:
                      session_id: 3ddc4cfb-c09a-43de-92c1-e4a069732e90
                      session_origin: request
                      agreement_id: c4cfb-c-43deb-c09a-4-92c109a
                      status: paid
                      currency_reference: USD
                      amount_reference: 50.01
                      identifier_label: Nombre y Apellido
                      identifier: Federico Coppola
                      description: ''
                      created_at: '2025-09-18T20:45:00Z'
                      session_payment:
                        payment_method: immediate_debit
                        spidi_transaction_id: 643
                        spidi_transaction_url: >-
                          https://mispidi.com/success?id=0ff89338-0ba5-4d3f-c999-8aa71e560d4a
                        user_message: Pago exitoso
                        crypto_details: null
                        payment_details:
                          action_date: '2025-09-18T21:00:08Z'
                          bank_name: BANCO PLAZA
                          bank_reference_id: '00001440'
                          amount_ves: 6100.56
                          bcv_rate_usd_ves: 122.0112
                          bcv_rate_eur_ves: 145.2414
                          rate_usdt_ves: 183.1112
                          rate_col_ves: 0.0501
                          paid_via: direct
                        receiver_credits:
                          owner:
                            receiver_id: owner
                            memo: propio
                            spidi_credit_id: '1122'
                            amount_ves_credited: 6090.56
                            bank_commissions_ves: 10.02
                            receive_date: '2025-09-18T21:00:10Z'
                            bank_name: BANESCO
                            bank_reference_id: '4555111'
                          partners: []
                        receiver_credits_summary:
                          split: false
                          total_credits: 1
                          total_amount_ves_credited: 6090.56
                          total_bank_commissions_ves: 10.02
                Pago expirado para un botón de pago:
                  summary: 'Status: expired (botón de pago) '
                  value:
                    success: true
                    message: Successful query.
                    data:
                      session_id: 2bbdd70e-1720-44fc-944c-52589d7377b2
                      session_origin: button
                      agreement_id: agr_020c6026d57086b1
                      status: expired
                      currency_reference: VES
                      amount_reference: 5
                      identifier_label: Nombre del cliente
                      identifier: Juan Pérez
                      description: Pago de membresía
                      created_at: '2026-02-22 11:27:21'
                      session_payment:
                        user_message: La sesión expiró por inactividad. Intenta nuevamente.
                        expired_at: '2026-02-22 11:37:21'
                        reason: timeout_expire_due_to_inactivity
                Pago expirado para una solicitud de pago:
                  summary: 'Status: expired'
                  value:
                    success: true
                    message: Successful query.
                    data:
                      session_id: 3ddc4cfb-c09a-43de-92c1-e4a069732e90
                      session_origin: request
                      agreement_id: btn_1024
                      status: expired
                      currency_reference: USD
                      amount_reference: 50.02
                      identifier_label: Nombre y Apellido
                      identifier: Federico Coppola
                      description: ''
                      created_at: '2025-09-18T20:45:00Z'
                      session_payment:
                        user_message: La sesión expiró por inactividad. Intenta nuevamente.
                        expired_at: '2025-10-05T14:22:01Z'
                        reason: manual_expire_due_to_contract_change
                Pago fallido para una solicitud de pago:
                  summary: 'Status: failed'
                  value:
                    success: true
                    message: Successful query.
                    data:
                      session_id: 3ddc4cfb-c09a-43de-92c1-e4a069732e90
                      session_origin: request
                      agreement_id: c4cfb-c-43deb-c09a-4-92c109a
                      status: failed
                      currency_reference: USD
                      amount_reference: 50.02
                      identifier_label: Nombre y Apellido
                      identifier: Federico Coppola
                      description: ''
                      created_at: '2025-09-18T20:45:00Z'
                      session_payment:
                        payment_method: immediate_debit
                        spidi_transaction_id: 643
                        spidi_transaction_url: >-
                          https://mispidi.com/failed?id=a403906c-da54-4724-acc0-db9c91dc11fd
                        user_message: Pago fallido clave errada
                        crypto_details: null
                        payment_details:
                          action_date: '2025-09-18T21:00:08Z'
                          bank_name: BANCO PLAZA
                          bank_reference_id: '00001440'
                          amount_ves: 6100.56
                          bcv_rate_usd_ves: 122.0112
                          bcv_rate_eur_ves: 145.2414
                          rate_usdt_ves: 183.1112
                          rate_col_ves: 0.0501
                Pago con criptomonedas completado para una solicitud de pago:
                  summary: 'Status: paid (pago con criptomonedas)'
                  value:
                    success: true
                    message: Successful query.
                    data:
                      session_id: 3ddc4cfb-c09a-43de-92c1-e4a069732e90
                      session_origin: request
                      agreement_id: c4cfb-c-43deb-c09a-4-92c109a
                      status: paid
                      currency_reference: USD
                      amount_reference: 50.02
                      identifier_label: Nombre y Apellido
                      identifier: Federico Coppola
                      description: ''
                      created_at: '2025-09-18T20:45:00Z'
                      session_payment:
                        payment_method: crypto
                        spidi_transaction_id: 643
                        spidi_transaction_url: >-
                          https://mispidi.com/success?id=0ff89338-0ba5-4d3f-c999-8aa71e560d4a
                        user_message: Pago exitoso
                        crypto_details:
                          provider_name: Crixto
                          crypto_order_id: '1535'
                          payment_method_name: BinancePay
                          currency_crypto: USDT
                          amount_transaction_ves: 635
                          amount_pay_by_user_crypto: 1.015
                          exchange_rate: 635
                          paid_at: '2025-09-18T21:00:08Z'
                        payment_details: null
                        receiver_credits:
                          owner:
                            receiver_id: owner
                            memo: propio
                            spidi_credit_id: '1122'
                            amount_ves_credited: 6090.56
                            bank_commissions_ves: 10.02
                            receive_date: '2025-09-18T21:00:10Z'
                            bank_name: BANESCO
                            bank_reference_id: '4555111'
                          partners: []
                        receiver_credits_summary:
                          total_credits: 1
                          total_amount_ves_credited: 6090.56
                          total_bank_commissions_ves: 10.02
        '400':
          description: Solicitud inválida - Campo faltante
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    example: false
                    description: Indica si la operación fue exitosa.
                  message:
                    type: string
                    example: Session not found.
                    description: Mensaje descriptivo del error.
                  errors:
                    type: object
                    nullable: true
                    description: Detalles específicos de los errores.
                    properties:
                      session_id:
                        type: string
                        example: This field is required.
                        description: Error relacionado con el campo session_id.
                      spidi_id:
                        type: string
                        example: The credentials are incorrect
                        description: Error de autenticación.
                      message:
                        type: string
                        example: No tienes permisos para esta operación
                        description: Mensaje de error genérico.
              example:
                success: false
                message: 'Missing required field: session_id'
                errors:
                  session_id: This field is required.
        '401':
          description: No autorizado - Credenciales incorrectas
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    example: false
                    description: Indica si la operación fue exitosa.
                  message:
                    type: string
                    example: Session not found.
                    description: Mensaje descriptivo del error.
                  errors:
                    type: object
                    nullable: true
                    description: Detalles específicos de los errores.
                    properties:
                      session_id:
                        type: string
                        example: This field is required.
                        description: Error relacionado con el campo session_id.
                      spidi_id:
                        type: string
                        example: The credentials are incorrect
                        description: Error de autenticación.
                      message:
                        type: string
                        example: No tienes permisos para esta operación
                        description: Mensaje de error genérico.
              example:
                success: false
                message: Unauthorized.
                errors:
                  spidi_id: The credentials are incorrect
        '403':
          description: Prohibido - Sin permisos
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    example: false
                    description: Indica si la operación fue exitosa.
                  message:
                    type: string
                    example: Session not found.
                    description: Mensaje descriptivo del error.
                  errors:
                    type: object
                    nullable: true
                    description: Detalles específicos de los errores.
                    properties:
                      session_id:
                        type: string
                        example: This field is required.
                        description: Error relacionado con el campo session_id.
                      spidi_id:
                        type: string
                        example: The credentials are incorrect
                        description: Error de autenticación.
                      message:
                        type: string
                        example: No tienes permisos para esta operación
                        description: Mensaje de error genérico.
              example:
                success: false
                message: Forbidden.
                errors:
                  message: No tienes permisos para esta operación
        '404':
          description: No encontrado - Sesión no existe
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    example: false
                    description: Indica si la operación fue exitosa.
                  message:
                    type: string
                    example: Session not found.
                    description: Mensaje descriptivo del error.
                  errors:
                    type: object
                    nullable: true
                    description: Detalles específicos de los errores.
                    properties:
                      session_id:
                        type: string
                        example: This field is required.
                        description: Error relacionado con el campo session_id.
                      spidi_id:
                        type: string
                        example: The credentials are incorrect
                        description: Error de autenticación.
                      message:
                        type: string
                        example: No tienes permisos para esta operación
                        description: Mensaje de error genérico.
              example:
                success: false
                message: Session not found.
                errors:
                  session_id: The session does not exist or has been deleted
        '422':
          description: Entidad no procesable - Formato inválido
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    example: false
                    description: Indica si la operación fue exitosa.
                  message:
                    type: string
                    example: Session not found.
                    description: Mensaje descriptivo del error.
                  errors:
                    type: object
                    nullable: true
                    description: Detalles específicos de los errores.
                    properties:
                      session_id:
                        type: string
                        example: This field is required.
                        description: Error relacionado con el campo session_id.
                      spidi_id:
                        type: string
                        example: The credentials are incorrect
                        description: Error de autenticación.
                      message:
                        type: string
                        example: No tienes permisos para esta operación
                        description: Mensaje de error genérico.
              example:
                success: false
                message: Unprocessable entity.
                errors:
                  session_id: Invalid session ID format
        '500':
          description: Error interno del servidor
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    example: false
                    description: Indica si la operación fue exitosa.
                  message:
                    type: string
                    example: Session not found.
                    description: Mensaje descriptivo del error.
                  errors:
                    type: object
                    nullable: true
                    description: Detalles específicos de los errores.
                    properties:
                      session_id:
                        type: string
                        example: This field is required.
                        description: Error relacionado con el campo session_id.
                      spidi_id:
                        type: string
                        example: The credentials are incorrect
                        description: Error de autenticación.
                      message:
                        type: string
                        example: No tienes permisos para esta operación
                        description: Mensaje de error genérico.
              example:
                success: false
                message: Internal server error.
  /api/v1/ext/payment-sessions/request/batch:
    post:
      summary: Crear Sesión(es)
      description: >-
        Permite crear una o múltiples sesiones de pago en forma de batch para
        solicitudes de pago. Cada item del batch contiene los campos de una
        sesión de pago más campos específicos para el manejo de vencimientos y
        notificaciones tardías.
      operationId: createPaymentSessionRequestBatch
      tags:
        - Endpoints Solicitud
      security:
        - bearerAuth: []
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - continue_on_error
                - items
              properties:
                continue_on_error:
                  type: boolean
                  nullable: true
                  default: false
                  description: >-
                    Indica si el procesamiento debe continuar con el resto de
                    los ítems aunque alguno falle en operaciones de batch.

                    - Si es `false`, se detiene en el primer error y las
                    operaciones ya exitosas permanecen válidas. 

                    - Si es `true`, continúa procesando hasta el final y luego
                    reporta las fallas acumuladas.
                  example: true
                items:
                  type: array
                  description: >-
                    Array de objetos con los datos de cada sesión de pago a
                    crear.
                  minItems: 1
                  items:
                    type: object
                    required:
                      - title
                      - agreement_id
                      - currency_reference
                      - amount_reference
                      - identifier
                      - due_date_session
                      - due_date_reached_behavior
                      - late_notice_message
                      - internal_reference
                    properties:
                      title:
                        type: string
                        nullable: false
                        description: Título de la landing page creada por SPIDI.
                        example: Pago de Servicios
                      agreement_id:
                        type: string
                        format: uuid
                        nullable: true
                        description: >-
                          Identificador único del acuerdo de liquidación. Debe
                          ser UUID v4. 
                      currency_reference:
                        type: string
                        nullable: false
                        enum:
                          - USD
                          - EUR
                          - COP
                          - USDT
                          - VES
                        description: >-
                          Moneda de referencia que se fija para el pago. Usada
                          para calcular el monto en bolívares con la tasa
                          vigente.
                      amount_reference:
                        description: >-
                          Monto de referencia en la moneda especificada en
                          currencyReference con 2 decimales.
                        type: number
                        nullable: false
                        format: double
                        example: '100.001'
                      identifier_label:
                        type: string
                        nullable: true
                        description: >-
                          Etiqueta que indica cómo debe interpretarse el valor
                          enviado en identifier (ej. 'Nro de orden').
                      identifier:
                        type: string
                        nullable: false
                        description: >-
                          Identificador del pagador, interpretado según el valor
                          de identifier_label. Ejemplo: Nro de orden, Nombre,
                          etc.
                      description:
                        type: string
                        nullable: true
                        description: >-
                          Descripción del acuerdo o del concepto de pago
                          asociado a una sesión.
                        maxLength: 500
                      success_url:
                        type: string
                        nullable: true
                        format: uri
                        description: >-
                          URL de redirección que se utiliza cuando un intento de
                          pago es exitoso.
                        pattern: ^[a-z1-9]+://[^\s]*$
                      failure_url:
                        type: string
                        nullable: true
                        format: uri
                        description: >-
                          URL de redirección que se utiliza cuando un intento de
                          pago falle. 
                        pattern: ^[a-z1-9]+://[^\s]*$
                      webhook_url:
                        type: string
                        nullable: true
                        format: uri
                        description: 'URL para recibir notificaciones de webhook. '
                      due_date_session:
                        type: string
                        nullable: true
                        format: date-time
                        description: >-
                          Fecha y hora límite de vencimiento de la Solicitud
                          SPIDI (sesión). 
                      due_date_reached_behavior:
                        type: string
                        nullable: true
                        enum:
                          - keep_active
                          - expire
                        description: >-
                          Comportamiento configurado para cuando la sesión
                          alcance su fecha de vencimiento.
                      late_notice_message:
                        type: string
                        nullable: true
                        description: >-
                          Mensaje que verá el pagador cuando la sesión haya
                          vencido pero continúe activa (keep_active). 
                      internal_reference:
                        type: string
                        nullable: false
                        description: >-
                          Referencia interna única utilizada por el sistema o el
                          comercio para identificar la solicitud de pago o
                          parada (propósito estrictamente técnico,no visible al
                          usuario final).


                          **Importancia para Paradas SPIDI:**

                          - Permite conciliar y auditar operaciones entre tu
                          sistema y SPIDI

                          - Sirve para asociar solicitudes de pago con su Parada
                          correspondiente

                          - Puede vincularse a clientes, contratos o facturas en
                          tu plataforma


                          Se recomienda mantener este campo de forma consistente
                          para facilitar la trazabilidad.
                        example: '8233232'
                      split:
                        type: object
                        nullable: true
                        description: >-
                          Configuración de división de pagos (Request) / Eco del
                          request del split (Response).
                        properties:
                          document:
                            type: object
                            nullable: true
                            description: >-
                              Información del documento proporcionado por el
                              owner a los partners para dejar evidencia del
                              split.


                              **Notas importantes:**

                              - Esta información **no implica cálculo fiscal**
                              por parte de SPIDI; es solo comunicación entre
                              owner y partners.

                              - `splitDocument_url` puede ser público con hash o
                              una URL autenticada.

                              - SPIDI **no interpreta ni calcula IVA** a partir
                              de esta información; solo lo transporta.
                            properties:
                              name:
                                type: string
                                nullable: true
                                description: >-
                                  Nombre del documento asociado a la transacción
                                  split (por ejemplo: factura/recibo/contrato
                                  D001-00045678).
                              type:
                                type: string
                                nullable: true
                                description: >-
                                  Formato libre del owner donde especifica el
                                  tipo de documento.
                                examples:
                                  - Factura
                                  - Contrato
                                  - Recibo
                              date:
                                type: string
                                nullable: true
                                format: date
                                description: >-
                                  Fecha de emisión del documento en formato ISO
                                  8601 (YYYY-MM-DD).
                              url:
                                type: string
                                nullable: true
                                format: uri
                                description: >-
                                  Enlace para visualizar/descargar el documento
                                  del split. Puede ser público con hash o una
                                  URL autenticada.
                              observations:
                                type: string
                                nullable: true
                                maxLength: 500
                                description: >-
                                  Observaciones libres del owner (máx. 500
                                  caracteres).
                          distribution:
                            type: array
                            nullable: false
                            description: >-
                              Lista de reglas/destinatarios del split. Debe
                              tener ≥ 1 ítem. La suma de amount_reference debe
                              ser menor al amount total de la sesión, porque la
                              diferencia restante se asigna automáticamente al
                              owner, quien siempre debe recibir una parte del
                              pago. (Requerido cuando split=true)
                            items:
                              type: object
                              required:
                                - split_recipient_agreement_id
                                - amount_reference
                                - observations
                              properties:
                                split_recipient_agreement_id:
                                  type: string
                                  nullable: false
                                  format: uuid
                                  description: >-
                                    UUID global SPIDI del agreement de
                                    recepción. Este ID se usará en acuerdos de
                                    distribución para identificar al receptor
                                    del split. (Requerido en distribution)
                                label:
                                  type: string
                                  nullable: true
                                  description: >-
                                    Etiqueta descriptiva del receptor en un
                                    split. (Opcional en distribution, Eco del
                                    request: sí)
                                amount_reference:
                                  description: >-
                                    Monto de referencia en la moneda
                                    especificada en currencyReference con 2
                                    decimales.
                                  type: number
                                  nullable: false
                                  format: double
                                  example: '100.001'
                                observations:
                                  type: string
                                  nullable: false
                                  maxLength: 500
                                  description: >-
                                    Mensaje libre para el partner (máx. 500
                                    caracteres). (Requerido en distribution, Eco
                                    del request: sí)
            examples:
              Sin Split:
                summary: Batch sin Split
                value:
                  continue_on_error: true
                  items:
                    - title: israeldavidvm
                      currency_reference: USD
                      amount_reference: 100
                      agreement_id: agr_5dc73cf74215ae4d
                      identifier_label: Nombre Cliente
                      identifier: Rafael
                      description: Pago Batch 1
                      due_date_session: '2026-12-31T23:59:59Z'
                      due_date_reached_behavior: keep_active
                      late_notice_message: Pago vencido
                      internal_reference: REF-001
                      success_url: miapp://pago/exitoso
                      failure_url: miapp://pago/fallido
                      webhook_url: https://miapi.com/spidi/webhook
              Con Split:
                summary: Batch con Split
                value:
                  continue_on_error: true
                  items:
                    - currency_reference: USD
                      amount_reference: 30
                      agreement_id: stl_session_01
                      identifier_label: Nombre del cliente
                      identifier: Juan Pérez
                      description: Pago de servicio de internet
                      success_url: miapp://pago/exitoso
                      failure_url: miapp://pago/fallido
                      webhook_url: https://miapi.com/spidi/webhook
                      due_date_session: '2025-10-31T23:59:59Z'
                      due_date_reached_behavior: keep_active
                      late_notice_message: Tu servicio está inactivo. Paga para reactivar.
                      internal_reference: INV-2025-10-USER_0001
                      split:
                        document:
                          document_name: D001-00045678
                          document_type: Factura
                          document_date: '2025-10-20'
                          document_url: https://owner.com/document/D001-00045678
                          document_observations: any observation to owner
                        rules:
                          - split_recipient_agreement_id: rcv_014…723c1a2
                            label: Partner 1
                            amount_reference: 10
                            observations: any observation to communicate to Partner 1
                          - split_recipient_agreement_id: rcv_016…112dde3
                            label: Partner 2
                            amount_reference: 20
                            observations: any observation to communicate to Partner 2
      responses:
        '200':
          description: Batch procesado exitosamente
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                  - data
                properties:
                  success:
                    type: boolean
                    nullable: false
                    description: >-
                      Indica si la operación fue exitosa. True si el endpoint se
                      procesó de forma exitosa. False de lo contrario
                    example: true
                  message:
                    type: string
                    example: Payment sessions created successfully.
                    description: Mensaje de confirmación de la creación.
                  data:
                    type: object
                    required:
                      - processed_count
                      - successful_count
                      - failed_count
                      - items
                    properties:
                      processed_count:
                        type: integer
                        nullable: false
                        description: 'Conteo de ítems procesados. Eco del request: no.'
                      successful_count:
                        type: integer
                        nullable: false
                        description: Número de sesiones creadas exitosamente.
                      failed_count:
                        type: integer
                        nullable: false
                        description: Número de sesiones que fallaron al crear en el batch.
                      items:
                        type: array
                        items:
                          type: object
                          properties:
                            session_origin:
                              type: string
                              nullable: false
                              enum:
                                - button
                                - request
                              description: >-
                                Origen de la sesión: 'button' (Botón de pago) o
                                'request' (Solicitud SPIDI).
                            session_id:
                              type: string
                              nullable: false
                              description: >-
                                Identificador único de la sesión de pago,
                                accedible a través del payment_url.
                            payment_url:
                              type: string
                              nullable: true
                              description: >-
                                URL de la página segura SPIDI donde quien paga
                                realiza el pago.
                              example: >-
                                {{base_url}}/?id=3ddc4cfb-c09a-43de-92c1-e4a069732e90
                            qr_payment_url:
                              type: string
                              nullable: true
                              description: >-
                                Cadena en base64 que representa la imagen de un
                                QR que apunta al payment_url.
                            currency_reference:
                              type: string
                              nullable: false
                              enum:
                                - USD
                                - EUR
                                - COP
                                - USDT
                                - VES
                              description: >-
                                Moneda de referencia que se fija para el pago.
                                Usada para calcular el monto en bolívares con la
                                tasa vigente.
                            amount_reference:
                              description: >-
                                Monto de referencia en la moneda especificada en
                                currencyReference con 2 decimales.
                              type: number
                              nullable: false
                              format: double
                              example: '100.001'
                            identifier_label:
                              type: string
                              nullable: true
                              description: >-
                                Etiqueta que indica cómo debe interpretarse el
                                valor enviado en identifier (ej. 'Nro de
                                orden').
                            identifier:
                              type: string
                              nullable: false
                              description: >-
                                Identificador del pagador, interpretado según el
                                valor de identifier_label. Ejemplo: Nro de
                                orden, Nombre, etc.
                            description:
                              type: string
                              nullable: true
                              description: >-
                                Descripción del acuerdo o del concepto de pago
                                asociado a una sesión.
                              maxLength: 500
                            success_url:
                              type: string
                              nullable: true
                              format: uri
                              description: >-
                                URL de redirección que se utiliza cuando un
                                intento de pago es exitoso.
                              pattern: ^[a-z1-9]+://[^\s]*$
                            failure_url:
                              type: string
                              nullable: true
                              format: uri
                              description: >-
                                URL de redirección que se utiliza cuando un
                                intento de pago falle. 
                              pattern: ^[a-z1-9]+://[^\s]*$
                            webhook_url:
                              type: string
                              nullable: true
                              format: uri
                              description: 'URL para recibir notificaciones de webhook. '
                            due_date_session:
                              type: string
                              nullable: true
                              format: date-time
                              description: >-
                                Fecha y hora límite de vencimiento de la
                                Solicitud SPIDI (sesión). 
                            due_date_reached_behavior:
                              type: string
                              nullable: true
                              enum:
                                - keep_active
                                - expire
                              description: >-
                                Comportamiento configurado para cuando la sesión
                                alcance su fecha de vencimiento.
                            late_notice_message:
                              type: string
                              nullable: true
                              description: >-
                                Mensaje que verá el pagador cuando la sesión
                                haya vencido pero continúe activa
                                (keep_active). 
                            internal_reference:
                              type: string
                              nullable: false
                              description: >-
                                Referencia interna única utilizada por el
                                sistema o el comercio para identificar la
                                solicitud de pago o parada (propósito
                                estrictamente técnico,no visible al usuario
                                final).


                                **Importancia para Paradas SPIDI:**

                                - Permite conciliar y auditar operaciones entre
                                tu sistema y SPIDI

                                - Sirve para asociar solicitudes de pago con su
                                Parada correspondiente

                                - Puede vincularse a clientes, contratos o
                                facturas en tu plataforma


                                Se recomienda mantener este campo de forma
                                consistente para facilitar la trazabilidad.
                              example: '8233232'
                            created_at:
                              type: string
                              nullable: true
                              format: date-time
                              description: >-
                                Fecha y hora de creación del recurso en formato
                                ISO 8601.
                            split:
                              type: object
                              nullable: true
                              description: >-
                                Configuración de división de pagos (Request) /
                                Eco del request del split (Response).
                              properties:
                                document:
                                  type: object
                                  nullable: true
                                  description: >-
                                    Información del documento proporcionado por
                                    el owner a los partners para dejar evidencia
                                    del split.


                                    **Notas importantes:**

                                    - Esta información **no implica cálculo
                                    fiscal** por parte de SPIDI; es solo
                                    comunicación entre owner y partners.

                                    - `splitDocument_url` puede ser público con
                                    hash o una URL autenticada.

                                    - SPIDI **no interpreta ni calcula IVA** a
                                    partir de esta información; solo lo
                                    transporta.
                                  properties:
                                    name:
                                      type: string
                                      nullable: true
                                      description: >-
                                        Nombre del documento asociado a la
                                        transacción split (por ejemplo:
                                        factura/recibo/contrato D001-00045678).
                                    type:
                                      type: string
                                      nullable: true
                                      description: >-
                                        Formato libre del owner donde especifica
                                        el tipo de documento.
                                      examples:
                                        - Factura
                                        - Contrato
                                        - Recibo
                                    date:
                                      type: string
                                      nullable: true
                                      format: date
                                      description: >-
                                        Fecha de emisión del documento en
                                        formato ISO 8601 (YYYY-MM-DD).
                                    url:
                                      type: string
                                      nullable: true
                                      format: uri
                                      description: >-
                                        Enlace para visualizar/descargar el
                                        documento del split. Puede ser público
                                        con hash o una URL autenticada.
                                    observations:
                                      type: string
                                      nullable: true
                                      maxLength: 500
                                      description: >-
                                        Observaciones libres del owner (máx. 500
                                        caracteres).
                                distribution:
                                  type: array
                                  nullable: false
                                  description: >-
                                    Lista de reglas/destinatarios del split.
                                    Debe tener ≥ 1 ítem. La suma de
                                    amount_reference debe ser menor al amount
                                    total de la sesión, porque la diferencia
                                    restante se asigna automáticamente al owner,
                                    quien siempre debe recibir una parte del
                                    pago. (Requerido cuando split=true)
                                  items:
                                    type: object
                                    required:
                                      - split_recipient_agreement_id
                                      - amount_reference
                                      - observations
                                    properties:
                                      split_recipient_agreement_id:
                                        type: string
                                        nullable: false
                                        format: uuid
                                        description: >-
                                          UUID global SPIDI del agreement de
                                          recepción. Este ID se usará en acuerdos
                                          de distribución para identificar al
                                          receptor del split. (Requerido en
                                          distribution)
                                      label:
                                        type: string
                                        nullable: true
                                        description: >-
                                          Etiqueta descriptiva del receptor en un
                                          split. (Opcional en distribution, Eco
                                          del request: sí)
                                      amount_reference:
                                        description: >-
                                          Monto de referencia en la moneda
                                          especificada en currencyReference con 2
                                          decimales.
                                        type: number
                                        nullable: false
                                        format: double
                                        example: '100.001'
                                      observations:
                                        type: string
                                        nullable: false
                                        maxLength: 500
                                        description: >-
                                          Mensaje libre para el partner (máx. 500
                                          caracteres). (Requerido en distribution,
                                          Eco del request: sí)
                      errors:
                        type: array
                        nullable: true
                        items:
                          type: object
                          properties:
                            item_index:
                              type: integer
                              nullable: true
                              description: Índice del ítem que falló en un batch.
                            errors:
                              type: object
              examples:
                Sin Split:
                  summary: Éxito - Sin Split
                  value:
                    success: true
                    message: Payment sessions created successfully.
                    data:
                      processed_count: 1
                      successful_count: 1
                      failed_count: 0
                      items:
                        - session_origin: request
                          session_id: 9896eec6-5448-4948-94dc-eec29735585f
                          payment_url: >-
                            https://sandbox.mispidi.com/?link_session_id=9896eec6-5448-4948-94dc-eec29735585f
                          payment_qr: >-
                            data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAYAAAB5fY51AAAAAklEQVR4AewaftIAAApwSURBVO3BgW0dSxIEwarG89/lPDkwe8CIS7L1M6L8EUlaYCJJS0wkaYmJJC0xkaQlJpK0xESSlphI0hITSVpiIklLTCRpiYkkLTGRpCUmkrTERJKW+OQvtM2/Asgb2uYJkJO2OQHyhra5BeQNbXMC5Fbb/CZAnrTNvwLIjYkkLTGRpCUmkrTERJKWmEjSEhNJWuKTlwD5bdrmt2mbEyAnbXMLyC0gJ21zAuSkbZ4AudE2vw2QNwD5bdrmq00kaYmJJC0xkaQlJpK0xESSlphI0hITSVrikx/SNm8A8oa2OQHyhrY5AfIGILeA3ADypG1uAHnSNidA3tA2J0De0DZvAPLdJpK0xESSlphI0hITSVpiIklLTCRpiU/0KiBP2uYEyEnbPAFy0jZvAPIGICdt84a2eQMQ3ZtI0hITSVpiIklLTCRpiYkkLTGRpCU+0V9rm1tATtrmBMiTtjkBcqttTtrmuwE5aZsnQLTLRJKWmEjSEhNJWmIiSUtMJGmJiSQtMZGkJT75IUD+FUDeAOSkbZ4AudE2t4DcaJtbbXMC5EnbnAC51TYnQL4bkH/FRJKWmEjSEhNJWmIiSUtMJGmJiSQt8clL2kZJ2zwBctI2J0CetM0JkFtATtrmBMgtICdt893a5gmQk7Y5AXKrbf4LJpK0xESSlphI0hITSVpiIklLTCRpifJH9H+1zQ0gt9rmBMiTtrkB5EnbfDUgb2ibJ0De0DYnQHRvIklLTCRpiYkkLTGRpCUmkrTERJKWmEjSEp/8hbY5AfKkbX4TIE+AnLTNrbY5AfLd2uYJkH9F25wAuQXkDW3zmwD5bhNJWmIiSUtMJGmJiSQtMZGkJSaStET5I79M25wAedI2J0C+W9vcAnKrbW4AedI2N4CctM0TIN+tbW4BOWmbEyBvaJsnQG60zRMgX20iSUtMJGmJiSQtMZGkJSaStMREkpYof+QHtM0NILfa5gTIb9M2J0CetM13A3LSNidAbrXNCZAnbXMC5KRtbgG51TYnQL5b29wCcmMiSUtMJGmJiSQtMZGkJSaStMREkpaYSNISn7ykbZ4AeUPbnAA5aZsnQG60zRMgvwmQ79Y2PwHIG4DcaJsnQE7a5haQG0CetM1Xm0jSEhNJWmIiSUtMJGmJiSQtMZGkJcofudQ2J0De0DZPgJy0zQmQN7TNfwWQk7a5BeSkbbQPkBsTSVpiIklLTCRpiYkkLTGRpCUmkrRE+SM/oG1OgPwr2uYJkJO2OQHypG1OgLyhbb4bkJO2eQOQW21zAuRW25wA+VdMJGmJiSQtMZGkJSaStMREkpaYSNISE0la4pO/0DYnQN7QNpsAedI2J0BO2uZW29wCcgPISdvcapsTID+hbd7QNjfa5haQk7a5BeTGRJKWmEjSEhNJWmIiSUtMJGmJiSQt8clL2uYJkBtAnrTNCZCTtnkC5KRtvhuQW21zAuQWkJO2OQHypG3e0DZvAHLSNreAnLTNLSA3gHy3iSQtMZGkJSaStMREkpaYSNISE0laovyRH9A2N4A8aZs3APlubfMGIG9omxMgb2ibNwD5bm3zBMhJ25wAudU2bwByYyJJS0wkaYmJJC0xkaQlJpK0xESSlphI0hLlj1xqmxMgt9rmDUBO2uYWkE3a5g1ANmmbNwC50TZPgPwmbfMEyFebSNISE0laYiJJS0wkaYmJJC0xkaQlPvmFgLyhbd7QNt8NyJO2OQFyq22+W9u8Acgb2uYGkCdt8wYgb2ibEyA3JpK0xESSlphI0hITSVpiIklLTCRpiU/+ApBbbXMDyC0gb2ibW0BO2uYWkBtt8wTISducAPluQN7QNk+A3GibNwB5A5AnbfPVJpK0xESSlphI0hITSVpiIklLTCRpiU9+CJCTtjlpmydATtrmDUButc2/AsiNtnkC5A1t84a2OQHyBiAnbfMGIE+AfLWJJC0xkaQlJpK0xESSlphI0hITSVpiIklLlD/ygrZ5AuSkbd4A5LdpmxMgJ23zBMgb2uYEyEnbvAHISds8AXKjbZ4AOWmbEyA/oW1OgJy0zRMgX20iSUtMJGmJiSQtMZGkJSaStMREkpYof+RS25wAedI2J0BO2uYnALnRNk+AfLe2eQOQG23zBMgb2uYEyK22OQFyq22+G5BbbXMC5MZEkpaYSNISE0laYiJJS0wkaYmJJC3xyV8A8tsAudE2T9rmBMgb2uYEyJO2+W5tcwLkDW1zAuQJkJO2uQXkRts8AXLSNreA3Gib7zaRpCUmkrTERJKWmEjSEhNJWmIiSUtMJGmJT34IkJO2eUPbnAB50jY3gLyhbW4BOWmbJ0C+GpBbQN4A5Fbb3ADy27TNCZDvNpGkJSaStMREkpaYSNISE0laYiJJS3zyF9rmFpATILfa5gTISds8AfKGtjkB8oa2OQHypG1uADlpmydA3tA2J0DeAOSkbW4BudU2J0B+k4kkLTGRpCUmkrTERJKWmEjSEhNJWuKTlwB50jYnQE7a5lbbbNI2t4DcaJtbQE7a5gTIrba5BeSkbU6APAFy0ja3gJy0zQmQJ0BO2uYNQG5MJGmJiSQtMZGkJSaStMREkpaYSNISE0la4pNlgDxpmxMgJ22zCZAnbXMDyBuAnLTNG4DcAnLSNreAvAHIrbY5AXLSNk+AfLWJJC0xkaQlJpK0xESSlphI0hITSVrik38MkJO2udU2J0BO2uYNbfOGtrkF5KRtToD8hLZ5A5CTttmkbX6TiSQtMZGkJSaStMREkpaYSNISE0laovwR/V9t8wYgJ21zAuS3aZs3ADlpm1tATtrmuwF5Q9vcAnLSNk+AfLWJJC0xkaQlJpK0xESSlphI0hITSVpiIklLfPIX2uZfAeQJkBttcwvIrba5AeQNQE7a5haQNwA5aZsnQE7a5lbbnAC5BeSkbU6APGmbEyA3JpK0xESSlphI0hITSVpiIklLTCRpiU9eAuS3aZtbbXMDyJO2uQHkCZCTtjlpmydAToCctM0JkJ/QNjeA/AQgb2ibEyC/yUSSlphI0hITSVpiIklLTCRpiYkkLfHJD2mbNwDZBMhJ29xqmxtAbrXNCZBbbXMC5KRtngA5aZtbbXOjbX4CkJO2OQHyBMhXm0jSEhNJWmIiSUtMJGmJiSQtMZGkJSaStMQn+mtAbrXNjbZ5Q9vcAnLSNidAngC5AeRJ25wAOWmbW0BO2uYWkJO2edI2J0B+k4kkLTGRpCUmkrTERJKWmEjSEhNJWuIT/SggN9rmFpA3tM0JkDe0zS0gN4C8AcgbgDxpmze0zQmQGxNJWmIiSUtMJGmJiSQtMZGkJSaStMQnPwTIJkBO2uYEyJO2+U3a5gmQEyBvaJsbQDZpmydAbrTNEyBbTCRpiYkkLTGRpCUmkrTERJKWmEjSEhNJWuKTl7TNv6RtToCctM0TICdtcwLkSdvcAPKkbU6A3GibJ0BO2uZW2/wmQJ60zQmQN7TNbzKRpCUmkrTERJKWmEjSEhNJWmIiSUuUPyJJC0wkaYmJJC0xkaQlJpK0xESSlphI0hITSVpiIklLTCRpiYkkLTGRpCUmkrTERJKW+B+9zwFKUGEapgAAAABJRU5ErkJggg==
                          currency_reference: USD
                          amount_reference: 100
                          identifier_label: Nombre Cliente
                          identifier: Rafael
                          title: israeldavidvm
                          description: Pago Batch 1
                          due_date_session: '2026-12-31T23:59:59Z'
                          due_date_reached_behavior: keep_active
                          late_notice_message: Pago vencido
                          internal_reference: REF-001
                          created_at: '2026-03-10T17:54:58.000Z'
                      errors: []
                Éxito Parcial sin Split Con Errore:
                  summary: Éxito Parcial - Con Errores
                  value:
                    success: false
                    message: Batch processing failed
                    data:
                      processed_count: 2
                      successful_count: 1
                      failed_count: 1
                      items:
                        - session_origin: request
                          session_id: 3ddc4cfb-c09a-43de-92c1-e4a069732e90
                          payment_url: '{url}/?id=3ddc4cfb-c09a-43de-92c1-e4a069732e90'
                          currency_reference: USD
                          amount_reference: 50
                          identifier_label: Nombre del cliente
                          identifier: Juan Pérez
                          description: Pago de servicio de internet
                          success_url: miapp://pago/exitoso
                          failure_url: miapp://pago/fallido
                          webhook_url: https://miapi.com/spidi/webhook
                          due_date_session: '2025-10-31T23:59:59Z'
                          due_date_reached_behavior: keep_active
                          late_notice_message: Tu servicio está inactivo. Paga para reactivar.
                          internal_reference: INV-2025-10-USER_0001
                          created_at: '2025-09-18T20:45:00Z'
                      errors:
                        - item_index: 1
                          errors:
                            due_date_link: This field is required.
        '400':
          description: Solicitud inválida - Campo faltante
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    example: false
                    description: Indica si la operación fue exitosa.
                  message:
                    type: string
                    example: 'Missing required field: items'
                    description: Mensaje descriptivo del error.
                  errors:
                    type: object
                    nullable: true
                    description: Detalles específicos de los errores.
                    properties:
                      items:
                        type: string
                        example: This field is required.
                        description: Error relacionado con el campo items.
                      continue_on_error:
                        type: string
                        example: Must be a boolean value.
                        description: Error relacionado con el campo continue_on_error.
                      spidi_id:
                        type: string
                        example: The credentials are incorrect
                        description: Error de autenticación.
                      Idempotency-Key:
                        type: string
                        example: A session already exists for this key.
                        description: Error de idempotencia.
                  data:
                    type: object
                    nullable: true
                    description: Datos parciales en caso de errores de batch.
                    properties:
                      processed_count:
                        type: integer
                      successful_count:
                        type: integer
                      failed_count:
                        type: integer
                      items:
                        type: array
                      errors:
                        type: array
                        items:
                          type: object
                          properties:
                            item_index:
                              type: integer
                            errors:
                              type: object
              example:
                success: false
                message: 'Missing required field: items'
                errors:
                  items: This field is required.
        '401':
          description: No autorizado - Credenciales incorrectas
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    example: false
                    description: Indica si la operación fue exitosa.
                  message:
                    type: string
                    example: 'Missing required field: items'
                    description: Mensaje descriptivo del error.
                  errors:
                    type: object
                    nullable: true
                    description: Detalles específicos de los errores.
                    properties:
                      items:
                        type: string
                        example: This field is required.
                        description: Error relacionado con el campo items.
                      continue_on_error:
                        type: string
                        example: Must be a boolean value.
                        description: Error relacionado con el campo continue_on_error.
                      spidi_id:
                        type: string
                        example: The credentials are incorrect
                        description: Error de autenticación.
                      Idempotency-Key:
                        type: string
                        example: A session already exists for this key.
                        description: Error de idempotencia.
                  data:
                    type: object
                    nullable: true
                    description: Datos parciales en caso de errores de batch.
                    properties:
                      processed_count:
                        type: integer
                      successful_count:
                        type: integer
                      failed_count:
                        type: integer
                      items:
                        type: array
                      errors:
                        type: array
                        items:
                          type: object
                          properties:
                            item_index:
                              type: integer
                            errors:
                              type: object
              example:
                success: false
                message: Unauthorized.
                errors:
                  spidi_id: The merchant does not match the provided credentials.
        '403':
          description: Prohibido - Sin permisos
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    example: false
                    description: Indica si la operación fue exitosa.
                  message:
                    type: string
                    example: 'Missing required field: items'
                    description: Mensaje descriptivo del error.
                  errors:
                    type: object
                    nullable: true
                    description: Detalles específicos de los errores.
                    properties:
                      items:
                        type: string
                        example: This field is required.
                        description: Error relacionado con el campo items.
                      continue_on_error:
                        type: string
                        example: Must be a boolean value.
                        description: Error relacionado con el campo continue_on_error.
                      spidi_id:
                        type: string
                        example: The credentials are incorrect
                        description: Error de autenticación.
                      Idempotency-Key:
                        type: string
                        example: A session already exists for this key.
                        description: Error de idempotencia.
                  data:
                    type: object
                    nullable: true
                    description: Datos parciales en caso de errores de batch.
                    properties:
                      processed_count:
                        type: integer
                      successful_count:
                        type: integer
                      failed_count:
                        type: integer
                      items:
                        type: array
                      errors:
                        type: array
                        items:
                          type: object
                          properties:
                            item_index:
                              type: integer
                            errors:
                              type: object
              example:
                success: false
                message: Forbidden.
                errors:
                  message: No tienes permisos para esta operación.
        '409':
          description: Conflicto - Idempotencia duplicada
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    example: false
                    description: Indica si la operación fue exitosa.
                  message:
                    type: string
                    example: 'Missing required field: items'
                    description: Mensaje descriptivo del error.
                  errors:
                    type: object
                    nullable: true
                    description: Detalles específicos de los errores.
                    properties:
                      items:
                        type: string
                        example: This field is required.
                        description: Error relacionado con el campo items.
                      continue_on_error:
                        type: string
                        example: Must be a boolean value.
                        description: Error relacionado con el campo continue_on_error.
                      spidi_id:
                        type: string
                        example: The credentials are incorrect
                        description: Error de autenticación.
                      Idempotency-Key:
                        type: string
                        example: A session already exists for this key.
                        description: Error de idempotencia.
                  data:
                    type: object
                    nullable: true
                    description: Datos parciales en caso de errores de batch.
                    properties:
                      processed_count:
                        type: integer
                      successful_count:
                        type: integer
                      failed_count:
                        type: integer
                      items:
                        type: array
                      errors:
                        type: array
                        items:
                          type: object
                          properties:
                            item_index:
                              type: integer
                            errors:
                              type: object
              example:
                success: false
                message: 'Conflict: duplicated request.'
                errors:
                  Idempotency-Key: A session already exists for this key.
        '422':
          description: Entidad no procesable - Datos inválidos
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    example: false
                    description: Indica si la operación fue exitosa.
                  message:
                    type: string
                    example: 'Missing required field: items'
                    description: Mensaje descriptivo del error.
                  errors:
                    type: object
                    nullable: true
                    description: Detalles específicos de los errores.
                    properties:
                      items:
                        type: string
                        example: This field is required.
                        description: Error relacionado con el campo items.
                      continue_on_error:
                        type: string
                        example: Must be a boolean value.
                        description: Error relacionado con el campo continue_on_error.
                      spidi_id:
                        type: string
                        example: The credentials are incorrect
                        description: Error de autenticación.
                      Idempotency-Key:
                        type: string
                        example: A session already exists for this key.
                        description: Error de idempotencia.
                  data:
                    type: object
                    nullable: true
                    description: Datos parciales en caso de errores de batch.
                    properties:
                      processed_count:
                        type: integer
                      successful_count:
                        type: integer
                      failed_count:
                        type: integer
                      items:
                        type: array
                      errors:
                        type: array
                        items:
                          type: object
                          properties:
                            item_index:
                              type: integer
                            errors:
                              type: object
              example:
                success: false
                message: Unprocessable entity.
                errors:
                  continue_on_error: Must be a boolean value.
                  items: Must be a non-empty array.
        '500':
          description: Error interno del servidor
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    example: false
                    description: Indica si la operación fue exitosa.
                  message:
                    type: string
                    example: 'Missing required field: items'
                    description: Mensaje descriptivo del error.
                  errors:
                    type: object
                    nullable: true
                    description: Detalles específicos de los errores.
                    properties:
                      items:
                        type: string
                        example: This field is required.
                        description: Error relacionado con el campo items.
                      continue_on_error:
                        type: string
                        example: Must be a boolean value.
                        description: Error relacionado con el campo continue_on_error.
                      spidi_id:
                        type: string
                        example: The credentials are incorrect
                        description: Error de autenticación.
                      Idempotency-Key:
                        type: string
                        example: A session already exists for this key.
                        description: Error de idempotencia.
                  data:
                    type: object
                    nullable: true
                    description: Datos parciales en caso de errores de batch.
                    properties:
                      processed_count:
                        type: integer
                      successful_count:
                        type: integer
                      failed_count:
                        type: integer
                      items:
                        type: array
                      errors:
                        type: array
                        items:
                          type: object
                          properties:
                            item_index:
                              type: integer
                            errors:
                              type: object
              example:
                success: false
                message: Internal server error.
  /api/v1/payment-session/{session_id}/expiration:
    post:
      summary: Expirar una Solicitud de Pago
      description: >+
        Fuerza el cierre de una sesión de pago que se encuentra en estado
        pendiente. 


        ### Comportamiento según Estado Actual


        - Si la sesión está **`PENDING`**, pasa a **`EXPIRED`** inmediatamente.

        - Si ya estaba **`EXPIRED`** no hace nada.

        - Si la sesión está **`PAID`**, **NO** puede expirarse (regla de negocio
        - retorna error 422).


        ## Efecto sobre Paradas SPIDI


        Si la sesión estaba asociada como activa en una Parada SPIDI, al pasar a
        **`expired`** deja de estar activa y queda en el histórico de la parada,
        por lo que el usuario podrá ver el mensaje que se le deja en
        `user_message`.


        ## Notas y Buenas Prácticas


        ### Paradas SPIDI


        No necesitas llamar a `/payment-stops/payment-sessions/batch` con un
        item con op = remove; al expirar, la sesión **sale sola** del conjunto
        activo de cualquier parada a la que esté asociada (queda en histórico).


        ### Trazabilidad

         Usa `message_audit` para auditoría (quién, cuándo, por qué).

      operationId: expirePaymentSession
      tags:
        - Endpoints Solicitud
      security:
        - bearerAuth: []
      parameters:
        - name: session_id
          in: path
          description: UUID único de la sesión de pago a invalidar.
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - category
              properties:
                category:
                  type: string
                  enum:
                    - INCORRECT_DATA
                    - ALTERNATIVE_PAYMENT_RECEIVED
                    - OTHER
                  description: >-
                    **Clasificación técnica obligatoria.** Permite segmentar el
                    motivo de cancelación para análisis de conversión y
                    auditoría. 


                    **Definiciones:**

                    * `INCORRECT_DATA`: Datos de pago o cliente inválidos (ej.
                    CI/RIF erróneo).

                    * `ALTERNATIVE_PAYMENT_RECEIVED`: El cliente pagó por otra
                    vía (ej. efectivo o transferencia directa).

                    * `OTHER`: Motivos no clasificados previamente (requiere
                    nota adicional).
                  example: INCORRECT_DATA
                message_audit:
                  type: string
                  nullable: true
                  description: >-
                    Nota de auditoría interna. Espacio para justificaciones
                    técnicas o administrativas. Este contenido no es visible
                    para el cliente final y se utiliza exclusivamente para
                    trazabilidad recomienda usarlo con esta estructura: (quién,
                    cuándo, por qué).
                  example: >-
                    La orden se habia generado de forma automatizada pero el
                    usuario liquido la la sesión en nuestra sucursal por medio
                    de pagos en efectivo.
                message_user:
                  type: string
                  nullable: true
                  description: >-
                    Mensaje para el usuario final cuado por ejemplo el
                    administrador necesita dar una instrucción específica.
                  example: Sesión cancelada por pago en efectivo
      responses:
        '200':
          description: >-
            Operación exitosa. Si la sesión ya estaba en un estado final
            EXPIRED, se devuelve el registro original sin aplicar cambios.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  message:
                    type: string
                    example: Session status expired.
                  data:
                    type: object
                    properties:
                      session_id:
                        type: string
                        format: uuid
                      status:
                        type: string
                        example: expired
                      category:
                        type: string
                        enum:
                          - INCORRECT_DATA
                          - ALTERNATIVE_PAYMENT_RECEIVED
                          - OTHER
                        description: >-
                          **Clasificación técnica obligatoria.** Permite
                          segmentar el motivo de cancelación para análisis de
                          conversión y auditoría. 


                          **Definiciones:**

                          * `INCORRECT_DATA`: Datos de pago o cliente inválidos
                          (ej. CI/RIF erróneo).

                          * `ALTERNATIVE_PAYMENT_RECEIVED`: El cliente pagó por
                          otra vía (ej. efectivo o transferencia directa).

                          * `OTHER`: Motivos no clasificados previamente
                          (requiere nota adicional).
                        example: INCORRECT_DATA
                      message_user:
                        type: string
                        nullable: true
                        description: >-
                          Mensaje para el usuario final cuado por ejemplo el
                          administrador necesita dar una instrucción específica.
                        example: Sesión cancelada por pago en efectivo
                      message_audit:
                        type: string
                        nullable: true
                        description: >-
                          Nota de auditoría interna. Espacio para
                          justificaciones técnicas o administrativas. Este
                          contenido no es visible para el cliente final y se
                          utiliza exclusivamente para trazabilidad recomienda
                          usarlo con esta estructura: (quién, cuándo, por qué).
                        example: >-
                          La orden se habia generado de forma automatizada pero
                          el usuario liquido la la sesión en nuestra sucursal
                          por medio de pagos en efectivo.
                      processed_at:
                        type: string
                        format: date-time
                        description: Fecha y hora de procesamiento en formato ISO 8601.
                        example: '2026-05-06T17:15:00-04:00'
              example:
                success: true
                message: Session status expired.
                data:
                  session_id: 3ddc4cfb-c09a-43de-92c1-e4a069732e90
                  status: expired
                  category: ALTERNATIVE_PAYMENT_RECEIVED
                  message_user: >-
                    El pago fue expirado forzosamente por que el usuario pago
                    por otro medio.
                  processed_at: '2026-05-06T17:15:00Z'
        '422':
          description: >-
            Entidad no procesable. Regla de integridad financiera: no se puede
            expirar una sesión con estado 'paid'.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: false
                  message:
                    type: string
                    example: 'Business Rule Violation: Paid sessions cannot be modified.'
                  errors:
                    type: object
                    additionalProperties:
                      type: string
              example:
                success: false
                message: 'Business Rule Violation: Paid sessions cannot be modified.'
                errors:
                  status: paid
  /api/v1/ext/split-receiving-agreements:
    post:
      summary: Crear Acuerdo de Recepción de Split
      description: >-
        Crea un *agreement* de **recepción de split** —un destinatario final que
        puede recibir montos distribuidos desde otros usuarios que apliquen un
        split en sus acuerdos de pago.


        Al crear este recurso, SPIDI genera un identificador único global
        (`split_recipient_agreement_id`) con prefijo semántico `rcv_`, que debes
        compartir con los usuarios que deseen enviar parte de sus pagos hacia tu
        cuenta.


        Este *agreement* no admite splits adicionales: su única función es
        definir el **ruteo de la liquidación**, determinando la cuenta bancaria
        destino.


        ## Características


        - Identificador **global** retornado como `split_recipient_agreement_id`
        (UUID SPIDI)

        - Enrutamiento con **fallback** a `default_bank_account_id`

        - Referenciable desde acuerdos de **distribución** vía
        `split_recipient_agreement_id`


        ## Notas de Validación


        - Debe existir **siempre** `default_bank_account_id`

        - En `rules`, cada `origin_bank_code` **no puede repetirse**

        - Si en runtime no hay match de `origin_bank_code`, se utiliza el
        `default_bank_account_id`

        - Si no hay match **y** falta `default_bank_account_id` → error


        ## Idempotencia


        Usa siempre `Idempotency-Key` (UUID v4). Reenviar el mismo POST con
        igual payload devolverá el mismo resultado sin duplicar efectos.
      operationId: createSplitReceivingAgreement
      tags:
        - Endpoints Especiales
      security:
        - bearerAuth: []
      parameters: []
      requestBody:
        description: Datos del acuerdo de recepción de split
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - title
                - default_bank_account_id
              properties:
                title:
                  type: string
                  nullable: false
                  description: 'Título visible. '
                description:
                  type: string
                  nullable: true
                  description: >-
                    Descripción del acuerdo o del concepto de pago asociado a
                    una sesión.
                  maxLength: 500
                split_recipient_agreement_id:
                  type: string
                  nullable: false
                  format: uuid
                  description: >-
                    UUID global SPIDI del agreement de recepción. Este ID se
                    usará en acuerdos de distribución para identificar al
                    receptor del split. (Requerido en distribution)
                default_bank_account_id:
                  type: string
                  format: uuid
                  nullable: false
                  description: >-
                    UUID de la cuenta bancaria por defecto que se utilizará para
                    la liquidación. 
                rules:
                  type: array
                  nullable: true
                  description: |-
                    (**En Desarrollo**) Reglas de acuerdo. 
                     En caso de usar origin_bank_code y destination_bank_account_id, se aplicará una regla de ruteo por banco de origen. Cada regla define a qué cuenta bancaria se debe enviar el dinero según el banco del pagador.
                  items:
                    type: object
                    properties:
                      origin_bank_code:
                        type: string
                        nullable: false
                        description: 'Código oficial del banco de origen. '
                      destination_bank_account_id:
                        type: string
                        nullable: true
                        description: >-
                          UUID de la cuenta bancaria de destino para un banco de
                          origen específico. 
            examples:
              withRules:
                summary: Con reglas de ruteo
                value:
                  title: Partner 1 (recepción)
                  description: Recibir de marketplace X
                  default_bank_account_id: uuid_sofitasa_001
                  rules:
                    - origin_bank_code: '0105'
                      destination_bank_account_id: uuid_mercantil_007
                    - origin_bank_code: '0108'
                      destination_bank_account_id: uuid_provincial_001
              withoutRules:
                summary: Sin reglas de ruteo
                value:
                  title: Partner 2 (recepción simple)
                  description: Recibir pagos de distribuidores
                  default_bank_account_id: uuid_banesco_003
      responses:
        '200':
          description: Acuerdo de recepción creado exitosamente
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - data
                properties:
                  success:
                    type: boolean
                    nullable: false
                    description: >-
                      Indica si la operación fue exitosa. True si el endpoint se
                      procesó de forma exitosa. False de lo contrario
                    example: true
                  data:
                    type: object
                    required:
                      - split_recipient_agreement_id
                      - title
                      - default_bank_account_id
                      - created_at
                      - created_by
                    properties:
                      split_recipient_agreement_id:
                        type: string
                        nullable: false
                        format: uuid
                        description: >-
                          UUID global SPIDI del agreement de recepción. Este ID
                          se usará en acuerdos de distribución para identificar
                          al receptor del split. (Requerido en distribution)
                      title:
                        type: string
                        nullable: false
                        description: 'Título visible. '
                      description:
                        type: string
                        nullable: true
                        description: >-
                          Descripción del acuerdo o del concepto de pago
                          asociado a una sesión.
                        maxLength: 500
                      default_bank_account_id:
                        type: string
                        format: uuid
                        nullable: false
                        description: >-
                          UUID de la cuenta bancaria por defecto que se
                          utilizará para la liquidación. 
                      rules:
                        type: array
                        nullable: true
                        description: |-
                          (**En Desarrollo**) Reglas de acuerdo. 
                           En caso de usar origin_bank_code y destination_bank_account_id, se aplicará una regla de ruteo por banco de origen. Cada regla define a qué cuenta bancaria se debe enviar el dinero según el banco del pagador.
                        items:
                          type: object
                          properties:
                            origin_bank_code:
                              type: string
                              nullable: false
                              description: 'Código oficial del banco de origen. '
                            destination_bank_account_id:
                              type: string
                              nullable: true
                              description: >-
                                UUID de la cuenta bancaria de destino para un
                                banco de origen específico. 
                      created_at:
                        type: string
                        nullable: true
                        format: date-time
                        description: >-
                          Fecha y hora de creación del recurso en formato ISO
                          8601.
                      created_by:
                        type: string
                        nullable: true
                        description: >-
                          Identificador del usuario que creó el recurso
                          administrable.
              example:
                success: true
                data:
                  split_recipient_agreement_id: rcv_01c3f7a2-4eaa-4a11-9d1d-3d3a6723c1a2
                  title: To receive from Partners
                  description: Recibir de marketplace X
                  default_bank_account_id: uuid_sofitasa_001
                  rules:
                    - origin_bank_code: '0105'
                      destination_bank_account_id: uuid_mercantil_007
                    - origin_bank_code: '0108'
                      destination_bank_account_id: uuid_provincial_001
                  created_at: '2025-10-20T14:30:00Z'
                  created_by: user_456
        '400':
          description: Solicitud inválida - Campo faltante o inválido
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    example: false
                    description: Indica que la operación falló.
                  message:
                    type: string
                    example: Invalid request parameters
                    description: Mensaje de error general.
                  errors:
                    type: object
                    nullable: true
                    description: Detalles específicos de los errores de validación.
                    properties:
                      title:
                        type: string
                        example: Title is required.
                        description: Error relacionado con el campo title.
                      default_bank_account_id:
                        type: string
                        example: Default bank account ID is required.
                        description: >-
                          Error relacionado con el campo
                          default_bank_account_id.
                      rules:
                        type: string
                        example: Duplicate origin_bank_code '0105' in rules.
                        description: Error relacionado con las reglas de ruteo.
                      origin_bank_code:
                        type: string
                        example: INVALID_BANK_CODE
                        description: Código de banco inválido.
                      destination_bank_account_id:
                        type: string
                        example: BANK_ACCOUNT_NOT_FOUND
                        description: Cuenta bancaria de destino no encontrada.
                      authorization:
                        type: string
                        example: Invalid or missing Bearer token
                        description: Error de autorización.
              example:
                success: false
                message: Invalid request parameters
                errors:
                  title: Title is required
                  default_bank_account_id: Default destination is required
        '401':
          description: No autorizado - Credenciales incorrectas
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    example: false
                    description: Indica que la operación falló.
                  message:
                    type: string
                    example: Invalid request parameters
                    description: Mensaje de error general.
                  errors:
                    type: object
                    nullable: true
                    description: Detalles específicos de los errores de validación.
                    properties:
                      title:
                        type: string
                        example: Title is required.
                        description: Error relacionado con el campo title.
                      default_bank_account_id:
                        type: string
                        example: Default bank account ID is required.
                        description: >-
                          Error relacionado con el campo
                          default_bank_account_id.
                      rules:
                        type: string
                        example: Duplicate origin_bank_code '0105' in rules.
                        description: Error relacionado con las reglas de ruteo.
                      origin_bank_code:
                        type: string
                        example: INVALID_BANK_CODE
                        description: Código de banco inválido.
                      destination_bank_account_id:
                        type: string
                        example: BANK_ACCOUNT_NOT_FOUND
                        description: Cuenta bancaria de destino no encontrada.
                      authorization:
                        type: string
                        example: Invalid or missing Bearer token
                        description: Error de autorización.
              example:
                success: false
                message: Unauthorized access
                errors:
                  authorization: Invalid or missing Bearer token
        '409':
          description: Conflicto - Acuerdo duplicado
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    example: false
                    description: Indica que la operación falló.
                  message:
                    type: string
                    example: Invalid request parameters
                    description: Mensaje de error general.
                  errors:
                    type: object
                    nullable: true
                    description: Detalles específicos de los errores de validación.
                    properties:
                      title:
                        type: string
                        example: Title is required.
                        description: Error relacionado con el campo title.
                      default_bank_account_id:
                        type: string
                        example: Default bank account ID is required.
                        description: >-
                          Error relacionado con el campo
                          default_bank_account_id.
                      rules:
                        type: string
                        example: Duplicate origin_bank_code '0105' in rules.
                        description: Error relacionado con las reglas de ruteo.
                      origin_bank_code:
                        type: string
                        example: INVALID_BANK_CODE
                        description: Código de banco inválido.
                      destination_bank_account_id:
                        type: string
                        example: BANK_ACCOUNT_NOT_FOUND
                        description: Cuenta bancaria de destino no encontrada.
                      authorization:
                        type: string
                        example: Invalid or missing Bearer token
                        description: Error de autorización.
              example:
                success: false
                message: Receiving agreement conflict
                errors:
                  title: A receiving agreement with a similar title already exists
        '422':
          description: Entidad no procesable - Reglas de ruteo inválidas
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    example: false
                    description: Indica que la operación falló.
                  message:
                    type: string
                    example: Invalid request parameters
                    description: Mensaje de error general.
                  errors:
                    type: object
                    nullable: true
                    description: Detalles específicos de los errores de validación.
                    properties:
                      title:
                        type: string
                        example: Title is required.
                        description: Error relacionado con el campo title.
                      default_bank_account_id:
                        type: string
                        example: Default bank account ID is required.
                        description: >-
                          Error relacionado con el campo
                          default_bank_account_id.
                      rules:
                        type: string
                        example: Duplicate origin_bank_code '0105' in rules.
                        description: Error relacionado con las reglas de ruteo.
                      origin_bank_code:
                        type: string
                        example: INVALID_BANK_CODE
                        description: Código de banco inválido.
                      destination_bank_account_id:
                        type: string
                        example: BANK_ACCOUNT_NOT_FOUND
                        description: Cuenta bancaria de destino no encontrada.
                      authorization:
                        type: string
                        example: Invalid or missing Bearer token
                        description: Error de autorización.
              examples:
                duplicateOriginBank:
                  summary: Código de banco duplicado en reglas
                  value:
                    success: false
                    message: Invalid routing configuration
                    errors:
                      rules: Duplicate origin_bank_code '0105' in rules
                invalidBankCode:
                  summary: Código de banco inválido
                  value:
                    success: false
                    message: Unprocessable entity.
                    errors:
                      origin_bank_code: INVALID_BANK_CODE
                bankAccountNotFound:
                  summary: Cuenta bancaria no encontrada
                  value:
                    success: false
                    message: Unprocessable entity.
                    errors:
                      destination_bank_account_id: BANK_ACCOUNT_NOT_FOUND
                missingDefaultFallback:
                  summary: Falta cuenta por defecto
                  value:
                    success: false
                    message: Invalid routing configuration
                    errors:
                      default_bank_account_id: Missing default destination when no rule matches
        '500':
          description: Error interno del servidor
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    example: false
                    description: Indica que la operación falló.
                  message:
                    type: string
                    example: Invalid request parameters
                    description: Mensaje de error general.
                  errors:
                    type: object
                    nullable: true
                    description: Detalles específicos de los errores de validación.
                    properties:
                      title:
                        type: string
                        example: Title is required.
                        description: Error relacionado con el campo title.
                      default_bank_account_id:
                        type: string
                        example: Default bank account ID is required.
                        description: >-
                          Error relacionado con el campo
                          default_bank_account_id.
                      rules:
                        type: string
                        example: Duplicate origin_bank_code '0105' in rules.
                        description: Error relacionado con las reglas de ruteo.
                      origin_bank_code:
                        type: string
                        example: INVALID_BANK_CODE
                        description: Código de banco inválido.
                      destination_bank_account_id:
                        type: string
                        example: BANK_ACCOUNT_NOT_FOUND
                        description: Cuenta bancaria de destino no encontrada.
                      authorization:
                        type: string
                        example: Invalid or missing Bearer token
                        description: Error de autorización.
              example:
                success: false
                message: Internal server error
  /api/v1/ext/payment-stops:
    get:
      summary: Listar Paradas
      description: >-
        Lista todas las paradas (stops) del comercio autenticado, con soporte de
        búsqueda y filtros (por estado, título, referencia interna) y
        paginación. Es útil para construir listados administrativos, buscadores
        y reportes.
      operationId: listStops
      tags:
        - Endpoints Parada
      security:
        - bearerAuth: []
      parameters:
        - name: status
          in: query
          description: Filtra por estado de la parada
          required: false
          schema:
            type: string
            enum:
              - active
              - disabled
            example: active
        - name: q
          in: query
          description: Búsqueda por texto en stop_title y/o internal_reference (contiene)
          required: false
          schema:
            type: string
            example: caja
        - name: internal_reference
          in: query
          description: Filtra por coincidencia exacta de la referencia interna
          required: false
          schema:
            type: string
            example: caja_001
        - name: from_date
          in: query
          description: >-
            ISO 8601 (UTC). Devuelve paradas creadas desde esta fecha/hora
            (inclusive)
          required: false
          schema:
            type: string
            format: date-time
            example: '2025-01-01T00:00:00Z'
        - name: to_date
          in: query
          description: >-
            ISO 8601 (UTC). Devuelve paradas creadas hasta esta fecha/hora
            (inclusive)
          required: false
          schema:
            type: string
            format: date-time
            example: '2025-12-31T23:59:59Z'
        - name: limit
          in: query
          description: Máximo de elementos a devolver
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 200
            default: 50
            example: 20
        - name: offset
          in: query
          description: Desplazamiento para paginación
          required: false
          schema:
            type: integer
            minimum: 0
            default: 0
            example: 0
        - name: sort
          in: query
          description: Orden de los resultados
          required: false
          schema:
            type: string
            enum:
              - created_desc
              - created_asc
              - updated_desc
              - updated_asc
            default: created_desc
            example: created_desc
      responses:
        '200':
          description: Lista de paradas obtenida exitosamente
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                  - data
                properties:
                  success:
                    type: boolean
                    description: True si el endpoint se procesó de forma exitosa
                    example: true
                  message:
                    type: string
                    description: Mensaje de confirmación legible para humanos
                    example: Payment stops retrieved successfully.
                  data:
                    type: object
                    required:
                      - total
                      - limit
                      - offset
                      - items
                    properties:
                      total:
                        type: integer
                        description: Total de paradas que cumplen con los filtros aplicados
                        example: 2
                      limit:
                        type: integer
                        description: Límite aplicado en esta página
                        example: 20
                      offset:
                        type: integer
                        description: Offset aplicado en esta página
                        example: 0
                      items:
                        type: array
                        description: Lista de paradas devueltas en esta página
                        items:
                          type: object
                          required:
                            - stop_id
                            - stop_url
                            - internal_reference
                            - stop_title
                            - status
                            - created_at
                            - updated_at
                            - links_active_count
                          properties:
                            stop_id:
                              type: string
                              nullable: false
                              format: uuid
                              description: >-
                                Identificador único de la Parada SPIDI en
                                formato UUID. Este ID identifica de forma
                                permanente el espacio donde el cliente puede
                                consultar y gestionar todas sus solicitudes de
                                pago.
                              example: stp_f9317c1b-8a4f-4d7e-9f25-3a2b8b9a4f12
                            stop_url:
                              type: string
                              nullable: true
                              format: uri
                              description: >-
                                URL permanente y única de la Parada SPIDI. El
                                cliente puede visitar esta URL en cualquier
                                momento para consultar y pagar todas sus
                                solicitudes de pago activas o históricas, sin
                                necesidad de recibir nuevos enlaces cada vez.
                              example: >-
                                https://mispidi.com/s/stp_f9317c1b-8a4f-4d7e-9f25-3a2b8b9a4f12
                            stop_title:
                              type: string
                              nullable: false
                              description: >-
                                Título visible de la Parada SPIDI mostrado al
                                cliente. Generalmente se usa el nombre del
                                cliente, contrato o servicio asociado.
                              example: Federico Díaz
                            internal_reference:
                              type: string
                              nullable: false
                              description: >-
                                Referencia interna única utilizada por el
                                sistema o el comercio para identificar la
                                solicitud de pago o parada (propósito
                                estrictamente técnico,no visible al usuario
                                final).


                                **Importancia para Paradas SPIDI:**

                                - Permite conciliar y auditar operaciones entre
                                tu sistema y SPIDI

                                - Sirve para asociar solicitudes de pago con su
                                Parada correspondiente

                                - Puede vincularse a clientes, contratos o
                                facturas en tu plataforma


                                Se recomienda mantener este campo de forma
                                consistente para facilitar la trazabilidad.
                              example: '8233232'
                            empty_state_message:
                              type: string
                              nullable: true
                              description: >-
                                Mensaje personalizado mostrado al cliente cuando
                                la Parada no tiene solicitudes de pago activas
                                (estado Empty). Ejemplo: 'No tienes pagos
                                pendientes' o 'Actualmente no hay deudas
                                asociadas'.
                              example: No tienes pagos pendientes
                            status:
                              type: string
                              enum:
                                - active
                                - disabled
                                - empty
                                - deleted
                              description: >-
                                Estado de la Parada SPIDI.


                                **Estados disponibles:**


                                - **active**: La parada está activa. Si tiene al
                                menos un enlace de pago activo, se muestran los
                                pagos disponibles en una lista con su
                                identificador, monto y estado. Si no tiene
                                solicitudes de pago activas (estado Empty),
                                muestra el mensaje configurado en
                                `empty_state_message`.


                                - **disabled**: La parada está deshabilitada
                                temporalmente. Los clientes no pueden acceder a
                                ella, pero puede reactivarse cambiando el estado
                                a `active`.


                                **Nota:** Aunque no aparece en el enum, existe
                                un estado **deleted** que indica que la parada
                                fue eliminada definitivamente y no puede
                                recuperarse.
                              example: active
                            created_at:
                              type: string
                              format: date-time
                              description: Fecha y hora de creación en formato ISO 8601.
                            updated_at:
                              type: string
                              format: date-time
                              description: Fecha y hora de última actualización (ISO 8601)
                              example: '2025-09-30T10:12:34Z'
                            links_active_count:
                              type: integer
                              description: >-
                                Número de solicitudes de pago activas en la
                                parada
                              example: 1
              example:
                success: true
                message: Payment stops retrieved successfully.
                data:
                  total: 2
                  limit: 20
                  offset: 0
                  items:
                    - stop_id: stp_92f3a5e1-1c9f-4a23-bbcd-6d42b0a0a9f4
                      stop_url: >-
                        https://pay.spidi.com/s/stp_92f3a5e1-1c9f-4a23-bbcd-6d42b0a0a9f4
                      internal_reference: caja_001
                      stop_title: Caja Principal
                      empty_state_message: No hay pagos disponibles en este momento.
                      status: active
                      created_at: '2025-09-27T14:05:21Z'
                      updated_at: '2025-09-30T10:12:34Z'
                      links_active_count: 1
                    - stop_id: stp_a12f34cd-56ef-78ab-90cd-12ef34ab56cd
                      stop_url: >-
                        https://pay.spidi.com/s/stp_a12f34cd-56ef-78ab-90cd-12ef34ab56cd
                      internal_reference: condominio_torre_a
                      stop_title: Condominio Torre A
                      empty_state_message: No existen deudas registradas.
                      status: disabled
                      created_at: '2025-08-12T09:31:10Z'
                      updated_at: '2025-09-01T08:15:00Z'
                      links_active_count: 0
        '400':
          description: Parámetros de consulta inválidos
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    description: Siempre false en caso de error
                    example: false
                  message:
                    type: string
                    description: Resumen legible del error principal
                    example: 'Missing required field: stop_title'
                  errors:
                    type: object
                    description: Detalle por campo (opcional)
                    additionalProperties:
                      type: string
                    example:
                      stop_title: This field is required.
              example:
                success: false
                message: Invalid query parameters.
                errors:
                  status: 'Allowed values are: active, disabled.'
                  limit: Must be an integer between 1 and 200.
                  from_date: Must be a valid ISO 8601 datetime.
    post:
      summary: Crear Parada(s)
      description: >-
        Crea una o múltiples Paradas SPIDI en un mismo request.


        ## ¿Qué son las Paradas SPIDI?


        Las Paradas SPIDI son espacios únicos y permanentes asociados a cada
        cliente, donde este puede consultar, gestionar y pagar todas sus
        solicitudes de pago activas o históricas, sin necesidad de recibir
        nuevos solicitudes de pago cada vez.


        Funcionan como un punto de acceso trazable y constante, ideal para
        relaciones comerciales continuas, suscripciones o pagos recurrentes,
        simplificando la experiencia tanto para el pagador como para la empresa.


        ## Características principales


        - **URL permanente**: Cada parada posee una `stop_url` única que el
        cliente puede visitar en cualquier momento

        - **Gestión centralizada**: Desde esa URL, el cliente ve todas sus
        solicitudes de pago (pendientes, vencidas o completadas)

        - **Creación masiva**: Permite crear de 1 a N paradas en un solo
        request, ideal para procesos de onboarding inicial

        - **Idempotencia**: Soporta reintentos idempotentes mediante
        `Idempotency-Key`

        - **Asociación flexible**: Puede vincularse a un cliente específico o a
        múltiples referencias según las necesidades de tu plataforma


        ## Estados de una Parada


        - **Active**: Existe al menos un enlace de pago activo; se muestran los
        pagos disponibles

        - **Empty**: Sin solicitudes de pago activas; muestra el mensaje
        configurado en `empty_state_message`

        - **Disabled**: Deshabilitada temporalmente, pero puede reactivarse

        - **Deleted**: Eliminada definitivamente


        ## Integración técnica


        Se recomienda definir y mantener un campo `internal_reference` para cada
        recurso (cliente, contrato o factura), que servirá para conciliar y
        auditar operaciones entre tu sistema y SPIDI, y asociar solicitudes de
        pago con su Parada correspondiente.
      operationId: createStops
      tags:
        - Endpoints Parada
      security:
        - bearerAuth: []
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - continue_on_error
                - spidi_id
                - items
              properties:
                spidi_id:
                  type: string
                  nullable: false
                  description: Identificador único de tipo UUID para el usuario SPIDI
                  example: a966ce0d-3af3-415d-ba86-1db5a1c21cf0
                continue_on_error:
                  type: boolean
                  nullable: true
                  default: false
                  description: >-
                    Indica si el procesamiento debe continuar con el resto de
                    los ítems aunque alguno falle en operaciones de batch.

                    - Si es `false`, se detiene en el primer error y las
                    operaciones ya exitosas permanecen válidas. 

                    - Si es `true`, continúa procesando hasta el final y luego
                    reporta las fallas acumuladas.
                  example: true
                items:
                  type: array
                  description: Listado de paradas a crear (mínimo 1 ítem)
                  minItems: 1
                  items:
                    type: object
                    required:
                      - stop_title
                      - internal_reference
                    properties:
                      stop_title:
                        type: string
                        nullable: false
                        description: >-
                          Título visible de la Parada SPIDI mostrado al cliente.
                          Generalmente se usa el nombre del cliente, contrato o
                          servicio asociado.
                        example: Federico Díaz
                      internal_reference:
                        type: string
                        nullable: false
                        description: >-
                          Referencia interna única utilizada por el sistema o el
                          comercio para identificar la solicitud de pago o
                          parada (propósito estrictamente técnico,no visible al
                          usuario final).


                          **Importancia para Paradas SPIDI:**

                          - Permite conciliar y auditar operaciones entre tu
                          sistema y SPIDI

                          - Sirve para asociar solicitudes de pago con su Parada
                          correspondiente

                          - Puede vincularse a clientes, contratos o facturas en
                          tu plataforma


                          Se recomienda mantener este campo de forma consistente
                          para facilitar la trazabilidad.
                        example: '8233232'
                      empty_state_message:
                        type: string
                        nullable: true
                        description: >-
                          Mensaje personalizado mostrado al cliente cuando la
                          Parada no tiene solicitudes de pago activas (estado
                          Empty). Ejemplo: 'No tienes pagos pendientes' o
                          'Actualmente no hay deudas asociadas'.
                        example: No tienes pagos pendientes
                      status:
                        type: string
                        enum:
                          - active
                          - disabled
                        description: Estado inicial de la parada
                        default: active
                        example: active
            examples:
              single:
                summary: Crear una sola parada
                value:
                  continue_on_error: false
                  spidi_id: 88eab2b9-739e-11f0-9e3f-42010a1ce014
                  items:
                    - internal_reference: '8233232'
                      stop_title: Federico Díaz
                      empty_state_message: No tienes pagos pendientes
                      status: active
              batch:
                summary: Crear múltiples paradas
                value:
                  continue_on_error: false
                  spidi_id: 88eab2b9-739e-11f0-9e3f-42010a1ce014
                  items:
                    - internal_reference: '8233232'
                      stop_title: Federico Díaz
                      empty_state_message: No tienes pagos pendientes
                      status: active
                    - internal_reference: '8233235'
                      stop_title: Juan González
                      empty_state_message: No tienes pagos pendientes
                      status: active
      responses:
        '200':
          description: Batch procesado exitosamente
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                  - batch_id
                  - results
                properties:
                  success:
                    type: boolean
                    nullable: false
                    description: >-
                      Indica si la operación fue exitosa. True si el endpoint se
                      procesó de forma exitosa. False de lo contrario
                    example: true
                  message:
                    type: string
                    description: Mensaje de confirmación legible para humanos
                    example: 'Batch processed: 2 items created.'
                  batch_id:
                    type: string
                    nullable: false
                    description: Identificador único de un lote (batch) procesado.
                    example: batch_54fa7a9e-31f1-41f0-a6b9-2cd05662c721
                  results:
                    type: array
                    description: Lista de paradas creadas
                    items:
                      type: object
                      required:
                        - internal_reference
                        - success
                      properties:
                        internal_reference:
                          type: string
                          nullable: false
                          description: >-
                            Referencia interna única utilizada por el sistema o
                            el comercio para identificar la solicitud de pago o
                            parada (propósito estrictamente técnico,no visible
                            al usuario final).


                            **Importancia para Paradas SPIDI:**

                            - Permite conciliar y auditar operaciones entre tu
                            sistema y SPIDI

                            - Sirve para asociar solicitudes de pago con su
                            Parada correspondiente

                            - Puede vincularse a clientes, contratos o facturas
                            en tu plataforma


                            Se recomienda mantener este campo de forma
                            consistente para facilitar la trazabilidad.
                          example: '8233232'
                        success:
                          type: boolean
                          description: Indica si este item se creó exitosamente
                          example: true
                        data:
                          type: object
                          properties:
                            stop_id:
                              type: string
                              nullable: false
                              format: uuid
                              description: >-
                                Identificador único de la Parada SPIDI en
                                formato UUID. Este ID identifica de forma
                                permanente el espacio donde el cliente puede
                                consultar y gestionar todas sus solicitudes de
                                pago.
                              example: stp_f9317c1b-8a4f-4d7e-9f25-3a2b8b9a4f12
                            stop_url:
                              type: string
                              nullable: true
                              format: uri
                              description: >-
                                URL permanente y única de la Parada SPIDI. El
                                cliente puede visitar esta URL en cualquier
                                momento para consultar y pagar todas sus
                                solicitudes de pago activas o históricas, sin
                                necesidad de recibir nuevos enlaces cada vez.
                              example: >-
                                https://mispidi.com/s/stp_f9317c1b-8a4f-4d7e-9f25-3a2b8b9a4f12
                            stop_title:
                              type: string
                              nullable: false
                              description: >-
                                Título visible de la Parada SPIDI mostrado al
                                cliente. Generalmente se usa el nombre del
                                cliente, contrato o servicio asociado.
                              example: Federico Díaz
                            internal_reference:
                              type: string
                              nullable: false
                              description: >-
                                Referencia interna única utilizada por el
                                sistema o el comercio para identificar la
                                solicitud de pago o parada (propósito
                                estrictamente técnico,no visible al usuario
                                final).


                                **Importancia para Paradas SPIDI:**

                                - Permite conciliar y auditar operaciones entre
                                tu sistema y SPIDI

                                - Sirve para asociar solicitudes de pago con su
                                Parada correspondiente

                                - Puede vincularse a clientes, contratos o
                                facturas en tu plataforma


                                Se recomienda mantener este campo de forma
                                consistente para facilitar la trazabilidad.
                              example: '8233232'
                            empty_state_message:
                              type: string
                              nullable: true
                              description: >-
                                Mensaje personalizado mostrado al cliente cuando
                                la Parada no tiene solicitudes de pago activas
                                (estado Empty). Ejemplo: 'No tienes pagos
                                pendientes' o 'Actualmente no hay deudas
                                asociadas'.
                              example: No tienes pagos pendientes
                            status:
                              type: string
                              enum:
                                - active
                                - disabled
                                - empty
                                - deleted
                              description: >-
                                Estado de la Parada SPIDI.


                                **Estados disponibles:**


                                - **active**: La parada está activa. Si tiene al
                                menos un enlace de pago activo, se muestran los
                                pagos disponibles en una lista con su
                                identificador, monto y estado. Si no tiene
                                solicitudes de pago activas (estado Empty),
                                muestra el mensaje configurado en
                                `empty_state_message`.


                                - **disabled**: La parada está deshabilitada
                                temporalmente. Los clientes no pueden acceder a
                                ella, pero puede reactivarse cambiando el estado
                                a `active`.


                                **Nota:** Aunque no aparece en el enum, existe
                                un estado **deleted** que indica que la parada
                                fue eliminada definitivamente y no puede
                                recuperarse.
                              example: active
                            created_at:
                              type: string
                              format: date-time
                              description: Fecha y hora de creación en formato ISO 8601.
                        errors:
                          type: object
                          description: Detalles de error (solo si success=false)
                          additionalProperties:
                            type: string
              example:
                success: true
                message: 'Batch processed: 2 items created.'
                batch_id: batch_54fa7a9e-31f1-41f0-a6b9-2cd05662c721
                results:
                  - internal_reference: '8233232'
                    success: true
                    data:
                      stop_id: stp_f9317c1b-8a4f-4d7e-9f25-3a2b8b9a4f12
                      stop_url: >-
                        https://mispidi.com/s/stp_f9317c1b-8a4f-4d7e-9f25-3a2b8b9a4f12
                      stop_title: Federico Díaz
                      empty_state_message: No tienes pagos pendientes
                      status: active
                      created_at: '2025-09-27T14:15:43Z'
                  - internal_reference: '8233235'
                    success: true
                    data:
                      stop_id: stp_a12f34cd-56ef-78ab-90cd-12ef34ab56cd
                      stop_url: >-
                        https://mispidi.com/s/stp_a12f34cd-56ef-78ab-90cd-12ef34ab56cd
                      stop_title: Juan González
                      empty_state_message: No tienes pagos pendientes
                      status: active
                      created_at: '2025-09-27T14:15:43Z'
        '400':
          description: Solicitud inválida - Campo faltante
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    description: Siempre false en caso de error
                    example: false
                  message:
                    type: string
                    description: Resumen legible del error principal
                    example: 'Missing required field: stop_title'
                  errors:
                    type: object
                    description: Detalle por campo (opcional)
                    additionalProperties:
                      type: string
                    example:
                      stop_title: This field is required.
              example:
                success: false
                message: 'Missing required field: stop_title'
                errors:
                  stop_title: This field is required.
        '401':
          description: No autorizado - Credenciales incorrectas
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    description: Siempre false en caso de error
                    example: false
                  message:
                    type: string
                    description: Resumen legible del error principal
                    example: 'Missing required field: stop_title'
                  errors:
                    type: object
                    description: Detalle por campo (opcional)
                    additionalProperties:
                      type: string
                    example:
                      stop_title: This field is required.
              example:
                success: false
                message: Unauthorized.
                errors:
                  authentication: The credentials are incorrect
        '422':
          description: Entidad no procesable - Datos inválidos
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    description: Siempre false en caso de error
                    example: false
                  message:
                    type: string
                    description: Resumen legible del error principal
                    example: 'Missing required field: stop_title'
                  errors:
                    type: object
                    description: Detalle por campo (opcional)
                    additionalProperties:
                      type: string
                    example:
                      stop_title: This field is required.
              example:
                success: false
                message: Unprocessable entity.
                errors:
                  stop_title: Invalid value provided
        '500':
          description: Error interno del servidor
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    description: Siempre false en caso de error
                    example: false
                  message:
                    type: string
                    description: Resumen legible del error principal
                    example: 'Missing required field: stop_title'
                  errors:
                    type: object
                    description: Detalle por campo (opcional)
                    additionalProperties:
                      type: string
                    example:
                      stop_title: This field is required.
              example:
                success: false
                message: Internal server error.
  /api/v1/ext/payment-stops/{stop_id}:
    get:
      summary: Consultar Parada
      description: >-
        Consulta los detalles y metadatos de una Parada SPIDI específica.


        Devuelve información completa de la parada incluyendo:

        - Identificadores (`stop_id`, `stop_url`)

        - Metadatos configurables (`stop_title`, `empty_state_message`,
        `status`)

        - Referencia interna (`internal_reference`)

        - **Solo solicitudes de pago activas** (`links_active`)


        Para consultar el historial completo de solicitudes de pago (incluyendo
        pagados y expirados), utiliza el endpoint
        `/api/v1/ext/payment-stops/{stop_id}/payment-sessions`.
      operationId: getStopDetails
      tags:
        - Endpoints Parada
      security:
        - bearerAuth: []
      parameters:
        - name: stop_id
          in: path
          description: Identificador único de la parada (UUID)
          required: true
          schema:
            type: string
            format: uuid
            example: 7f8b2c6a-4d19-45df-9a10-3e872aa812c1
      responses:
        '200':
          description: Detalles de la parada obtenidos exitosamente
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                  - data
                properties:
                  success:
                    type: boolean
                    nullable: false
                    description: >-
                      Indica si la operación fue exitosa. True si el endpoint se
                      procesó de forma exitosa. False de lo contrario
                    example: true
                  message:
                    type: string
                    nullable: true
                    description: Mensaje de confirmación o error legible.
                  data:
                    type: object
                    required:
                      - stop_id
                      - stop_url
                      - internal_reference
                      - stop_title
                      - status
                      - created_at
                    properties:
                      stop_id:
                        type: string
                        nullable: false
                        format: uuid
                        description: >-
                          Identificador único de la Parada SPIDI en formato
                          UUID. Este ID identifica de forma permanente el
                          espacio donde el cliente puede consultar y gestionar
                          todas sus solicitudes de pago.
                        example: stp_f9317c1b-8a4f-4d7e-9f25-3a2b8b9a4f12
                      stop_url:
                        type: string
                        nullable: true
                        format: uri
                        description: >-
                          URL permanente y única de la Parada SPIDI. El cliente
                          puede visitar esta URL en cualquier momento para
                          consultar y pagar todas sus solicitudes de pago
                          activas o históricas, sin necesidad de recibir nuevos
                          enlaces cada vez.
                        example: >-
                          https://mispidi.com/s/stp_f9317c1b-8a4f-4d7e-9f25-3a2b8b9a4f12
                      stop_title:
                        type: string
                        nullable: false
                        description: >-
                          Título visible de la Parada SPIDI mostrado al cliente.
                          Generalmente se usa el nombre del cliente, contrato o
                          servicio asociado.
                        example: Federico Díaz
                      internal_reference:
                        type: string
                        nullable: false
                        description: >-
                          Referencia interna única utilizada por el sistema o el
                          comercio para identificar la solicitud de pago o
                          parada (propósito estrictamente técnico,no visible al
                          usuario final).


                          **Importancia para Paradas SPIDI:**

                          - Permite conciliar y auditar operaciones entre tu
                          sistema y SPIDI

                          - Sirve para asociar solicitudes de pago con su Parada
                          correspondiente

                          - Puede vincularse a clientes, contratos o facturas en
                          tu plataforma


                          Se recomienda mantener este campo de forma consistente
                          para facilitar la trazabilidad.
                        example: '8233232'
                      empty_state_message:
                        type: string
                        nullable: true
                        description: >-
                          Mensaje personalizado mostrado al cliente cuando la
                          Parada no tiene solicitudes de pago activas (estado
                          Empty). Ejemplo: 'No tienes pagos pendientes' o
                          'Actualmente no hay deudas asociadas'.
                        example: No tienes pagos pendientes
                      status:
                        type: string
                        enum:
                          - active
                          - disabled
                          - empty
                          - deleted
                        description: >-
                          Estado de la Parada SPIDI.


                          **Estados disponibles:**


                          - **active**: La parada está activa. Si tiene al menos
                          un enlace de pago activo, se muestran los pagos
                          disponibles en una lista con su identificador, monto y
                          estado. Si no tiene solicitudes de pago activas
                          (estado Empty), muestra el mensaje configurado en
                          `empty_state_message`.


                          - **disabled**: La parada está deshabilitada
                          temporalmente. Los clientes no pueden acceder a ella,
                          pero puede reactivarse cambiando el estado a `active`.


                          **Nota:** Aunque no aparece en el enum, existe un
                          estado **deleted** que indica que la parada fue
                          eliminada definitivamente y no puede recuperarse.
                        example: active
                      created_at:
                        type: string
                        format: date-time
                        description: Fecha y hora de creación en formato ISO 8601.
                      updated_at:
                        type: string
                        format: date-time
                        description: Fecha y hora de última actualización (ISO 8601)
                        example: '2025-09-30T10:12:34Z'
                      links_active:
                        type: array
                        description: Lista de solicitudes de pago activas en la parada
                        items:
                          type: object
                          required:
                            - session_id
                            - payment_url
                            - status
                            - amount
                            - currency_reference
                            - amount_ves
                          properties:
                            session_id:
                              type: string
                              nullable: false
                              description: >-
                                Identificador único de la sesión de pago,
                                accedible a través del payment_url.
                            payment_url:
                              type: string
                              nullable: true
                              description: >-
                                URL de la página segura SPIDI donde quien paga
                                realiza el pago.
                              example: >-
                                {{base_url}}/?id=3ddc4cfb-c09a-43de-92c1-e4a069732e90
                            status:
                              type: string
                              enum:
                                - pending
                                - paid
                                - expired
                              description: Estado del solicitud de pago.
                              example: pending
                            amount:
                              type: number
                              format: double
                              description: >-
                                Monto en la moneda de referencia para una
                                solicitud de pago.
                              example: 15.5
                            currency_reference:
                              type: string
                              nullable: false
                              enum:
                                - USD
                                - EUR
                                - COP
                                - USDT
                                - VES
                              description: >-
                                Moneda de referencia que se fija para el pago.
                                Usada para calcular el monto en bolívares con la
                                tasa vigente.
                            amount_ves:
                              type: number
                              description: >-
                                Monto en bolívares. Si el currency_reference es
                                diferente a VES, este monto se calculó con base
                                a la tasa. Posee 2 decimales
                              format: double
                            due_date_link:
                              type: string
                              nullable: true
                              format: date-time
                              description: >-
                                Fecha y hora límite de vencimiento de la
                                Solicitud SPIDI (link). 
                            expire_behavior_link:
                              type: string
                              nullable: true
                              enum:
                                - expire
                                - keep_active
                              description: >-
                                Comportamiento configurado para la Solicitud
                                SPIDI cuando alcanza su fecha de vencimiento. 
                            late_notice_message:
                              type: string
                              nullable: true
                              description: >-
                                Mensaje que verá el pagador cuando la sesión
                                haya vencido pero continúe activa
                                (keep_active). 
              example:
                success: true
                message: Payment stop details retrieved successfully.
                data:
                  stop_id: 7f8b2c6a-4d19-45df-9a10-3e872aa812c1
                  stop_url: https://pay.spidi.com/stop/7f8b2c6a
                  internal_reference: USER-2025-0931
                  stop_title: Caja Principal - Suscripción Premium
                  empty_state_message: Actualmente no tienes pagos pendientes.
                  status: active
                  created_at: '2025-02-10T15:42:00Z'
                  links_active:
                    - session_id: 21f43a2b-d9ff-42d2-87ce-559bdaf1f901
                      payment_url: >-
                        https://pay.spidi.com/21f43a2b-d9ff-42d2-87ce-559bdaf1f901
                      status: pending
                      amount: 15.5
                      currency_reference: USD
                      amount_ves: 1900
                      due_date_link: '2025-03-01T00:00:00Z'
                      expire_behavior_link: keep_active
                      late_notice_message: >-
                        Tu servicio está inactivo. Realiza el pago ahora para
                        recuperar la continuidad de tu suscripción.
        '404':
          description: Parada no encontrada
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    description: Siempre false en caso de error
                    example: false
                  message:
                    type: string
                    description: Resumen legible del error principal
                    example: 'Missing required field: stop_title'
                  errors:
                    type: object
                    description: Detalle por campo (opcional)
                    additionalProperties:
                      type: string
                    example:
                      stop_title: This field is required.
              example:
                success: false
                message: Payment stop not found.
                errors:
                  stop_id: No payment stop exists with the provided stop_id.
    patch:
      summary: Actualizar Parada
      description: >-
        Actualiza los metadatos de una Parada SPIDI existente.


        Permite modificar:

        - **stop_title**: Título visible de la parada

        - **status**: Estado de la parada (`active` o `disabled`)

        - **empty_state_message**: Mensaje mostrado cuando no hay solicitudes de
        pago activas


        Los campos `stop_id`, `stop_url` e `internal_reference` no pueden
        modificarse una vez creada la parada.
      operationId: updateStop
      tags:
        - Endpoints Parada
      security:
        - bearerAuth: []
      parameters:
        - name: stop_id
          in: path
          description: Identificador único de la parada (UUID)
          required: true
          schema:
            type: string
            format: uuid
            example: stp_9f82b1d3-6e9a-4b0a-9bcd-4fd3f2e5c8a7
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - stop_title
                - status
                - empty_state_message
              properties:
                stop_title:
                  type: string
                  description: Nuevo título visible de la parada
                  example: Caja Principal
                status:
                  type: string
                  enum:
                    - active
                    - disabled
                  description: Estado de la parada
                  example: disabled
                empty_state_message:
                  type: string
                  description: >-
                    Texto mostrado al pagador cuando no existan solicitudes de
                    pago activas en la parada
                  example: Actualmente no hay deudas asociadas a esta parada.
            example:
              stop_title: Caja Principal
              status: disabled
              empty_state_message: Actualmente no hay deudas asociadas a esta parada.
      responses:
        '200':
          description: Parada actualizada exitosamente
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                  - data
                properties:
                  success:
                    type: boolean
                    description: True si el endpoint se procesó de forma exitosa
                    example: true
                  message:
                    type: string
                    description: Mensaje de confirmación legible para humanos
                    example: Payment stop updated successfully.
                  data:
                    type: object
                    required:
                      - stop_id
                      - stop_url
                      - stop_title
                      - status
                      - empty_state_message
                      - updated_at
                    properties:
                      stop_id:
                        type: string
                        description: Identificador de la Parada SPIDI actualizada
                        example: stp_9f82b1d3-6e9a-4b0a-9bcd-4fd3f2e5c8a7
                      stop_url:
                        type: string
                        format: uri
                        description: URL permanente de la parada
                        example: >-
                          https://pay.spidi.com/stop/stp_9f82b1d3-6e9a-4b0a-9bcd-4fd3f2e5c8a7
                      stop_title:
                        type: string
                        description: Título de la parada actualizado
                        example: Caja Principal
                      status:
                        type: string
                        enum:
                          - active
                          - disabled
                        description: Estado de la parada
                        example: disabled
                      empty_state_message:
                        type: string
                        description: Mensaje cuando no hay solicitudes de pago activas
                        example: Actualmente no hay deudas asociadas a esta parada.
                      updated_at:
                        type: string
                        format: date-time
                        description: Fecha y hora de actualización (ISO 8601)
                        example: '2025-09-29T14:45:12Z'
              example:
                success: true
                message: Payment stop updated successfully.
                data:
                  stop_id: stp_9f82b1d3-6e9a-4b0a-9bcd-4fd3f2e5c8a7
                  stop_url: >-
                    https://pay.spidi.com/stop/stp_9f82b1d3-6e9a-4b0a-9bcd-4fd3f2e5c8a7
                  stop_title: Caja Principal
                  status: disabled
                  empty_state_message: Actualmente no hay deudas asociadas a esta parada.
                  updated_at: '2025-09-29T14:45:12Z'
        '400':
          description: Solicitud inválida - Campo faltante
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    description: Siempre false en caso de error
                    example: false
                  message:
                    type: string
                    description: Resumen legible del error principal
                    example: 'Missing required field: stop_title'
                  errors:
                    type: object
                    description: Detalle por campo (opcional)
                    additionalProperties:
                      type: string
                    example:
                      stop_title: This field is required.
              example:
                success: false
                message: 'Missing required field: stop_title'
                errors:
                  stop_title: This field is required.
        '401':
          description: No autorizado - Credenciales incorrectas
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    description: Siempre false en caso de error
                    example: false
                  message:
                    type: string
                    description: Resumen legible del error principal
                    example: 'Missing required field: stop_title'
                  errors:
                    type: object
                    description: Detalle por campo (opcional)
                    additionalProperties:
                      type: string
                    example:
                      stop_title: This field is required.
              example:
                success: false
                message: Unauthorized.
        '422':
          description: Entidad no procesable - Datos inválidos
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    description: Siempre false en caso de error
                    example: false
                  message:
                    type: string
                    description: Resumen legible del error principal
                    example: 'Missing required field: stop_title'
                  errors:
                    type: object
                    description: Detalle por campo (opcional)
                    additionalProperties:
                      type: string
                    example:
                      stop_title: This field is required.
              example:
                success: false
                message: Unprocessable entity.
                errors:
                  stop_title: Invalid value provided
        '500':
          description: Error interno del servidor
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    description: Siempre false en caso de error
                    example: false
                  message:
                    type: string
                    description: Resumen legible del error principal
                    example: 'Missing required field: stop_title'
                  errors:
                    type: object
                    description: Detalle por campo (opcional)
                    additionalProperties:
                      type: string
                    example:
                      stop_title: This field is required.
              example:
                success: false
                message: Internal server error.
    delete:
      summary: Eliminar Parada
      description: >-
        Elimina definitivamente una Parada SPIDI.


        **⚠️ Importante:**

        - La eliminación es **permanente** y no se puede revertir

        - **No se permite eliminar** una parada que tenga solicitudes de pago
        activas asociadas; primero debes removerlos o expirarlos

        - La operación es **idempotente**: múltiples llamadas con la misma
        `Idempotency-Key` no crearán duplicados


        ** Recomendación:** En lugar de eliminar, considera deshabilitar la
        parada usando el endpoint PATCH con `status: "disabled"`. Esto permite
        reactivarla en el futuro si es necesario.
      operationId: deleteStop
      tags:
        - Endpoints Parada
      security:
        - bearerAuth: []
      parameters:
        - name: stop_id
          in: path
          description: Identificador único de la parada (UUID)
          required: true
          schema:
            type: string
            format: uuid
            example: stp_9f82b1d3-6e9a-4b0a-9bcd-4fd3f2e5c8a7
      responses:
        '200':
          description: Parada eliminada exitosamente
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                  - data
                properties:
                  success:
                    type: boolean
                    description: True si el endpoint se procesó de forma exitosa
                    example: true
                  message:
                    type: string
                    description: Mensaje de confirmación legible para humanos
                    example: Payment stop deleted successfully.
                  data:
                    type: object
                    required:
                      - stop_id
                      - deleted_at
                    properties:
                      stop_id:
                        type: string
                        description: Identificador de la Parada SPIDI eliminada
                        example: stp_9f82b1d3-6e9a-4b0a-9bcd-4fd3f2e5c8a7
                      deleted_at:
                        type: string
                        format: date-time
                        description: Fecha y hora de eliminación (ISO 8601)
                        example: '2025-09-30T16:12:04Z'
              example:
                success: true
                message: Payment stop deleted successfully.
                data:
                  stop_id: stp_9f82b1d3-6e9a-4b0a-9bcd-4fd3f2e5c8a7
                  deleted_at: '2025-09-30T16:12:04Z'
        '400':
          description: Solicitud inválida - Campo faltante
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    description: Siempre false en caso de error
                    example: false
                  message:
                    type: string
                    description: Resumen legible del error principal
                    example: 'Missing required field: stop_title'
                  errors:
                    type: object
                    description: Detalle por campo (opcional)
                    additionalProperties:
                      type: string
                    example:
                      stop_title: This field is required.
              example:
                success: false
                message: 'Missing required field: stop_id'
                errors:
                  stop_id: This field is required.
        '403':
          description: Prohibido - Sin permisos
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    description: Siempre false en caso de error
                    example: false
                  message:
                    type: string
                    description: Resumen legible del error principal
                    example: 'Missing required field: stop_title'
                  errors:
                    type: object
                    description: Detalle por campo (opcional)
                    additionalProperties:
                      type: string
                    example:
                      stop_title: This field is required.
              example:
                success: false
                message: You are not allowed to delete this payment stop.
                errors:
                  authorization: The stop does not belong to your spidi_id or credentials.
        '404':
          description: Parada no encontrada
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    description: Siempre false en caso de error
                    example: false
                  message:
                    type: string
                    description: Resumen legible del error principal
                    example: 'Missing required field: stop_title'
                  errors:
                    type: object
                    description: Detalle por campo (opcional)
                    additionalProperties:
                      type: string
                    example:
                      stop_title: This field is required.
              example:
                success: false
                message: Payment stop not found.
                errors:
                  stop_id: No payment stop exists with the provided stop_id.
        '500':
          description: Error interno del servidor
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    description: Siempre false en caso de error
                    example: false
                  message:
                    type: string
                    description: Resumen legible del error principal
                    example: 'Missing required field: stop_title'
                  errors:
                    type: object
                    description: Detalle por campo (opcional)
                    additionalProperties:
                      type: string
                    example:
                      stop_title: This field is required.
              example:
                success: false
                message: Internal server error.
  /api/v1/ext/payment-stops/{stop_id}/payment-sessions:
    get:
      summary: Consultar Históricos de Solicitudes de Parada
      description: >-
        Consulta el historial completo de solicitudes de pago asociados a una
        Parada SPIDI.


        Devuelve la lista completa de solicitudes de pago asociados a un
        `stop_id`, incluyendo:

        - **Sesiones de Pago Activas** (`pending`)

        - **Sesiones de Pago Pagadas ** (`paid`)

        - **Sesiones de Pago Expiradas** (`expired`)


        Soporta filtros avanzados por estado, rango de fechas y paginación para
        manejar colecciones grandes.


        **Diferencia con ```GET /payment-stops/{stop_id}```:**

        - El endpoint básico solo devuelve solicitudes de pago activas

        - Este endpoint devuelve el historial completo con opciones de filtrado
        y paginación
      operationId: getStopPaymentSessionsHistory
      tags:
        - Endpoints Parada
      security:
        - bearerAuth: []
      parameters:
        - name: stop_id
          in: path
          description: Identificador único de la parada (UUID)
          required: true
          schema:
            type: string
            format: uuid
            example: 7f8b2c6a-4d19-45df-9a10-3e872aa812c1
        - name: status
          in: query
          description: Filtra por estado del link. Si se omite, se devuelven todos
          required: false
          schema:
            type: string
            enum:
              - pending
              - paid
              - expired
            example: pending
        - name: from_date
          in: query
          description: >-
            ISO 8601 (UTC). Devuelve elementos creados desde esta fecha/hora
            (inclusive)
          required: false
          schema:
            type: string
            format: date-time
            example: '2025-01-01T00:00:00Z'
        - name: to_date
          in: query
          description: >-
            ISO 8601 (UTC). Devuelve elementos creados hasta esta fecha/hora
            (inclusive)
          required: false
          schema:
            type: string
            format: date-time
            example: '2025-12-31T23:59:59Z'
        - name: limit
          in: query
          description: Máximo de elementos a devolver
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 200
            default: 50
            example: 20
        - name: offset
          in: query
          description: Desplazamiento para paginación
          required: false
          schema:
            type: integer
            minimum: 0
            default: 0
            example: 0
        - name: sort
          in: query
          description: Orden de los resultados
          required: false
          schema:
            type: string
            enum:
              - created_desc
              - created_asc
              - updated_desc
              - updated_asc
            default: created_desc
            example: created_desc
      responses:
        '200':
          description: Enlaces obtenidos exitosamente
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                  - data
                properties:
                  success:
                    type: boolean
                    description: True si el endpoint se procesó de forma exitosa
                    example: true
                  message:
                    type: string
                    description: Mensaje de confirmación legible para humanos
                    example: PaymentSessions retrieved successfully.
                  data:
                    type: object
                    required:
                      - stop_id
                      - total
                      - limit
                      - offset
                      - items
                    properties:
                      stop_id:
                        type: string
                        description: Identificador de la Parada SPIDI
                        example: 7f8b2c6a-4d19-45df-9a10-3e872aa812c1
                      total:
                        type: integer
                        description: >-
                          Total de solicitudes de pago que cumplen con los
                          filtros aplicados
                        example: 3
                      limit:
                        type: integer
                        description: Límite aplicado en esta página
                        example: 20
                      offset:
                        type: integer
                        description: Offset aplicado en esta página
                        example: 0
                      items:
                        type: array
                        description: Lista de solicitudes de pago (activos e históricos)
                        items:
                          type: object
                          required:
                            - session_id
                            - status
                            - payment_url
                            - created_at
                            - updated_at
                            - amount
                            - currency_reference
                            - amount_ves
                            - bcv_exchange_rate
                            - exchange_rate_from
                            - exchange_rate_to
                            - identifier_label
                            - identifier
                            - description
                          properties:
                            session_id:
                              type: string
                              description: Identificador único de la sesión de pago
                              example: 21f43a2b-d9ff-42d2-87ce-559bdaf1f901
                            status:
                              type: string
                              enum:
                                - pending
                                - paid
                                - expired
                              description: Estado del enlace
                              example: pending
                            payment_url:
                              type: string
                              format: uri
                              description: URL donde el usuario puede realizar el pago
                              example: >-
                                https://pay.spidi.com/21f43a2b-d9ff-42d2-87ce-559bdaf1f901
                            created_at:
                              type: string
                              format: date-time
                              description: Fecha/hora de creación (ISO 8601)
                              example: '2025-02-15T12:30:22Z'
                            updated_at:
                              type: string
                              format: date-time
                              description: Última actualización (ISO 8601)
                              example: '2025-02-15T12:31:10Z'
                            amount:
                              type: number
                              format: double
                              description: Monto en la moneda de referencia
                              example: 15.5
                            currency_reference:
                              type: string
                              enum:
                                - USD
                                - EUR
                                - COP
                                - VES
                              description: Moneda de referencia
                              example: USD
                            amount_ves:
                              type: number
                              format: double
                              description: Monto calculado en bolívares
                              example: 1900
                            bcv_exchange_rate:
                              type: number
                              format: double
                              description: Tasa oficial usada para la conversión
                              example: 122.58
                            exchange_rate_from:
                              type: string
                              description: Moneda base de la tasa
                              example: USD
                            exchange_rate_to:
                              type: string
                              description: Moneda destino de la tasa (siempre VES)
                              example: VES
                            identifier_label:
                              type: string
                              description: Etiqueta del identificador
                              example: Suscriptor
                            identifier:
                              type: string
                              description: Identificador del pagador
                              example: Juan Pérez
                            description:
                              type: string
                              description: Descripción del pago
                              example: Mensualidad febrero
                            due_date_link:
                              type: string
                              format: date-time
                              description: Fecha y hora límite de vencimiento
                              example: '2025-03-01T00:00:00Z'
                            expire_behavior_link:
                              type: string
                              enum:
                                - expire
                                - keep_active
                              description: Comportamiento al vencer
                              example: keep_active
                            late_notice_message:
                              type: string
                              description: >-
                                Mensaje mostrado si el enlace está vencido pero
                                activo
                              example: Tu servicio está inactivo. Paga para reactivar.
                            paid_at:
                              type: string
                              format: date-time
                              description: Fecha/hora de pago (solo si status = paid)
                              example: '2025-01-30T17:05:33Z'
                            expired_at:
                              type: string
                              format: date-time
                              description: >-
                                Fecha/hora de expiración (solo si status =
                                expired)
                              example: '2025-01-10T10:20:15Z'
              example:
                stop_id: stp_123
                page: 1
                page_size: 20
                total: 2
                has_next: false
                items:
                  - session_id: sess_A
                    payment_url: https://pay.spidi.io/sess_A
                    status: pending
                    amount:
                      value: '15.00'
                      currency: USD_BCV
                    amount_bs:
                      value: Bs. 552,00
                      rate_date: '2025-10-16'
                    created_at: '2025-10-15T14:25:32Z'
                    expires_at: '2025-10-15T14:35:32Z'
                    order_index: 0
                  - session_id: sess_B
                    payment_url: https://pay.spidi.io/sess_B
                    status: pending
                    amount:
                      value: 120.000.000,00
                      currency: VES
                    created_at: '2025-10-15T12:01:10Z'
                    expires_at: '2025-10-15T12:11:10Z'
                    order_index: 1
        '400':
          description: Parámetros de consulta inválidos
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    description: Siempre false en caso de error
                    example: false
                  message:
                    type: string
                    description: Resumen legible del error principal
                    example: 'Missing required field: stop_title'
                  errors:
                    type: object
                    description: Detalle por campo (opcional)
                    additionalProperties:
                      type: string
                    example:
                      stop_title: This field is required.
              example:
                success: false
                message: Invalid query parameters.
                errors:
                  status: 'Allowed: pending, paid, expired, active, historical.'
                  page_size: Must be between 1 and 200.
        '404':
          description: Parada no encontrada
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    description: Siempre false en caso de error
                    example: false
                  message:
                    type: string
                    description: Resumen legible del error principal
                    example: 'Missing required field: stop_title'
                  errors:
                    type: object
                    description: Detalle por campo (opcional)
                    additionalProperties:
                      type: string
                    example:
                      stop_title: This field is required.
              example:
                success: false
                message: Stop not found.
  /api/v1/ext/payment-stops/payment-sessions/batch:
    post:
      summary: Operar en Lote Enlaces de Paradas
      description: >-
        Ejecuta operaciones en lote para asociar/desasociar/reemplazar/limpiar
        sesiones de pago (`session_id`) visibles en una o varias Paradas
        (`stop_id`) en una sola llamada.


        **Operaciones soportadas:**

        - **add**: Agrega 1..N `session_id` como activos (si ya estaban, es
        no-op y se reportan en `already_present`)

        - **remove**: Desasocia 1..N `session_id` activos (si no estaban
        activos, se reportan en `not_active` o `not_found`)

        - **replace**: Sustituye atómicamente el conjunto activo por
        `session_ids`. Con lista vacía ⇒ `clear`

        - **clear**: Elimina todos los activos (la Parada puede quedar en estado
        Empty)


        **Características:**

        - Idempotente mediante encabezado `Idempotency-Key` (TTL: 24 horas)

        - Cada ítem se procesa de forma independiente

        - El resultado se devuelve por Parada

        - Rate limit: 100 requests/minuto por comercio


        **Notas importantes:**

        - Solo sesiones `pending` pueden activarse (`add`/`replace`). Las
        sesiones `paid`/`expired` pasan a histórico automáticamente

        - `replace` con lista vacía equivale a `clear` (limpieza atómica)

        - Usa siempre `Idempotency-Key` en operaciones en lote

        - Máximo 100 items por batch
      operationId: batchOperateStopPaymentSessions
      tags:
        - Endpoints Publicar
      security:
        - bearerAuth: []
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - continue_on_error
                - items
              properties:
                continue_on_error:
                  type: boolean
                  nullable: true
                  default: false
                  description: >-
                    Indica si el procesamiento debe continuar con el resto de
                    los ítems aunque alguno falle en operaciones de batch.

                    - Si es `false`, se detiene en el primer error y las
                    operaciones ya exitosas permanecen válidas. 

                    - Si es `true`, continúa procesando hasta el final y luego
                    reporta las fallas acumuladas.
                  example: true
                items:
                  type: array
                  minItems: 1
                  items:
                    type: object
                    required:
                      - stop_id
                      - op
                    properties:
                      stop_id:
                        type: string
                        description: >-
                          Identificador de la Parada sobre la que se ejecuta la
                          operación. Debe pertenecer al comercio autenticado.
                        example: stp_111
                      op:
                        type: string
                        enum:
                          - add
                          - remove
                          - replace
                          - clear
                        description: >-
                          Operación a ejecutar: **add** (agregar sesiones),
                          **remove** (desasociar sesiones), **replace**
                          (reemplazar conjunto activo), **clear** (limpiar todos
                          los activos)
                        example: add
                      session_ids:
                        type: array
                        items:
                          type: string
                        description: >-
                          IDs de sesiones involucradas. Requerido para
                          operaciones add, remove y replace. Solo sesiones en
                          estado **pending** pueden activarse (add/replace).
                        example:
                          - sess_A
                          - sess_B
                  description: >-
                    Lista de operaciones por Parada. Debe contener al menos 1
                    ítem.
                  example:
                    - stop_id: stp_111
                      op: add
                      session_ids:
                        - sess_A
                        - sess_B
                    - stop_id: stp_222
                      op: remove
                      session_ids:
                        - sess_C
                    - stop_id: stp_333
                      op: replace
                      session_ids:
                        - sess_D
                    - stop_id: stp_444
                      op: clear
            examples:
              mixed_operations:
                summary: Operaciones mixtas en múltiples paradas
                value:
                  continue_on_error: true
                  items:
                    - stop_id: stp_111
                      op: add
                      session_ids:
                        - sess_A
                        - sess_B
                    - stop_id: stp_222
                      op: remove
                      session_ids:
                        - sess_C
                    - stop_id: stp_333
                      op: replace
                      session_ids:
                        - sess_D
                    - stop_id: stp_444
                      op: clear
      responses:
        '201':
          description: Batch procesado exitosamente - todas las operaciones completadas
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                  - batch_id
                  - results
                properties:
                  success:
                    type: boolean
                    nullable: false
                    description: >-
                      Indica si la operación fue exitosa. True si el endpoint se
                      procesó de forma exitosa. False de lo contrario
                    example: true
                  message:
                    type: string
                    nullable: true
                    description: Mensaje de confirmación o error legible.
                  batch_id:
                    type: string
                    nullable: false
                    description: Identificador único de un lote (batch) procesado.
                    example: batch_54fa7a9e-31f1-41f0-a6b9-2cd05662c721
                  results:
                    type: array
                    items:
                      type: object
                      required:
                        - stop_id
                        - op
                        - success
                      properties:
                        stop_id:
                          type: string
                          nullable: false
                          format: uuid
                          description: >-
                            Identificador único de la Parada SPIDI en formato
                            UUID. Este ID identifica de forma permanente el
                            espacio donde el cliente puede consultar y gestionar
                            todas sus solicitudes de pago.
                          example: stp_f9317c1b-8a4f-4d7e-9f25-3a2b8b9a4f12
                        op:
                          type: string
                          nullable: false
                          enum:
                            - add
                            - remove
                            - replace
                            - clear
                          description: >-
                            Operación para batch: add | remove | replace |
                            clear.
                        success:
                          type: boolean
                          nullable: false
                          description: >-
                            Indica si la operación fue exitosa. True si el
                            endpoint se procesó de forma exitosa. False de lo
                            contrario
                          example: true
                        errors:
                          type: object
                          description: >-
                            Detalle de errores solo si success=false en
                            operaciones batch
                          additionalProperties:
                            type: string
                        added:
                          type: array
                          items:
                            type: string
                          description: Sesiones agregadas como activas (operación add)
                        already_present:
                          type: array
                          items:
                            type: string
                          description: Sesiones ya activas, no-op (operación add)
                        removed:
                          type: array
                          nullable: true
                          description: >-
                            Sesiones desasociadas de activos en Parada
                            (op=remove).
                          items:
                            type: string
                        not_active:
                          type: array
                          nullable: true
                          description: Solicitudes SPIDI no activas en Parada.
                          items:
                            type: string
                        not_found:
                          type: array
                          nullable: true
                          description: Sesiones no encontradas en Parada.
                          items:
                            type: string
                        active_now:
                          type: array
                          items:
                            type: string
                          description: >-
                            Conjunto final de activos tras la operación
                            (operación replace)
                        replaced_previous:
                          type: array
                          nullable: true
                          description: >-
                            Sesiones que dejaron de estar activas en Parada
                            (op=replace).
                          items:
                            type: string
                        cleared:
                          type: boolean
                          nullable: false
                          description: >-
                            Indica si se aplicó una operación de limpieza
                            (`op=clear`) sobre las Solicitudes SPIDI activas en
                            la parada.
                    description: Resultado por ítem (por stop_id/op)
                    example:
                      - stop_id: stp_111
                        op: add
                        success: true
                        added:
                          - sess_A
                          - sess_B
                        already_present: []
                      - stop_id: stp_222
                        op: remove
                        success: true
                        removed:
                          - sess_C
                        not_active: []
                        not_found: []
                      - stop_id: stp_333
                        op: replace
                        success: true
                        active_now:
                          - sess_D
                        replaced_previous:
                          - sess_X
                      - stop_id: stp_444
                        op: clear
                        success: true
                        cleared: true
              examples:
                full_success:
                  summary: Éxito total
                  value:
                    success: true
                    message: 'Batch processed: 4 items succeeded.'
                    batch_id: batch_9a1b2c3d-ef45-6789-abcd-0123456789ab
                    results:
                      - stop_id: stp_111
                        op: add
                        success: true
                        added:
                          - sess_A
                          - sess_B
                        already_present: []
                      - stop_id: stp_222
                        op: remove
                        success: true
                        removed:
                          - sess_C
                        not_active: []
                        not_found: []
                      - stop_id: stp_333
                        op: replace
                        success: true
                        active_now:
                          - sess_D
                        replaced_previous:
                          - sess_X
                      - stop_id: stp_444
                        op: clear
                        success: true
                        cleared: true
        '207':
          description: >-
            Multi-Status - Batch procesado con resultados mixtos (algunos
            éxitos, algunos fallos)
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                  - batch_id
                  - results
                properties:
                  success:
                    type: boolean
                    nullable: false
                    description: >-
                      Indica si la operación fue exitosa. True si el endpoint se
                      procesó de forma exitosa. False de lo contrario
                    example: true
                  message:
                    type: string
                    nullable: true
                    description: Mensaje de confirmación o error legible.
                  batch_id:
                    type: string
                    nullable: false
                    description: Identificador único de un lote (batch) procesado.
                    example: batch_54fa7a9e-31f1-41f0-a6b9-2cd05662c721
                  results:
                    type: array
                    items:
                      type: object
                      required:
                        - stop_id
                        - op
                        - success
                      properties:
                        stop_id:
                          type: string
                          nullable: false
                          format: uuid
                          description: >-
                            Identificador único de la Parada SPIDI en formato
                            UUID. Este ID identifica de forma permanente el
                            espacio donde el cliente puede consultar y gestionar
                            todas sus solicitudes de pago.
                          example: stp_f9317c1b-8a4f-4d7e-9f25-3a2b8b9a4f12
                        op:
                          type: string
                          nullable: false
                          enum:
                            - add
                            - remove
                            - replace
                            - clear
                          description: >-
                            Operación para batch: add | remove | replace |
                            clear.
                        success:
                          type: boolean
                          nullable: false
                          description: >-
                            Indica si la operación fue exitosa. True si el
                            endpoint se procesó de forma exitosa. False de lo
                            contrario
                          example: true
                        errors:
                          type: object
                          description: >-
                            Detalle de errores solo si success=false en
                            operaciones batch
                          additionalProperties:
                            type: string
                        added:
                          type: array
                          items:
                            type: string
                          description: Sesiones agregadas como activas (operación add)
                        already_present:
                          type: array
                          items:
                            type: string
                          description: Sesiones ya activas, no-op (operación add)
                        removed:
                          type: array
                          nullable: true
                          description: >-
                            Sesiones desasociadas de activos en Parada
                            (op=remove).
                          items:
                            type: string
                        not_active:
                          type: array
                          nullable: true
                          description: Solicitudes SPIDI no activas en Parada.
                          items:
                            type: string
                        not_found:
                          type: array
                          nullable: true
                          description: Sesiones no encontradas en Parada.
                          items:
                            type: string
                        active_now:
                          type: array
                          items:
                            type: string
                          description: >-
                            Conjunto final de activos tras la operación
                            (operación replace)
                        replaced_previous:
                          type: array
                          nullable: true
                          description: >-
                            Sesiones que dejaron de estar activas en Parada
                            (op=replace).
                          items:
                            type: string
                        cleared:
                          type: boolean
                          nullable: false
                          description: >-
                            Indica si se aplicó una operación de limpieza
                            (`op=clear`) sobre las Solicitudes SPIDI activas en
                            la parada.
                    description: Resultado por ítem (por stop_id/op)
                    example:
                      - stop_id: stp_111
                        op: add
                        success: true
                        added:
                          - sess_A
                          - sess_B
                        already_present: []
                      - stop_id: stp_222
                        op: remove
                        success: true
                        removed:
                          - sess_C
                        not_active: []
                        not_found: []
                      - stop_id: stp_333
                        op: replace
                        success: true
                        active_now:
                          - sess_D
                        replaced_previous:
                          - sess_X
                      - stop_id: stp_444
                        op: clear
                        success: true
                        cleared: true
              examples:
                partial_errors:
                  summary: Éxito parcial con errores
                  value:
                    success: false
                    message: >-
                      Batch processed with partial errors: 3 succeeded, 1
                      failed.
                    batch_id: batch_1c2d3e4f-5566-7788-99aa-bbccddeeff00
                    results:
                      - stop_id: stp_111
                        op: add
                        success: true
                        added:
                          - sess_A
                        already_present:
                          - sess_B
                      - stop_id: stp_222
                        op: remove
                        success: true
                        removed: []
                        not_active:
                          - sess_C
                        not_found: []
                      - stop_id: stp_333
                        op: replace
                        success: false
                        errors:
                          session_ids[0]: >-
                            Session is not pending (paid/expired cannot be set
                            active).
                      - stop_id: stp_444
                        op: clear
                        success: true
                        cleared: true
        '400':
          description: >-
            Bad Request - Payload inválido, campos requeridos faltantes, formato
            incorrecto
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    nullable: false
                    description: >-
                      Indica si la operación fue exitosa. True si el endpoint se
                      procesó de forma exitosa. False de lo contrario
                    example: true
                  message:
                    type: string
                    nullable: true
                    description: Mensaje de confirmación o error legible.
                  errors:
                    type: object
                    nullable: true
                    description: Detalles específicos de los errores de validación.
              example:
                success: false
                message: Invalid batch payload.
                errors:
                  items: Must be a non-empty array.
                  items[0].op: 'Allowed values are: add, remove, replace, clear.'
                  items[1].session_ids: Required for op=add/remove/replace.
        '401':
          description: Unauthorized - Token de autorización faltante o inválido
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    nullable: false
                    description: >-
                      Indica si la operación fue exitosa. True si el endpoint se
                      procesó de forma exitosa. False de lo contrario
                    example: true
                  message:
                    type: string
                    nullable: true
                    description: Mensaje de confirmación o error legible.
                  errors:
                    type: object
                    nullable: true
                    description: Detalles específicos de los errores de validación.
              example:
                success: false
                message: Unauthorized.
        '409':
          description: >-
            Conflict - Conflicto de idempotencia, clave ya utilizada con payload
            diferente
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    nullable: false
                    description: >-
                      Indica si la operación fue exitosa. True si el endpoint se
                      procesó de forma exitosa. False de lo contrario
                    example: true
                  message:
                    type: string
                    nullable: true
                    description: Mensaje de confirmación o error legible.
                  errors:
                    type: object
                    nullable: true
                    description: Detalles específicos de los errores de validación.
              example:
                success: false
                message: Idempotency conflict.
                errors:
                  Idempotency-Key: >-
                    A different payload was previously submitted with the same
                    key.
        '422':
          description: >-
            Unprocessable Entity - Reglas de negocio violadas, sesiones no
            válidas, paradas no autorizadas
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    nullable: false
                    description: >-
                      Indica si la operación fue exitosa. True si el endpoint se
                      procesó de forma exitosa. False de lo contrario
                    example: true
                  message:
                    type: string
                    nullable: true
                    description: Mensaje de confirmación o error legible.
                  errors:
                    type: object
                    nullable: true
                    description: Detalles específicos de los errores de validación.
              example:
                success: false
                message: Unprocessable entity.
                errors:
                  items[2].session_ids[0]: Session is not pending (paid/expired cannot be set active).
                  items[3].stop_id: Stop does not belong to your commerce credentials.
        '429':
          description: Too Many Requests - Rate limit excedido
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    nullable: false
                    description: >-
                      Indica si la operación fue exitosa. True si el endpoint se
                      procesó de forma exitosa. False de lo contrario
                    example: true
                  message:
                    type: string
                    nullable: true
                    description: Mensaje de confirmación o error legible.
                  errors:
                    type: object
                    nullable: true
                    description: Detalles específicos de los errores de validación.
              example:
                success: false
                message: 'Too many requests. Limit: 100 requests/minute.'
          headers:
            Retry-After:
              description: Segundos hasta que se puede reintentar
              schema:
                type: integer
                example: 45
            X-RateLimit-Limit:
              description: Límite de requests por ventana
              schema:
                type: integer
                example: 100
            X-RateLimit-Remaining:
              description: Requests restantes en la ventana actual
              schema:
                type: integer
                example: 0
            X-RateLimit-Reset:
              description: Timestamp Unix cuando se resetea el límite
              schema:
                type: integer
                example: 1702814181
        '500':
          description: >-
            Internal Server Error - Error interno del servidor, problemas de
            conectividad
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    nullable: false
                    description: >-
                      Indica si la operación fue exitosa. True si el endpoint se
                      procesó de forma exitosa. False de lo contrario
                    example: true
                  message:
                    type: string
                    nullable: true
                    description: Mensaje de confirmación o error legible.
                  errors:
                    type: object
                    nullable: true
                    description: Detalles específicos de los errores de validación.
              example:
                success: false
                message: Internal server error.
  /api/v1/ext/payment-stops/payment-sessions/reorder:
    patch:
      summary: Reordenar Sesiones en Paradas
      description: >-
        Define el orden de visualización de los solicitudes de pago activas
        (derivados de sesiones `session_id`) dentro de una o varias Paradas
        (`stop_id`) en una sola llamada.


        **Características:**

        - No agrega ni quita sesiones; **solo** cambia el **orden**

        - Idempotente mediante `Idempotency-Key` (TTL: 24 horas)

        - Control de concurrencia opcional mediante `order_version`
        (recomendado)

        - Rate limit: 100 requests/minuto por comercio


        **Modos de operación:**

        - **append** (default): reordena las sesiones listadas arriba y
        cualquier activa no listada queda al final manteniendo su orden relativo
        actual

        - **strict**: la lista debe representar exactamente el conjunto de
        activos; si falta alguna activa o sobra alguna no activa, se devuelve
        error por ítem


        **Notas importantes:**

        - Separación de responsabilidades: usa `reorder` solo para ordenar. Para
        agregar/quitar/sustituir, utiliza el batch de operar solicitudes de pago

        - Idempotencia siempre: envía `Idempotency-Key`; misma clave + mismo
        payload ⇒ misma respuesta

        - Máximo 100 items por batch
      operationId: reorderStopPaymentSessions
      tags:
        - Endpoints Publicar
      security:
        - bearerAuth: []
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - continue_on_error
                - items
              properties:
                continue_on_error:
                  type: boolean
                  nullable: true
                  default: false
                  description: >-
                    Indica si el procesamiento debe continuar con el resto de
                    los ítems aunque alguno falle en operaciones de batch.

                    - Si es `false`, se detiene en el primer error y las
                    operaciones ya exitosas permanecen válidas. 

                    - Si es `true`, continúa procesando hasta el final y luego
                    reporta las fallas acumuladas.
                  example: true
                items:
                  type: array
                  minItems: 1
                  items:
                    type: object
                    required:
                      - stop_id
                      - session_ids
                    properties:
                      stop_id:
                        type: string
                        nullable: false
                        format: uuid
                        description: >-
                          Identificador único de la Parada SPIDI en formato
                          UUID. Este ID identifica de forma permanente el
                          espacio donde el cliente puede consultar y gestionar
                          todas sus solicitudes de pago.
                        example: stp_f9317c1b-8a4f-4d7e-9f25-3a2b8b9a4f12
                      session_ids:
                        type: array
                        minItems: 1
                        items:
                          type: string
                        description: >-
                          Nuevo orden deseado. Deben ser `session_id`
                          **activos** en esa Parada (ver `mode`)
                      mode:
                        type: string
                        nullable: true
                        default: append
                        enum:
                          - append
                          - strict
                        description: >-
                          Modo de reordenamiento: 'append' (por defecto) o
                          'strict' (reemplazar lista).
                  description: >-
                    Lista de instrucciones de reorden por Parada. Al menos 1
                    ítem
                  example:
                    - stop_id: stp_111
                      session_ids:
                        - sess_B
                        - sess_A
                        - sess_C
                      mode: append
                    - stop_id: stp_222
                      session_ids:
                        - sess_X
                        - sess_Y
                      mode: strict
            examples:
              mixed_modes:
                summary: Reordenamiento con modos mixtos
                value:
                  continue_on_error: true
                  items:
                    - stop_id: stp_111
                      session_ids:
                        - sess_B
                        - sess_A
                        - sess_C
                      mode: append
                    - stop_id: stp_222
                      session_ids:
                        - sess_X
                        - sess_Y
                      mode: strict
      responses:
        '200':
          description: >-
            Reordenamiento procesado exitosamente - todas las operaciones
            completadas
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                  - batch_id
                  - results
                properties:
                  success:
                    type: boolean
                    description: >-
                      **true** si todos los ítems fueron exitosos; **false** si
                      al menos uno falló
                    example: true
                  message:
                    type: string
                    description: Resumen legible del resultado
                    example: 'Batch reorder processed: 2 items succeeded.'
                  batch_id:
                    type: string
                    description: Identificador único del batch para auditoría/idempotencia
                    example: batch_5e9a1b2c-3344-5566-7788-99aabbccdd00
                  results:
                    type: array
                    items:
                      type: object
                      required:
                        - stop_id
                        - success
                        - mode
                      properties:
                        stop_id:
                          type: string
                          description: Parada afectada
                          example: stp_111
                        success:
                          type: boolean
                          description: Resultado del ítem
                          example: true
                        mode:
                          type: string
                          enum:
                            - append
                            - strict
                          description: Modo aplicado
                          example: append
                        applied_order:
                          type: array
                          items:
                            type: string
                          description: Orden final aplicado (solo si success=true)
                          example:
                            - sess_B
                            - sess_A
                            - sess_C
                            - sess_D
                        errors:
                          type: object
                          description: Detalle de validaciones cuando success=false
                          properties:
                            missing_actives:
                              type: array
                              items:
                                type: string
                              description: Sesiones activas no incluidas (en strict)
                              example:
                                - sess_Z
                            not_active:
                              type: array
                              items:
                                type: string
                              description: IDs listados que no están activos
                              example:
                                - sess_Q
                            not_found:
                              type: array
                              items:
                                type: string
                              description: IDs no asociados a la Parada
                              example: []
                            duplicates:
                              type: array
                              items:
                                type: string
                              description: IDs repetidos en la lista
                              example:
                                - sess_Y
                    description: Resultados por ítem (stop_id)
                    example:
                      - stop_id: stp_111
                        success: true
                        applied_order:
                          - sess_B
                          - sess_A
                          - sess_C
                          - sess_D
                        mode: append
                      - stop_id: stp_222
                        success: true
                        applied_order:
                          - sess_X
                          - sess_Y
                        mode: strict
              examples:
                full_success:
                  summary: Éxito total
                  value:
                    success: true
                    message: 'Batch reorder processed: 2 items succeeded.'
                    batch_id: batch_5e9a1b2c-3344-5566-7788-99aabbccdd00
                    results:
                      - stop_id: stp_111
                        success: true
                        applied_order:
                          - sess_B
                          - sess_A
                          - sess_C
                          - sess_D
                        mode: append
                      - stop_id: stp_222
                        success: true
                        applied_order:
                          - sess_X
                          - sess_Y
                        mode: strict
        '207':
          description: Multi-Status - Reordenamiento procesado con resultados mixtos
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                  - batch_id
                  - results
                properties:
                  success:
                    type: boolean
                    description: >-
                      **true** si todos los ítems fueron exitosos; **false** si
                      al menos uno falló
                    example: true
                  message:
                    type: string
                    description: Resumen legible del resultado
                    example: 'Batch reorder processed: 2 items succeeded.'
                  batch_id:
                    type: string
                    description: Identificador único del batch para auditoría/idempotencia
                    example: batch_5e9a1b2c-3344-5566-7788-99aabbccdd00
                  results:
                    type: array
                    items:
                      type: object
                      required:
                        - stop_id
                        - success
                        - mode
                      properties:
                        stop_id:
                          type: string
                          description: Parada afectada
                          example: stp_111
                        success:
                          type: boolean
                          description: Resultado del ítem
                          example: true
                        mode:
                          type: string
                          enum:
                            - append
                            - strict
                          description: Modo aplicado
                          example: append
                        applied_order:
                          type: array
                          items:
                            type: string
                          description: Orden final aplicado (solo si success=true)
                          example:
                            - sess_B
                            - sess_A
                            - sess_C
                            - sess_D
                        errors:
                          type: object
                          description: Detalle de validaciones cuando success=false
                          properties:
                            missing_actives:
                              type: array
                              items:
                                type: string
                              description: Sesiones activas no incluidas (en strict)
                              example:
                                - sess_Z
                            not_active:
                              type: array
                              items:
                                type: string
                              description: IDs listados que no están activos
                              example:
                                - sess_Q
                            not_found:
                              type: array
                              items:
                                type: string
                              description: IDs no asociados a la Parada
                              example: []
                            duplicates:
                              type: array
                              items:
                                type: string
                              description: IDs repetidos en la lista
                              example:
                                - sess_Y
                    description: Resultados por ítem (stop_id)
                    example:
                      - stop_id: stp_111
                        success: true
                        applied_order:
                          - sess_B
                          - sess_A
                          - sess_C
                          - sess_D
                        mode: append
                      - stop_id: stp_222
                        success: true
                        applied_order:
                          - sess_X
                          - sess_Y
                        mode: strict
              examples:
                partial_errors:
                  summary: Éxito parcial con errores
                  value:
                    success: false
                    message: >-
                      Batch reorder processed with partial errors: 1 succeeded,
                      1 failed.
                    batch_id: batch_aa11bb22-cc33-dd44-ee55-ff6677889900
                    results:
                      - stop_id: stp_111
                        success: true
                        applied_order:
                          - sess_B
                          - sess_A
                          - sess_C
                        mode: append
                      - stop_id: stp_222
                        success: false
                        mode: strict
                        errors:
                          missing_actives:
                            - sess_Z
                          not_active:
                            - sess_Q
                          duplicates:
                            - sess_Y
        '400':
          description: >-
            Bad Request - Payload inválido, campos requeridos faltantes, formato
            incorrecto
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    description: Siempre **false** en respuestas de error
                    example: false
                  message:
                    type: string
                    description: Resumen legible del error principal
                    example: Invalid batch payload.
                  errors:
                    type: object
                    description: Detalles específicos de los errores de validación
                    additionalProperties:
                      type: string
                    example:
                      items: Must be a non-empty array.
                      items[0].mode: 'Allowed values are: append, strict.'
                      items[1].session_ids: Must be a non-empty array of strings.
              example:
                success: false
                message: Invalid batch payload.
                errors:
                  items: Must be a non-empty array.
                  items[0].mode: 'Allowed values are: append, strict.'
                  items[1].session_ids: Must be a non-empty array of strings.
        '401':
          description: Unauthorized - Token de autorización faltante o inválido
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    description: Siempre **false** en respuestas de error
                    example: false
                  message:
                    type: string
                    description: Resumen legible del error principal
                    example: Invalid batch payload.
                  errors:
                    type: object
                    description: Detalles específicos de los errores de validación
                    additionalProperties:
                      type: string
                    example:
                      items: Must be a non-empty array.
                      items[0].mode: 'Allowed values are: append, strict.'
                      items[1].session_ids: Must be a non-empty array of strings.
              example:
                success: false
                message: Unauthorized.
        '409':
          description: Conflict - Conflicto de idempotencia o versión desactualizada
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    description: Siempre **false** en respuestas de error
                    example: false
                  message:
                    type: string
                    description: Resumen legible del error principal
                    example: Invalid batch payload.
                  errors:
                    type: object
                    description: Detalles específicos de los errores de validación
                    additionalProperties:
                      type: string
                    example:
                      items: Must be a non-empty array.
                      items[0].mode: 'Allowed values are: append, strict.'
                      items[1].session_ids: Must be a non-empty array of strings.
              example:
                success: false
                message: Order version conflict.
                errors:
                  stp_222.order_version: Provided 12, current is 13.
        '422':
          description: >-
            Unprocessable Entity - Reglas de negocio violadas, sesiones no
            válidas
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    description: Siempre **false** en respuestas de error
                    example: false
                  message:
                    type: string
                    description: Resumen legible del error principal
                    example: Invalid batch payload.
                  errors:
                    type: object
                    description: Detalles específicos de los errores de validación
                    additionalProperties:
                      type: string
                    example:
                      items: Must be a non-empty array.
                      items[0].mode: 'Allowed values are: append, strict.'
                      items[1].session_ids: Must be a non-empty array of strings.
              example:
                success: false
                message: Unprocessable entity.
                errors:
                  items[0].session_ids[2]: Session is not active.
                  items[1].session_ids: List contains duplicates.
        '429':
          description: Too Many Requests - Rate limit excedido
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    description: Siempre **false** en respuestas de error
                    example: false
                  message:
                    type: string
                    description: Resumen legible del error principal
                    example: Invalid batch payload.
                  errors:
                    type: object
                    description: Detalles específicos de los errores de validación
                    additionalProperties:
                      type: string
                    example:
                      items: Must be a non-empty array.
                      items[0].mode: 'Allowed values are: append, strict.'
                      items[1].session_ids: Must be a non-empty array of strings.
              example:
                success: false
                message: 'Too many requests. Limit: 100 requests/minute.'
          headers:
            Retry-After:
              description: Segundos hasta que se puede reintentar
              schema:
                type: integer
                example: 45
            X-RateLimit-Limit:
              description: Límite de requests por ventana
              schema:
                type: integer
                example: 100
            X-RateLimit-Remaining:
              description: Requests restantes en la ventana actual
              schema:
                type: integer
                example: 0
            X-RateLimit-Reset:
              description: Timestamp Unix cuando se resetea el límite
              schema:
                type: integer
                example: 1702814181
        '500':
          description: >-
            Internal Server Error - Error interno del servidor, problemas de
            conectividad
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    description: Siempre **false** en respuestas de error
                    example: false
                  message:
                    type: string
                    description: Resumen legible del error principal
                    example: Invalid batch payload.
                  errors:
                    type: object
                    description: Detalles específicos de los errores de validación
                    additionalProperties:
                      type: string
                    example:
                      items: Must be a non-empty array.
                      items[0].mode: 'Allowed values are: append, strict.'
                      items[1].session_ids: Must be a non-empty array of strings.
              example:
                success: false
                message: Internal server error.
  /api/v1/ext/payment-stops/payment-sessions/query:
    post:
      summary: Consultar Enlaces de Múltiples Paradas
      description: >-
        Devuelve, en una sola llamada, los solicitudes de pago activas
        (derivados de sesiones `pending`) para varias Paradas (`stop_id`).


        Incluye paginación por Parada, filtros básicos y posibilidad de limitar
        campos para reducir payload.


        **¿Por qué POST para "leer"?**

        Acepta listas grandes de `stop_id` (hasta 200) y tokens de paginación
        por Parada; un `GET` se quedaría corto por límites de longitud de URL.
        Este patrón es común en APIs modernas (Google Cloud, AWS) para queries
        complejas.


        **Características:**

        - Optimizado para **UI cliente** - devuelve **solo activos por defecto**
        (`status=pending`)

        - Paginación cursor-based por parada

        - Rate limit: 100 requests/minuto por comercio

        - Máximo: 200 `stop_ids` por request


        **Notas importantes:**

        - Si necesitas histórico, usa `status: "historical"` o `include_history:
        true` en el request

        - Para más de 200 stops, realiza múltiples requests

        - Este endpoint es idempotente (lectura) y cacheable
      operationId: queryMultipleStops
      tags:
        - Endpoints Publicar
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - stop_ids
              properties:
                stop_ids:
                  type: array
                  minItems: 1
                  maxItems: 200
                  items:
                    type: string
                  description: >-
                    Lista de Paradas a consultar (máx. recomendado: 200 por
                    request)
                  example:
                    - stp_111
                    - stp_222
                    - stp_333
                status:
                  type: string
                  enum:
                    - active
                    - pending
                    - paid
                    - expired
                    - historical
                  default: active
                  description: >-
                    Filtro de estado: **active** (default, alias de
                    **pending**), **pending**, **paid**, **expired**,
                    **historical** (paid+expired)
                  example: active
                per_stop:
                  description: Configuración de paginación y filtros por Parada
                  type: object
                  properties:
                    page_size:
                      type: integer
                      minimum: 1
                      maximum: 200
                      default: 50
                      description: Tamaño por Parada (1..200, default 50)
                      example: 20
                    sort:
                      type: string
                      enum:
                        - created_at
                        - updated_at
                        - expires_at
                        - amount
                      default: created_at
                      description: Campo de ordenación
                      example: created_at
                    order:
                      type: string
                      enum:
                        - asc
                        - desc
                      default: desc
                      description: Dirección de ordenación
                      example: desc
                    only_fields:
                      type: array
                      items:
                        type: string
                      description: >-
                        Limitar campos para reducir payload (p. ej.,
                        ["session_id","payment_url","expires_at"])
                      example:
                        - session_id
                        - payment_url
                        - expires_at
                    cursor_by_stop:
                      type: object
                      additionalProperties:
                        type: string
                      description: >-
                        Cursor por Parada para continuar desde una respuesta
                        previa. Usa `next_cursor` por `stop_id` para cargas
                        incrementales eficientes
                      example:
                        stp_111: cur_aaa
                        stp_333: cur_ccc
            examples:
              simple_query:
                summary: Consulta simple (solo activos)
                value:
                  stop_ids:
                    - stp_111
                    - stp_222
                    - stp_333
              with_pagination:
                summary: Con paginación y campos mínimos
                value:
                  stop_ids:
                    - stp_111
                    - stp_222
                  per_stop:
                    page_size: 20
                    sort: created_at
                    order: desc
                    only_fields:
                      - session_id
                      - payment_url
                      - expires_at
              with_cursors:
                summary: Reanudación por Parada (usando next_cursor previo)
                value:
                  stop_ids:
                    - stp_111
                    - stp_222
                    - stp_333
                  per_stop:
                    cursor_by_stop:
                      stp_111: cur_aaa
                      stp_333: cur_ccc
                    page_size: 50
      responses:
        '200':
          description: Consulta procesada exitosamente
          headers:
            X-Total-Stops:
              description: Número total de paradas consultadas
              schema:
                type: integer
                example: 3
            X-RateLimit-Limit:
              description: Límite de requests por ventana
              schema:
                type: integer
                example: 100
            X-RateLimit-Remaining:
              description: Requests restantes en la ventana actual
              schema:
                type: integer
                example: 95
            X-RateLimit-Reset:
              description: Timestamp Unix cuando se resetea el límite
              schema:
                type: integer
                example: 1702814181
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - requested
                  - results
                properties:
                  success:
                    type: boolean
                    description: >-
                      **true** si el batch de consulta se procesó (aunque
                      existan errores por Parada)
                    example: true
                  requested:
                    type: object
                    description: Eco de parámetros aplicados
                    properties:
                      stop_ids:
                        type: array
                        items:
                          type: string
                        example:
                          - stp_111
                          - stp_222
                          - stp_333
                      status:
                        type: string
                        example: active
                      per_stop:
                        type: object
                        properties:
                          page_size:
                            type: integer
                            minimum: 1
                            maximum: 200
                            default: 50
                            description: Tamaño por Parada (1..200, default 50)
                            example: 20
                          sort:
                            type: string
                            enum:
                              - created_at
                              - updated_at
                              - expires_at
                              - amount
                            default: created_at
                            description: Campo de ordenación
                            example: created_at
                          order:
                            type: string
                            enum:
                              - asc
                              - desc
                            default: desc
                            description: Dirección de ordenación
                            example: desc
                          only_fields:
                            type: array
                            items:
                              type: string
                            description: >-
                              Limitar campos para reducir payload (p. ej.,
                              ["session_id","payment_url","expires_at"])
                            example:
                              - session_id
                              - payment_url
                              - expires_at
                          cursor_by_stop:
                            type: object
                            additionalProperties:
                              type: string
                            description: >-
                              Cursor por Parada para continuar desde una
                              respuesta previa. Usa `next_cursor` por `stop_id`
                              para cargas incrementales eficientes
                            example:
                              stp_111: cur_aaa
                              stp_333: cur_ccc
                  results:
                    type: array
                    items:
                      type: object
                      required:
                        - stop_id
                      properties:
                        stop_id:
                          type: string
                          description: Parada consultada
                          example: stp_111
                        page_size:
                          type: integer
                          description: Tamaño aplicado por Parada
                          example: 20
                        has_next:
                          type: boolean
                          description: Si hay más resultados
                          example: true
                        next_cursor:
                          type: string
                          description: Cursor para continuar la paginación de esa Parada
                          example: cur_aaa_next
                        total_estimate:
                          type: integer
                          description: Estimación rápida del total (opcional)
                          example: 72
                        items:
                          type: array
                          items:
                            type: object
                            required:
                              - session_id
                              - payment_url
                              - status
                              - amount
                              - created_at
                            properties:
                              session_id:
                                type: string
                                description: Identificador único de la sesión de pago
                                example: sess_A
                              payment_url:
                                type: string
                                format: uri
                                description: Enlace de pago asociado a la sesión
                                example: https://pay.spidi.io/sess_A
                              status:
                                type: string
                                enum:
                                  - pending
                                  - paid
                                  - expired
                                description: Estado de la sesión de pago
                                example: pending
                              amount:
                                type: object
                                required:
                                  - value
                                  - currency
                                properties:
                                  value:
                                    type: string
                                    description: Monto en la moneda especificada
                                    example: '15.00'
                                  currency:
                                    type: string
                                    enum:
                                      - USD_BCV
                                      - EUR_BCV
                                      - COP
                                      - USDT
                                      - VES
                                    description: >-
                                      Moneda del monto (VES o moneda de
                                      referencia)
                                    example: USD_BCV
                                description: Monto original de la sesión
                              amount_bs:
                                type: object
                                properties:
                                  value:
                                    type: string
                                    description: Monto expresado en bolívares
                                    example: Bs. 552,00
                                  rate_date:
                                    type: string
                                    format: date
                                    description: Fecha de la tasa de cambio aplicada
                                    example: '2025-10-16'
                                description: >-
                                  Monto expresado en Bs. cuando la referencia no
                                  es VES
                              created_at:
                                type: string
                                format: date-time
                                description: Fecha/hora de creación de la sesión
                                example: '2025-10-15T14:25:32Z'
                              updated_at:
                                type: string
                                format: date-time
                                description: Fecha/hora de última actualización
                                example: '2025-10-15T14:26:10Z'
                              expires_at:
                                type: string
                                format: date-time
                                description: >-
                                  Vencimiento de la sesión (Botón: 10 min;
                                  Solicitud: configurable)
                                example: '2025-10-15T14:35:32Z'
                              paid_at:
                                type: string
                                format: date-time
                                description: Fecha/hora de confirmación de pago (si paid)
                                example: '2025-10-15T14:30:00Z'
                              agreement_id:
                                type: string
                                description: Acuerdo de liquidación aplicado (si existe)
                                example: agr_001
                              internal_reference:
                                type: string
                                description: >-
                                  Identificador interno del comercio (requerido
                                  en Solicitudes)
                                example: INV-9842
                              customer_ref:
                                type: string
                                description: Referencia del cliente (si aplica)
                                example: cust_778
                              order_index:
                                type: integer
                                description: >-
                                  Posición relativa en la Parada (para
                                  visualización)
                                example: 0
                              receipt_url:
                                type: string
                                format: uri
                                description: URL del comprobante de pago SPIDI (si paid)
                                example: https://pay.spidi.io/receipt/sess_A
                              metadata:
                                type: object
                                description: Datos adicionales definidos por el comercio
                                additionalProperties: true
                                example:
                                  plan: pro
                              expiration_behavior:
                                type: string
                                enum:
                                  - expire
                                  - message_only
                                description: Comportamiento al vencer (solo Solicitudes)
                                example: message_only
                          description: Lista de sesiones (cada una con su payment_url)
                        error:
                          type: object
                          properties:
                            code:
                              type: string
                              enum:
                                - not_found
                                - forbidden
                                - invalid_cursor
                              description: Código de error
                              example: not_found
                            message:
                              type: string
                              description: Mensaje de error
                              example: Stop not found.
                          description: Error específico de esta Parada (si aplica)
                    description: Resultado por stop_id
                    example:
                      - stop_id: stp_111
                        page_size: 20
                        has_next: true
                        next_cursor: cur_aaa_next
                        total_estimate: 72
                        items:
                          - session_id: sess_A
                            payment_url: https://pay.spidi.io/sess_A
                            status: pending
                            amount:
                              value: '15.00'
                              currency: USD_BCV
                            amount_bs:
                              value: Bs. 552,00
                              rate_date: '2025-10-16'
                            created_at: '2025-10-15T14:25:32Z'
                            expires_at: '2025-10-15T14:35:32Z'
                            order_index: 0
                      - stop_id: stp_222
                        page_size: 20
                        has_next: false
                        next_cursor: null
                        total_estimate: 2
                        items: []
                      - stop_id: stp_333
                        error:
                          code: not_found
                          message: Stop not found.
              examples:
                successful_query:
                  summary: Consulta exitosa con resultados
                  value:
                    success: true
                    requested:
                      stop_ids:
                        - stp_111
                        - stp_222
                        - stp_333
                      status: active
                      per_stop:
                        page_size: 20
                        sort: created_at
                        order: desc
                    results:
                      - stop_id: stp_111
                        page_size: 20
                        has_next: true
                        next_cursor: cur_aaa_next
                        total_estimate: 72
                        items:
                          - session_id: sess_A
                            payment_url: https://pay.spidi.io/sess_A
                            status: pending
                            amount:
                              value: '15.00'
                              currency: USD_BCV
                            amount_bs:
                              value: Bs. 552,00
                              rate_date: '2025-10-16'
                            created_at: '2025-10-15T14:25:32Z'
                            expires_at: '2025-10-15T14:35:32Z'
                            order_index: 0
                      - stop_id: stp_222
                        page_size: 20
                        has_next: false
                        next_cursor: null
                        total_estimate: 2
                        items:
                          - session_id: sess_X
                            payment_url: https://pay.spidi.io/sess_X
                            status: pending
                            amount:
                              value: '120.00'
                              currency: USD_BCV
                            created_at: '2025-10-15T12:01:10Z'
                            expires_at: '2025-10-15T12:11:10Z'
                            order_index: 1
                          - session_id: sess_Y
                            payment_url: https://pay.spidi.io/sess_Y
                            status: pending
                            amount:
                              value: '90000000'
                              currency: VES
                            created_at: '2025-10-14T19:01:10Z'
                            expires_at: '2025-10-14T19:11:10Z'
                            order_index: 2
                      - stop_id: stp_333
                        error:
                          code: not_found
                          message: Stop not found.
        '400':
          description: Bad Request - Payload inválido, campos requeridos faltantes
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    nullable: false
                    description: >-
                      Indica si la operación fue exitosa. True si el endpoint se
                      procesó de forma exitosa. False de lo contrario
                    example: true
                  message:
                    type: string
                    nullable: true
                    description: Mensaje de confirmación o error legible.
                  errors:
                    type: object
                    nullable: true
                    description: Detalles específicos de los errores de validación.
              example:
                success: false
                message: Invalid payload.
                errors:
                  stop_ids: Must be a non-empty array.
        '401':
          description: Unauthorized - Token de autorización faltante o inválido
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    nullable: false
                    description: >-
                      Indica si la operación fue exitosa. True si el endpoint se
                      procesó de forma exitosa. False de lo contrario
                    example: true
                  message:
                    type: string
                    nullable: true
                    description: Mensaje de confirmación o error legible.
                  errors:
                    type: object
                    nullable: true
                    description: Detalles específicos de los errores de validación.
              example:
                success: false
                message: Unauthorized.
        '403':
          description: Forbidden - Parada no pertenece a las credenciales del comercio
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    nullable: false
                    description: >-
                      Indica si la operación fue exitosa. True si el endpoint se
                      procesó de forma exitosa. False de lo contrario
                    example: true
                  message:
                    type: string
                    nullable: true
                    description: Mensaje de confirmación o error legible.
                  errors:
                    type: object
                    nullable: true
                    description: Detalles específicos de los errores de validación.
              example:
                success: false
                message: 'Forbidden: stop does not belong to your commerce.'
        '422':
          description: Unprocessable Entity - Cursor inválido, page_size fuera de rango
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    nullable: false
                    description: >-
                      Indica si la operación fue exitosa. True si el endpoint se
                      procesó de forma exitosa. False de lo contrario
                    example: true
                  message:
                    type: string
                    nullable: true
                    description: Mensaje de confirmación o error legible.
                  errors:
                    type: object
                    nullable: true
                    description: Detalles específicos de los errores de validación.
              example:
                success: false
                message: Unprocessable entity.
                errors:
                  per_stop.page_size: Must be between 1 and 200.
                  per_stop.cursor_by_stop.stp_111: Invalid cursor format.
        '500':
          description: Internal Server Error - Error interno del servidor
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - message
                properties:
                  success:
                    type: boolean
                    nullable: false
                    description: >-
                      Indica si la operación fue exitosa. True si el endpoint se
                      procesó de forma exitosa. False de lo contrario
                    example: true
                  message:
                    type: string
                    nullable: true
                    description: Mensaje de confirmación o error legible.
                  errors:
                    type: object
                    nullable: true
                    description: Detalles específicos de los errores de validación.
              example:
                success: false
                message: Internal server error.
webhooks:
  payment_session.created:
    post:
      operationId: paymentSessionCreated
      tags:
        - Webhooks
      summary: Evento de creación de sesión
      description: >-
        Se produce cuando se crea una nueva sesión de pago. Esta sesión queda
        disponible para que el pagador realice el pago correspondiente. Se
        enviará una notificación de este evento mediante un webhook cuando se
        crea una nueva sesión de pago.
      parameters:
        - name: spidi-signature
          in: header
          required: true
          description: >-
            Firma HMAC-SHA256 para validar la autenticidad e integridad del
            mensaje.
          schema:
            type: string
            example: d9c8227652758252615617f6a8759526703902939d892376987f22387a672889
        - name: spidi-timestamp
          in: header
          required: true
          description: >-
            Timestamp ISO 8601 de la creación del evento para prevenir ataques
            de replay.
          schema:
            type: string
            format: date-time
            example: '2026-02-06T15:24:36.000Z'
        - name: idempotency-key
          in: header
          required: true
          description: >-
            UUID v4 único para garantizar que la operación se procese una sola
            vez.
          schema:
            type: string
            format: uuid
            example: 93465a7e-ea9b-41a8-8dca-14e811641c25
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - event
                - data
              properties:
                event:
                  type: string
                  enum:
                    - payment_session.created
                  description: >-
                    Tipo de evento siguiendo el estándar de jerarquía por
                    puntos.
                data:
                  type: object
                  properties:
                    session_id:
                      type: string
                      nullable: false
                      description: >-
                        Identificador único de la sesión de pago, accedible a
                        través del payment_url.
                    session_origin:
                      type: string
                      nullable: false
                      enum:
                        - button
                        - request
                      description: >-
                        Origen de la sesión: 'button' (Botón de pago) o
                        'request' (Solicitud SPIDI).
                    status:
                      type: string
                      nullable: false
                      enum:
                        - pending
                        - paid
                        - failed
                        - expired
                      description: >-
                        Estado actual de la sesión. El valor failed solo se
                        aplica para sesiones creadas con botón de pago.
                    identifier_label:
                      type: string
                      nullable: true
                      description: >-
                        Etiqueta que indica cómo debe interpretarse el valor
                        enviado en identifier (ej. 'Nro de orden').
                    identifier:
                      type: string
                      nullable: false
                      description: >-
                        Identificador del pagador, interpretado según el valor
                        de identifier_label. Ejemplo: Nro de orden, Nombre, etc.
                    description:
                      type: string
                      nullable: true
                      description: >-
                        Descripción del acuerdo o del concepto de pago asociado
                        a una sesión.
                      maxLength: 500
                    payment_method:
                      type: string
                      nullable: true
                      enum:
                        - crypto
                        - immediate_debit
                        - mobile_payment
                      description: 'Método de pago utilizado. Eco del request: no.'
                    amount_reference:
                      description: >-
                        Monto de referencia en la moneda especificada en
                        currencyReference con 2 decimales.
                      type: number
                      nullable: false
                      format: double
                      example: '100.001'
                    currency_reference:
                      type: string
                      nullable: false
                      enum:
                        - USD
                        - EUR
                        - COP
                        - USDT
                        - VES
                      description: >-
                        Moneda de referencia que se fija para el pago. Usada
                        para calcular el monto en bolívares con la tasa vigente.
                    success_url:
                      type: string
                      nullable: true
                      format: uri
                      description: >-
                        URL de redirección que se utiliza cuando un intento de
                        pago es exitoso.
                      pattern: ^[a-z1-9]+://[^\s]*$
                    failure_url:
                      type: string
                      nullable: true
                      format: uri
                      description: >-
                        URL de redirección que se utiliza cuando un intento de
                        pago falle. 
                      pattern: ^[a-z1-9]+://[^\s]*$
                    webhook_url:
                      type: string
                      nullable: true
                      format: uri
                      description: 'URL para recibir notificaciones de webhook. '
                    split:
                      type: object
                      nullable: true
                      description: >-
                        Configuración de división de pagos (Request) / Eco del
                        request del split (Response).
                      properties:
                        document:
                          type: object
                          nullable: true
                          description: >-
                            Información del documento proporcionado por el owner
                            a los partners para dejar evidencia del split.


                            **Notas importantes:**

                            - Esta información **no implica cálculo fiscal** por
                            parte de SPIDI; es solo comunicación entre owner y
                            partners.

                            - `splitDocument_url` puede ser público con hash o
                            una URL autenticada.

                            - SPIDI **no interpreta ni calcula IVA** a partir de
                            esta información; solo lo transporta.
                          properties:
                            name:
                              type: string
                              nullable: true
                              description: >-
                                Nombre del documento asociado a la transacción
                                split (por ejemplo: factura/recibo/contrato
                                D001-00045678).
                            type:
                              type: string
                              nullable: true
                              description: >-
                                Formato libre del owner donde especifica el tipo
                                de documento.
                              examples:
                                - Factura
                                - Contrato
                                - Recibo
                            date:
                              type: string
                              nullable: true
                              format: date
                              description: >-
                                Fecha de emisión del documento en formato ISO
                                8601 (YYYY-MM-DD).
                            url:
                              type: string
                              nullable: true
                              format: uri
                              description: >-
                                Enlace para visualizar/descargar el documento
                                del split. Puede ser público con hash o una URL
                                autenticada.
                            observations:
                              type: string
                              nullable: true
                              maxLength: 500
                              description: >-
                                Observaciones libres del owner (máx. 500
                                caracteres).
                        distribution:
                          type: array
                          nullable: false
                          description: >-
                            Lista de reglas/destinatarios del split. Debe tener
                            ≥ 1 ítem. La suma de amount_reference debe ser menor
                            al amount total de la sesión, porque la diferencia
                            restante se asigna automáticamente al owner, quien
                            siempre debe recibir una parte del pago. (Requerido
                            cuando split=true)
                          items:
                            type: object
                            required:
                              - split_recipient_agreement_id
                              - amount_reference
                              - observations
                            properties:
                              split_recipient_agreement_id:
                                type: string
                                nullable: false
                                format: uuid
                                description: >-
                                  UUID global SPIDI del agreement de recepción.
                                  Este ID se usará en acuerdos de distribución
                                  para identificar al receptor del split.
                                  (Requerido en distribution)
                              label:
                                type: string
                                nullable: true
                                description: >-
                                  Etiqueta descriptiva del receptor en un split.
                                  (Opcional en distribution, Eco del request:
                                  sí)
                              amount_reference:
                                description: >-
                                  Monto de referencia en la moneda especificada
                                  en currencyReference con 2 decimales.
                                type: number
                                nullable: false
                                format: double
                                example: '100.001'
                              observations:
                                type: string
                                nullable: false
                                maxLength: 500
                                description: >-
                                  Mensaje libre para el partner (máx. 500
                                  caracteres). (Requerido en distribution, Eco
                                  del request: sí)
            examples:
              creacion_exitosa:
                summary: Ejemplo de request recibo por el webhook
                value:
                  event: payment_session.created
                  data:
                    session_id: ce075ab5-a4e0-4d16-8281-a27fced565f2
                    session_origin: button
                    status: pending
                    identifier_label: Nombre del cliente
                    identifier: Juan Pérez
                    description: Pago de servicio de internet
                    payment_method: immediate_debit
                    amount_reference: 5
                    currency_reference: VES
                    success_url: miapp://pago/exitoso
                    failure_url: miapp://pago/fallido
                    webhook_url: https://miapi.com/spidi/webhook
                    split:
                      document:
                        document_name: D001-00045678
                        document_type: Factura
                        document_date: '2025-10-20'
                        document_url: https://owner.com/document/D001-00045678
                        document_observations: any observation to owner
                      distribution:
                        - split_recipient_agreement_id: rcv_014…723c1a2
                          label: Partner 1
                          amount_reference: 10
                          observations: any observation to communicate to Partner 1
                        - split_recipient_agreement_id: rcv_016…112dde3
                          label: Partner 2
                          amount_reference: 0
                          observations: any observation to communicate to Partner 2
      responses:
        '200':
          description: Webhook recibido correctamente por el cliente
  payment_session.payment_completed:
    post:
      operationId: paymentSessionPaymentCompleted
      tags:
        - Webhooks
      summary: Evento de pago exitoso
      description: >-
        Se produce cuando el pagador completa exitosamente el pago de una
        sesión, confirmándose la recepción de los fondos. Se enviará una
        notificación de este evento mediante un webhook cuando el pagador
        completa exitosamente el pago de una sesión
      parameters:
        - name: spidi-signature
          in: header
          required: true
          description: >-
            Firma HMAC-SHA256 para validar la autenticidad e integridad del
            mensaje.
          schema:
            type: string
            example: d9c8227652758252615617f6a8759526703902939d892376987f22387a672889
        - name: spidi-timestamp
          in: header
          required: true
          description: >-
            Timestamp ISO 8601 de la creación del evento para prevenir ataques
            de replay.
          schema:
            type: string
            format: date-time
            example: '2026-02-06T15:24:36.000Z'
        - name: idempotency-key
          in: header
          required: true
          description: >-
            UUID v4 único para garantizar que la operación se procese una sola
            vez.
          schema:
            type: string
            format: uuid
            example: 93465a7e-ea9b-41a8-8dca-14e811641c25
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - event
                - data
              properties:
                event:
                  type: string
                  enum:
                    - payment_session.paid
                  description: Tipo de evento de cobro exitoso.
                data:
                  type: object
                  required:
                    - session_payment
                    - payment_details
                  properties:
                    session_payment:
                      type: object
                      properties:
                        id:
                          type: string
                          nullable: false
                          description: >-
                            Identificador único de la sesión de pago, accedible
                            a través del payment_url.
                        origin:
                          type: string
                          nullable: false
                          enum:
                            - button
                            - request
                          description: >-
                            Origen de la sesión: 'button' (Botón de pago) o
                            'request' (Solicitud SPIDI).
                        agreement_id:
                          type: string
                          format: uuid
                          nullable: true
                          description: >-
                            Identificador único del acuerdo de liquidación. Debe
                            ser UUID v4. 
                        currency_reference:
                          type: string
                          nullable: false
                          enum:
                            - USD
                            - EUR
                            - COP
                            - USDT
                            - VES
                          description: >-
                            Moneda de referencia que se fija para el pago. Usada
                            para calcular el monto en bolívares con la tasa
                            vigente.
                        amount_reference:
                          description: >-
                            Monto de referencia en la moneda especificada en
                            currencyReference con 2 decimales.
                          type: number
                          nullable: false
                          format: double
                          example: '100.001'
                        identifier_label:
                          type: string
                          nullable: true
                          description: >-
                            Etiqueta que indica cómo debe interpretarse el valor
                            enviado en identifier (ej. 'Nro de orden').
                        identifier:
                          type: string
                          nullable: false
                          description: >-
                            Identificador del pagador, interpretado según el
                            valor de identifier_label. Ejemplo: Nro de orden,
                            Nombre, etc.
                        description:
                          type: string
                          nullable: true
                          description: >-
                            Descripción del acuerdo o del concepto de pago
                            asociado a una sesión.
                          maxLength: 500
                        payment_method:
                          type: string
                          nullable: true
                          enum:
                            - crypto
                            - immediate_debit
                            - mobile_payment
                          description: 'Método de pago utilizado. Eco del request: no.'
                        spidi_transaction:
                          type: object
                          properties:
                            id:
                              description: ID de la transacción en SPIDI.
                              type: number
                              example: 1296
                            url:
                              type: string
                              nullable: true
                              format: uri
                              description: >-
                                URL del comprobante de pago en SPIDI (Comparar
                                con 'receipt_url').
                    crypto_details:
                      type: object
                      nullable: true
                      description: Detalles de pago con criptomonedas (null si no aplica).
                      properties:
                        provider_name:
                          type: string
                          nullable: true
                          description: >-
                            Nombre de la entidad o plataforma financiera que
                            custodia los activos del usuario. Representa el
                            ecosistema o 'banco digital' donde reside el saldo
                            original (ej. Binance, Crixto).
                          examples:
                            - Binance
                            - Crixto
                        crypto_order_id:
                          type: string
                          nullable: true
                          description: >-
                            Identificador de la orden cripto generada por el
                            proveedor.
                        payment_method_name:
                          type: string
                          description: >-
                            Nombre del método de pago (ej. Binance Pay, Crixto
                            Pay).
                          examples:
                            - Binance Pay
                            - Crixto Pay
                        amount_transaction_ves:
                          type: number
                          format: double
                          nullable: true
                          description: >-
                            Monto con 3 decimales de la transacción en la moneda
                            VES. Note que es el monto original sin incluir la
                            comisión por el pago.
                          example: 157.783
                        amount_pay_by_user_crypto:
                          type: number
                          format: double
                          nullable: true
                          description: >-
                            Monto con 3 decimales del pago realizado por el
                            usuario en la moneda cripto. Note que puede variar
                            del monto original si se aplica una comisión por el
                            pago.
                          example: 157.783
                        currency_crypto:
                          type: string
                          nullable: true
                          description: >-
                            Moneda cripto utilizada en el pago (por ejemplo,
                            USDT).
                          enum:
                            - USDT
                        exchange_rate:
                          type: number
                          format: double
                          description: >-
                            Tasa Cripto/Fiat usada durante la conversión de
                            cripto-fiat, especificada 4 decimales
                          example: 157.7837
                        paid_at:
                          type: string
                          nullable: true
                          format: date-time
                          description: >-
                            Fecha y hora en que se confirmó el pago cripto, en
                            formato ISO 8601.
                    payment_details:
                      type: object
                      nullable: true
                      description: >-
                        Detalles del pago bancario. Es 'null' si no aplica.
                        (Nota: Revisar si es objeto vacío o null). Eco del
                        request: no.
                      properties:
                        action_date:
                          type: string
                          format: date-time
                          nullable: true
                          description: >-
                            Fecha y hora de la acción del pagador, en formato
                            ISO 8601 con sufijo Z (UTC).
                        bank_name:
                          type: string
                          nullable: true
                          description: 'Nombre comercial del banco. Eco del request: no.'
                        bank_reference_id:
                          type: string
                          nullable: true
                          description: 'Referencia bancaria del pago. Eco del request: no.'
                        amount_ves:
                          type: number
                          description: Monto en bolívares con 2 decimales.
                          format: double
                        bcv_rate_usd_ves:
                          type: number
                          nullable: true
                          format: decimal(10,4)
                          description: >-
                            Tasa oficial BCV de USD a VES usada en el cálculo
                            del monto en bolívares. Eco del request: no.
                        bcv_rate_eur_ves:
                          type: number
                          nullable: true
                          format: decimal(10,4)
                          description: >-
                            Tasa oficial BCV de EUR a VES usada en el cálculo
                            del monto en bolívares. Eco del request: no.
                        rate_usdt_ves:
                          type: number
                          format: decimal(10,4)
                          nullable: true
                          description: Tasa de cambio USDT a VES.
                        rate_col_ves:
                          type: number
                          format: decimal(10,4)
                          nullable: true
                          description: Tasa de cambio COP a VES.
            examples:
              cobro_exitoso:
                summary: Ejemplo de request de cobro exitoso
                value:
                  event: payment_session.paid
                  data:
                    session_payment:
                      id: 3ddc4cfb-c09a-43de-92c1-e4a069732e90
                      origin: request
                      agreement_id: c4cfb-c-43deb-c09a-4-92c109a
                      currency_reference: USD
                      amount_reference: 50.01
                      identifier_label: Nombre y Apellido
                      identifier: Federico Coppola
                      description: ''
                      payment_method: immediate_debit
                      spidi_transaction:
                        id: 643
                        url: >-
                          https://mispidi.com/success?id=0ff89338-0ba5-4d3f-c999-8aa71e560d4a
                    crypto_details: null
                    payment_details:
                      action_date: '2025-09-18T21:00:08Z'
                      bank_name: BANCO PLAZA
                      bank_reference_id: '00001440'
                      amount_ves: 6100.56
                      bcv_rate_usd_ves: 122.0112
                      bcv_rate_eur_ves: 145.2414
                      rate_usdt_ves: 183.1112
                      rate_col_ves: 0.0501
                      paid_via: direct
      responses:
        '200':
          description: Webhook procesado exitosamente
  payment_session.accreditation_to_recipient_failed:
    post:
      operationId: paymentSessionAccreditationToRecipientFailed
      tags:
        - Webhooks
      summary: '[En Desarrollo] Evento de acreditación fallida al receptor'
      description: |-
        **Advertencia: Este endpoint está en desarrollo** 

         Se produce cuando ocurre un fallo en el intento de acreditar los fondos a un receptor esperado del pago. Se enviará una notificación de este evento mediante un webhook por cada intento fallido. El sistema realizará reintentos automáticos hasta lograr la acreditación exitosa.
      parameters:
        - name: spidi-signature
          in: header
          required: true
          description: >-
            Firma HMAC-SHA256 para validar la autenticidad e integridad del
            mensaje.
          schema:
            type: string
            example: d9c8227652758252615617f6a8759526703902939d892376987f22387a672889
        - name: spidi-timestamp
          in: header
          required: true
          description: >-
            Timestamp ISO 8601 de la creación del evento para prevenir ataques
            de replay.
          schema:
            type: string
            format: date-time
            example: '2026-02-06T15:24:36.000Z'
        - name: idempotency-key
          in: header
          required: true
          description: >-
            UUID v4 único para garantizar que la operación se procese una sola
            vez.
          schema:
            type: string
            format: uuid
            example: 93465a7e-ea9b-41a8-8dca-14e811641c25
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - event
                - data
              properties:
                event:
                  type: string
                  enum:
                    - payment_session.accreditation_to_recipient_failed
                  description: >-
                    Se enviará cuando ocurre un fallo en el intento de acreditar
                    los fondos a un receptor esperado del pago.
                data:
                  type: object
                  required:
                    - session_payment
                    - credit
                  properties:
                    session_payment:
                      type: object
                      properties:
                        id:
                          type: string
                          nullable: false
                          description: >-
                            Identificador único de la sesión de pago, accedible
                            a través del payment_url.
                        origin:
                          type: string
                          nullable: false
                          enum:
                            - button
                            - request
                          description: >-
                            Origen de la sesión: 'button' (Botón de pago) o
                            'request' (Solicitud SPIDI).
                        agreement_id:
                          type: string
                          format: uuid
                          nullable: true
                          description: >-
                            Identificador único del acuerdo de liquidación. Debe
                            ser UUID v4. 
                        currency_reference:
                          type: string
                          nullable: false
                          enum:
                            - USD
                            - EUR
                            - COP
                            - USDT
                            - VES
                          description: >-
                            Moneda de referencia que se fija para el pago. Usada
                            para calcular el monto en bolívares con la tasa
                            vigente.
                        amount_reference:
                          description: >-
                            Monto de referencia en la moneda especificada en
                            currencyReference con 2 decimales.
                          type: number
                          nullable: false
                          format: double
                          example: '100.001'
                        identifier_label:
                          type: string
                          nullable: true
                          description: >-
                            Etiqueta que indica cómo debe interpretarse el valor
                            enviado en identifier (ej. 'Nro de orden').
                        identifier:
                          type: string
                          nullable: false
                          description: >-
                            Identificador del pagador, interpretado según el
                            valor de identifier_label. Ejemplo: Nro de orden,
                            Nombre, etc.
                        description:
                          type: string
                          nullable: true
                          description: >-
                            Descripción del acuerdo o del concepto de pago
                            asociado a una sesión.
                          maxLength: 500
                        payment_method:
                          type: string
                          nullable: true
                          enum:
                            - crypto
                            - immediate_debit
                            - mobile_payment
                          description: 'Método de pago utilizado. Eco del request: no.'
                    credit:
                      type: object
                      description: Detalle del crédito que falló.
                      allOf:
                        - type: object
                          properties:
                            id:
                              type: string
                            amount_ves_credited:
                              type: number
                              nullable: true
                              description: >-
                                Monto neto acreditado al receptor en bolívares,
                                luego de aplicar las comisiones
                                correspondientes. Siempre tiene 2 decimales.
                              format: double
                              example: '100.01'
                            bank_commissions_ves:
                              type: number
                              nullable: true
                              format: decimal(12,2)
                              description: >-
                                Comisión bancaria total cobrada en bolívares
                                para la liquidación. Eco del request: no.
                            receive_date:
                              type: string
                              format: date-time
                              nullable: true
                              description: >-
                                Fecha y hora en que se acreditó el pago (ISO
                                8601).
                            bank_name:
                              type: string
                              nullable: true
                              description: 'Nombre comercial del banco. Eco del request: no.'
                            bank_reference_id:
                              type: string
                              nullable: true
                              description: >-
                                Referencia bancaria del pago. Eco del request:
                                no.
                            recipient:
                              type: object
                              properties:
                                id:
                                  type: string
                                  nullable: true
                                  description: Identificador del receptor del crédito.
                                type:
                                  type: string
                                  nullable: true
                                  description: Tipo del receptor del crédito.
                                  enum:
                                    - owner
                                    - partner
                                split_recipient_agreement_id:
                                  type: string
                                  nullable: false
                                  format: uuid
                                  description: >-
                                    UUID global SPIDI del agreement de
                                    recepción. Este ID se usará en acuerdos de
                                    distribución para identificar al receptor
                                    del split. (Requerido en distribution)
                                partner:
                                  type: object
                                  properties:
                                    observations:
                                      type: string
                                      nullable: false
                                      maxLength: 500
                                      description: >-
                                        Mensaje libre para el partner (máx. 500
                                        caracteres). (Requerido en distribution,
                                        Eco del request: sí)
                                    name:
                                      type: string
                                      nullable: true
                                      description: Nombre o razón social del partner
                                    rif_number:
                                      type: string
                                      nullable: true
                                      description: RIF del partner
                        - type: object
                          properties:
                            errors:
                              type: array
                              description: >-
                                Lista de mensajes de error devueltos durante el
                                intento de acreditación.
                              items:
                                type: string
            examples:
              fallo_acreditacion:
                summary: Ejemplo de request por fallo en acreditación
                value:
                  event: payment_session.accreditation_to_recipient_failed
                  data:
                    session_payment:
                      id: 3ddc4cfb-c09a-43de-92c1-e4a069732e90
                      origin: request
                      agreement_id: c4cfb-c-43deb-c09a-4-92c109a
                      currency_reference: USD
                      amount_reference: 50.01
                      identifier_label: Nombre y Apellido
                      identifier: Federico Coppola
                      payment_method: immediate_debit
                    credit:
                      id: '1122'
                      amount_ves_credited: 1000.12
                      bank_commissions_ves: 2.32
                      receive_date: '2025-09-18T21:00:10Z'
                      bank_name: BANESCO
                      bank_reference_id: '4555111'
                      recipient:
                        id: partner_1
                        agreement_id: rcv_014…723c1a2
                        partner_info:
                          name: Restaurante Los Sabores C.A.
                          rif_number: J-40011223-5
                      errors:
                        - Límite diario de transferencias excedido
      responses:
        '200':
          description: Webhook procesado exitosamente
  payment_session.accreditation_to_recipient_completed:
    post:
      operationId: paymentSessionAccreditationToRecipientCompleted
      tags:
        - Webhooks
      summary: >-
        [En Desarrollo] Evento de acreditación exitosa a uno de los receptores
        del split (solo enviado durante splits)
      description: |-
        **Advertencia: Este endpoint está en desarrollo** 

         Los fondos han sido acreditados a uno de los receptores esperados del pago. Se enviará una notificación de este evento mediante un webhook por cada receptor esperado y únicamente cuando el pago contempla múltiples acreditaciones (split).
      parameters:
        - name: spidi-signature
          in: header
          required: true
          description: >-
            Firma HMAC-SHA256 para validar la autenticidad e integridad del
            mensaje.
          schema:
            type: string
            example: d9c8227652758252615617f6a8759526703902939d892376987f22387a672889
        - name: spidi-timestamp
          in: header
          required: true
          description: >-
            Timestamp ISO 8601 de la creación del evento para prevenir ataques
            de replay.
          schema:
            type: string
            format: date-time
            example: '2026-02-06T15:24:36.000Z'
        - name: idempotency-key
          in: header
          required: true
          description: >-
            UUID v4 único para garantizar que la operación se procese una sola
            vez.
          schema:
            type: string
            format: uuid
            example: 93465a7e-ea9b-41a8-8dca-14e811641c25
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - event
                - data
              properties:
                event:
                  type: string
                  enum:
                    - payment_session.accreditation_to_recipient_completed
                  description: >-
                    Se enviará cuando los fondos han sido acreditados a uno de
                    los receptores esperados del pago.
                data:
                  type: object
                  required:
                    - session_payment
                    - credit
                  properties:
                    session_payment:
                      type: object
                      properties:
                        id:
                          type: string
                          nullable: false
                          description: >-
                            Identificador único de la sesión de pago, accedible
                            a través del payment_url.
                        origin:
                          type: string
                          nullable: false
                          enum:
                            - button
                            - request
                          description: >-
                            Origen de la sesión: 'button' (Botón de pago) o
                            'request' (Solicitud SPIDI).
                        agreement_id:
                          type: string
                          format: uuid
                          nullable: true
                          description: >-
                            Identificador único del acuerdo de liquidación. Debe
                            ser UUID v4. 
                        currency_reference:
                          type: string
                          nullable: false
                          enum:
                            - USD
                            - EUR
                            - COP
                            - USDT
                            - VES
                          description: >-
                            Moneda de referencia que se fija para el pago. Usada
                            para calcular el monto en bolívares con la tasa
                            vigente.
                        amount_reference:
                          description: >-
                            Monto de referencia en la moneda especificada en
                            currencyReference con 2 decimales.
                          type: number
                          nullable: false
                          format: double
                          example: '100.001'
                        identifier_label:
                          type: string
                          nullable: true
                          description: >-
                            Etiqueta que indica cómo debe interpretarse el valor
                            enviado en identifier (ej. 'Nro de orden').
                        identifier:
                          type: string
                          nullable: false
                          description: >-
                            Identificador del pagador, interpretado según el
                            valor de identifier_label. Ejemplo: Nro de orden,
                            Nombre, etc.
                        description:
                          type: string
                          nullable: true
                          description: >-
                            Descripción del acuerdo o del concepto de pago
                            asociado a una sesión.
                          maxLength: 500
                        payment_method:
                          type: string
                          nullable: true
                          enum:
                            - crypto
                            - immediate_debit
                            - mobile_payment
                          description: 'Método de pago utilizado. Eco del request: no.'
                    credit:
                      type: object
                      properties:
                        id:
                          type: string
                        amount_ves_credited:
                          type: number
                          nullable: true
                          description: >-
                            Monto neto acreditado al receptor en bolívares,
                            luego de aplicar las comisiones correspondientes.
                            Siempre tiene 2 decimales.
                          format: double
                          example: '100.01'
                        bank_commissions_ves:
                          type: number
                          nullable: true
                          format: decimal(12,2)
                          description: >-
                            Comisión bancaria total cobrada en bolívares para la
                            liquidación. Eco del request: no.
                        receive_date:
                          type: string
                          format: date-time
                          nullable: true
                          description: Fecha y hora en que se acreditó el pago (ISO 8601).
                        bank_name:
                          type: string
                          nullable: true
                          description: 'Nombre comercial del banco. Eco del request: no.'
                        bank_reference_id:
                          type: string
                          nullable: true
                          description: 'Referencia bancaria del pago. Eco del request: no.'
                        recipient:
                          type: object
                          properties:
                            id:
                              type: string
                              nullable: true
                              description: Identificador del receptor del crédito.
                            type:
                              type: string
                              nullable: true
                              description: Tipo del receptor del crédito.
                              enum:
                                - owner
                                - partner
                            split_recipient_agreement_id:
                              type: string
                              nullable: false
                              format: uuid
                              description: >-
                                UUID global SPIDI del agreement de recepción.
                                Este ID se usará en acuerdos de distribución
                                para identificar al receptor del split.
                                (Requerido en distribution)
                            partner:
                              type: object
                              properties:
                                observations:
                                  type: string
                                  nullable: false
                                  maxLength: 500
                                  description: >-
                                    Mensaje libre para el partner (máx. 500
                                    caracteres). (Requerido en distribution, Eco
                                    del request: sí)
                                name:
                                  type: string
                                  nullable: true
                                  description: Nombre o razón social del partner
                                rif_number:
                                  type: string
                                  nullable: true
                                  description: RIF del partner
            examples:
              acreditacion_parcial:
                summary: >-
                  Ejemplo de request de acreditación exitosa por receptor de
                  split
                value:
                  event: payment_session.accreditation_to_recipient_completed
                  data:
                    session_payment:
                      id: 3ddc4cfb-c09a-43de-92c1-e4a069732e90
                      origin: request
                      agreement_id: c4cfb-c-43deb-c09a-4-92c109a
                      currency_reference: USD
                      amount_reference: 50.01
                      identifier_label: Nombre y Apellido
                      identifier: Federico Coppola
                      description: ''
                      payment_method: immediate_debit
                    credit:
                      id: '1122'
                      amount_ves_credited: 1000.12
                      bank_commissions_ves: 2.32
                      receive_date: '2025-09-18T21:00:10Z'
                      bank_name: BANESCO
                      bank_reference_id: '4555111'
                      recipient:
                        id: partner_1
                        type: partner
                        agreement_id: rcv_014…723c1a2
                        partner_info:
                          observations: any observation to Partner 1
                          name: Restaurante Los Sabores C.A.
                          rif_number: J-40011223-5
      responses:
        '200':
          description: Webhook procesado exitosamente
  payment_session.accreditations_completed:
    post:
      tags:
        - Webhooks
      operationId: paymentSessionAccreditationsCompleted
      summary: Evento de finalización exitosa de la acreditación total de los fondos
      description: >-
        La totalidad de los fondos ha sido acreditada al receptor o a los
        receptores esperados del pago. Se enviará una notificación de este
        evento mediante un webhook cuando el pago contemple una única
        acreditación, se enviara el evento cuando se complete dicha
        acreditación. En caso de múltiples acreditaciones (split), se emitirá
        una sola vez al completarse exitosamente la totalidad de las
        acreditaciones.
      parameters:
        - name: spidi-signature
          in: header
          required: true
          description: >-
            Firma HMAC-SHA256 para validar la autenticidad e integridad del
            mensaje.
          schema:
            type: string
            example: d9c8227652758252615617f6a8759526703902939d892376987f22387a672889
        - name: spidi-timestamp
          in: header
          required: true
          description: >-
            Timestamp ISO 8601 de la creación del evento para prevenir ataques
            de replay.
          schema:
            type: string
            format: date-time
            example: '2026-02-06T15:24:36.000Z'
        - name: idempotency-key
          in: header
          required: true
          description: >-
            UUID v4 único para garantizar que la operación se procese una sola
            vez.
          schema:
            type: string
            format: uuid
            example: 93465a7e-ea9b-41a8-8dca-14e811641c25
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - event
                - data
              properties:
                event:
                  type: string
                  enum:
                    - payment_session.accredited
                  description: Tipo de evento de acreditación completa.
                data:
                  type: object
                  required:
                    - session_payment
                    - receiver_credits
                    - receiver_credits_summary
                  properties:
                    session_payment:
                      type: object
                      properties:
                        id:
                          type: string
                          nullable: false
                          description: >-
                            Identificador único de la sesión de pago, accedible
                            a través del payment_url.
                        origin:
                          type: string
                          nullable: false
                          enum:
                            - button
                            - request
                          description: >-
                            Origen de la sesión: 'button' (Botón de pago) o
                            'request' (Solicitud SPIDI).
                        agreement_id:
                          type: string
                          format: uuid
                          nullable: true
                          description: >-
                            Identificador único del acuerdo de liquidación. Debe
                            ser UUID v4. 
                        currency_reference:
                          type: string
                          nullable: false
                          enum:
                            - USD
                            - EUR
                            - COP
                            - USDT
                            - VES
                          description: >-
                            Moneda de referencia que se fija para el pago. Usada
                            para calcular el monto en bolívares con la tasa
                            vigente.
                        amount_reference:
                          description: >-
                            Monto de referencia en la moneda especificada en
                            currencyReference con 2 decimales.
                          type: number
                          nullable: false
                          format: double
                          example: '100.001'
                        identifier_label:
                          type: string
                          nullable: true
                          description: >-
                            Etiqueta que indica cómo debe interpretarse el valor
                            enviado en identifier (ej. 'Nro de orden').
                        identifier:
                          type: string
                          nullable: false
                          description: >-
                            Identificador del pagador, interpretado según el
                            valor de identifier_label. Ejemplo: Nro de orden,
                            Nombre, etc.
                        description:
                          type: string
                          nullable: true
                          description: >-
                            Descripción del acuerdo o del concepto de pago
                            asociado a una sesión.
                          maxLength: 500
                        payment_method:
                          type: string
                          nullable: true
                          enum:
                            - crypto
                            - immediate_debit
                            - mobile_payment
                          description: 'Método de pago utilizado. Eco del request: no.'
                    receiver_credits:
                      type: object
                      nullable: true
                      description: >-
                        Detalles de la liquidación de créditos (Owner y
                        Partners).
                      properties:
                        owner:
                          type: object
                          description: Crédito asignado al dueño de la cuenta principal.
                          properties:
                            receiver_id:
                              type: string
                              nullable: true
                              description: Identificador del receptor del crédito.
                            memo:
                              type: string
                              nullable: true
                              description: Nota o referencia interna para el crédito.
                            spidi_credit_id:
                              type: string
                              nullable: true
                              description: ID de la liquidación al receptor del pago.
                            amount_ves_credited:
                              type: number
                              nullable: true
                              description: >-
                                Monto neto acreditado al receptor en bolívares,
                                luego de aplicar las comisiones
                                correspondientes. Siempre tiene 2 decimales.
                              format: double
                              example: '100.01'
                            bank_commissions_ves:
                              type: number
                              nullable: true
                              format: decimal(12,2)
                              description: >-
                                Comisión bancaria total cobrada en bolívares
                                para la liquidación. Eco del request: no.
                            receive_date:
                              type: string
                              format: date-time
                              nullable: true
                              description: >-
                                Fecha y hora en que se acreditó el pago (ISO
                                8601).
                            bank_name:
                              type: string
                              nullable: true
                              description: 'Nombre comercial del banco. Eco del request: no.'
                            bank_reference_id:
                              type: string
                              nullable: true
                              description: >-
                                Referencia bancaria del pago. Eco del request:
                                no.
                        partners:
                          type: array
                          nullable: true
                          description: Lista de créditos asignados a partners (split).
                          items:
                            type: object
                            properties:
                              receiver_id:
                                type: string
                                nullable: true
                                description: Identificador del receptor del crédito.
                              memo:
                                type: string
                                nullable: true
                                description: Nota o referencia interna para el crédito.
                              partner_rif_name:
                                type: string
                                nullable: true
                                description: Nombre o razón social del partner
                              partner_rif_number:
                                type: string
                                nullable: true
                                description: RIF del partner
                              split_recipient_agreement_id:
                                type: string
                                nullable: false
                                format: uuid
                                description: >-
                                  UUID global SPIDI del agreement de recepción.
                                  Este ID se usará en acuerdos de distribución
                                  para identificar al receptor del split.
                                  (Requerido en distribution)
                              spidi_credit_id:
                                type: string
                                nullable: true
                                description: ID de la liquidación al receptor del pago.
                              amount_ves_credited:
                                type: number
                                nullable: true
                                description: >-
                                  Monto neto acreditado al receptor en
                                  bolívares, luego de aplicar las comisiones
                                  correspondientes. Siempre tiene 2 decimales.
                                format: double
                                example: '100.01'
                              bank_commissions_ves:
                                type: number
                                nullable: true
                                format: decimal(12,2)
                                description: >-
                                  Comisión bancaria total cobrada en bolívares
                                  para la liquidación. Eco del request: no.
                              receive_date:
                                type: string
                                format: date-time
                                nullable: true
                                description: >-
                                  Fecha y hora en que se acreditó el pago (ISO
                                  8601).
                              bank_name:
                                type: string
                                nullable: true
                                description: >-
                                  Nombre comercial del banco. Eco del request:
                                  no.
                              bank_reference_id:
                                type: string
                                nullable: true
                                description: >-
                                  Referencia bancaria del pago. Eco del request:
                                  no.
                              observations:
                                type: string
                                nullable: false
                                maxLength: 500
                                description: >-
                                  Mensaje libre para el partner (máx. 500
                                  caracteres). (Requerido en distribution, Eco
                                  del request: sí)
                    receiver_credits_summary:
                      type: object
                      nullable: true
                      description: Resumen agregado de liquidaciones al o los receptores.
                      properties:
                        total_credits:
                          type: integer
                          nullable: false
                          description: Número total de créditos/liquidaciones realizados.
                        total_amount_ves_credited:
                          type: number
                          nullable: true
                          format: double
                          description: Monto total acreditado en VES.
                        total_bank_commissions_ves:
                          type: number
                          nullable: true
                          format: double
                          description: Total de comisiones bancarias en VES.
            examples:
              acreditacion_completa:
                summary: Ejemplo de request de acreditación completa
                value:
                  event: payment_session.accredited
                  data:
                    session_payment:
                      id: 3ddc4cfb-c09a-43de-92c1-e4a069732e90
                      origin: request
                      agreement_id: c4cfb-c-43deb-c09a-4-92c109a
                      currency_reference: USD
                      amount_reference: 50.01
                      identifier_label: Nombre y Apellido
                      identifier: Federico Coppola
                      description: ''
                      payment_method: immediate_debit
                    receiver_credits:
                      owner:
                        receiver_id: owner
                        memo: propio
                        spidi_credit_id: '1122'
                        amount_ves_credited: 5090.56
                        bank_commissions_ves: 8.01
                        receive_date: '2025-09-18T21:00:10Z'
                        bank_name: BANESCO
                        bank_reference_id: '4555111'
                      partners:
                        - receiver_id: partner_1
                          memo: ''
                          partner_rif_name: Restaurante Los Sabores C.A.
                          partner_rif_number: J-40011223-5
                          split_recipient_agreement_id: rcv_014…723c1a2
                          spidi_credit_id: '1122'
                          amount_ves_credited: 1000.12
                          bank_commissions_ves: 2.32
                          receive_date: '2025-09-18T21:00:10Z'
                          bank_name: BANESCO
                          bank_reference_id: '4555111'
                          observations: any observation to Partner 1
                    receiver_credits_summary:
                      split: true
                      total_credits: 2
                      total_amount_ves_credited: 6090.56
                      total_bank_commissions_ves: 10.3
                      split_general_info:
                        document_name: D001-00045678
                        document_date: '2025-10-20'
                        document_url: https://owner.com/document/F001-00045678
                        document_observations: any observation to owner
      responses:
        '200':
          description: Webhook procesado exitosamente
components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: Requiere el uso de el token obtenido en /auth/login
    BasicAuth:
      type: http
      scheme: basic
      description: >-
        Requiere el uso de las credenciales (Usuario/Contraseña) codificadas en
        Base64
  schemas:
    userSpidi_username:
      type: string
      nullable: false
      description: Nombre de usuario o identificador único del comercio.
    password:
      type: string
      nullable: false
      description: Contraseña de acceso del usuario.
    LoginRequest:
      type: object
      required:
        - short_name
        - password
      properties:
        short_name:
          type: string
          nullable: false
          description: Nombre de usuario o identificador único del comercio.
        password:
          type: string
          nullable: false
          description: Contraseña de acceso del usuario.
    token:
      type: string
      nullable: false
      description: >-
        Token de autorización **JWT** para autenticar requests posteriores. 


        * El token es un **JWT (JSON Web Token)** codificado en Base64.

        * Debe incluirse en el header `Authorization: Bearer {token}` de
        requests posteriores.

        * Tiene un tiempo de expiración definido por seguridad.

        * Contiene información del usuario autenticado y permisos.
    LoginResponse:
      type: object
      required:
        - token
      properties:
        token:
          type: string
          nullable: false
          description: >-
            Token de autorización **JWT** para autenticar requests posteriores. 


            * El token es un **JWT (JSON Web Token)** codificado en Base64.

            * Debe incluirse en el header `Authorization: Bearer {token}` de
            requests posteriores.

            * Tiene un tiempo de expiración definido por seguridad.

            * Contiene información del usuario autenticado y permisos.
    authentication--loginValidationError:
      type: string
      example: The provided credentials are incorrect
      nullable: true
      description: Error general de autenticación.
    LoginErrorResponse:
      type: object
      required:
        - success
        - message
      properties:
        success:
          type: boolean
          example: false
          description: Indica si la operación fue exitosa.
        message:
          type: string
          example: Invalid credentials
          description: Mensaje descriptivo del error.
        errors:
          type: object
          nullable: true
          description: Detalles específicos de los errores de validación.
          properties:
            short_name:
              type: string
              nullable: true
              example: This field is required.
              description: Error relacionado con el campo short_name.
            password:
              type: string
              nullable: true
              example: This field is required.
              description: Error relacionado con el campo password.
            authentication:
              nullable: true
              type: string
              example: The provided credentials are incorrect
              description: Error general de autenticación.
    title:
      type: string
      nullable: false
      description: 'Título visible. '
    description:
      type: string
      nullable: true
      description: Descripción del acuerdo o del concepto de pago asociado a una sesión.
      maxLength: 500
    immediate_debit:
      type: boolean
      description: Indica si permite pagos con débito inmediato.
    crypto:
      type: boolean
      description: >-
        Indica si se permiten pagos con criptomonedas en la configuración
        correspondiente. La liquidación siempre ocurre en bolívares.
    default_bank_account_id:
      type: string
      format: uuid
      nullable: false
      description: >-
        UUID de la cuenta bancaria por defecto que se utilizará para la
        liquidación. 
    origin_bank_code:
      type: string
      nullable: false
      description: 'Código oficial del banco de origen. '
    destination_bank_account_id:
      type: string
      nullable: true
      description: >-
        UUID de la cuenta bancaria de destino para un banco de origen
        específico. 
    agreement_rules:
      type: array
      nullable: true
      description: |-
        (**En Desarrollo**) Reglas de acuerdo. 
         En caso de usar origin_bank_code y destination_bank_account_id, se aplicará una regla de ruteo por banco de origen. Cada regla define a qué cuenta bancaria se debe enviar el dinero según el banco del pagador.
      items:
        type: object
        properties:
          origin_bank_code:
            type: string
            nullable: false
            description: 'Código oficial del banco de origen. '
          destination_bank_account_id:
            type: string
            nullable: true
            description: >-
              UUID de la cuenta bancaria de destino para un banco de origen
              específico. 
    AgreementRequest:
      type: object
      required:
        - title
        - payment_methods
        - default_bank_account_id
        - split
      properties:
        title:
          type: string
          nullable: false
          description: 'Título visible. '
        description:
          type: string
          nullable: true
          description: >-
            Descripción del acuerdo o del concepto de pago asociado a una
            sesión.
          maxLength: 500
        payment_methods:
          type: object
          required:
            - immediate_debit
            - crypto
            - mobile_payment
          properties:
            immediate_debit:
              type: boolean
              description: Indica si permite pagos con débito inmediato.
            crypto:
              type: boolean
              description: >-
                Indica si se permiten pagos con criptomonedas en la
                configuración correspondiente. La liquidación siempre ocurre en
                bolívares.
            mobile_payment:
              type: boolean
              description: Indica si permite pagos móviles.
        default_bank_account_id:
          type: string
          format: uuid
          nullable: false
          description: >-
            UUID de la cuenta bancaria por defecto que se utilizará para la
            liquidación. 
        rules:
          type: array
          nullable: true
          description: |-
            (**En Desarrollo**) Reglas de acuerdo. 
             En caso de usar origin_bank_code y destination_bank_account_id, se aplicará una regla de ruteo por banco de origen. Cada regla define a qué cuenta bancaria se debe enviar el dinero según el banco del pagador.
          items:
            type: object
            properties:
              origin_bank_code:
                type: string
                nullable: false
                description: 'Código oficial del banco de origen. '
              destination_bank_account_id:
                type: string
                nullable: true
                description: >-
                  UUID de la cuenta bancaria de destino para un banco de origen
                  específico. 
        split:
          type: boolean
          description: >-
            Modo de split: false (sin distribución) o true (permite split por
            sesión).
    success:
      type: boolean
      nullable: false
      description: >-
        Indica si la operación fue exitosa. True si el endpoint se procesó de
        forma exitosa. False de lo contrario
      example: true
    agreement_id:
      type: string
      format: uuid
      nullable: true
      description: 'Identificador único del acuerdo de liquidación. Debe ser UUID v4. '
    status:
      type: string
      nullable: false
      enum:
        - pending
        - paid
        - failed
        - expired
      description: >-
        Estado actual de la sesión. El valor failed solo se aplica para sesiones
        creadas con botón de pago.
    created_at:
      type: string
      nullable: true
      format: date-time
      description: Fecha y hora de creación del recurso en formato ISO 8601.
    created_by:
      type: string
      nullable: true
      description: Identificador del usuario que creó el recurso administrable.
    AgreementResponse:
      type: object
      required:
        - success
        - data
      properties:
        success:
          type: boolean
          nullable: false
          description: >-
            Indica si la operación fue exitosa. True si el endpoint se procesó
            de forma exitosa. False de lo contrario
          example: true
        data:
          type: object
          required:
            - agreement_id
            - title
            - split
            - payment_methods
            - default_bank_account_id
            - status
            - created_at
            - created_by
          properties:
            agreement_id:
              type: string
              format: uuid
              nullable: true
              description: >-
                Identificador único del acuerdo de liquidación. Debe ser UUID
                v4. 
            title:
              type: string
              nullable: false
              description: 'Título visible. '
            description:
              type: string
              nullable: true
              description: >-
                Descripción del acuerdo o del concepto de pago asociado a una
                sesión.
              maxLength: 500
            split:
              type: boolean
              description: Modo de split configurado en el acuerdo.
            payment_methods:
              type: object
              required:
                - immediate_debit
                - crypto
                - mobile_payment
              properties:
                immediate_debit:
                  type: boolean
                  description: Indica si permite pagos con débito inmediato.
                crypto:
                  type: boolean
                  description: >-
                    Indica si se permiten pagos con criptomonedas en la
                    configuración correspondiente. La liquidación siempre ocurre
                    en bolívares.
                mobile_payment:
                  type: boolean
                  description: Indica si permite pagos móviles.
            default_bank_account_id:
              type: string
              format: uuid
              nullable: false
              description: >-
                UUID de la cuenta bancaria por defecto que se utilizará para la
                liquidación. 
            rules:
              type: array
              nullable: true
              description: |-
                (**En Desarrollo**) Reglas de acuerdo. 
                 En caso de usar origin_bank_code y destination_bank_account_id, se aplicará una regla de ruteo por banco de origen. Cada regla define a qué cuenta bancaria se debe enviar el dinero según el banco del pagador.
              items:
                type: object
                properties:
                  origin_bank_code:
                    type: string
                    nullable: false
                    description: 'Código oficial del banco de origen. '
                  destination_bank_account_id:
                    type: string
                    nullable: true
                    description: >-
                      UUID de la cuenta bancaria de destino para un banco de
                      origen específico. 
            status:
              type: string
              nullable: false
              enum:
                - pending
                - paid
                - failed
                - expired
              description: >-
                Estado actual de la sesión. El valor failed solo se aplica para
                sesiones creadas con botón de pago.
            created_at:
              type: string
              nullable: true
              format: date-time
              description: Fecha y hora de creación del recurso en formato ISO 8601.
            created_by:
              type: string
              nullable: true
              description: Identificador del usuario que creó el recurso administrable.
    type:
      type: string
      example: Invalid value. Must be button or request
      description: Error relacionado con el campo type.
    field:
      type: string
      example: Invalid field value
      description: Error genérico de campo.
    AgreementErrorResponse:
      type: object
      required:
        - success
        - message
      properties:
        success:
          type: boolean
          example: false
          description: Indica si la operación fue exitosa.
        message:
          type: string
          example: 'Missing required field: title'
          description: Mensaje descriptivo del error.
        errors:
          type: object
          nullable: true
          description: Detalles específicos de los errores de validación.
          properties:
            type:
              type: string
              example: Invalid value. Must be button or request
              description: Error relacionado con el campo type.
            split:
              type: boolean
              example: Invalid value. Must be true or false
              description: Error relacionado con el modo de split.
            spidi_id:
              type: string
              example: The credentials are incorrect
              description: Error de autenticación.
            field:
              type: string
              example: Invalid field value
              description: Error genérico de campo.
    partner_name:
      type: string
      nullable: true
      description: Nombre o razón social del partner
    partner_rifNumber:
      type: string
      nullable: true
      description: RIF del partner
    partner_email:
      type: string
      format: email
      description: Correo electrónico del partner.
    partner_phone:
      type: string
      description: Teléfono del partner.
    bankCode:
      type: string
      nullable: false
      description: Código del banco. Solo acepta 3–4 dígitos (p.ej., 105 o 0137).
    partner_phoneOrAccountForPayment:
      type: string
      description: Teléfono o número de cuenta para el pago.
    partner_type:
      type: string
      description: Tipo de usuario.
      enum:
        - personal
        - comercial
    message:
      type: string
      nullable: true
      description: Mensaje de confirmación o error legible.
    partner_id:
      type: string
      format: uuid
      description: Identificador único del partner.
    partner_shortName:
      type: string
      description: >-
        Nombre corto del partner. Se genera automáticamente a partir del owner
        que lo crea seguido de p1 p2 p3 etc
    accountBank_id:
      type: string
      format: uuid
      description: Identificador único de la cuenta bancaria en nuestros sistemas.
    agreementRecipient_id:
      type: string
      nullable: false
      format: uuid
      description: >-
        UUID global SPIDI del agreement de recepción. Este ID se usará en
        acuerdos de distribución para identificar al receptor del split.
        (Requerido en distribution)
    amountReference:
      description: >-
        Monto de referencia en la moneda especificada en currencyReference con 2
        decimales.
      type: number
      nullable: false
      format: double
      example: '100.001'
    currencyReference:
      type: string
      nullable: false
      enum:
        - USD
        - EUR
        - COP
        - USDT
        - VES
      description: >-
        Moneda de referencia que se fija para el pago. Usada para calcular el
        monto en bolívares con la tasa vigente.
    identifier_label:
      type: string
      nullable: true
      description: >-
        Etiqueta que indica cómo debe interpretarse el valor enviado en
        identifier (ej. 'Nro de orden').
    identifier:
      type: string
      nullable: false
      description: >-
        Identificador del pagador, interpretado según el valor de
        identifier_label. Ejemplo: Nro de orden, Nombre, etc.
    success_url:
      type: string
      nullable: true
      format: uri
      description: URL de redirección que se utiliza cuando un intento de pago es exitoso.
      pattern: ^[a-z1-9]+://[^\s]*$
    failure_url:
      type: string
      nullable: true
      format: uri
      description: 'URL de redirección que se utiliza cuando un intento de pago falle. '
      pattern: ^[a-z1-9]+://[^\s]*$
    webhook_url:
      type: string
      nullable: true
      format: uri
      description: 'URL para recibir notificaciones de webhook. '
    splitDocument_name:
      type: string
      nullable: true
      description: >-
        Nombre del documento asociado a la transacción split (por ejemplo:
        factura/recibo/contrato D001-00045678).
    splitDocument_type:
      type: string
      nullable: true
      description: Formato libre del owner donde especifica el tipo de documento.
      examples:
        - Factura
        - Contrato
        - Recibo
    splitDocument_date:
      type: string
      nullable: true
      format: date
      description: Fecha de emisión del documento en formato ISO 8601 (YYYY-MM-DD).
    splitDocument_url:
      type: string
      nullable: true
      format: uri
      description: >-
        Enlace para visualizar/descargar el documento del split. Puede ser
        público con hash o una URL autenticada.
    splitDocument_observations:
      type: string
      nullable: true
      maxLength: 500
      description: Observaciones libres del owner (máx. 500 caracteres).
    splitDocument:
      type: object
      nullable: true
      description: >-
        Información del documento proporcionado por el owner a los partners para
        dejar evidencia del split.


        **Notas importantes:**

        - Esta información **no implica cálculo fiscal** por parte de SPIDI; es
        solo comunicación entre owner y partners.

        - `splitDocument_url` puede ser público con hash o una URL autenticada.

        - SPIDI **no interpreta ni calcula IVA** a partir de esta información;
        solo lo transporta.
      properties:
        name:
          type: string
          nullable: true
          description: >-
            Nombre del documento asociado a la transacción split (por ejemplo:
            factura/recibo/contrato D001-00045678).
        type:
          type: string
          nullable: true
          description: Formato libre del owner donde especifica el tipo de documento.
          examples:
            - Factura
            - Contrato
            - Recibo
        date:
          type: string
          nullable: true
          format: date
          description: Fecha de emisión del documento en formato ISO 8601 (YYYY-MM-DD).
        url:
          type: string
          nullable: true
          format: uri
          description: >-
            Enlace para visualizar/descargar el documento del split. Puede ser
            público con hash o una URL autenticada.
        observations:
          type: string
          nullable: true
          maxLength: 500
          description: Observaciones libres del owner (máx. 500 caracteres).
    label:
      type: string
      nullable: true
      description: >-
        Etiqueta descriptiva del receptor en un split. (Opcional en
        distribution, Eco del request: sí)
    observations:
      type: string
      nullable: false
      maxLength: 500
      description: >-
        Mensaje libre para el partner (máx. 500 caracteres). (Requerido en
        distribution, Eco del request: sí)
    distribution:
      type: array
      nullable: false
      description: >-
        Lista de reglas/destinatarios del split. Debe tener ≥ 1 ítem. La suma de
        amount_reference debe ser menor al amount total de la sesión, porque la
        diferencia restante se asigna automáticamente al owner, quien siempre
        debe recibir una parte del pago. (Requerido cuando split=true)
      items:
        type: object
        required:
          - split_recipient_agreement_id
          - amount_reference
          - observations
        properties:
          split_recipient_agreement_id:
            type: string
            nullable: false
            format: uuid
            description: >-
              UUID global SPIDI del agreement de recepción. Este ID se usará en
              acuerdos de distribución para identificar al receptor del split.
              (Requerido en distribution)
          label:
            type: string
            nullable: true
            description: >-
              Etiqueta descriptiva del receptor en un split. (Opcional en
              distribution, Eco del request: sí)
          amount_reference:
            description: >-
              Monto de referencia en la moneda especificada en currencyReference
              con 2 decimales.
            type: number
            nullable: false
            format: double
            example: '100.001'
          observations:
            type: string
            nullable: false
            maxLength: 500
            description: >-
              Mensaje libre para el partner (máx. 500 caracteres). (Requerido en
              distribution, Eco del request: sí)
    split:
      type: object
      nullable: true
      description: >-
        Configuración de división de pagos (Request) / Eco del request del split
        (Response).
      properties:
        document:
          type: object
          nullable: true
          description: >-
            Información del documento proporcionado por el owner a los partners
            para dejar evidencia del split.


            **Notas importantes:**

            - Esta información **no implica cálculo fiscal** por parte de SPIDI;
            es solo comunicación entre owner y partners.

            - `splitDocument_url` puede ser público con hash o una URL
            autenticada.

            - SPIDI **no interpreta ni calcula IVA** a partir de esta
            información; solo lo transporta.
          properties:
            name:
              type: string
              nullable: true
              description: >-
                Nombre del documento asociado a la transacción split (por
                ejemplo: factura/recibo/contrato D001-00045678).
            type:
              type: string
              nullable: true
              description: Formato libre del owner donde especifica el tipo de documento.
              examples:
                - Factura
                - Contrato
                - Recibo
            date:
              type: string
              nullable: true
              format: date
              description: Fecha de emisión del documento en formato ISO 8601 (YYYY-MM-DD).
            url:
              type: string
              nullable: true
              format: uri
              description: >-
                Enlace para visualizar/descargar el documento del split. Puede
                ser público con hash o una URL autenticada.
            observations:
              type: string
              nullable: true
              maxLength: 500
              description: Observaciones libres del owner (máx. 500 caracteres).
        distribution:
          type: array
          nullable: false
          description: >-
            Lista de reglas/destinatarios del split. Debe tener ≥ 1 ítem. La
            suma de amount_reference debe ser menor al amount total de la
            sesión, porque la diferencia restante se asigna automáticamente al
            owner, quien siempre debe recibir una parte del pago. (Requerido
            cuando split=true)
          items:
            type: object
            required:
              - split_recipient_agreement_id
              - amount_reference
              - observations
            properties:
              split_recipient_agreement_id:
                type: string
                nullable: false
                format: uuid
                description: >-
                  UUID global SPIDI del agreement de recepción. Este ID se usará
                  en acuerdos de distribución para identificar al receptor del
                  split. (Requerido en distribution)
              label:
                type: string
                nullable: true
                description: >-
                  Etiqueta descriptiva del receptor en un split. (Opcional en
                  distribution, Eco del request: sí)
              amount_reference:
                description: >-
                  Monto de referencia en la moneda especificada en
                  currencyReference con 2 decimales.
                type: number
                nullable: false
                format: double
                example: '100.001'
              observations:
                type: string
                nullable: false
                maxLength: 500
                description: >-
                  Mensaje libre para el partner (máx. 500 caracteres).
                  (Requerido en distribution, Eco del request: sí)
    button_config:
      type: array
      description: >-
        Configuración dinámica opcional para personalizar la experiencia
        comercial del botón de pago.
      items:
        type: object
        properties:
          type:
            type: string
            description: >-
              Identificador de la configuración a aplicar. Por ejemplo,
              'initial_currency' sirve para priorizar qué método de pago (fiat o
              cripto) se muestra por defecto al usuario.
          value:
            description: >-
              Valor asociado a la configuración. Para 'initial_currency', debe
              seguir el estándar ISO 4217 para monedas fiduciarias o 'CRYPTO'
              para activos digitales.
            enum:
              - VES
              - CRYPTO
        required:
          - type
          - value
        example:
          type: initial_currency
          value: CRYPTO
    durationMinutes:
      type: integer
      nullable: true
      description: Duración en minutos de la sesión.
      minimum: 5
      maximum: 20
      example: 5
    PaymentSessionButtonRequest:
      type: object
      required:
        - agreement_id
        - amount_reference
        - currency_reference
        - identifier_label
        - identifier
        - description
        - success_url
        - failure_url
      properties:
        agreement_id:
          type: string
          format: uuid
          nullable: true
          description: 'Identificador único del acuerdo de liquidación. Debe ser UUID v4. '
        amount_reference:
          description: >-
            Monto de referencia en la moneda especificada en currencyReference
            con 2 decimales.
          type: number
          nullable: false
          format: double
          example: '100.001'
        currency_reference:
          type: string
          nullable: false
          enum:
            - USD
            - EUR
            - COP
            - USDT
            - VES
          description: >-
            Moneda de referencia que se fija para el pago. Usada para calcular
            el monto en bolívares con la tasa vigente.
        identifier_label:
          type: string
          nullable: true
          description: >-
            Etiqueta que indica cómo debe interpretarse el valor enviado en
            identifier (ej. 'Nro de orden').
        identifier:
          type: string
          nullable: false
          description: >-
            Identificador del pagador, interpretado según el valor de
            identifier_label. Ejemplo: Nro de orden, Nombre, etc.
        description:
          type: string
          nullable: true
          description: >-
            Descripción del acuerdo o del concepto de pago asociado a una
            sesión.
          maxLength: 500
        success_url:
          type: string
          nullable: true
          format: uri
          description: >-
            URL de redirección que se utiliza cuando un intento de pago es
            exitoso.
          pattern: ^[a-z1-9]+://[^\s]*$
        failure_url:
          type: string
          nullable: true
          format: uri
          description: 'URL de redirección que se utiliza cuando un intento de pago falle. '
          pattern: ^[a-z1-9]+://[^\s]*$
        webhook_url:
          type: string
          nullable: true
          format: uri
          description: 'URL para recibir notificaciones de webhook. '
        split:
          type: object
          nullable: true
          description: >-
            Configuración de división de pagos (Request) / Eco del request del
            split (Response).
          properties:
            document:
              type: object
              nullable: true
              description: >-
                Información del documento proporcionado por el owner a los
                partners para dejar evidencia del split.


                **Notas importantes:**

                - Esta información **no implica cálculo fiscal** por parte de
                SPIDI; es solo comunicación entre owner y partners.

                - `splitDocument_url` puede ser público con hash o una URL
                autenticada.

                - SPIDI **no interpreta ni calcula IVA** a partir de esta
                información; solo lo transporta.
              properties:
                name:
                  type: string
                  nullable: true
                  description: >-
                    Nombre del documento asociado a la transacción split (por
                    ejemplo: factura/recibo/contrato D001-00045678).
                type:
                  type: string
                  nullable: true
                  description: >-
                    Formato libre del owner donde especifica el tipo de
                    documento.
                  examples:
                    - Factura
                    - Contrato
                    - Recibo
                date:
                  type: string
                  nullable: true
                  format: date
                  description: >-
                    Fecha de emisión del documento en formato ISO 8601
                    (YYYY-MM-DD).
                url:
                  type: string
                  nullable: true
                  format: uri
                  description: >-
                    Enlace para visualizar/descargar el documento del split.
                    Puede ser público con hash o una URL autenticada.
                observations:
                  type: string
                  nullable: true
                  maxLength: 500
                  description: Observaciones libres del owner (máx. 500 caracteres).
            distribution:
              type: array
              nullable: false
              description: >-
                Lista de reglas/destinatarios del split. Debe tener ≥ 1 ítem. La
                suma de amount_reference debe ser menor al amount total de la
                sesión, porque la diferencia restante se asigna automáticamente
                al owner, quien siempre debe recibir una parte del pago.
                (Requerido cuando split=true)
              items:
                type: object
                required:
                  - split_recipient_agreement_id
                  - amount_reference
                  - observations
                properties:
                  split_recipient_agreement_id:
                    type: string
                    nullable: false
                    format: uuid
                    description: >-
                      UUID global SPIDI del agreement de recepción. Este ID se
                      usará en acuerdos de distribución para identificar al
                      receptor del split. (Requerido en distribution)
                  label:
                    type: string
                    nullable: true
                    description: >-
                      Etiqueta descriptiva del receptor en un split. (Opcional
                      en distribution, Eco del request: sí)
                  amount_reference:
                    description: >-
                      Monto de referencia en la moneda especificada en
                      currencyReference con 2 decimales.
                    type: number
                    nullable: false
                    format: double
                    example: '100.001'
                  observations:
                    type: string
                    nullable: false
                    maxLength: 500
                    description: >-
                      Mensaje libre para el partner (máx. 500 caracteres).
                      (Requerido en distribution, Eco del request: sí)
        config:
          type: array
          description: >-
            Configuración dinámica opcional para personalizar la experiencia
            comercial del botón de pago.
          items:
            type: object
            properties:
              type:
                type: string
                description: >-
                  Identificador de la configuración a aplicar. Por ejemplo,
                  'initial_currency' sirve para priorizar qué método de pago
                  (fiat o cripto) se muestra por defecto al usuario.
              value:
                description: >-
                  Valor asociado a la configuración. Para 'initial_currency',
                  debe seguir el estándar ISO 4217 para monedas fiduciarias o
                  'CRYPTO' para activos digitales.
                enum:
                  - VES
                  - CRYPTO
            required:
              - type
              - value
            example:
              type: initial_currency
              value: CRYPTO
        duration_minutes:
          type: integer
          nullable: true
          description: Duración en minutos de la sesión.
          minimum: 5
          maximum: 20
          example: 5
    session_id:
      type: string
      nullable: false
      description: >-
        Identificador único de la sesión de pago, accedible a través del
        payment_url.
    session_origin:
      type: string
      nullable: false
      enum:
        - button
        - request
      description: >-
        Origen de la sesión: 'button' (Botón de pago) o 'request' (Solicitud
        SPIDI).
    payment_url:
      type: string
      nullable: true
      description: URL de la página segura SPIDI donde quien paga realiza el pago.
      example: '{{base_url}}/?id=3ddc4cfb-c09a-43de-92c1-e4a069732e90'
    PaymentSessionButtonResponse:
      type: object
      required:
        - success
        - message
        - data
      properties:
        success:
          type: boolean
          nullable: false
          description: >-
            Indica si la operación fue exitosa. True si el endpoint se procesó
            de forma exitosa. False de lo contrario
          example: true
        message:
          type: string
          example: Payment session created successfully.
          description: Mensaje de confirmación de la creación.
        data:
          type: object
          required:
            - session_id
            - session_origin
            - payment_url
            - currency_reference
            - amount_reference
            - identifier_label
            - identifier
            - description
            - success_url
            - failure_url
            - created_at
          properties:
            session_id:
              type: string
              nullable: false
              description: >-
                Identificador único de la sesión de pago, accedible a través del
                payment_url.
            session_origin:
              type: string
              nullable: false
              enum:
                - button
                - request
              description: >-
                Origen de la sesión: 'button' (Botón de pago) o 'request'
                (Solicitud SPIDI).
            payment_url:
              type: string
              nullable: true
              description: URL de la página segura SPIDI donde quien paga realiza el pago.
              example: '{{base_url}}/?id=3ddc4cfb-c09a-43de-92c1-e4a069732e90'
            currency_reference:
              type: string
              nullable: false
              enum:
                - USD
                - EUR
                - COP
                - USDT
                - VES
              description: >-
                Moneda de referencia que se fija para el pago. Usada para
                calcular el monto en bolívares con la tasa vigente.
            amount_reference:
              description: >-
                Monto de referencia en la moneda especificada en
                currencyReference con 2 decimales.
              type: number
              nullable: false
              format: double
              example: '100.001'
            identifier_label:
              type: string
              nullable: true
              description: >-
                Etiqueta que indica cómo debe interpretarse el valor enviado en
                identifier (ej. 'Nro de orden').
            identifier:
              type: string
              nullable: false
              description: >-
                Identificador del pagador, interpretado según el valor de
                identifier_label. Ejemplo: Nro de orden, Nombre, etc.
            description:
              type: string
              nullable: true
              description: >-
                Descripción del acuerdo o del concepto de pago asociado a una
                sesión.
              maxLength: 500
            success_url:
              type: string
              nullable: true
              format: uri
              description: >-
                URL de redirección que se utiliza cuando un intento de pago es
                exitoso.
              pattern: ^[a-z1-9]+://[^\s]*$
            failure_url:
              type: string
              nullable: true
              format: uri
              description: >-
                URL de redirección que se utiliza cuando un intento de pago
                falle. 
              pattern: ^[a-z1-9]+://[^\s]*$
            webhook_url:
              type: string
              nullable: true
              format: uri
              description: 'URL para recibir notificaciones de webhook. '
            created_at:
              type: string
              nullable: true
              format: date-time
              description: Fecha y hora de creación del recurso en formato ISO 8601.
            split:
              type: object
              nullable: true
              description: >-
                Configuración de división de pagos (Request) / Eco del request
                del split (Response).
              properties:
                document:
                  type: object
                  nullable: true
                  description: >-
                    Información del documento proporcionado por el owner a los
                    partners para dejar evidencia del split.


                    **Notas importantes:**

                    - Esta información **no implica cálculo fiscal** por parte
                    de SPIDI; es solo comunicación entre owner y partners.

                    - `splitDocument_url` puede ser público con hash o una URL
                    autenticada.

                    - SPIDI **no interpreta ni calcula IVA** a partir de esta
                    información; solo lo transporta.
                  properties:
                    name:
                      type: string
                      nullable: true
                      description: >-
                        Nombre del documento asociado a la transacción split
                        (por ejemplo: factura/recibo/contrato D001-00045678).
                    type:
                      type: string
                      nullable: true
                      description: >-
                        Formato libre del owner donde especifica el tipo de
                        documento.
                      examples:
                        - Factura
                        - Contrato
                        - Recibo
                    date:
                      type: string
                      nullable: true
                      format: date
                      description: >-
                        Fecha de emisión del documento en formato ISO 8601
                        (YYYY-MM-DD).
                    url:
                      type: string
                      nullable: true
                      format: uri
                      description: >-
                        Enlace para visualizar/descargar el documento del split.
                        Puede ser público con hash o una URL autenticada.
                    observations:
                      type: string
                      nullable: true
                      maxLength: 500
                      description: Observaciones libres del owner (máx. 500 caracteres).
                distribution:
                  type: array
                  nullable: false
                  description: >-
                    Lista de reglas/destinatarios del split. Debe tener ≥ 1
                    ítem. La suma de amount_reference debe ser menor al amount
                    total de la sesión, porque la diferencia restante se asigna
                    automáticamente al owner, quien siempre debe recibir una
                    parte del pago. (Requerido cuando split=true)
                  items:
                    type: object
                    required:
                      - split_recipient_agreement_id
                      - amount_reference
                      - observations
                    properties:
                      split_recipient_agreement_id:
                        type: string
                        nullable: false
                        format: uuid
                        description: >-
                          UUID global SPIDI del agreement de recepción. Este ID
                          se usará en acuerdos de distribución para identificar
                          al receptor del split. (Requerido en distribution)
                      label:
                        type: string
                        nullable: true
                        description: >-
                          Etiqueta descriptiva del receptor en un split.
                          (Opcional en distribution, Eco del request: sí)
                      amount_reference:
                        description: >-
                          Monto de referencia en la moneda especificada en
                          currencyReference con 2 decimales.
                        type: number
                        nullable: false
                        format: double
                        example: '100.001'
                      observations:
                        type: string
                        nullable: false
                        maxLength: 500
                        description: >-
                          Mensaje libre para el partner (máx. 500 caracteres).
                          (Requerido en distribution, Eco del request: sí)
    authorization--loginValidationError:
      type: string
      example: Invalid or missing Bearer token
      description: Error de autorización.
    idempotency_key:
      type: string
      example: This idempotency key has already been used
      description: Error relacionado con la clave de idempotencia.
    PaymentSessionButtonErrorResponse:
      type: object
      required:
        - success
        - message
      properties:
        success:
          type: boolean
          example: false
          description: Indica si la operación fue exitosa.
        message:
          type: string
          example: Invalid request parameters
          description: Mensaje descriptivo del error.
        errors:
          type: object
          nullable: true
          description: Detalles específicos de los errores de validación.
          properties:
            agreement_id:
              type: string
              example: agreement ID is required
              description: Error relacionado con el campo agreement_id.
            amount_reference:
              type: string
              example: Amount must be greater than 0
              description: Error relacionado con el campo amount_reference.
            authorization:
              type: string
              example: Invalid or missing Bearer token
              description: Error de autorización.
            idempotency_key:
              type: string
              example: This idempotency key has already been used
              description: Error relacionado con la clave de idempotencia.
            field:
              type: string
              example: Invalid field value
              description: Error genérico de campo.
    last_expired_by:
      type: string
      nullable: true
      enum:
        - api
        - system
      description: 'Origen de la expiración: api o system.'
    inboundCrypto_provider_name:
      type: string
      nullable: true
      description: >-
        Nombre de la entidad o plataforma financiera que custodia los activos
        del usuario. Representa el ecosistema o 'banco digital' donde reside el
        saldo original (ej. Binance, Crixto).
      examples:
        - Binance
        - Crixto
    inboundCrypto_id:
      type: string
      nullable: true
      description: Identificador de la orden cripto generada por el proveedor.
    inboundCrixto_paymentMethod_name:
      type: string
      description: Nombre del método de pago (ej. Binance Pay, Crixto Pay).
      examples:
        - Binance Pay
        - Crixto Pay
    inboundCrypto_amountTransactionVes:
      type: number
      format: double
      nullable: true
      description: >-
        Monto con 3 decimales de la transacción en la moneda VES. Note que es el
        monto original sin incluir la comisión por el pago.
      example: 157.783
    inboundCrypto_amountPayByUserCrypto:
      type: number
      format: double
      nullable: true
      description: >-
        Monto con 3 decimales del pago realizado por el usuario en la moneda
        cripto. Note que puede variar del monto original si se aplica una
        comisión por el pago.
      example: 157.783
    currency_crypto:
      type: string
      nullable: true
      description: Moneda cripto utilizada en el pago (por ejemplo, USDT).
      enum:
        - USDT
    inboundCrixto_rateCryptoFiat:
      type: number
      format: double
      description: >-
        Tasa Cripto/Fiat usada durante la conversión de cripto-fiat,
        especificada 4 decimales
      example: 157.7837
    inboundCrypto_paidAt:
      type: string
      nullable: true
      format: date-time
      description: Fecha y hora en que se confirmó el pago cripto, en formato ISO 8601.
    inboundCrypto_details:
      type: object
      nullable: true
      description: Detalles de pago con criptomonedas (null si no aplica).
      properties:
        provider_name:
          type: string
          nullable: true
          description: >-
            Nombre de la entidad o plataforma financiera que custodia los
            activos del usuario. Representa el ecosistema o 'banco digital'
            donde reside el saldo original (ej. Binance, Crixto).
          examples:
            - Binance
            - Crixto
        crypto_order_id:
          type: string
          nullable: true
          description: Identificador de la orden cripto generada por el proveedor.
        payment_method_name:
          type: string
          description: Nombre del método de pago (ej. Binance Pay, Crixto Pay).
          examples:
            - Binance Pay
            - Crixto Pay
        amount_transaction_ves:
          type: number
          format: double
          nullable: true
          description: >-
            Monto con 3 decimales de la transacción en la moneda VES. Note que
            es el monto original sin incluir la comisión por el pago.
          example: 157.783
        amount_pay_by_user_crypto:
          type: number
          format: double
          nullable: true
          description: >-
            Monto con 3 decimales del pago realizado por el usuario en la moneda
            cripto. Note que puede variar del monto original si se aplica una
            comisión por el pago.
          example: 157.783
        currency_crypto:
          type: string
          nullable: true
          description: Moneda cripto utilizada en el pago (por ejemplo, USDT).
          enum:
            - USDT
        exchange_rate:
          type: number
          format: double
          description: >-
            Tasa Cripto/Fiat usada durante la conversión de cripto-fiat,
            especificada 4 decimales
          example: 157.7837
        paid_at:
          type: string
          nullable: true
          format: date-time
          description: Fecha y hora en que se confirmó el pago cripto, en formato ISO 8601.
    action_date:
      type: string
      format: date-time
      nullable: true
      description: >-
        Fecha y hora de la acción del pagador, en formato ISO 8601 con sufijo Z
        (UTC).
    bank_name:
      type: string
      nullable: true
      description: 'Nombre comercial del banco. Eco del request: no.'
    bank_reference_id:
      type: string
      nullable: true
      description: 'Referencia bancaria del pago. Eco del request: no.'
    amountVes:
      type: number
      description: Monto en bolívares con 2 decimales.
      format: double
    bcv_rate_usd_ves:
      type: number
      nullable: true
      format: decimal(10,4)
      description: >-
        Tasa oficial BCV de USD a VES usada en el cálculo del monto en
        bolívares. Eco del request: no.
    bcv_rate_eur_ves:
      type: number
      nullable: true
      format: decimal(10,4)
      description: >-
        Tasa oficial BCV de EUR a VES usada en el cálculo del monto en
        bolívares. Eco del request: no.
    rate_usdt_ves:
      type: number
      format: decimal(10,4)
      nullable: true
      description: Tasa de cambio USDT a VES.
    rate_col_ves:
      type: number
      format: decimal(10,4)
      nullable: true
      description: Tasa de cambio COP a VES.
    payment_details:
      type: object
      nullable: true
      description: >-
        Detalles del pago bancario. Es 'null' si no aplica. (Nota: Revisar si es
        objeto vacío o null). Eco del request: no.
      properties:
        action_date:
          type: string
          format: date-time
          nullable: true
          description: >-
            Fecha y hora de la acción del pagador, en formato ISO 8601 con
            sufijo Z (UTC).
        bank_name:
          type: string
          nullable: true
          description: 'Nombre comercial del banco. Eco del request: no.'
        bank_reference_id:
          type: string
          nullable: true
          description: 'Referencia bancaria del pago. Eco del request: no.'
        amount_ves:
          type: number
          description: Monto en bolívares con 2 decimales.
          format: double
        bcv_rate_usd_ves:
          type: number
          nullable: true
          format: decimal(10,4)
          description: >-
            Tasa oficial BCV de USD a VES usada en el cálculo del monto en
            bolívares. Eco del request: no.
        bcv_rate_eur_ves:
          type: number
          nullable: true
          format: decimal(10,4)
          description: >-
            Tasa oficial BCV de EUR a VES usada en el cálculo del monto en
            bolívares. Eco del request: no.
        rate_usdt_ves:
          type: number
          format: decimal(10,4)
          nullable: true
          description: Tasa de cambio USDT a VES.
        rate_col_ves:
          type: number
          format: decimal(10,4)
          nullable: true
          description: Tasa de cambio COP a VES.
    recipientId:
      type: string
      nullable: true
      description: Identificador del receptor del crédito.
    memo:
      type: string
      nullable: true
      description: Nota o referencia interna para el crédito.
    creditSpidi_id:
      type: string
      nullable: true
      description: ID de la liquidación al receptor del pago.
    amountVesCredited:
      type: number
      nullable: true
      description: >-
        Monto neto acreditado al receptor en bolívares, luego de aplicar las
        comisiones correspondientes. Siempre tiene 2 decimales.
      format: double
      example: '100.01'
    bank_commissions_ves:
      type: number
      nullable: true
      format: decimal(12,2)
      description: >-
        Comisión bancaria total cobrada en bolívares para la liquidación. Eco
        del request: no.
    receive_date:
      type: string
      format: date-time
      nullable: true
      description: Fecha y hora en que se acreditó el pago (ISO 8601).
    receiverCredits:
      type: object
      nullable: true
      description: Detalles de la liquidación de créditos (Owner y Partners).
      properties:
        owner:
          type: object
          description: Crédito asignado al dueño de la cuenta principal.
          properties:
            receiver_id:
              type: string
              nullable: true
              description: Identificador del receptor del crédito.
            memo:
              type: string
              nullable: true
              description: Nota o referencia interna para el crédito.
            spidi_credit_id:
              type: string
              nullable: true
              description: ID de la liquidación al receptor del pago.
            amount_ves_credited:
              type: number
              nullable: true
              description: >-
                Monto neto acreditado al receptor en bolívares, luego de aplicar
                las comisiones correspondientes. Siempre tiene 2 decimales.
              format: double
              example: '100.01'
            bank_commissions_ves:
              type: number
              nullable: true
              format: decimal(12,2)
              description: >-
                Comisión bancaria total cobrada en bolívares para la
                liquidación. Eco del request: no.
            receive_date:
              type: string
              format: date-time
              nullable: true
              description: Fecha y hora en que se acreditó el pago (ISO 8601).
            bank_name:
              type: string
              nullable: true
              description: 'Nombre comercial del banco. Eco del request: no.'
            bank_reference_id:
              type: string
              nullable: true
              description: 'Referencia bancaria del pago. Eco del request: no.'
        partners:
          type: array
          nullable: true
          description: Lista de créditos asignados a partners (split).
          items:
            type: object
            properties:
              receiver_id:
                type: string
                nullable: true
                description: Identificador del receptor del crédito.
              memo:
                type: string
                nullable: true
                description: Nota o referencia interna para el crédito.
              partner_rif_name:
                type: string
                nullable: true
                description: Nombre o razón social del partner
              partner_rif_number:
                type: string
                nullable: true
                description: RIF del partner
              split_recipient_agreement_id:
                type: string
                nullable: false
                format: uuid
                description: >-
                  UUID global SPIDI del agreement de recepción. Este ID se usará
                  en acuerdos de distribución para identificar al receptor del
                  split. (Requerido en distribution)
              spidi_credit_id:
                type: string
                nullable: true
                description: ID de la liquidación al receptor del pago.
              amount_ves_credited:
                type: number
                nullable: true
                description: >-
                  Monto neto acreditado al receptor en bolívares, luego de
                  aplicar las comisiones correspondientes. Siempre tiene 2
                  decimales.
                format: double
                example: '100.01'
              bank_commissions_ves:
                type: number
                nullable: true
                format: decimal(12,2)
                description: >-
                  Comisión bancaria total cobrada en bolívares para la
                  liquidación. Eco del request: no.
              receive_date:
                type: string
                format: date-time
                nullable: true
                description: Fecha y hora en que se acreditó el pago (ISO 8601).
              bank_name:
                type: string
                nullable: true
                description: 'Nombre comercial del banco. Eco del request: no.'
              bank_reference_id:
                type: string
                nullable: true
                description: 'Referencia bancaria del pago. Eco del request: no.'
              observations:
                type: string
                nullable: false
                maxLength: 500
                description: >-
                  Mensaje libre para el partner (máx. 500 caracteres).
                  (Requerido en distribution, Eco del request: sí)
    total_credits:
      type: integer
      nullable: false
      description: Número total de créditos/liquidaciones realizados.
    total_amount_ves_credited:
      type: number
      nullable: true
      format: double
      description: Monto total acreditado en VES.
    total_bank_commissions_ves:
      type: number
      nullable: true
      format: double
      description: Total de comisiones bancarias en VES.
    receiverCreditsSummary:
      type: object
      nullable: true
      description: Resumen agregado de liquidaciones al o los receptores.
      properties:
        total_credits:
          type: integer
          nullable: false
          description: Número total de créditos/liquidaciones realizados.
        total_amount_ves_credited:
          type: number
          nullable: true
          format: double
          description: Monto total acreditado en VES.
        total_bank_commissions_ves:
          type: number
          nullable: true
          format: double
          description: Total de comisiones bancarias en VES.
    sessionPayment:
      type: object
      nullable: true
      description: Detalles del pago y estado de la sesión.
      properties:
        payment_method:
          type: string
          description: 'Método de pago: "crypto", "immediate_debit" o "mobile_payment".'
        spidi_transaction_id:
          type: integer
          nullable: true
          description: ID de la transacción en Spidi (null si no se ha completado).
        spidi_transaction_url:
          type: string
          nullable: true
          description: URL del comprobante de pago (null si no se ha completado).
        due_date_session:
          type: string
          description: Fecha límite para completar el pago (ISO 8601).
        due_date_reached_behavior:
          type: string
          description: 'Comportamiento al expirar: "keep_active" o "expire".'
        late_notice_message:
          type: string
          description: Mensaje para mostrar cuando el pago está atrasado.
        expired_at:
          type: string
          description: Fecha hora ISO 8601 de la expiración más reciente.
        last_expired_by:
          type: string
          nullable: true
          enum:
            - api
            - system
          description: 'Origen de la expiración: api o system.'
        reason:
          type: string
          nullable: true
          enum:
            - api
            - system
          description: 'Origen de la expiración: api o system.'
        user_message:
          type: string
          description: Último Mensaje para el usuario.
        crypto_details:
          type: object
          nullable: true
          description: Detalles de pago con criptomonedas (null si no aplica).
          properties:
            provider_name:
              type: string
              nullable: true
              description: >-
                Nombre de la entidad o plataforma financiera que custodia los
                activos del usuario. Representa el ecosistema o 'banco digital'
                donde reside el saldo original (ej. Binance, Crixto).
              examples:
                - Binance
                - Crixto
            crypto_order_id:
              type: string
              nullable: true
              description: Identificador de la orden cripto generada por el proveedor.
            payment_method_name:
              type: string
              description: Nombre del método de pago (ej. Binance Pay, Crixto Pay).
              examples:
                - Binance Pay
                - Crixto Pay
            amount_transaction_ves:
              type: number
              format: double
              nullable: true
              description: >-
                Monto con 3 decimales de la transacción en la moneda VES. Note
                que es el monto original sin incluir la comisión por el pago.
              example: 157.783
            amount_pay_by_user_crypto:
              type: number
              format: double
              nullable: true
              description: >-
                Monto con 3 decimales del pago realizado por el usuario en la
                moneda cripto. Note que puede variar del monto original si se
                aplica una comisión por el pago.
              example: 157.783
            currency_crypto:
              type: string
              nullable: true
              description: Moneda cripto utilizada en el pago (por ejemplo, USDT).
              enum:
                - USDT
            exchange_rate:
              type: number
              format: double
              description: >-
                Tasa Cripto/Fiat usada durante la conversión de cripto-fiat,
                especificada 4 decimales
              example: 157.7837
            paid_at:
              type: string
              nullable: true
              format: date-time
              description: >-
                Fecha y hora en que se confirmó el pago cripto, en formato ISO
                8601.
        payment_details:
          type: object
          nullable: true
          description: Detalles del pago bancario (null si no aplica).
          properties:
            action_date:
              type: string
              format: date-time
              nullable: true
              description: >-
                Fecha y hora de la acción del pagador, en formato ISO 8601 con
                sufijo Z (UTC).
            bank_name:
              type: string
              nullable: true
              description: 'Nombre comercial del banco. Eco del request: no.'
            bank_reference_id:
              type: string
              nullable: true
              description: 'Referencia bancaria del pago. Eco del request: no.'
            amount_ves:
              type: number
              description: Monto en bolívares con 2 decimales.
              format: double
            bcv_rate_usd_ves:
              type: number
              nullable: true
              format: decimal(10,4)
              description: >-
                Tasa oficial BCV de USD a VES usada en el cálculo del monto en
                bolívares. Eco del request: no.
            bcv_rate_eur_ves:
              type: number
              nullable: true
              format: decimal(10,4)
              description: >-
                Tasa oficial BCV de EUR a VES usada en el cálculo del monto en
                bolívares. Eco del request: no.
            rate_usdt_ves:
              type: number
              format: decimal(10,4)
              nullable: true
              description: Tasa de cambio USDT a VES.
            rate_col_ves:
              type: number
              format: decimal(10,4)
              nullable: true
              description: Tasa de cambio COP a VES.
        receiver_credits:
          type: object
          nullable: true
          description: Detalles de la liquidación de créditos (Owner y Partners).
          properties:
            owner:
              type: object
              description: Crédito asignado al dueño de la cuenta principal.
              properties:
                receiver_id:
                  type: string
                  nullable: true
                  description: Identificador del receptor del crédito.
                memo:
                  type: string
                  nullable: true
                  description: Nota o referencia interna para el crédito.
                spidi_credit_id:
                  type: string
                  nullable: true
                  description: ID de la liquidación al receptor del pago.
                amount_ves_credited:
                  type: number
                  nullable: true
                  description: >-
                    Monto neto acreditado al receptor en bolívares, luego de
                    aplicar las comisiones correspondientes. Siempre tiene 2
                    decimales.
                  format: double
                  example: '100.01'
                bank_commissions_ves:
                  type: number
                  nullable: true
                  format: decimal(12,2)
                  description: >-
                    Comisión bancaria total cobrada en bolívares para la
                    liquidación. Eco del request: no.
                receive_date:
                  type: string
                  format: date-time
                  nullable: true
                  description: Fecha y hora en que se acreditó el pago (ISO 8601).
                bank_name:
                  type: string
                  nullable: true
                  description: 'Nombre comercial del banco. Eco del request: no.'
                bank_reference_id:
                  type: string
                  nullable: true
                  description: 'Referencia bancaria del pago. Eco del request: no.'
            partners:
              type: array
              nullable: true
              description: Lista de créditos asignados a partners (split).
              items:
                type: object
                properties:
                  receiver_id:
                    type: string
                    nullable: true
                    description: Identificador del receptor del crédito.
                  memo:
                    type: string
                    nullable: true
                    description: Nota o referencia interna para el crédito.
                  partner_rif_name:
                    type: string
                    nullable: true
                    description: Nombre o razón social del partner
                  partner_rif_number:
                    type: string
                    nullable: true
                    description: RIF del partner
                  split_recipient_agreement_id:
                    type: string
                    nullable: false
                    format: uuid
                    description: >-
                      UUID global SPIDI del agreement de recepción. Este ID se
                      usará en acuerdos de distribución para identificar al
                      receptor del split. (Requerido en distribution)
                  spidi_credit_id:
                    type: string
                    nullable: true
                    description: ID de la liquidación al receptor del pago.
                  amount_ves_credited:
                    type: number
                    nullable: true
                    description: >-
                      Monto neto acreditado al receptor en bolívares, luego de
                      aplicar las comisiones correspondientes. Siempre tiene 2
                      decimales.
                    format: double
                    example: '100.01'
                  bank_commissions_ves:
                    type: number
                    nullable: true
                    format: decimal(12,2)
                    description: >-
                      Comisión bancaria total cobrada en bolívares para la
                      liquidación. Eco del request: no.
                  receive_date:
                    type: string
                    format: date-time
                    nullable: true
                    description: Fecha y hora en que se acreditó el pago (ISO 8601).
                  bank_name:
                    type: string
                    nullable: true
                    description: 'Nombre comercial del banco. Eco del request: no.'
                  bank_reference_id:
                    type: string
                    nullable: true
                    description: 'Referencia bancaria del pago. Eco del request: no.'
                  observations:
                    type: string
                    nullable: false
                    maxLength: 500
                    description: >-
                      Mensaje libre para el partner (máx. 500 caracteres).
                      (Requerido en distribution, Eco del request: sí)
        receiver_credits_summary:
          type: object
          nullable: true
          description: Resumen agregado de liquidaciones al o los receptores.
          properties:
            total_credits:
              type: integer
              nullable: false
              description: Número total de créditos/liquidaciones realizados.
            total_amount_ves_credited:
              type: number
              nullable: true
              format: double
              description: Monto total acreditado en VES.
            total_bank_commissions_ves:
              type: number
              nullable: true
              format: double
              description: Total de comisiones bancarias en VES.
    PaymentSessionStatusResponse:
      type: object
      required:
        - success
        - message
        - data
      properties:
        success:
          type: boolean
          nullable: false
          description: >-
            Indica si la operación fue exitosa. True si el endpoint se procesó
            de forma exitosa. False de lo contrario
          example: true
        message:
          type: string
          example: Successful query.
          description: Mensaje de confirmación de la consulta.
        data:
          type: object
          required:
            - session_id
            - session_origin
            - agreement_id
            - status
            - currency_reference
            - amount_reference
            - identifier_label
            - identifier
            - description
            - created_at
            - session_payment
          properties:
            session_id:
              type: string
              nullable: false
              description: >-
                Identificador único de la sesión de pago, accedible a través del
                payment_url.
            session_origin:
              type: string
              nullable: false
              enum:
                - button
                - request
              description: >-
                Origen de la sesión: 'button' (Botón de pago) o 'request'
                (Solicitud SPIDI).
            agreement_id:
              type: string
              format: uuid
              nullable: true
              description: >-
                Identificador único del acuerdo de liquidación. Debe ser UUID
                v4. 
            status:
              type: string
              nullable: false
              enum:
                - pending
                - paid
                - failed
                - expired
              description: >-
                Estado actual de la sesión. El valor failed solo se aplica para
                sesiones creadas con botón de pago.
            currency_reference:
              type: string
              nullable: false
              enum:
                - USD
                - EUR
                - COP
                - USDT
                - VES
              description: >-
                Moneda de referencia que se fija para el pago. Usada para
                calcular el monto en bolívares con la tasa vigente.
            amount_reference:
              description: >-
                Monto de referencia en la moneda especificada en
                currencyReference con 2 decimales.
              type: number
              nullable: false
              format: double
              example: '100.001'
            identifier_label:
              type: string
              nullable: true
              description: >-
                Etiqueta que indica cómo debe interpretarse el valor enviado en
                identifier (ej. 'Nro de orden').
            identifier:
              type: string
              nullable: false
              description: >-
                Identificador del pagador, interpretado según el valor de
                identifier_label. Ejemplo: Nro de orden, Nombre, etc.
            description:
              type: string
              nullable: true
              description: >-
                Descripción del acuerdo o del concepto de pago asociado a una
                sesión.
              maxLength: 500
            created_at:
              type: string
              nullable: true
              format: date-time
              description: Fecha y hora de creación del recurso en formato ISO 8601.
            session_payment:
              type: object
              nullable: true
              description: Detalles del pago y estado de la sesión.
              properties:
                payment_method:
                  type: string
                  description: >-
                    Método de pago: "crypto", "immediate_debit" o
                    "mobile_payment".
                spidi_transaction_id:
                  type: integer
                  nullable: true
                  description: ID de la transacción en Spidi (null si no se ha completado).
                spidi_transaction_url:
                  type: string
                  nullable: true
                  description: URL del comprobante de pago (null si no se ha completado).
                due_date_session:
                  type: string
                  description: Fecha límite para completar el pago (ISO 8601).
                due_date_reached_behavior:
                  type: string
                  description: 'Comportamiento al expirar: "keep_active" o "expire".'
                late_notice_message:
                  type: string
                  description: Mensaje para mostrar cuando el pago está atrasado.
                expired_at:
                  type: string
                  description: Fecha hora ISO 8601 de la expiración más reciente.
                last_expired_by:
                  type: string
                  nullable: true
                  enum:
                    - api
                    - system
                  description: 'Origen de la expiración: api o system.'
                reason:
                  type: string
                  nullable: true
                  enum:
                    - api
                    - system
                  description: 'Origen de la expiración: api o system.'
                user_message:
                  type: string
                  description: Último Mensaje para el usuario.
                crypto_details:
                  type: object
                  nullable: true
                  description: Detalles de pago con criptomonedas (null si no aplica).
                  properties:
                    provider_name:
                      type: string
                      nullable: true
                      description: >-
                        Nombre de la entidad o plataforma financiera que
                        custodia los activos del usuario. Representa el
                        ecosistema o 'banco digital' donde reside el saldo
                        original (ej. Binance, Crixto).
                      examples:
                        - Binance
                        - Crixto
                    crypto_order_id:
                      type: string
                      nullable: true
                      description: >-
                        Identificador de la orden cripto generada por el
                        proveedor.
                    payment_method_name:
                      type: string
                      description: Nombre del método de pago (ej. Binance Pay, Crixto Pay).
                      examples:
                        - Binance Pay
                        - Crixto Pay
                    amount_transaction_ves:
                      type: number
                      format: double
                      nullable: true
                      description: >-
                        Monto con 3 decimales de la transacción en la moneda
                        VES. Note que es el monto original sin incluir la
                        comisión por el pago.
                      example: 157.783
                    amount_pay_by_user_crypto:
                      type: number
                      format: double
                      nullable: true
                      description: >-
                        Monto con 3 decimales del pago realizado por el usuario
                        en la moneda cripto. Note que puede variar del monto
                        original si se aplica una comisión por el pago.
                      example: 157.783
                    currency_crypto:
                      type: string
                      nullable: true
                      description: Moneda cripto utilizada en el pago (por ejemplo, USDT).
                      enum:
                        - USDT
                    exchange_rate:
                      type: number
                      format: double
                      description: >-
                        Tasa Cripto/Fiat usada durante la conversión de
                        cripto-fiat, especificada 4 decimales
                      example: 157.7837
                    paid_at:
                      type: string
                      nullable: true
                      format: date-time
                      description: >-
                        Fecha y hora en que se confirmó el pago cripto, en
                        formato ISO 8601.
                payment_details:
                  type: object
                  nullable: true
                  description: Detalles del pago bancario (null si no aplica).
                  properties:
                    action_date:
                      type: string
                      format: date-time
                      nullable: true
                      description: >-
                        Fecha y hora de la acción del pagador, en formato ISO
                        8601 con sufijo Z (UTC).
                    bank_name:
                      type: string
                      nullable: true
                      description: 'Nombre comercial del banco. Eco del request: no.'
                    bank_reference_id:
                      type: string
                      nullable: true
                      description: 'Referencia bancaria del pago. Eco del request: no.'
                    amount_ves:
                      type: number
                      description: Monto en bolívares con 2 decimales.
                      format: double
                    bcv_rate_usd_ves:
                      type: number
                      nullable: true
                      format: decimal(10,4)
                      description: >-
                        Tasa oficial BCV de USD a VES usada en el cálculo del
                        monto en bolívares. Eco del request: no.
                    bcv_rate_eur_ves:
                      type: number
                      nullable: true
                      format: decimal(10,4)
                      description: >-
                        Tasa oficial BCV de EUR a VES usada en el cálculo del
                        monto en bolívares. Eco del request: no.
                    rate_usdt_ves:
                      type: number
                      format: decimal(10,4)
                      nullable: true
                      description: Tasa de cambio USDT a VES.
                    rate_col_ves:
                      type: number
                      format: decimal(10,4)
                      nullable: true
                      description: Tasa de cambio COP a VES.
                receiver_credits:
                  type: object
                  nullable: true
                  description: Detalles de la liquidación de créditos (Owner y Partners).
                  properties:
                    owner:
                      type: object
                      description: Crédito asignado al dueño de la cuenta principal.
                      properties:
                        receiver_id:
                          type: string
                          nullable: true
                          description: Identificador del receptor del crédito.
                        memo:
                          type: string
                          nullable: true
                          description: Nota o referencia interna para el crédito.
                        spidi_credit_id:
                          type: string
                          nullable: true
                          description: ID de la liquidación al receptor del pago.
                        amount_ves_credited:
                          type: number
                          nullable: true
                          description: >-
                            Monto neto acreditado al receptor en bolívares,
                            luego de aplicar las comisiones correspondientes.
                            Siempre tiene 2 decimales.
                          format: double
                          example: '100.01'
                        bank_commissions_ves:
                          type: number
                          nullable: true
                          format: decimal(12,2)
                          description: >-
                            Comisión bancaria total cobrada en bolívares para la
                            liquidación. Eco del request: no.
                        receive_date:
                          type: string
                          format: date-time
                          nullable: true
                          description: Fecha y hora en que se acreditó el pago (ISO 8601).
                        bank_name:
                          type: string
                          nullable: true
                          description: 'Nombre comercial del banco. Eco del request: no.'
                        bank_reference_id:
                          type: string
                          nullable: true
                          description: 'Referencia bancaria del pago. Eco del request: no.'
                    partners:
                      type: array
                      nullable: true
                      description: Lista de créditos asignados a partners (split).
                      items:
                        type: object
                        properties:
                          receiver_id:
                            type: string
                            nullable: true
                            description: Identificador del receptor del crédito.
                          memo:
                            type: string
                            nullable: true
                            description: Nota o referencia interna para el crédito.
                          partner_rif_name:
                            type: string
                            nullable: true
                            description: Nombre o razón social del partner
                          partner_rif_number:
                            type: string
                            nullable: true
                            description: RIF del partner
                          split_recipient_agreement_id:
                            type: string
                            nullable: false
                            format: uuid
                            description: >-
                              UUID global SPIDI del agreement de recepción. Este
                              ID se usará en acuerdos de distribución para
                              identificar al receptor del split. (Requerido en
                              distribution)
                          spidi_credit_id:
                            type: string
                            nullable: true
                            description: ID de la liquidación al receptor del pago.
                          amount_ves_credited:
                            type: number
                            nullable: true
                            description: >-
                              Monto neto acreditado al receptor en bolívares,
                              luego de aplicar las comisiones correspondientes.
                              Siempre tiene 2 decimales.
                            format: double
                            example: '100.01'
                          bank_commissions_ves:
                            type: number
                            nullable: true
                            format: decimal(12,2)
                            description: >-
                              Comisión bancaria total cobrada en bolívares para
                              la liquidación. Eco del request: no.
                          receive_date:
                            type: string
                            format: date-time
                            nullable: true
                            description: >-
                              Fecha y hora en que se acreditó el pago (ISO
                              8601).
                          bank_name:
                            type: string
                            nullable: true
                            description: 'Nombre comercial del banco. Eco del request: no.'
                          bank_reference_id:
                            type: string
                            nullable: true
                            description: 'Referencia bancaria del pago. Eco del request: no.'
                          observations:
                            type: string
                            nullable: false
                            maxLength: 500
                            description: >-
                              Mensaje libre para el partner (máx. 500
                              caracteres). (Requerido en distribution, Eco del
                              request: sí)
                receiver_credits_summary:
                  type: object
                  nullable: true
                  description: Resumen agregado de liquidaciones al o los receptores.
                  properties:
                    total_credits:
                      type: integer
                      nullable: false
                      description: Número total de créditos/liquidaciones realizados.
                    total_amount_ves_credited:
                      type: number
                      nullable: true
                      format: double
                      description: Monto total acreditado en VES.
                    total_bank_commissions_ves:
                      type: number
                      nullable: true
                      format: double
                      description: Total de comisiones bancarias en VES.
    PaymentSessionStatusErrorResponse:
      type: object
      required:
        - success
        - message
      properties:
        success:
          type: boolean
          example: false
          description: Indica si la operación fue exitosa.
        message:
          type: string
          example: Session not found.
          description: Mensaje descriptivo del error.
        errors:
          type: object
          nullable: true
          description: Detalles específicos de los errores.
          properties:
            session_id:
              type: string
              example: This field is required.
              description: Error relacionado con el campo session_id.
            spidi_id:
              type: string
              example: The credentials are incorrect
              description: Error de autenticación.
            message:
              type: string
              example: No tienes permisos para esta operación
              description: Mensaje de error genérico.
    continueOnerror:
      type: boolean
      nullable: true
      default: false
      description: >-
        Indica si el procesamiento debe continuar con el resto de los ítems
        aunque alguno falle en operaciones de batch.

        - Si es `false`, se detiene en el primer error y las operaciones ya
        exitosas permanecen válidas. 

        - Si es `true`, continúa procesando hasta el final y luego reporta las
        fallas acumuladas.
      example: true
    landing_title:
      type: string
      nullable: false
      description: Título de la landing page creada por SPIDI.
      example: Pago de Servicios
    due_date_session:
      type: string
      nullable: true
      format: date-time
      description: 'Fecha y hora límite de vencimiento de la Solicitud SPIDI (sesión). '
    due_date_reached_behavior:
      type: string
      nullable: true
      enum:
        - keep_active
        - expire
      description: >-
        Comportamiento configurado para cuando la sesión alcance su fecha de
        vencimiento.
    late_notice_message:
      type: string
      nullable: true
      description: >-
        Mensaje que verá el pagador cuando la sesión haya vencido pero continúe
        activa (keep_active). 
    internal_reference:
      type: string
      nullable: false
      description: >-
        Referencia interna única utilizada por el sistema o el comercio para
        identificar la solicitud de pago o parada (propósito estrictamente
        técnico,no visible al usuario final).


        **Importancia para Paradas SPIDI:**

        - Permite conciliar y auditar operaciones entre tu sistema y SPIDI

        - Sirve para asociar solicitudes de pago con su Parada correspondiente

        - Puede vincularse a clientes, contratos o facturas en tu plataforma


        Se recomienda mantener este campo de forma consistente para facilitar la
        trazabilidad.
      example: '8233232'
    PaymentSessionRequestBatchRequest:
      type: object
      required:
        - continue_on_error
        - items
      properties:
        continue_on_error:
          type: boolean
          nullable: true
          default: false
          description: >-
            Indica si el procesamiento debe continuar con el resto de los ítems
            aunque alguno falle en operaciones de batch.

            - Si es `false`, se detiene en el primer error y las operaciones ya
            exitosas permanecen válidas. 

            - Si es `true`, continúa procesando hasta el final y luego reporta
            las fallas acumuladas.
          example: true
        items:
          type: array
          description: Array de objetos con los datos de cada sesión de pago a crear.
          minItems: 1
          items:
            type: object
            required:
              - title
              - agreement_id
              - currency_reference
              - amount_reference
              - identifier
              - due_date_session
              - due_date_reached_behavior
              - late_notice_message
              - internal_reference
            properties:
              title:
                type: string
                nullable: false
                description: Título de la landing page creada por SPIDI.
                example: Pago de Servicios
              agreement_id:
                type: string
                format: uuid
                nullable: true
                description: >-
                  Identificador único del acuerdo de liquidación. Debe ser UUID
                  v4. 
              currency_reference:
                type: string
                nullable: false
                enum:
                  - USD
                  - EUR
                  - COP
                  - USDT
                  - VES
                description: >-
                  Moneda de referencia que se fija para el pago. Usada para
                  calcular el monto en bolívares con la tasa vigente.
              amount_reference:
                description: >-
                  Monto de referencia en la moneda especificada en
                  currencyReference con 2 decimales.
                type: number
                nullable: false
                format: double
                example: '100.001'
              identifier_label:
                type: string
                nullable: true
                description: >-
                  Etiqueta que indica cómo debe interpretarse el valor enviado
                  en identifier (ej. 'Nro de orden').
              identifier:
                type: string
                nullable: false
                description: >-
                  Identificador del pagador, interpretado según el valor de
                  identifier_label. Ejemplo: Nro de orden, Nombre, etc.
              description:
                type: string
                nullable: true
                description: >-
                  Descripción del acuerdo o del concepto de pago asociado a una
                  sesión.
                maxLength: 500
              success_url:
                type: string
                nullable: true
                format: uri
                description: >-
                  URL de redirección que se utiliza cuando un intento de pago es
                  exitoso.
                pattern: ^[a-z1-9]+://[^\s]*$
              failure_url:
                type: string
                nullable: true
                format: uri
                description: >-
                  URL de redirección que se utiliza cuando un intento de pago
                  falle. 
                pattern: ^[a-z1-9]+://[^\s]*$
              webhook_url:
                type: string
                nullable: true
                format: uri
                description: 'URL para recibir notificaciones de webhook. '
              due_date_session:
                type: string
                nullable: true
                format: date-time
                description: >-
                  Fecha y hora límite de vencimiento de la Solicitud SPIDI
                  (sesión). 
              due_date_reached_behavior:
                type: string
                nullable: true
                enum:
                  - keep_active
                  - expire
                description: >-
                  Comportamiento configurado para cuando la sesión alcance su
                  fecha de vencimiento.
              late_notice_message:
                type: string
                nullable: true
                description: >-
                  Mensaje que verá el pagador cuando la sesión haya vencido pero
                  continúe activa (keep_active). 
              internal_reference:
                type: string
                nullable: false
                description: >-
                  Referencia interna única utilizada por el sistema o el
                  comercio para identificar la solicitud de pago o parada
                  (propósito estrictamente técnico,no visible al usuario final).


                  **Importancia para Paradas SPIDI:**

                  - Permite conciliar y auditar operaciones entre tu sistema y
                  SPIDI

                  - Sirve para asociar solicitudes de pago con su Parada
                  correspondiente

                  - Puede vincularse a clientes, contratos o facturas en tu
                  plataforma


                  Se recomienda mantener este campo de forma consistente para
                  facilitar la trazabilidad.
                example: '8233232'
              split:
                type: object
                nullable: true
                description: >-
                  Configuración de división de pagos (Request) / Eco del request
                  del split (Response).
                properties:
                  document:
                    type: object
                    nullable: true
                    description: >-
                      Información del documento proporcionado por el owner a los
                      partners para dejar evidencia del split.


                      **Notas importantes:**

                      - Esta información **no implica cálculo fiscal** por parte
                      de SPIDI; es solo comunicación entre owner y partners.

                      - `splitDocument_url` puede ser público con hash o una URL
                      autenticada.

                      - SPIDI **no interpreta ni calcula IVA** a partir de esta
                      información; solo lo transporta.
                    properties:
                      name:
                        type: string
                        nullable: true
                        description: >-
                          Nombre del documento asociado a la transacción split
                          (por ejemplo: factura/recibo/contrato D001-00045678).
                      type:
                        type: string
                        nullable: true
                        description: >-
                          Formato libre del owner donde especifica el tipo de
                          documento.
                        examples:
                          - Factura
                          - Contrato
                          - Recibo
                      date:
                        type: string
                        nullable: true
                        format: date
                        description: >-
                          Fecha de emisión del documento en formato ISO 8601
                          (YYYY-MM-DD).
                      url:
                        type: string
                        nullable: true
                        format: uri
                        description: >-
                          Enlace para visualizar/descargar el documento del
                          split. Puede ser público con hash o una URL
                          autenticada.
                      observations:
                        type: string
                        nullable: true
                        maxLength: 500
                        description: Observaciones libres del owner (máx. 500 caracteres).
                  distribution:
                    type: array
                    nullable: false
                    description: >-
                      Lista de reglas/destinatarios del split. Debe tener ≥ 1
                      ítem. La suma de amount_reference debe ser menor al amount
                      total de la sesión, porque la diferencia restante se
                      asigna automáticamente al owner, quien siempre debe
                      recibir una parte del pago. (Requerido cuando split=true)
                    items:
                      type: object
                      required:
                        - split_recipient_agreement_id
                        - amount_reference
                        - observations
                      properties:
                        split_recipient_agreement_id:
                          type: string
                          nullable: false
                          format: uuid
                          description: >-
                            UUID global SPIDI del agreement de recepción. Este
                            ID se usará en acuerdos de distribución para
                            identificar al receptor del split. (Requerido en
                            distribution)
                        label:
                          type: string
                          nullable: true
                          description: >-
                            Etiqueta descriptiva del receptor en un split.
                            (Opcional en distribution, Eco del request: sí)
                        amount_reference:
                          description: >-
                            Monto de referencia en la moneda especificada en
                            currencyReference con 2 decimales.
                          type: number
                          nullable: false
                          format: double
                          example: '100.001'
                        observations:
                          type: string
                          nullable: false
                          maxLength: 500
                          description: >-
                            Mensaje libre para el partner (máx. 500 caracteres).
                            (Requerido en distribution, Eco del request: sí)
    processed_count:
      type: integer
      nullable: false
      description: 'Conteo de ítems procesados. Eco del request: no.'
    successful_count:
      type: integer
      nullable: false
      description: Número de sesiones creadas exitosamente.
    failed_count:
      type: integer
      nullable: false
      description: Número de sesiones que fallaron al crear en el batch.
    qr_payment_url:
      type: string
      nullable: true
      description: >-
        Cadena en base64 que representa la imagen de un QR que apunta al
        payment_url.
    item_index:
      type: integer
      nullable: true
      description: Índice del ítem que falló en un batch.
    PaymentSessionRequestBatchResponse:
      type: object
      required:
        - success
        - message
        - data
      properties:
        success:
          type: boolean
          nullable: false
          description: >-
            Indica si la operación fue exitosa. True si el endpoint se procesó
            de forma exitosa. False de lo contrario
          example: true
        message:
          type: string
          example: Payment sessions created successfully.
          description: Mensaje de confirmación de la creación.
        data:
          type: object
          required:
            - processed_count
            - successful_count
            - failed_count
            - items
          properties:
            processed_count:
              type: integer
              nullable: false
              description: 'Conteo de ítems procesados. Eco del request: no.'
            successful_count:
              type: integer
              nullable: false
              description: Número de sesiones creadas exitosamente.
            failed_count:
              type: integer
              nullable: false
              description: Número de sesiones que fallaron al crear en el batch.
            items:
              type: array
              items:
                type: object
                properties:
                  session_origin:
                    type: string
                    nullable: false
                    enum:
                      - button
                      - request
                    description: >-
                      Origen de la sesión: 'button' (Botón de pago) o 'request'
                      (Solicitud SPIDI).
                  session_id:
                    type: string
                    nullable: false
                    description: >-
                      Identificador único de la sesión de pago, accedible a
                      través del payment_url.
                  payment_url:
                    type: string
                    nullable: true
                    description: >-
                      URL de la página segura SPIDI donde quien paga realiza el
                      pago.
                    example: '{{base_url}}/?id=3ddc4cfb-c09a-43de-92c1-e4a069732e90'
                  qr_payment_url:
                    type: string
                    nullable: true
                    description: >-
                      Cadena en base64 que representa la imagen de un QR que
                      apunta al payment_url.
                  currency_reference:
                    type: string
                    nullable: false
                    enum:
                      - USD
                      - EUR
                      - COP
                      - USDT
                      - VES
                    description: >-
                      Moneda de referencia que se fija para el pago. Usada para
                      calcular el monto en bolívares con la tasa vigente.
                  amount_reference:
                    description: >-
                      Monto de referencia en la moneda especificada en
                      currencyReference con 2 decimales.
                    type: number
                    nullable: false
                    format: double
                    example: '100.001'
                  identifier_label:
                    type: string
                    nullable: true
                    description: >-
                      Etiqueta que indica cómo debe interpretarse el valor
                      enviado en identifier (ej. 'Nro de orden').
                  identifier:
                    type: string
                    nullable: false
                    description: >-
                      Identificador del pagador, interpretado según el valor de
                      identifier_label. Ejemplo: Nro de orden, Nombre, etc.
                  description:
                    type: string
                    nullable: true
                    description: >-
                      Descripción del acuerdo o del concepto de pago asociado a
                      una sesión.
                    maxLength: 500
                  success_url:
                    type: string
                    nullable: true
                    format: uri
                    description: >-
                      URL de redirección que se utiliza cuando un intento de
                      pago es exitoso.
                    pattern: ^[a-z1-9]+://[^\s]*$
                  failure_url:
                    type: string
                    nullable: true
                    format: uri
                    description: >-
                      URL de redirección que se utiliza cuando un intento de
                      pago falle. 
                    pattern: ^[a-z1-9]+://[^\s]*$
                  webhook_url:
                    type: string
                    nullable: true
                    format: uri
                    description: 'URL para recibir notificaciones de webhook. '
                  due_date_session:
                    type: string
                    nullable: true
                    format: date-time
                    description: >-
                      Fecha y hora límite de vencimiento de la Solicitud SPIDI
                      (sesión). 
                  due_date_reached_behavior:
                    type: string
                    nullable: true
                    enum:
                      - keep_active
                      - expire
                    description: >-
                      Comportamiento configurado para cuando la sesión alcance
                      su fecha de vencimiento.
                  late_notice_message:
                    type: string
                    nullable: true
                    description: >-
                      Mensaje que verá el pagador cuando la sesión haya vencido
                      pero continúe activa (keep_active). 
                  internal_reference:
                    type: string
                    nullable: false
                    description: >-
                      Referencia interna única utilizada por el sistema o el
                      comercio para identificar la solicitud de pago o parada
                      (propósito estrictamente técnico,no visible al usuario
                      final).


                      **Importancia para Paradas SPIDI:**

                      - Permite conciliar y auditar operaciones entre tu sistema
                      y SPIDI

                      - Sirve para asociar solicitudes de pago con su Parada
                      correspondiente

                      - Puede vincularse a clientes, contratos o facturas en tu
                      plataforma


                      Se recomienda mantener este campo de forma consistente
                      para facilitar la trazabilidad.
                    example: '8233232'
                  created_at:
                    type: string
                    nullable: true
                    format: date-time
                    description: Fecha y hora de creación del recurso en formato ISO 8601.
                  split:
                    type: object
                    nullable: true
                    description: >-
                      Configuración de división de pagos (Request) / Eco del
                      request del split (Response).
                    properties:
                      document:
                        type: object
                        nullable: true
                        description: >-
                          Información del documento proporcionado por el owner a
                          los partners para dejar evidencia del split.


                          **Notas importantes:**

                          - Esta información **no implica cálculo fiscal** por
                          parte de SPIDI; es solo comunicación entre owner y
                          partners.

                          - `splitDocument_url` puede ser público con hash o una
                          URL autenticada.

                          - SPIDI **no interpreta ni calcula IVA** a partir de
                          esta información; solo lo transporta.
                        properties:
                          name:
                            type: string
                            nullable: true
                            description: >-
                              Nombre del documento asociado a la transacción
                              split (por ejemplo: factura/recibo/contrato
                              D001-00045678).
                          type:
                            type: string
                            nullable: true
                            description: >-
                              Formato libre del owner donde especifica el tipo
                              de documento.
                            examples:
                              - Factura
                              - Contrato
                              - Recibo
                          date:
                            type: string
                            nullable: true
                            format: date
                            description: >-
                              Fecha de emisión del documento en formato ISO 8601
                              (YYYY-MM-DD).
                          url:
                            type: string
                            nullable: true
                            format: uri
                            description: >-
                              Enlace para visualizar/descargar el documento del
                              split. Puede ser público con hash o una URL
                              autenticada.
                          observations:
                            type: string
                            nullable: true
                            maxLength: 500
                            description: >-
                              Observaciones libres del owner (máx. 500
                              caracteres).
                      distribution:
                        type: array
                        nullable: false
                        description: >-
                          Lista de reglas/destinatarios del split. Debe tener ≥
                          1 ítem. La suma de amount_reference debe ser menor al
                          amount total de la sesión, porque la diferencia
                          restante se asigna automáticamente al owner, quien
                          siempre debe recibir una parte del pago. (Requerido
                          cuando split=true)
                        items:
                          type: object
                          required:
                            - split_recipient_agreement_id
                            - amount_reference
                            - observations
                          properties:
                            split_recipient_agreement_id:
                              type: string
                              nullable: false
                              format: uuid
                              description: >-
                                UUID global SPIDI del agreement de recepción.
                                Este ID se usará en acuerdos de distribución
                                para identificar al receptor del split.
                                (Requerido en distribution)
                            label:
                              type: string
                              nullable: true
                              description: >-
                                Etiqueta descriptiva del receptor en un split.
                                (Opcional en distribution, Eco del request: sí)
                            amount_reference:
                              description: >-
                                Monto de referencia en la moneda especificada en
                                currencyReference con 2 decimales.
                              type: number
                              nullable: false
                              format: double
                              example: '100.001'
                            observations:
                              type: string
                              nullable: false
                              maxLength: 500
                              description: >-
                                Mensaje libre para el partner (máx. 500
                                caracteres). (Requerido en distribution, Eco del
                                request: sí)
            errors:
              type: array
              nullable: true
              items:
                type: object
                properties:
                  item_index:
                    type: integer
                    nullable: true
                    description: Índice del ítem que falló en un batch.
                  errors:
                    type: object
    PaymentSessionRequestBatchErrorResponse:
      type: object
      required:
        - success
        - message
      properties:
        success:
          type: boolean
          example: false
          description: Indica si la operación fue exitosa.
        message:
          type: string
          example: 'Missing required field: items'
          description: Mensaje descriptivo del error.
        errors:
          type: object
          nullable: true
          description: Detalles específicos de los errores.
          properties:
            items:
              type: string
              example: This field is required.
              description: Error relacionado con el campo items.
            continue_on_error:
              type: string
              example: Must be a boolean value.
              description: Error relacionado con el campo continue_on_error.
            spidi_id:
              type: string
              example: The credentials are incorrect
              description: Error de autenticación.
            Idempotency-Key:
              type: string
              example: A session already exists for this key.
              description: Error de idempotencia.
        data:
          type: object
          nullable: true
          description: Datos parciales en caso de errores de batch.
          properties:
            processed_count:
              type: integer
            successful_count:
              type: integer
            failed_count:
              type: integer
            items:
              type: array
            errors:
              type: array
              items:
                type: object
                properties:
                  item_index:
                    type: integer
                  errors:
                    type: object
    cancellation_category:
      type: string
      enum:
        - INCORRECT_DATA
        - ALTERNATIVE_PAYMENT_RECEIVED
        - OTHER
      description: >-
        **Clasificación técnica obligatoria.** Permite segmentar el motivo de
        cancelación para análisis de conversión y auditoría. 


        **Definiciones:**

        * `INCORRECT_DATA`: Datos de pago o cliente inválidos (ej. CI/RIF
        erróneo).

        * `ALTERNATIVE_PAYMENT_RECEIVED`: El cliente pagó por otra vía (ej.
        efectivo o transferencia directa).

        * `OTHER`: Motivos no clasificados previamente (requiere nota
        adicional).
      example: INCORRECT_DATA
    cancellation_messageAudit:
      type: string
      nullable: true
      description: >-
        Nota de auditoría interna. Espacio para justificaciones técnicas o
        administrativas. Este contenido no es visible para el cliente final y se
        utiliza exclusivamente para trazabilidad recomienda usarlo con esta
        estructura: (quién, cuándo, por qué).
      example: >-
        La orden se habia generado de forma automatizada pero el usuario liquido
        la la sesión en nuestra sucursal por medio de pagos en efectivo.
    cancellation_messageUser:
      type: string
      nullable: true
      description: >-
        Mensaje para el usuario final cuado por ejemplo el administrador
        necesita dar una instrucción específica.
      example: Sesión cancelada por pago en efectivo
    processedAt:
      type: string
      format: date-time
      description: Fecha y hora de procesamiento en formato ISO 8601.
      example: '2026-05-06T17:15:00-04:00'
    SplitReceivingAgreementRequest:
      type: object
      required:
        - title
        - default_bank_account_id
      properties:
        title:
          type: string
          nullable: false
          description: 'Título visible. '
        description:
          type: string
          nullable: true
          description: >-
            Descripción del acuerdo o del concepto de pago asociado a una
            sesión.
          maxLength: 500
        split_recipient_agreement_id:
          type: string
          nullable: false
          format: uuid
          description: >-
            UUID global SPIDI del agreement de recepción. Este ID se usará en
            acuerdos de distribución para identificar al receptor del split.
            (Requerido en distribution)
        default_bank_account_id:
          type: string
          format: uuid
          nullable: false
          description: >-
            UUID de la cuenta bancaria por defecto que se utilizará para la
            liquidación. 
        rules:
          type: array
          nullable: true
          description: |-
            (**En Desarrollo**) Reglas de acuerdo. 
             En caso de usar origin_bank_code y destination_bank_account_id, se aplicará una regla de ruteo por banco de origen. Cada regla define a qué cuenta bancaria se debe enviar el dinero según el banco del pagador.
          items:
            type: object
            properties:
              origin_bank_code:
                type: string
                nullable: false
                description: 'Código oficial del banco de origen. '
              destination_bank_account_id:
                type: string
                nullable: true
                description: >-
                  UUID de la cuenta bancaria de destino para un banco de origen
                  específico. 
    SplitReceivingAgreementResponse:
      type: object
      required:
        - success
        - data
      properties:
        success:
          type: boolean
          nullable: false
          description: >-
            Indica si la operación fue exitosa. True si el endpoint se procesó
            de forma exitosa. False de lo contrario
          example: true
        data:
          type: object
          required:
            - split_recipient_agreement_id
            - title
            - default_bank_account_id
            - created_at
            - created_by
          properties:
            split_recipient_agreement_id:
              type: string
              nullable: false
              format: uuid
              description: >-
                UUID global SPIDI del agreement de recepción. Este ID se usará
                en acuerdos de distribución para identificar al receptor del
                split. (Requerido en distribution)
            title:
              type: string
              nullable: false
              description: 'Título visible. '
            description:
              type: string
              nullable: true
              description: >-
                Descripción del acuerdo o del concepto de pago asociado a una
                sesión.
              maxLength: 500
            default_bank_account_id:
              type: string
              format: uuid
              nullable: false
              description: >-
                UUID de la cuenta bancaria por defecto que se utilizará para la
                liquidación. 
            rules:
              type: array
              nullable: true
              description: |-
                (**En Desarrollo**) Reglas de acuerdo. 
                 En caso de usar origin_bank_code y destination_bank_account_id, se aplicará una regla de ruteo por banco de origen. Cada regla define a qué cuenta bancaria se debe enviar el dinero según el banco del pagador.
              items:
                type: object
                properties:
                  origin_bank_code:
                    type: string
                    nullable: false
                    description: 'Código oficial del banco de origen. '
                  destination_bank_account_id:
                    type: string
                    nullable: true
                    description: >-
                      UUID de la cuenta bancaria de destino para un banco de
                      origen específico. 
            created_at:
              type: string
              nullable: true
              format: date-time
              description: Fecha y hora de creación del recurso en formato ISO 8601.
            created_by:
              type: string
              nullable: true
              description: Identificador del usuario que creó el recurso administrable.
    SplitReceivingAgreementErrorResponse:
      type: object
      required:
        - success
        - message
      properties:
        success:
          type: boolean
          example: false
          description: Indica que la operación falló.
        message:
          type: string
          example: Invalid request parameters
          description: Mensaje de error general.
        errors:
          type: object
          nullable: true
          description: Detalles específicos de los errores de validación.
          properties:
            title:
              type: string
              example: Title is required.
              description: Error relacionado con el campo title.
            default_bank_account_id:
              type: string
              example: Default bank account ID is required.
              description: Error relacionado con el campo default_bank_account_id.
            rules:
              type: string
              example: Duplicate origin_bank_code '0105' in rules.
              description: Error relacionado con las reglas de ruteo.
            origin_bank_code:
              type: string
              example: INVALID_BANK_CODE
              description: Código de banco inválido.
            destination_bank_account_id:
              type: string
              example: BANK_ACCOUNT_NOT_FOUND
              description: Cuenta bancaria de destino no encontrada.
            authorization:
              type: string
              example: Invalid or missing Bearer token
              description: Error de autorización.
    stop_id:
      type: string
      nullable: false
      format: uuid
      description: >-
        Identificador único de la Parada SPIDI en formato UUID. Este ID
        identifica de forma permanente el espacio donde el cliente puede
        consultar y gestionar todas sus solicitudes de pago.
      example: stp_f9317c1b-8a4f-4d7e-9f25-3a2b8b9a4f12
    stop_url:
      type: string
      nullable: true
      format: uri
      description: >-
        URL permanente y única de la Parada SPIDI. El cliente puede visitar esta
        URL en cualquier momento para consultar y pagar todas sus solicitudes de
        pago activas o históricas, sin necesidad de recibir nuevos enlaces cada
        vez.
      example: https://mispidi.com/s/stp_f9317c1b-8a4f-4d7e-9f25-3a2b8b9a4f12
    stop_title:
      type: string
      nullable: false
      description: >-
        Título visible de la Parada SPIDI mostrado al cliente. Generalmente se
        usa el nombre del cliente, contrato o servicio asociado.
      example: Federico Díaz
    stop_emptyStateMessage:
      type: string
      nullable: true
      description: >-
        Mensaje personalizado mostrado al cliente cuando la Parada no tiene
        solicitudes de pago activas (estado Empty). Ejemplo: 'No tienes pagos
        pendientes' o 'Actualmente no hay deudas asociadas'.
      example: No tienes pagos pendientes
    stop_status:
      type: string
      enum:
        - active
        - disabled
        - empty
        - deleted
      description: >-
        Estado de la Parada SPIDI.


        **Estados disponibles:**


        - **active**: La parada está activa. Si tiene al menos un enlace de pago
        activo, se muestran los pagos disponibles en una lista con su
        identificador, monto y estado. Si no tiene solicitudes de pago activas
        (estado Empty), muestra el mensaje configurado en `empty_state_message`.


        - **disabled**: La parada está deshabilitada temporalmente. Los clientes
        no pueden acceder a ella, pero puede reactivarse cambiando el estado a
        `active`.


        **Nota:** Aunque no aparece en el enum, existe un estado **deleted** que
        indica que la parada fue eliminada definitivamente y no puede
        recuperarse.
      example: active
    createdAt:
      type: string
      format: date-time
      description: Fecha y hora de creación en formato ISO 8601.
    StopListResponse:
      type: object
      required:
        - success
        - message
        - data
      properties:
        success:
          type: boolean
          description: True si el endpoint se procesó de forma exitosa
          example: true
        message:
          type: string
          description: Mensaje de confirmación legible para humanos
          example: Payment stops retrieved successfully.
        data:
          type: object
          required:
            - total
            - limit
            - offset
            - items
          properties:
            total:
              type: integer
              description: Total de paradas que cumplen con los filtros aplicados
              example: 2
            limit:
              type: integer
              description: Límite aplicado en esta página
              example: 20
            offset:
              type: integer
              description: Offset aplicado en esta página
              example: 0
            items:
              type: array
              description: Lista de paradas devueltas en esta página
              items:
                type: object
                required:
                  - stop_id
                  - stop_url
                  - internal_reference
                  - stop_title
                  - status
                  - created_at
                  - updated_at
                  - links_active_count
                properties:
                  stop_id:
                    type: string
                    nullable: false
                    format: uuid
                    description: >-
                      Identificador único de la Parada SPIDI en formato UUID.
                      Este ID identifica de forma permanente el espacio donde el
                      cliente puede consultar y gestionar todas sus solicitudes
                      de pago.
                    example: stp_f9317c1b-8a4f-4d7e-9f25-3a2b8b9a4f12
                  stop_url:
                    type: string
                    nullable: true
                    format: uri
                    description: >-
                      URL permanente y única de la Parada SPIDI. El cliente
                      puede visitar esta URL en cualquier momento para consultar
                      y pagar todas sus solicitudes de pago activas o
                      históricas, sin necesidad de recibir nuevos enlaces cada
                      vez.
                    example: >-
                      https://mispidi.com/s/stp_f9317c1b-8a4f-4d7e-9f25-3a2b8b9a4f12
                  stop_title:
                    type: string
                    nullable: false
                    description: >-
                      Título visible de la Parada SPIDI mostrado al cliente.
                      Generalmente se usa el nombre del cliente, contrato o
                      servicio asociado.
                    example: Federico Díaz
                  internal_reference:
                    type: string
                    nullable: false
                    description: >-
                      Referencia interna única utilizada por el sistema o el
                      comercio para identificar la solicitud de pago o parada
                      (propósito estrictamente técnico,no visible al usuario
                      final).


                      **Importancia para Paradas SPIDI:**

                      - Permite conciliar y auditar operaciones entre tu sistema
                      y SPIDI

                      - Sirve para asociar solicitudes de pago con su Parada
                      correspondiente

                      - Puede vincularse a clientes, contratos o facturas en tu
                      plataforma


                      Se recomienda mantener este campo de forma consistente
                      para facilitar la trazabilidad.
                    example: '8233232'
                  empty_state_message:
                    type: string
                    nullable: true
                    description: >-
                      Mensaje personalizado mostrado al cliente cuando la Parada
                      no tiene solicitudes de pago activas (estado Empty).
                      Ejemplo: 'No tienes pagos pendientes' o 'Actualmente no
                      hay deudas asociadas'.
                    example: No tienes pagos pendientes
                  status:
                    type: string
                    enum:
                      - active
                      - disabled
                      - empty
                      - deleted
                    description: >-
                      Estado de la Parada SPIDI.


                      **Estados disponibles:**


                      - **active**: La parada está activa. Si tiene al menos un
                      enlace de pago activo, se muestran los pagos disponibles
                      en una lista con su identificador, monto y estado. Si no
                      tiene solicitudes de pago activas (estado Empty), muestra
                      el mensaje configurado en `empty_state_message`.


                      - **disabled**: La parada está deshabilitada
                      temporalmente. Los clientes no pueden acceder a ella, pero
                      puede reactivarse cambiando el estado a `active`.


                      **Nota:** Aunque no aparece en el enum, existe un estado
                      **deleted** que indica que la parada fue eliminada
                      definitivamente y no puede recuperarse.
                    example: active
                  created_at:
                    type: string
                    format: date-time
                    description: Fecha y hora de creación en formato ISO 8601.
                  updated_at:
                    type: string
                    format: date-time
                    description: Fecha y hora de última actualización (ISO 8601)
                    example: '2025-09-30T10:12:34Z'
                  links_active_count:
                    type: integer
                    description: Número de solicitudes de pago activas en la parada
                    example: 1
    CreateStopErrorResponse:
      type: object
      required:
        - success
        - message
      properties:
        success:
          type: boolean
          description: Siempre false en caso de error
          example: false
        message:
          type: string
          description: Resumen legible del error principal
          example: 'Missing required field: stop_title'
        errors:
          type: object
          description: Detalle por campo (opcional)
          additionalProperties:
            type: string
          example:
            stop_title: This field is required.
    userSpidi_id:
      type: string
      nullable: false
      description: Identificador único de tipo UUID para el usuario SPIDI
      example: a966ce0d-3af3-415d-ba86-1db5a1c21cf0
    stop_statusInitial:
      type: string
      enum:
        - active
        - disabled
      description: Estado inicial de la parada
      default: active
      example: active
    batch_id:
      type: string
      nullable: false
      description: Identificador único de un lote (batch) procesado.
      example: batch_54fa7a9e-31f1-41f0-a6b9-2cd05662c721
    stop:
      type: object
      properties:
        stop_id:
          type: string
          nullable: false
          format: uuid
          description: >-
            Identificador único de la Parada SPIDI en formato UUID. Este ID
            identifica de forma permanente el espacio donde el cliente puede
            consultar y gestionar todas sus solicitudes de pago.
          example: stp_f9317c1b-8a4f-4d7e-9f25-3a2b8b9a4f12
        stop_url:
          type: string
          nullable: true
          format: uri
          description: >-
            URL permanente y única de la Parada SPIDI. El cliente puede visitar
            esta URL en cualquier momento para consultar y pagar todas sus
            solicitudes de pago activas o históricas, sin necesidad de recibir
            nuevos enlaces cada vez.
          example: https://mispidi.com/s/stp_f9317c1b-8a4f-4d7e-9f25-3a2b8b9a4f12
        stop_title:
          type: string
          nullable: false
          description: >-
            Título visible de la Parada SPIDI mostrado al cliente. Generalmente
            se usa el nombre del cliente, contrato o servicio asociado.
          example: Federico Díaz
        internal_reference:
          type: string
          nullable: false
          description: >-
            Referencia interna única utilizada por el sistema o el comercio para
            identificar la solicitud de pago o parada (propósito estrictamente
            técnico,no visible al usuario final).


            **Importancia para Paradas SPIDI:**

            - Permite conciliar y auditar operaciones entre tu sistema y SPIDI

            - Sirve para asociar solicitudes de pago con su Parada
            correspondiente

            - Puede vincularse a clientes, contratos o facturas en tu plataforma


            Se recomienda mantener este campo de forma consistente para
            facilitar la trazabilidad.
          example: '8233232'
        empty_state_message:
          type: string
          nullable: true
          description: >-
            Mensaje personalizado mostrado al cliente cuando la Parada no tiene
            solicitudes de pago activas (estado Empty). Ejemplo: 'No tienes
            pagos pendientes' o 'Actualmente no hay deudas asociadas'.
          example: No tienes pagos pendientes
        status:
          type: string
          enum:
            - active
            - disabled
            - empty
            - deleted
          description: >-
            Estado de la Parada SPIDI.


            **Estados disponibles:**


            - **active**: La parada está activa. Si tiene al menos un enlace de
            pago activo, se muestran los pagos disponibles en una lista con su
            identificador, monto y estado. Si no tiene solicitudes de pago
            activas (estado Empty), muestra el mensaje configurado en
            `empty_state_message`.


            - **disabled**: La parada está deshabilitada temporalmente. Los
            clientes no pueden acceder a ella, pero puede reactivarse cambiando
            el estado a `active`.


            **Nota:** Aunque no aparece en el enum, existe un estado **deleted**
            que indica que la parada fue eliminada definitivamente y no puede
            recuperarse.
          example: active
        created_at:
          type: string
          format: date-time
          description: Fecha y hora de creación en formato ISO 8601.
    link_status:
      type: string
      enum:
        - pending
        - paid
        - expired
      description: Estado del solicitud de pago.
      example: pending
    link_amount:
      type: number
      format: double
      description: Monto en la moneda de referencia para una solicitud de pago.
      example: 15.5
    amountVesCalculate:
      type: number
      description: >-
        Monto en bolívares. Si el currency_reference es diferente a VES, este
        monto se calculó con base a la tasa. Posee 2 decimales
      format: double
    due_date_link:
      type: string
      nullable: true
      format: date-time
      description: 'Fecha y hora límite de vencimiento de la Solicitud SPIDI (link). '
    expire_behavior_link:
      type: string
      nullable: true
      enum:
        - expire
        - keep_active
      description: >-
        Comportamiento configurado para la Solicitud SPIDI cuando alcanza su
        fecha de vencimiento. 
    StopDetailsResponse:
      type: object
      required:
        - success
        - message
        - data
      properties:
        success:
          type: boolean
          nullable: false
          description: >-
            Indica si la operación fue exitosa. True si el endpoint se procesó
            de forma exitosa. False de lo contrario
          example: true
        message:
          type: string
          nullable: true
          description: Mensaje de confirmación o error legible.
        data:
          type: object
          required:
            - stop_id
            - stop_url
            - internal_reference
            - stop_title
            - status
            - created_at
          properties:
            stop_id:
              type: string
              nullable: false
              format: uuid
              description: >-
                Identificador único de la Parada SPIDI en formato UUID. Este ID
                identifica de forma permanente el espacio donde el cliente puede
                consultar y gestionar todas sus solicitudes de pago.
              example: stp_f9317c1b-8a4f-4d7e-9f25-3a2b8b9a4f12
            stop_url:
              type: string
              nullable: true
              format: uri
              description: >-
                URL permanente y única de la Parada SPIDI. El cliente puede
                visitar esta URL en cualquier momento para consultar y pagar
                todas sus solicitudes de pago activas o históricas, sin
                necesidad de recibir nuevos enlaces cada vez.
              example: https://mispidi.com/s/stp_f9317c1b-8a4f-4d7e-9f25-3a2b8b9a4f12
            stop_title:
              type: string
              nullable: false
              description: >-
                Título visible de la Parada SPIDI mostrado al cliente.
                Generalmente se usa el nombre del cliente, contrato o servicio
                asociado.
              example: Federico Díaz
            internal_reference:
              type: string
              nullable: false
              description: >-
                Referencia interna única utilizada por el sistema o el comercio
                para identificar la solicitud de pago o parada (propósito
                estrictamente técnico,no visible al usuario final).


                **Importancia para Paradas SPIDI:**

                - Permite conciliar y auditar operaciones entre tu sistema y
                SPIDI

                - Sirve para asociar solicitudes de pago con su Parada
                correspondiente

                - Puede vincularse a clientes, contratos o facturas en tu
                plataforma


                Se recomienda mantener este campo de forma consistente para
                facilitar la trazabilidad.
              example: '8233232'
            empty_state_message:
              type: string
              nullable: true
              description: >-
                Mensaje personalizado mostrado al cliente cuando la Parada no
                tiene solicitudes de pago activas (estado Empty). Ejemplo: 'No
                tienes pagos pendientes' o 'Actualmente no hay deudas
                asociadas'.
              example: No tienes pagos pendientes
            status:
              type: string
              enum:
                - active
                - disabled
                - empty
                - deleted
              description: >-
                Estado de la Parada SPIDI.


                **Estados disponibles:**


                - **active**: La parada está activa. Si tiene al menos un enlace
                de pago activo, se muestran los pagos disponibles en una lista
                con su identificador, monto y estado. Si no tiene solicitudes de
                pago activas (estado Empty), muestra el mensaje configurado en
                `empty_state_message`.


                - **disabled**: La parada está deshabilitada temporalmente. Los
                clientes no pueden acceder a ella, pero puede reactivarse
                cambiando el estado a `active`.


                **Nota:** Aunque no aparece en el enum, existe un estado
                **deleted** que indica que la parada fue eliminada
                definitivamente y no puede recuperarse.
              example: active
            created_at:
              type: string
              format: date-time
              description: Fecha y hora de creación en formato ISO 8601.
            updated_at:
              type: string
              format: date-time
              description: Fecha y hora de última actualización (ISO 8601)
              example: '2025-09-30T10:12:34Z'
            links_active:
              type: array
              description: Lista de solicitudes de pago activas en la parada
              items:
                type: object
                required:
                  - session_id
                  - payment_url
                  - status
                  - amount
                  - currency_reference
                  - amount_ves
                properties:
                  session_id:
                    type: string
                    nullable: false
                    description: >-
                      Identificador único de la sesión de pago, accedible a
                      través del payment_url.
                  payment_url:
                    type: string
                    nullable: true
                    description: >-
                      URL de la página segura SPIDI donde quien paga realiza el
                      pago.
                    example: '{{base_url}}/?id=3ddc4cfb-c09a-43de-92c1-e4a069732e90'
                  status:
                    type: string
                    enum:
                      - pending
                      - paid
                      - expired
                    description: Estado del solicitud de pago.
                    example: pending
                  amount:
                    type: number
                    format: double
                    description: >-
                      Monto en la moneda de referencia para una solicitud de
                      pago.
                    example: 15.5
                  currency_reference:
                    type: string
                    nullable: false
                    enum:
                      - USD
                      - EUR
                      - COP
                      - USDT
                      - VES
                    description: >-
                      Moneda de referencia que se fija para el pago. Usada para
                      calcular el monto en bolívares con la tasa vigente.
                  amount_ves:
                    type: number
                    description: >-
                      Monto en bolívares. Si el currency_reference es diferente
                      a VES, este monto se calculó con base a la tasa. Posee 2
                      decimales
                    format: double
                  due_date_link:
                    type: string
                    nullable: true
                    format: date-time
                    description: >-
                      Fecha y hora límite de vencimiento de la Solicitud SPIDI
                      (link). 
                  expire_behavior_link:
                    type: string
                    nullable: true
                    enum:
                      - expire
                      - keep_active
                    description: >-
                      Comportamiento configurado para la Solicitud SPIDI cuando
                      alcanza su fecha de vencimiento. 
                  late_notice_message:
                    type: string
                    nullable: true
                    description: >-
                      Mensaje que verá el pagador cuando la sesión haya vencido
                      pero continúe activa (keep_active). 
    DeleteStopResponse:
      type: object
      required:
        - success
        - message
        - data
      properties:
        success:
          type: boolean
          description: True si el endpoint se procesó de forma exitosa
          example: true
        message:
          type: string
          description: Mensaje de confirmación legible para humanos
          example: Payment stop deleted successfully.
        data:
          type: object
          required:
            - stop_id
            - deleted_at
          properties:
            stop_id:
              type: string
              description: Identificador de la Parada SPIDI eliminada
              example: stp_9f82b1d3-6e9a-4b0a-9bcd-4fd3f2e5c8a7
            deleted_at:
              type: string
              format: date-time
              description: Fecha y hora de eliminación (ISO 8601)
              example: '2025-09-30T16:12:04Z'
    UpdateStopRequest:
      type: object
      required:
        - stop_title
        - status
        - empty_state_message
      properties:
        stop_title:
          type: string
          description: Nuevo título visible de la parada
          example: Caja Principal
        status:
          type: string
          enum:
            - active
            - disabled
          description: Estado de la parada
          example: disabled
        empty_state_message:
          type: string
          description: >-
            Texto mostrado al pagador cuando no existan solicitudes de pago
            activas en la parada
          example: Actualmente no hay deudas asociadas a esta parada.
    UpdateStopResponse:
      type: object
      required:
        - success
        - message
        - data
      properties:
        success:
          type: boolean
          description: True si el endpoint se procesó de forma exitosa
          example: true
        message:
          type: string
          description: Mensaje de confirmación legible para humanos
          example: Payment stop updated successfully.
        data:
          type: object
          required:
            - stop_id
            - stop_url
            - stop_title
            - status
            - empty_state_message
            - updated_at
          properties:
            stop_id:
              type: string
              description: Identificador de la Parada SPIDI actualizada
              example: stp_9f82b1d3-6e9a-4b0a-9bcd-4fd3f2e5c8a7
            stop_url:
              type: string
              format: uri
              description: URL permanente de la parada
              example: >-
                https://pay.spidi.com/stop/stp_9f82b1d3-6e9a-4b0a-9bcd-4fd3f2e5c8a7
            stop_title:
              type: string
              description: Título de la parada actualizado
              example: Caja Principal
            status:
              type: string
              enum:
                - active
                - disabled
              description: Estado de la parada
              example: disabled
            empty_state_message:
              type: string
              description: Mensaje cuando no hay solicitudes de pago activas
              example: Actualmente no hay deudas asociadas a esta parada.
            updated_at:
              type: string
              format: date-time
              description: Fecha y hora de actualización (ISO 8601)
              example: '2025-09-29T14:45:12Z'
    bcv_exchange_rate:
      type: number
      format: double
      description: Tasa oficial usada para la conversión
      example: 122.58
    StopPaymentSessionsHistoryResponse:
      type: object
      required:
        - success
        - message
        - data
      properties:
        success:
          type: boolean
          description: True si el endpoint se procesó de forma exitosa
          example: true
        message:
          type: string
          description: Mensaje de confirmación legible para humanos
          example: PaymentSessions retrieved successfully.
        data:
          type: object
          required:
            - stop_id
            - total
            - limit
            - offset
            - items
          properties:
            stop_id:
              type: string
              description: Identificador de la Parada SPIDI
              example: 7f8b2c6a-4d19-45df-9a10-3e872aa812c1
            total:
              type: integer
              description: >-
                Total de solicitudes de pago que cumplen con los filtros
                aplicados
              example: 3
            limit:
              type: integer
              description: Límite aplicado en esta página
              example: 20
            offset:
              type: integer
              description: Offset aplicado en esta página
              example: 0
            items:
              type: array
              description: Lista de solicitudes de pago (activos e históricos)
              items:
                type: object
                required:
                  - session_id
                  - status
                  - payment_url
                  - created_at
                  - updated_at
                  - amount
                  - currency_reference
                  - amount_ves
                  - bcv_exchange_rate
                  - exchange_rate_from
                  - exchange_rate_to
                  - identifier_label
                  - identifier
                  - description
                properties:
                  session_id:
                    type: string
                    description: Identificador único de la sesión de pago
                    example: 21f43a2b-d9ff-42d2-87ce-559bdaf1f901
                  status:
                    type: string
                    enum:
                      - pending
                      - paid
                      - expired
                    description: Estado del enlace
                    example: pending
                  payment_url:
                    type: string
                    format: uri
                    description: URL donde el usuario puede realizar el pago
                    example: https://pay.spidi.com/21f43a2b-d9ff-42d2-87ce-559bdaf1f901
                  created_at:
                    type: string
                    format: date-time
                    description: Fecha/hora de creación (ISO 8601)
                    example: '2025-02-15T12:30:22Z'
                  updated_at:
                    type: string
                    format: date-time
                    description: Última actualización (ISO 8601)
                    example: '2025-02-15T12:31:10Z'
                  amount:
                    type: number
                    format: double
                    description: Monto en la moneda de referencia
                    example: 15.5
                  currency_reference:
                    type: string
                    enum:
                      - USD
                      - EUR
                      - COP
                      - VES
                    description: Moneda de referencia
                    example: USD
                  amount_ves:
                    type: number
                    format: double
                    description: Monto calculado en bolívares
                    example: 1900
                  bcv_exchange_rate:
                    type: number
                    format: double
                    description: Tasa oficial usada para la conversión
                    example: 122.58
                  exchange_rate_from:
                    type: string
                    description: Moneda base de la tasa
                    example: USD
                  exchange_rate_to:
                    type: string
                    description: Moneda destino de la tasa (siempre VES)
                    example: VES
                  identifier_label:
                    type: string
                    description: Etiqueta del identificador
                    example: Suscriptor
                  identifier:
                    type: string
                    description: Identificador del pagador
                    example: Juan Pérez
                  description:
                    type: string
                    description: Descripción del pago
                    example: Mensualidad febrero
                  due_date_link:
                    type: string
                    format: date-time
                    description: Fecha y hora límite de vencimiento
                    example: '2025-03-01T00:00:00Z'
                  expire_behavior_link:
                    type: string
                    enum:
                      - expire
                      - keep_active
                    description: Comportamiento al vencer
                    example: keep_active
                  late_notice_message:
                    type: string
                    description: Mensaje mostrado si el enlace está vencido pero activo
                    example: Tu servicio está inactivo. Paga para reactivar.
                  paid_at:
                    type: string
                    format: date-time
                    description: Fecha/hora de pago (solo si status = paid)
                    example: '2025-01-30T17:05:33Z'
                  expired_at:
                    type: string
                    format: date-time
                    description: Fecha/hora de expiración (solo si status = expired)
                    example: '2025-01-10T10:20:15Z'
    batch_operation_payment_stops_payment_sessions_item:
      type: object
      required:
        - stop_id
        - op
      properties:
        stop_id:
          type: string
          description: >-
            Identificador de la Parada sobre la que se ejecuta la operación.
            Debe pertenecer al comercio autenticado.
          example: stp_111
        op:
          type: string
          enum:
            - add
            - remove
            - replace
            - clear
          description: >-
            Operación a ejecutar: **add** (agregar sesiones), **remove**
            (desasociar sesiones), **replace** (reemplazar conjunto activo),
            **clear** (limpiar todos los activos)
          example: add
        session_ids:
          type: array
          items:
            type: string
          description: >-
            IDs de sesiones involucradas. Requerido para operaciones add, remove
            y replace. Solo sesiones en estado **pending** pueden activarse
            (add/replace).
          example:
            - sess_A
            - sess_B
    BatchOperationRequest:
      type: object
      required:
        - continue_on_error
        - items
      properties:
        continue_on_error:
          type: boolean
          nullable: true
          default: false
          description: >-
            Indica si el procesamiento debe continuar con el resto de los ítems
            aunque alguno falle en operaciones de batch.

            - Si es `false`, se detiene en el primer error y las operaciones ya
            exitosas permanecen válidas. 

            - Si es `true`, continúa procesando hasta el final y luego reporta
            las fallas acumuladas.
          example: true
        items:
          type: array
          minItems: 1
          items:
            type: object
            required:
              - stop_id
              - op
            properties:
              stop_id:
                type: string
                description: >-
                  Identificador de la Parada sobre la que se ejecuta la
                  operación. Debe pertenecer al comercio autenticado.
                example: stp_111
              op:
                type: string
                enum:
                  - add
                  - remove
                  - replace
                  - clear
                description: >-
                  Operación a ejecutar: **add** (agregar sesiones), **remove**
                  (desasociar sesiones), **replace** (reemplazar conjunto
                  activo), **clear** (limpiar todos los activos)
                example: add
              session_ids:
                type: array
                items:
                  type: string
                description: >-
                  IDs de sesiones involucradas. Requerido para operaciones add,
                  remove y replace. Solo sesiones en estado **pending** pueden
                  activarse (add/replace).
                example:
                  - sess_A
                  - sess_B
          description: Lista de operaciones por Parada. Debe contener al menos 1 ítem.
          example:
            - stop_id: stp_111
              op: add
              session_ids:
                - sess_A
                - sess_B
            - stop_id: stp_222
              op: remove
              session_ids:
                - sess_C
            - stop_id: stp_333
              op: replace
              session_ids:
                - sess_D
            - stop_id: stp_444
              op: clear
    op:
      type: string
      nullable: false
      enum:
        - add
        - remove
        - replace
        - clear
      description: 'Operación para batch: add | remove | replace | clear.'
    batch_errors:
      type: object
      description: Detalle de errores solo si success=false en operaciones batch
      additionalProperties:
        type: string
    batch_added:
      type: array
      items:
        type: string
      description: Sesiones agregadas como activas (operación add)
    batch_already_present:
      type: array
      items:
        type: string
      description: Sesiones ya activas, no-op (operación add)
    removed:
      type: array
      nullable: true
      description: Sesiones desasociadas de activos en Parada (op=remove).
      items:
        type: string
    not_active:
      type: array
      nullable: true
      description: Solicitudes SPIDI no activas en Parada.
      items:
        type: string
    not_found:
      type: array
      nullable: true
      description: Sesiones no encontradas en Parada.
      items:
        type: string
    batch_active_now:
      type: array
      items:
        type: string
      description: Conjunto final de activos tras la operación (operación replace)
    replaced_previous:
      type: array
      nullable: true
      description: Sesiones que dejaron de estar activas en Parada (op=replace).
      items:
        type: string
    cleared:
      type: boolean
      nullable: false
      description: >-
        Indica si se aplicó una operación de limpieza (`op=clear`) sobre las
        Solicitudes SPIDI activas en la parada.
    BatchOperationResult:
      type: object
      required:
        - stop_id
        - op
        - success
      properties:
        stop_id:
          type: string
          nullable: false
          format: uuid
          description: >-
            Identificador único de la Parada SPIDI en formato UUID. Este ID
            identifica de forma permanente el espacio donde el cliente puede
            consultar y gestionar todas sus solicitudes de pago.
          example: stp_f9317c1b-8a4f-4d7e-9f25-3a2b8b9a4f12
        op:
          type: string
          nullable: false
          enum:
            - add
            - remove
            - replace
            - clear
          description: 'Operación para batch: add | remove | replace | clear.'
        success:
          type: boolean
          nullable: false
          description: >-
            Indica si la operación fue exitosa. True si el endpoint se procesó
            de forma exitosa. False de lo contrario
          example: true
        errors:
          type: object
          description: Detalle de errores solo si success=false en operaciones batch
          additionalProperties:
            type: string
        added:
          type: array
          items:
            type: string
          description: Sesiones agregadas como activas (operación add)
        already_present:
          type: array
          items:
            type: string
          description: Sesiones ya activas, no-op (operación add)
        removed:
          type: array
          nullable: true
          description: Sesiones desasociadas de activos en Parada (op=remove).
          items:
            type: string
        not_active:
          type: array
          nullable: true
          description: Solicitudes SPIDI no activas en Parada.
          items:
            type: string
        not_found:
          type: array
          nullable: true
          description: Sesiones no encontradas en Parada.
          items:
            type: string
        active_now:
          type: array
          items:
            type: string
          description: Conjunto final de activos tras la operación (operación replace)
        replaced_previous:
          type: array
          nullable: true
          description: Sesiones que dejaron de estar activas en Parada (op=replace).
          items:
            type: string
        cleared:
          type: boolean
          nullable: false
          description: >-
            Indica si se aplicó una operación de limpieza (`op=clear`) sobre las
            Solicitudes SPIDI activas en la parada.
    BatchOperationResponse:
      type: object
      required:
        - success
        - message
        - batch_id
        - results
      properties:
        success:
          type: boolean
          nullable: false
          description: >-
            Indica si la operación fue exitosa. True si el endpoint se procesó
            de forma exitosa. False de lo contrario
          example: true
        message:
          type: string
          nullable: true
          description: Mensaje de confirmación o error legible.
        batch_id:
          type: string
          nullable: false
          description: Identificador único de un lote (batch) procesado.
          example: batch_54fa7a9e-31f1-41f0-a6b9-2cd05662c721
        results:
          type: array
          items:
            type: object
            required:
              - stop_id
              - op
              - success
            properties:
              stop_id:
                type: string
                nullable: false
                format: uuid
                description: >-
                  Identificador único de la Parada SPIDI en formato UUID. Este
                  ID identifica de forma permanente el espacio donde el cliente
                  puede consultar y gestionar todas sus solicitudes de pago.
                example: stp_f9317c1b-8a4f-4d7e-9f25-3a2b8b9a4f12
              op:
                type: string
                nullable: false
                enum:
                  - add
                  - remove
                  - replace
                  - clear
                description: 'Operación para batch: add | remove | replace | clear.'
              success:
                type: boolean
                nullable: false
                description: >-
                  Indica si la operación fue exitosa. True si el endpoint se
                  procesó de forma exitosa. False de lo contrario
                example: true
              errors:
                type: object
                description: Detalle de errores solo si success=false en operaciones batch
                additionalProperties:
                  type: string
              added:
                type: array
                items:
                  type: string
                description: Sesiones agregadas como activas (operación add)
              already_present:
                type: array
                items:
                  type: string
                description: Sesiones ya activas, no-op (operación add)
              removed:
                type: array
                nullable: true
                description: Sesiones desasociadas de activos en Parada (op=remove).
                items:
                  type: string
              not_active:
                type: array
                nullable: true
                description: Solicitudes SPIDI no activas en Parada.
                items:
                  type: string
              not_found:
                type: array
                nullable: true
                description: Sesiones no encontradas en Parada.
                items:
                  type: string
              active_now:
                type: array
                items:
                  type: string
                description: >-
                  Conjunto final de activos tras la operación (operación
                  replace)
              replaced_previous:
                type: array
                nullable: true
                description: Sesiones que dejaron de estar activas en Parada (op=replace).
                items:
                  type: string
              cleared:
                type: boolean
                nullable: false
                description: >-
                  Indica si se aplicó una operación de limpieza (`op=clear`)
                  sobre las Solicitudes SPIDI activas en la parada.
          description: Resultado por ítem (por stop_id/op)
          example:
            - stop_id: stp_111
              op: add
              success: true
              added:
                - sess_A
                - sess_B
              already_present: []
            - stop_id: stp_222
              op: remove
              success: true
              removed:
                - sess_C
              not_active: []
              not_found: []
            - stop_id: stp_333
              op: replace
              success: true
              active_now:
                - sess_D
              replaced_previous:
                - sess_X
            - stop_id: stp_444
              op: clear
              success: true
              cleared: true
    errors:
      type: object
      nullable: true
      description: Detalles específicos de los errores de validación.
    BatchOperationErrorResponse:
      type: object
      required:
        - success
        - message
      properties:
        success:
          type: boolean
          nullable: false
          description: >-
            Indica si la operación fue exitosa. True si el endpoint se procesó
            de forma exitosa. False de lo contrario
          example: true
        message:
          type: string
          nullable: true
          description: Mensaje de confirmación o error legible.
        errors:
          type: object
          nullable: true
          description: Detalles específicos de los errores de validación.
    reorder_session_ids:
      type: array
      minItems: 1
      items:
        type: string
      description: >-
        Nuevo orden deseado. Deben ser `session_id` **activos** en esa Parada
        (ver `mode`)
    mode:
      type: string
      nullable: true
      default: append
      enum:
        - append
        - strict
      description: >-
        Modo de reordenamiento: 'append' (por defecto) o 'strict' (reemplazar
        lista).
    ReorderItem:
      type: object
      required:
        - stop_id
        - session_ids
      properties:
        stop_id:
          type: string
          nullable: false
          format: uuid
          description: >-
            Identificador único de la Parada SPIDI en formato UUID. Este ID
            identifica de forma permanente el espacio donde el cliente puede
            consultar y gestionar todas sus solicitudes de pago.
          example: stp_f9317c1b-8a4f-4d7e-9f25-3a2b8b9a4f12
        session_ids:
          type: array
          minItems: 1
          items:
            type: string
          description: >-
            Nuevo orden deseado. Deben ser `session_id` **activos** en esa
            Parada (ver `mode`)
        mode:
          type: string
          nullable: true
          default: append
          enum:
            - append
            - strict
          description: >-
            Modo de reordenamiento: 'append' (por defecto) o 'strict'
            (reemplazar lista).
    ReorderRequest:
      type: object
      required:
        - continue_on_error
        - items
      properties:
        continue_on_error:
          type: boolean
          nullable: true
          default: false
          description: >-
            Indica si el procesamiento debe continuar con el resto de los ítems
            aunque alguno falle en operaciones de batch.

            - Si es `false`, se detiene en el primer error y las operaciones ya
            exitosas permanecen válidas. 

            - Si es `true`, continúa procesando hasta el final y luego reporta
            las fallas acumuladas.
          example: true
        items:
          type: array
          minItems: 1
          items:
            type: object
            required:
              - stop_id
              - session_ids
            properties:
              stop_id:
                type: string
                nullable: false
                format: uuid
                description: >-
                  Identificador único de la Parada SPIDI en formato UUID. Este
                  ID identifica de forma permanente el espacio donde el cliente
                  puede consultar y gestionar todas sus solicitudes de pago.
                example: stp_f9317c1b-8a4f-4d7e-9f25-3a2b8b9a4f12
              session_ids:
                type: array
                minItems: 1
                items:
                  type: string
                description: >-
                  Nuevo orden deseado. Deben ser `session_id` **activos** en esa
                  Parada (ver `mode`)
              mode:
                type: string
                nullable: true
                default: append
                enum:
                  - append
                  - strict
                description: >-
                  Modo de reordenamiento: 'append' (por defecto) o 'strict'
                  (reemplazar lista).
          description: Lista de instrucciones de reorden por Parada. Al menos 1 ítem
          example:
            - stop_id: stp_111
              session_ids:
                - sess_B
                - sess_A
                - sess_C
              mode: append
            - stop_id: stp_222
              session_ids:
                - sess_X
                - sess_Y
              mode: strict
    ReorderResult:
      type: object
      required:
        - stop_id
        - success
        - mode
      properties:
        stop_id:
          type: string
          description: Parada afectada
          example: stp_111
        success:
          type: boolean
          description: Resultado del ítem
          example: true
        mode:
          type: string
          enum:
            - append
            - strict
          description: Modo aplicado
          example: append
        applied_order:
          type: array
          items:
            type: string
          description: Orden final aplicado (solo si success=true)
          example:
            - sess_B
            - sess_A
            - sess_C
            - sess_D
        errors:
          type: object
          description: Detalle de validaciones cuando success=false
          properties:
            missing_actives:
              type: array
              items:
                type: string
              description: Sesiones activas no incluidas (en strict)
              example:
                - sess_Z
            not_active:
              type: array
              items:
                type: string
              description: IDs listados que no están activos
              example:
                - sess_Q
            not_found:
              type: array
              items:
                type: string
              description: IDs no asociados a la Parada
              example: []
            duplicates:
              type: array
              items:
                type: string
              description: IDs repetidos en la lista
              example:
                - sess_Y
    ReorderResponse:
      type: object
      required:
        - success
        - message
        - batch_id
        - results
      properties:
        success:
          type: boolean
          description: >-
            **true** si todos los ítems fueron exitosos; **false** si al menos
            uno falló
          example: true
        message:
          type: string
          description: Resumen legible del resultado
          example: 'Batch reorder processed: 2 items succeeded.'
        batch_id:
          type: string
          description: Identificador único del batch para auditoría/idempotencia
          example: batch_5e9a1b2c-3344-5566-7788-99aabbccdd00
        results:
          type: array
          items:
            type: object
            required:
              - stop_id
              - success
              - mode
            properties:
              stop_id:
                type: string
                description: Parada afectada
                example: stp_111
              success:
                type: boolean
                description: Resultado del ítem
                example: true
              mode:
                type: string
                enum:
                  - append
                  - strict
                description: Modo aplicado
                example: append
              applied_order:
                type: array
                items:
                  type: string
                description: Orden final aplicado (solo si success=true)
                example:
                  - sess_B
                  - sess_A
                  - sess_C
                  - sess_D
              errors:
                type: object
                description: Detalle de validaciones cuando success=false
                properties:
                  missing_actives:
                    type: array
                    items:
                      type: string
                    description: Sesiones activas no incluidas (en strict)
                    example:
                      - sess_Z
                  not_active:
                    type: array
                    items:
                      type: string
                    description: IDs listados que no están activos
                    example:
                      - sess_Q
                  not_found:
                    type: array
                    items:
                      type: string
                    description: IDs no asociados a la Parada
                    example: []
                  duplicates:
                    type: array
                    items:
                      type: string
                    description: IDs repetidos en la lista
                    example:
                      - sess_Y
          description: Resultados por ítem (stop_id)
          example:
            - stop_id: stp_111
              success: true
              applied_order:
                - sess_B
                - sess_A
                - sess_C
                - sess_D
              mode: append
            - stop_id: stp_222
              success: true
              applied_order:
                - sess_X
                - sess_Y
              mode: strict
    ReorderErrorResponse:
      type: object
      required:
        - success
        - message
      properties:
        success:
          type: boolean
          description: Siempre **false** en respuestas de error
          example: false
        message:
          type: string
          description: Resumen legible del error principal
          example: Invalid batch payload.
        errors:
          type: object
          description: Detalles específicos de los errores de validación
          additionalProperties:
            type: string
          example:
            items: Must be a non-empty array.
            items[0].mode: 'Allowed values are: append, strict.'
            items[1].session_ids: Must be a non-empty array of strings.
    PerStopConfig:
      type: object
      properties:
        page_size:
          type: integer
          minimum: 1
          maximum: 200
          default: 50
          description: Tamaño por Parada (1..200, default 50)
          example: 20
        sort:
          type: string
          enum:
            - created_at
            - updated_at
            - expires_at
            - amount
          default: created_at
          description: Campo de ordenación
          example: created_at
        order:
          type: string
          enum:
            - asc
            - desc
          default: desc
          description: Dirección de ordenación
          example: desc
        only_fields:
          type: array
          items:
            type: string
          description: >-
            Limitar campos para reducir payload (p. ej.,
            ["session_id","payment_url","expires_at"])
          example:
            - session_id
            - payment_url
            - expires_at
        cursor_by_stop:
          type: object
          additionalProperties:
            type: string
          description: >-
            Cursor por Parada para continuar desde una respuesta previa. Usa
            `next_cursor` por `stop_id` para cargas incrementales eficientes
          example:
            stp_111: cur_aaa
            stp_333: cur_ccc
    QueryStopsRequest:
      type: object
      required:
        - stop_ids
      properties:
        stop_ids:
          type: array
          minItems: 1
          maxItems: 200
          items:
            type: string
          description: 'Lista de Paradas a consultar (máx. recomendado: 200 por request)'
          example:
            - stp_111
            - stp_222
            - stp_333
        status:
          type: string
          enum:
            - active
            - pending
            - paid
            - expired
            - historical
          default: active
          description: >-
            Filtro de estado: **active** (default, alias de **pending**),
            **pending**, **paid**, **expired**, **historical** (paid+expired)
          example: active
        per_stop:
          description: Configuración de paginación y filtros por Parada
          type: object
          properties:
            page_size:
              type: integer
              minimum: 1
              maximum: 200
              default: 50
              description: Tamaño por Parada (1..200, default 50)
              example: 20
            sort:
              type: string
              enum:
                - created_at
                - updated_at
                - expires_at
                - amount
              default: created_at
              description: Campo de ordenación
              example: created_at
            order:
              type: string
              enum:
                - asc
                - desc
              default: desc
              description: Dirección de ordenación
              example: desc
            only_fields:
              type: array
              items:
                type: string
              description: >-
                Limitar campos para reducir payload (p. ej.,
                ["session_id","payment_url","expires_at"])
              example:
                - session_id
                - payment_url
                - expires_at
            cursor_by_stop:
              type: object
              additionalProperties:
                type: string
              description: >-
                Cursor por Parada para continuar desde una respuesta previa. Usa
                `next_cursor` por `stop_id` para cargas incrementales eficientes
              example:
                stp_111: cur_aaa
                stp_333: cur_ccc
    SessionLink:
      type: object
      required:
        - session_id
        - payment_url
        - status
        - amount
        - created_at
      properties:
        session_id:
          type: string
          description: Identificador único de la sesión de pago
          example: sess_A
        payment_url:
          type: string
          format: uri
          description: Enlace de pago asociado a la sesión
          example: https://pay.spidi.io/sess_A
        status:
          type: string
          enum:
            - pending
            - paid
            - expired
          description: Estado de la sesión de pago
          example: pending
        amount:
          type: object
          required:
            - value
            - currency
          properties:
            value:
              type: string
              description: Monto en la moneda especificada
              example: '15.00'
            currency:
              type: string
              enum:
                - USD_BCV
                - EUR_BCV
                - COP
                - USDT
                - VES
              description: Moneda del monto (VES o moneda de referencia)
              example: USD_BCV
          description: Monto original de la sesión
        amount_bs:
          type: object
          properties:
            value:
              type: string
              description: Monto expresado en bolívares
              example: Bs. 552,00
            rate_date:
              type: string
              format: date
              description: Fecha de la tasa de cambio aplicada
              example: '2025-10-16'
          description: Monto expresado en Bs. cuando la referencia no es VES
        created_at:
          type: string
          format: date-time
          description: Fecha/hora de creación de la sesión
          example: '2025-10-15T14:25:32Z'
        updated_at:
          type: string
          format: date-time
          description: Fecha/hora de última actualización
          example: '2025-10-15T14:26:10Z'
        expires_at:
          type: string
          format: date-time
          description: 'Vencimiento de la sesión (Botón: 10 min; Solicitud: configurable)'
          example: '2025-10-15T14:35:32Z'
        paid_at:
          type: string
          format: date-time
          description: Fecha/hora de confirmación de pago (si paid)
          example: '2025-10-15T14:30:00Z'
        agreement_id:
          type: string
          description: Acuerdo de liquidación aplicado (si existe)
          example: agr_001
        internal_reference:
          type: string
          description: Identificador interno del comercio (requerido en Solicitudes)
          example: INV-9842
        customer_ref:
          type: string
          description: Referencia del cliente (si aplica)
          example: cust_778
        order_index:
          type: integer
          description: Posición relativa en la Parada (para visualización)
          example: 0
        receipt_url:
          type: string
          format: uri
          description: URL del comprobante de pago SPIDI (si paid)
          example: https://pay.spidi.io/receipt/sess_A
        metadata:
          type: object
          description: Datos adicionales definidos por el comercio
          additionalProperties: true
          example:
            plan: pro
        expiration_behavior:
          type: string
          enum:
            - expire
            - message_only
          description: Comportamiento al vencer (solo Solicitudes)
          example: message_only
    QueryStopResult:
      type: object
      required:
        - stop_id
      properties:
        stop_id:
          type: string
          description: Parada consultada
          example: stp_111
        page_size:
          type: integer
          description: Tamaño aplicado por Parada
          example: 20
        has_next:
          type: boolean
          description: Si hay más resultados
          example: true
        next_cursor:
          type: string
          description: Cursor para continuar la paginación de esa Parada
          example: cur_aaa_next
        total_estimate:
          type: integer
          description: Estimación rápida del total (opcional)
          example: 72
        items:
          type: array
          items:
            type: object
            required:
              - session_id
              - payment_url
              - status
              - amount
              - created_at
            properties:
              session_id:
                type: string
                description: Identificador único de la sesión de pago
                example: sess_A
              payment_url:
                type: string
                format: uri
                description: Enlace de pago asociado a la sesión
                example: https://pay.spidi.io/sess_A
              status:
                type: string
                enum:
                  - pending
                  - paid
                  - expired
                description: Estado de la sesión de pago
                example: pending
              amount:
                type: object
                required:
                  - value
                  - currency
                properties:
                  value:
                    type: string
                    description: Monto en la moneda especificada
                    example: '15.00'
                  currency:
                    type: string
                    enum:
                      - USD_BCV
                      - EUR_BCV
                      - COP
                      - USDT
                      - VES
                    description: Moneda del monto (VES o moneda de referencia)
                    example: USD_BCV
                description: Monto original de la sesión
              amount_bs:
                type: object
                properties:
                  value:
                    type: string
                    description: Monto expresado en bolívares
                    example: Bs. 552,00
                  rate_date:
                    type: string
                    format: date
                    description: Fecha de la tasa de cambio aplicada
                    example: '2025-10-16'
                description: Monto expresado en Bs. cuando la referencia no es VES
              created_at:
                type: string
                format: date-time
                description: Fecha/hora de creación de la sesión
                example: '2025-10-15T14:25:32Z'
              updated_at:
                type: string
                format: date-time
                description: Fecha/hora de última actualización
                example: '2025-10-15T14:26:10Z'
              expires_at:
                type: string
                format: date-time
                description: >-
                  Vencimiento de la sesión (Botón: 10 min; Solicitud:
                  configurable)
                example: '2025-10-15T14:35:32Z'
              paid_at:
                type: string
                format: date-time
                description: Fecha/hora de confirmación de pago (si paid)
                example: '2025-10-15T14:30:00Z'
              agreement_id:
                type: string
                description: Acuerdo de liquidación aplicado (si existe)
                example: agr_001
              internal_reference:
                type: string
                description: Identificador interno del comercio (requerido en Solicitudes)
                example: INV-9842
              customer_ref:
                type: string
                description: Referencia del cliente (si aplica)
                example: cust_778
              order_index:
                type: integer
                description: Posición relativa en la Parada (para visualización)
                example: 0
              receipt_url:
                type: string
                format: uri
                description: URL del comprobante de pago SPIDI (si paid)
                example: https://pay.spidi.io/receipt/sess_A
              metadata:
                type: object
                description: Datos adicionales definidos por el comercio
                additionalProperties: true
                example:
                  plan: pro
              expiration_behavior:
                type: string
                enum:
                  - expire
                  - message_only
                description: Comportamiento al vencer (solo Solicitudes)
                example: message_only
          description: Lista de sesiones (cada una con su payment_url)
        error:
          type: object
          properties:
            code:
              type: string
              enum:
                - not_found
                - forbidden
                - invalid_cursor
              description: Código de error
              example: not_found
            message:
              type: string
              description: Mensaje de error
              example: Stop not found.
          description: Error específico de esta Parada (si aplica)
    QueryStopsResponse:
      type: object
      required:
        - success
        - requested
        - results
      properties:
        success:
          type: boolean
          description: >-
            **true** si el batch de consulta se procesó (aunque existan errores
            por Parada)
          example: true
        requested:
          type: object
          description: Eco de parámetros aplicados
          properties:
            stop_ids:
              type: array
              items:
                type: string
              example:
                - stp_111
                - stp_222
                - stp_333
            status:
              type: string
              example: active
            per_stop:
              type: object
              properties:
                page_size:
                  type: integer
                  minimum: 1
                  maximum: 200
                  default: 50
                  description: Tamaño por Parada (1..200, default 50)
                  example: 20
                sort:
                  type: string
                  enum:
                    - created_at
                    - updated_at
                    - expires_at
                    - amount
                  default: created_at
                  description: Campo de ordenación
                  example: created_at
                order:
                  type: string
                  enum:
                    - asc
                    - desc
                  default: desc
                  description: Dirección de ordenación
                  example: desc
                only_fields:
                  type: array
                  items:
                    type: string
                  description: >-
                    Limitar campos para reducir payload (p. ej.,
                    ["session_id","payment_url","expires_at"])
                  example:
                    - session_id
                    - payment_url
                    - expires_at
                cursor_by_stop:
                  type: object
                  additionalProperties:
                    type: string
                  description: >-
                    Cursor por Parada para continuar desde una respuesta previa.
                    Usa `next_cursor` por `stop_id` para cargas incrementales
                    eficientes
                  example:
                    stp_111: cur_aaa
                    stp_333: cur_ccc
        results:
          type: array
          items:
            type: object
            required:
              - stop_id
            properties:
              stop_id:
                type: string
                description: Parada consultada
                example: stp_111
              page_size:
                type: integer
                description: Tamaño aplicado por Parada
                example: 20
              has_next:
                type: boolean
                description: Si hay más resultados
                example: true
              next_cursor:
                type: string
                description: Cursor para continuar la paginación de esa Parada
                example: cur_aaa_next
              total_estimate:
                type: integer
                description: Estimación rápida del total (opcional)
                example: 72
              items:
                type: array
                items:
                  type: object
                  required:
                    - session_id
                    - payment_url
                    - status
                    - amount
                    - created_at
                  properties:
                    session_id:
                      type: string
                      description: Identificador único de la sesión de pago
                      example: sess_A
                    payment_url:
                      type: string
                      format: uri
                      description: Enlace de pago asociado a la sesión
                      example: https://pay.spidi.io/sess_A
                    status:
                      type: string
                      enum:
                        - pending
                        - paid
                        - expired
                      description: Estado de la sesión de pago
                      example: pending
                    amount:
                      type: object
                      required:
                        - value
                        - currency
                      properties:
                        value:
                          type: string
                          description: Monto en la moneda especificada
                          example: '15.00'
                        currency:
                          type: string
                          enum:
                            - USD_BCV
                            - EUR_BCV
                            - COP
                            - USDT
                            - VES
                          description: Moneda del monto (VES o moneda de referencia)
                          example: USD_BCV
                      description: Monto original de la sesión
                    amount_bs:
                      type: object
                      properties:
                        value:
                          type: string
                          description: Monto expresado en bolívares
                          example: Bs. 552,00
                        rate_date:
                          type: string
                          format: date
                          description: Fecha de la tasa de cambio aplicada
                          example: '2025-10-16'
                      description: Monto expresado en Bs. cuando la referencia no es VES
                    created_at:
                      type: string
                      format: date-time
                      description: Fecha/hora de creación de la sesión
                      example: '2025-10-15T14:25:32Z'
                    updated_at:
                      type: string
                      format: date-time
                      description: Fecha/hora de última actualización
                      example: '2025-10-15T14:26:10Z'
                    expires_at:
                      type: string
                      format: date-time
                      description: >-
                        Vencimiento de la sesión (Botón: 10 min; Solicitud:
                        configurable)
                      example: '2025-10-15T14:35:32Z'
                    paid_at:
                      type: string
                      format: date-time
                      description: Fecha/hora de confirmación de pago (si paid)
                      example: '2025-10-15T14:30:00Z'
                    agreement_id:
                      type: string
                      description: Acuerdo de liquidación aplicado (si existe)
                      example: agr_001
                    internal_reference:
                      type: string
                      description: >-
                        Identificador interno del comercio (requerido en
                        Solicitudes)
                      example: INV-9842
                    customer_ref:
                      type: string
                      description: Referencia del cliente (si aplica)
                      example: cust_778
                    order_index:
                      type: integer
                      description: Posición relativa en la Parada (para visualización)
                      example: 0
                    receipt_url:
                      type: string
                      format: uri
                      description: URL del comprobante de pago SPIDI (si paid)
                      example: https://pay.spidi.io/receipt/sess_A
                    metadata:
                      type: object
                      description: Datos adicionales definidos por el comercio
                      additionalProperties: true
                      example:
                        plan: pro
                    expiration_behavior:
                      type: string
                      enum:
                        - expire
                        - message_only
                      description: Comportamiento al vencer (solo Solicitudes)
                      example: message_only
                description: Lista de sesiones (cada una con su payment_url)
              error:
                type: object
                properties:
                  code:
                    type: string
                    enum:
                      - not_found
                      - forbidden
                      - invalid_cursor
                    description: Código de error
                    example: not_found
                  message:
                    type: string
                    description: Mensaje de error
                    example: Stop not found.
                description: Error específico de esta Parada (si aplica)
          description: Resultado por stop_id
          example:
            - stop_id: stp_111
              page_size: 20
              has_next: true
              next_cursor: cur_aaa_next
              total_estimate: 72
              items:
                - session_id: sess_A
                  payment_url: https://pay.spidi.io/sess_A
                  status: pending
                  amount:
                    value: '15.00'
                    currency: USD_BCV
                  amount_bs:
                    value: Bs. 552,00
                    rate_date: '2025-10-16'
                  created_at: '2025-10-15T14:25:32Z'
                  expires_at: '2025-10-15T14:35:32Z'
                  order_index: 0
            - stop_id: stp_222
              page_size: 20
              has_next: false
              next_cursor: null
              total_estimate: 2
              items: []
            - stop_id: stp_333
              error:
                code: not_found
                message: Stop not found.
    payment_method:
      type: string
      nullable: true
      enum:
        - crypto
        - immediate_debit
        - mobile_payment
      description: 'Método de pago utilizado. Eco del request: no.'
    transactionSpidi_id:
      description: ID de la transacción en SPIDI.
      type: number
      example: 1296
    transactionSpidi_url:
      type: string
      nullable: true
      format: uri
      description: URL del comprobante de pago en SPIDI (Comparar con 'receipt_url').
    sessionPaymentWebhook:
      type: object
      properties:
        id:
          type: string
          nullable: false
          description: >-
            Identificador único de la sesión de pago, accedible a través del
            payment_url.
        origin:
          type: string
          nullable: false
          enum:
            - button
            - request
          description: >-
            Origen de la sesión: 'button' (Botón de pago) o 'request' (Solicitud
            SPIDI).
        agreement_id:
          type: string
          format: uuid
          nullable: true
          description: 'Identificador único del acuerdo de liquidación. Debe ser UUID v4. '
        currency_reference:
          type: string
          nullable: false
          enum:
            - USD
            - EUR
            - COP
            - USDT
            - VES
          description: >-
            Moneda de referencia que se fija para el pago. Usada para calcular
            el monto en bolívares con la tasa vigente.
        amount_reference:
          description: >-
            Monto de referencia en la moneda especificada en currencyReference
            con 2 decimales.
          type: number
          nullable: false
          format: double
          example: '100.001'
        identifier_label:
          type: string
          nullable: true
          description: >-
            Etiqueta que indica cómo debe interpretarse el valor enviado en
            identifier (ej. 'Nro de orden').
        identifier:
          type: string
          nullable: false
          description: >-
            Identificador del pagador, interpretado según el valor de
            identifier_label. Ejemplo: Nro de orden, Nombre, etc.
        description:
          type: string
          nullable: true
          description: >-
            Descripción del acuerdo o del concepto de pago asociado a una
            sesión.
          maxLength: 500
        payment_method:
          type: string
          nullable: true
          enum:
            - crypto
            - immediate_debit
            - mobile_payment
          description: 'Método de pago utilizado. Eco del request: no.'
    recipientType:
      type: string
      nullable: true
      description: Tipo del receptor del crédito.
      enum:
        - owner
        - partner
    partner_observations:
      type: string
      nullable: false
      maxLength: 500
      description: >-
        Mensaje libre para el partner (máx. 500 caracteres). (Requerido en
        distribution, Eco del request: sí)
    recipient:
      type: object
      properties:
        id:
          type: string
          nullable: true
          description: Identificador del receptor del crédito.
        type:
          type: string
          nullable: true
          description: Tipo del receptor del crédito.
          enum:
            - owner
            - partner
        split_recipient_agreement_id:
          type: string
          nullable: false
          format: uuid
          description: >-
            UUID global SPIDI del agreement de recepción. Este ID se usará en
            acuerdos de distribución para identificar al receptor del split.
            (Requerido en distribution)
        partner:
          type: object
          properties:
            observations:
              type: string
              nullable: false
              maxLength: 500
              description: >-
                Mensaje libre para el partner (máx. 500 caracteres). (Requerido
                en distribution, Eco del request: sí)
            name:
              type: string
              nullable: true
              description: Nombre o razón social del partner
            rif_number:
              type: string
              nullable: true
              description: RIF del partner
    creditWebhook:
      type: object
      properties:
        id:
          type: string
        amount_ves_credited:
          type: number
          nullable: true
          description: >-
            Monto neto acreditado al receptor en bolívares, luego de aplicar las
            comisiones correspondientes. Siempre tiene 2 decimales.
          format: double
          example: '100.01'
        bank_commissions_ves:
          type: number
          nullable: true
          format: decimal(12,2)
          description: >-
            Comisión bancaria total cobrada en bolívares para la liquidación.
            Eco del request: no.
        receive_date:
          type: string
          format: date-time
          nullable: true
          description: Fecha y hora en que se acreditó el pago (ISO 8601).
        bank_name:
          type: string
          nullable: true
          description: 'Nombre comercial del banco. Eco del request: no.'
        bank_reference_id:
          type: string
          nullable: true
          description: 'Referencia bancaria del pago. Eco del request: no.'
        recipient:
          type: object
          properties:
            id:
              type: string
              nullable: true
              description: Identificador del receptor del crédito.
            type:
              type: string
              nullable: true
              description: Tipo del receptor del crédito.
              enum:
                - owner
                - partner
            split_recipient_agreement_id:
              type: string
              nullable: false
              format: uuid
              description: >-
                UUID global SPIDI del agreement de recepción. Este ID se usará
                en acuerdos de distribución para identificar al receptor del
                split. (Requerido en distribution)
            partner:
              type: object
              properties:
                observations:
                  type: string
                  nullable: false
                  maxLength: 500
                  description: >-
                    Mensaje libre para el partner (máx. 500 caracteres).
                    (Requerido en distribution, Eco del request: sí)
                name:
                  type: string
                  nullable: true
                  description: Nombre o razón social del partner
                rif_number:
                  type: string
                  nullable: true
                  description: RIF del partner
  parameters:
    spidiSignature:
      name: spidi-signature
      in: header
      required: true
      description: Firma HMAC-SHA256 para validar la autenticidad e integridad del mensaje.
      schema:
        type: string
        example: d9c8227652758252615617f6a8759526703902939d892376987f22387a672889
    spidiTimestamp:
      name: spidi-timestamp
      in: header
      required: true
      description: >-
        Timestamp ISO 8601 de la creación del evento para prevenir ataques de
        replay.
      schema:
        type: string
        format: date-time
        example: '2026-02-06T15:24:36.000Z'
    idempotencyKey:
      name: idempotency-key
      in: header
      required: true
      description: UUID v4 único para garantizar que la operación se procese una sola vez.
      schema:
        type: string
        format: uuid
        example: 93465a7e-ea9b-41a8-8dca-14e811641c25
