{
  "openapi": "3.1.0",
  "info": {
    "title": "API Products",
    "version": "1.0.0",
    "description": "API para integraciones con SPIDI.\n\n ##  Navegación en Móvil\n\nSi estás en un dispositivo móvil, recuerda usar el menú de hamburguesa en la esquina superior izquierda para ver todos los endpoints disponibles.\n\n##  Entornos\n\nPara información detallada sobre entornos (Sandbox y Producción), consulta la página dedicada:\n\n **[Entornos](../../env)**\n\n##  Webhooks\n\nSPIDI utiliza webhooks para notificar en tiempo real sobre eventos importantes (pagos completados, sesiones expiradas, etc.). Para información completa sobre:\n\n- Eventos disponibles\n- Estructura de webhooks\n- Reintentos automáticos\n- Seguridad y validación\n- Ejemplos de implementación\n\nConsulta la página dedicada:\n\n **[Webhooks](../../concepts/webhooks.mdx)**\n\n"
  },
  "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.\n\n## ¿Qué son las Paradas SPIDI?\n\nLas 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.\n\n**Beneficios clave:**\n- **URL permanente**: Punto de acceso constante y trazable\n- **Gestión centralizada**: Todas las solicitudes de pago en un solo lugar\n- **Ideal para**: Relaciones comerciales continuas, suscripciones, pagos recurrentes\n- **Experiencia simplificada**: Para el pagador y la empresa\n\n**Estados de una Parada:**\n- **Active**: Con solicitudes de pago activas disponibles\n- **Empty**: Sin solicitudes de pago activas, muestra mensaje personalizado\n- **Disabled**: Deshabilitada temporalmente, puede reactivarse\n- **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.\n\n### Funcionalidades principales:\n\n* **Autenticación segura:** Valida las credenciales del usuario (`short_name` y `password`).\n* **Generación de token JWT:** Retorna un token de acceso que debe utilizarse en requests posteriores.\n* **Control de sesión:** El token tiene un tiempo de expiración definido para mayor seguridad.\n\n### Casos de uso típicos:\n\n* Inicio de sesión de usuarios comercio.\n* Obtención de token para operaciones API.\n* Renovación de credenciales de acceso.\n* Autenticación en aplicaciones integradas.\n\nUna 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. \n\n* El token es un **JWT (JSON Web Token)** codificado en Base64.\n* Debe incluirse en el header `Authorization: Bearer {token}` de requests posteriores.\n* Tiene un tiempo de expiración definido por seguridad.\n* 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.\n\n---\n\n### **⚙️ Funcionalidades principales**\n\n* **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.\n* **Liquidación bancaria inteligente:** Permite dirigir los pagos hacia distintas cuentas bancarias de destino dependiendo del banco de origen del pagador.\n* **Medios de pago configurables:** Determina qué tipos de pago acepta el acuerdo (`immediate_debit`, `crypto`, `mobile_payment`).\n* **`split`:**\n  * **`false`:** No aplica distribución; el owner recibe el 100 % del pago.\n  * **`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.\n\n### **Casos de uso típicos**\n\n* Comercios que trabajan con partners y necesitan distribuir comisiones automáticamente.\n* Marketplaces que deben dividir los pagos entre vendedores y la plataforma.\n* Servicios que liquidan fondos en distintas cuentas según el banco de origen.\n* Plataformas que requieren flexibilidad para definir la distribución por cada transacción.\n\n### **Reutilización**\n\nUna 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. \n 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. \n 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.\n\n**Notas importantes:**\n- Esta información **no implica cálculo fiscal** por parte de SPIDI; es solo comunicación entre owner y partners.\n- `splitDocument_url` puede ser público con hash o una URL autenticada.\n- 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.\n\n**Notas importantes:**\n- Esta información **no implica cálculo fiscal** por parte de SPIDI; es solo comunicación entre owner y partners.\n- `splitDocument_url` puede ser público con hash o una URL autenticada.\n- 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.\n\nEste 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`).\n\n### Origen de la Sesión\n\nUna 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`).\n\nEn 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`.\n\n## Notas Importantes\n\n### Verificación de Pagos (Backend Obligatorio)\n\n**No asumas `paid` solo por redirección**; **consulta este endpoint** desde tu servidor antes de liberar servicios o productos.\n\n### Liquidación al Receptor\n\nTras `paid`, la liquidación al receptor puede tardar unos segundos; en ese caso `receiver_credits` y `receiver_credits_summary` pueden venir `null` temporalmente. \n\n**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.\n\nLa 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.\n\n**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.\n\n### Consulta de Datos de Liquidación\n\nSi 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. \n\nOpcionalmente, 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`).\n\n### URL del Comprobante\n\nRecuerda que se incluye el URL del comprobante exitoso (`spidi_transaction_url`), que debe ser mostrado al usuario de una forma u otra.\n\n## Pagos con Criptomonedas\n\n- Si `payment_method` es `\"crypto\"`, el objeto `crypto_details` contendrá información específica del pago cripto\n- Si `payment_method` es distinto a `\"crypto\"`, entonces `crypto_details` será `null`\n- 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`\n\n## Split de Pagos\n\n- Si no se generó un split, entonces el objeto de `receiver_credits` tiene un solo elemento\n- Si existió el split, deben haber al menos dos elementos en `receiver_credits`\n\n## Estados Vigentes\n\n- `pending`: Sesión creada, esperando que el usuario complete el pago\n- `paid`: Pago completado exitosamente\n- `expired`: Sesión expirada por inactividad o manualmente\n- `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.\n- Si es `false`, se detiene en el primer error y las operaciones ya exitosas permanecen válidas. \n- 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).\n\n**Importancia para Paradas SPIDI:**\n- Permite conciliar y auditar operaciones entre tu sistema y SPIDI\n- Sirve para asociar solicitudes de pago con su Parada correspondiente\n- Puede vincularse a clientes, contratos o facturas en tu plataforma\n\nSe 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.\n\n**Notas importantes:**\n- Esta información **no implica cálculo fiscal** por parte de SPIDI; es solo comunicación entre owner y partners.\n- `splitDocument_url` puede ser público con hash o una URL autenticada.\n- 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).\n\n**Importancia para Paradas SPIDI:**\n- Permite conciliar y auditar operaciones entre tu sistema y SPIDI\n- Sirve para asociar solicitudes de pago con su Parada correspondiente\n- Puede vincularse a clientes, contratos o facturas en tu plataforma\n\nSe 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.\n\n**Notas importantes:**\n- Esta información **no implica cálculo fiscal** por parte de SPIDI; es solo comunicación entre owner y partners.\n- `splitDocument_url` puede ser público con hash o una URL autenticada.\n- 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. \n\n### Comportamiento según Estado Actual\n\n- Si la sesión está **`PENDING`**, pasa a **`EXPIRED`** inmediatamente.\n- Si ya estaba **`EXPIRED`** no hace nada.\n- Si la sesión está **`PAID`**, **NO** puede expirarse (regla de negocio - retorna error 422).\n\n## Efecto sobre Paradas SPIDI\n\nSi 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`.\n\n## Notas y Buenas Prácticas\n\n### Paradas SPIDI\n\nNo 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).\n\n### Trazabilidad\n\n Usa `message_audit` para auditoría (quién, cuándo, por qué).\n\n",
        "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. \n\n**Definiciones:**\n* `INCORRECT_DATA`: Datos de pago o cliente inválidos (ej. CI/RIF erróneo).\n* `ALTERNATIVE_PAYMENT_RECEIVED`: El cliente pagó por otra vía (ej. efectivo o transferencia directa).\n* `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. \n\n**Definiciones:**\n* `INCORRECT_DATA`: Datos de pago o cliente inválidos (ej. CI/RIF erróneo).\n* `ALTERNATIVE_PAYMENT_RECEIVED`: El cliente pagó por otra vía (ej. efectivo o transferencia directa).\n* `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.\n\nAl 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.\n\nEste *agreement* no admite splits adicionales: su única función es definir el **ruteo de la liquidación**, determinando la cuenta bancaria destino.\n\n## Características\n\n- Identificador **global** retornado como `split_recipient_agreement_id` (UUID SPIDI)\n- Enrutamiento con **fallback** a `default_bank_account_id`\n- Referenciable desde acuerdos de **distribución** vía `split_recipient_agreement_id`\n\n## Notas de Validación\n\n- Debe existir **siempre** `default_bank_account_id`\n- En `rules`, cada `origin_bank_code` **no puede repetirse**\n- Si en runtime no hay match de `origin_bank_code`, se utiliza el `default_bank_account_id`\n- Si no hay match **y** falta `default_bank_account_id` → error\n\n## Idempotencia\n\nUsa 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. \n 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. \n 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).\n\n**Importancia para Paradas SPIDI:**\n- Permite conciliar y auditar operaciones entre tu sistema y SPIDI\n- Sirve para asociar solicitudes de pago con su Parada correspondiente\n- Puede vincularse a clientes, contratos o facturas en tu plataforma\n\nSe 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.\n\n**Estados disponibles:**\n\n- **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`.\n\n- **disabled**: La parada está deshabilitada temporalmente. Los clientes no pueden acceder a ella, pero puede reactivarse cambiando el estado a `active`.\n\n**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.\n\n## ¿Qué son las Paradas SPIDI?\n\nLas 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.\n\nFuncionan 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.\n\n## Características principales\n\n- **URL permanente**: Cada parada posee una `stop_url` única que el cliente puede visitar en cualquier momento\n- **Gestión centralizada**: Desde esa URL, el cliente ve todas sus solicitudes de pago (pendientes, vencidas o completadas)\n- **Creación masiva**: Permite crear de 1 a N paradas en un solo request, ideal para procesos de onboarding inicial\n- **Idempotencia**: Soporta reintentos idempotentes mediante `Idempotency-Key`\n- **Asociación flexible**: Puede vincularse a un cliente específico o a múltiples referencias según las necesidades de tu plataforma\n\n## Estados de una Parada\n\n- **Active**: Existe al menos un enlace de pago activo; se muestran los pagos disponibles\n- **Empty**: Sin solicitudes de pago activas; muestra el mensaje configurado en `empty_state_message`\n- **Disabled**: Deshabilitada temporalmente, pero puede reactivarse\n- **Deleted**: Eliminada definitivamente\n\n## Integración técnica\n\nSe 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.\n- Si es `false`, se detiene en el primer error y las operaciones ya exitosas permanecen válidas. \n- 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).\n\n**Importancia para Paradas SPIDI:**\n- Permite conciliar y auditar operaciones entre tu sistema y SPIDI\n- Sirve para asociar solicitudes de pago con su Parada correspondiente\n- Puede vincularse a clientes, contratos o facturas en tu plataforma\n\nSe 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).\n\n**Importancia para Paradas SPIDI:**\n- Permite conciliar y auditar operaciones entre tu sistema y SPIDI\n- Sirve para asociar solicitudes de pago con su Parada correspondiente\n- Puede vincularse a clientes, contratos o facturas en tu plataforma\n\nSe 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).\n\n**Importancia para Paradas SPIDI:**\n- Permite conciliar y auditar operaciones entre tu sistema y SPIDI\n- Sirve para asociar solicitudes de pago con su Parada correspondiente\n- Puede vincularse a clientes, contratos o facturas en tu plataforma\n\nSe 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.\n\n**Estados disponibles:**\n\n- **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`.\n\n- **disabled**: La parada está deshabilitada temporalmente. Los clientes no pueden acceder a ella, pero puede reactivarse cambiando el estado a `active`.\n\n**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.\n\nDevuelve información completa de la parada incluyendo:\n- Identificadores (`stop_id`, `stop_url`)\n- Metadatos configurables (`stop_title`, `empty_state_message`, `status`)\n- Referencia interna (`internal_reference`)\n- **Solo solicitudes de pago activas** (`links_active`)\n\nPara 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).\n\n**Importancia para Paradas SPIDI:**\n- Permite conciliar y auditar operaciones entre tu sistema y SPIDI\n- Sirve para asociar solicitudes de pago con su Parada correspondiente\n- Puede vincularse a clientes, contratos o facturas en tu plataforma\n\nSe 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.\n\n**Estados disponibles:**\n\n- **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`.\n\n- **disabled**: La parada está deshabilitada temporalmente. Los clientes no pueden acceder a ella, pero puede reactivarse cambiando el estado a `active`.\n\n**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.\n\nPermite modificar:\n- **stop_title**: Título visible de la parada\n- **status**: Estado de la parada (`active` o `disabled`)\n- **empty_state_message**: Mensaje mostrado cuando no hay solicitudes de pago activas\n\nLos 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.\n\n**⚠️ Importante:**\n- La eliminación es **permanente** y no se puede revertir\n- **No se permite eliminar** una parada que tenga solicitudes de pago activas asociadas; primero debes removerlos o expirarlos\n- La operación es **idempotente**: múltiples llamadas con la misma `Idempotency-Key` no crearán duplicados\n\n** 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.\n\nDevuelve la lista completa de solicitudes de pago asociados a un `stop_id`, incluyendo:\n- **Sesiones de Pago Activas** (`pending`)\n- **Sesiones de Pago Pagadas ** (`paid`)\n- **Sesiones de Pago Expiradas** (`expired`)\n\nSoporta filtros avanzados por estado, rango de fechas y paginación para manejar colecciones grandes.\n\n**Diferencia con ```GET /payment-stops/{stop_id}```:**\n- El endpoint básico solo devuelve solicitudes de pago activas\n- 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.\n\n**Operaciones soportadas:**\n- **add**: Agrega 1..N `session_id` como activos (si ya estaban, es no-op y se reportan en `already_present`)\n- **remove**: Desasocia 1..N `session_id` activos (si no estaban activos, se reportan en `not_active` o `not_found`)\n- **replace**: Sustituye atómicamente el conjunto activo por `session_ids`. Con lista vacía ⇒ `clear`\n- **clear**: Elimina todos los activos (la Parada puede quedar en estado Empty)\n\n**Características:**\n- Idempotente mediante encabezado `Idempotency-Key` (TTL: 24 horas)\n- Cada ítem se procesa de forma independiente\n- El resultado se devuelve por Parada\n- Rate limit: 100 requests/minuto por comercio\n\n**Notas importantes:**\n- Solo sesiones `pending` pueden activarse (`add`/`replace`). Las sesiones `paid`/`expired` pasan a histórico automáticamente\n- `replace` con lista vacía equivale a `clear` (limpieza atómica)\n- Usa siempre `Idempotency-Key` en operaciones en lote\n- 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.\n- Si es `false`, se detiene en el primer error y las operaciones ya exitosas permanecen válidas. \n- 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.\n\n**Características:**\n- No agrega ni quita sesiones; **solo** cambia el **orden**\n- Idempotente mediante `Idempotency-Key` (TTL: 24 horas)\n- Control de concurrencia opcional mediante `order_version` (recomendado)\n- Rate limit: 100 requests/minuto por comercio\n\n**Modos de operación:**\n- **append** (default): reordena las sesiones listadas arriba y cualquier activa no listada queda al final manteniendo su orden relativo actual\n- **strict**: la lista debe representar exactamente el conjunto de activos; si falta alguna activa o sobra alguna no activa, se devuelve error por ítem\n\n**Notas importantes:**\n- Separación de responsabilidades: usa `reorder` solo para ordenar. Para agregar/quitar/sustituir, utiliza el batch de operar solicitudes de pago\n- Idempotencia siempre: envía `Idempotency-Key`; misma clave + mismo payload ⇒ misma respuesta\n- 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.\n- Si es `false`, se detiene en el primer error y las operaciones ya exitosas permanecen válidas. \n- 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`).\n\nIncluye paginación por Parada, filtros básicos y posibilidad de limitar campos para reducir payload.\n\n**¿Por qué POST para \"leer\"?**\nAcepta 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.\n\n**Características:**\n- Optimizado para **UI cliente** - devuelve **solo activos por defecto** (`status=pending`)\n- Paginación cursor-based por parada\n- Rate limit: 100 requests/minuto por comercio\n- Máximo: 200 `stop_ids` por request\n\n**Notas importantes:**\n- Si necesitas histórico, usa `status: \"historical\"` o `include_history: true` en el request\n- Para más de 200 stops, realiza múltiples requests\n- 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.\n\n**Notas importantes:**\n- Esta información **no implica cálculo fiscal** por parte de SPIDI; es solo comunicación entre owner y partners.\n- `splitDocument_url` puede ser público con hash o una URL autenticada.\n- 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** \n\n 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** \n\n 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"
      },
      "POSSignature": {
        "type": "apiKey",
        "in": "header",
        "name": "x-pos-signature",
        "description": "Requiere el uso de la firma HMAC para verificar la autenticidad de la solicitud"
      }
    },
    "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. \n\n* El token es un **JWT (JSON Web Token)** codificado en Base64.\n* Debe incluirse en el header `Authorization: Bearer {token}` de requests posteriores.\n* Tiene un tiempo de expiración definido por seguridad.\n* 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. \n\n* El token es un **JWT (JSON Web Token)** codificado en Base64.\n* Debe incluirse en el header `Authorization: Bearer {token}` de requests posteriores.\n* Tiene un tiempo de expiración definido por seguridad.\n* 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. \n 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. \n 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. \n 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.\n\n**Notas importantes:**\n- Esta información **no implica cálculo fiscal** por parte de SPIDI; es solo comunicación entre owner y partners.\n- `splitDocument_url` puede ser público con hash o una URL autenticada.\n- 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.\n\n**Notas importantes:**\n- Esta información **no implica cálculo fiscal** por parte de SPIDI; es solo comunicación entre owner y partners.\n- `splitDocument_url` puede ser público con hash o una URL autenticada.\n- 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.\n\n**Notas importantes:**\n- Esta información **no implica cálculo fiscal** por parte de SPIDI; es solo comunicación entre owner y partners.\n- `splitDocument_url` puede ser público con hash o una URL autenticada.\n- 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.\n\n**Notas importantes:**\n- Esta información **no implica cálculo fiscal** por parte de SPIDI; es solo comunicación entre owner y partners.\n- `splitDocument_url` puede ser público con hash o una URL autenticada.\n- 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.\n- Si es `false`, se detiene en el primer error y las operaciones ya exitosas permanecen válidas. \n- 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).\n\n**Importancia para Paradas SPIDI:**\n- Permite conciliar y auditar operaciones entre tu sistema y SPIDI\n- Sirve para asociar solicitudes de pago con su Parada correspondiente\n- Puede vincularse a clientes, contratos o facturas en tu plataforma\n\nSe 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.\n- Si es `false`, se detiene en el primer error y las operaciones ya exitosas permanecen válidas. \n- 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).\n\n**Importancia para Paradas SPIDI:**\n- Permite conciliar y auditar operaciones entre tu sistema y SPIDI\n- Sirve para asociar solicitudes de pago con su Parada correspondiente\n- Puede vincularse a clientes, contratos o facturas en tu plataforma\n\nSe 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.\n\n**Notas importantes:**\n- Esta información **no implica cálculo fiscal** por parte de SPIDI; es solo comunicación entre owner y partners.\n- `splitDocument_url` puede ser público con hash o una URL autenticada.\n- 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).\n\n**Importancia para Paradas SPIDI:**\n- Permite conciliar y auditar operaciones entre tu sistema y SPIDI\n- Sirve para asociar solicitudes de pago con su Parada correspondiente\n- Puede vincularse a clientes, contratos o facturas en tu plataforma\n\nSe 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.\n\n**Notas importantes:**\n- Esta información **no implica cálculo fiscal** por parte de SPIDI; es solo comunicación entre owner y partners.\n- `splitDocument_url` puede ser público con hash o una URL autenticada.\n- 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. \n\n**Definiciones:**\n* `INCORRECT_DATA`: Datos de pago o cliente inválidos (ej. CI/RIF erróneo).\n* `ALTERNATIVE_PAYMENT_RECEIVED`: El cliente pagó por otra vía (ej. efectivo o transferencia directa).\n* `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. \n 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. \n 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.\n\n**Estados disponibles:**\n\n- **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`.\n\n- **disabled**: La parada está deshabilitada temporalmente. Los clientes no pueden acceder a ella, pero puede reactivarse cambiando el estado a `active`.\n\n**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).\n\n**Importancia para Paradas SPIDI:**\n- Permite conciliar y auditar operaciones entre tu sistema y SPIDI\n- Sirve para asociar solicitudes de pago con su Parada correspondiente\n- Puede vincularse a clientes, contratos o facturas en tu plataforma\n\nSe 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.\n\n**Estados disponibles:**\n\n- **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`.\n\n- **disabled**: La parada está deshabilitada temporalmente. Los clientes no pueden acceder a ella, pero puede reactivarse cambiando el estado a `active`.\n\n**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).\n\n**Importancia para Paradas SPIDI:**\n- Permite conciliar y auditar operaciones entre tu sistema y SPIDI\n- Sirve para asociar solicitudes de pago con su Parada correspondiente\n- Puede vincularse a clientes, contratos o facturas en tu plataforma\n\nSe 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.\n\n**Estados disponibles:**\n\n- **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`.\n\n- **disabled**: La parada está deshabilitada temporalmente. Los clientes no pueden acceder a ella, pero puede reactivarse cambiando el estado a `active`.\n\n**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).\n\n**Importancia para Paradas SPIDI:**\n- Permite conciliar y auditar operaciones entre tu sistema y SPIDI\n- Sirve para asociar solicitudes de pago con su Parada correspondiente\n- Puede vincularse a clientes, contratos o facturas en tu plataforma\n\nSe 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.\n\n**Estados disponibles:**\n\n- **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`.\n\n- **disabled**: La parada está deshabilitada temporalmente. Los clientes no pueden acceder a ella, pero puede reactivarse cambiando el estado a `active`.\n\n**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.\n- Si es `false`, se detiene en el primer error y las operaciones ya exitosas permanecen válidas. \n- 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.\n- Si es `false`, se detiene en el primer error y las operaciones ya exitosas permanecen válidas. \n- 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"
        }
      }
    }
  }
}