{
  "brand": "Kevmi",
  "version": "2026-10-23.16",
  "updatedAt": "2026-10-23",
  "articles": [
    {
      "id": "quickstart",
      "title": "Inicio rápido",
      "summary": "Explora tu espacio de trabajo, configura tu tienda y ve una factura tal como la verá tu cliente. Esta guía te lleva por los pasos principales en orden.",
      "group": "start",
      "url": "/docs/quickstart",
      "tags": [
        "inicio",
        "configuración",
        "primer pago",
        "inicio rápido"
      ],
      "sections": [
        {
          "id": "explore",
          "title": "1. Explora el producto",
          "paragraphs": [
            "Abre el espacio de trabajo de demostración para crear un pedido de prueba, explora los enlaces de pago y revisa un cálculo de comisiones. La demostración utiliza datos de prueba separados. No crea un pago bancario ni transfiere fondos a una billetera."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Abrir el espacio de trabajo de demostración",
              "href": "/demo/index.html"
            },
            {
              "label": "Vista previa del pago",
              "href": "/pay/demo"
            }
          ]
        },
        {
          "id": "account",
          "title": "2. Crea una cuenta con Telegram",
          "paragraphs": [
            "Después de iniciar sesión con Telegram, se abre la cuenta del comerciante. La incorporación web está en /account#applications; tanto el formulario como el seguimiento individual en /account#applications/{id} permanecen dentro de la aplicación.",
            "Un nuevo pago e intento de tarjeta requieren que la última solicitud de revisión web del comerciante esté aprobada. La aprobación por sí sola no conecta la pasarela de pago. Si la revisión cambia después del envío, la operación existente permanece disponible para lecturas de estado, conciliación y un código bancario solicitado."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Abrir tu cuenta",
              "href": "/account"
            }
          ]
        },
        {
          "id": "settings",
          "title": "3. Configura tu tienda",
          "paragraphs": [],
          "bullets": [],
          "steps": [
            "Elige un nombre de tienda que tu cliente reconozca.",
            "Elige una regla de IVA predeterminada. Cada factura nueva acepta por separado participaciones de comisión del cliente e IVA del 0 al 100%.",
            "Selecciona las notificaciones que deseas recibir en Telegram.",
            "Usa la calculadora para verificar el monto típico de un pedido."
          ],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Calcular comisiones e IVA",
              "href": "/pricing"
            }
          ]
        },
        {
          "id": "invoice",
          "title": "4. Prepara un enlace de pago",
          "paragraphs": [
            "Ingresa un título de pedido claro, un monto y una moneda. El cliente obtiene una página dedicada con los detalles de la compra y el total a pagar. Una factura existente conserva sus términos originales cuando cambian los ajustes de tu tienda."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Guía de enlaces de pago",
              "href": "/docs/payment-links"
            }
          ]
        },
        {
          "id": "activate",
          "title": "5. Verifica la disponibilidad del pago",
          "paragraphs": [
            "Administra facturas, claves de API, widgets y webhooks desde tu cuenta. Antes del pago, Kevmi verifica la configuración de la pasarela, la aprobación del comerciante, el monto y los términos de la factura. Si el método seleccionado no está disponible, el pago explica el motivo.",
            "Las facturas del nuevo espacio de trabajo usan un precio base en USD y Any ofrece los cuatro métodos. SBP convierte a RUB al tipo de referencia congelado del Banco de Rusia; cripto usa la regla explícita de factura 1:1 USD/USDT. El precio nativo heredado sigue disponible para facturas antiguas y solicitudes de API sin pricingMode=universal. Consulte la sección de múltiples tiendas y precios en USD a continuación.",
            "Para un pago nuevo en vivo con tarjeta o Alipay, la pasarela actual solo admite feeCustomerPercent=0 y vatCustomerPercent=100: el comerciante cubre toda la comisión de procesamiento y el IVA se añade completo para el cliente. Otras participaciones se pueden guardar y calcular en una factura, pero la ejecución está bloqueada con unsupported_allocation. El servidor nunca cambia silenciosamente los términos guardados. Los pagos cripto SBP y USDT admiten todas las participaciones de comisión de procesamiento y no tienen IVA."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "Crear una factura, clave o aplicación no cobra dinero. La creación de pagos a través de la API no está disponible; los términos de retiro se cubren en una guía separada.",
          "links": [
            {
              "label": "Requisitos de integración de la pasarela",
              "href": "/docs/gateway"
            }
          ]
        },
        {
          "id": "stores-usd",
          "title": "Múltiples tiendas y un precio base en USD",
          "paragraphs": [
            "Elija Todas las tiendas para análisis y operaciones agregados, o seleccione una tienda para sus propios registros. Cada tienda tiene un storeId, nombre, IVA predeterminado, facturas, claves de API, endpoints de webhook, historial de eventos y aplicación web separados. Las notificaciones y tickets de soporte pertenecen a la cuenta. Una cuenta puede crear hasta 100 tiendas. Los registros existentes permanecen en su primera tienda.",
            "Las facturas del nuevo espacio de trabajo usan pricingMode=\"universal\" y un precio base en USD. Any incluye tarjeta, alipay, sbp y cripto; un comerciante puede seleccionar un subconjunto. Tarjetas y Alipay cobran en USD. SBP cobra en RUB usando el tipo de referencia USD/RUB del Banco de Rusia. Cripto cobra USDT bajo la regla explícita de factura 1 USD = 1 USDT. Esta es una regla de conversión de factura, no una cotización de mercado de USDT. La pasarela proporciona la tasa de la moneda seleccionada, el monto exacto de transferencia y las instrucciones antes de la transferencia.",
            "El tipo de referencia y ambos montos se congelan al crear. Las facturas que implican conversión de RUB vencen dentro de 24 horas. Si no se puede obtener el tipo de referencia, la creación falla con FX_UNAVAILABLE; no se usa ningún tipo de respaldo inventado o desactualizado. El monto en minor del propietario y las cotizaciones usan la moneda contable USD. quotes[method].settlement contiene la cotización de cargo nativa. El checkout público expone la moneda de cargo seleccionada en currency, el precio original en baseAmountMinor/baseCurrency y el tipo de referencia en fx. Una vez que un pago ha sido despachado, su método no se puede cambiar; una factura tiene una operación de pasarela.",
            "Cree una clave de API dentro de la tienda prevista y envíe Authorization: Bearer <key> desde su servidor. Su vinculación a tienda es inmutable; X-Kevmi-Store no puede otorgarle acceso a otra tienda. Las sesiones del navegador seleccionan X-Kevmi-Store: <storeId>; omitirlo selecciona la primera tienda. El valor all solo es aceptado por GET /api/account/dashboard y GET /api/payment-links. Las mutaciones requieren una tienda seleccionada, Origin y X-CSRF-Token. Los IDs de cuenta y los IDs de tienda son identificadores diferentes.",
            "Por compatibilidad, las solicitudes de API sin pricingMode=\"universal\" conservan el precio nativo y las restricciones de moneda originales. Las facturas existentes nunca se recalculan. Los recibos confirmados en análisis reflejan pagos verificados menos gastos de factura guardados; no son un saldo retirable. Las monedas de factura heredadas permanecen separadas y los pagos se gestionan con soporte. Cumpla un pedido solo después de verificar payment.fulfillmentReady=true y payment.status=\"succeeded\" a través de la API del servidor, el historial de eventos o un webhook firmado."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        }
      ],
      "body": "1. Explora el producto\n\nAbre el espacio de trabajo de demostración para crear un pedido de prueba, explora los enlaces de pago y revisa un cálculo de comisiones. La demostración utiliza datos de prueba separados. No crea un pago bancario ni transfiere fondos a una billetera.\n\nAbrir el espacio de trabajo de demostración\n\nVista previa del pago\n\n2. Crea una cuenta con Telegram\n\nDespués de iniciar sesión con Telegram, se abre la cuenta del comerciante. La incorporación web está en /account#applications; tanto el formulario como el seguimiento individual en /account#applications/{id} permanecen dentro de la aplicación.\n\nUn nuevo pago e intento de tarjeta requieren que la última solicitud de revisión web del comerciante esté aprobada. La aprobación por sí sola no conecta la pasarela de pago. Si la revisión cambia después del envío, la operación existente permanece disponible para lecturas de estado, conciliación y un código bancario solicitado.\n\nAbrir tu cuenta\n\n3. Configura tu tienda\n\nElige un nombre de tienda que tu cliente reconozca.\n\nElige una regla de IVA predeterminada. Cada factura nueva acepta por separado participaciones de comisión del cliente e IVA del 0 al 100%.\n\nSelecciona las notificaciones que deseas recibir en Telegram.\n\nUsa la calculadora para verificar el monto típico de un pedido.\n\nCalcular comisiones e IVA\n\n4. Prepara un enlace de pago\n\nIngresa un título de pedido claro, un monto y una moneda. El cliente obtiene una página dedicada con los detalles de la compra y el total a pagar. Una factura existente conserva sus términos originales cuando cambian los ajustes de tu tienda.\n\nGuía de enlaces de pago\n\n5. Verifica la disponibilidad del pago\n\nAdministra facturas, claves de API, widgets y webhooks desde tu cuenta. Antes del pago, Kevmi verifica la configuración de la pasarela, la aprobación del comerciante, el monto y los términos de la factura. Si el método seleccionado no está disponible, el pago explica el motivo.\n\nLas facturas del nuevo espacio de trabajo usan un precio base en USD y Any ofrece los cuatro métodos. SBP convierte a RUB al tipo de referencia congelado del Banco de Rusia; cripto usa la regla explícita de factura 1:1 USD/USDT. El precio nativo heredado sigue disponible para facturas antiguas y solicitudes de API sin pricingMode=universal. Consulte la sección de múltiples tiendas y precios en USD a continuación.\n\nPara un pago nuevo en vivo con tarjeta o Alipay, la pasarela actual solo admite feeCustomerPercent=0 y vatCustomerPercent=100: el comerciante cubre toda la comisión de procesamiento y el IVA se añade completo para el cliente. Otras participaciones se pueden guardar y calcular en una factura, pero la ejecución está bloqueada con unsupported_allocation. El servidor nunca cambia silenciosamente los términos guardados. Los pagos cripto SBP y USDT admiten todas las participaciones de comisión de procesamiento y no tienen IVA.\n\nCrear una factura, clave o aplicación no cobra dinero. La creación de pagos a través de la API no está disponible; los términos de retiro se cubren en una guía separada.\n\nRequisitos de integración de la pasarela\n\nMúltiples tiendas y un precio base en USD\n\nElija Todas las tiendas para análisis y operaciones agregados, o seleccione una tienda para sus propios registros. Cada tienda tiene un storeId, nombre, IVA predeterminado, facturas, claves de API, endpoints de webhook, historial de eventos y aplicación web separados. Las notificaciones y tickets de soporte pertenecen a la cuenta. Una cuenta puede crear hasta 100 tiendas. Los registros existentes permanecen en su primera tienda.\n\nLas facturas del nuevo espacio de trabajo usan pricingMode=\"universal\" y un precio base en USD. Any incluye tarjeta, alipay, sbp y cripto; un comerciante puede seleccionar un subconjunto. Tarjetas y Alipay cobran en USD. SBP cobra en RUB usando el tipo de referencia USD/RUB del Banco de Rusia. Cripto cobra USDT bajo la regla explícita de factura 1 USD = 1 USDT. Esta es una regla de conversión de factura, no una cotización de mercado de USDT. La pasarela proporciona la tasa de la moneda seleccionada, el monto exacto de transferencia y las instrucciones antes de la transferencia.\n\nEl tipo de referencia y ambos montos se congelan al crear. Las facturas que implican conversión de RUB vencen dentro de 24 horas. Si no se puede obtener el tipo de referencia, la creación falla con FX_UNAVAILABLE; no se usa ningún tipo de respaldo inventado o desactualizado. El monto en minor del propietario y las cotizaciones usan la moneda contable USD. quotes[method].settlement contiene la cotización de cargo nativa. El checkout público expone la moneda de cargo seleccionada en currency, el precio original en baseAmountMinor/baseCurrency y el tipo de referencia en fx. Una vez que un pago ha sido despachado, su método no se puede cambiar; una factura tiene una operación de pasarela.\n\nCree una clave de API dentro de la tienda prevista y envíe Authorization: Bearer <key> desde su servidor. Su vinculación a tienda es inmutable; X-Kevmi-Store no puede otorgarle acceso a otra tienda. Las sesiones del navegador seleccionan X-Kevmi-Store: <storeId>; omitirlo selecciona la primera tienda. El valor all solo es aceptado por GET /api/account/dashboard y GET /api/payment-links. Las mutaciones requieren una tienda seleccionada, Origin y X-CSRF-Token. Los IDs de cuenta y los IDs de tienda son identificadores diferentes.\n\nPor compatibilidad, las solicitudes de API sin pricingMode=\"universal\" conservan el precio nativo y las restricciones de moneda originales. Las facturas existentes nunca se recalculan. Los recibos confirmados en análisis reflejan pagos verificados menos gastos de factura guardados; no son un saldo retirable. Las monedas de factura heredadas permanecen separadas y los pagos se gestionan con soporte. Cumpla un pedido solo después de verificar payment.fulfillmentReady=true y payment.status=\"succeeded\" a través de la API del servidor, el historial de eventos o un webhook firmado.",
      "readMinutes": 3
    },
    {
      "id": "overview",
      "title": "Cómo funciona Kevmi",
      "summary": "Kevmi reúne facturas individuales, métodos de pago y reglas de precios en un solo espacio de trabajo. Cada pedido se paga por separado. No hay suscripciones ni cargos recurrentes automáticos.",
      "group": "start",
      "url": "/docs/overview",
      "tags": [
        "descripción general",
        "pagos únicos",
        "espacio de trabajo",
        "sin suscripciones"
      ],
      "sections": [
        {
          "id": "roles",
          "title": "El comerciante y el cliente",
          "paragraphs": [
            "El comerciante establece un título de pedido, precio base, moneda y asignación de impuestos. El cliente abre una página de pago dedicada, elige un método disponible y ve el total antes de confirmar.",
            "El cliente no necesita acceso al espacio de trabajo del comerciante. El pago expone los detalles de un solo pedido, no el saldo de la tienda, la configuración ni otros registros de clientes."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "channels",
          "title": "Cuatro canales de pago",
          "paragraphs": [],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Método",
              "Audiencia",
              "Comisión de aceptación"
            ],
            "rows": [
              [
                "Tarjetas internacionales",
                "Clientes internacionales",
                "10% + $0.50; 16% IVA"
              ],
              [
                "SBP",
                "Clientes en Rusia",
                "8%; sin IVA"
              ],
              [
                "Alipay",
                "Clientes en China",
                "10% + $0.50; 16% IVA"
              ],
              [
                "Criptomonedas",
                "Pagos cripto",
                "4%; sin IVA"
              ]
            ]
          },
          "code": null,
          "note": "Visa y Mastercard están disponibles en más de 190 países, excepto las restricciones publicadas. Las criptomonedas están disponibles en todos los países.",
          "links": [
            {
              "label": "Países y restricciones",
              "href": "/docs/geography"
            }
          ]
        },
        {
          "id": "workspace",
          "title": "Dentro de tu espacio de trabajo",
          "paragraphs": [
            "Los registros del servidor pertenecen a la cuenta verificada. La demostración es separada y no puede crear pagos en vivo ni un saldo retirable."
          ],
          "bullets": [
            "Enlaces de pago y términos de pedido: /account#links.",
            "Solicitudes web y seguimiento individual: /account#applications.",
            "Claves de API, webhooks, widget y eventos: /account#keys, #webhooks, #widget, #events.",
            "Precios, calculadora, mapa de países y documentación completa: /account#knowledge.",
            "Ajustes de la tienda, notificaciones de Telegram y solicitudes de soporte permanecen en la misma cuenta."
          ],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "money",
          "title": "Comprensión de los importes",
          "paragraphs": [
            "El precio base es el precio de los bienes o servicios antes de la asignación de costos. La comisión y el IVA usan esa base de forma independiente. Las partes del cliente se añaden al pago; las partes del comerciante se deducen del precio base. El IVA de tarjetas y Alipay es del 16%, con la asignación de comisión e IVA controlada por separado.",
            "La comisión de plataforma de Kevmi ya está incluida en las tarifas publicadas. No hay un recargo adicional del 5%. Un pago USDT TRC20 tiene una tarifa separada basada en la fuente de fondos y una cotización de conversión explícita."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Todas las tarifas",
              "href": "/pricing"
            }
          ]
        },
        {
          "id": "availability",
          "title": "Acceso a funciones",
          "paragraphs": [
            "Documentación, la calculadora y el asistente de documentación están disponibles sin iniciar sesión. Los ajustes de la tienda, los enlaces de pago y las solicitudes privadas de soporte requieren una cuenta. La disponibilidad financiera se verifica por separado, y un canal de pago no disponible se informa antes de un cargo."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        }
      ],
      "body": "El comerciante y el cliente\n\nEl comerciante establece un título de pedido, precio base, moneda y asignación de impuestos. El cliente abre una página de pago dedicada, elige un método disponible y ve el total antes de confirmar.\n\nEl cliente no necesita acceso al espacio de trabajo del comerciante. El pago expone los detalles de un solo pedido, no el saldo de la tienda, la configuración ni otros registros de clientes.\n\nCuatro canales de pago\n\nMétodo · Audiencia · Comisión de aceptación\nTarjetas internacionales · Clientes internacionales · 10% + $0.50; 16% IVA\nSBP · Clientes en Rusia · 8%; sin IVA\nAlipay · Clientes en China · 10% + $0.50; 16% IVA\nCriptomonedas · Pagos cripto · 4%; sin IVA\n\nVisa y Mastercard están disponibles en más de 190 países, excepto las restricciones publicadas. Las criptomonedas están disponibles en todos los países.\n\nPaíses y restricciones\n\nDentro de tu espacio de trabajo\n\nLos registros del servidor pertenecen a la cuenta verificada. La demostración es separada y no puede crear pagos en vivo ni un saldo retirable.\n\nEnlaces de pago y términos de pedido: /account#links.\n\nSolicitudes web y seguimiento individual: /account#applications.\n\nClaves de API, webhooks, widget y eventos: /account#keys, #webhooks, #widget, #events.\n\nPrecios, calculadora, mapa de países y documentación completa: /account#knowledge.\n\nAjustes de la tienda, notificaciones de Telegram y solicitudes de soporte permanecen en la misma cuenta.\n\nComprensión de los importes\n\nEl precio base es el precio de los bienes o servicios antes de la asignación de costos. La comisión y el IVA usan esa base de forma independiente. Las partes del cliente se añaden al pago; las partes del comerciante se deducen del precio base. El IVA de tarjetas y Alipay es del 16%, con la asignación de comisión e IVA controlada por separado.\n\nLa comisión de plataforma de Kevmi ya está incluida en las tarifas publicadas. No hay un recargo adicional del 5%. Un pago USDT TRC20 tiene una tarifa separada basada en la fuente de fondos y una cotización de conversión explícita.\n\nTodas las tarifas\n\nAcceso a funciones\n\nDocumentación, la calculadora y el asistente de documentación están disponibles sin iniciar sesión. Los ajustes de la tienda, los enlaces de pago y las solicitudes privadas de soporte requieren una cuenta. La disponibilidad financiera se verifica por separado, y un canal de pago no disponible se informa antes de un cargo.",
      "readMinutes": 3
    },
    {
      "id": "fees",
      "title": "Tarifas de pago y de retiro",
      "summary": "La tarifa de aceptación depende del método de pago y usa el precio base del pedido. La comisión de Kevmi está incluida. El IVA y las tarifas de retiro se muestran por separado.",
      "group": "payments",
      "url": "/docs/fees",
      "tags": [
        "tarifas",
        "precios",
        "costo",
        "retiro",
        "comisión"
      ],
      "sections": [
        {
          "id": "incoming",
          "title": "Aceptar un pago",
          "paragraphs": [
            "Suma los componentes porcentuales y fijos. Para un pedido de tarjeta de $5, la tarifa es $0.50 + $0.50 = $1. El IVA es $0.80 y es separado de esta tarifa.",
            "La parte de la plataforma, aproximadamente el 5% en promedio, ya está incorporada en estos términos. No agregues un segundo porcentaje de plataforma."
          ],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Método",
              "Porcentaje",
              "Tarifa fija",
              "VAT"
            ],
            "rows": [
              [
                "Tarjetas internacionales",
                "10%",
                "$0.50",
                "16% del precio base"
              ],
              [
                "Alipay",
                "10%",
                "$0.50",
                "16% del precio base"
              ],
              [
                "SBP",
                "8%",
                "Ninguna",
                "Ninguna"
              ],
              [
                "Criptomonedas",
                "4%",
                "Ninguna",
                "Ninguna"
              ]
            ]
          },
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "payout",
          "title": "Retirar fondos",
          "paragraphs": [
            "La fuente de fondos y la red de retiro son ajustes separados. Usar TRC20 no hace que todas las tarifas de retiro sean iguales. La tarifa de retiro es separada de la tarifa de aceptación.",
            "Mantén la tarifa fija en su moneda indicada. No deduzcas RUB 400 de un importe en USD ni asumas que $3 equivale a 3 USDT. El retiro final requiere una cotización de conversión explícita."
          ],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Fuente de fondos",
              "Tarifa de retiro",
              "Destino"
            ],
            "rows": [
              [
                "Tarjetas",
                "4%",
                "USDT TRC20"
              ],
              [
                "Alipay",
                "4%",
                "USDT TRC20"
              ],
              [
                "SBP",
                "5% + RUB 400",
                "USDT TRC20"
              ],
              [
                "Criptomonedas",
                "0% + $3",
                "USDT TRC20"
              ]
            ]
          },
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "rounding",
          "title": "Precisión de cálculo",
          "paragraphs": [
            "El importe menor de la factura es un entero: 500 significa 5.00 USD, RUB o USDT en la moneda explícitamente indicada. Estas son unidades de cálculo de factura; USD y USDT no se convierten automáticamente. Las tarifas y el IVA usan redondeo por separado hacia arriba en el punto medio.",
            "Para una transferencia cripto, usa el importe decimal exacto de la moneda y la red devueltos por la operación creada. No derives el importe de la transferencia del precio de factura redondeado. Un cálculo no puede producir ganancias negativas para el comerciante."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": {
            "language": "Formula",
            "code": "feeMinor = roundHalfUp(baseMinor × rate / 100) + fixedMinor\nvatMinor = roundHalfUp(baseMinor × 16 / 100)\n// For SBP and cryptocurrency, vatMinor = 0"
          },
          "note": "",
          "links": []
        },
        {
          "id": "before-pay",
          "title": "Verifica antes de pagar",
          "paragraphs": [],
          "bullets": [
            "El importe original del pedido y su moneda.",
            "El método de pago, que determina la tarifa y si aplica el IVA.",
            "El pagador de IVA guardado con la factura.",
            "El total del cliente y el crédito esperado del comerciante."
          ],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Calcula tu importe",
              "href": "/pricing"
            },
            {
              "label": "Comprende el IVA",
              "href": "/docs/vat"
            }
          ]
        }
      ],
      "body": "Aceptar un pago\n\nSuma los componentes porcentuales y fijos. Para un pedido de tarjeta de $5, la tarifa es $0.50 + $0.50 = $1. El IVA es $0.80 y es separado de esta tarifa.\n\nLa parte de la plataforma, aproximadamente el 5% en promedio, ya está incorporada en estos términos. No agregues un segundo porcentaje de plataforma.\n\nMétodo · Porcentaje · Tarifa fija · VAT\nTarjetas internacionales · 10% · $0.50 · 16% del precio base\nAlipay · 10% · $0.50 · 16% del precio base\nSBP · 8% · Ninguna · Ninguna\nCriptomonedas · 4% · Ninguna · Ninguna\n\nRetirar fondos\n\nLa fuente de fondos y la red de retiro son ajustes separados. Usar TRC20 no hace que todas las tarifas de retiro sean iguales. La tarifa de retiro es separada de la tarifa de aceptación.\n\nMantén la tarifa fija en su moneda indicada. No deduzcas RUB 400 de un importe en USD ni asumas que $3 equivale a 3 USDT. El retiro final requiere una cotización de conversión explícita.\n\nFuente de fondos · Tarifa de retiro · Destino\nTarjetas · 4% · USDT TRC20\nAlipay · 4% · USDT TRC20\nSBP · 5% + RUB 400 · USDT TRC20\nCriptomonedas · 0% + $3 · USDT TRC20\n\nPrecisión de cálculo\n\nEl importe menor de la factura es un entero: 500 significa 5.00 USD, RUB o USDT en la moneda explícitamente indicada. Estas son unidades de cálculo de factura; USD y USDT no se convierten automáticamente. Las tarifas y el IVA usan redondeo por separado hacia arriba en el punto medio.\n\nPara una transferencia cripto, usa el importe decimal exacto de la moneda y la red devueltos por la operación creada. No derives el importe de la transferencia del precio de factura redondeado. Un cálculo no puede producir ganancias negativas para el comerciante.\n\nfeeMinor = roundHalfUp(baseMinor × rate / 100) + fixedMinor\nvatMinor = roundHalfUp(baseMinor × 16 / 100)\n// For SBP and cryptocurrency, vatMinor = 0\n\nVerifica antes de pagar\n\nEl importe original del pedido y su moneda.\n\nEl método de pago, que determina la tarifa y si aplica el IVA.\n\nEl pagador de IVA guardado con la factura.\n\nEl total del cliente y el crédito esperado del comerciante.\n\nCalcula tu importe\n\nComprende el IVA",
      "readMinutes": 3
    },
    {
      "id": "vat",
      "title": "IVA y asignación de costos",
      "summary": "El IVA es el 16% del precio base del pedido para tarjetas internacionales y Alipay. El comerciante establece una parte del cliente de 0 a 100% y cubre el resto con los ingresos. SBP y criptomonedas no tienen IVA bajo estos términos publicados.",
      "group": "payments",
      "url": "/docs/vat",
      "tags": [
        "VAT",
        "impuesto",
        "cliente",
        "comerciante",
        "cinco dólares"
      ],
      "sections": [
        {
          "id": "base",
          "title": "Una sola base para tarifas e impuestos",
          "paragraphs": [
            "El precio base es el importe del pedido ingresado por la tienda. La tarifa de 10% + $0.50 y el IVA del 16% se calculan de forma independiente a partir de este precio. La tarifa no se aplica al IVA que se añade encima.",
            "Con un precio base de $5, la tarifa es $1 y el IVA es $0.80. Cambiar el pagador cambia la asignación, no la tasa impositiva ni su base de cálculo."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "customer",
          "title": "El cliente paga el IVA",
          "paragraphs": [
            "Esta es la regla predeterminada de IVA: una parte del cliente del 100%, equivalente al valor heredado del cliente. El comerciante cubre toda la tarifa en este ejemplo. El IVA se añade al precio base. El pago muestra el precio del pedido, el IVA y el total adeudado.",
            "Solo la tarifa de aceptación se deduce del precio base. Para un pedido de $5, el cliente paga $5.80 y el comerciante recibe $4."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": {
            "language": "Formula",
            "code": "customerTotalMinor = baseMinor + vatMinor\nmerchantNetMinor = baseMinor - feeMinor"
          },
          "note": "",
          "links": []
        },
        {
          "id": "merchant",
          "title": "El comerciante paga el IVA",
          "paragraphs": [
            "En este ejemplo, las partes del cliente son 0% tanto para el IVA como para la tarifa. El valor heredado de IVA del comerciante corresponde a una parte de cliente de cero para el IVA; el comerciante cubre ambos costos del precio base.",
            "Para un pedido de $5, el cliente paga $5, la tarifa es $1, el IVA es $0.80 y el comerciante recibe $3.20. El IVA sigue siendo el 16% del precio base; no reemplaces esta regla con una fórmula de 16/116."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": {
            "language": "Formula",
            "code": "customerTotalMinor = baseMinor\nmerchantNetMinor = baseMinor - feeMinor - vatMinor"
          },
          "note": "",
          "links": []
        },
        {
          "id": "comparison",
          "title": "Un ejemplo lado a lado",
          "paragraphs": [],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Importe",
              "El cliente paga el IVA",
              "El comerciante paga el IVA"
            ],
            "rows": [
              [
                "Precio base del pedido",
                "$5.00",
                "$5.00"
              ],
              [
                "Comisión de aceptación",
                "$1.00",
                "$1.00"
              ],
              [
                "VAT",
                "$0.80",
                "$0.80"
              ],
              [
                "El cliente paga",
                "$5.80",
                "$5.00"
              ],
              [
                "El comerciante recibe",
                "$4.00",
                "$3.20"
              ]
            ]
          },
          "code": null,
          "note": "Ambas columnas suponen una participación del 0% en la tarifa de procesamiento del cliente. Las participaciones intermedias de IVA y la asignación separada de tarifas están disponibles en la calculadora.",
          "links": []
        },
        {
          "id": "snapshot",
          "title": "Cuando se aplica la configuración",
          "paragraphs": [
            "La preferencia de la tienda proporciona la asignación inicial. La interfaz y la API guardan participaciones independientes de IVA del cliente y de tarifas de procesamiento de 0 a 100 para cada factura. Los cambios en la configuración de la tienda no recalculan las facturas emitidas.",
            "Para un pago nuevo en vivo con tarjeta o Alipay, la pasarela actual solo admite feeCustomerPercent=0 y vatCustomerPercent=100: el comerciante cubre toda la comisión de procesamiento y el IVA se añade completo para el cliente. Otras participaciones se pueden guardar y calcular en una factura, pero la ejecución está bloqueada con unsupported_allocation. El servidor nunca cambia silenciosamente los términos guardados. Los pagos cripto SBP y USDT admiten todas las participaciones de comisión de procesamiento y no tienen IVA.",
            "Cree un nuevo enlace para condiciones diferentes. El IVA es cero para SBP y criptomonedas."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Configuración de la tienda",
              "href": "/docs/settings"
            },
            {
              "label": "Verifique el cálculo",
              "href": "/pricing"
            },
            {
              "label": "Dividir las tarifas de procesamiento y el IVA",
              "href": "/docs/cost-sharing"
            }
          ]
        }
      ],
      "body": "Una sola base para tarifas e impuestos\n\nEl precio base es el importe del pedido ingresado por la tienda. La tarifa de 10% + $0.50 y el IVA del 16% se calculan de forma independiente a partir de este precio. La tarifa no se aplica al IVA que se añade encima.\n\nCon un precio base de $5, la tarifa es $1 y el IVA es $0.80. Cambiar el pagador cambia la asignación, no la tasa impositiva ni su base de cálculo.\n\nEl cliente paga el IVA\n\nEsta es la regla predeterminada de IVA: una parte del cliente del 100%, equivalente al valor heredado del cliente. El comerciante cubre toda la tarifa en este ejemplo. El IVA se añade al precio base. El pago muestra el precio del pedido, el IVA y el total adeudado.\n\nSolo la tarifa de aceptación se deduce del precio base. Para un pedido de $5, el cliente paga $5.80 y el comerciante recibe $4.\n\ncustomerTotalMinor = baseMinor + vatMinor\nmerchantNetMinor = baseMinor - feeMinor\n\nEl comerciante paga el IVA\n\nEn este ejemplo, las partes del cliente son 0% tanto para el IVA como para la tarifa. El valor heredado de IVA del comerciante corresponde a una parte de cliente de cero para el IVA; el comerciante cubre ambos costos del precio base.\n\nPara un pedido de $5, el cliente paga $5, la tarifa es $1, el IVA es $0.80 y el comerciante recibe $3.20. El IVA sigue siendo el 16% del precio base; no reemplaces esta regla con una fórmula de 16/116.\n\ncustomerTotalMinor = baseMinor\nmerchantNetMinor = baseMinor - feeMinor - vatMinor\n\nUn ejemplo lado a lado\n\nImporte · El cliente paga el IVA · El comerciante paga el IVA\nPrecio base del pedido · $5.00 · $5.00\nComisión de aceptación · $1.00 · $1.00\nVAT · $0.80 · $0.80\nEl cliente paga · $5.80 · $5.00\nEl comerciante recibe · $4.00 · $3.20\n\nAmbas columnas suponen una participación del 0% en la tarifa de procesamiento del cliente. Las participaciones intermedias de IVA y la asignación separada de tarifas están disponibles en la calculadora.\n\nCuando se aplica la configuración\n\nLa preferencia de la tienda proporciona la asignación inicial. La interfaz y la API guardan participaciones independientes de IVA del cliente y de tarifas de procesamiento de 0 a 100 para cada factura. Los cambios en la configuración de la tienda no recalculan las facturas emitidas.\n\nPara un pago nuevo en vivo con tarjeta o Alipay, la pasarela actual solo admite feeCustomerPercent=0 y vatCustomerPercent=100: el comerciante cubre toda la comisión de procesamiento y el IVA se añade completo para el cliente. Otras participaciones se pueden guardar y calcular en una factura, pero la ejecución está bloqueada con unsupported_allocation. El servidor nunca cambia silenciosamente los términos guardados. Los pagos cripto SBP y USDT admiten todas las participaciones de comisión de procesamiento y no tienen IVA.\n\nCree un nuevo enlace para condiciones diferentes. El IVA es cero para SBP y criptomonedas.\n\nConfiguración de la tienda\n\nVerifique el cálculo\n\nDividir las tarifas de procesamiento y el IVA",
      "readMinutes": 4
    },
    {
      "id": "geography",
      "title": "Países y métodos de pago",
      "summary": "Visa y Mastercard cubren más de 190 países, excepto las restricciones publicadas. SBP atiende a Rusia, Alipay atiende a China y las criptomonedas están disponibles en todo el mundo.",
      "group": "payments",
      "url": "/docs/geography",
      "tags": [
        "países",
        "cobertura",
        "190+",
        "Rusia",
        "China",
        "Islas Åland",
        "Albania",
        "Argelia",
        "Samoa Americana",
        "Andorra",
        "Angola",
        "Anguila",
        "Antigua y Barbuda",
        "Argentina",
        "Armenia",
        "Aruba",
        "Australia",
        "Austria",
        "Azerbaiyán",
        "Bahamas",
        "Baréin",
        "Bangladesh",
        "Barbados",
        "Bélgica",
        "Belice",
        "Benín",
        "Bermudas",
        "Bután",
        "Bolivia",
        "Caribe Neerlandés",
        "Bosnia y Herzegovina",
        "Botsuana",
        "Isla Bouvet",
        "Brasil",
        "Territorio Británico del Océano Índico",
        "Brunéi",
        "Bulgaria",
        "Burkina Faso",
        "Cabo Verde",
        "Camboya",
        "Camerún",
        "Canadá",
        "Islas Caimán",
        "Chile",
        "China",
        "Isla de Navidad",
        "Islas Cocos (Keeling)",
        "Colombia",
        "Comoras",
        "Islas Cook",
        "Costa Rica",
        "Croacia",
        "Curazao",
        "Chipre",
        "Chequia",
        "Costa de Marfil",
        "Dinamarca",
        "Yibuti",
        "Dominica",
        "República Dominicana",
        "Ecuador",
        "Egipto",
        "El Salvador",
        "Guinea Ecuatorial",
        "Estonia",
        "Esuatini",
        "Etiopía",
        "Islas Malvinas",
        "Islas Feroe",
        "Micronesia",
        "Fiyi",
        "Finlandia",
        "Francia",
        "Guayana Francesa",
        "Polinesia Francesa",
        "Territorios Australes Franceses",
        "Gabón",
        "Gambia",
        "Georgia",
        "Alemania",
        "Ghana",
        "Gibraltar",
        "Grecia",
        "Groenlandia",
        "Granada",
        "Guadalupe",
        "Guam",
        "Guatemala",
        "Guernsey",
        "Guinea",
        "Guinea-Bisáu",
        "Guyana",
        "Islas Heard y McDonald",
        "Ciudad del Vaticano",
        "Honduras",
        "RAE de Hong Kong (China)",
        "Hungría",
        "Islandia",
        "India",
        "Indonesia",
        "Irlanda",
        "Isla de Man",
        "Israel",
        "Italia",
        "Jamaica",
        "Japón",
        "Jersey",
        "Jordania",
        "Kazajistán",
        "Kenia",
        "Kiribati",
        "Kuwait",
        "Kirguistán",
        "Laos",
        "Letonia",
        "Líbano",
        "Lesoto",
        "Liberia",
        "Liechtenstein",
        "Lituania",
        "Luxemburgo",
        "Macao RAE China",
        "Madagascar",
        "Malaui",
        "Malasia",
        "Maldivas",
        "Malta",
        "Islas Marshall",
        "Martinica",
        "Mauritania",
        "Mauricio",
        "Mayotte",
        "México",
        "Moldavia",
        "Mónaco",
        "Mongolia",
        "Montenegro",
        "Montserrat",
        "Marruecos",
        "Mozambique",
        "Namibia",
        "Nauru",
        "Nepal",
        "Países Bajos",
        "Nueva Caledonia",
        "Nueva Zelanda",
        "Níger",
        "Nigeria",
        "Niue",
        "Isla Norfolk",
        "Macedonia del Norte",
        "Islas Marianas del Norte",
        "Noruega",
        "Omán",
        "Pakistán",
        "Palaos",
        "Panamá",
        "Papúa Nueva Guinea",
        "Paraguay",
        "Perú",
        "Filipinas",
        "Islas Pitcairn",
        "Polonia",
        "Portugal",
        "Puerto Rico",
        "Catar",
        "Rumania",
        "Ruanda",
        "Reunión",
        "San Bartolomé",
        "Santa Elena",
        "San Cristóbal y Nieves",
        "Santa Lucía",
        "San Martín",
        "San Pedro y Miquelón",
        "San Vicente y las Granadinas",
        "Samoa",
        "San Marino",
        "Santo Tomé y Príncipe",
        "Arabia Saudita",
        "Senegal",
        "Serbia",
        "Seychelles",
        "Sierra Leona",
        "Singapur",
        "Sint Maarten",
        "Eslovaquia",
        "Eslovenia",
        "Islas Salomón",
        "Sudáfrica",
        "Georgia del Sur e Islas Sandwich del Sur",
        "Corea del Sur",
        "España",
        "Sri Lanka",
        "Territorios Palestinos",
        "Surinam",
        "Svalbard y Jan Mayen",
        "Suecia",
        "Suiza",
        "Taiwán",
        "Tayikistán",
        "Tanzania",
        "Tailandia",
        "Timor Oriental",
        "Togo",
        "Tokelau",
        "Tonga",
        "Trinidad y Tobago",
        "Túnez",
        "Turkmenistán",
        "Islas Turcas y Caicos",
        "Tuvalu",
        "Turquía",
        "Uganda",
        "Ucrania",
        "Emiratos Árabes Unidos",
        "Reino Unido",
        "Islas Periféricas de EE. UU.",
        "Estados Unidos",
        "Uruguay",
        "Uzbekistán",
        "Vanuatu",
        "Vietnam",
        "Islas Vírgenes Británicas",
        "Islas Vírgenes de EE. UU.",
        "Wallis y Futuna",
        "Sáhara Occidental",
        "Zambia"
      ],
      "sections": [
        {
          "id": "coverage",
          "title": "Cobertura por canal",
          "paragraphs": [],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Canal",
              "Cobertura",
              "Condiciones"
            ],
            "rows": [
              [
                "Tarjetas internacionales",
                "Más de 190 países",
                "Excepto la lista de restricciones y cinco regiones de Ucrania"
              ],
              [
                "SBP",
                "Rusia",
                "La disponibilidad depende del banco y de la transacción"
              ],
              [
                "Alipay",
                "China",
                "La disponibilidad depende de la cuenta y de la transacción"
              ],
              [
                "Criptomonedas",
                "Todos los países",
                "Elige una moneda compatible y una red"
              ]
            ]
          },
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "map",
          "title": "El mapa interactivo",
          "paragraphs": [
            "La página de Geografía tiene un mapa mundial bidimensional. Los filtros destacan los países con tarjetas internacionales publicados, Rusia para SBP y China para Alipay. Busca por nombre de país o código ISO para ver sus métodos y notas.",
            "El rayado marca Ucrania porque cinco regiones están excluidas de las tarjetas. El resto de Ucrania está disponible. Las restricciones de tarjetas no se aplican a las criptomonedas, que están disponibles en todos los países."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Abrir el mapa",
              "href": "/countries"
            }
          ]
        },
        {
          "id": "cards",
          "title": "Qué cubre la lista",
          "paragraphs": [
            "La lista completa a continuación describe la cobertura de tarjetas internacionales. Los países de registro del comerciante y los destinos de pago tienen condiciones separadas.",
            "La aprobación depende del país emisor, el banco, el tipo de tarjeta y las verificaciones del canal de pago. Que un país figure en la lista no garantiza la aprobación de cada tarjeta o transacción."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "restrictions",
          "title": "Restricciones de Visa y Mastercard",
          "paragraphs": [
            "Las tarjetas no están disponibles en Crimea, Donetsk, Luhansk, Jersón y Zaporiyia. El resto de Ucrania está disponible.",
            "Todos los demás países están disponibles. Antillas Neerlandesas se conserva como entrada histórica de la lista del proveedor; no bloquea ningún territorio caribeño moderno."
          ],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Código",
              "País o territorio"
            ],
            "rows": [
              [
                "AF",
                "Afganistán"
              ],
              [
                "AQ",
                "Antártida"
              ],
              [
                "BY",
                "Bielorrusia"
              ],
              [
                "MM",
                "Birmania (Myanmar)"
              ],
              [
                "BI",
                "Burundi"
              ],
              [
                "CF",
                "República Centroafricana"
              ],
              [
                "TD",
                "Chad"
              ],
              [
                "CU",
                "Cuba"
              ],
              [
                "CD",
                "República Democrática del Congo"
              ],
              [
                "CG",
                "República del Congo"
              ],
              [
                "ER",
                "Eritrea"
              ],
              [
                "HT",
                "Haití"
              ],
              [
                "IR",
                "Irán"
              ],
              [
                "IQ",
                "Irak"
              ],
              [
                "LY",
                "Libia"
              ],
              [
                "ML",
                "Malí"
              ],
              [
                "NI",
                "Nicaragua"
              ],
              [
                "KP",
                "Corea del Norte"
              ],
              [
                "RU",
                "Rusia"
              ],
              [
                "SO",
                "Somalia"
              ],
              [
                "SS",
                "Sudán del Sur"
              ],
              [
                "SD",
                "Sudán"
              ],
              [
                "SY",
                "Siria"
              ],
              [
                "VE",
                "Venezuela"
              ],
              [
                "YE",
                "Yemen"
              ],
              [
                "ZW",
                "Zimbabue"
              ],
              [
                "UA-43",
                "Crimea (Región de Ucrania)"
              ],
              [
                "UA-14",
                "Donetsk (Región de Ucrania)"
              ],
              [
                "UA-65",
                "Jersón (Región de Ucrania)"
              ],
              [
                "UA-09",
                "Luhansk (Región de Ucrania)"
              ],
              [
                "UA-23",
                "Zaporiyia (Región de Ucrania)"
              ],
              [
                "AN",
                "Antillas Neerlandesas"
              ]
            ]
          },
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "card-list",
          "title": "Directorio de países y territorios",
          "paragraphs": [
            "Los nombres, los códigos ISO y los marcadores provienen del registro de países compartido. Estas notas se aplican a las tarjetas internacionales."
          ],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "ISO",
              "País o territorio",
              "Nota"
            ],
            "rows": [
              [
                "AX",
                "Islas Åland",
                "—"
              ],
              [
                "AL",
                "Albania",
                "—"
              ],
              [
                "DZ",
                "Argelia",
                "—"
              ],
              [
                "AS",
                "Samoa Americana",
                "—"
              ],
              [
                "AD",
                "Andorra",
                "—"
              ],
              [
                "AO",
                "Angola",
                "—"
              ],
              [
                "AI",
                "Anguila",
                "—"
              ],
              [
                "AG",
                "Antigua y Barbuda",
                "—"
              ],
              [
                "AR",
                "Argentina",
                "—"
              ],
              [
                "AM",
                "Armenia",
                "—"
              ],
              [
                "AW",
                "Aruba",
                "—"
              ],
              [
                "AU",
                "Australia",
                "—"
              ],
              [
                "AT",
                "Austria",
                "—"
              ],
              [
                "AZ",
                "Azerbaiyán",
                "—"
              ],
              [
                "BS",
                "Bahamas",
                "—"
              ],
              [
                "BH",
                "Baréin",
                "—"
              ],
              [
                "BD",
                "Bangladesh",
                "—"
              ],
              [
                "BB",
                "Barbados",
                "—"
              ],
              [
                "BE",
                "Bélgica",
                "—"
              ],
              [
                "BZ",
                "Belice",
                "—"
              ],
              [
                "BJ",
                "Benín",
                "—"
              ],
              [
                "BM",
                "Bermudas",
                "—"
              ],
              [
                "BT",
                "Bután",
                "—"
              ],
              [
                "BO",
                "Bolivia",
                "—"
              ],
              [
                "BQ",
                "Caribe Neerlandés",
                "—"
              ],
              [
                "BA",
                "Bosnia y Herzegovina",
                "—"
              ],
              [
                "BW",
                "Botsuana",
                "—"
              ],
              [
                "BV",
                "Isla Bouvet",
                "—"
              ],
              [
                "BR",
                "Brasil",
                "—"
              ],
              [
                "IO",
                "Territorio Británico del Océano Índico",
                "—"
              ],
              [
                "BN",
                "Brunéi",
                "—"
              ],
              [
                "BG",
                "Bulgaria",
                "—"
              ],
              [
                "BF",
                "Burkina Faso",
                "—"
              ],
              [
                "CV",
                "Cabo Verde",
                "—"
              ],
              [
                "KH",
                "Camboya",
                "—"
              ],
              [
                "CM",
                "Camerún",
                "—"
              ],
              [
                "CA",
                "Canadá",
                "—"
              ],
              [
                "KY",
                "Islas Caimán",
                "—"
              ],
              [
                "CL",
                "Chile",
                "—"
              ],
              [
                "CN",
                "China",
                "—"
              ],
              [
                "CX",
                "Isla de Navidad",
                "—"
              ],
              [
                "CC",
                "Islas Cocos (Keeling)",
                "—"
              ],
              [
                "CO",
                "Colombia",
                "—"
              ],
              [
                "KM",
                "Comoras",
                "—"
              ],
              [
                "CK",
                "Islas Cook",
                "—"
              ],
              [
                "CR",
                "Costa Rica",
                "—"
              ],
              [
                "HR",
                "Croacia",
                "—"
              ],
              [
                "CW",
                "Curazao",
                "—"
              ],
              [
                "CY",
                "Chipre",
                "—"
              ],
              [
                "CZ",
                "Chequia",
                "—"
              ],
              [
                "CI",
                "Costa de Marfil",
                "—"
              ],
              [
                "DK",
                "Dinamarca",
                "—"
              ],
              [
                "DJ",
                "Yibuti",
                "—"
              ],
              [
                "DM",
                "Dominica",
                "—"
              ],
              [
                "DO",
                "República Dominicana",
                "—"
              ],
              [
                "EC",
                "Ecuador",
                "—"
              ],
              [
                "EG",
                "Egipto",
                "—"
              ],
              [
                "SV",
                "El Salvador",
                "—"
              ],
              [
                "GQ",
                "Guinea Ecuatorial",
                "—"
              ],
              [
                "EE",
                "Estonia",
                "—"
              ],
              [
                "SZ",
                "Esuatini",
                "—"
              ],
              [
                "ET",
                "Etiopía",
                "—"
              ],
              [
                "FK",
                "Islas Malvinas",
                "—"
              ],
              [
                "FO",
                "Islas Feroe",
                "—"
              ],
              [
                "FM",
                "Micronesia",
                "—"
              ],
              [
                "FJ",
                "Fiyi",
                "—"
              ],
              [
                "FI",
                "Finlandia",
                "—"
              ],
              [
                "FR",
                "Francia",
                "—"
              ],
              [
                "GF",
                "Guayana Francesa",
                "—"
              ],
              [
                "PF",
                "Polinesia Francesa",
                "—"
              ],
              [
                "TF",
                "Territorios Australes Franceses",
                "—"
              ],
              [
                "GA",
                "Gabón",
                "—"
              ],
              [
                "GM",
                "Gambia",
                "—"
              ],
              [
                "GE",
                "Georgia",
                "—"
              ],
              [
                "DE",
                "Alemania",
                "—"
              ],
              [
                "GH",
                "Ghana",
                "—"
              ],
              [
                "GI",
                "Gibraltar",
                "—"
              ],
              [
                "GR",
                "Grecia",
                "—"
              ],
              [
                "GL",
                "Groenlandia",
                "—"
              ],
              [
                "GD",
                "Granada",
                "—"
              ],
              [
                "GP",
                "Guadalupe",
                "—"
              ],
              [
                "GU",
                "Guam",
                "—"
              ],
              [
                "GT",
                "Guatemala",
                "—"
              ],
              [
                "GG",
                "Guernsey",
                "—"
              ],
              [
                "GN",
                "Guinea",
                "—"
              ],
              [
                "GW",
                "Guinea-Bisáu",
                "—"
              ],
              [
                "GY",
                "Guyana",
                "—"
              ],
              [
                "HM",
                "Islas Heard y McDonald",
                "—"
              ],
              [
                "VA",
                "Ciudad del Vaticano",
                "—"
              ],
              [
                "HN",
                "Honduras",
                "—"
              ],
              [
                "HK",
                "RAE de Hong Kong (China)",
                "—"
              ],
              [
                "HU",
                "Hungría",
                "—"
              ],
              [
                "IS",
                "Islandia",
                "—"
              ],
              [
                "IN",
                "India",
                "—"
              ],
              [
                "ID",
                "Indonesia",
                "—"
              ],
              [
                "IE",
                "Irlanda",
                "—"
              ],
              [
                "IM",
                "Isla de Man",
                "—"
              ],
              [
                "IL",
                "Israel",
                "—"
              ],
              [
                "IT",
                "Italia",
                "—"
              ],
              [
                "JM",
                "Jamaica",
                "—"
              ],
              [
                "JP",
                "Japón",
                "—"
              ],
              [
                "JE",
                "Jersey",
                "—"
              ],
              [
                "JO",
                "Jordania",
                "—"
              ],
              [
                "KZ",
                "Kazajistán",
                "—"
              ],
              [
                "KE",
                "Kenia",
                "—"
              ],
              [
                "KI",
                "Kiribati",
                "—"
              ],
              [
                "KW",
                "Kuwait",
                "—"
              ],
              [
                "KG",
                "Kirguistán",
                "—"
              ],
              [
                "LA",
                "Laos",
                "—"
              ],
              [
                "LV",
                "Letonia",
                "—"
              ],
              [
                "LB",
                "Líbano",
                "—"
              ],
              [
                "LS",
                "Lesoto",
                "—"
              ],
              [
                "LR",
                "Liberia",
                "—"
              ],
              [
                "LI",
                "Liechtenstein",
                "—"
              ],
              [
                "LT",
                "Lituania",
                "—"
              ],
              [
                "LU",
                "Luxemburgo",
                "—"
              ],
              [
                "MO",
                "Macao RAE China",
                "—"
              ],
              [
                "MG",
                "Madagascar",
                "—"
              ],
              [
                "MW",
                "Malaui",
                "—"
              ],
              [
                "MY",
                "Malasia",
                "—"
              ],
              [
                "MV",
                "Maldivas",
                "—"
              ],
              [
                "MT",
                "Malta",
                "—"
              ],
              [
                "MH",
                "Islas Marshall",
                "—"
              ],
              [
                "MQ",
                "Martinica",
                "—"
              ],
              [
                "MR",
                "Mauritania",
                "—"
              ],
              [
                "MU",
                "Mauricio",
                "—"
              ],
              [
                "YT",
                "Mayotte",
                "—"
              ],
              [
                "MX",
                "México",
                "—"
              ],
              [
                "MD",
                "Moldavia",
                "—"
              ],
              [
                "MC",
                "Mónaco",
                "—"
              ],
              [
                "MN",
                "Mongolia",
                "—"
              ],
              [
                "ME",
                "Montenegro",
                "—"
              ],
              [
                "MS",
                "Montserrat",
                "—"
              ],
              [
                "MA",
                "Marruecos",
                "—"
              ],
              [
                "MZ",
                "Mozambique",
                "—"
              ],
              [
                "NA",
                "Namibia",
                "—"
              ],
              [
                "NR",
                "Nauru",
                "—"
              ],
              [
                "NP",
                "Nepal",
                "—"
              ],
              [
                "NL",
                "Países Bajos",
                "—"
              ],
              [
                "NC",
                "Nueva Caledonia",
                "—"
              ],
              [
                "NZ",
                "Nueva Zelanda",
                "—"
              ],
              [
                "NE",
                "Níger",
                "—"
              ],
              [
                "NG",
                "Nigeria",
                "—"
              ],
              [
                "NU",
                "Niue",
                "—"
              ],
              [
                "NF",
                "Isla Norfolk",
                "—"
              ],
              [
                "MK",
                "Macedonia del Norte",
                "—"
              ],
              [
                "MP",
                "Islas Marianas del Norte",
                "—"
              ],
              [
                "NO",
                "Noruega",
                "—"
              ],
              [
                "OM",
                "Omán",
                "—"
              ],
              [
                "PK",
                "Pakistán",
                "—"
              ],
              [
                "PW",
                "Palaos",
                "—"
              ],
              [
                "PA",
                "Panamá",
                "—"
              ],
              [
                "PG",
                "Papúa Nueva Guinea",
                "—"
              ],
              [
                "PY",
                "Paraguay",
                "—"
              ],
              [
                "PE",
                "Perú",
                "—"
              ],
              [
                "PH",
                "Filipinas",
                "—"
              ],
              [
                "PN",
                "Islas Pitcairn",
                "—"
              ],
              [
                "PL",
                "Polonia",
                "—"
              ],
              [
                "PT",
                "Portugal",
                "—"
              ],
              [
                "PR",
                "Puerto Rico",
                "—"
              ],
              [
                "QA",
                "Catar",
                "—"
              ],
              [
                "RO",
                "Rumania",
                "—"
              ],
              [
                "RW",
                "Ruanda",
                "—"
              ],
              [
                "RE",
                "Reunión",
                "—"
              ],
              [
                "BL",
                "San Bartolomé",
                "—"
              ],
              [
                "SH",
                "Santa Elena",
                "—"
              ],
              [
                "KN",
                "San Cristóbal y Nieves",
                "—"
              ],
              [
                "LC",
                "Santa Lucía",
                "—"
              ],
              [
                "MF",
                "San Martín",
                "—"
              ],
              [
                "PM",
                "San Pedro y Miquelón",
                "—"
              ],
              [
                "VC",
                "San Vicente y las Granadinas",
                "—"
              ],
              [
                "WS",
                "Samoa",
                "—"
              ],
              [
                "SM",
                "San Marino",
                "—"
              ],
              [
                "ST",
                "Santo Tomé y Príncipe",
                "—"
              ],
              [
                "SA",
                "Arabia Saudita",
                "—"
              ],
              [
                "SN",
                "Senegal",
                "—"
              ],
              [
                "RS",
                "Serbia",
                "—"
              ],
              [
                "SC",
                "Seychelles",
                "—"
              ],
              [
                "SL",
                "Sierra Leona",
                "—"
              ],
              [
                "SG",
                "Singapur",
                "—"
              ],
              [
                "SX",
                "Sint Maarten",
                "—"
              ],
              [
                "SK",
                "Eslovaquia",
                "—"
              ],
              [
                "SI",
                "Eslovenia",
                "—"
              ],
              [
                "SB",
                "Islas Salomón",
                "—"
              ],
              [
                "ZA",
                "Sudáfrica",
                "—"
              ],
              [
                "GS",
                "Georgia del Sur e Islas Sandwich del Sur",
                "—"
              ],
              [
                "KR",
                "Corea del Sur",
                "—"
              ],
              [
                "ES",
                "España",
                "—"
              ],
              [
                "LK",
                "Sri Lanka",
                "—"
              ],
              [
                "PS",
                "Territorios Palestinos",
                "—"
              ],
              [
                "SR",
                "Surinam",
                "—"
              ],
              [
                "SJ",
                "Svalbard y Jan Mayen",
                "—"
              ],
              [
                "SE",
                "Suecia",
                "—"
              ],
              [
                "CH",
                "Suiza",
                "—"
              ],
              [
                "TW",
                "Taiwán",
                "—"
              ],
              [
                "TJ",
                "Tayikistán",
                "—"
              ],
              [
                "TZ",
                "Tanzania",
                "—"
              ],
              [
                "TH",
                "Tailandia",
                "—"
              ],
              [
                "TL",
                "Timor Oriental",
                "—"
              ],
              [
                "TG",
                "Togo",
                "—"
              ],
              [
                "TK",
                "Tokelau",
                "—"
              ],
              [
                "TO",
                "Tonga",
                "—"
              ],
              [
                "TT",
                "Trinidad y Tobago",
                "—"
              ],
              [
                "TN",
                "Túnez",
                "—"
              ],
              [
                "TM",
                "Turkmenistán",
                "—"
              ],
              [
                "TC",
                "Islas Turcas y Caicos",
                "—"
              ],
              [
                "TV",
                "Tuvalu",
                "—"
              ],
              [
                "TR",
                "Turquía",
                "—"
              ],
              [
                "UG",
                "Uganda",
                "—"
              ],
              [
                "UA",
                "Ucrania**",
                "Las tarjetas no están disponibles en Crimea, Donetsk, Luhansk, Jersón y Zaporiyia. El resto de Ucrania está disponible."
              ],
              [
                "AE",
                "Emiratos Árabes Unidos",
                "—"
              ],
              [
                "GB",
                "Reino Unido",
                "—"
              ],
              [
                "UM",
                "Islas Periféricas de EE. UU.",
                "—"
              ],
              [
                "US",
                "Estados Unidos",
                "—"
              ],
              [
                "UY",
                "Uruguay",
                "—"
              ],
              [
                "UZ",
                "Uzbekistán",
                "—"
              ],
              [
                "VU",
                "Vanuatu",
                "—"
              ],
              [
                "VN",
                "Vietnam",
                "—"
              ],
              [
                "VG",
                "Islas Vírgenes Británicas",
                "—"
              ],
              [
                "VI",
                "Islas Vírgenes de EE. UU.",
                "—"
              ],
              [
                "WF",
                "Wallis y Futuna",
                "—"
              ],
              [
                "EH",
                "Sáhara Occidental",
                "—"
              ],
              [
                "ZM",
                "Zambia",
                "—"
              ]
            ]
          },
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "crypto",
          "title": "Monedas y redes de pago",
          "paragraphs": [
            "El catálogo contiene 16 monedas y 31 pares de moneda/red. Una moneda puede aceptarse en varias redes: USDT en Tron y USDT en Ethereum son opciones de transferencia diferentes. La lista completa aparece a continuación.",
            "Las opciones disponibles para una factura específica y sus límites provienen de GET /api/checkout/{token}/crypto-services. Esta página describe las combinaciones admitidas; la respuesta actual de la pasarela determina si se puede crear un pago. Una entrada de referencia por sí sola no hace que un par no disponible sea pagable.",
            "El comerciante crea una factura de criptomoneda en USDT, y el cliente elige una moneda y una red disponibles. La operación creada en la pasarela proporciona el monto exacto de la moneda, la dirección, el código QR y la caducidad. El precio de una factura en USDT no fija el tipo de cambio de BTC, ETH u otra moneda, ni implica un tipo 1:1. Transfiere el monto decimal exacto según las instrucciones de pago sin redondear ni calcular una conversión por tu cuenta.",
            "USDT TRC20 es un término separado de pago al comerciante. No restringe los pagos entrantes a Tron ni significa que la creación de pagos esté disponible a través de la cuenta o la API. La guía de pagos explica los términos y restricciones de retiro."
          ],
          "bullets": [],
          "steps": [
            "Abre la factura y elige criptomoneda como método de pago.",
            "Elige una moneda y una red disponible. La red de la billetera del remitente debe coincidir con la red indicada en las instrucciones de pago de Kevmi.",
            "Crea las instrucciones de pago y verifica el monto exacto, la dirección completa y la caducidad. Copia la dirección y el monto, o usa el código QR correspondiente.",
            "Envía el monto especificado en la red seleccionada. Ten en cuenta las comisiones de la billetera o de la red para que el destinatario reciba el monto completo indicado en las instrucciones.",
            "Espera un estado confirmado en el pago. Enviar una transferencia de billetera por sí sola no completa el pedido: Kevmi verifica el resultado a través de la pasarela."
          ],
          "table": {
            "headers": [
              "Moneda",
              "Nombre",
              "Redes y códigos de pasarela"
            ],
            "rows": [
              [
                "AVAX",
                "Avalanche",
                "Avalanche C-Chain (avalanche)"
              ],
              [
                "BCH",
                "Bitcoin Cash",
                "Bitcoin Cash (bch)"
              ],
              [
                "BNB",
                "BNB",
                "BNB Smart Chain (bsc)"
              ],
              [
                "BTC",
                "Bitcoin",
                "Bitcoin (btc)"
              ],
              [
                "DAI",
                "Dai",
                "BNB Smart Chain (bsc), Ethereum (eth), Polygon PoS (polygon)"
              ],
              [
                "DASH",
                "Dash",
                "Dash (dash)"
              ],
              [
                "DOGE",
                "Dogecoin",
                "Dogecoin (doge)"
              ],
              [
                "ETH",
                "Ethereum",
                "Ethereum (eth), Arbitrum One (arbitrum), BNB Smart Chain (bsc)"
              ],
              [
                "GRAM",
                "Gram",
                "TON (ton)"
              ],
              [
                "LTC",
                "Litecoin",
                "Litecoin (ltc)"
              ],
              [
                "POL",
                "Polygon",
                "Ethereum (eth), Polygon PoS (polygon)"
              ],
              [
                "SHIB",
                "Shiba Inu",
                "Ethereum (eth)"
              ],
              [
                "TRX",
                "TRON",
                "TRON (tron)"
              ],
              [
                "USDC",
                "USD Coin",
                "Arbitrum One (arbitrum), BNB Smart Chain (bsc), Polygon PoS (polygon), Ethereum (eth), Avalanche C-Chain (avalanche)"
              ],
              [
                "USDT",
                "Tether",
                "TRON (tron), Avalanche C-Chain (avalanche), BNB Smart Chain (bsc), TON (ton), Polygon PoS (polygon), Arbitrum One (arbitrum), Ethereum (eth)"
              ],
              [
                "XMR",
                "Monero",
                "Monero (xmr)"
              ]
            ]
          },
          "code": null,
          "note": "No uses instrucciones de pago antiguas después de su caducidad. Si ya enviaste fondos, verifica la misma operación y contacta con soporte si es necesario; no crees un segundo pago para verificar el primero.",
          "links": [
            {
              "label": "Pago",
              "href": "/docs/checkout#method"
            },
            {
              "label": "Términos de pago",
              "href": "/docs/payouts"
            }
          ]
        },
        {
          "id": "specific",
          "title": "Consulta de un país específico",
          "paragraphs": [
            "El asistente puede encontrar un país por su nombre en ruso o inglés, o por su código ISO, y explicar su marcador publicado. Para países **, especifica la ubicación que necesitas. Para China *, pregunta sobre tu tarjeta.",
            "Si un país no aparece en la lista, esta base de conocimientos no puede confirmar la cobertura internacional de tarjetas. Incluye el país, el banco y el método deseado en una solicitud de soporte. No envíes el número completo de tarjeta ni secretos de pago."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Geografía",
              "href": "/countries"
            },
            {
              "label": "Preguntar a soporte",
              "href": "/?support=open"
            }
          ]
        }
      ],
      "body": "Cobertura por canal\n\nCanal · Cobertura · Condiciones\nTarjetas internacionales · Más de 190 países · Excepto la lista de restricciones y cinco regiones de Ucrania\nSBP · Rusia · La disponibilidad depende del banco y de la transacción\nAlipay · China · La disponibilidad depende de la cuenta y de la transacción\nCriptomonedas · Todos los países · Elige una moneda compatible y una red\n\nEl mapa interactivo\n\nLa página de Geografía tiene un mapa mundial bidimensional. Los filtros destacan los países con tarjetas internacionales publicados, Rusia para SBP y China para Alipay. Busca por nombre de país o código ISO para ver sus métodos y notas.\n\nEl rayado marca Ucrania porque cinco regiones están excluidas de las tarjetas. El resto de Ucrania está disponible. Las restricciones de tarjetas no se aplican a las criptomonedas, que están disponibles en todos los países.\n\nAbrir el mapa\n\nQué cubre la lista\n\nLa lista completa a continuación describe la cobertura de tarjetas internacionales. Los países de registro del comerciante y los destinos de pago tienen condiciones separadas.\n\nLa aprobación depende del país emisor, el banco, el tipo de tarjeta y las verificaciones del canal de pago. Que un país figure en la lista no garantiza la aprobación de cada tarjeta o transacción.\n\nRestricciones de Visa y Mastercard\n\nLas tarjetas no están disponibles en Crimea, Donetsk, Luhansk, Jersón y Zaporiyia. El resto de Ucrania está disponible.\n\nTodos los demás países están disponibles. Antillas Neerlandesas se conserva como entrada histórica de la lista del proveedor; no bloquea ningún territorio caribeño moderno.\n\nCódigo · País o territorio\nAF · Afganistán\nAQ · Antártida\nBY · Bielorrusia\nMM · Birmania (Myanmar)\nBI · Burundi\nCF · República Centroafricana\nTD · Chad\nCU · Cuba\nCD · República Democrática del Congo\nCG · República del Congo\nER · Eritrea\nHT · Haití\nIR · Irán\nIQ · Irak\nLY · Libia\nML · Malí\nNI · Nicaragua\nKP · Corea del Norte\nRU · Rusia\nSO · Somalia\nSS · Sudán del Sur\nSD · Sudán\nSY · Siria\nVE · Venezuela\nYE · Yemen\nZW · Zimbabue\nUA-43 · Crimea (Región de Ucrania)\nUA-14 · Donetsk (Región de Ucrania)\nUA-65 · Jersón (Región de Ucrania)\nUA-09 · Luhansk (Región de Ucrania)\nUA-23 · Zaporiyia (Región de Ucrania)\nAN · Antillas Neerlandesas\n\nDirectorio de países y territorios\n\nLos nombres, los códigos ISO y los marcadores provienen del registro de países compartido. Estas notas se aplican a las tarjetas internacionales.\n\nISO · País o territorio · Nota\nAX · Islas Åland · —\nAL · Albania · —\nDZ · Argelia · —\nAS · Samoa Americana · —\nAD · Andorra · —\nAO · Angola · —\nAI · Anguila · —\nAG · Antigua y Barbuda · —\nAR · Argentina · —\nAM · Armenia · —\nAW · Aruba · —\nAU · Australia · —\nAT · Austria · —\nAZ · Azerbaiyán · —\nBS · Bahamas · —\nBH · Baréin · —\nBD · Bangladesh · —\nBB · Barbados · —\nBE · Bélgica · —\nBZ · Belice · —\nBJ · Benín · —\nBM · Bermudas · —\nBT · Bután · —\nBO · Bolivia · —\nBQ · Caribe Neerlandés · —\nBA · Bosnia y Herzegovina · —\nBW · Botsuana · —\nBV · Isla Bouvet · —\nBR · Brasil · —\nIO · Territorio Británico del Océano Índico · —\nBN · Brunéi · —\nBG · Bulgaria · —\nBF · Burkina Faso · —\nCV · Cabo Verde · —\nKH · Camboya · —\nCM · Camerún · —\nCA · Canadá · —\nKY · Islas Caimán · —\nCL · Chile · —\nCN · China · —\nCX · Isla de Navidad · —\nCC · Islas Cocos (Keeling) · —\nCO · Colombia · —\nKM · Comoras · —\nCK · Islas Cook · —\nCR · Costa Rica · —\nHR · Croacia · —\nCW · Curazao · —\nCY · Chipre · —\nCZ · Chequia · —\nCI · Costa de Marfil · —\nDK · Dinamarca · —\nDJ · Yibuti · —\nDM · Dominica · —\nDO · República Dominicana · —\nEC · Ecuador · —\nEG · Egipto · —\nSV · El Salvador · —\nGQ · Guinea Ecuatorial · —\nEE · Estonia · —\nSZ · Esuatini · —\nET · Etiopía · —\nFK · Islas Malvinas · —\nFO · Islas Feroe · —\nFM · Micronesia · —\nFJ · Fiyi · —\nFI · Finlandia · —\nFR · Francia · —\nGF · Guayana Francesa · —\nPF · Polinesia Francesa · —\nTF · Territorios Australes Franceses · —\nGA · Gabón · —\nGM · Gambia · —\nGE · Georgia · —\nDE · Alemania · —\nGH · Ghana · —\nGI · Gibraltar · —\nGR · Grecia · —\nGL · Groenlandia · —\nGD · Granada · —\nGP · Guadalupe · —\nGU · Guam · —\nGT · Guatemala · —\nGG · Guernsey · —\nGN · Guinea · —\nGW · Guinea-Bisáu · —\nGY · Guyana · —\nHM · Islas Heard y McDonald · —\nVA · Ciudad del Vaticano · —\nHN · Honduras · —\nHK · RAE de Hong Kong (China) · —\nHU · Hungría · —\nIS · Islandia · —\nIN · India · —\nID · Indonesia · —\nIE · Irlanda · —\nIM · Isla de Man · —\nIL · Israel · —\nIT · Italia · —\nJM · Jamaica · —\nJP · Japón · —\nJE · Jersey · —\nJO · Jordania · —\nKZ · Kazajistán · —\nKE · Kenia · —\nKI · Kiribati · —\nKW · Kuwait · —\nKG · Kirguistán · —\nLA · Laos · —\nLV · Letonia · —\nLB · Líbano · —\nLS · Lesoto · —\nLR · Liberia · —\nLI · Liechtenstein · —\nLT · Lituania · —\nLU · Luxemburgo · —\nMO · Macao RAE China · —\nMG · Madagascar · —\nMW · Malaui · —\nMY · Malasia · —\nMV · Maldivas · —\nMT · Malta · —\nMH · Islas Marshall · —\nMQ · Martinica · —\nMR · Mauritania · —\nMU · Mauricio · —\nYT · Mayotte · —\nMX · México · —\nMD · Moldavia · —\nMC · Mónaco · —\nMN · Mongolia · —\nME · Montenegro · —\nMS · Montserrat · —\nMA · Marruecos · —\nMZ · Mozambique · —\nNA · Namibia · —\nNR · Nauru · —\nNP · Nepal · —\nNL · Países Bajos · —\nNC · Nueva Caledonia · —\nNZ · Nueva Zelanda · —\nNE · Níger · —\nNG · Nigeria · —\nNU · Niue · —\nNF · Isla Norfolk · —\nMK · Macedonia del Norte · —\nMP · Islas Marianas del Norte · —\nNO · Noruega · —\nOM · Omán · —\nPK · Pakistán · —\nPW · Palaos · —\nPA · Panamá · —\nPG · Papúa Nueva Guinea · —\nPY · Paraguay · —\nPE · Perú · —\nPH · Filipinas · —\nPN · Islas Pitcairn · —\nPL · Polonia · —\nPT · Portugal · —\nPR · Puerto Rico · —\nQA · Catar · —\nRO · Rumania · —\nRW · Ruanda · —\nRE · Reunión · —\nBL · San Bartolomé · —\nSH · Santa Elena · —\nKN · San Cristóbal y Nieves · —\nLC · Santa Lucía · —\nMF · San Martín · —\nPM · San Pedro y Miquelón · —\nVC · San Vicente y las Granadinas · —\nWS · Samoa · —\nSM · San Marino · —\nST · Santo Tomé y Príncipe · —\nSA · Arabia Saudita · —\nSN · Senegal · —\nRS · Serbia · —\nSC · Seychelles · —\nSL · Sierra Leona · —\nSG · Singapur · —\nSX · Sint Maarten · —\nSK · Eslovaquia · —\nSI · Eslovenia · —\nSB · Islas Salomón · —\nZA · Sudáfrica · —\nGS · Georgia del Sur e Islas Sandwich del Sur · —\nKR · Corea del Sur · —\nES · España · —\nLK · Sri Lanka · —\nPS · Territorios Palestinos · —\nSR · Surinam · —\nSJ · Svalbard y Jan Mayen · —\nSE · Suecia · —\nCH · Suiza · —\nTW · Taiwán · —\nTJ · Tayikistán · —\nTZ · Tanzania · —\nTH · Tailandia · —\nTL · Timor Oriental · —\nTG · Togo · —\nTK · Tokelau · —\nTO · Tonga · —\nTT · Trinidad y Tobago · —\nTN · Túnez · —\nTM · Turkmenistán · —\nTC · Islas Turcas y Caicos · —\nTV · Tuvalu · —\nTR · Turquía · —\nUG · Uganda · —\nUA · Ucrania** · Las tarjetas no están disponibles en Crimea, Donetsk, Luhansk, Jersón y Zaporiyia. El resto de Ucrania está disponible.\nAE · Emiratos Árabes Unidos · —\nGB · Reino Unido · —\nUM · Islas Periféricas de EE. UU. · —\nUS · Estados Unidos · —\nUY · Uruguay · —\nUZ · Uzbekistán · —\nVU · Vanuatu · —\nVN · Vietnam · —\nVG · Islas Vírgenes Británicas · —\nVI · Islas Vírgenes de EE. UU. · —\nWF · Wallis y Futuna · —\nEH · Sáhara Occidental · —\nZM · Zambia · —\n\nMonedas y redes de pago\n\nEl catálogo contiene 16 monedas y 31 pares de moneda/red. Una moneda puede aceptarse en varias redes: USDT en Tron y USDT en Ethereum son opciones de transferencia diferentes. La lista completa aparece a continuación.\n\nLas opciones disponibles para una factura específica y sus límites provienen de GET /api/checkout/{token}/crypto-services. Esta página describe las combinaciones admitidas; la respuesta actual de la pasarela determina si se puede crear un pago. Una entrada de referencia por sí sola no hace que un par no disponible sea pagable.\n\nEl comerciante crea una factura de criptomoneda en USDT, y el cliente elige una moneda y una red disponibles. La operación creada en la pasarela proporciona el monto exacto de la moneda, la dirección, el código QR y la caducidad. El precio de una factura en USDT no fija el tipo de cambio de BTC, ETH u otra moneda, ni implica un tipo 1:1. Transfiere el monto decimal exacto según las instrucciones de pago sin redondear ni calcular una conversión por tu cuenta.\n\nUSDT TRC20 es un término separado de pago al comerciante. No restringe los pagos entrantes a Tron ni significa que la creación de pagos esté disponible a través de la cuenta o la API. La guía de pagos explica los términos y restricciones de retiro.\n\nAbre la factura y elige criptomoneda como método de pago.\n\nElige una moneda y una red disponible. La red de la billetera del remitente debe coincidir con la red indicada en las instrucciones de pago de Kevmi.\n\nCrea las instrucciones de pago y verifica el monto exacto, la dirección completa y la caducidad. Copia la dirección y el monto, o usa el código QR correspondiente.\n\nEnvía el monto especificado en la red seleccionada. Ten en cuenta las comisiones de la billetera o de la red para que el destinatario reciba el monto completo indicado en las instrucciones.\n\nEspera un estado confirmado en el pago. Enviar una transferencia de billetera por sí sola no completa el pedido: Kevmi verifica el resultado a través de la pasarela.\n\nMoneda · Nombre · Redes y códigos de pasarela\nAVAX · Avalanche · Avalanche C-Chain (avalanche)\nBCH · Bitcoin Cash · Bitcoin Cash (bch)\nBNB · BNB · BNB Smart Chain (bsc)\nBTC · Bitcoin · Bitcoin (btc)\nDAI · Dai · BNB Smart Chain (bsc), Ethereum (eth), Polygon PoS (polygon)\nDASH · Dash · Dash (dash)\nDOGE · Dogecoin · Dogecoin (doge)\nETH · Ethereum · Ethereum (eth), Arbitrum One (arbitrum), BNB Smart Chain (bsc)\nGRAM · Gram · TON (ton)\nLTC · Litecoin · Litecoin (ltc)\nPOL · Polygon · Ethereum (eth), Polygon PoS (polygon)\nSHIB · Shiba Inu · Ethereum (eth)\nTRX · TRON · TRON (tron)\nUSDC · USD Coin · Arbitrum One (arbitrum), BNB Smart Chain (bsc), Polygon PoS (polygon), Ethereum (eth), Avalanche C-Chain (avalanche)\nUSDT · Tether · TRON (tron), Avalanche C-Chain (avalanche), BNB Smart Chain (bsc), TON (ton), Polygon PoS (polygon), Arbitrum One (arbitrum), Ethereum (eth)\nXMR · Monero · Monero (xmr)\n\nNo uses instrucciones de pago antiguas después de su caducidad. Si ya enviaste fondos, verifica la misma operación y contacta con soporte si es necesario; no crees un segundo pago para verificar el primero.\n\nPago\n\nTérminos de pago\n\nConsulta de un país específico\n\nEl asistente puede encontrar un país por su nombre en ruso o inglés, o por su código ISO, y explicar su marcador publicado. Para países **, especifica la ubicación que necesitas. Para China *, pregunta sobre tu tarjeta.\n\nSi un país no aparece en la lista, esta base de conocimientos no puede confirmar la cobertura internacional de tarjetas. Incluye el país, el banco y el método deseado en una solicitud de soporte. No envíes el número completo de tarjeta ni secretos de pago.\n\nGeografía\n\nPreguntar a soporte",
      "readMinutes": 15
    },
    {
      "id": "payment-links",
      "title": "Enlaces de pago",
      "summary": "Un enlace de pago abre una página de pedido dedicada. Los clientes ven al vendedor, la descripción de la compra, los métodos disponibles y el total a pagar en su teléfono o computadora.",
      "group": "payments",
      "url": "/docs/payment-links",
      "tags": [
        "enlace de pago",
        "factura",
        "pago",
        "pausa",
        "pedido",
        "Cualquier",
        "selección de método"
      ],
      "sections": [
        {
          "id": "contents",
          "title": "Qué incluye una factura",
          "paragraphs": [
            "Las facturas del nuevo espacio de trabajo usan un precio base en USD y Any ofrece los cuatro métodos. SBP convierte a RUB al tipo de referencia congelado del Banco de Rusia; cripto usa la regla explícita de factura 1:1 USD/USDT. El precio nativo heredado sigue disponible para facturas antiguas y solicitudes de API sin pricingMode=universal. Consulte la sección de múltiples tiendas y precios en USD a continuación.",
            "Nunca incluyas contraseñas, claves API, datos de tarjetas ni códigos bancarios en descripciones públicas. Usa un título de pedido y una referencia que el cliente reconozca."
          ],
          "bullets": [
            "Nombre de la tienda, un título de pedido de hasta 120 caracteres y una descripción de hasta 500 caracteres.",
            "Monto base y una moneda explícita en USD, RUB o USDT.",
            "Métodos compatibles, comisión separada y proporciones de IVA, una referencia de pedido y caducidad del enlace.",
            "Las respuestas del propietario incluyen link.payment con el estado guardado de una operación existente; esto es independiente del estado de disponibilidad del enlace."
          ],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "any",
          "title": "Cualquiera — el cliente elige",
          "paragraphs": [
            "Cualquiera selecciona todos los métodos compatibles con la moneda de la factura: tarjetas y Alipay para USD, SBP para RUB y cripto para USDT. La API usa una matriz de métodos concretos en lugar de la cadena cualquiera. Cada método tiene su propia cotización.",
            "Las facturas del nuevo espacio de trabajo usan un precio base en USD y Any ofrece los cuatro métodos. SBP convierte a RUB al tipo de referencia congelado del Banco de Rusia; cripto usa la regla explícita de factura 1:1 USD/USDT. El precio nativo heredado sigue disponible para facturas antiguas y solicitudes de API sin pricingMode=universal. Consulte la sección de múltiples tiendas y precios en USD a continuación.",
            "Para un pago nuevo en vivo con tarjeta o Alipay, la pasarela actual solo admite feeCustomerPercent=0 y vatCustomerPercent=100: el comerciante cubre toda la comisión de procesamiento y el IVA se añade completo para el cliente. Otras participaciones se pueden guardar y calcular en una factura, pero la ejecución está bloqueada con unsupported_allocation. El servidor nunca cambia silenciosamente los términos guardados. Los pagos cripto SBP y USDT admiten todas las participaciones de comisión de procesamiento y no tienen IVA."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Enviar métodos a través de la API",
              "href": "/docs/payment-links-api#methods"
            }
          ]
        },
        {
          "id": "create",
          "title": "Crear un enlace",
          "paragraphs": [],
          "bullets": [],
          "steps": [
            "Abra los enlaces de pago en su cuenta.",
            "Introduzca un título, monto, moneda y descripción. Establezca las participaciones de tarifa e IVA con los dos controles.",
            "Mantenga Cualquiera para que el cliente elija, o seleccione métodos específicos. Establezca la expiración.",
            "Compare el total de cada método y obtenga una vista previa del pago.",
            "Reciba el enlace de pago listo inmediatamente después de la creación, luego cópielo para su cliente o widget."
          ],
          "table": null,
          "code": null,
          "note": "Si la aceptación del pago no está disponible, el pago lo informa antes de la confirmación. Crear una factura no cobra dinero.",
          "links": []
        },
        {
          "id": "fixed",
          "title": "Los términos permanecen con la factura",
          "paragraphs": [
            "Una factura guardada no cambia cuando cambian los ajustes de la tienda. Su precio, moneda, tarifa y participaciones de IVA, referencia de pedido y metadatos pertenecen a ese pedido. Esto mantiene el total consistente para un cliente que ya abrió el enlace.",
            "Cree un nuevo enlace y pausa el anterior cuando cambien el precio, la descripción o la asignación de costos. Editar el monto de una URL no puede cambiar el cálculo del servidor."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "public",
          "title": "Una página de pago dedicada",
          "paragraphs": [
            "Los enlaces del servidor se guardan en la base de datos y se abren en distintos dispositivos en /pay/… sin acceso a la cuenta del comerciante. Un cliente no necesita registrarse para ver una factura. Los saldos de la tienda, los ajustes y otros registros del cliente permanecen privados.",
            "El ejemplo /pay/demo muestra la experiencia sin cobrar dinero. Los enlaces de demostración del navegador son datos de prueba y no deben presentarse como facturas reales."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Vista previa del pago",
              "href": "/pay/demo"
            },
            {
              "label": "Estados del pago",
              "href": "/docs/checkout"
            }
          ]
        },
        {
          "id": "control",
          "title": "Gestión de disponibilidad",
          "paragraphs": [
            "Pausar, cancelar o expirar un enlace bloquea una nueva operación. No oculta un pago ya enviado: el estado, la conciliación y un código bancario solicitado permanecen disponibles. La disponibilidad del enlace y el estado financiero se verifican por separado.",
            "Reanudar levanta una pausa sin cambiar los términos. La cancelación es definitiva, y un enlace expirado no puede extenderse. Cree una nueva factura para un nuevo pedido o términos modificados, no para reintentar un cargo cuyo resultado es desconocido."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "stores-usd",
          "title": "Múltiples tiendas y un precio base en USD",
          "paragraphs": [
            "Elija Todas las tiendas para análisis y operaciones agregados, o seleccione una tienda para sus propios registros. Cada tienda tiene un storeId, nombre, IVA predeterminado, facturas, claves de API, endpoints de webhook, historial de eventos y aplicación web separados. Las notificaciones y tickets de soporte pertenecen a la cuenta. Una cuenta puede crear hasta 100 tiendas. Los registros existentes permanecen en su primera tienda.",
            "Las facturas del nuevo espacio de trabajo usan pricingMode=\"universal\" y un precio base en USD. Any incluye tarjeta, alipay, sbp y cripto; un comerciante puede seleccionar un subconjunto. Tarjetas y Alipay cobran en USD. SBP cobra en RUB usando el tipo de referencia USD/RUB del Banco de Rusia. Cripto cobra USDT bajo la regla explícita de factura 1 USD = 1 USDT. Esta es una regla de conversión de factura, no una cotización de mercado de USDT. La pasarela proporciona la tasa de la moneda seleccionada, el monto exacto de transferencia y las instrucciones antes de la transferencia.",
            "El tipo de referencia y ambos montos se congelan al crear. Las facturas que implican conversión de RUB vencen dentro de 24 horas. Si no se puede obtener el tipo de referencia, la creación falla con FX_UNAVAILABLE; no se usa ningún tipo de respaldo inventado o desactualizado. El monto en minor del propietario y las cotizaciones usan la moneda contable USD. quotes[method].settlement contiene la cotización de cargo nativa. El checkout público expone la moneda de cargo seleccionada en currency, el precio original en baseAmountMinor/baseCurrency y el tipo de referencia en fx. Una vez que un pago ha sido despachado, su método no se puede cambiar; una factura tiene una operación de pasarela.",
            "Cree una clave de API dentro de la tienda prevista y envíe Authorization: Bearer <key> desde su servidor. Su vinculación a tienda es inmutable; X-Kevmi-Store no puede otorgarle acceso a otra tienda. Las sesiones del navegador seleccionan X-Kevmi-Store: <storeId>; omitirlo selecciona la primera tienda. El valor all solo es aceptado por GET /api/account/dashboard y GET /api/payment-links. Las mutaciones requieren una tienda seleccionada, Origin y X-CSRF-Token. Los IDs de cuenta y los IDs de tienda son identificadores diferentes.",
            "Por compatibilidad, las solicitudes de API sin pricingMode=\"universal\" conservan el precio nativo y las restricciones de moneda originales. Las facturas existentes nunca se recalculan. Los recibos confirmados en análisis reflejan pagos verificados menos gastos de factura guardados; no son un saldo retirable. Las monedas de factura heredadas permanecen separadas y los pagos se gestionan con soporte. Cumpla un pedido solo después de verificar payment.fulfillmentReady=true y payment.status=\"succeeded\" a través de la API del servidor, el historial de eventos o un webhook firmado."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        }
      ],
      "body": "Qué incluye una factura\n\nLas facturas del nuevo espacio de trabajo usan un precio base en USD y Any ofrece los cuatro métodos. SBP convierte a RUB al tipo de referencia congelado del Banco de Rusia; cripto usa la regla explícita de factura 1:1 USD/USDT. El precio nativo heredado sigue disponible para facturas antiguas y solicitudes de API sin pricingMode=universal. Consulte la sección de múltiples tiendas y precios en USD a continuación.\n\nNunca incluyas contraseñas, claves API, datos de tarjetas ni códigos bancarios en descripciones públicas. Usa un título de pedido y una referencia que el cliente reconozca.\n\nNombre de la tienda, un título de pedido de hasta 120 caracteres y una descripción de hasta 500 caracteres.\n\nMonto base y una moneda explícita en USD, RUB o USDT.\n\nMétodos compatibles, comisión separada y proporciones de IVA, una referencia de pedido y caducidad del enlace.\n\nLas respuestas del propietario incluyen link.payment con el estado guardado de una operación existente; esto es independiente del estado de disponibilidad del enlace.\n\nCualquiera — el cliente elige\n\nCualquiera selecciona todos los métodos compatibles con la moneda de la factura: tarjetas y Alipay para USD, SBP para RUB y cripto para USDT. La API usa una matriz de métodos concretos en lugar de la cadena cualquiera. Cada método tiene su propia cotización.\n\nLas facturas del nuevo espacio de trabajo usan un precio base en USD y Any ofrece los cuatro métodos. SBP convierte a RUB al tipo de referencia congelado del Banco de Rusia; cripto usa la regla explícita de factura 1:1 USD/USDT. El precio nativo heredado sigue disponible para facturas antiguas y solicitudes de API sin pricingMode=universal. Consulte la sección de múltiples tiendas y precios en USD a continuación.\n\nPara un pago nuevo en vivo con tarjeta o Alipay, la pasarela actual solo admite feeCustomerPercent=0 y vatCustomerPercent=100: el comerciante cubre toda la comisión de procesamiento y el IVA se añade completo para el cliente. Otras participaciones se pueden guardar y calcular en una factura, pero la ejecución está bloqueada con unsupported_allocation. El servidor nunca cambia silenciosamente los términos guardados. Los pagos cripto SBP y USDT admiten todas las participaciones de comisión de procesamiento y no tienen IVA.\n\nEnviar métodos a través de la API\n\nCrear un enlace\n\nAbra los enlaces de pago en su cuenta.\n\nIntroduzca un título, monto, moneda y descripción. Establezca las participaciones de tarifa e IVA con los dos controles.\n\nMantenga Cualquiera para que el cliente elija, o seleccione métodos específicos. Establezca la expiración.\n\nCompare el total de cada método y obtenga una vista previa del pago.\n\nReciba el enlace de pago listo inmediatamente después de la creación, luego cópielo para su cliente o widget.\n\nSi la aceptación del pago no está disponible, el pago lo informa antes de la confirmación. Crear una factura no cobra dinero.\n\nLos términos permanecen con la factura\n\nUna factura guardada no cambia cuando cambian los ajustes de la tienda. Su precio, moneda, tarifa y participaciones de IVA, referencia de pedido y metadatos pertenecen a ese pedido. Esto mantiene el total consistente para un cliente que ya abrió el enlace.\n\nCree un nuevo enlace y pausa el anterior cuando cambien el precio, la descripción o la asignación de costos. Editar el monto de una URL no puede cambiar el cálculo del servidor.\n\nUna página de pago dedicada\n\nLos enlaces del servidor se guardan en la base de datos y se abren en distintos dispositivos en /pay/… sin acceso a la cuenta del comerciante. Un cliente no necesita registrarse para ver una factura. Los saldos de la tienda, los ajustes y otros registros del cliente permanecen privados.\n\nEl ejemplo /pay/demo muestra la experiencia sin cobrar dinero. Los enlaces de demostración del navegador son datos de prueba y no deben presentarse como facturas reales.\n\nVista previa del pago\n\nEstados del pago\n\nGestión de disponibilidad\n\nPausar, cancelar o expirar un enlace bloquea una nueva operación. No oculta un pago ya enviado: el estado, la conciliación y un código bancario solicitado permanecen disponibles. La disponibilidad del enlace y el estado financiero se verifican por separado.\n\nReanudar levanta una pausa sin cambiar los términos. La cancelación es definitiva, y un enlace expirado no puede extenderse. Cree una nueva factura para un nuevo pedido o términos modificados, no para reintentar un cargo cuyo resultado es desconocido.\n\nMúltiples tiendas y un precio base en USD\n\nElija Todas las tiendas para análisis y operaciones agregados, o seleccione una tienda para sus propios registros. Cada tienda tiene un storeId, nombre, IVA predeterminado, facturas, claves de API, endpoints de webhook, historial de eventos y aplicación web separados. Las notificaciones y tickets de soporte pertenecen a la cuenta. Una cuenta puede crear hasta 100 tiendas. Los registros existentes permanecen en su primera tienda.\n\nLas facturas del nuevo espacio de trabajo usan pricingMode=\"universal\" y un precio base en USD. Any incluye tarjeta, alipay, sbp y cripto; un comerciante puede seleccionar un subconjunto. Tarjetas y Alipay cobran en USD. SBP cobra en RUB usando el tipo de referencia USD/RUB del Banco de Rusia. Cripto cobra USDT bajo la regla explícita de factura 1 USD = 1 USDT. Esta es una regla de conversión de factura, no una cotización de mercado de USDT. La pasarela proporciona la tasa de la moneda seleccionada, el monto exacto de transferencia y las instrucciones antes de la transferencia.\n\nEl tipo de referencia y ambos montos se congelan al crear. Las facturas que implican conversión de RUB vencen dentro de 24 horas. Si no se puede obtener el tipo de referencia, la creación falla con FX_UNAVAILABLE; no se usa ningún tipo de respaldo inventado o desactualizado. El monto en minor del propietario y las cotizaciones usan la moneda contable USD. quotes[method].settlement contiene la cotización de cargo nativa. El checkout público expone la moneda de cargo seleccionada en currency, el precio original en baseAmountMinor/baseCurrency y el tipo de referencia en fx. Una vez que un pago ha sido despachado, su método no se puede cambiar; una factura tiene una operación de pasarela.\n\nCree una clave de API dentro de la tienda prevista y envíe Authorization: Bearer <key> desde su servidor. Su vinculación a tienda es inmutable; X-Kevmi-Store no puede otorgarle acceso a otra tienda. Las sesiones del navegador seleccionan X-Kevmi-Store: <storeId>; omitirlo selecciona la primera tienda. El valor all solo es aceptado por GET /api/account/dashboard y GET /api/payment-links. Las mutaciones requieren una tienda seleccionada, Origin y X-CSRF-Token. Los IDs de cuenta y los IDs de tienda son identificadores diferentes.\n\nPor compatibilidad, las solicitudes de API sin pricingMode=\"universal\" conservan el precio nativo y las restricciones de moneda originales. Las facturas existentes nunca se recalculan. Los recibos confirmados en análisis reflejan pagos verificados menos gastos de factura guardados; no son un saldo retirable. Las monedas de factura heredadas permanecen separadas y los pagos se gestionan con soporte. Cumpla un pedido solo después de verificar payment.fulfillmentReady=true y payment.status=\"succeeded\" a través de la API del servidor, el historial de eventos o un webhook firmado.",
      "readMinutes": 5
    },
    {
      "id": "checkout",
      "title": "Pago",
      "summary": "El pago muestra al cliente qué está comprando, cómo puede pagar y el monto adeudado antes de la confirmación. Está separado del espacio de trabajo del comerciante.",
      "group": "payments",
      "url": "/docs/checkout",
      "tags": [
        "pago",
        "cliente",
        "pagar",
        "factura",
        "error de pago"
      ],
      "sections": [
        {
          "id": "review",
          "title": "Revise el pedido",
          "paragraphs": [
            "Verifique el nombre de la tienda, la compra, el precio base y la moneda. Si difieren de su acuerdo con el vendedor, solicite una factura corregida antes de continuar.",
            "Una factura pública solo requiere su dirección; no se necesita acceso a la cuenta del vendedor. Una página de demostración está claramente marcada y no recopila datos de tarjeta para un cargo real."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "method",
          "title": "Elija un método",
          "paragraphs": [
            "Las facturas del nuevo espacio de trabajo usan un precio base en USD y Any ofrece los cuatro métodos. SBP convierte a RUB al tipo de referencia congelado del Banco de Rusia; cripto usa la regla explícita de factura 1:1 USD/USDT. El precio nativo heredado sigue disponible para facturas antiguas y solicitudes de API sin pricingMode=universal. Consulte la sección de múltiples tiendas y precios en USD a continuación.",
            "Tarjeta: el navegador cifra los datos de pago con la clave pública de la pasarela. Kevmi retransmite el sobre cifrado; su servidor no acepta ni almacena números de tarjeta en texto plano, CVV ni códigos bancarios de un solo uso. Un formulario de código bancario solicitado aparece solo mientras el desafío de la pasarela es válido.",
            "Alipay: el cliente proporciona un nombre y recibe un código QR. SBP abre la URL de pago bancario; también se puede usar un QR proporcionado por la pasarela. Se muestra una expiración cuando la pasarela la proporciona.",
            "Cripto: elija una moneda y luego una red disponible del catálogo actual. Después de crear una operación, el pago muestra el monto decimal exacto, la dirección del destinatario y dos modos de QR: solo dirección, o dirección y monto. La red de la billetera debe coincidir con la red elegida. El precio de una factura en USDT no fija el tipo de cambio de otra moneda: use el monto proporcionado por la pasarela. Las instrucciones expiradas se ocultan mientras la conciliación continúa para el mismo pago.",
            "Para un pago nuevo en vivo con tarjeta o Alipay, la pasarela actual solo admite feeCustomerPercent=0 y vatCustomerPercent=100: el comerciante cubre toda la comisión de procesamiento y el IVA se añade completo para el cliente. Otras participaciones se pueden guardar y calcular en una factura, pero la ejecución está bloqueada con unsupported_allocation. El servidor nunca cambia silenciosamente los términos guardados. Los pagos cripto SBP y USDT admiten todas las participaciones de comisión de procesamiento y no tienen IVA."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "states",
          "title": "Estados del pago",
          "paragraphs": [],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Estado",
              "Significado",
              "Siguiente paso"
            ],
            "rows": [
              [
                "Activo",
                "La factura está disponible para verse",
                "Verifique el total y la disponibilidad del método seleccionado"
              ],
              [
                "Pausado / expirado / cancelado",
                "Ningún pago nuevo puede comenzar a través del enlace",
                "Contacte al vendedor; una operación original se verifica por separado"
              ],
              [
                "No encontrado",
                "La dirección es inválida o no está disponible",
                "Verifique la dirección completa"
              ],
              [
                "Pago no disponible",
                "Una nueva operación está bloqueada por configuración, método, límite, asignación o revisión del comerciante",
                "Siga el mensaje mostrado; los términos de la factura guardada no cambian"
              ],
              [
                "Pendiente / acción requerida",
                "La operación original existe o necesita confirmación",
                "Complete el paso actual o verifique su estado"
              ],
              [
                "Verificando resultado",
                "Un resultado confirmado aún no está disponible",
                "Verifique la operación original; no cree un segundo cargo"
              ]
            ]
          },
          "code": null,
          "note": "Un error de red o una respuesta faltante no prueba que no ocurrió un cargo. Una operación ya enviada permanece legible incluso si el enlace ya no acepta nuevos pagos.",
          "links": []
        },
        {
          "id": "confirmation",
          "title": "Qué confirma el pago",
          "paragraphs": [
            "El pago se confirma mediante la conciliación del servidor de la operación exacta de la pasarela. El éxito requiere fulfillment_ready=true, verification=provider_confirmed, sin disputa y una coincidencia exacta entre el monto pagado y el total aprobado. Cripto además requiere evidencia de liquidación confirmada.",
            "Una redirección, un mensaje de widget, un código bancario aceptado o una observación del navegador no confirman dinero. Después de un tiempo de espera, lea el estado de la operación original; nunca se crea automáticamente un intento de reemplazo.",
            "Un nuevo pago e intento de tarjeta requieren que la última solicitud de revisión web del comerciante esté aprobada. La aprobación por sí sola no conecta la pasarela de pago. Si la revisión cambia después del envío, la operación existente permanece disponible para lecturas de estado, conciliación y un código bancario solicitado."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "help",
          "title": "Obtener ayuda",
          "paragraphs": [
            "Envíe al vendedor la referencia o dirección de la factura, la hora del intento y el error mostrado. No envíe CVV, una contraseña bancaria, código de confirmación ni frase semilla al soporte. El asistente de documentación puede explicar términos pero no puede confirmar de forma independiente un abono."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Ayuda de pago",
              "href": "/?support=open"
            },
            {
              "label": "Cálculo de IVA",
              "href": "/docs/vat"
            }
          ]
        }
      ],
      "body": "Revise el pedido\n\nVerifique el nombre de la tienda, la compra, el precio base y la moneda. Si difieren de su acuerdo con el vendedor, solicite una factura corregida antes de continuar.\n\nUna factura pública solo requiere su dirección; no se necesita acceso a la cuenta del vendedor. Una página de demostración está claramente marcada y no recopila datos de tarjeta para un cargo real.\n\nElija un método\n\nLas facturas del nuevo espacio de trabajo usan un precio base en USD y Any ofrece los cuatro métodos. SBP convierte a RUB al tipo de referencia congelado del Banco de Rusia; cripto usa la regla explícita de factura 1:1 USD/USDT. El precio nativo heredado sigue disponible para facturas antiguas y solicitudes de API sin pricingMode=universal. Consulte la sección de múltiples tiendas y precios en USD a continuación.\n\nTarjeta: el navegador cifra los datos de pago con la clave pública de la pasarela. Kevmi retransmite el sobre cifrado; su servidor no acepta ni almacena números de tarjeta en texto plano, CVV ni códigos bancarios de un solo uso. Un formulario de código bancario solicitado aparece solo mientras el desafío de la pasarela es válido.\n\nAlipay: el cliente proporciona un nombre y recibe un código QR. SBP abre la URL de pago bancario; también se puede usar un QR proporcionado por la pasarela. Se muestra una expiración cuando la pasarela la proporciona.\n\nCripto: elija una moneda y luego una red disponible del catálogo actual. Después de crear una operación, el pago muestra el monto decimal exacto, la dirección del destinatario y dos modos de QR: solo dirección, o dirección y monto. La red de la billetera debe coincidir con la red elegida. El precio de una factura en USDT no fija el tipo de cambio de otra moneda: use el monto proporcionado por la pasarela. Las instrucciones expiradas se ocultan mientras la conciliación continúa para el mismo pago.\n\nPara un pago nuevo en vivo con tarjeta o Alipay, la pasarela actual solo admite feeCustomerPercent=0 y vatCustomerPercent=100: el comerciante cubre toda la comisión de procesamiento y el IVA se añade completo para el cliente. Otras participaciones se pueden guardar y calcular en una factura, pero la ejecución está bloqueada con unsupported_allocation. El servidor nunca cambia silenciosamente los términos guardados. Los pagos cripto SBP y USDT admiten todas las participaciones de comisión de procesamiento y no tienen IVA.\n\nEstados del pago\n\nEstado · Significado · Siguiente paso\nActivo · La factura está disponible para verse · Verifique el total y la disponibilidad del método seleccionado\nPausado / expirado / cancelado · Ningún pago nuevo puede comenzar a través del enlace · Contacte al vendedor; una operación original se verifica por separado\nNo encontrado · La dirección es inválida o no está disponible · Verifique la dirección completa\nPago no disponible · Una nueva operación está bloqueada por configuración, método, límite, asignación o revisión del comerciante · Siga el mensaje mostrado; los términos de la factura guardada no cambian\nPendiente / acción requerida · La operación original existe o necesita confirmación · Complete el paso actual o verifique su estado\nVerificando resultado · Un resultado confirmado aún no está disponible · Verifique la operación original; no cree un segundo cargo\n\nUn error de red o una respuesta faltante no prueba que no ocurrió un cargo. Una operación ya enviada permanece legible incluso si el enlace ya no acepta nuevos pagos.\n\nQué confirma el pago\n\nEl pago se confirma mediante la conciliación del servidor de la operación exacta de la pasarela. El éxito requiere fulfillment_ready=true, verification=provider_confirmed, sin disputa y una coincidencia exacta entre el monto pagado y el total aprobado. Cripto además requiere evidencia de liquidación confirmada.\n\nUna redirección, un mensaje de widget, un código bancario aceptado o una observación del navegador no confirman dinero. Después de un tiempo de espera, lea el estado de la operación original; nunca se crea automáticamente un intento de reemplazo.\n\nUn nuevo pago e intento de tarjeta requieren que la última solicitud de revisión web del comerciante esté aprobada. La aprobación por sí sola no conecta la pasarela de pago. Si la revisión cambia después del envío, la operación existente permanece disponible para lecturas de estado, conciliación y un código bancario solicitado.\n\nObtener ayuda\n\nEnvíe al vendedor la referencia o dirección de la factura, la hora del intento y el error mostrado. No envíe CVV, una contraseña bancaria, código de confirmación ni frase semilla al soporte. El asistente de documentación puede explicar términos pero no puede confirmar de forma independiente un abono.\n\nAyuda de pago\n\nCálculo de IVA",
      "readMinutes": 5
    },
    {
      "id": "payments",
      "title": "Pagos y estados",
      "summary": "Una factura describe un pedido. Un pago es un intento específico de pagarlo. Un intento de pago y la disponibilidad de su enlace son estados separados.",
      "group": "payments",
      "url": "/docs/payments",
      "tags": [
        "pago",
        "estado",
        "pendiente",
        "exitoso",
        "fallido"
      ],
      "sections": [
        {
          "id": "record",
          "title": "El registro de pago",
          "paragraphs": [
            "La factura almacena los términos del pedido; el pago identifica su operación de pasarela. El primer lanzamiento reserva un vínculo duradero y una clave de idempotencia del servidor. Una vez que comienza el envío, otro método no puede crear un segundo cargo en la misma factura.",
            "GET /api/payment-links y GET /api/v1/payments devuelven link.payment al propietario. El estado activo/pausado/cancelado/expirado del enlace es independiente del estado del pago. Un cliente solo puede leer su operación mediante el token aleatorio de pago."
          ],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Datos",
              "Propósito"
            ],
            "rows": [
              [
                "Identificador y pedido",
                "Asociar el intento con una compra"
              ],
              [
                "Monto base y moneda",
                "La base de cálculo"
              ],
              [
                "Método de pago",
                "Comisión e impuesto aplicables"
              ],
              [
                "Contribuyente de IVA",
                "Quién cubre el impuesto"
              ],
              [
                "Comisión, IVA y totales",
                "Cálculo guardado"
              ],
              [
                "Estado y hora",
                "Estado actual de la transacción"
              ],
              [
                "Referencia del evento de la pasarela",
                "Fuente de confirmación del servidor"
              ]
            ]
          },
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "statuses",
          "title": "Estados de operación en vivo",
          "paragraphs": [
            "La demo utiliza registros de prueba separados. Cambiar un estado de demo no confirma un pago real ni modifica registros financieros."
          ],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Estado",
              "Significado"
            ],
            "rows": [
              [
                "pendiente",
                "Operación creada; en espera de acción o resultado"
              ],
              [
                "requires_action",
                "Se requiere un código bancario o confirmación del cliente"
              ],
              [
                "processing",
                "El proveedor aún está confirmando el resultado"
              ],
              [
                "exitoso",
                "El servidor verificó el pago exacto"
              ],
              [
                "fallido",
                "El intento terminó sin pago confirmado"
              ],
              [
                "expired",
                "Instrucciones vencidas; la conciliación sigue disponible"
              ],
              [
                "review_required",
                "Se requiere revisión adicional; no pague de nuevo"
              ],
              [
                "partially_paid",
                "Solo se recibió parte del monto; no cree otro pago"
              ],
              [
                "partially_refunded",
                "Parte del pago fue reembolsada"
              ],
              [
                "refunded",
                "Reembolso confirmado"
              ],
              [
                "disputed",
                "La operación está en disputa"
              ]
            ]
          },
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "authority",
          "title": "La fuente de verdad",
          "paragraphs": [
            "Un webhook firmado activa una lectura autenticada de la operación exacta de la pasarela. Se validan los IDs, el pedido, la moneda, el método, los montos base y final, el modo en vivo y la versión monotónica. El nombre de un evento entrante por sí solo no es prueba de dinero.",
            "El estado, el recibo y el evento del comerciante se consolidan atómicamente. Las respuestas antiguas no pueden sobrescribir una versión más nueva; los duplicados no se cumplen dos veces y un estado pendiente no puede reemplazar un pago confirmado. Estos registros no crean automáticamente un saldo retirable ni un pago."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "uncertain",
          "title": "Cuando el resultado es desconocido",
          "paragraphs": [],
          "bullets": [],
          "steps": [
            "Conserve la factura original y el identificador de la operación.",
            "Lea GET /api/checkout/{token}/status; no crea un cargo.",
            "Use POST /api/checkout/{token}/reconcile cuando se necesite una conciliación explícita.",
            "No cambie el método, el monto ni la clave de idempotencia después de un resultado incierto."
          ],
          "table": null,
          "code": null,
          "note": "Un tiempo de espera agotado no es un rechazo. Una respuesta perdida se recupera con la clave original del servidor; no se crea automáticamente un intento de reemplazo.",
          "links": []
        },
        {
          "id": "stores-usd",
          "title": "Múltiples tiendas y un precio base en USD",
          "paragraphs": [
            "Elija Todas las tiendas para análisis y operaciones agregados, o seleccione una tienda para sus propios registros. Cada tienda tiene un storeId, nombre, IVA predeterminado, facturas, claves de API, endpoints de webhook, historial de eventos y aplicación web separados. Las notificaciones y tickets de soporte pertenecen a la cuenta. Una cuenta puede crear hasta 100 tiendas. Los registros existentes permanecen en su primera tienda.",
            "Las facturas del nuevo espacio de trabajo usan pricingMode=\"universal\" y un precio base en USD. Any incluye tarjeta, alipay, sbp y cripto; un comerciante puede seleccionar un subconjunto. Tarjetas y Alipay cobran en USD. SBP cobra en RUB usando el tipo de referencia USD/RUB del Banco de Rusia. Cripto cobra USDT bajo la regla explícita de factura 1 USD = 1 USDT. Esta es una regla de conversión de factura, no una cotización de mercado de USDT. La pasarela proporciona la tasa de la moneda seleccionada, el monto exacto de transferencia y las instrucciones antes de la transferencia.",
            "El tipo de referencia y ambos montos se congelan al crear. Las facturas que implican conversión de RUB vencen dentro de 24 horas. Si no se puede obtener el tipo de referencia, la creación falla con FX_UNAVAILABLE; no se usa ningún tipo de respaldo inventado o desactualizado. El monto en minor del propietario y las cotizaciones usan la moneda contable USD. quotes[method].settlement contiene la cotización de cargo nativa. El checkout público expone la moneda de cargo seleccionada en currency, el precio original en baseAmountMinor/baseCurrency y el tipo de referencia en fx. Una vez que un pago ha sido despachado, su método no se puede cambiar; una factura tiene una operación de pasarela.",
            "Cree una clave de API dentro de la tienda prevista y envíe Authorization: Bearer <key> desde su servidor. Su vinculación a tienda es inmutable; X-Kevmi-Store no puede otorgarle acceso a otra tienda. Las sesiones del navegador seleccionan X-Kevmi-Store: <storeId>; omitirlo selecciona la primera tienda. El valor all solo es aceptado por GET /api/account/dashboard y GET /api/payment-links. Las mutaciones requieren una tienda seleccionada, Origin y X-CSRF-Token. Los IDs de cuenta y los IDs de tienda son identificadores diferentes.",
            "Por compatibilidad, las solicitudes de API sin pricingMode=\"universal\" conservan el precio nativo y las restricciones de moneda originales. Las facturas existentes nunca se recalculan. Los recibos confirmados en análisis reflejan pagos verificados menos gastos de factura guardados; no son un saldo retirable. Las monedas de factura heredadas permanecen separadas y los pagos se gestionan con soporte. Cumpla un pedido solo después de verificar payment.fulfillmentReady=true y payment.status=\"succeeded\" a través de la API del servidor, el historial de eventos o un webhook firmado."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        }
      ],
      "body": "El registro de pago\n\nLa factura almacena los términos del pedido; el pago identifica su operación de pasarela. El primer lanzamiento reserva un vínculo duradero y una clave de idempotencia del servidor. Una vez que comienza el envío, otro método no puede crear un segundo cargo en la misma factura.\n\nGET /api/payment-links y GET /api/v1/payments devuelven link.payment al propietario. El estado activo/pausado/cancelado/expirado del enlace es independiente del estado del pago. Un cliente solo puede leer su operación mediante el token aleatorio de pago.\n\nDatos · Propósito\nIdentificador y pedido · Asociar el intento con una compra\nMonto base y moneda · La base de cálculo\nMétodo de pago · Comisión e impuesto aplicables\nContribuyente de IVA · Quién cubre el impuesto\nComisión, IVA y totales · Cálculo guardado\nEstado y hora · Estado actual de la transacción\nReferencia del evento de la pasarela · Fuente de confirmación del servidor\n\nEstados de operación en vivo\n\nLa demo utiliza registros de prueba separados. Cambiar un estado de demo no confirma un pago real ni modifica registros financieros.\n\nEstado · Significado\npendiente · Operación creada; en espera de acción o resultado\nrequires_action · Se requiere un código bancario o confirmación del cliente\nprocessing · El proveedor aún está confirmando el resultado\nexitoso · El servidor verificó el pago exacto\nfallido · El intento terminó sin pago confirmado\nexpired · Instrucciones vencidas; la conciliación sigue disponible\nreview_required · Se requiere revisión adicional; no pague de nuevo\npartially_paid · Solo se recibió parte del monto; no cree otro pago\npartially_refunded · Parte del pago fue reembolsada\nrefunded · Reembolso confirmado\ndisputed · La operación está en disputa\n\nLa fuente de verdad\n\nUn webhook firmado activa una lectura autenticada de la operación exacta de la pasarela. Se validan los IDs, el pedido, la moneda, el método, los montos base y final, el modo en vivo y la versión monotónica. El nombre de un evento entrante por sí solo no es prueba de dinero.\n\nEl estado, el recibo y el evento del comerciante se consolidan atómicamente. Las respuestas antiguas no pueden sobrescribir una versión más nueva; los duplicados no se cumplen dos veces y un estado pendiente no puede reemplazar un pago confirmado. Estos registros no crean automáticamente un saldo retirable ni un pago.\n\nCuando el resultado es desconocido\n\nConserve la factura original y el identificador de la operación.\n\nLea GET /api/checkout/{token}/status; no crea un cargo.\n\nUse POST /api/checkout/{token}/reconcile cuando se necesite una conciliación explícita.\n\nNo cambie el método, el monto ni la clave de idempotencia después de un resultado incierto.\n\nUn tiempo de espera agotado no es un rechazo. Una respuesta perdida se recupera con la clave original del servidor; no se crea automáticamente un intento de reemplazo.\n\nMúltiples tiendas y un precio base en USD\n\nElija Todas las tiendas para análisis y operaciones agregados, o seleccione una tienda para sus propios registros. Cada tienda tiene un storeId, nombre, IVA predeterminado, facturas, claves de API, endpoints de webhook, historial de eventos y aplicación web separados. Las notificaciones y tickets de soporte pertenecen a la cuenta. Una cuenta puede crear hasta 100 tiendas. Los registros existentes permanecen en su primera tienda.\n\nLas facturas del nuevo espacio de trabajo usan pricingMode=\"universal\" y un precio base en USD. Any incluye tarjeta, alipay, sbp y cripto; un comerciante puede seleccionar un subconjunto. Tarjetas y Alipay cobran en USD. SBP cobra en RUB usando el tipo de referencia USD/RUB del Banco de Rusia. Cripto cobra USDT bajo la regla explícita de factura 1 USD = 1 USDT. Esta es una regla de conversión de factura, no una cotización de mercado de USDT. La pasarela proporciona la tasa de la moneda seleccionada, el monto exacto de transferencia y las instrucciones antes de la transferencia.\n\nEl tipo de referencia y ambos montos se congelan al crear. Las facturas que implican conversión de RUB vencen dentro de 24 horas. Si no se puede obtener el tipo de referencia, la creación falla con FX_UNAVAILABLE; no se usa ningún tipo de respaldo inventado o desactualizado. El monto en minor del propietario y las cotizaciones usan la moneda contable USD. quotes[method].settlement contiene la cotización de cargo nativa. El checkout público expone la moneda de cargo seleccionada en currency, el precio original en baseAmountMinor/baseCurrency y el tipo de referencia en fx. Una vez que un pago ha sido despachado, su método no se puede cambiar; una factura tiene una operación de pasarela.\n\nCree una clave de API dentro de la tienda prevista y envíe Authorization: Bearer <key> desde su servidor. Su vinculación a tienda es inmutable; X-Kevmi-Store no puede otorgarle acceso a otra tienda. Las sesiones del navegador seleccionan X-Kevmi-Store: <storeId>; omitirlo selecciona la primera tienda. El valor all solo es aceptado por GET /api/account/dashboard y GET /api/payment-links. Las mutaciones requieren una tienda seleccionada, Origin y X-CSRF-Token. Los IDs de cuenta y los IDs de tienda son identificadores diferentes.\n\nPor compatibilidad, las solicitudes de API sin pricingMode=\"universal\" conservan el precio nativo y las restricciones de moneda originales. Las facturas existentes nunca se recalculan. Los recibos confirmados en análisis reflejan pagos verificados menos gastos de factura guardados; no son un saldo retirable. Las monedas de factura heredadas permanecen separadas y los pagos se gestionan con soporte. Cumpla un pedido solo después de verificar payment.fulfillmentReady=true y payment.status=\"succeeded\" a través de la API del servidor, el historial de eventos o un webhook firmado.",
      "readMinutes": 3
    },
    {
      "id": "payouts",
      "title": "Pagos de salida USDT TRC20",
      "summary": "Los términos de pago de salida especifican USDT en TRC20, con comisiones basadas en la fuente de los fondos. Esta guía cubre comisiones, requisitos de cotización y restricciones: la creación de pagos de salida a través de la cuenta y la API no está disponible.",
      "group": "payments",
      "url": "/docs/payouts",
      "tags": [
        "retiro",
        "retiro",
        "USDT",
        "TRC20",
        "billetera",
        "tipo de cambio"
      ],
      "sections": [
        {
          "id": "tariffs",
          "title": "Comisiones por fuente",
          "paragraphs": [
            "La comisión de aceptación ya está incluida en el crédito del comerciante. Un pago es una operación separada con su propia comisión. No aplique la comisión de aceptación al saldo una segunda vez."
          ],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Fuente",
              "Comisión"
            ],
            "rows": [
              [
                "Tarjetas y Alipay",
                "4%"
              ],
              [
                "SBP",
                "5% + RUB 400"
              ],
              [
                "Criptomonedas",
                "0% + $3"
              ]
            ]
          },
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "quote",
          "title": "Cotizaciones y monedas",
          "paragraphs": [
            "Los montos en USD y RUB deben contabilizarse por separado. No los sume sin un tipo de cambio. USD es una moneda fiduciaria y USDT es un activo digital; no se asume un tipo de cambio automático de 1:1.",
            "Una cotización debe indicar la moneda y el monto de origen, la comisión, la salida de USDT y la expiración. Los cambios en el monto o la billetera requieren una nueva verificación de los términos."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "address",
          "title": "Dirección del destinatario",
          "paragraphs": [
            "Use una dirección TRC20 perteneciente al destinatario. La validación del formato de dirección puede detectar algunos errores tipográficos, pero no puede verificar al propietario ni garantizar la entrega.",
            "Verifique la dirección completa y la red antes de enviar. El servidor debe validar el monto, el saldo disponible y la cotización de forma independiente del formulario del cliente."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "flow",
          "title": "El proceso de pago",
          "paragraphs": [
            "La demo utiliza una cotización ingresada manualmente solo para cálculo. Un pago de prueba reserva fondos de demostración y no transfiere activos."
          ],
          "bullets": [],
          "steps": [
            "Elija la fuente de fondos y el monto a debitar.",
            "Ingrese una dirección TRC20.",
            "Obtenga una cotización actual y revise la comisión.",
            "Confirme los términos exactos de la solicitud.",
            "Espere un resultado confirmado por el servidor."
          ],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "availability",
          "title": "Disponibilidad de pagos",
          "paragraphs": [
            "La creación de pagos a través de la cuenta y /api/payouts no está disponible. Las comisiones publicadas y un cálculo de comisión no crean una solicitud de transferencia ni confirman su ejecución.",
            "Los pagos verificados, recibos y eventos se guardan en el historial. Estos registros no son un saldo retirable. Ejecutar un pago requiere un libro de fondos separado, una cotización actual, validación del destino y confirmación de la transferencia."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Integración de pasarela",
              "href": "/docs/gateway"
            }
          ]
        }
      ],
      "body": "Comisiones por fuente\n\nLa comisión de aceptación ya está incluida en el crédito del comerciante. Un pago es una operación separada con su propia comisión. No aplique la comisión de aceptación al saldo una segunda vez.\n\nFuente · Comisión\nTarjetas y Alipay · 4%\nSBP · 5% + RUB 400\nCriptomonedas · 0% + $3\n\nCotizaciones y monedas\n\nLos montos en USD y RUB deben contabilizarse por separado. No los sume sin un tipo de cambio. USD es una moneda fiduciaria y USDT es un activo digital; no se asume un tipo de cambio automático de 1:1.\n\nUna cotización debe indicar la moneda y el monto de origen, la comisión, la salida de USDT y la expiración. Los cambios en el monto o la billetera requieren una nueva verificación de los términos.\n\nDirección del destinatario\n\nUse una dirección TRC20 perteneciente al destinatario. La validación del formato de dirección puede detectar algunos errores tipográficos, pero no puede verificar al propietario ni garantizar la entrega.\n\nVerifique la dirección completa y la red antes de enviar. El servidor debe validar el monto, el saldo disponible y la cotización de forma independiente del formulario del cliente.\n\nEl proceso de pago\n\nLa demo utiliza una cotización ingresada manualmente solo para cálculo. Un pago de prueba reserva fondos de demostración y no transfiere activos.\n\nElija la fuente de fondos y el monto a debitar.\n\nIngrese una dirección TRC20.\n\nObtenga una cotización actual y revise la comisión.\n\nConfirme los términos exactos de la solicitud.\n\nEspere un resultado confirmado por el servidor.\n\nDisponibilidad de pagos\n\nLa creación de pagos a través de la cuenta y /api/payouts no está disponible. Las comisiones publicadas y un cálculo de comisión no crean una solicitud de transferencia ni confirman su ejecución.\n\nLos pagos verificados, recibos y eventos se guardan en el historial. Estos registros no son un saldo retirable. Ejecutar un pago requiere un libro de fondos separado, una cotización actual, validación del destino y confirmación de la transferencia.\n\nIntegración de pasarela",
      "readMinutes": 3
    },
    {
      "id": "telegram-login",
      "title": "Inicie sesión y regístrese con Telegram",
      "summary": "Telegram verifica su identidad. Kevmi crea su cuenta en el primer inicio de sesión y la abre en visitas posteriores. No se requiere una contraseña separada de Kevmi.",
      "group": "account",
      "url": "/docs/telegram-login",
      "tags": [
        "Telegram",
        "iniciar sesión",
        "acceder",
        "registrarse",
        "cuenta",
        "bot"
      ],
      "sections": [
        {
          "id": "steps",
          "title": "Inicio de sesión",
          "paragraphs": [
            "La solicitud dura cinco minutos. Inicie una nueva solicitud si expira. Una solicitud antigua no puede reutilizarse para obtener una sesión."
          ],
          "bullets": [],
          "steps": [
            "Abra Iniciar sesión o Crear cuenta y seleccione Continuar con Telegram.",
            "Siga el enlace del bot creado por este navegador.",
            "Compare el código de seis dígitos en el sitio web y en el mensaje del bot.",
            "Confirme en el chat privado.",
            "Vuelva al navegador original. Su cuenta se abre después de la verificación."
          ],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "browser",
          "title": "Por qué importa el navegador original",
          "paragraphs": [
            "El enlace de Telegram está vinculado a una cookie protegida en el navegador que inició la sesión. Un challengeId o un enlace reenviado por sí solo no puede crear una sesión en otro dispositivo.",
            "Puede confirmar en Telegram desde otro dispositivo, pero la cuenta se abre en el navegador donde comenzó el inicio de sesión. No confirme una solicitud que usted no inició."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "session",
          "title": "Sesiones y cierre de sesión",
          "paragraphs": [
            "Una sesión dura hasta 24 horas. Su token aleatorio se almacena en una cookie Secure HttpOnly y no puede ser leído por JavaScript. El cierre de sesión en el sitio web finaliza la sesión actual.",
            "El comando del bot /logout finaliza todas las sesiones de la cuenta y cancela confirmaciones no utilizadas. Un nuevo inicio de sesión requiere una nueva solicitud."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "trouble",
          "title": "Solución de problemas de inicio de sesión",
          "paragraphs": [],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Situación",
              "Acción"
            ],
            "rows": [
              [
                "El enlace expiró",
                "Inicie una nueva solicitud en el sitio web"
              ],
              [
                "Hay un navegador diferente abierto",
                "Vuelva a la pestaña donde comenzó el inicio de sesión"
              ],
              [
                "Los códigos difieren",
                "No confirme; comience de nuevo"
              ],
              [
                "Inicio de sesión no disponible",
                "Intente más tarde o contacte al soporte"
              ],
              [
                "Error de red temporal",
                "Espere la siguiente verificación o reintente el inicio de sesión"
              ]
            ]
          },
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "privacy",
          "title": "Información utilizada para el inicio de sesión",
          "paragraphs": [
            "El servidor recibe un ID de Telegram verificado y campos de perfil disponibles para crear la cuenta. Un nombre de usuario público por sí solo no es prueba de identidad.",
            "El bot no solicita su contraseña de Telegram, códigos bancarios, CVV, frase semilla ni claves privadas."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "API de autenticación",
              "href": "/docs/auth-api"
            },
            {
              "label": "Iniciar sesión",
              "href": "/login"
            }
          ]
        },
        {
          "id": "assistant-admin-v16",
          "title": "Asistencia, soporte y administración de proyectos",
          "paragraphs": [
            "Habilitar Permite el acceso a mis datos en el chat cuando necesites ayuda con operaciones privadas. Una solicitud web con includeAccount=true requiere una sesión válida, Origin y X-CSRF-Token; X-Kevmi-Store selecciona una tienda propia o todas las tiendas propias. Sin permiso, el asistente usa documentación pública. En Telegram, un botón separado habilita el acceso después de identificar al remitente.",
            "La herramienta read_account lee tiendas propias, facturas con estado de recibo verificado, eventos, solicitudes y solicitudes de soporte con respuestas de especialistas. Devuelve 30 registros y nextPage; los registros más antiguos están disponibles mediante paginación. Las lecturas por respuesta están limitadas, por lo que una muestra incompleta debe revelarse. Las claves de API, secretos de webhook, datos de tarjetas y sesiones no se proporcionan a la herramienta. No puede cobrar, pagar, reembolsar ni cambiar la configuración.",
            "Crear una solicitud de soporte en el espacio de trabajo o en Telegram coloca una alerta de administrador separada en una cola duradera. Se enlaza a /admin/tickets?ticket=<id>; los fallos temporales de Telegram se reintentan. La recuperación también recoge solicitudes abiertas antiguas sin alerta. Los administradores responden en la página de la solicitud; la respuesta se guarda en el espacio de trabajo del usuario y se envía por Telegram cuando las notificaciones de soporte están habilitadas.",
            "El bot usa botones en línea para el menú principal, tiendas, notificaciones, soporte, seguridad e idioma. La navegación edita el mensaje actual; un menú antiguo no disponible se reemplaza. Las notificaciones de pago y seguridad no se tratan como navegación desechable. Cerrar sesión a través del menú requiere confirmación. El comando explícito /logout sigue terminando cada sesión de cuenta.",
            "El panel /admin/project está restringido a IDs de Telegram en la lista de permitidos MODERATOR_TELEGRAM_IDS del lado del servidor. Incluye usuarios, tiendas, operaciones, revocación de claves, deshabilitación de webhooks, pausa de facturas, controles de aceptación y un registro de auditoría. Las mutaciones requieren CSRF y un motivo. El panel no puede restringir a un administrador ni declarar manualmente un pago como exitoso. Restringir a un propietario termina las sesiones y bloquea el acceso a claves de API; restringir una tienda detiene nuevas operaciones. El historial se conserva.",
            "La oferta pública está disponible en /public-offer y la política de privacidad en /privacy-policy en cada idioma habilitado. Busca monedas por nombre o ticker. Un selector de red aparece solo cuando hay múltiples redes en vivo disponibles. Una sola red se selecciona automáticamente y permanece nombrada en la confirmación. La disponibilidad en vivo de la pasarela determina los pares seleccionables; el catálogo de referencia no habilita un servicio.",
            "Usa update.sh para lanzamientos rutinarios de la aplicación web: compila el candidato, verifica el historial de migraciones, haz una copia de seguridad de SQLite en línea, inicia un segundo contenedor, verifícalo y cambia Caddy sin interrupciones. La pasarela, PostgreSQL y el correo no se reinician. Los activos estáticos anteriores siguen disponibles para pestañas abiertas. Una nueva migración requiere autorización revisada explícita; un cambio de esquema incompatible no es un despliegue sin interrupciones."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Oferta pública",
              "href": "/public-offer"
            },
            {
              "label": "Política de privacidad",
              "href": "/privacy-policy"
            }
          ]
        }
      ],
      "body": "Inicio de sesión\n\nLa solicitud dura cinco minutos. Inicie una nueva solicitud si expira. Una solicitud antigua no puede reutilizarse para obtener una sesión.\n\nAbra Iniciar sesión o Crear cuenta y seleccione Continuar con Telegram.\n\nSiga el enlace del bot creado por este navegador.\n\nCompare el código de seis dígitos en el sitio web y en el mensaje del bot.\n\nConfirme en el chat privado.\n\nVuelva al navegador original. Su cuenta se abre después de la verificación.\n\nPor qué importa el navegador original\n\nEl enlace de Telegram está vinculado a una cookie protegida en el navegador que inició la sesión. Un challengeId o un enlace reenviado por sí solo no puede crear una sesión en otro dispositivo.\n\nPuede confirmar en Telegram desde otro dispositivo, pero la cuenta se abre en el navegador donde comenzó el inicio de sesión. No confirme una solicitud que usted no inició.\n\nSesiones y cierre de sesión\n\nUna sesión dura hasta 24 horas. Su token aleatorio se almacena en una cookie Secure HttpOnly y no puede ser leído por JavaScript. El cierre de sesión en el sitio web finaliza la sesión actual.\n\nEl comando del bot /logout finaliza todas las sesiones de la cuenta y cancela confirmaciones no utilizadas. Un nuevo inicio de sesión requiere una nueva solicitud.\n\nSolución de problemas de inicio de sesión\n\nSituación · Acción\nEl enlace expiró · Inicie una nueva solicitud en el sitio web\nHay un navegador diferente abierto · Vuelva a la pestaña donde comenzó el inicio de sesión\nLos códigos difieren · No confirme; comience de nuevo\nInicio de sesión no disponible · Intente más tarde o contacte al soporte\nError de red temporal · Espere la siguiente verificación o reintente el inicio de sesión\n\nInformación utilizada para el inicio de sesión\n\nEl servidor recibe un ID de Telegram verificado y campos de perfil disponibles para crear la cuenta. Un nombre de usuario público por sí solo no es prueba de identidad.\n\nEl bot no solicita su contraseña de Telegram, códigos bancarios, CVV, frase semilla ni claves privadas.\n\nAPI de autenticación\n\nIniciar sesión\n\nAsistencia, soporte y administración de proyectos\n\nHabilitar Permite el acceso a mis datos en el chat cuando necesites ayuda con operaciones privadas. Una solicitud web con includeAccount=true requiere una sesión válida, Origin y X-CSRF-Token; X-Kevmi-Store selecciona una tienda propia o todas las tiendas propias. Sin permiso, el asistente usa documentación pública. En Telegram, un botón separado habilita el acceso después de identificar al remitente.\n\nLa herramienta read_account lee tiendas propias, facturas con estado de recibo verificado, eventos, solicitudes y solicitudes de soporte con respuestas de especialistas. Devuelve 30 registros y nextPage; los registros más antiguos están disponibles mediante paginación. Las lecturas por respuesta están limitadas, por lo que una muestra incompleta debe revelarse. Las claves de API, secretos de webhook, datos de tarjetas y sesiones no se proporcionan a la herramienta. No puede cobrar, pagar, reembolsar ni cambiar la configuración.\n\nCrear una solicitud de soporte en el espacio de trabajo o en Telegram coloca una alerta de administrador separada en una cola duradera. Se enlaza a /admin/tickets?ticket=<id>; los fallos temporales de Telegram se reintentan. La recuperación también recoge solicitudes abiertas antiguas sin alerta. Los administradores responden en la página de la solicitud; la respuesta se guarda en el espacio de trabajo del usuario y se envía por Telegram cuando las notificaciones de soporte están habilitadas.\n\nEl bot usa botones en línea para el menú principal, tiendas, notificaciones, soporte, seguridad e idioma. La navegación edita el mensaje actual; un menú antiguo no disponible se reemplaza. Las notificaciones de pago y seguridad no se tratan como navegación desechable. Cerrar sesión a través del menú requiere confirmación. El comando explícito /logout sigue terminando cada sesión de cuenta.\n\nEl panel /admin/project está restringido a IDs de Telegram en la lista de permitidos MODERATOR_TELEGRAM_IDS del lado del servidor. Incluye usuarios, tiendas, operaciones, revocación de claves, deshabilitación de webhooks, pausa de facturas, controles de aceptación y un registro de auditoría. Las mutaciones requieren CSRF y un motivo. El panel no puede restringir a un administrador ni declarar manualmente un pago como exitoso. Restringir a un propietario termina las sesiones y bloquea el acceso a claves de API; restringir una tienda detiene nuevas operaciones. El historial se conserva.\n\nLa oferta pública está disponible en /public-offer y la política de privacidad en /privacy-policy en cada idioma habilitado. Busca monedas por nombre o ticker. Un selector de red aparece solo cuando hay múltiples redes en vivo disponibles. Una sola red se selecciona automáticamente y permanece nombrada en la confirmación. La disponibilidad en vivo de la pasarela determina los pares seleccionables; el catálogo de referencia no habilita un servicio.\n\nUsa update.sh para lanzamientos rutinarios de la aplicación web: compila el candidato, verifica el historial de migraciones, haz una copia de seguridad de SQLite en línea, inicia un segundo contenedor, verifícalo y cambia Caddy sin interrupciones. La pasarela, PostgreSQL y el correo no se reinician. Los activos estáticos anteriores siguen disponibles para pestañas abiertas. Una nueva migración requiere autorización revisada explícita; un cambio de esquema incompatible no es un despliegue sin interrupciones.\n\nOferta pública\n\nPolítica de privacidad",
      "readMinutes": 3
    },
    {
      "id": "settings",
      "title": "Configuración de la tienda",
      "summary": "Configuración: vincula el nombre de tu tienda, la regla de IVA y las notificaciones a tu cuenta verificada. Los cambios se guardan en el servidor para el usuario actual.",
      "group": "account",
      "url": "/docs/settings",
      "tags": [
        "configuración",
        "tienda",
        "Contribuyente de IVA",
        "tema",
        "notificaciones"
      ],
      "sections": [
        {
          "id": "name",
          "title": "Nombre de la tienda",
          "paragraphs": [
            "Elige un nombre corto y reconocible que tu cliente espere ver en el pedido. El nombre debe contener de 1 a 80 caracteres después de eliminar los espacios circundantes.",
            "Un nombre para mostrar no reemplaza los datos legales ni tu acuerdo con el cliente. Mantén secretos, credenciales de pago e información personal de otras personas fuera de este campo."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "vat",
          "title": "Contribuyente de IVA",
          "paragraphs": [
            "El pagador predeterminado es el cliente. El IVA aplica solo a tarjetas y Alipay. Cambiar la configuración no modifica los totales de SBP ni de criptomonedas.",
            "Las facturas existentes conservan sus términos guardados. Al crear una factura, el IVA del cliente y las participaciones de tarifas del 0 al 100% pueden anular los valores predeterminados. La preferencia de la tienda solo proporciona un valor predeterminado para facturas futuras.",
            "Una preferencia guardada no amplía las capacidades de la pasarela. Los canales actuales de tarjeta en vivo y Alipay requieren 100% de IVA del cliente y 0% de tarifa de procesamiento del cliente; otras asignaciones guardadas permanecen como cálculos."
          ],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Valor",
              "Regla para una factura nueva"
            ],
            "rows": [
              [
                "cliente",
                "El IVA se añade al precio base del cliente"
              ],
              [
                "comerciante",
                "El comerciante cubre el IVA desde el precio base"
              ]
            ]
          },
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "notifications",
          "title": "Notificaciones de Telegram",
          "paragraphs": [
            "Selecciona las categorías de pagos, pagos, soporte y seguridad. Elegir una categoría controla las notificaciones; no activa un canal de pago ni genera eventos financieros.",
            "Un mensaje de prueba verifica la entrega al chat privado vinculado. Su estado aparece en el centro de notificaciones y en GET /api/notifications. Un mensaje en cola aún no se ha entregado; también revisa Telegram."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Guía de notificaciones",
              "href": "/docs/notifications"
            }
          ]
        },
        {
          "id": "saving",
          "title": "Guardado y errores",
          "paragraphs": [
            "El formulario confirma un guardado completado. Si la red falla, tu entrada permanece disponible para reintentar; presionar Guardar solo no prueba que el cambio se haya almacenado.",
            "Inicia sesión de nuevo cuando tu sesión expire. El servidor identifica la cuenta a partir de la sesión y no acepta otro ID de propietario de tienda desde el navegador."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "local",
          "title": "Tema y datos de demostración",
          "paragraphs": [
            "El tema de visualización se guarda localmente en el dispositivo. El espacio de trabajo de demostración utiliza datos de navegador separados y no cambia la cuenta del servidor.",
            "Restablecer la demostración elimina solo los registros de prueba en ese navegador. Una exportación de demostración no es un estado de cuenta bancario ni una prueba de pago."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "stores-usd",
          "title": "Múltiples tiendas y un precio base en USD",
          "paragraphs": [
            "Elija Todas las tiendas para análisis y operaciones agregados, o seleccione una tienda para sus propios registros. Cada tienda tiene un storeId, nombre, IVA predeterminado, facturas, claves de API, endpoints de webhook, historial de eventos y aplicación web separados. Las notificaciones y tickets de soporte pertenecen a la cuenta. Una cuenta puede crear hasta 100 tiendas. Los registros existentes permanecen en su primera tienda.",
            "Las facturas del nuevo espacio de trabajo usan pricingMode=\"universal\" y un precio base en USD. Any incluye tarjeta, alipay, sbp y cripto; un comerciante puede seleccionar un subconjunto. Tarjetas y Alipay cobran en USD. SBP cobra en RUB usando el tipo de referencia USD/RUB del Banco de Rusia. Cripto cobra USDT bajo la regla explícita de factura 1 USD = 1 USDT. Esta es una regla de conversión de factura, no una cotización de mercado de USDT. La pasarela proporciona la tasa de la moneda seleccionada, el monto exacto de transferencia y las instrucciones antes de la transferencia.",
            "El tipo de referencia y ambos montos se congelan al crear. Las facturas que implican conversión de RUB vencen dentro de 24 horas. Si no se puede obtener el tipo de referencia, la creación falla con FX_UNAVAILABLE; no se usa ningún tipo de respaldo inventado o desactualizado. El monto en minor del propietario y las cotizaciones usan la moneda contable USD. quotes[method].settlement contiene la cotización de cargo nativa. El checkout público expone la moneda de cargo seleccionada en currency, el precio original en baseAmountMinor/baseCurrency y el tipo de referencia en fx. Una vez que un pago ha sido despachado, su método no se puede cambiar; una factura tiene una operación de pasarela.",
            "Cree una clave de API dentro de la tienda prevista y envíe Authorization: Bearer <key> desde su servidor. Su vinculación a tienda es inmutable; X-Kevmi-Store no puede otorgarle acceso a otra tienda. Las sesiones del navegador seleccionan X-Kevmi-Store: <storeId>; omitirlo selecciona la primera tienda. El valor all solo es aceptado por GET /api/account/dashboard y GET /api/payment-links. Las mutaciones requieren una tienda seleccionada, Origin y X-CSRF-Token. Los IDs de cuenta y los IDs de tienda son identificadores diferentes.",
            "Por compatibilidad, las solicitudes de API sin pricingMode=\"universal\" conservan el precio nativo y las restricciones de moneda originales. Las facturas existentes nunca se recalculan. Los recibos confirmados en análisis reflejan pagos verificados menos gastos de factura guardados; no son un saldo retirable. Las monedas de factura heredadas permanecen separadas y los pagos se gestionan con soporte. Cumpla un pedido solo después de verificar payment.fulfillmentReady=true y payment.status=\"succeeded\" a través de la API del servidor, el historial de eventos o un webhook firmado."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "assistant-admin-v16",
          "title": "Asistencia, soporte y administración de proyectos",
          "paragraphs": [
            "Habilitar Permite el acceso a mis datos en el chat cuando necesites ayuda con operaciones privadas. Una solicitud web con includeAccount=true requiere una sesión válida, Origin y X-CSRF-Token; X-Kevmi-Store selecciona una tienda propia o todas las tiendas propias. Sin permiso, el asistente usa documentación pública. En Telegram, un botón separado habilita el acceso después de identificar al remitente.",
            "La herramienta read_account lee tiendas propias, facturas con estado de recibo verificado, eventos, solicitudes y solicitudes de soporte con respuestas de especialistas. Devuelve 30 registros y nextPage; los registros más antiguos están disponibles mediante paginación. Las lecturas por respuesta están limitadas, por lo que una muestra incompleta debe revelarse. Las claves de API, secretos de webhook, datos de tarjetas y sesiones no se proporcionan a la herramienta. No puede cobrar, pagar, reembolsar ni cambiar la configuración.",
            "Crear una solicitud de soporte en el espacio de trabajo o en Telegram coloca una alerta de administrador separada en una cola duradera. Se enlaza a /admin/tickets?ticket=<id>; los fallos temporales de Telegram se reintentan. La recuperación también recoge solicitudes abiertas antiguas sin alerta. Los administradores responden en la página de la solicitud; la respuesta se guarda en el espacio de trabajo del usuario y se envía por Telegram cuando las notificaciones de soporte están habilitadas.",
            "El bot usa botones en línea para el menú principal, tiendas, notificaciones, soporte, seguridad e idioma. La navegación edita el mensaje actual; un menú antiguo no disponible se reemplaza. Las notificaciones de pago y seguridad no se tratan como navegación desechable. Cerrar sesión a través del menú requiere confirmación. El comando explícito /logout sigue terminando cada sesión de cuenta.",
            "El panel /admin/project está restringido a IDs de Telegram en la lista de permitidos MODERATOR_TELEGRAM_IDS del lado del servidor. Incluye usuarios, tiendas, operaciones, revocación de claves, deshabilitación de webhooks, pausa de facturas, controles de aceptación y un registro de auditoría. Las mutaciones requieren CSRF y un motivo. El panel no puede restringir a un administrador ni declarar manualmente un pago como exitoso. Restringir a un propietario termina las sesiones y bloquea el acceso a claves de API; restringir una tienda detiene nuevas operaciones. El historial se conserva.",
            "La oferta pública está disponible en /public-offer y la política de privacidad en /privacy-policy en cada idioma habilitado. Busca monedas por nombre o ticker. Un selector de red aparece solo cuando hay múltiples redes en vivo disponibles. Una sola red se selecciona automáticamente y permanece nombrada en la confirmación. La disponibilidad en vivo de la pasarela determina los pares seleccionables; el catálogo de referencia no habilita un servicio.",
            "Usa update.sh para lanzamientos rutinarios de la aplicación web: compila el candidato, verifica el historial de migraciones, haz una copia de seguridad de SQLite en línea, inicia un segundo contenedor, verifícalo y cambia Caddy sin interrupciones. La pasarela, PostgreSQL y el correo no se reinician. Los activos estáticos anteriores siguen disponibles para pestañas abiertas. Una nueva migración requiere autorización revisada explícita; un cambio de esquema incompatible no es un despliegue sin interrupciones."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Oferta pública",
              "href": "/public-offer"
            },
            {
              "label": "Política de privacidad",
              "href": "/privacy-policy"
            }
          ]
        }
      ],
      "body": "Nombre de la tienda\n\nElige un nombre corto y reconocible que tu cliente espere ver en el pedido. El nombre debe contener de 1 a 80 caracteres después de eliminar los espacios circundantes.\n\nUn nombre para mostrar no reemplaza los datos legales ni tu acuerdo con el cliente. Mantén secretos, credenciales de pago e información personal de otras personas fuera de este campo.\n\nContribuyente de IVA\n\nEl pagador predeterminado es el cliente. El IVA aplica solo a tarjetas y Alipay. Cambiar la configuración no modifica los totales de SBP ni de criptomonedas.\n\nLas facturas existentes conservan sus términos guardados. Al crear una factura, el IVA del cliente y las participaciones de tarifas del 0 al 100% pueden anular los valores predeterminados. La preferencia de la tienda solo proporciona un valor predeterminado para facturas futuras.\n\nUna preferencia guardada no amplía las capacidades de la pasarela. Los canales actuales de tarjeta en vivo y Alipay requieren 100% de IVA del cliente y 0% de tarifa de procesamiento del cliente; otras asignaciones guardadas permanecen como cálculos.\n\nValor · Regla para una factura nueva\ncliente · El IVA se añade al precio base del cliente\ncomerciante · El comerciante cubre el IVA desde el precio base\n\nNotificaciones de Telegram\n\nSelecciona las categorías de pagos, pagos, soporte y seguridad. Elegir una categoría controla las notificaciones; no activa un canal de pago ni genera eventos financieros.\n\nUn mensaje de prueba verifica la entrega al chat privado vinculado. Su estado aparece en el centro de notificaciones y en GET /api/notifications. Un mensaje en cola aún no se ha entregado; también revisa Telegram.\n\nGuía de notificaciones\n\nGuardado y errores\n\nEl formulario confirma un guardado completado. Si la red falla, tu entrada permanece disponible para reintentar; presionar Guardar solo no prueba que el cambio se haya almacenado.\n\nInicia sesión de nuevo cuando tu sesión expire. El servidor identifica la cuenta a partir de la sesión y no acepta otro ID de propietario de tienda desde el navegador.\n\nTema y datos de demostración\n\nEl tema de visualización se guarda localmente en el dispositivo. El espacio de trabajo de demostración utiliza datos de navegador separados y no cambia la cuenta del servidor.\n\nRestablecer la demostración elimina solo los registros de prueba en ese navegador. Una exportación de demostración no es un estado de cuenta bancario ni una prueba de pago.\n\nMúltiples tiendas y un precio base en USD\n\nElija Todas las tiendas para análisis y operaciones agregados, o seleccione una tienda para sus propios registros. Cada tienda tiene un storeId, nombre, IVA predeterminado, facturas, claves de API, endpoints de webhook, historial de eventos y aplicación web separados. Las notificaciones y tickets de soporte pertenecen a la cuenta. Una cuenta puede crear hasta 100 tiendas. Los registros existentes permanecen en su primera tienda.\n\nLas facturas del nuevo espacio de trabajo usan pricingMode=\"universal\" y un precio base en USD. Any incluye tarjeta, alipay, sbp y cripto; un comerciante puede seleccionar un subconjunto. Tarjetas y Alipay cobran en USD. SBP cobra en RUB usando el tipo de referencia USD/RUB del Banco de Rusia. Cripto cobra USDT bajo la regla explícita de factura 1 USD = 1 USDT. Esta es una regla de conversión de factura, no una cotización de mercado de USDT. La pasarela proporciona la tasa de la moneda seleccionada, el monto exacto de transferencia y las instrucciones antes de la transferencia.\n\nEl tipo de referencia y ambos montos se congelan al crear. Las facturas que implican conversión de RUB vencen dentro de 24 horas. Si no se puede obtener el tipo de referencia, la creación falla con FX_UNAVAILABLE; no se usa ningún tipo de respaldo inventado o desactualizado. El monto en minor del propietario y las cotizaciones usan la moneda contable USD. quotes[method].settlement contiene la cotización de cargo nativa. El checkout público expone la moneda de cargo seleccionada en currency, el precio original en baseAmountMinor/baseCurrency y el tipo de referencia en fx. Una vez que un pago ha sido despachado, su método no se puede cambiar; una factura tiene una operación de pasarela.\n\nCree una clave de API dentro de la tienda prevista y envíe Authorization: Bearer <key> desde su servidor. Su vinculación a tienda es inmutable; X-Kevmi-Store no puede otorgarle acceso a otra tienda. Las sesiones del navegador seleccionan X-Kevmi-Store: <storeId>; omitirlo selecciona la primera tienda. El valor all solo es aceptado por GET /api/account/dashboard y GET /api/payment-links. Las mutaciones requieren una tienda seleccionada, Origin y X-CSRF-Token. Los IDs de cuenta y los IDs de tienda son identificadores diferentes.\n\nPor compatibilidad, las solicitudes de API sin pricingMode=\"universal\" conservan el precio nativo y las restricciones de moneda originales. Las facturas existentes nunca se recalculan. Los recibos confirmados en análisis reflejan pagos verificados menos gastos de factura guardados; no son un saldo retirable. Las monedas de factura heredadas permanecen separadas y los pagos se gestionan con soporte. Cumpla un pedido solo después de verificar payment.fulfillmentReady=true y payment.status=\"succeeded\" a través de la API del servidor, el historial de eventos o un webhook firmado.\n\nAsistencia, soporte y administración de proyectos\n\nHabilitar Permite el acceso a mis datos en el chat cuando necesites ayuda con operaciones privadas. Una solicitud web con includeAccount=true requiere una sesión válida, Origin y X-CSRF-Token; X-Kevmi-Store selecciona una tienda propia o todas las tiendas propias. Sin permiso, el asistente usa documentación pública. En Telegram, un botón separado habilita el acceso después de identificar al remitente.\n\nLa herramienta read_account lee tiendas propias, facturas con estado de recibo verificado, eventos, solicitudes y solicitudes de soporte con respuestas de especialistas. Devuelve 30 registros y nextPage; los registros más antiguos están disponibles mediante paginación. Las lecturas por respuesta están limitadas, por lo que una muestra incompleta debe revelarse. Las claves de API, secretos de webhook, datos de tarjetas y sesiones no se proporcionan a la herramienta. No puede cobrar, pagar, reembolsar ni cambiar la configuración.\n\nCrear una solicitud de soporte en el espacio de trabajo o en Telegram coloca una alerta de administrador separada en una cola duradera. Se enlaza a /admin/tickets?ticket=<id>; los fallos temporales de Telegram se reintentan. La recuperación también recoge solicitudes abiertas antiguas sin alerta. Los administradores responden en la página de la solicitud; la respuesta se guarda en el espacio de trabajo del usuario y se envía por Telegram cuando las notificaciones de soporte están habilitadas.\n\nEl bot usa botones en línea para el menú principal, tiendas, notificaciones, soporte, seguridad e idioma. La navegación edita el mensaje actual; un menú antiguo no disponible se reemplaza. Las notificaciones de pago y seguridad no se tratan como navegación desechable. Cerrar sesión a través del menú requiere confirmación. El comando explícito /logout sigue terminando cada sesión de cuenta.\n\nEl panel /admin/project está restringido a IDs de Telegram en la lista de permitidos MODERATOR_TELEGRAM_IDS del lado del servidor. Incluye usuarios, tiendas, operaciones, revocación de claves, deshabilitación de webhooks, pausa de facturas, controles de aceptación y un registro de auditoría. Las mutaciones requieren CSRF y un motivo. El panel no puede restringir a un administrador ni declarar manualmente un pago como exitoso. Restringir a un propietario termina las sesiones y bloquea el acceso a claves de API; restringir una tienda detiene nuevas operaciones. El historial se conserva.\n\nLa oferta pública está disponible en /public-offer y la política de privacidad en /privacy-policy en cada idioma habilitado. Busca monedas por nombre o ticker. Un selector de red aparece solo cuando hay múltiples redes en vivo disponibles. Una sola red se selecciona automáticamente y permanece nombrada en la confirmación. La disponibilidad en vivo de la pasarela determina los pares seleccionables; el catálogo de referencia no habilita un servicio.\n\nUsa update.sh para lanzamientos rutinarios de la aplicación web: compila el candidato, verifica el historial de migraciones, haz una copia de seguridad de SQLite en línea, inicia un segundo contenedor, verifícalo y cambia Caddy sin interrupciones. La pasarela, PostgreSQL y el correo no se reinician. Los activos estáticos anteriores siguen disponibles para pestañas abiertas. Una nueva migración requiere autorización revisada explícita; un cambio de esquema incompatible no es un despliegue sin interrupciones.\n\nOferta pública\n\nPolítica de privacidad",
      "readMinutes": 3
    },
    {
      "id": "notifications",
      "title": "Notificaciones del sitio web y Telegram",
      "summary": "Los eventos de la cuenta aparecen bajo la campana en la barra superior. Lee las notificaciones, verifica la entrega de Telegram y abre la parte relevante de tu espacio de trabajo.",
      "group": "account",
      "url": "/docs/notifications",
      "tags": [
        "notificaciones",
        "Telegram",
        "campana",
        "leer",
        "entrega"
      ],
      "sections": [
        {
          "id": "inbox",
          "title": "Centro de notificaciones",
          "paragraphs": [
            "La insignia cuenta los eventos de cuenta no leídos. Los mensajes se agrupan por fecha; Cargar más recupera registros más antiguos. Se solicita a los visitantes iniciar sesión.",
            "El estado de lectura se almacena en el servidor. Las páginas visibles se actualizan automáticamente y las pestañas abiertas sincronizan las marcas de lectura. Los eventos más recientes que el último mensaje mostrado no se marcan como leídos junto con los más antiguos."
          ],
          "bullets": [],
          "steps": [
            "Selecciona la campana en la barra superior.",
            "Elige todos los eventos o solo no leídos.",
            "Abre la página relacionada o marca un mensaje como leído.",
            "Usa Marcar todos como leídos para los eventos ya cargados."
          ],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "types",
          "title": "Categorías de eventos",
          "paragraphs": [
            "Soporte y seguridad están habilitados para una cuenta nueva; las categorías de pago son seleccionadas por el usuario. El centro muestra eventos guardados para categorías habilitadas. Los eventos de demostración del navegador no son notificaciones de fondos reales."
          ],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Categoría",
              "Contenido"
            ],
            "rows": [
              [
                "Pagos",
                "Eventos de pago confirmados"
              ],
              [
                "Pagos",
                "Eventos de pago confirmados"
              ],
              [
                "Soporte",
                "Solicitudes de soporte y actualizaciones de etapa de solicitud"
              ],
              [
                "Seguridad",
                "Un nuevo inicio de sesión verificado"
              ],
              [
                "Prueba",
                "Verificación de entrega a tu Telegram"
              ]
            ]
          },
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "setup",
          "title": "Configuración de la entrega",
          "paragraphs": [
            "Las pruebas están limitadas a tres por cuenta por hora. Una prueba no cambia un saldo ni crea un pago. Poner un mensaje en cola no prueba la entrega."
          ],
          "bullets": [],
          "steps": [
            "Inicia sesión con Telegram y abre Cuenta → Notificaciones.",
            "Habilita las categorías deseadas y guarda.",
            "Selecciona Probar entrega.",
            "Revisa el estado del centro y el chat privado del bot."
          ],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Configuración de notificaciones",
              "href": "/account#notifications"
            }
          ]
        },
        {
          "id": "statuses",
          "title": "El estado de entrega y el de lectura son independientes",
          "paragraphs": [
            "La entrega depende de la disponibilidad de Telegram y de los permisos del usuario. Una respuesta perdida puede provocar un mensaje repetido, pero no una operación financiera repetida.",
            "Si la entrega falla, compruebe que el bot está accesible y no está bloqueado. Los reintentos de notificación de la aplicación también se ejecutan en tareas en segundo plano; las interacciones de servicio pueden activar otras entregas en cola. Consulte el centro de notificaciones para ver el estado actual."
          ],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Estado",
              "Significado"
            ],
            "rows": [
              [
                "pendiente",
                "En cola para procesamiento"
              ],
              [
                "enviando",
                "El servidor está intentando la entrega"
              ],
              [
                "enviado",
                "Telegram confirmó el envío"
              ],
              [
                "fallido",
                "Error de entrega"
              ]
            ]
          },
          "code": null,
          "note": "El estado de entrega del mensaje se refiere a Telegram. Marcar una notificación como leída en el sitio web no significa que se haya leído en Telegram y no cambia la entrega.",
          "links": []
        },
        {
          "id": "feedback",
          "title": "Confirmaciones de acciones",
          "paragraphs": [
            "El sitio web muestra una notificación breve después de un guardado, un nuevo enlace o una acción similar. Se cierra automáticamente y permanece más tiempo al pasar el cursor o enfocarla.",
            "Esto confirma la acción de la interfaz. No sustituye un estado financiero confirmado ni crea un registro de pago. Los errores de campo permanecen junto al formulario."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "api",
          "title": "Lectura y marcado a través de la API",
          "paragraphs": [
            "GET /api/notifications devuelve hasta 30 eventos de cuenta, unreadCount y nextCursor. Pase nextCursor sin cambios como cursor para cargar otra página. unread=1 selecciona entradas no leídas. El orden de clasificación es createdAt descendente y luego id descendente.",
            "PATCH /api/notifications/read acepta 1–100 ids, o all:true con before establecido en la marca de tiempo en milisegundos del último evento mostrado. Se requieren una sesión, Origin y X-CSRF-Token. El cliente no puede establecer el propietario del registro.",
            "La respuesta contiene updated, readAt y unreadCount. Leer un evento ya leído conserva su readAt original. Listar eventos no los marca como leídos; el estado de Telegram y sentAt permanecen sin cambios."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": {
            "language": "JSON · mark selected",
            "code": "{\n  \"ids\": [\"ntf_46d94180-492e-4c28-b15f-a70049161a63\"]\n}"
          },
          "note": "",
          "links": [
            {
              "label": "Referencia de la API",
              "href": "/docs/api-reference"
            }
          ]
        },
        {
          "id": "commands",
          "title": "Comandos del bot",
          "paragraphs": [],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Comando",
              "Acción"
            ],
            "rows": [
              [
                "/notifications",
                "Gestionar categorías"
              ],
              [
                "/stop",
                "Desactivar notificaciones"
              ],
              [
                "/help",
                "Listar comandos disponibles"
              ],
              [
                "/logout",
                "Finalizar todas las sesiones de la cuenta"
              ]
            ]
          },
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "availability",
          "title": "Disponibilidad de funciones",
          "paragraphs": [
            "El centro de notificaciones requiere iniciar sesión. Los mensajes de Telegram se envían al chat privado verificado del bot. Si la entrega no está disponible, compruebe los permisos del bot y el estado del mensaje.",
            "Una notificación de pago o de retiro se basa en un evento de servidor confirmado. Seleccionar una categoría cambia las preferencias de entrega, no la disponibilidad de transacciones."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "assistant-admin-v16",
          "title": "Asistencia, soporte y administración de proyectos",
          "paragraphs": [
            "Habilitar Permite el acceso a mis datos en el chat cuando necesites ayuda con operaciones privadas. Una solicitud web con includeAccount=true requiere una sesión válida, Origin y X-CSRF-Token; X-Kevmi-Store selecciona una tienda propia o todas las tiendas propias. Sin permiso, el asistente usa documentación pública. En Telegram, un botón separado habilita el acceso después de identificar al remitente.",
            "La herramienta read_account lee tiendas propias, facturas con estado de recibo verificado, eventos, solicitudes y solicitudes de soporte con respuestas de especialistas. Devuelve 30 registros y nextPage; los registros más antiguos están disponibles mediante paginación. Las lecturas por respuesta están limitadas, por lo que una muestra incompleta debe revelarse. Las claves de API, secretos de webhook, datos de tarjetas y sesiones no se proporcionan a la herramienta. No puede cobrar, pagar, reembolsar ni cambiar la configuración.",
            "Crear una solicitud de soporte en el espacio de trabajo o en Telegram coloca una alerta de administrador separada en una cola duradera. Se enlaza a /admin/tickets?ticket=<id>; los fallos temporales de Telegram se reintentan. La recuperación también recoge solicitudes abiertas antiguas sin alerta. Los administradores responden en la página de la solicitud; la respuesta se guarda en el espacio de trabajo del usuario y se envía por Telegram cuando las notificaciones de soporte están habilitadas.",
            "El bot usa botones en línea para el menú principal, tiendas, notificaciones, soporte, seguridad e idioma. La navegación edita el mensaje actual; un menú antiguo no disponible se reemplaza. Las notificaciones de pago y seguridad no se tratan como navegación desechable. Cerrar sesión a través del menú requiere confirmación. El comando explícito /logout sigue terminando cada sesión de cuenta.",
            "El panel /admin/project está restringido a IDs de Telegram en la lista de permitidos MODERATOR_TELEGRAM_IDS del lado del servidor. Incluye usuarios, tiendas, operaciones, revocación de claves, deshabilitación de webhooks, pausa de facturas, controles de aceptación y un registro de auditoría. Las mutaciones requieren CSRF y un motivo. El panel no puede restringir a un administrador ni declarar manualmente un pago como exitoso. Restringir a un propietario termina las sesiones y bloquea el acceso a claves de API; restringir una tienda detiene nuevas operaciones. El historial se conserva.",
            "La oferta pública está disponible en /public-offer y la política de privacidad en /privacy-policy en cada idioma habilitado. Busca monedas por nombre o ticker. Un selector de red aparece solo cuando hay múltiples redes en vivo disponibles. Una sola red se selecciona automáticamente y permanece nombrada en la confirmación. La disponibilidad en vivo de la pasarela determina los pares seleccionables; el catálogo de referencia no habilita un servicio.",
            "Usa update.sh para lanzamientos rutinarios de la aplicación web: compila el candidato, verifica el historial de migraciones, haz una copia de seguridad de SQLite en línea, inicia un segundo contenedor, verifícalo y cambia Caddy sin interrupciones. La pasarela, PostgreSQL y el correo no se reinician. Los activos estáticos anteriores siguen disponibles para pestañas abiertas. Una nueva migración requiere autorización revisada explícita; un cambio de esquema incompatible no es un despliegue sin interrupciones."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Oferta pública",
              "href": "/public-offer"
            },
            {
              "label": "Política de privacidad",
              "href": "/privacy-policy"
            }
          ]
        }
      ],
      "body": "Centro de notificaciones\n\nLa insignia cuenta los eventos de cuenta no leídos. Los mensajes se agrupan por fecha; Cargar más recupera registros más antiguos. Se solicita a los visitantes iniciar sesión.\n\nEl estado de lectura se almacena en el servidor. Las páginas visibles se actualizan automáticamente y las pestañas abiertas sincronizan las marcas de lectura. Los eventos más recientes que el último mensaje mostrado no se marcan como leídos junto con los más antiguos.\n\nSelecciona la campana en la barra superior.\n\nElige todos los eventos o solo no leídos.\n\nAbre la página relacionada o marca un mensaje como leído.\n\nUsa Marcar todos como leídos para los eventos ya cargados.\n\nCategorías de eventos\n\nSoporte y seguridad están habilitados para una cuenta nueva; las categorías de pago son seleccionadas por el usuario. El centro muestra eventos guardados para categorías habilitadas. Los eventos de demostración del navegador no son notificaciones de fondos reales.\n\nCategoría · Contenido\nPagos · Eventos de pago confirmados\nPagos · Eventos de pago confirmados\nSoporte · Solicitudes de soporte y actualizaciones de etapa de solicitud\nSeguridad · Un nuevo inicio de sesión verificado\nPrueba · Verificación de entrega a tu Telegram\n\nConfiguración de la entrega\n\nLas pruebas están limitadas a tres por cuenta por hora. Una prueba no cambia un saldo ni crea un pago. Poner un mensaje en cola no prueba la entrega.\n\nInicia sesión con Telegram y abre Cuenta → Notificaciones.\n\nHabilita las categorías deseadas y guarda.\n\nSelecciona Probar entrega.\n\nRevisa el estado del centro y el chat privado del bot.\n\nConfiguración de notificaciones\n\nEl estado de entrega y el de lectura son independientes\n\nLa entrega depende de la disponibilidad de Telegram y de los permisos del usuario. Una respuesta perdida puede provocar un mensaje repetido, pero no una operación financiera repetida.\n\nSi la entrega falla, compruebe que el bot está accesible y no está bloqueado. Los reintentos de notificación de la aplicación también se ejecutan en tareas en segundo plano; las interacciones de servicio pueden activar otras entregas en cola. Consulte el centro de notificaciones para ver el estado actual.\n\nEstado · Significado\npendiente · En cola para procesamiento\nenviando · El servidor está intentando la entrega\nenviado · Telegram confirmó el envío\nfallido · Error de entrega\n\nEl estado de entrega del mensaje se refiere a Telegram. Marcar una notificación como leída en el sitio web no significa que se haya leído en Telegram y no cambia la entrega.\n\nConfirmaciones de acciones\n\nEl sitio web muestra una notificación breve después de un guardado, un nuevo enlace o una acción similar. Se cierra automáticamente y permanece más tiempo al pasar el cursor o enfocarla.\n\nEsto confirma la acción de la interfaz. No sustituye un estado financiero confirmado ni crea un registro de pago. Los errores de campo permanecen junto al formulario.\n\nLectura y marcado a través de la API\n\nGET /api/notifications devuelve hasta 30 eventos de cuenta, unreadCount y nextCursor. Pase nextCursor sin cambios como cursor para cargar otra página. unread=1 selecciona entradas no leídas. El orden de clasificación es createdAt descendente y luego id descendente.\n\nPATCH /api/notifications/read acepta 1–100 ids, o all:true con before establecido en la marca de tiempo en milisegundos del último evento mostrado. Se requieren una sesión, Origin y X-CSRF-Token. El cliente no puede establecer el propietario del registro.\n\nLa respuesta contiene updated, readAt y unreadCount. Leer un evento ya leído conserva su readAt original. Listar eventos no los marca como leídos; el estado de Telegram y sentAt permanecen sin cambios.\n\n{\n  \"ids\": [\"ntf_46d94180-492e-4c28-b15f-a70049161a63\"]\n}\n\nReferencia de la API\n\nComandos del bot\n\nComando · Acción\n/notifications · Gestionar categorías\n/stop · Desactivar notificaciones\n/help · Listar comandos disponibles\n/logout · Finalizar todas las sesiones de la cuenta\n\nDisponibilidad de funciones\n\nEl centro de notificaciones requiere iniciar sesión. Los mensajes de Telegram se envían al chat privado verificado del bot. Si la entrega no está disponible, compruebe los permisos del bot y el estado del mensaje.\n\nUna notificación de pago o de retiro se basa en un evento de servidor confirmado. Seleccionar una categoría cambia las preferencias de entrega, no la disponibilidad de transacciones.\n\nAsistencia, soporte y administración de proyectos\n\nHabilitar Permite el acceso a mis datos en el chat cuando necesites ayuda con operaciones privadas. Una solicitud web con includeAccount=true requiere una sesión válida, Origin y X-CSRF-Token; X-Kevmi-Store selecciona una tienda propia o todas las tiendas propias. Sin permiso, el asistente usa documentación pública. En Telegram, un botón separado habilita el acceso después de identificar al remitente.\n\nLa herramienta read_account lee tiendas propias, facturas con estado de recibo verificado, eventos, solicitudes y solicitudes de soporte con respuestas de especialistas. Devuelve 30 registros y nextPage; los registros más antiguos están disponibles mediante paginación. Las lecturas por respuesta están limitadas, por lo que una muestra incompleta debe revelarse. Las claves de API, secretos de webhook, datos de tarjetas y sesiones no se proporcionan a la herramienta. No puede cobrar, pagar, reembolsar ni cambiar la configuración.\n\nCrear una solicitud de soporte en el espacio de trabajo o en Telegram coloca una alerta de administrador separada en una cola duradera. Se enlaza a /admin/tickets?ticket=<id>; los fallos temporales de Telegram se reintentan. La recuperación también recoge solicitudes abiertas antiguas sin alerta. Los administradores responden en la página de la solicitud; la respuesta se guarda en el espacio de trabajo del usuario y se envía por Telegram cuando las notificaciones de soporte están habilitadas.\n\nEl bot usa botones en línea para el menú principal, tiendas, notificaciones, soporte, seguridad e idioma. La navegación edita el mensaje actual; un menú antiguo no disponible se reemplaza. Las notificaciones de pago y seguridad no se tratan como navegación desechable. Cerrar sesión a través del menú requiere confirmación. El comando explícito /logout sigue terminando cada sesión de cuenta.\n\nEl panel /admin/project está restringido a IDs de Telegram en la lista de permitidos MODERATOR_TELEGRAM_IDS del lado del servidor. Incluye usuarios, tiendas, operaciones, revocación de claves, deshabilitación de webhooks, pausa de facturas, controles de aceptación y un registro de auditoría. Las mutaciones requieren CSRF y un motivo. El panel no puede restringir a un administrador ni declarar manualmente un pago como exitoso. Restringir a un propietario termina las sesiones y bloquea el acceso a claves de API; restringir una tienda detiene nuevas operaciones. El historial se conserva.\n\nLa oferta pública está disponible en /public-offer y la política de privacidad en /privacy-policy en cada idioma habilitado. Busca monedas por nombre o ticker. Un selector de red aparece solo cuando hay múltiples redes en vivo disponibles. Una sola red se selecciona automáticamente y permanece nombrada en la confirmación. La disponibilidad en vivo de la pasarela determina los pares seleccionables; el catálogo de referencia no habilita un servicio.\n\nUsa update.sh para lanzamientos rutinarios de la aplicación web: compila el candidato, verifica el historial de migraciones, haz una copia de seguridad de SQLite en línea, inicia un segundo contenedor, verifícalo y cambia Caddy sin interrupciones. La pasarela, PostgreSQL y el correo no se reinician. Los activos estáticos anteriores siguen disponibles para pestañas abiertas. Una nueva migración requiere autorización revisada explícita; un cambio de esquema incompatible no es un despliegue sin interrupciones.\n\nOferta pública\n\nPolítica de privacidad",
      "readMinutes": 4
    },
    {
      "id": "support",
      "title": "Chat de soporte y solicitudes",
      "summary": "El asistente explica los términos de Kevmi, encuentra la página correcta y ayuda con la configuración. Abra el chat usando el botón redondo en la parte inferior derecha. Use una solicitud privada para una pregunta específica de la cuenta.",
      "group": "account",
      "url": "/docs/support",
      "tags": [
        "soporte",
        "ayuda",
        "AI",
        "asistente",
        "documentación",
        "solicitud",
        "chat"
      ],
      "sections": [
        {
          "id": "chat",
          "title": "Ayuda en la página actual",
          "paragraphs": [
            "En teléfonos, el chat se abre en un panel compacto. Puede minimizarlo y reabrirlo; aparece una insignia si llega una respuesta mientras está cerrado.",
            "El soporte se abre en la página actual. La antigua dirección /help redirige a la página de inicio con el chat abierto."
          ],
          "bullets": [],
          "steps": [
            "Seleccione el botón redondo de soporte en la parte inferior derecha o Haga su pregunta.",
            "Abra una conversación existente o inicie una nueva. Elija una sugerencia o escriba una pregunta: Enter envía; Shift + Enter añade una línea.",
            "Lea la respuesta y siga sus fuentes de documentación.",
            "Minimice el chat para seguir trabajando. Los mensajes y el borrador permanecen en este navegador."
          ],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Abrir chat de soporte",
              "href": "/?support=open"
            }
          ]
        },
        {
          "id": "history",
          "title": "Conversaciones, borradores e historial",
          "paragraphs": [
            "Mantenga cada tema en una conversación separada. Busque en el historial por título o texto, renombre una conversación y fije las importantes. Una conversación nueva conserva los chats anteriores, y cada una mantiene su propio borrador.",
            "Restablezca una conversación desde Eliminadas, o elimínela permanentemente después de la confirmación. El historial se almacena en el navegador de este dispositivo, sobrevive a las recargas de página y no se sincroniza entre dispositivos, su cuenta o Telegram. Borrar los datos del sitio en el navegador elimina el historial local.",
            "Si el almacenamiento del navegador no está disponible, el chat continúa en la memoria de la página abierta. Las conversaciones locales son independientes de las solicitudes de soporte privadas, que se almacenan en el servidor después de iniciar sesión."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "knowledge",
          "title": "En qué se basan las respuestas",
          "paragraphs": [
            "El sitio web y el bot usan una base de conocimiento con versiones. El servidor proporciona guías publicadas, precios estructurados, datos de asignación y de países, el catálogo de páginas y la disponibilidad real de funciones al asistente generativo. La base incluye aplicaciones, claves de API, widgets y webhooks.",
            "Las fuentes de las respuestas solo se refieren a artículos de esa base. Cuando la información confirmada es insuficiente, el asistente lo dice y sugiere una pregunta más específica o una solicitud de soporte. No inventa países, tiempos de retiro, límites ni obligaciones fiscales."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "context",
          "title": "Preguntas de seguimiento y contexto",
          "paragraphs": [
            "La siguiente pregunta incluye los últimos tres pares de pregunta y respuesta de la conversación seleccionada, lo que ayuda con seguimientos como \"¿Qué pasa si el comerciante paga el IVA?\". Otro historial local no se adjunta automáticamente a la solicitud.",
            "También se envía una etiqueta corta de sección, como Precios o Pago. La URL, los parámetros de consulta y el token de factura se excluyen. Los mensajes anteriores son contexto no confiable y se verifican contra la base de conocimiento."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "modes",
          "title": "IA y búsqueda en documentación",
          "paragraphs": [
            "El modo IA usa un proveedor configurado, almacenamiento del servidor y una cuota disponible. /api/config informa la preparación de la configuración; la conectividad del modelo se verifica en una solicitud. La generación no disponible, la cuota agotada o una respuesta inválida recurren a la búsqueda de documentación etiquetada.",
            "La búsqueda también funciona sin un modelo externo. Los registros privados requieren permiso explícito del propietario y son de solo lectura. Sin permiso solo está disponible la información pública. No puede cobrar fondos, crear pagos ni cambiar configuración."
          ],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Modo",
              "Comportamiento"
            ],
            "rows": [
              [
                "ai",
                "Escribe una respuesta a partir del conocimiento publicado completo y enlaza guías relevantes"
              ],
              [
                "búsqueda",
                "Devuelve documentación publicada que coincide"
              ]
            ]
          },
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "question",
          "title": "Hacer una pregunta útil",
          "paragraphs": [
            "Por ejemplo: «Un pedido de tarjeta de $5, con IVA pagado por el comerciante. ¿Qué recibe el comerciante?» Verifica las cifras exactas en la calculadora publicada.",
            "El campo de chat acepta hasta 1.800 caracteres. Si la conexión falla, la pregunta permanece en el campo para otro intento."
          ],
          "bullets": [
            "Nombra el método: tarjeta, SBP, Alipay o criptomoneda.",
            "Para un cálculo, indica el monto base y ambas partes del costo del cliente: tarifa e IVA.",
            "Para un error, nombra la página, la acción y el mensaje mostrado.",
            "No envíes contraseñas, códigos de inicio de sesión, tokens, CVV ni frases semilla."
          ],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "request",
          "title": "Preguntar mediante la API",
          "paragraphs": [
            "POST /api/support/ask acepta una pregunta de 2 a 2.000 caracteres después de recortar. El historial opcional contiene hasta seis mensajes con role=user o role=assistant. Los mensajes de usuario aceptan de 1 a 1.800 caracteres y los de asistente de 1 a 3.000.",
            "El pageContext opcional es una etiqueta de sección de 1 a 80 caracteres, sin URLs, tokens, parámetros de consulta ni saltos de línea. El locale opcional es ru, en, es, de o fr y selecciona el idioma de la respuesta. El inglés es el predeterminado; las fuentes técnicas completas están disponibles en ruso e inglés. La API no acepta mensajes de sistema, herramientas ni instrucciones arbitrarias del proveedor.",
            "El límite del cuerpo JSON es de 65.536 bytes. La respuesta contiene mode, answer, sources, knowledgeVersion y needsHuman, con aiUnavailable:true cuando la generación no está disponible. No se necesita sesión de usuario; un Origin proporcionado debe coincidir con la aplicación."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Contrato de API",
              "href": "/docs/api-reference"
            }
          ]
        },
        {
          "id": "ticket",
          "title": "Solicitudes de soporte privadas",
          "paragraphs": [
            "Después de iniciar sesión, crea una solicitud con un asunto de 1 a 120 caracteres y un mensaje de 5 a 4.000 caracteres. Se guarda en tu cuenta y no es visible para otro usuario.",
            "La lista muestra las 30 solicitudes más recientes. Puedes cerrar tu propia solicitud. Conserva su referencia al preguntar por el estado; el tiempo de resolución depende del problema."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Mis solicitudes de soporte",
              "href": "/account#support"
            }
          ]
        },
        {
          "id": "assistant-admin-v16",
          "title": "Asistencia, soporte y administración de proyectos",
          "paragraphs": [
            "Habilitar Permite el acceso a mis datos en el chat cuando necesites ayuda con operaciones privadas. Una solicitud web con includeAccount=true requiere una sesión válida, Origin y X-CSRF-Token; X-Kevmi-Store selecciona una tienda propia o todas las tiendas propias. Sin permiso, el asistente usa documentación pública. En Telegram, un botón separado habilita el acceso después de identificar al remitente.",
            "La herramienta read_account lee tiendas propias, facturas con estado de recibo verificado, eventos, solicitudes y solicitudes de soporte con respuestas de especialistas. Devuelve 30 registros y nextPage; los registros más antiguos están disponibles mediante paginación. Las lecturas por respuesta están limitadas, por lo que una muestra incompleta debe revelarse. Las claves de API, secretos de webhook, datos de tarjetas y sesiones no se proporcionan a la herramienta. No puede cobrar, pagar, reembolsar ni cambiar la configuración.",
            "Crear una solicitud de soporte en el espacio de trabajo o en Telegram coloca una alerta de administrador separada en una cola duradera. Se enlaza a /admin/tickets?ticket=<id>; los fallos temporales de Telegram se reintentan. La recuperación también recoge solicitudes abiertas antiguas sin alerta. Los administradores responden en la página de la solicitud; la respuesta se guarda en el espacio de trabajo del usuario y se envía por Telegram cuando las notificaciones de soporte están habilitadas.",
            "El bot usa botones en línea para el menú principal, tiendas, notificaciones, soporte, seguridad e idioma. La navegación edita el mensaje actual; un menú antiguo no disponible se reemplaza. Las notificaciones de pago y seguridad no se tratan como navegación desechable. Cerrar sesión a través del menú requiere confirmación. El comando explícito /logout sigue terminando cada sesión de cuenta.",
            "El panel /admin/project está restringido a IDs de Telegram en la lista de permitidos MODERATOR_TELEGRAM_IDS del lado del servidor. Incluye usuarios, tiendas, operaciones, revocación de claves, deshabilitación de webhooks, pausa de facturas, controles de aceptación y un registro de auditoría. Las mutaciones requieren CSRF y un motivo. El panel no puede restringir a un administrador ni declarar manualmente un pago como exitoso. Restringir a un propietario termina las sesiones y bloquea el acceso a claves de API; restringir una tienda detiene nuevas operaciones. El historial se conserva.",
            "La oferta pública está disponible en /public-offer y la política de privacidad en /privacy-policy en cada idioma habilitado. Busca monedas por nombre o ticker. Un selector de red aparece solo cuando hay múltiples redes en vivo disponibles. Una sola red se selecciona automáticamente y permanece nombrada en la confirmación. La disponibilidad en vivo de la pasarela determina los pares seleccionables; el catálogo de referencia no habilita un servicio.",
            "Usa update.sh para lanzamientos rutinarios de la aplicación web: compila el candidato, verifica el historial de migraciones, haz una copia de seguridad de SQLite en línea, inicia un segundo contenedor, verifícalo y cambia Caddy sin interrupciones. La pasarela, PostgreSQL y el correo no se reinician. Los activos estáticos anteriores siguen disponibles para pestañas abiertas. Una nueva migración requiere autorización revisada explícita; un cambio de esquema incompatible no es un despliegue sin interrupciones."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Oferta pública",
              "href": "/public-offer"
            },
            {
              "label": "Política de privacidad",
              "href": "/privacy-policy"
            }
          ]
        }
      ],
      "body": "Ayuda en la página actual\n\nEn teléfonos, el chat se abre en un panel compacto. Puede minimizarlo y reabrirlo; aparece una insignia si llega una respuesta mientras está cerrado.\n\nEl soporte se abre en la página actual. La antigua dirección /help redirige a la página de inicio con el chat abierto.\n\nSeleccione el botón redondo de soporte en la parte inferior derecha o Haga su pregunta.\n\nAbra una conversación existente o inicie una nueva. Elija una sugerencia o escriba una pregunta: Enter envía; Shift + Enter añade una línea.\n\nLea la respuesta y siga sus fuentes de documentación.\n\nMinimice el chat para seguir trabajando. Los mensajes y el borrador permanecen en este navegador.\n\nAbrir chat de soporte\n\nConversaciones, borradores e historial\n\nMantenga cada tema en una conversación separada. Busque en el historial por título o texto, renombre una conversación y fije las importantes. Una conversación nueva conserva los chats anteriores, y cada una mantiene su propio borrador.\n\nRestablezca una conversación desde Eliminadas, o elimínela permanentemente después de la confirmación. El historial se almacena en el navegador de este dispositivo, sobrevive a las recargas de página y no se sincroniza entre dispositivos, su cuenta o Telegram. Borrar los datos del sitio en el navegador elimina el historial local.\n\nSi el almacenamiento del navegador no está disponible, el chat continúa en la memoria de la página abierta. Las conversaciones locales son independientes de las solicitudes de soporte privadas, que se almacenan en el servidor después de iniciar sesión.\n\nEn qué se basan las respuestas\n\nEl sitio web y el bot usan una base de conocimiento con versiones. El servidor proporciona guías publicadas, precios estructurados, datos de asignación y de países, el catálogo de páginas y la disponibilidad real de funciones al asistente generativo. La base incluye aplicaciones, claves de API, widgets y webhooks.\n\nLas fuentes de las respuestas solo se refieren a artículos de esa base. Cuando la información confirmada es insuficiente, el asistente lo dice y sugiere una pregunta más específica o una solicitud de soporte. No inventa países, tiempos de retiro, límites ni obligaciones fiscales.\n\nPreguntas de seguimiento y contexto\n\nLa siguiente pregunta incluye los últimos tres pares de pregunta y respuesta de la conversación seleccionada, lo que ayuda con seguimientos como \"¿Qué pasa si el comerciante paga el IVA?\". Otro historial local no se adjunta automáticamente a la solicitud.\n\nTambién se envía una etiqueta corta de sección, como Precios o Pago. La URL, los parámetros de consulta y el token de factura se excluyen. Los mensajes anteriores son contexto no confiable y se verifican contra la base de conocimiento.\n\nIA y búsqueda en documentación\n\nEl modo IA usa un proveedor configurado, almacenamiento del servidor y una cuota disponible. /api/config informa la preparación de la configuración; la conectividad del modelo se verifica en una solicitud. La generación no disponible, la cuota agotada o una respuesta inválida recurren a la búsqueda de documentación etiquetada.\n\nLa búsqueda también funciona sin un modelo externo. Los registros privados requieren permiso explícito del propietario y son de solo lectura. Sin permiso solo está disponible la información pública. No puede cobrar fondos, crear pagos ni cambiar configuración.\n\nModo · Comportamiento\nai · Escribe una respuesta a partir del conocimiento publicado completo y enlaza guías relevantes\nbúsqueda · Devuelve documentación publicada que coincide\n\nHacer una pregunta útil\n\nPor ejemplo: «Un pedido de tarjeta de $5, con IVA pagado por el comerciante. ¿Qué recibe el comerciante?» Verifica las cifras exactas en la calculadora publicada.\n\nEl campo de chat acepta hasta 1.800 caracteres. Si la conexión falla, la pregunta permanece en el campo para otro intento.\n\nNombra el método: tarjeta, SBP, Alipay o criptomoneda.\n\nPara un cálculo, indica el monto base y ambas partes del costo del cliente: tarifa e IVA.\n\nPara un error, nombra la página, la acción y el mensaje mostrado.\n\nNo envíes contraseñas, códigos de inicio de sesión, tokens, CVV ni frases semilla.\n\nPreguntar mediante la API\n\nPOST /api/support/ask acepta una pregunta de 2 a 2.000 caracteres después de recortar. El historial opcional contiene hasta seis mensajes con role=user o role=assistant. Los mensajes de usuario aceptan de 1 a 1.800 caracteres y los de asistente de 1 a 3.000.\n\nEl pageContext opcional es una etiqueta de sección de 1 a 80 caracteres, sin URLs, tokens, parámetros de consulta ni saltos de línea. El locale opcional es ru, en, es, de o fr y selecciona el idioma de la respuesta. El inglés es el predeterminado; las fuentes técnicas completas están disponibles en ruso e inglés. La API no acepta mensajes de sistema, herramientas ni instrucciones arbitrarias del proveedor.\n\nEl límite del cuerpo JSON es de 65.536 bytes. La respuesta contiene mode, answer, sources, knowledgeVersion y needsHuman, con aiUnavailable:true cuando la generación no está disponible. No se necesita sesión de usuario; un Origin proporcionado debe coincidir con la aplicación.\n\nContrato de API\n\nSolicitudes de soporte privadas\n\nDespués de iniciar sesión, crea una solicitud con un asunto de 1 a 120 caracteres y un mensaje de 5 a 4.000 caracteres. Se guarda en tu cuenta y no es visible para otro usuario.\n\nLa lista muestra las 30 solicitudes más recientes. Puedes cerrar tu propia solicitud. Conserva su referencia al preguntar por el estado; el tiempo de resolución depende del problema.\n\nMis solicitudes de soporte\n\nAsistencia, soporte y administración de proyectos\n\nHabilitar Permite el acceso a mis datos en el chat cuando necesites ayuda con operaciones privadas. Una solicitud web con includeAccount=true requiere una sesión válida, Origin y X-CSRF-Token; X-Kevmi-Store selecciona una tienda propia o todas las tiendas propias. Sin permiso, el asistente usa documentación pública. En Telegram, un botón separado habilita el acceso después de identificar al remitente.\n\nLa herramienta read_account lee tiendas propias, facturas con estado de recibo verificado, eventos, solicitudes y solicitudes de soporte con respuestas de especialistas. Devuelve 30 registros y nextPage; los registros más antiguos están disponibles mediante paginación. Las lecturas por respuesta están limitadas, por lo que una muestra incompleta debe revelarse. Las claves de API, secretos de webhook, datos de tarjetas y sesiones no se proporcionan a la herramienta. No puede cobrar, pagar, reembolsar ni cambiar la configuración.\n\nCrear una solicitud de soporte en el espacio de trabajo o en Telegram coloca una alerta de administrador separada en una cola duradera. Se enlaza a /admin/tickets?ticket=<id>; los fallos temporales de Telegram se reintentan. La recuperación también recoge solicitudes abiertas antiguas sin alerta. Los administradores responden en la página de la solicitud; la respuesta se guarda en el espacio de trabajo del usuario y se envía por Telegram cuando las notificaciones de soporte están habilitadas.\n\nEl bot usa botones en línea para el menú principal, tiendas, notificaciones, soporte, seguridad e idioma. La navegación edita el mensaje actual; un menú antiguo no disponible se reemplaza. Las notificaciones de pago y seguridad no se tratan como navegación desechable. Cerrar sesión a través del menú requiere confirmación. El comando explícito /logout sigue terminando cada sesión de cuenta.\n\nEl panel /admin/project está restringido a IDs de Telegram en la lista de permitidos MODERATOR_TELEGRAM_IDS del lado del servidor. Incluye usuarios, tiendas, operaciones, revocación de claves, deshabilitación de webhooks, pausa de facturas, controles de aceptación y un registro de auditoría. Las mutaciones requieren CSRF y un motivo. El panel no puede restringir a un administrador ni declarar manualmente un pago como exitoso. Restringir a un propietario termina las sesiones y bloquea el acceso a claves de API; restringir una tienda detiene nuevas operaciones. El historial se conserva.\n\nLa oferta pública está disponible en /public-offer y la política de privacidad en /privacy-policy en cada idioma habilitado. Busca monedas por nombre o ticker. Un selector de red aparece solo cuando hay múltiples redes en vivo disponibles. Una sola red se selecciona automáticamente y permanece nombrada en la confirmación. La disponibilidad en vivo de la pasarela determina los pares seleccionables; el catálogo de referencia no habilita un servicio.\n\nUsa update.sh para lanzamientos rutinarios de la aplicación web: compila el candidato, verifica el historial de migraciones, haz una copia de seguridad de SQLite en línea, inicia un segundo contenedor, verifícalo y cambia Caddy sin interrupciones. La pasarela, PostgreSQL y el correo no se reinician. Los activos estáticos anteriores siguen disponibles para pestañas abiertas. Una nueva migración requiere autorización revisada explícita; un cambio de esquema incompatible no es un despliegue sin interrupciones.\n\nOferta pública\n\nPolítica de privacidad",
      "readMinutes": 6
    },
    {
      "id": "api-reference",
      "title": "Referencia de la API",
      "summary": "La API del servidor admite cuentas, facturas, pago seguro, estados y webhooks. OpenAPI describe rutas, campos y errores. Iniciar un pago requiere una pasarela configurada, un comerciante aprobado y términos de factura compatibles.",
      "group": "developers",
      "url": "/docs/api-reference",
      "tags": [
        "API",
        "OpenAPI",
        "endpoint",
        "referencia",
        "JSON"
      ],
      "sections": [
        {
          "id": "base",
          "title": "URL base y formato",
          "paragraphs": [
            "The base URL is https://kevmi.one. Request and response bodies use JSON. Money values are integer minor units. Account and support dates are Unix timestamps in milliseconds.",
            "Las respuestas de API usan Cache-Control: no-store. El /openapi.json público puede almacenarse en caché durante cinco minutos. No coloques cookies ni secretos en una URL."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": {
            "language": "cURL",
            "code": "curl 'https://kevmi.one/api/config'\n\ncurl 'https://kevmi.one/openapi.json'"
          },
          "note": "",
          "links": []
        },
        {
          "id": "session",
          "title": "Autorización de solicitudes",
          "paragraphs": [
            "La cuenta web usa una cookie de sesión HttpOnly. GET /api/auth/me devuelve el usuario actual y csrfToken. Las mutaciones requieren X-CSRF-Token y una solicitud de mismo origen.",
            "Las claves de comerciante Kevmi con alcance autorizan /api/v1/payments, /api/v1/payment-links y /api/v1/events. No reemplazan la cookie de sesión para los ajustes de cuenta ni las rutas administrativas."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": {
            "language": "JavaScript · website browser",
            "code": "const me = await fetch('/api/auth/me').then(r => r.json());\nif (!me.authenticated) throw new Error('Sign in required');\nconst response = await fetch('/api/account/settings', {\n  method: 'PATCH',\n  headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': me.csrfToken },\n  body: JSON.stringify({ vatPayer: 'merchant' })\n});\nif (!response.ok) throw new Error('Settings were not saved');\nconst updated = await response.json();"
          },
          "note": "",
          "links": []
        },
        {
          "id": "groups",
          "title": "Grupos de endpoints",
          "paragraphs": [
            "GET /api/config informa la presencia de la configuración del servidor. GET /api/checkout/{token} devuelve la disponibilidad de la factura para el método seleccionado, incluida la aprobación del comerciante y los términos guardados. Estas comprobaciones no establecen la conectividad del proveedor ni el éxito del pago: el resultado proviene de la operación verificada de la pasarela."
          ],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Grupo",
              "Propósito"
            ],
            "rows": [
              [
                "Configuración y estado",
                "Disponibilidad del servicio público y del almacenamiento"
              ],
              [
                "Autenticación",
                "Desafíos y sesiones de Telegram"
              ],
              [
                "Cuenta",
                "Ajustes y la aplicación privada del comerciante"
              ],
              [
                "/api/v1/payments",
                "Creación y lectura de facturas de servidor con alcance; no inicia un cargo"
              ],
              [
                "/api/v1/events",
                "Registro de eventos del servidor con events:read"
              ],
              [
                "Integraciones",
                "Administración de claves y endpoints de webhook autenticados por sesión"
              ],
              [
                "Aplicaciones y moderación",
                "Envíos propios, seguimiento de estado y permisos de moderador separados"
              ],
              [
                "Pago",
                "Factura pública, solicitud de tarjeta cifrada, operación concreta, código bancario, estado y conciliación"
              ],
              [
                "Entrada de pasarela",
                "Notificaciones v3 firmadas y verificación de operación autenticada"
              ],
              [
                "Soporte y notificaciones",
                "Preguntas, solicitudes privadas, eventos y estado de lectura"
              ],
              [
                "Telegram",
                "Webhook de bot verificado"
              ],
              [
                "Rutas de dinero no compatibles",
                "Los /api/payments y /api/payouts directos heredados no crean un cargo ni un pago"
              ]
            ]
          },
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "support-example",
          "title": "Una solicitud de conocimiento pública",
          "paragraphs": [
            "La respuesta incluye mode, answer, sources, knowledgeVersion y needsHuman. Un Origin proporcionado debe coincidir con el origen de la aplicación. Un agente de documentación del lado del servidor puede omitir Origin."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": {
            "language": "cURL",
            "code": "curl 'https://kevmi.one/api/support/ask' \\\n  -H 'Content-Type: application/json' \\\n  --data '{\"question\":\"Who pays VAT?\",\"locale\":\"en\"}'"
          },
          "note": "",
          "links": []
        },
        {
          "id": "errors",
          "title": "Errores y límites",
          "paragraphs": [
            "Un error incluye un código legible por máquina y un mensaje. Los campos de solicitud desconocidos se rechazan. Los cuerpos JSON estándar permiten 16.384 bytes; /api/support/ask y el webhook de Telegram permiten 65.536.",
            "429 indica un límite de velocidad. 503 puede indicar una integración no disponible, no un pago rechazado. Lee error.code y no cambies un estado financiero solo por un código de estado HTTP."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Códigos de error",
              "href": "/docs/errors"
            },
            {
              "label": "Especificación OpenAPI completa",
              "href": "/openapi.json"
            }
          ]
        },
        {
          "id": "stores-usd",
          "title": "Múltiples tiendas y un precio base en USD",
          "paragraphs": [
            "Elija Todas las tiendas para análisis y operaciones agregados, o seleccione una tienda para sus propios registros. Cada tienda tiene un storeId, nombre, IVA predeterminado, facturas, claves de API, endpoints de webhook, historial de eventos y aplicación web separados. Las notificaciones y tickets de soporte pertenecen a la cuenta. Una cuenta puede crear hasta 100 tiendas. Los registros existentes permanecen en su primera tienda.",
            "Las facturas del nuevo espacio de trabajo usan pricingMode=\"universal\" y un precio base en USD. Any incluye tarjeta, alipay, sbp y cripto; un comerciante puede seleccionar un subconjunto. Tarjetas y Alipay cobran en USD. SBP cobra en RUB usando el tipo de referencia USD/RUB del Banco de Rusia. Cripto cobra USDT bajo la regla explícita de factura 1 USD = 1 USDT. Esta es una regla de conversión de factura, no una cotización de mercado de USDT. La pasarela proporciona la tasa de la moneda seleccionada, el monto exacto de transferencia y las instrucciones antes de la transferencia.",
            "El tipo de referencia y ambos montos se congelan al crear. Las facturas que implican conversión de RUB vencen dentro de 24 horas. Si no se puede obtener el tipo de referencia, la creación falla con FX_UNAVAILABLE; no se usa ningún tipo de respaldo inventado o desactualizado. El monto en minor del propietario y las cotizaciones usan la moneda contable USD. quotes[method].settlement contiene la cotización de cargo nativa. El checkout público expone la moneda de cargo seleccionada en currency, el precio original en baseAmountMinor/baseCurrency y el tipo de referencia en fx. Una vez que un pago ha sido despachado, su método no se puede cambiar; una factura tiene una operación de pasarela.",
            "Cree una clave de API dentro de la tienda prevista y envíe Authorization: Bearer <key> desde su servidor. Su vinculación a tienda es inmutable; X-Kevmi-Store no puede otorgarle acceso a otra tienda. Las sesiones del navegador seleccionan X-Kevmi-Store: <storeId>; omitirlo selecciona la primera tienda. El valor all solo es aceptado por GET /api/account/dashboard y GET /api/payment-links. Las mutaciones requieren una tienda seleccionada, Origin y X-CSRF-Token. Los IDs de cuenta y los IDs de tienda son identificadores diferentes.",
            "Por compatibilidad, las solicitudes de API sin pricingMode=\"universal\" conservan el precio nativo y las restricciones de moneda originales. Las facturas existentes nunca se recalculan. Los recibos confirmados en análisis reflejan pagos verificados menos gastos de factura guardados; no son un saldo retirable. Las monedas de factura heredadas permanecen separadas y los pagos se gestionan con soporte. Cumpla un pedido solo después de verificar payment.fulfillmentReady=true y payment.status=\"succeeded\" a través de la API del servidor, el historial de eventos o un webhook firmado."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": {
            "language": "json",
            "code": "{\n  \"pricingMode\": \"universal\",\n  \"title\": \"Order 1042\",\n  \"amountMinor\": 1000,\n  \"currency\": \"USD\",\n  \"methods\": [\n    \"card\",\n    \"alipay\",\n    \"sbp\",\n    \"crypto\"\n  ],\n  \"vatCustomerPercent\": 100,\n  \"feeCustomerPercent\": 0\n}"
          },
          "note": "",
          "links": []
        },
        {
          "id": "assistant-admin-v16",
          "title": "Asistencia, soporte y administración de proyectos",
          "paragraphs": [
            "Habilitar Permite el acceso a mis datos en el chat cuando necesites ayuda con operaciones privadas. Una solicitud web con includeAccount=true requiere una sesión válida, Origin y X-CSRF-Token; X-Kevmi-Store selecciona una tienda propia o todas las tiendas propias. Sin permiso, el asistente usa documentación pública. En Telegram, un botón separado habilita el acceso después de identificar al remitente.",
            "La herramienta read_account lee tiendas propias, facturas con estado de recibo verificado, eventos, solicitudes y solicitudes de soporte con respuestas de especialistas. Devuelve 30 registros y nextPage; los registros más antiguos están disponibles mediante paginación. Las lecturas por respuesta están limitadas, por lo que una muestra incompleta debe revelarse. Las claves de API, secretos de webhook, datos de tarjetas y sesiones no se proporcionan a la herramienta. No puede cobrar, pagar, reembolsar ni cambiar la configuración.",
            "Crear una solicitud de soporte en el espacio de trabajo o en Telegram coloca una alerta de administrador separada en una cola duradera. Se enlaza a /admin/tickets?ticket=<id>; los fallos temporales de Telegram se reintentan. La recuperación también recoge solicitudes abiertas antiguas sin alerta. Los administradores responden en la página de la solicitud; la respuesta se guarda en el espacio de trabajo del usuario y se envía por Telegram cuando las notificaciones de soporte están habilitadas.",
            "El bot usa botones en línea para el menú principal, tiendas, notificaciones, soporte, seguridad e idioma. La navegación edita el mensaje actual; un menú antiguo no disponible se reemplaza. Las notificaciones de pago y seguridad no se tratan como navegación desechable. Cerrar sesión a través del menú requiere confirmación. El comando explícito /logout sigue terminando cada sesión de cuenta.",
            "El panel /admin/project está restringido a IDs de Telegram en la lista de permitidos MODERATOR_TELEGRAM_IDS del lado del servidor. Incluye usuarios, tiendas, operaciones, revocación de claves, deshabilitación de webhooks, pausa de facturas, controles de aceptación y un registro de auditoría. Las mutaciones requieren CSRF y un motivo. El panel no puede restringir a un administrador ni declarar manualmente un pago como exitoso. Restringir a un propietario termina las sesiones y bloquea el acceso a claves de API; restringir una tienda detiene nuevas operaciones. El historial se conserva.",
            "La oferta pública está disponible en /public-offer y la política de privacidad en /privacy-policy en cada idioma habilitado. Busca monedas por nombre o ticker. Un selector de red aparece solo cuando hay múltiples redes en vivo disponibles. Una sola red se selecciona automáticamente y permanece nombrada en la confirmación. La disponibilidad en vivo de la pasarela determina los pares seleccionables; el catálogo de referencia no habilita un servicio.",
            "Usa update.sh para lanzamientos rutinarios de la aplicación web: compila el candidato, verifica el historial de migraciones, haz una copia de seguridad de SQLite en línea, inicia un segundo contenedor, verifícalo y cambia Caddy sin interrupciones. La pasarela, PostgreSQL y el correo no se reinician. Los activos estáticos anteriores siguen disponibles para pestañas abiertas. Una nueva migración requiere autorización revisada explícita; un cambio de esquema incompatible no es un despliegue sin interrupciones."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Oferta pública",
              "href": "/public-offer"
            },
            {
              "label": "Política de privacidad",
              "href": "/privacy-policy"
            }
          ]
        }
      ],
      "body": "URL base y formato\n\nThe base URL is https://kevmi.one. Request and response bodies use JSON. Money values are integer minor units. Account and support dates are Unix timestamps in milliseconds.\n\nLas respuestas de API usan Cache-Control: no-store. El /openapi.json público puede almacenarse en caché durante cinco minutos. No coloques cookies ni secretos en una URL.\n\ncurl 'https://kevmi.one/api/config'\n\ncurl 'https://kevmi.one/openapi.json'\n\nAutorización de solicitudes\n\nLa cuenta web usa una cookie de sesión HttpOnly. GET /api/auth/me devuelve el usuario actual y csrfToken. Las mutaciones requieren X-CSRF-Token y una solicitud de mismo origen.\n\nLas claves de comerciante Kevmi con alcance autorizan /api/v1/payments, /api/v1/payment-links y /api/v1/events. No reemplazan la cookie de sesión para los ajustes de cuenta ni las rutas administrativas.\n\nconst me = await fetch('/api/auth/me').then(r => r.json());\nif (!me.authenticated) throw new Error('Sign in required');\nconst response = await fetch('/api/account/settings', {\n  method: 'PATCH',\n  headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': me.csrfToken },\n  body: JSON.stringify({ vatPayer: 'merchant' })\n});\nif (!response.ok) throw new Error('Settings were not saved');\nconst updated = await response.json();\n\nGrupos de endpoints\n\nGET /api/config informa la presencia de la configuración del servidor. GET /api/checkout/{token} devuelve la disponibilidad de la factura para el método seleccionado, incluida la aprobación del comerciante y los términos guardados. Estas comprobaciones no establecen la conectividad del proveedor ni el éxito del pago: el resultado proviene de la operación verificada de la pasarela.\n\nGrupo · Propósito\nConfiguración y estado · Disponibilidad del servicio público y del almacenamiento\nAutenticación · Desafíos y sesiones de Telegram\nCuenta · Ajustes y la aplicación privada del comerciante\n/api/v1/payments · Creación y lectura de facturas de servidor con alcance; no inicia un cargo\n/api/v1/events · Registro de eventos del servidor con events:read\nIntegraciones · Administración de claves y endpoints de webhook autenticados por sesión\nAplicaciones y moderación · Envíos propios, seguimiento de estado y permisos de moderador separados\nPago · Factura pública, solicitud de tarjeta cifrada, operación concreta, código bancario, estado y conciliación\nEntrada de pasarela · Notificaciones v3 firmadas y verificación de operación autenticada\nSoporte y notificaciones · Preguntas, solicitudes privadas, eventos y estado de lectura\nTelegram · Webhook de bot verificado\nRutas de dinero no compatibles · Los /api/payments y /api/payouts directos heredados no crean un cargo ni un pago\n\nUna solicitud de conocimiento pública\n\nLa respuesta incluye mode, answer, sources, knowledgeVersion y needsHuman. Un Origin proporcionado debe coincidir con el origen de la aplicación. Un agente de documentación del lado del servidor puede omitir Origin.\n\ncurl 'https://kevmi.one/api/support/ask' \\\n  -H 'Content-Type: application/json' \\\n  --data '{\"question\":\"Who pays VAT?\",\"locale\":\"en\"}'\n\nErrores y límites\n\nUn error incluye un código legible por máquina y un mensaje. Los campos de solicitud desconocidos se rechazan. Los cuerpos JSON estándar permiten 16.384 bytes; /api/support/ask y el webhook de Telegram permiten 65.536.\n\n429 indica un límite de velocidad. 503 puede indicar una integración no disponible, no un pago rechazado. Lee error.code y no cambies un estado financiero solo por un código de estado HTTP.\n\nCódigos de error\n\nEspecificación OpenAPI completa\n\nMúltiples tiendas y un precio base en USD\n\nElija Todas las tiendas para análisis y operaciones agregados, o seleccione una tienda para sus propios registros. Cada tienda tiene un storeId, nombre, IVA predeterminado, facturas, claves de API, endpoints de webhook, historial de eventos y aplicación web separados. Las notificaciones y tickets de soporte pertenecen a la cuenta. Una cuenta puede crear hasta 100 tiendas. Los registros existentes permanecen en su primera tienda.\n\nLas facturas del nuevo espacio de trabajo usan pricingMode=\"universal\" y un precio base en USD. Any incluye tarjeta, alipay, sbp y cripto; un comerciante puede seleccionar un subconjunto. Tarjetas y Alipay cobran en USD. SBP cobra en RUB usando el tipo de referencia USD/RUB del Banco de Rusia. Cripto cobra USDT bajo la regla explícita de factura 1 USD = 1 USDT. Esta es una regla de conversión de factura, no una cotización de mercado de USDT. La pasarela proporciona la tasa de la moneda seleccionada, el monto exacto de transferencia y las instrucciones antes de la transferencia.\n\nEl tipo de referencia y ambos montos se congelan al crear. Las facturas que implican conversión de RUB vencen dentro de 24 horas. Si no se puede obtener el tipo de referencia, la creación falla con FX_UNAVAILABLE; no se usa ningún tipo de respaldo inventado o desactualizado. El monto en minor del propietario y las cotizaciones usan la moneda contable USD. quotes[method].settlement contiene la cotización de cargo nativa. El checkout público expone la moneda de cargo seleccionada en currency, el precio original en baseAmountMinor/baseCurrency y el tipo de referencia en fx. Una vez que un pago ha sido despachado, su método no se puede cambiar; una factura tiene una operación de pasarela.\n\nCree una clave de API dentro de la tienda prevista y envíe Authorization: Bearer <key> desde su servidor. Su vinculación a tienda es inmutable; X-Kevmi-Store no puede otorgarle acceso a otra tienda. Las sesiones del navegador seleccionan X-Kevmi-Store: <storeId>; omitirlo selecciona la primera tienda. El valor all solo es aceptado por GET /api/account/dashboard y GET /api/payment-links. Las mutaciones requieren una tienda seleccionada, Origin y X-CSRF-Token. Los IDs de cuenta y los IDs de tienda son identificadores diferentes.\n\nPor compatibilidad, las solicitudes de API sin pricingMode=\"universal\" conservan el precio nativo y las restricciones de moneda originales. Las facturas existentes nunca se recalculan. Los recibos confirmados en análisis reflejan pagos verificados menos gastos de factura guardados; no son un saldo retirable. Las monedas de factura heredadas permanecen separadas y los pagos se gestionan con soporte. Cumpla un pedido solo después de verificar payment.fulfillmentReady=true y payment.status=\"succeeded\" a través de la API del servidor, el historial de eventos o un webhook firmado.\n\n{\n  \"pricingMode\": \"universal\",\n  \"title\": \"Order 1042\",\n  \"amountMinor\": 1000,\n  \"currency\": \"USD\",\n  \"methods\": [\n    \"card\",\n    \"alipay\",\n    \"sbp\",\n    \"crypto\"\n  ],\n  \"vatCustomerPercent\": 100,\n  \"feeCustomerPercent\": 0\n}\n\nAsistencia, soporte y administración de proyectos\n\nHabilitar Permite el acceso a mis datos en el chat cuando necesites ayuda con operaciones privadas. Una solicitud web con includeAccount=true requiere una sesión válida, Origin y X-CSRF-Token; X-Kevmi-Store selecciona una tienda propia o todas las tiendas propias. Sin permiso, el asistente usa documentación pública. En Telegram, un botón separado habilita el acceso después de identificar al remitente.\n\nLa herramienta read_account lee tiendas propias, facturas con estado de recibo verificado, eventos, solicitudes y solicitudes de soporte con respuestas de especialistas. Devuelve 30 registros y nextPage; los registros más antiguos están disponibles mediante paginación. Las lecturas por respuesta están limitadas, por lo que una muestra incompleta debe revelarse. Las claves de API, secretos de webhook, datos de tarjetas y sesiones no se proporcionan a la herramienta. No puede cobrar, pagar, reembolsar ni cambiar la configuración.\n\nCrear una solicitud de soporte en el espacio de trabajo o en Telegram coloca una alerta de administrador separada en una cola duradera. Se enlaza a /admin/tickets?ticket=<id>; los fallos temporales de Telegram se reintentan. La recuperación también recoge solicitudes abiertas antiguas sin alerta. Los administradores responden en la página de la solicitud; la respuesta se guarda en el espacio de trabajo del usuario y se envía por Telegram cuando las notificaciones de soporte están habilitadas.\n\nEl bot usa botones en línea para el menú principal, tiendas, notificaciones, soporte, seguridad e idioma. La navegación edita el mensaje actual; un menú antiguo no disponible se reemplaza. Las notificaciones de pago y seguridad no se tratan como navegación desechable. Cerrar sesión a través del menú requiere confirmación. El comando explícito /logout sigue terminando cada sesión de cuenta.\n\nEl panel /admin/project está restringido a IDs de Telegram en la lista de permitidos MODERATOR_TELEGRAM_IDS del lado del servidor. Incluye usuarios, tiendas, operaciones, revocación de claves, deshabilitación de webhooks, pausa de facturas, controles de aceptación y un registro de auditoría. Las mutaciones requieren CSRF y un motivo. El panel no puede restringir a un administrador ni declarar manualmente un pago como exitoso. Restringir a un propietario termina las sesiones y bloquea el acceso a claves de API; restringir una tienda detiene nuevas operaciones. El historial se conserva.\n\nLa oferta pública está disponible en /public-offer y la política de privacidad en /privacy-policy en cada idioma habilitado. Busca monedas por nombre o ticker. Un selector de red aparece solo cuando hay múltiples redes en vivo disponibles. Una sola red se selecciona automáticamente y permanece nombrada en la confirmación. La disponibilidad en vivo de la pasarela determina los pares seleccionables; el catálogo de referencia no habilita un servicio.\n\nUsa update.sh para lanzamientos rutinarios de la aplicación web: compila el candidato, verifica el historial de migraciones, haz una copia de seguridad de SQLite en línea, inicia un segundo contenedor, verifícalo y cambia Caddy sin interrupciones. La pasarela, PostgreSQL y el correo no se reinician. Los activos estáticos anteriores siguen disponibles para pestañas abiertas. Una nueva migración requiere autorización revisada explícita; un cambio de esquema incompatible no es un despliegue sin interrupciones.\n\nOferta pública\n\nPolítica de privacidad",
      "readMinutes": 4
    },
    {
      "id": "payment-links-api",
      "title": "API de enlaces de pago y claves de API",
      "summary": "Crea una factura desde tu backend y recibe checkoutUrl de inmediato. La API admite claves con alcance, reintentos idempotentes, tarifa e IVA independientes, una referencia de pedido y metadatos privados.",
      "tags": [
        "API",
        "enlace de pago",
        "idempotencia",
        "pago",
        "paginación",
        "clave de API",
        "alcance",
        "metadatos"
      ],
      "sections": [
        {
          "id": "create",
          "title": "Una solicitud de servidor devuelve un enlace listo",
          "paragraphs": [
            "POST /api/v1/payments y /api/v1/payment-links crean el mismo tipo de factura. El nombre de la ruta payments no implica un cargo: el resultado son términos de factura persistidos y una checkoutUrl para el cliente.",
            "Envíe Authorization: Bearer <key>, Content-Type: application/json y Idempotency-Key. Las claves de idempotencia contienen 16–100 letras, dígitos, guiones o guiones bajos. Persista una clave para cada creación lógica de pedido."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": {
            "language": "cURL · server only",
            "code": "curl 'https://kevmi.maxeevmax1.chatgpt.site/api/v1/payments' \\\n  -H \"Authorization: Bearer $KEVMI_API_KEY\" \\\n  -H 'Content-Type: application/json' \\\n  -H 'Idempotency-Key: order-1042-create-v1' \\\n  --data '{\"title\":\"Design project · order 1042\",\"description\":\"One-time payment for the agreed design work\",\"amountMinor\":500,\"currency\":\"USD\",\"methods\":[\"card\",\"alipay\"],\"vatCustomerPercent\":100,\"feeCustomerPercent\":0,\"orderId\":\"order-1042\",\"metadata\":{\"campaign\":\"autumn\"}}'"
          },
          "note": "La respuesta contiene link, checkoutUrl y replayed. Pase checkoutUrl al cliente o widget; mantenga la clave de API en su servidor.",
          "links": []
        },
        {
          "id": "keys",
          "title": "Alcances y caducidad de las claves de API",
          "paragraphs": [
            "Cree una clave en /account#keys en su cuenta de comerciante verificada. Su valor completo aparece una sola vez; solo se almacena un hash. Las claves duran 90 días de forma predeterminada, con una vida útil permitida de 1–365 días y hasta diez claves activas por cuenta.",
            "Otorgue únicamente los alcances necesarios. La revocación o caducidad detiene el acceso. Una clave no reemplaza la sesión del navegador para la configuración de la cuenta, la administración de endpoints, las aplicaciones o la moderación. Manténgala fuera de widgets, URL, repositorios públicos y mensajes de soporte.",
            "El sitio web usa /api/payment-links con su cookie de sesión, Origin exacto y X-CSRF-Token. Esas rutas operan sobre las mismas facturas propiedad de la cuenta."
          ],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Alcance",
              "Propósito"
            ],
            "rows": [
              [
                "invoices:read",
                "Leer facturas propias y su lista"
              ],
              [
                "invoices:write",
                "Crear facturas y cambiar la disponibilidad del enlace"
              ],
              [
                "events:read",
                "Leer el registro de eventos del servidor"
              ]
            ]
          },
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Claves de API en su cuenta",
              "href": "/account#keys"
            }
          ]
        },
        {
          "id": "methods",
          "title": "Any y métodos de API concretos",
          "paragraphs": [
            "Any es un modo de selección de interfaz. Las facturas nuevas aceptan métodos: [\"card\", \"alipay\"] o un subconjunto no vacío para USD; [\"sbp\"] para RUB; [\"crypto\"] para USDT. El valor any no es un método de pago de API.",
            "Para una factura nueva en la interfaz, USD ofrece tarjetas y Alipay; RUB ofrece SBP; USDT ofrece criptomonedas. La API también puede guardar USD + criptomonedas por compatibilidad, pero su pago cripto en vivo está bloqueado con crypto_requires_usdt. USD y USDT son distintos, sin conversión automática ni supuesta tasa 1:1. Un pago cripto requiere una factura USDT separada.",
            "Para un pago nuevo en vivo con tarjeta o Alipay, la pasarela actual solo admite feeCustomerPercent=0 y vatCustomerPercent=100: el comerciante cubre toda la comisión de procesamiento y el IVA se añade completo para el cliente. Otras participaciones se pueden guardar y calcular en una factura, pero la ejecución está bloqueada con unsupported_allocation. El servidor nunca cambia silenciosamente los términos guardados. Los pagos cripto SBP y USDT admiten todas las participaciones de comisión de procesamiento y no tienen IVA."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Any en la interfaz de la cuenta",
              "href": "/docs/payment-links#any"
            },
            {
              "label": "Pago",
              "href": "/docs/checkout"
            }
          ]
        },
        {
          "id": "snapshot",
          "title": "Campos y términos persistidos",
          "paragraphs": [
            "La factura guarda el nombre del comerciante, el precio, la moneda, los métodos, ambas participaciones de costo y las cotizaciones calculadas. Los metadatos se devuelven al propietario y en los eventos del servidor, pero no a través del checkout público. No almacene secretos de pago en ellos.",
            "Si se omiten las participaciones, el comerciante cubre la tarifa; el IVA hereda vatPayer o la configuración de la cuenta. Una asignación parcial puede devolver vatPayer=shared. El título, orderId y description son públicos."
          ],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Campo",
              "Regla"
            ],
            "rows": [
              [
                "title / description",
                "1–120 / 0–500 caracteres"
              ],
              [
                "amountMinor",
                "Entero de 1–10 000 000 000; 500 significa $5.00 en USD"
              ],
              [
                "currency / methods",
                "USD: card, alipay; RUB: sbp; USDT: crypto. Lista única no vacía."
              ],
              [
                "vatCustomerPercent / feeCustomerPercent",
                "Participaciones de cliente enteras independientes de 0 a 100"
              ],
              [
                "vatPayer",
                "Legacy customer o merchant; no puede entrar en conflicto con la participación de IVA"
              ],
              [
                "orderId",
                "Opcional, hasta 100 caracteres; visible para el cliente"
              ],
              [
                "metadatos",
                "Hasta diez entradas de cadena; clave de 1–40 letras/dígitos/_/-; valor hasta 500 caracteres; total hasta 3000 bytes UTF-8"
              ],
              [
                "expiresAt",
                "Milisegundos Unix futuros dentro de 90 días; siete días de forma predeterminada"
              ]
            ]
          },
          "code": null,
          "note": "Por compatibilidad, la API también guarda USD + crypto, pero la ejecución criptográfica en vivo está bloqueada con crypto_requires_usdt. Use USDT para facturas criptográficas nuevas; no se realiza ninguna conversión automática.",
          "links": [
            {
              "label": "Fórmulas de asignación de costos",
              "href": "/docs/cost-sharing"
            }
          ]
        },
        {
          "id": "idempotency",
          "title": "Reintente después de un error de red",
          "paragraphs": [
            "La creación inicial devuelve 201 con replayed=false. La misma clave y cuerpo canónico devuelven 200, la checkoutUrl original y replayed=true. Una solicitud diferente con esa clave devuelve 409 IDEMPOTENCY_CONFLICT.",
            "No genere otra clave después de un tiempo de espera. Repita la solicitud original con campos idénticos. Los valores omitidos no heredan configuraciones cambiadas de nuevo. orderId ayuda a correlacionar un pedido pero no reemplaza Idempotency-Key y no se requiere que sea único en el almacenamiento."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "read",
          "title": "Lectura y paginación",
          "paragraphs": [
            "GET /api/v1/payments devuelve links y nextCursor; GET /api/v1/payments/{id} devuelve un enlace propio. Se requiere invoices:read. El tamaño de página predeterminado es 30; limit acepta 1–100.",
            "Las respuestas de lista y detalle de GET incluyen link.payment: un resumen de la operación relacionada, o null cuando no existe ninguna operación. Las respuestas POST/PATCH pueden omitirlo; lea la factura de nuevo cuando necesite el resumen. El estado del enlace describe por separado si un pago nuevo puede comenzar. Los campos de tarjeta y las claves privadas nunca se incluyen.",
            "Pase nextCursor sin cambios a través de URLSearchParams. null marca el final; los ID desconocidos y los de otros comerciantes devuelven 404."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": {
            "language": "HTTP",
            "code": "GET /api/v1/payments?limit=30\nAuthorization: Bearer <server-side key>"
          },
          "note": "",
          "links": []
        },
        {
          "id": "status",
          "title": "Pausar, reanudar y cancelar",
          "paragraphs": [
            "PATCH /api/v1/payments/{id} con invoices:write acepta solo {\"status\":\"active\"}, {\"status\":\"paused\"} o {\"status\":\"cancelled\"}. La cancelación es definitiva. expired se deriva del tiempo de caducidad; una factura caducada no puede extenderse.",
            "El precio, las participaciones de costo, la descripción, orderId, los metadatos y la caducidad son inmutables. Cree otra factura para términos diferentes. Cambiar la disponibilidad emite invoice.updated, no un evento de pago exitoso."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "buyer",
          "title": "La respuesta del cliente",
          "paragraphs": [
            "GET /api/checkout/{token}?method=card devuelve la factura pública, la cotización, la disponibilidad del método y la operación existente. Los metadatos, secretos y saldos del propietario no se exponen.",
            "POST /api/checkout/{token}/pay requiere el Origin del sitio y un método concreto. Los datos de tarjeta se aceptan solo como sellados: {intent,jwe}, después de que el navegador obtenga /card-intent. Los códigos bancarios están cifrados y se envían a través de /code. Crypto usa una factura USDT guardada y un par moneda/red disponible.",
            "Un nuevo pago e intento de tarjeta requieren que la última solicitud de revisión web del comerciante esté aprobada. La aprobación por sí sola no conecta la pasarela de pago. Si la revisión cambia después del envío, la operación existente permanece disponible para lecturas de estado, conciliación y un código bancario solicitado.",
            "Una conexión en vivo faltante devuelve GATEWAY_NOT_CONNECTED; una asignación incompatible nunca se reemplaza con otro cálculo. El estado y reconcile leen la operación original sin un cargo duplicado."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Widget de checkout",
              "href": "/docs/widgets"
            },
            {
              "label": "Confirmar pago con webhooks",
              "href": "/docs/webhooks"
            }
          ]
        },
        {
          "id": "stores-usd",
          "title": "Múltiples tiendas y un precio base en USD",
          "paragraphs": [
            "Elija Todas las tiendas para análisis y operaciones agregados, o seleccione una tienda para sus propios registros. Cada tienda tiene un storeId, nombre, IVA predeterminado, facturas, claves de API, endpoints de webhook, historial de eventos y aplicación web separados. Las notificaciones y tickets de soporte pertenecen a la cuenta. Una cuenta puede crear hasta 100 tiendas. Los registros existentes permanecen en su primera tienda.",
            "Las facturas del nuevo espacio de trabajo usan pricingMode=\"universal\" y un precio base en USD. Any incluye tarjeta, alipay, sbp y cripto; un comerciante puede seleccionar un subconjunto. Tarjetas y Alipay cobran en USD. SBP cobra en RUB usando el tipo de referencia USD/RUB del Banco de Rusia. Cripto cobra USDT bajo la regla explícita de factura 1 USD = 1 USDT. Esta es una regla de conversión de factura, no una cotización de mercado de USDT. La pasarela proporciona la tasa de la moneda seleccionada, el monto exacto de transferencia y las instrucciones antes de la transferencia.",
            "El tipo de referencia y ambos montos se congelan al crear. Las facturas que implican conversión de RUB vencen dentro de 24 horas. Si no se puede obtener el tipo de referencia, la creación falla con FX_UNAVAILABLE; no se usa ningún tipo de respaldo inventado o desactualizado. El monto en minor del propietario y las cotizaciones usan la moneda contable USD. quotes[method].settlement contiene la cotización de cargo nativa. El checkout público expone la moneda de cargo seleccionada en currency, el precio original en baseAmountMinor/baseCurrency y el tipo de referencia en fx. Una vez que un pago ha sido despachado, su método no se puede cambiar; una factura tiene una operación de pasarela.",
            "Cree una clave de API dentro de la tienda prevista y envíe Authorization: Bearer <key> desde su servidor. Su vinculación a tienda es inmutable; X-Kevmi-Store no puede otorgarle acceso a otra tienda. Las sesiones del navegador seleccionan X-Kevmi-Store: <storeId>; omitirlo selecciona la primera tienda. El valor all solo es aceptado por GET /api/account/dashboard y GET /api/payment-links. Las mutaciones requieren una tienda seleccionada, Origin y X-CSRF-Token. Los IDs de cuenta y los IDs de tienda son identificadores diferentes.",
            "Por compatibilidad, las solicitudes de API sin pricingMode=\"universal\" conservan el precio nativo y las restricciones de moneda originales. Las facturas existentes nunca se recalculan. Los recibos confirmados en análisis reflejan pagos verificados menos gastos de factura guardados; no son un saldo retirable. Las monedas de factura heredadas permanecen separadas y los pagos se gestionan con soporte. Cumpla un pedido solo después de verificar payment.fulfillmentReady=true y payment.status=\"succeeded\" a través de la API del servidor, el historial de eventos o un webhook firmado."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        }
      ],
      "group": "developers",
      "url": "/docs/payment-links-api",
      "body": "Una solicitud de servidor devuelve un enlace listo\n\nPOST /api/v1/payments y /api/v1/payment-links crean el mismo tipo de factura. El nombre de la ruta payments no implica un cargo: el resultado son términos de factura persistidos y una checkoutUrl para el cliente.\n\nEnvíe Authorization: Bearer <key>, Content-Type: application/json y Idempotency-Key. Las claves de idempotencia contienen 16–100 letras, dígitos, guiones o guiones bajos. Persista una clave para cada creación lógica de pedido.\n\ncurl 'https://kevmi.maxeevmax1.chatgpt.site/api/v1/payments' \\\n  -H \"Authorization: Bearer $KEVMI_API_KEY\" \\\n  -H 'Content-Type: application/json' \\\n  -H 'Idempotency-Key: order-1042-create-v1' \\\n  --data '{\"title\":\"Design project · order 1042\",\"description\":\"One-time payment for the agreed design work\",\"amountMinor\":500,\"currency\":\"USD\",\"methods\":[\"card\",\"alipay\"],\"vatCustomerPercent\":100,\"feeCustomerPercent\":0,\"orderId\":\"order-1042\",\"metadata\":{\"campaign\":\"autumn\"}}'\n\nLa respuesta contiene link, checkoutUrl y replayed. Pase checkoutUrl al cliente o widget; mantenga la clave de API en su servidor.\n\nAlcances y caducidad de las claves de API\n\nCree una clave en /account#keys en su cuenta de comerciante verificada. Su valor completo aparece una sola vez; solo se almacena un hash. Las claves duran 90 días de forma predeterminada, con una vida útil permitida de 1–365 días y hasta diez claves activas por cuenta.\n\nOtorgue únicamente los alcances necesarios. La revocación o caducidad detiene el acceso. Una clave no reemplaza la sesión del navegador para la configuración de la cuenta, la administración de endpoints, las aplicaciones o la moderación. Manténgala fuera de widgets, URL, repositorios públicos y mensajes de soporte.\n\nEl sitio web usa /api/payment-links con su cookie de sesión, Origin exacto y X-CSRF-Token. Esas rutas operan sobre las mismas facturas propiedad de la cuenta.\n\nAlcance · Propósito\ninvoices:read · Leer facturas propias y su lista\ninvoices:write · Crear facturas y cambiar la disponibilidad del enlace\nevents:read · Leer el registro de eventos del servidor\n\nClaves de API en su cuenta\n\nAny y métodos de API concretos\n\nAny es un modo de selección de interfaz. Las facturas nuevas aceptan métodos: [\"card\", \"alipay\"] o un subconjunto no vacío para USD; [\"sbp\"] para RUB; [\"crypto\"] para USDT. El valor any no es un método de pago de API.\n\nPara una factura nueva en la interfaz, USD ofrece tarjetas y Alipay; RUB ofrece SBP; USDT ofrece criptomonedas. La API también puede guardar USD + criptomonedas por compatibilidad, pero su pago cripto en vivo está bloqueado con crypto_requires_usdt. USD y USDT son distintos, sin conversión automática ni supuesta tasa 1:1. Un pago cripto requiere una factura USDT separada.\n\nPara un pago nuevo en vivo con tarjeta o Alipay, la pasarela actual solo admite feeCustomerPercent=0 y vatCustomerPercent=100: el comerciante cubre toda la comisión de procesamiento y el IVA se añade completo para el cliente. Otras participaciones se pueden guardar y calcular en una factura, pero la ejecución está bloqueada con unsupported_allocation. El servidor nunca cambia silenciosamente los términos guardados. Los pagos cripto SBP y USDT admiten todas las participaciones de comisión de procesamiento y no tienen IVA.\n\nAny en la interfaz de la cuenta\n\nPago\n\nCampos y términos persistidos\n\nLa factura guarda el nombre del comerciante, el precio, la moneda, los métodos, ambas participaciones de costo y las cotizaciones calculadas. Los metadatos se devuelven al propietario y en los eventos del servidor, pero no a través del checkout público. No almacene secretos de pago en ellos.\n\nSi se omiten las participaciones, el comerciante cubre la tarifa; el IVA hereda vatPayer o la configuración de la cuenta. Una asignación parcial puede devolver vatPayer=shared. El título, orderId y description son públicos.\n\nCampo · Regla\ntitle / description · 1–120 / 0–500 caracteres\namountMinor · Entero de 1–10 000 000 000; 500 significa $5.00 en USD\ncurrency / methods · USD: card, alipay; RUB: sbp; USDT: crypto. Lista única no vacía.\nvatCustomerPercent / feeCustomerPercent · Participaciones de cliente enteras independientes de 0 a 100\nvatPayer · Legacy customer o merchant; no puede entrar en conflicto con la participación de IVA\norderId · Opcional, hasta 100 caracteres; visible para el cliente\nmetadatos · Hasta diez entradas de cadena; clave de 1–40 letras/dígitos/_/-; valor hasta 500 caracteres; total hasta 3000 bytes UTF-8\nexpiresAt · Milisegundos Unix futuros dentro de 90 días; siete días de forma predeterminada\n\nPor compatibilidad, la API también guarda USD + crypto, pero la ejecución criptográfica en vivo está bloqueada con crypto_requires_usdt. Use USDT para facturas criptográficas nuevas; no se realiza ninguna conversión automática.\n\nFórmulas de asignación de costos\n\nReintente después de un error de red\n\nLa creación inicial devuelve 201 con replayed=false. La misma clave y cuerpo canónico devuelven 200, la checkoutUrl original y replayed=true. Una solicitud diferente con esa clave devuelve 409 IDEMPOTENCY_CONFLICT.\n\nNo genere otra clave después de un tiempo de espera. Repita la solicitud original con campos idénticos. Los valores omitidos no heredan configuraciones cambiadas de nuevo. orderId ayuda a correlacionar un pedido pero no reemplaza Idempotency-Key y no se requiere que sea único en el almacenamiento.\n\nLectura y paginación\n\nGET /api/v1/payments devuelve links y nextCursor; GET /api/v1/payments/{id} devuelve un enlace propio. Se requiere invoices:read. El tamaño de página predeterminado es 30; limit acepta 1–100.\n\nLas respuestas de lista y detalle de GET incluyen link.payment: un resumen de la operación relacionada, o null cuando no existe ninguna operación. Las respuestas POST/PATCH pueden omitirlo; lea la factura de nuevo cuando necesite el resumen. El estado del enlace describe por separado si un pago nuevo puede comenzar. Los campos de tarjeta y las claves privadas nunca se incluyen.\n\nPase nextCursor sin cambios a través de URLSearchParams. null marca el final; los ID desconocidos y los de otros comerciantes devuelven 404.\n\nGET /api/v1/payments?limit=30\nAuthorization: Bearer <server-side key>\n\nPausar, reanudar y cancelar\n\nPATCH /api/v1/payments/{id} con invoices:write acepta solo {\"status\":\"active\"}, {\"status\":\"paused\"} o {\"status\":\"cancelled\"}. La cancelación es definitiva. expired se deriva del tiempo de caducidad; una factura caducada no puede extenderse.\n\nEl precio, las participaciones de costo, la descripción, orderId, los metadatos y la caducidad son inmutables. Cree otra factura para términos diferentes. Cambiar la disponibilidad emite invoice.updated, no un evento de pago exitoso.\n\nLa respuesta del cliente\n\nGET /api/checkout/{token}?method=card devuelve la factura pública, la cotización, la disponibilidad del método y la operación existente. Los metadatos, secretos y saldos del propietario no se exponen.\n\nPOST /api/checkout/{token}/pay requiere el Origin del sitio y un método concreto. Los datos de tarjeta se aceptan solo como sellados: {intent,jwe}, después de que el navegador obtenga /card-intent. Los códigos bancarios están cifrados y se envían a través de /code. Crypto usa una factura USDT guardada y un par moneda/red disponible.\n\nUn nuevo pago e intento de tarjeta requieren que la última solicitud de revisión web del comerciante esté aprobada. La aprobación por sí sola no conecta la pasarela de pago. Si la revisión cambia después del envío, la operación existente permanece disponible para lecturas de estado, conciliación y un código bancario solicitado.\n\nUna conexión en vivo faltante devuelve GATEWAY_NOT_CONNECTED; una asignación incompatible nunca se reemplaza con otro cálculo. El estado y reconcile leen la operación original sin un cargo duplicado.\n\nWidget de checkout\n\nConfirmar pago con webhooks\n\nMúltiples tiendas y un precio base en USD\n\nElija Todas las tiendas para análisis y operaciones agregados, o seleccione una tienda para sus propios registros. Cada tienda tiene un storeId, nombre, IVA predeterminado, facturas, claves de API, endpoints de webhook, historial de eventos y aplicación web separados. Las notificaciones y tickets de soporte pertenecen a la cuenta. Una cuenta puede crear hasta 100 tiendas. Los registros existentes permanecen en su primera tienda.\n\nLas facturas del nuevo espacio de trabajo usan pricingMode=\"universal\" y un precio base en USD. Any incluye tarjeta, alipay, sbp y cripto; un comerciante puede seleccionar un subconjunto. Tarjetas y Alipay cobran en USD. SBP cobra en RUB usando el tipo de referencia USD/RUB del Banco de Rusia. Cripto cobra USDT bajo la regla explícita de factura 1 USD = 1 USDT. Esta es una regla de conversión de factura, no una cotización de mercado de USDT. La pasarela proporciona la tasa de la moneda seleccionada, el monto exacto de transferencia y las instrucciones antes de la transferencia.\n\nEl tipo de referencia y ambos montos se congelan al crear. Las facturas que implican conversión de RUB vencen dentro de 24 horas. Si no se puede obtener el tipo de referencia, la creación falla con FX_UNAVAILABLE; no se usa ningún tipo de respaldo inventado o desactualizado. El monto en minor del propietario y las cotizaciones usan la moneda contable USD. quotes[method].settlement contiene la cotización de cargo nativa. El checkout público expone la moneda de cargo seleccionada en currency, el precio original en baseAmountMinor/baseCurrency y el tipo de referencia en fx. Una vez que un pago ha sido despachado, su método no se puede cambiar; una factura tiene una operación de pasarela.\n\nCree una clave de API dentro de la tienda prevista y envíe Authorization: Bearer <key> desde su servidor. Su vinculación a tienda es inmutable; X-Kevmi-Store no puede otorgarle acceso a otra tienda. Las sesiones del navegador seleccionan X-Kevmi-Store: <storeId>; omitirlo selecciona la primera tienda. El valor all solo es aceptado por GET /api/account/dashboard y GET /api/payment-links. Las mutaciones requieren una tienda seleccionada, Origin y X-CSRF-Token. Los IDs de cuenta y los IDs de tienda son identificadores diferentes.\n\nPor compatibilidad, las solicitudes de API sin pricingMode=\"universal\" conservan el precio nativo y las restricciones de moneda originales. Las facturas existentes nunca se recalculan. Los recibos confirmados en análisis reflejan pagos verificados menos gastos de factura guardados; no son un saldo retirable. Las monedas de factura heredadas permanecen separadas y los pagos se gestionan con soporte. Cumpla un pedido solo después de verificar payment.fulfillmentReady=true y payment.status=\"succeeded\" a través de la API del servidor, el historial de eventos o un webhook firmado.",
      "readMinutes": 7
    },
    {
      "id": "auth-api",
      "title": "API de autenticación y sesión",
      "summary": "El inicio de sesión utiliza un desafío de corta duración, confirmación por Telegram y prueba de control del navegador original. Un ID de Telegram proporcionado por el cliente no es prueba de identidad.",
      "group": "developers",
      "url": "/docs/auth-api",
      "tags": [
        "autenticación",
        "sesión",
        "CSRF",
        "desafío",
        "API"
      ],
      "sections": [
        {
          "id": "start",
          "title": "Inicio de sesión",
          "paragraphs": [
            "POST /api/auth/telegram/start acepta un objeto JSON vacío {}. Requiere el Origin exacto de la aplicación y un bot disponible. El servidor crea un desafío que dura 300 segundos y una cookie protegida de prueba del navegador.",
            "La respuesta 201 contiene challengeId, code, expiresAt y telegramUrl. La cookie de prueba se excluye del enlace profundo y es inaccesible para JavaScript. El límite es de seis inicios por minuto por dirección con hash."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": {
            "language": "JavaScript",
            "code": "const response = await fetch('/api/auth/telegram/start', {\n  method: 'POST',\n  headers: { 'Content-Type': 'application/json' },\n  body: '{}'\n});\nconst challenge = await response.json();\n// Show code and telegramUrl to the user."
          },
          "note": "",
          "links": []
        },
        {
          "id": "complete",
          "title": "Esperando confirmación",
          "paragraphs": [
            "POST /api/auth/telegram/complete acepta {challengeId}. Requiere Origin y la cookie original de prueba del navegador. Hasta la confirmación, la respuesta es 202 {status: \"pending\"}.",
            "Después de la confirmación, 200 devuelve status=authenticated, user, csrfToken y expiresAt. Se emite una sesión una sola vez. Los desafíos caducados devuelven 410; los desafíos usados o cancelados devuelven 409."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": {
            "language": "JavaScript",
            "code": "const response = await fetch('/api/auth/telegram/complete', {\n  method: 'POST',\n  headers: { 'Content-Type': 'application/json' },\n  body: JSON.stringify({ challengeId: challenge.challengeId })\n});\nif (response.status === 202) {\n  // Poll again after a delay; do not create a new challenge.\n}"
          },
          "note": "",
          "links": []
        },
        {
          "id": "me",
          "title": "Lectura de la sesión",
          "paragraphs": [
            "GET /api/auth/me devuelve 200 {authenticated:false} cuando no existe una sesión válida. Una respuesta con sesión iniciada incluye el usuario, el token CSRF y la caducidad.",
            "La cookie __Host-kevmi-session dura hasta 24 horas con Secure, HttpOnly, SameSite=Lax y Path=/. La base de datos almacena un hash SHA-256 de su token. Un formulario de perfil no puede leer ni reemplazar la cookie."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "write",
          "title": "Cambios en la cuenta",
          "paragraphs": [
            "Las mutaciones requieren la sesión, el Origin exacto y el X-CSRF-Token actual. Se rechaza Sec-Fetch-Site: cross-site. El servidor no ofrece acceso CORS arbitrario.",
            "El ID de la cuenta proviene de la sesión, no de la entrada de la solicitud. Los registros faltantes o de otro usuario no revelan detalles de propiedad distinguibles."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "logout",
          "title": "Cierre de sesión",
          "paragraphs": [
            "POST /api/auth/logout finaliza la sesión actual y borra la cookie. Se requieren Origin y CSRF; el cuerpo no se lee. Telegram /logout también finaliza todas las sesiones de la cuenta.",
            "Las cookies no se mueven automáticamente a otro dominio. Al cambiar el dominio del servicio, actualice APP_ORIGIN y el webhook del bot, y luego inicie sesión nuevamente."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "assistant-admin-v16",
          "title": "Asistencia, soporte y administración de proyectos",
          "paragraphs": [
            "Habilitar Permite el acceso a mis datos en el chat cuando necesites ayuda con operaciones privadas. Una solicitud web con includeAccount=true requiere una sesión válida, Origin y X-CSRF-Token; X-Kevmi-Store selecciona una tienda propia o todas las tiendas propias. Sin permiso, el asistente usa documentación pública. En Telegram, un botón separado habilita el acceso después de identificar al remitente.",
            "La herramienta read_account lee tiendas propias, facturas con estado de recibo verificado, eventos, solicitudes y solicitudes de soporte con respuestas de especialistas. Devuelve 30 registros y nextPage; los registros más antiguos están disponibles mediante paginación. Las lecturas por respuesta están limitadas, por lo que una muestra incompleta debe revelarse. Las claves de API, secretos de webhook, datos de tarjetas y sesiones no se proporcionan a la herramienta. No puede cobrar, pagar, reembolsar ni cambiar la configuración.",
            "Crear una solicitud de soporte en el espacio de trabajo o en Telegram coloca una alerta de administrador separada en una cola duradera. Se enlaza a /admin/tickets?ticket=<id>; los fallos temporales de Telegram se reintentan. La recuperación también recoge solicitudes abiertas antiguas sin alerta. Los administradores responden en la página de la solicitud; la respuesta se guarda en el espacio de trabajo del usuario y se envía por Telegram cuando las notificaciones de soporte están habilitadas.",
            "El bot usa botones en línea para el menú principal, tiendas, notificaciones, soporte, seguridad e idioma. La navegación edita el mensaje actual; un menú antiguo no disponible se reemplaza. Las notificaciones de pago y seguridad no se tratan como navegación desechable. Cerrar sesión a través del menú requiere confirmación. El comando explícito /logout sigue terminando cada sesión de cuenta.",
            "El panel /admin/project está restringido a IDs de Telegram en la lista de permitidos MODERATOR_TELEGRAM_IDS del lado del servidor. Incluye usuarios, tiendas, operaciones, revocación de claves, deshabilitación de webhooks, pausa de facturas, controles de aceptación y un registro de auditoría. Las mutaciones requieren CSRF y un motivo. El panel no puede restringir a un administrador ni declarar manualmente un pago como exitoso. Restringir a un propietario termina las sesiones y bloquea el acceso a claves de API; restringir una tienda detiene nuevas operaciones. El historial se conserva.",
            "La oferta pública está disponible en /public-offer y la política de privacidad en /privacy-policy en cada idioma habilitado. Busca monedas por nombre o ticker. Un selector de red aparece solo cuando hay múltiples redes en vivo disponibles. Una sola red se selecciona automáticamente y permanece nombrada en la confirmación. La disponibilidad en vivo de la pasarela determina los pares seleccionables; el catálogo de referencia no habilita un servicio.",
            "Usa update.sh para lanzamientos rutinarios de la aplicación web: compila el candidato, verifica el historial de migraciones, haz una copia de seguridad de SQLite en línea, inicia un segundo contenedor, verifícalo y cambia Caddy sin interrupciones. La pasarela, PostgreSQL y el correo no se reinician. Los activos estáticos anteriores siguen disponibles para pestañas abiertas. Una nueva migración requiere autorización revisada explícita; un cambio de esquema incompatible no es un despliegue sin interrupciones."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Oferta pública",
              "href": "/public-offer"
            },
            {
              "label": "Política de privacidad",
              "href": "/privacy-policy"
            }
          ]
        }
      ],
      "body": "Inicio de sesión\n\nPOST /api/auth/telegram/start acepta un objeto JSON vacío {}. Requiere el Origin exacto de la aplicación y un bot disponible. El servidor crea un desafío que dura 300 segundos y una cookie protegida de prueba del navegador.\n\nLa respuesta 201 contiene challengeId, code, expiresAt y telegramUrl. La cookie de prueba se excluye del enlace profundo y es inaccesible para JavaScript. El límite es de seis inicios por minuto por dirección con hash.\n\nconst response = await fetch('/api/auth/telegram/start', {\n  method: 'POST',\n  headers: { 'Content-Type': 'application/json' },\n  body: '{}'\n});\nconst challenge = await response.json();\n// Show code and telegramUrl to the user.\n\nEsperando confirmación\n\nPOST /api/auth/telegram/complete acepta {challengeId}. Requiere Origin y la cookie original de prueba del navegador. Hasta la confirmación, la respuesta es 202 {status: \"pending\"}.\n\nDespués de la confirmación, 200 devuelve status=authenticated, user, csrfToken y expiresAt. Se emite una sesión una sola vez. Los desafíos caducados devuelven 410; los desafíos usados o cancelados devuelven 409.\n\nconst response = await fetch('/api/auth/telegram/complete', {\n  method: 'POST',\n  headers: { 'Content-Type': 'application/json' },\n  body: JSON.stringify({ challengeId: challenge.challengeId })\n});\nif (response.status === 202) {\n  // Poll again after a delay; do not create a new challenge.\n}\n\nLectura de la sesión\n\nGET /api/auth/me devuelve 200 {authenticated:false} cuando no existe una sesión válida. Una respuesta con sesión iniciada incluye el usuario, el token CSRF y la caducidad.\n\nLa cookie __Host-kevmi-session dura hasta 24 horas con Secure, HttpOnly, SameSite=Lax y Path=/. La base de datos almacena un hash SHA-256 de su token. Un formulario de perfil no puede leer ni reemplazar la cookie.\n\nCambios en la cuenta\n\nLas mutaciones requieren la sesión, el Origin exacto y el X-CSRF-Token actual. Se rechaza Sec-Fetch-Site: cross-site. El servidor no ofrece acceso CORS arbitrario.\n\nEl ID de la cuenta proviene de la sesión, no de la entrada de la solicitud. Los registros faltantes o de otro usuario no revelan detalles de propiedad distinguibles.\n\nCierre de sesión\n\nPOST /api/auth/logout finaliza la sesión actual y borra la cookie. Se requieren Origin y CSRF; el cuerpo no se lee. Telegram /logout también finaliza todas las sesiones de la cuenta.\n\nLas cookies no se mueven automáticamente a otro dominio. Al cambiar el dominio del servicio, actualice APP_ORIGIN y el webhook del bot, y luego inicie sesión nuevamente.\n\nAsistencia, soporte y administración de proyectos\n\nHabilitar Permite el acceso a mis datos en el chat cuando necesites ayuda con operaciones privadas. Una solicitud web con includeAccount=true requiere una sesión válida, Origin y X-CSRF-Token; X-Kevmi-Store selecciona una tienda propia o todas las tiendas propias. Sin permiso, el asistente usa documentación pública. En Telegram, un botón separado habilita el acceso después de identificar al remitente.\n\nLa herramienta read_account lee tiendas propias, facturas con estado de recibo verificado, eventos, solicitudes y solicitudes de soporte con respuestas de especialistas. Devuelve 30 registros y nextPage; los registros más antiguos están disponibles mediante paginación. Las lecturas por respuesta están limitadas, por lo que una muestra incompleta debe revelarse. Las claves de API, secretos de webhook, datos de tarjetas y sesiones no se proporcionan a la herramienta. No puede cobrar, pagar, reembolsar ni cambiar la configuración.\n\nCrear una solicitud de soporte en el espacio de trabajo o en Telegram coloca una alerta de administrador separada en una cola duradera. Se enlaza a /admin/tickets?ticket=<id>; los fallos temporales de Telegram se reintentan. La recuperación también recoge solicitudes abiertas antiguas sin alerta. Los administradores responden en la página de la solicitud; la respuesta se guarda en el espacio de trabajo del usuario y se envía por Telegram cuando las notificaciones de soporte están habilitadas.\n\nEl bot usa botones en línea para el menú principal, tiendas, notificaciones, soporte, seguridad e idioma. La navegación edita el mensaje actual; un menú antiguo no disponible se reemplaza. Las notificaciones de pago y seguridad no se tratan como navegación desechable. Cerrar sesión a través del menú requiere confirmación. El comando explícito /logout sigue terminando cada sesión de cuenta.\n\nEl panel /admin/project está restringido a IDs de Telegram en la lista de permitidos MODERATOR_TELEGRAM_IDS del lado del servidor. Incluye usuarios, tiendas, operaciones, revocación de claves, deshabilitación de webhooks, pausa de facturas, controles de aceptación y un registro de auditoría. Las mutaciones requieren CSRF y un motivo. El panel no puede restringir a un administrador ni declarar manualmente un pago como exitoso. Restringir a un propietario termina las sesiones y bloquea el acceso a claves de API; restringir una tienda detiene nuevas operaciones. El historial se conserva.\n\nLa oferta pública está disponible en /public-offer y la política de privacidad en /privacy-policy en cada idioma habilitado. Busca monedas por nombre o ticker. Un selector de red aparece solo cuando hay múltiples redes en vivo disponibles. Una sola red se selecciona automáticamente y permanece nombrada en la confirmación. La disponibilidad en vivo de la pasarela determina los pares seleccionables; el catálogo de referencia no habilita un servicio.\n\nUsa update.sh para lanzamientos rutinarios de la aplicación web: compila el candidato, verifica el historial de migraciones, haz una copia de seguridad de SQLite en línea, inicia un segundo contenedor, verifícalo y cambia Caddy sin interrupciones. La pasarela, PostgreSQL y el correo no se reinician. Los activos estáticos anteriores siguen disponibles para pestañas abiertas. Una nueva migración requiere autorización revisada explícita; un cambio de esquema incompatible no es un despliegue sin interrupciones.\n\nOferta pública\n\nPolítica de privacidad",
      "readMinutes": 3
    },
    {
      "id": "errors",
      "title": "Errores y reintentos",
      "summary": "Los errores de API utilizan un formato consistente. El código es para la lógica de la aplicación; el mensaje explica el problema. Mantenga la entrada del usuario intacta y ofrezca un siguiente paso claro.",
      "group": "developers",
      "url": "/docs/errors",
      "tags": [
        "error",
        "429",
        "503",
        "reintento",
        "estado"
      ],
      "sections": [
        {
          "id": "format",
          "title": "Un solo formato de error",
          "paragraphs": [
            "Las respuestas no incluyen trazas de pila, SQL, tokens ni una respuesta completa del proveedor externo. No muestre registros internos sin procesar a un cliente."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": {
            "language": "JSON",
            "code": "{\n  \"error\": {\n    \"code\": \"GATEWAY_NOT_CONNECTED\",\n    \"message\": \"Financial operations are temporarily unavailable. Try later or contact support.\"\n  }\n}"
          },
          "note": "",
          "links": []
        },
        {
          "id": "codes",
          "title": "Grupos de errores comunes",
          "paragraphs": [],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "HTTP",
              "Ejemplos",
              "Siguiente paso"
            ],
            "rows": [
              [
                "400",
                "INVALID_JSON, UNKNOWN_FIELD, INVALID_INPUT",
                "Verifique la entrada y los campos permitidos"
              ],
              [
                "401",
                "AUTH_REQUIRED, SESSION_EXPIRED",
                "Inicie sesión nuevamente"
              ],
              [
                "403",
                "INVALID_ORIGIN, CSRF_REQUIRED",
                "Verifique el origin y la sesión actual"
              ],
              [
                "404",
                "NOT_FOUND, TICKET_NOT_FOUND",
                "Verifique la dirección y la propiedad"
              ],
              [
                "409",
                "CHALLENGE_UNAVAILABLE",
                "Inicie un nuevo inicio de sesión"
              ],
              [
                "410",
                "CHALLENGE_EXPIRED",
                "Cree un nuevo enlace de inicio de sesión"
              ],
              [
                "413",
                "REQUEST_TOO_LARGE",
                "Reduzca el cuerpo de la solicitud"
              ],
              [
                "415",
                "JSON_REQUIRED",
                "Envíe application/json"
              ],
              [
                "429",
                "RATE_LIMITED",
                "Reduzca la frecuencia y espere"
              ],
              [
                "503",
                "GATEWAY_NOT_CONNECTED, SERVICE_UNAVAILABLE",
                "Verifique la disponibilidad o intente más tarde"
              ]
            ]
          },
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "rate",
          "title": "Límites de velocidad",
          "paragraphs": [],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Acción",
              "Límite"
            ],
            "rows": [
              [
                "Iniciar sesión",
                "6 por minuto por dirección con hash"
              ],
              [
                "Verificar un desafío",
                "90 por minuto por desafío"
              ],
              [
                "Pregunta de conocimiento",
                "12 por minuto por dirección con hash con D1"
              ],
              [
                "Crear un enlace de servidor",
                "20 por minuto por usuario"
              ],
              [
                "API de comerciante",
                "90 solicitudes por minuto por clave"
              ],
              [
                "Nueva aplicación",
                "Cinco por día por usuario"
              ],
              [
                "Reanudar aplicación / decisión del moderador",
                "30 por minuto por usuario para cada acción"
              ],
              [
                "Revisión de sitio web con IA",
                "30 por hora en todo el servicio"
              ],
              [
                "Leer el pago o intentar el pago",
                "90 por minuto por dirección hashada"
              ],
              [
                "Crear una solicitud de soporte",
                "6 por hora por usuario"
              ],
              [
                "Probar una notificación",
                "3 por hora por usuario"
              ],
              [
                "Generación con IA",
                "60 por hora en todo el servicio por defecto"
              ]
            ]
          },
          "code": null,
          "note": "Retry-After: 60 indica una demora, no una garantía de que la cuota horaria se haya restablecido.",
          "links": []
        },
        {
          "id": "retry",
          "title": "Qué se puede reintentar",
          "paragraphs": [
            "Una lectura se puede reintentar después de una demora ante una falla temporal de red. Antes de reintentar una mutación, verifique si la original se completó; una respuesta perdida no demuestra una falla.",
            "Las operaciones financieras requieren idempotencia y una verificación del estado del servidor. Una redirección del cliente a una página de resultados no sustituye la confirmación."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "report",
          "title": "Qué incluir en una solicitud",
          "paragraphs": [],
          "bullets": [
            "La página y la acción inmediatamente antes del error.",
            "Hora, zona horaria y el código de error visible.",
            "Su referencia de factura o de solicitud de soporte, si está disponible.",
            "Una descripción breve del resultado que esperaba."
          ],
          "steps": [],
          "table": null,
          "code": null,
          "note": "No adjunte cookies, tokens, encabezados de autorización, CVV ni códigos bancarios.",
          "links": []
        }
      ],
      "body": "Un solo formato de error\n\nLas respuestas no incluyen trazas de pila, SQL, tokens ni una respuesta completa del proveedor externo. No muestre registros internos sin procesar a un cliente.\n\n{\n  \"error\": {\n    \"code\": \"GATEWAY_NOT_CONNECTED\",\n    \"message\": \"Financial operations are temporarily unavailable. Try later or contact support.\"\n  }\n}\n\nGrupos de errores comunes\n\nHTTP · Ejemplos · Siguiente paso\n400 · INVALID_JSON, UNKNOWN_FIELD, INVALID_INPUT · Verifique la entrada y los campos permitidos\n401 · AUTH_REQUIRED, SESSION_EXPIRED · Inicie sesión nuevamente\n403 · INVALID_ORIGIN, CSRF_REQUIRED · Verifique el origin y la sesión actual\n404 · NOT_FOUND, TICKET_NOT_FOUND · Verifique la dirección y la propiedad\n409 · CHALLENGE_UNAVAILABLE · Inicie un nuevo inicio de sesión\n410 · CHALLENGE_EXPIRED · Cree un nuevo enlace de inicio de sesión\n413 · REQUEST_TOO_LARGE · Reduzca el cuerpo de la solicitud\n415 · JSON_REQUIRED · Envíe application/json\n429 · RATE_LIMITED · Reduzca la frecuencia y espere\n503 · GATEWAY_NOT_CONNECTED, SERVICE_UNAVAILABLE · Verifique la disponibilidad o intente más tarde\n\nLímites de velocidad\n\nAcción · Límite\nIniciar sesión · 6 por minuto por dirección con hash\nVerificar un desafío · 90 por minuto por desafío\nPregunta de conocimiento · 12 por minuto por dirección con hash con D1\nCrear un enlace de servidor · 20 por minuto por usuario\nAPI de comerciante · 90 solicitudes por minuto por clave\nNueva aplicación · Cinco por día por usuario\nReanudar aplicación / decisión del moderador · 30 por minuto por usuario para cada acción\nRevisión de sitio web con IA · 30 por hora en todo el servicio\nLeer el pago o intentar el pago · 90 por minuto por dirección hashada\nCrear una solicitud de soporte · 6 por hora por usuario\nProbar una notificación · 3 por hora por usuario\nGeneración con IA · 60 por hora en todo el servicio por defecto\n\nRetry-After: 60 indica una demora, no una garantía de que la cuota horaria se haya restablecido.\n\nQué se puede reintentar\n\nUna lectura se puede reintentar después de una demora ante una falla temporal de red. Antes de reintentar una mutación, verifique si la original se completó; una respuesta perdida no demuestra una falla.\n\nLas operaciones financieras requieren idempotencia y una verificación del estado del servidor. Una redirección del cliente a una página de resultados no sustituye la confirmación.\n\nQué incluir en una solicitud\n\nLa página y la acción inmediatamente antes del error.\n\nHora, zona horaria y el código de error visible.\n\nSu referencia de factura o de solicitud de soporte, si está disponible.\n\nUna descripción breve del resultado que esperaba.\n\nNo adjunte cookies, tokens, encabezados de autorización, CVV ni códigos bancarios.",
      "readMinutes": 3
    },
    {
      "id": "security",
      "title": "Seguridad de la integración",
      "summary": "Las verificaciones de confianza se ejecutan en el servidor. El navegador controla la interfaz, pero no puede establecer identidad, estado financiero ni montos finales.",
      "group": "developers",
      "url": "/docs/security",
      "tags": [
        "seguridad",
        "CSRF",
        "cookie",
        "propiedad",
        "secreto",
        "idempotencia"
      ],
      "sections": [
        {
          "id": "identity",
          "title": "Sesiones y propiedad",
          "paragraphs": [
            "Una sesión de servidor válida identifica la cuenta. Los ajustes, solicitudes, notificaciones y enlaces se filtran por propietario. Un userId enviado desde un formulario no puede reemplazar ese filtro.",
            "Las mutaciones además verifican Origin y CSRF. Una URL pública de factura expone únicamente esa factura y no otorga acceso a la cuenta."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "secrets",
          "title": "Los secretos permanecen en el servidor",
          "paragraphs": [
            "Los secretos no deben aparecer en Git, HTML, JavaScript del cliente, ejemplos de OpenAPI, archivos llms ni mensajes de soporte. El nombre de usuario público del bot no es un secreto."
          ],
          "bullets": [
            "Token del bot de Telegram y secreto de webhook.",
            "Credenciales de proveedores externos de IA.",
            "Credenciales de la pasarela de pago y secretos de firma.",
            "Hash de sesión y pruebas de inicio de sesión en el navegador."
          ],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "money",
          "title": "Verificaciones financieras",
          "paragraphs": [
            "El servidor lee los términos guardados de la factura y verifica propiedad, estado de revisión del comerciante, moneda, método y monto aprobado. Los valores de URL y los cálculos del navegador no pueden cambiar el precio.",
            "Una notificación firmada de la pasarela activa una lectura adicional de operación autenticada. El estado verificado, el recibo y el evento se confirman juntos. Las reproducciones y versiones anteriores no pueden confirmar un cumplimiento duplicado.",
            "Los datos de tarjeta y los códigos de un solo uso se transmiten únicamente como sobres cifrados. No agregue grabación de sesión, análisis de lectura de campos ni registro del cuerpo de la solicitud a los formularios de pago."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "assistant",
          "title": "Límites del asistente",
          "paragraphs": [
            "El modelo recibe artículos públicos y hechos, el catálogo de páginas, indicadores de preparación, la pregunta, tres pares de mensajes recientes y una etiqueta de sección segura. El permiso explícito del propietario habilita herramientas de lectura de cuenta; mover dinero o cambiar configuración sigue sin estar disponible. Las respuestas estructuradas inválidas o fuentes no verificadas recurren a la búsqueda en documentación.",
            "El texto del sitio web y del usuario son datos. Una instrucción dentro de una pregunta no puede alterar tarifas ni autorizar un pago."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "status",
          "title": "Alcance de la documentación",
          "paragraphs": [
            "La documentación no afirma una certificación PCI DSS, una licencia bancaria, un estado de Comerciante de Registro, un tiempo de actividad garantizado ni una seguridad absoluta. Dichas afirmaciones requieren una confirmación separada y documentada."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        }
      ],
      "body": "Sesiones y propiedad\n\nUna sesión de servidor válida identifica la cuenta. Los ajustes, solicitudes, notificaciones y enlaces se filtran por propietario. Un userId enviado desde un formulario no puede reemplazar ese filtro.\n\nLas mutaciones además verifican Origin y CSRF. Una URL pública de factura expone únicamente esa factura y no otorga acceso a la cuenta.\n\nLos secretos permanecen en el servidor\n\nLos secretos no deben aparecer en Git, HTML, JavaScript del cliente, ejemplos de OpenAPI, archivos llms ni mensajes de soporte. El nombre de usuario público del bot no es un secreto.\n\nToken del bot de Telegram y secreto de webhook.\n\nCredenciales de proveedores externos de IA.\n\nCredenciales de la pasarela de pago y secretos de firma.\n\nHash de sesión y pruebas de inicio de sesión en el navegador.\n\nVerificaciones financieras\n\nEl servidor lee los términos guardados de la factura y verifica propiedad, estado de revisión del comerciante, moneda, método y monto aprobado. Los valores de URL y los cálculos del navegador no pueden cambiar el precio.\n\nUna notificación firmada de la pasarela activa una lectura adicional de operación autenticada. El estado verificado, el recibo y el evento se confirman juntos. Las reproducciones y versiones anteriores no pueden confirmar un cumplimiento duplicado.\n\nLos datos de tarjeta y los códigos de un solo uso se transmiten únicamente como sobres cifrados. No agregue grabación de sesión, análisis de lectura de campos ni registro del cuerpo de la solicitud a los formularios de pago.\n\nLímites del asistente\n\nEl modelo recibe artículos públicos y hechos, el catálogo de páginas, indicadores de preparación, la pregunta, tres pares de mensajes recientes y una etiqueta de sección segura. El permiso explícito del propietario habilita herramientas de lectura de cuenta; mover dinero o cambiar configuración sigue sin estar disponible. Las respuestas estructuradas inválidas o fuentes no verificadas recurren a la búsqueda en documentación.\n\nEl texto del sitio web y del usuario son datos. Una instrucción dentro de una pregunta no puede alterar tarifas ni autorizar un pago.\n\nAlcance de la documentación\n\nLa documentación no afirma una certificación PCI DSS, una licencia bancaria, un estado de Comerciante de Registro, un tiempo de actividad garantizado ni una seguridad absoluta. Dichas afirmaciones requieren una confirmación separada y documentada.",
      "readMinutes": 2
    },
    {
      "id": "gateway",
      "title": "Integración de la pasarela de pago",
      "summary": "La pasarela procesa las operaciones financieras. Kevmi las conecta con pedidos, ajustes de tienda y notificaciones. Esta guía describe el contrato de integración y las verificaciones de disponibilidad.",
      "group": "developers",
      "url": "/docs/gateway",
      "tags": [
        "API",
        "pasarela",
        "backend",
        "servidor",
        "integración",
        "localhost"
      ],
      "sections": [
        {
          "id": "current",
          "title": "Verificación de disponibilidad",
          "paragraphs": [
            "Kevmi utiliza la API v3 de la pasarela para crear y recuperar operaciones, leer estados y conciliar resultados. La integración admite transporte cifrado de tarjeta y códigos bancarios, pagos QR de Alipay y SBP, un catálogo de criptomonedas/redes y eventos financieros entrantes.",
            "gateway.configured en GET /api/config informa si están presentes los ajustes de conexión requeridos. Este endpoint no sondea la pasarela; gateway.connected=false aquí significa que la conectividad no se ha verificado. Para una factura específica, lea invoice.availability en GET /api/checkout/{token}: verifica el método, el monto, los términos y la aprobación del comerciante. El campo de compatibilidad invoice.gatewayConnected refleja availability.available y tampoco es una verificación de salud ni una garantía de aprobación del pago.",
            "Un nuevo pago e intento de tarjeta requieren que la última solicitud de revisión web del comerciante esté aprobada. La aprobación por sí sola no conecta la pasarela de pago. Si la revisión cambia después del envío, la operación existente permanece disponible para lecturas de estado, conciliación y un código bancario solicitado."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "required",
          "title": "Contrato de pago del cliente",
          "paragraphs": [
            "Los datos sensibles se cifran en el navegador con RSA-OAEP-256 y A256GCM. La clave privada permanece en la pasarela. Kevmi valida que la intención pertenece a esta factura y propósito, transmite el sobre, y no almacena números de tarjeta en texto plano, CVV, nombre del comprador, correo electrónico, códigos bancarios ni el sobre mismo.",
            "Instale la extensión de transporte cifrado en el host de la pasarela antes de habilitar tarjetas. Verifica la firma de la intención, expiración, reproducción, orden y montos. No hay alternativa en texto plano. Esto describe el mecanismo de protección, no la certificación PCI."
          ],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Ruta de Kevmi",
              "Propósito"
            ],
            "rows": [
              [
                "GET /api/checkout/{token}",
                "Factura, cotización, disponibilidad del método y pago existente"
              ],
              [
                "POST /api/checkout/{token}/card-intent",
                "Intención de un solo uso y clave pública para pago o código"
              ],
              [
                "POST /api/checkout/{token}/pay",
                "Iniciar una operación; la tarjeta usa sellado: {intent,jwe}"
              ],
              [
                "POST /api/checkout/{token}/code",
                "Código de un solo uso cifrado para el desafío bancario actual"
              ],
              [
                "GET /api/checkout/{token}/status",
                "Leer la operación original sin otro cargo"
              ],
              [
                "POST /api/checkout/{token}/reconcile",
                "Reconciliar explícitamente la operación original"
              ],
              [
                "GET /api/checkout/{token}/crypto-services",
                "Monedas, redes y límites actuales para una factura USDT"
              ]
            ]
          },
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "network",
          "title": "Alojamiento y conectividad de pasarela",
          "paragraphs": [
            "Kevmi admite alojamiento en Sites en Cloudflare Workers con D1, y autoalojamiento en Node.js con SQLite. SQLite requiere un volumen persistente y copias de seguridad. La pasarela de pago se ejecuta como un servicio separado con su propio almacenamiento duradero.",
            "Una pasarela externa requiere un origen HTTPS alcanzable por el servidor. En el paquete autoalojado, el servidor se conecta a un servicio de pasarela fijo en la red privada del contenedor; la API del servicio de pasarela no está expuesta a internet. El sitio público y las devoluciones de llamada usan HTTPS. El navegador también cifra los datos de la tarjeta y los códigos bancarios antes de que lleguen a Kevmi.",
            "localhost se refiere al servidor o contenedor actual; no expone la computadora del propietario de la pasarela. Las claves de conexión y los secretos pertenecen solo a la configuración del servidor.",
            "Para un dominio personalizado, establezca un origen HTTPS público en NEXT_PUBLIC_SITE_URL antes de compilar. La documentación, los enlaces canónicos y los recursos de indexación usan este valor. Acepta solo un esquema y un host con un puerto opcional, sin ruta, consulta, fragmento ni credenciales. Emparejelo con APP_ORIGIN en la configuración del servidor."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "adapter",
          "title": "Cálculo y términos admitidos",
          "paragraphs": [
            "Las facturas del nuevo espacio de trabajo usan un precio base en USD y Any ofrece los cuatro métodos. SBP convierte a RUB al tipo de referencia congelado del Banco de Rusia; cripto usa la regla explícita de factura 1:1 USD/USDT. El precio nativo heredado sigue disponible para facturas antiguas y solicitudes de API sin pricingMode=universal. Consulte la sección de múltiples tiendas y precios en USD a continuación.",
            "Para un pago nuevo en vivo con tarjeta o Alipay, la pasarela actual solo admite feeCustomerPercent=0 y vatCustomerPercent=100: el comerciante cubre toda la comisión de procesamiento y el IVA se añade completo para el cliente. Otras participaciones se pueden guardar y calcular en una factura, pero la ejecución está bloqueada con unsupported_allocation. El servidor nunca cambia silenciosamente los términos guardados. Los pagos cripto SBP y USDT admiten todas las participaciones de comisión de procesamiento y no tienen IVA.",
            "Enviar un total_cents arbitrario no cambia el cálculo de impuestos del proveedor. Un monto real que difiera del total guardado entra en revisión y no puede confirmar el cumplimiento. Los campos business_balance de la pasarela se conservan como evidencia de liquidación, no se tratan como un saldo de comerciante de Kevmi."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "activation",
          "title": "Conectar una pasarela en vivo",
          "paragraphs": [
            "Conectar la pasarela incluye la configuración del servidor, verificaciones de los canales seleccionados y el procesamiento de eventos financieros verificados. La disponibilidad de la configuración se verifica por separado de la conectividad del proveedor. Un pago exitoso se acepta después de verificar el estado y el monto de la operación. Las instrucciones de implementación están en ops/gateway-integration.md."
          ],
          "bullets": [],
          "steps": [
            "Implemente el servidor de Kevmi y la pasarela como servicios separados. Configure almacenamiento duradero, copias de seguridad y los procesos en segundo plano requeridos.",
            "Para una conexión externa, establezca un origen HTTPS en GATEWAY_BASE_URL. El paquete autoalojado usa su servicio interno configurado. Ambos requieren un GATEWAY_API_KEY solo de servidor y un GATEWAY_WEBHOOK_SECRET separado; los secretos nunca llegan al navegador.",
            "Establezca el BACKEND_WEBHOOK_URL de la pasarela en /api/gateway/webhook en Kevmi y un BACKEND_WEBHOOK_SECRET coincidente.",
            "Habilite el transporte cifrado de tarjetas y mantenga su clave privada exclusivamente en el host de la pasarela. Verifique la disponibilidad de la clave pública y los ajustes de firma de intenciones coincidentes.",
            "Verifique la disponibilidad de los canales, las restricciones y la aprobación del sitio del comerciante antes del lanzamiento."
          ],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Webhooks y eventos repetidos",
              "href": "/docs/webhooks"
            },
            {
              "label": "Seguridad",
              "href": "/docs/security"
            }
          ]
        },
        {
          "id": "stores-usd",
          "title": "Múltiples tiendas y un precio base en USD",
          "paragraphs": [
            "Elija Todas las tiendas para análisis y operaciones agregados, o seleccione una tienda para sus propios registros. Cada tienda tiene un storeId, nombre, IVA predeterminado, facturas, claves de API, endpoints de webhook, historial de eventos y aplicación web separados. Las notificaciones y tickets de soporte pertenecen a la cuenta. Una cuenta puede crear hasta 100 tiendas. Los registros existentes permanecen en su primera tienda.",
            "Las facturas del nuevo espacio de trabajo usan pricingMode=\"universal\" y un precio base en USD. Any incluye tarjeta, alipay, sbp y cripto; un comerciante puede seleccionar un subconjunto. Tarjetas y Alipay cobran en USD. SBP cobra en RUB usando el tipo de referencia USD/RUB del Banco de Rusia. Cripto cobra USDT bajo la regla explícita de factura 1 USD = 1 USDT. Esta es una regla de conversión de factura, no una cotización de mercado de USDT. La pasarela proporciona la tasa de la moneda seleccionada, el monto exacto de transferencia y las instrucciones antes de la transferencia.",
            "El tipo de referencia y ambos montos se congelan al crear. Las facturas que implican conversión de RUB vencen dentro de 24 horas. Si no se puede obtener el tipo de referencia, la creación falla con FX_UNAVAILABLE; no se usa ningún tipo de respaldo inventado o desactualizado. El monto en minor del propietario y las cotizaciones usan la moneda contable USD. quotes[method].settlement contiene la cotización de cargo nativa. El checkout público expone la moneda de cargo seleccionada en currency, el precio original en baseAmountMinor/baseCurrency y el tipo de referencia en fx. Una vez que un pago ha sido despachado, su método no se puede cambiar; una factura tiene una operación de pasarela.",
            "Cree una clave de API dentro de la tienda prevista y envíe Authorization: Bearer <key> desde su servidor. Su vinculación a tienda es inmutable; X-Kevmi-Store no puede otorgarle acceso a otra tienda. Las sesiones del navegador seleccionan X-Kevmi-Store: <storeId>; omitirlo selecciona la primera tienda. El valor all solo es aceptado por GET /api/account/dashboard y GET /api/payment-links. Las mutaciones requieren una tienda seleccionada, Origin y X-CSRF-Token. Los IDs de cuenta y los IDs de tienda son identificadores diferentes.",
            "Por compatibilidad, las solicitudes de API sin pricingMode=\"universal\" conservan el precio nativo y las restricciones de moneda originales. Las facturas existentes nunca se recalculan. Los recibos confirmados en análisis reflejan pagos verificados menos gastos de factura guardados; no son un saldo retirable. Las monedas de factura heredadas permanecen separadas y los pagos se gestionan con soporte. Cumpla un pedido solo después de verificar payment.fulfillmentReady=true y payment.status=\"succeeded\" a través de la API del servidor, el historial de eventos o un webhook firmado."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "assistant-admin-v16",
          "title": "Asistencia, soporte y administración de proyectos",
          "paragraphs": [
            "Habilitar Permite el acceso a mis datos en el chat cuando necesites ayuda con operaciones privadas. Una solicitud web con includeAccount=true requiere una sesión válida, Origin y X-CSRF-Token; X-Kevmi-Store selecciona una tienda propia o todas las tiendas propias. Sin permiso, el asistente usa documentación pública. En Telegram, un botón separado habilita el acceso después de identificar al remitente.",
            "La herramienta read_account lee tiendas propias, facturas con estado de recibo verificado, eventos, solicitudes y solicitudes de soporte con respuestas de especialistas. Devuelve 30 registros y nextPage; los registros más antiguos están disponibles mediante paginación. Las lecturas por respuesta están limitadas, por lo que una muestra incompleta debe revelarse. Las claves de API, secretos de webhook, datos de tarjetas y sesiones no se proporcionan a la herramienta. No puede cobrar, pagar, reembolsar ni cambiar la configuración.",
            "Crear una solicitud de soporte en el espacio de trabajo o en Telegram coloca una alerta de administrador separada en una cola duradera. Se enlaza a /admin/tickets?ticket=<id>; los fallos temporales de Telegram se reintentan. La recuperación también recoge solicitudes abiertas antiguas sin alerta. Los administradores responden en la página de la solicitud; la respuesta se guarda en el espacio de trabajo del usuario y se envía por Telegram cuando las notificaciones de soporte están habilitadas.",
            "El bot usa botones en línea para el menú principal, tiendas, notificaciones, soporte, seguridad e idioma. La navegación edita el mensaje actual; un menú antiguo no disponible se reemplaza. Las notificaciones de pago y seguridad no se tratan como navegación desechable. Cerrar sesión a través del menú requiere confirmación. El comando explícito /logout sigue terminando cada sesión de cuenta.",
            "El panel /admin/project está restringido a IDs de Telegram en la lista de permitidos MODERATOR_TELEGRAM_IDS del lado del servidor. Incluye usuarios, tiendas, operaciones, revocación de claves, deshabilitación de webhooks, pausa de facturas, controles de aceptación y un registro de auditoría. Las mutaciones requieren CSRF y un motivo. El panel no puede restringir a un administrador ni declarar manualmente un pago como exitoso. Restringir a un propietario termina las sesiones y bloquea el acceso a claves de API; restringir una tienda detiene nuevas operaciones. El historial se conserva.",
            "La oferta pública está disponible en /public-offer y la política de privacidad en /privacy-policy en cada idioma habilitado. Busca monedas por nombre o ticker. Un selector de red aparece solo cuando hay múltiples redes en vivo disponibles. Una sola red se selecciona automáticamente y permanece nombrada en la confirmación. La disponibilidad en vivo de la pasarela determina los pares seleccionables; el catálogo de referencia no habilita un servicio.",
            "Usa update.sh para lanzamientos rutinarios de la aplicación web: compila el candidato, verifica el historial de migraciones, haz una copia de seguridad de SQLite en línea, inicia un segundo contenedor, verifícalo y cambia Caddy sin interrupciones. La pasarela, PostgreSQL y el correo no se reinician. Los activos estáticos anteriores siguen disponibles para pestañas abiertas. Una nueva migración requiere autorización revisada explícita; un cambio de esquema incompatible no es un despliegue sin interrupciones."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Oferta pública",
              "href": "/public-offer"
            },
            {
              "label": "Política de privacidad",
              "href": "/privacy-policy"
            }
          ]
        }
      ],
      "body": "Verificación de disponibilidad\n\nKevmi utiliza la API v3 de la pasarela para crear y recuperar operaciones, leer estados y conciliar resultados. La integración admite transporte cifrado de tarjeta y códigos bancarios, pagos QR de Alipay y SBP, un catálogo de criptomonedas/redes y eventos financieros entrantes.\n\ngateway.configured en GET /api/config informa si están presentes los ajustes de conexión requeridos. Este endpoint no sondea la pasarela; gateway.connected=false aquí significa que la conectividad no se ha verificado. Para una factura específica, lea invoice.availability en GET /api/checkout/{token}: verifica el método, el monto, los términos y la aprobación del comerciante. El campo de compatibilidad invoice.gatewayConnected refleja availability.available y tampoco es una verificación de salud ni una garantía de aprobación del pago.\n\nUn nuevo pago e intento de tarjeta requieren que la última solicitud de revisión web del comerciante esté aprobada. La aprobación por sí sola no conecta la pasarela de pago. Si la revisión cambia después del envío, la operación existente permanece disponible para lecturas de estado, conciliación y un código bancario solicitado.\n\nContrato de pago del cliente\n\nLos datos sensibles se cifran en el navegador con RSA-OAEP-256 y A256GCM. La clave privada permanece en la pasarela. Kevmi valida que la intención pertenece a esta factura y propósito, transmite el sobre, y no almacena números de tarjeta en texto plano, CVV, nombre del comprador, correo electrónico, códigos bancarios ni el sobre mismo.\n\nInstale la extensión de transporte cifrado en el host de la pasarela antes de habilitar tarjetas. Verifica la firma de la intención, expiración, reproducción, orden y montos. No hay alternativa en texto plano. Esto describe el mecanismo de protección, no la certificación PCI.\n\nRuta de Kevmi · Propósito\nGET /api/checkout/{token} · Factura, cotización, disponibilidad del método y pago existente\nPOST /api/checkout/{token}/card-intent · Intención de un solo uso y clave pública para pago o código\nPOST /api/checkout/{token}/pay · Iniciar una operación; la tarjeta usa sellado: {intent,jwe}\nPOST /api/checkout/{token}/code · Código de un solo uso cifrado para el desafío bancario actual\nGET /api/checkout/{token}/status · Leer la operación original sin otro cargo\nPOST /api/checkout/{token}/reconcile · Reconciliar explícitamente la operación original\nGET /api/checkout/{token}/crypto-services · Monedas, redes y límites actuales para una factura USDT\n\nAlojamiento y conectividad de pasarela\n\nKevmi admite alojamiento en Sites en Cloudflare Workers con D1, y autoalojamiento en Node.js con SQLite. SQLite requiere un volumen persistente y copias de seguridad. La pasarela de pago se ejecuta como un servicio separado con su propio almacenamiento duradero.\n\nUna pasarela externa requiere un origen HTTPS alcanzable por el servidor. En el paquete autoalojado, el servidor se conecta a un servicio de pasarela fijo en la red privada del contenedor; la API del servicio de pasarela no está expuesta a internet. El sitio público y las devoluciones de llamada usan HTTPS. El navegador también cifra los datos de la tarjeta y los códigos bancarios antes de que lleguen a Kevmi.\n\nlocalhost se refiere al servidor o contenedor actual; no expone la computadora del propietario de la pasarela. Las claves de conexión y los secretos pertenecen solo a la configuración del servidor.\n\nPara un dominio personalizado, establezca un origen HTTPS público en NEXT_PUBLIC_SITE_URL antes de compilar. La documentación, los enlaces canónicos y los recursos de indexación usan este valor. Acepta solo un esquema y un host con un puerto opcional, sin ruta, consulta, fragmento ni credenciales. Emparejelo con APP_ORIGIN en la configuración del servidor.\n\nCálculo y términos admitidos\n\nLas facturas del nuevo espacio de trabajo usan un precio base en USD y Any ofrece los cuatro métodos. SBP convierte a RUB al tipo de referencia congelado del Banco de Rusia; cripto usa la regla explícita de factura 1:1 USD/USDT. El precio nativo heredado sigue disponible para facturas antiguas y solicitudes de API sin pricingMode=universal. Consulte la sección de múltiples tiendas y precios en USD a continuación.\n\nPara un pago nuevo en vivo con tarjeta o Alipay, la pasarela actual solo admite feeCustomerPercent=0 y vatCustomerPercent=100: el comerciante cubre toda la comisión de procesamiento y el IVA se añade completo para el cliente. Otras participaciones se pueden guardar y calcular en una factura, pero la ejecución está bloqueada con unsupported_allocation. El servidor nunca cambia silenciosamente los términos guardados. Los pagos cripto SBP y USDT admiten todas las participaciones de comisión de procesamiento y no tienen IVA.\n\nEnviar un total_cents arbitrario no cambia el cálculo de impuestos del proveedor. Un monto real que difiera del total guardado entra en revisión y no puede confirmar el cumplimiento. Los campos business_balance de la pasarela se conservan como evidencia de liquidación, no se tratan como un saldo de comerciante de Kevmi.\n\nConectar una pasarela en vivo\n\nConectar la pasarela incluye la configuración del servidor, verificaciones de los canales seleccionados y el procesamiento de eventos financieros verificados. La disponibilidad de la configuración se verifica por separado de la conectividad del proveedor. Un pago exitoso se acepta después de verificar el estado y el monto de la operación. Las instrucciones de implementación están en ops/gateway-integration.md.\n\nImplemente el servidor de Kevmi y la pasarela como servicios separados. Configure almacenamiento duradero, copias de seguridad y los procesos en segundo plano requeridos.\n\nPara una conexión externa, establezca un origen HTTPS en GATEWAY_BASE_URL. El paquete autoalojado usa su servicio interno configurado. Ambos requieren un GATEWAY_API_KEY solo de servidor y un GATEWAY_WEBHOOK_SECRET separado; los secretos nunca llegan al navegador.\n\nEstablezca el BACKEND_WEBHOOK_URL de la pasarela en /api/gateway/webhook en Kevmi y un BACKEND_WEBHOOK_SECRET coincidente.\n\nHabilite el transporte cifrado de tarjetas y mantenga su clave privada exclusivamente en el host de la pasarela. Verifique la disponibilidad de la clave pública y los ajustes de firma de intenciones coincidentes.\n\nVerifique la disponibilidad de los canales, las restricciones y la aprobación del sitio del comerciante antes del lanzamiento.\n\nWebhooks y eventos repetidos\n\nSeguridad\n\nMúltiples tiendas y un precio base en USD\n\nElija Todas las tiendas para análisis y operaciones agregados, o seleccione una tienda para sus propios registros. Cada tienda tiene un storeId, nombre, IVA predeterminado, facturas, claves de API, endpoints de webhook, historial de eventos y aplicación web separados. Las notificaciones y tickets de soporte pertenecen a la cuenta. Una cuenta puede crear hasta 100 tiendas. Los registros existentes permanecen en su primera tienda.\n\nLas facturas del nuevo espacio de trabajo usan pricingMode=\"universal\" y un precio base en USD. Any incluye tarjeta, alipay, sbp y cripto; un comerciante puede seleccionar un subconjunto. Tarjetas y Alipay cobran en USD. SBP cobra en RUB usando el tipo de referencia USD/RUB del Banco de Rusia. Cripto cobra USDT bajo la regla explícita de factura 1 USD = 1 USDT. Esta es una regla de conversión de factura, no una cotización de mercado de USDT. La pasarela proporciona la tasa de la moneda seleccionada, el monto exacto de transferencia y las instrucciones antes de la transferencia.\n\nEl tipo de referencia y ambos montos se congelan al crear. Las facturas que implican conversión de RUB vencen dentro de 24 horas. Si no se puede obtener el tipo de referencia, la creación falla con FX_UNAVAILABLE; no se usa ningún tipo de respaldo inventado o desactualizado. El monto en minor del propietario y las cotizaciones usan la moneda contable USD. quotes[method].settlement contiene la cotización de cargo nativa. El checkout público expone la moneda de cargo seleccionada en currency, el precio original en baseAmountMinor/baseCurrency y el tipo de referencia en fx. Una vez que un pago ha sido despachado, su método no se puede cambiar; una factura tiene una operación de pasarela.\n\nCree una clave de API dentro de la tienda prevista y envíe Authorization: Bearer <key> desde su servidor. Su vinculación a tienda es inmutable; X-Kevmi-Store no puede otorgarle acceso a otra tienda. Las sesiones del navegador seleccionan X-Kevmi-Store: <storeId>; omitirlo selecciona la primera tienda. El valor all solo es aceptado por GET /api/account/dashboard y GET /api/payment-links. Las mutaciones requieren una tienda seleccionada, Origin y X-CSRF-Token. Los IDs de cuenta y los IDs de tienda son identificadores diferentes.\n\nPor compatibilidad, las solicitudes de API sin pricingMode=\"universal\" conservan el precio nativo y las restricciones de moneda originales. Las facturas existentes nunca se recalculan. Los recibos confirmados en análisis reflejan pagos verificados menos gastos de factura guardados; no son un saldo retirable. Las monedas de factura heredadas permanecen separadas y los pagos se gestionan con soporte. Cumpla un pedido solo después de verificar payment.fulfillmentReady=true y payment.status=\"succeeded\" a través de la API del servidor, el historial de eventos o un webhook firmado.\n\nAsistencia, soporte y administración de proyectos\n\nHabilitar Permite el acceso a mis datos en el chat cuando necesites ayuda con operaciones privadas. Una solicitud web con includeAccount=true requiere una sesión válida, Origin y X-CSRF-Token; X-Kevmi-Store selecciona una tienda propia o todas las tiendas propias. Sin permiso, el asistente usa documentación pública. En Telegram, un botón separado habilita el acceso después de identificar al remitente.\n\nLa herramienta read_account lee tiendas propias, facturas con estado de recibo verificado, eventos, solicitudes y solicitudes de soporte con respuestas de especialistas. Devuelve 30 registros y nextPage; los registros más antiguos están disponibles mediante paginación. Las lecturas por respuesta están limitadas, por lo que una muestra incompleta debe revelarse. Las claves de API, secretos de webhook, datos de tarjetas y sesiones no se proporcionan a la herramienta. No puede cobrar, pagar, reembolsar ni cambiar la configuración.\n\nCrear una solicitud de soporte en el espacio de trabajo o en Telegram coloca una alerta de administrador separada en una cola duradera. Se enlaza a /admin/tickets?ticket=<id>; los fallos temporales de Telegram se reintentan. La recuperación también recoge solicitudes abiertas antiguas sin alerta. Los administradores responden en la página de la solicitud; la respuesta se guarda en el espacio de trabajo del usuario y se envía por Telegram cuando las notificaciones de soporte están habilitadas.\n\nEl bot usa botones en línea para el menú principal, tiendas, notificaciones, soporte, seguridad e idioma. La navegación edita el mensaje actual; un menú antiguo no disponible se reemplaza. Las notificaciones de pago y seguridad no se tratan como navegación desechable. Cerrar sesión a través del menú requiere confirmación. El comando explícito /logout sigue terminando cada sesión de cuenta.\n\nEl panel /admin/project está restringido a IDs de Telegram en la lista de permitidos MODERATOR_TELEGRAM_IDS del lado del servidor. Incluye usuarios, tiendas, operaciones, revocación de claves, deshabilitación de webhooks, pausa de facturas, controles de aceptación y un registro de auditoría. Las mutaciones requieren CSRF y un motivo. El panel no puede restringir a un administrador ni declarar manualmente un pago como exitoso. Restringir a un propietario termina las sesiones y bloquea el acceso a claves de API; restringir una tienda detiene nuevas operaciones. El historial se conserva.\n\nLa oferta pública está disponible en /public-offer y la política de privacidad en /privacy-policy en cada idioma habilitado. Busca monedas por nombre o ticker. Un selector de red aparece solo cuando hay múltiples redes en vivo disponibles. Una sola red se selecciona automáticamente y permanece nombrada en la confirmación. La disponibilidad en vivo de la pasarela determina los pares seleccionables; el catálogo de referencia no habilita un servicio.\n\nUsa update.sh para lanzamientos rutinarios de la aplicación web: compila el candidato, verifica el historial de migraciones, haz una copia de seguridad de SQLite en línea, inicia un segundo contenedor, verifícalo y cambia Caddy sin interrupciones. La pasarela, PostgreSQL y el correo no se reinician. Los activos estáticos anteriores siguen disponibles para pestañas abiertas. Una nueva migración requiere autorización revisada explícita; un cambio de esquema incompatible no es un despliegue sin interrupciones.\n\nOferta pública\n\nPolítica de privacidad",
      "readMinutes": 6
    },
    {
      "id": "webhooks",
      "title": "Webhooks: eventos, firmas y entrega",
      "summary": "Registre un endpoint HTTPS público, demuestre control y reciba eventos firmados de factura y pago. La entrega se pone en cola de forma duradera; procesar el mismo evento nuevamente debe ser seguro para su pedido.",
      "tags": [
        "webhook",
        "firma",
        "HMAC",
        "idempotencia",
        "evento",
        "reintento"
      ],
      "sections": [
        {
          "id": "sources",
          "title": "De dónde provienen los eventos",
          "paragraphs": [
            "invoice.created no significa pagado. Los eventos de pago provienen de una operación de servidor verificada después de una lectura actual de la pasarela; un nombre de evento entrante por sí solo es insuficiente.",
            "La entrada Pasarela → Kevmi y la entrega Kevmi → comerciante son tramos diferentes con secretos separados. El navegador, la navegación de retorno y los mensajes del widget no establecen el estado financiero."
          ],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Evento",
              "Fuente"
            ],
            "rows": [
              [
                "invoice.created",
                "Factura persistida"
              ],
              [
                "invoice.updated",
                "Disponibilidad del enlace cambiada"
              ],
              [
                "payment.succeeded",
                "Pago exacto verificado por el servidor"
              ],
              [
                "payment.failed",
                "Operación fallida verificada"
              ],
              [
                "payment.refunded",
                "Reembolso completo verificado"
              ],
              [
                "payment.partially_refunded",
                "Reembolso parcial verificado"
              ],
              [
                "payment.disputed",
                "Disputa verificada"
              ],
              [
                "payment.review_required",
                "La operación requiere revisión adicional"
              ]
            ]
          },
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "setup",
          "title": "Registrar y verificar un endpoint",
          "paragraphs": [
            "Las URL no pueden apuntar a direcciones IP, localhost, redes privadas, puertos no estándar ni contener credenciales. El DNS se verifica antes de la entrega; las solicitudes POST salientes no siguen redirecciones. Una cuenta puede registrar hasta cinco endpoints.",
            "El evento de verificación tiene livemode=false. Un código de estado HTTP exitoso por sí solo es insuficiente: el desafío debe coincidir exactamente. Rotar el secreto requiere verificación nuevamente."
          ],
          "bullets": [],
          "steps": [
            "En /account#webhooks en su cuenta de comerciante, ingrese una URL HTTPS pública, una descripción y los tipos de evento que necesite.",
            "Guarde el secreto emitido en el almacenamiento del lado del servidor. Su valor completo se muestra una sola vez.",
            "Verifique las firmas sobre los bytes originales de la solicitud.",
            "Ejecute la verificación del endpoint. Para endpoint.verification, devuelva JSON que repita data.challenge: {\"challenge\":\"el valor recibido\"}.",
            "Habilite el endpoint verificado e inspeccione el historial de entrega."
          ],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Webhooks en tu cuenta",
              "href": "/account#webhooks"
            }
          ]
        },
        {
          "id": "envelope",
          "title": "Sobre del evento",
          "paragraphs": [
            "id permanece igual en cada intento de entrega de un evento. createdAt es una marca de tiempo Unix en milisegundos, y apiVersion identifica la versión del contrato. data contiene el objeto persistido en el servidor; el ejemplo está abreviado.",
            "livemode=true distingue un evento real del servidor de la verificación del endpoint. No significa que una factura esté pagada: verifica el tipo y los datos de pago. Maneja los tipos de evento conocidos y valida el esquema."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": {
            "language": "JSON · shortened example",
            "code": "{\n  \"id\": \"evt_example\",\n  \"type\": \"invoice.created\",\n  \"apiVersion\": \"2026-10-21\",\n  \"createdAt\": 1792540800000,\n  \"livemode\": true,\n  \"data\": {\n    \"invoice\": {\n      \"id\": \"lnk_example\",\n      \"orderId\": \"order-1042\",\n      \"currency\": \"USD\",\n      \"amountMinor\": 500,\n      \"vatCustomerPercent\": 100,\n      \"feeCustomerPercent\": 0\n    }\n  }\n}"
          },
          "note": "",
          "links": []
        },
        {
          "id": "signature",
          "title": "Verificar HMAC-SHA256",
          "paragraphs": [
            "Kevmi-Signature contiene t=segundos,v1=hex. La firma es HMAC-SHA256 sobre la cadena de la marca de tiempo, un punto y el cuerpo original: timestamp + \".\" + rawBody. Usa el secreto específico del endpoint y una comparación de tiempo constante.",
            "Rechaza firmas cuya marca de tiempo difiera de la hora del servidor en más de 300 segundos en cualquier dirección. Sincroniza los relojes. No analices ni vuelvas a serializar JSON antes de la verificación: los espacios en blanco y el orden de las propiedades afectan los bytes firmados."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": {
            "language": "Node.js · verification core",
            "code": "import { createHmac, timingSafeEqual } from 'node:crypto';\n\nfunction verifyKevmi(rawBody, header, secret, nowSeconds) {\n  const match = /^t=(\\d{10}),v1=([a-f0-9]{64})$/.exec(header || '');\n  if (!match || Math.abs(nowSeconds - Number(match[1])) > 300) {\n    return false;\n  }\n  const expected = createHmac('sha256', secret)\n    .update(match[1] + '.')\n    .update(rawBody)\n    .digest();\n  const received = Buffer.from(match[2], 'hex');\n  return expected.length === received.length\n    && timingSafeEqual(expected, received);\n}\n\n// Read bytes before JSON parsing; cap the request body.\n// secret comes from your server secret store.\nconst valid = verifyKevmi(rawBody, signature, secret,\n  Math.floor(Date.now() / 1000));\nif (!valid) throw new Error('Invalid webhook signature');\nconst event = JSON.parse(rawBody.toString('utf8'));\n// Validate the event schema and persist its ID together\n// with your order update in one database transaction.\n// Return a 2xx response after durable acceptance."
          },
          "note": "Este ejemplo cubre la verificación de firma. Tu servidor HTTP también necesita un límite de tamaño del cuerpo, validación de esquema y persistencia transaccional de eventos.",
          "links": []
        },
        {
          "id": "delivery",
          "title": "Reintentos y confirmación",
          "paragraphs": [
            "Cualquier respuesta 2xx confirma un evento ordinario. Persiste el evento de forma duradera antes de responder; el trabajo costoso puede continuar a través de tu propia cola. El tiempo de espera de respuesta es de ocho segundos. Un error de red o una respuesta que no sea 2xx programa un reintento.",
            "Hay como máximo seis intentos: la entrega inicial más demoras de un minuto, cinco minutos, 30 minutos, dos horas y 12 horas después de fallos sucesivos. Estos son programas de cola, no garantías de hora exacta de entrega. Agotar los intentos marca la entrega como fallida.",
            "La entrega es al menos una vez y no promete un orden estricto. Persiste el ID único del evento en la misma transacción que la actualización de tu pedido. Un duplicado ya aplicado debe recibir 2xx sin cumplir el pedido nuevamente.",
            "Un reintento manual reinicia los intentos de entrega preservando el ID original del evento, el ID de entrega y el cuerpo exacto. Cada intento recibe una marca de tiempo de firma nueva. Pausar un endpoint conserva su cola; eliminarlo cancela las entregas pendientes y fallidas."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "reconcile",
          "title": "Historial de entrega y conciliación",
          "paragraphs": [
            "La interfaz muestra el estado del endpoint, entregas recientes, conteos de intentos, última respuesta HTTP, error y próxima hora de intento. Estos diagnósticos complementan tus propios registros de pedidos.",
            "GET /api/v1/events con events:read devuelve hasta 50 eventos y nextCursor. Pasa el nextCursor opaco sin cambios como cursor; null marca el final. El ordenamiento usa tanto createdAt como id. El límite anterior de milisegundos Unix permanece disponible por separado y no puede combinarse con cursor. Los endpoints verificados reciben eventos suscritos no antes de su registro; los endpoints pausados siguen acumulando eventos en cola para entrega después de reanudar. Esto no promete historial anterior a la creación del endpoint."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Claves de API y creación de facturas",
              "href": "/docs/payment-links-api"
            }
          ]
        },
        {
          "id": "gateway",
          "title": "Verificaciones de recibos entrantes de gateway",
          "paragraphs": [
            "Gateway v3 publica en /api/gateway/webhook con X-Gateway-Event-Id, X-Gateway-Timestamp y X-Gateway-Signature: v1=<hex>. HMAC-SHA256 firma timestamp + \".\" + rawBody con GATEWAY_WEBHOOK_SECRET; la ventana de reloj es de 300 segundos. Se verifican la igualdad de ID entre cabecera y cuerpo, la versión de API, el modo en vivo y el hash del cuerpo.",
            "Un ID de evento reutilizado con bytes de cuerpo diferentes es rechazado. Una notificación firmada activa un GET autenticado de la operación exacta. Se verifican pedido, método, moneda, base, total aprobado y versión. El éxito requiere fulfillment_ready=true, verification=provider_confirmed, el monto pagado exacto y sin disputa; cripto también necesita evidencia de liquidación confirmada.",
            "El manejo de ingreso, recibos y eventos de comerciante están protegidos contra duplicados. Los formatos antiguos de notificación solo para navegador no pueden establecer un pago exitoso. Los webhooks de comerciante nunca contienen campos de tarjeta, códigos bancarios, datos QR, credenciales del proveedor ni el secreto del gateway."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "telegram",
          "title": "Telegram tiene un contrato separado",
          "paragraphs": [
            "POST /api/telegram/webhook verifica X-Telegram-Bot-Api-Secret-Token, la estructura de la actualización y el remitente. update_id protege contra procesamiento duplicado. Esta ruta maneja inicio de sesión, comandos, soporte y acciones de moderación; no acepta recibos financieros.",
            "El propietario del despliegue configura el token del bot, el secreto del webhook, el registro setWebhook y la dirección HTTPS alcanzable. Son separados del secreto de firma del endpoint de comerciante."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "stores-usd",
          "title": "Múltiples tiendas y un precio base en USD",
          "paragraphs": [
            "Elija Todas las tiendas para análisis y operaciones agregados, o seleccione una tienda para sus propios registros. Cada tienda tiene un storeId, nombre, IVA predeterminado, facturas, claves de API, endpoints de webhook, historial de eventos y aplicación web separados. Las notificaciones y tickets de soporte pertenecen a la cuenta. Una cuenta puede crear hasta 100 tiendas. Los registros existentes permanecen en su primera tienda.",
            "Las facturas del nuevo espacio de trabajo usan pricingMode=\"universal\" y un precio base en USD. Any incluye tarjeta, alipay, sbp y cripto; un comerciante puede seleccionar un subconjunto. Tarjetas y Alipay cobran en USD. SBP cobra en RUB usando el tipo de referencia USD/RUB del Banco de Rusia. Cripto cobra USDT bajo la regla explícita de factura 1 USD = 1 USDT. Esta es una regla de conversión de factura, no una cotización de mercado de USDT. La pasarela proporciona la tasa de la moneda seleccionada, el monto exacto de transferencia y las instrucciones antes de la transferencia.",
            "El tipo de referencia y ambos montos se congelan al crear. Las facturas que implican conversión de RUB vencen dentro de 24 horas. Si no se puede obtener el tipo de referencia, la creación falla con FX_UNAVAILABLE; no se usa ningún tipo de respaldo inventado o desactualizado. El monto en minor del propietario y las cotizaciones usan la moneda contable USD. quotes[method].settlement contiene la cotización de cargo nativa. El checkout público expone la moneda de cargo seleccionada en currency, el precio original en baseAmountMinor/baseCurrency y el tipo de referencia en fx. Una vez que un pago ha sido despachado, su método no se puede cambiar; una factura tiene una operación de pasarela.",
            "Cree una clave de API dentro de la tienda prevista y envíe Authorization: Bearer <key> desde su servidor. Su vinculación a tienda es inmutable; X-Kevmi-Store no puede otorgarle acceso a otra tienda. Las sesiones del navegador seleccionan X-Kevmi-Store: <storeId>; omitirlo selecciona la primera tienda. El valor all solo es aceptado por GET /api/account/dashboard y GET /api/payment-links. Las mutaciones requieren una tienda seleccionada, Origin y X-CSRF-Token. Los IDs de cuenta y los IDs de tienda son identificadores diferentes.",
            "Por compatibilidad, las solicitudes de API sin pricingMode=\"universal\" conservan el precio nativo y las restricciones de moneda originales. Las facturas existentes nunca se recalculan. Los recibos confirmados en análisis reflejan pagos verificados menos gastos de factura guardados; no son un saldo retirable. Las monedas de factura heredadas permanecen separadas y los pagos se gestionan con soporte. Cumpla un pedido solo después de verificar payment.fulfillmentReady=true y payment.status=\"succeeded\" a través de la API del servidor, el historial de eventos o un webhook firmado."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        }
      ],
      "group": "developers",
      "url": "/docs/webhooks",
      "body": "De dónde provienen los eventos\n\ninvoice.created no significa pagado. Los eventos de pago provienen de una operación de servidor verificada después de una lectura actual de la pasarela; un nombre de evento entrante por sí solo es insuficiente.\n\nLa entrada Pasarela → Kevmi y la entrega Kevmi → comerciante son tramos diferentes con secretos separados. El navegador, la navegación de retorno y los mensajes del widget no establecen el estado financiero.\n\nEvento · Fuente\ninvoice.created · Factura persistida\ninvoice.updated · Disponibilidad del enlace cambiada\npayment.succeeded · Pago exacto verificado por el servidor\npayment.failed · Operación fallida verificada\npayment.refunded · Reembolso completo verificado\npayment.partially_refunded · Reembolso parcial verificado\npayment.disputed · Disputa verificada\npayment.review_required · La operación requiere revisión adicional\n\nRegistrar y verificar un endpoint\n\nLas URL no pueden apuntar a direcciones IP, localhost, redes privadas, puertos no estándar ni contener credenciales. El DNS se verifica antes de la entrega; las solicitudes POST salientes no siguen redirecciones. Una cuenta puede registrar hasta cinco endpoints.\n\nEl evento de verificación tiene livemode=false. Un código de estado HTTP exitoso por sí solo es insuficiente: el desafío debe coincidir exactamente. Rotar el secreto requiere verificación nuevamente.\n\nEn /account#webhooks en su cuenta de comerciante, ingrese una URL HTTPS pública, una descripción y los tipos de evento que necesite.\n\nGuarde el secreto emitido en el almacenamiento del lado del servidor. Su valor completo se muestra una sola vez.\n\nVerifique las firmas sobre los bytes originales de la solicitud.\n\nEjecute la verificación del endpoint. Para endpoint.verification, devuelva JSON que repita data.challenge: {\"challenge\":\"el valor recibido\"}.\n\nHabilite el endpoint verificado e inspeccione el historial de entrega.\n\nWebhooks en tu cuenta\n\nSobre del evento\n\nid permanece igual en cada intento de entrega de un evento. createdAt es una marca de tiempo Unix en milisegundos, y apiVersion identifica la versión del contrato. data contiene el objeto persistido en el servidor; el ejemplo está abreviado.\n\nlivemode=true distingue un evento real del servidor de la verificación del endpoint. No significa que una factura esté pagada: verifica el tipo y los datos de pago. Maneja los tipos de evento conocidos y valida el esquema.\n\n{\n  \"id\": \"evt_example\",\n  \"type\": \"invoice.created\",\n  \"apiVersion\": \"2026-10-21\",\n  \"createdAt\": 1792540800000,\n  \"livemode\": true,\n  \"data\": {\n    \"invoice\": {\n      \"id\": \"lnk_example\",\n      \"orderId\": \"order-1042\",\n      \"currency\": \"USD\",\n      \"amountMinor\": 500,\n      \"vatCustomerPercent\": 100,\n      \"feeCustomerPercent\": 0\n    }\n  }\n}\n\nVerificar HMAC-SHA256\n\nKevmi-Signature contiene t=segundos,v1=hex. La firma es HMAC-SHA256 sobre la cadena de la marca de tiempo, un punto y el cuerpo original: timestamp + \".\" + rawBody. Usa el secreto específico del endpoint y una comparación de tiempo constante.\n\nRechaza firmas cuya marca de tiempo difiera de la hora del servidor en más de 300 segundos en cualquier dirección. Sincroniza los relojes. No analices ni vuelvas a serializar JSON antes de la verificación: los espacios en blanco y el orden de las propiedades afectan los bytes firmados.\n\nimport { createHmac, timingSafeEqual } from 'node:crypto';\n\nfunction verifyKevmi(rawBody, header, secret, nowSeconds) {\n  const match = /^t=(\\d{10}),v1=([a-f0-9]{64})$/.exec(header || '');\n  if (!match || Math.abs(nowSeconds - Number(match[1])) > 300) {\n    return false;\n  }\n  const expected = createHmac('sha256', secret)\n    .update(match[1] + '.')\n    .update(rawBody)\n    .digest();\n  const received = Buffer.from(match[2], 'hex');\n  return expected.length === received.length\n    && timingSafeEqual(expected, received);\n}\n\n// Read bytes before JSON parsing; cap the request body.\n// secret comes from your server secret store.\nconst valid = verifyKevmi(rawBody, signature, secret,\n  Math.floor(Date.now() / 1000));\nif (!valid) throw new Error('Invalid webhook signature');\nconst event = JSON.parse(rawBody.toString('utf8'));\n// Validate the event schema and persist its ID together\n// with your order update in one database transaction.\n// Return a 2xx response after durable acceptance.\n\nEste ejemplo cubre la verificación de firma. Tu servidor HTTP también necesita un límite de tamaño del cuerpo, validación de esquema y persistencia transaccional de eventos.\n\nReintentos y confirmación\n\nCualquier respuesta 2xx confirma un evento ordinario. Persiste el evento de forma duradera antes de responder; el trabajo costoso puede continuar a través de tu propia cola. El tiempo de espera de respuesta es de ocho segundos. Un error de red o una respuesta que no sea 2xx programa un reintento.\n\nHay como máximo seis intentos: la entrega inicial más demoras de un minuto, cinco minutos, 30 minutos, dos horas y 12 horas después de fallos sucesivos. Estos son programas de cola, no garantías de hora exacta de entrega. Agotar los intentos marca la entrega como fallida.\n\nLa entrega es al menos una vez y no promete un orden estricto. Persiste el ID único del evento en la misma transacción que la actualización de tu pedido. Un duplicado ya aplicado debe recibir 2xx sin cumplir el pedido nuevamente.\n\nUn reintento manual reinicia los intentos de entrega preservando el ID original del evento, el ID de entrega y el cuerpo exacto. Cada intento recibe una marca de tiempo de firma nueva. Pausar un endpoint conserva su cola; eliminarlo cancela las entregas pendientes y fallidas.\n\nHistorial de entrega y conciliación\n\nLa interfaz muestra el estado del endpoint, entregas recientes, conteos de intentos, última respuesta HTTP, error y próxima hora de intento. Estos diagnósticos complementan tus propios registros de pedidos.\n\nGET /api/v1/events con events:read devuelve hasta 50 eventos y nextCursor. Pasa el nextCursor opaco sin cambios como cursor; null marca el final. El ordenamiento usa tanto createdAt como id. El límite anterior de milisegundos Unix permanece disponible por separado y no puede combinarse con cursor. Los endpoints verificados reciben eventos suscritos no antes de su registro; los endpoints pausados siguen acumulando eventos en cola para entrega después de reanudar. Esto no promete historial anterior a la creación del endpoint.\n\nClaves de API y creación de facturas\n\nVerificaciones de recibos entrantes de gateway\n\nGateway v3 publica en /api/gateway/webhook con X-Gateway-Event-Id, X-Gateway-Timestamp y X-Gateway-Signature: v1=<hex>. HMAC-SHA256 firma timestamp + \".\" + rawBody con GATEWAY_WEBHOOK_SECRET; la ventana de reloj es de 300 segundos. Se verifican la igualdad de ID entre cabecera y cuerpo, la versión de API, el modo en vivo y el hash del cuerpo.\n\nUn ID de evento reutilizado con bytes de cuerpo diferentes es rechazado. Una notificación firmada activa un GET autenticado de la operación exacta. Se verifican pedido, método, moneda, base, total aprobado y versión. El éxito requiere fulfillment_ready=true, verification=provider_confirmed, el monto pagado exacto y sin disputa; cripto también necesita evidencia de liquidación confirmada.\n\nEl manejo de ingreso, recibos y eventos de comerciante están protegidos contra duplicados. Los formatos antiguos de notificación solo para navegador no pueden establecer un pago exitoso. Los webhooks de comerciante nunca contienen campos de tarjeta, códigos bancarios, datos QR, credenciales del proveedor ni el secreto del gateway.\n\nTelegram tiene un contrato separado\n\nPOST /api/telegram/webhook verifica X-Telegram-Bot-Api-Secret-Token, la estructura de la actualización y el remitente. update_id protege contra procesamiento duplicado. Esta ruta maneja inicio de sesión, comandos, soporte y acciones de moderación; no acepta recibos financieros.\n\nEl propietario del despliegue configura el token del bot, el secreto del webhook, el registro setWebhook y la dirección HTTPS alcanzable. Son separados del secreto de firma del endpoint de comerciante.\n\nMúltiples tiendas y un precio base en USD\n\nElija Todas las tiendas para análisis y operaciones agregados, o seleccione una tienda para sus propios registros. Cada tienda tiene un storeId, nombre, IVA predeterminado, facturas, claves de API, endpoints de webhook, historial de eventos y aplicación web separados. Las notificaciones y tickets de soporte pertenecen a la cuenta. Una cuenta puede crear hasta 100 tiendas. Los registros existentes permanecen en su primera tienda.\n\nLas facturas del nuevo espacio de trabajo usan pricingMode=\"universal\" y un precio base en USD. Any incluye tarjeta, alipay, sbp y cripto; un comerciante puede seleccionar un subconjunto. Tarjetas y Alipay cobran en USD. SBP cobra en RUB usando el tipo de referencia USD/RUB del Banco de Rusia. Cripto cobra USDT bajo la regla explícita de factura 1 USD = 1 USDT. Esta es una regla de conversión de factura, no una cotización de mercado de USDT. La pasarela proporciona la tasa de la moneda seleccionada, el monto exacto de transferencia y las instrucciones antes de la transferencia.\n\nEl tipo de referencia y ambos montos se congelan al crear. Las facturas que implican conversión de RUB vencen dentro de 24 horas. Si no se puede obtener el tipo de referencia, la creación falla con FX_UNAVAILABLE; no se usa ningún tipo de respaldo inventado o desactualizado. El monto en minor del propietario y las cotizaciones usan la moneda contable USD. quotes[method].settlement contiene la cotización de cargo nativa. El checkout público expone la moneda de cargo seleccionada en currency, el precio original en baseAmountMinor/baseCurrency y el tipo de referencia en fx. Una vez que un pago ha sido despachado, su método no se puede cambiar; una factura tiene una operación de pasarela.\n\nCree una clave de API dentro de la tienda prevista y envíe Authorization: Bearer <key> desde su servidor. Su vinculación a tienda es inmutable; X-Kevmi-Store no puede otorgarle acceso a otra tienda. Las sesiones del navegador seleccionan X-Kevmi-Store: <storeId>; omitirlo selecciona la primera tienda. El valor all solo es aceptado por GET /api/account/dashboard y GET /api/payment-links. Las mutaciones requieren una tienda seleccionada, Origin y X-CSRF-Token. Los IDs de cuenta y los IDs de tienda son identificadores diferentes.\n\nPor compatibilidad, las solicitudes de API sin pricingMode=\"universal\" conservan el precio nativo y las restricciones de moneda originales. Las facturas existentes nunca se recalculan. Los recibos confirmados en análisis reflejan pagos verificados menos gastos de factura guardados; no son un saldo retirable. Las monedas de factura heredadas permanecen separadas y los pagos se gestionan con soporte. Cumpla un pedido solo después de verificar payment.fulfillmentReady=true y payment.status=\"succeeded\" a través de la API del servidor, el historial de eventos o un webhook firmado.",
      "readMinutes": 7
    },
    {
      "id": "limits",
      "title": "Límites y disponibilidad",
      "summary": "La disponibilidad de pago depende del método, el monto, el país y los términos de una factura en particular. Verifica el total, las restricciones y el tiempo de procesamiento aplicable antes de la confirmación.",
      "group": "payments",
      "url": "/docs/limits",
      "tags": [
        "límite",
        "tiempo de procesamiento",
        "retención",
        "reembolso",
        "contracargo",
        "restricción"
      ],
      "sections": [
        {
          "id": "pending",
          "title": "Límites de adaptador y canal",
          "paragraphs": [
            "Kevmi verifica los rangos a continuación antes de crear una operación. Un canal de pago puede imponer restricciones adicionales; un monto dentro del rango no garantiza aprobación. Cambiar la configuración del gateway no cambia automáticamente los límites de Kevmi.",
            "Un nuevo pago e intento de tarjeta requieren que la última solicitud de revisión web del comerciante esté aprobada. La aprobación por sí sola no conecta la pasarela de pago. Si la revisión cambia después del envío, la operación existente permanece disponible para lecturas de estado, conciliación y un código bancario solicitado."
          ],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Método",
              "Monto verificado",
              "Rango de Kevmi"
            ],
            "rows": [
              [
                "Tarjeta / Alipay",
                "Precio base en USD",
                "$1–$1,000"
              ],
              [
                "SBP",
                "Total del cliente en RUB",
                "₽1–₽100,000"
              ],
              [
                "Cripto",
                "Total del cliente en USDT",
                "1–1.000.000 USDT + límites del red seleccionada"
              ]
            ]
          },
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "validation",
          "title": "La validación no es un límite comercial",
          "paragraphs": [
            "La calculadora y la API rechazan montos negativos, monedas inválidas y cálculos donde la tarifa asignada del comerciante y el IVA exceden el monto base. Estas verificaciones protegen la corrección de los datos.",
            "Pasar la validación aritmética no garantiza que un proveedor pueda aceptar el pago. Los límites comerciales y de riesgo se verifican por separado mediante el canal de pago."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "refunds",
          "title": "Reembolsos y transacciones disputadas",
          "paragraphs": [
            "Reembolsos verificados, reembolsos parciales, disputas y estados de revisión aparecen en la operación y en los eventos de comerciante. Esto no implica que crear un reembolso o un pago esté implementado en la cuenta.",
            "No cumplas nuevamente por payment.partially_refunded, payment.refunded, payment.disputed o payment.review_required. Preserva la asociación original de pedido/pago y enruta los casos disputados a un operador autorizado."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "subscriptions",
          "title": "Cargos recurrentes",
          "paragraphs": [
            "Kevmi no tiene suscripciones ni pagos recurrentes. Guardar un enlace de pedido no autoriza un cargo automático futuro. Cada nuevo pedido se paga por separado."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "ready",
          "title": "Verificaciones de preparación",
          "paragraphs": [
            "gateway.configured en /api/config informa los ajustes requeridos del gateway, mientras que /api/health verifica el almacenamiento del servidor. Ninguno establece conectividad con un proveedor de pago. Usa invoice.availability en GET /api/checkout/{token} para los términos de una factura específica; el éxito del pago se verifica por separado contra la operación del gateway."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Requisitos de integración",
              "href": "/docs/gateway"
            },
            {
              "label": "Pregunta sobre tu caso de uso",
              "href": "/?support=open"
            }
          ]
        }
      ],
      "body": "Límites de adaptador y canal\n\nKevmi verifica los rangos a continuación antes de crear una operación. Un canal de pago puede imponer restricciones adicionales; un monto dentro del rango no garantiza aprobación. Cambiar la configuración del gateway no cambia automáticamente los límites de Kevmi.\n\nUn nuevo pago e intento de tarjeta requieren que la última solicitud de revisión web del comerciante esté aprobada. La aprobación por sí sola no conecta la pasarela de pago. Si la revisión cambia después del envío, la operación existente permanece disponible para lecturas de estado, conciliación y un código bancario solicitado.\n\nMétodo · Monto verificado · Rango de Kevmi\nTarjeta / Alipay · Precio base en USD · $1–$1,000\nSBP · Total del cliente en RUB · ₽1–₽100,000\nCripto · Total del cliente en USDT · 1–1.000.000 USDT + límites del red seleccionada\n\nLa validación no es un límite comercial\n\nLa calculadora y la API rechazan montos negativos, monedas inválidas y cálculos donde la tarifa asignada del comerciante y el IVA exceden el monto base. Estas verificaciones protegen la corrección de los datos.\n\nPasar la validación aritmética no garantiza que un proveedor pueda aceptar el pago. Los límites comerciales y de riesgo se verifican por separado mediante el canal de pago.\n\nReembolsos y transacciones disputadas\n\nReembolsos verificados, reembolsos parciales, disputas y estados de revisión aparecen en la operación y en los eventos de comerciante. Esto no implica que crear un reembolso o un pago esté implementado en la cuenta.\n\nNo cumplas nuevamente por payment.partially_refunded, payment.refunded, payment.disputed o payment.review_required. Preserva la asociación original de pedido/pago y enruta los casos disputados a un operador autorizado.\n\nCargos recurrentes\n\nKevmi no tiene suscripciones ni pagos recurrentes. Guardar un enlace de pedido no autoriza un cargo automático futuro. Cada nuevo pedido se paga por separado.\n\nVerificaciones de preparación\n\ngateway.configured en /api/config informa los ajustes requeridos del gateway, mientras que /api/health verifica el almacenamiento del servidor. Ninguno establece conectividad con un proveedor de pago. Usa invoice.availability en GET /api/checkout/{token} para los términos de una factura específica; el éxito del pago se verifica por separado contra la operación del gateway.\n\nRequisitos de integración\n\nPregunta sobre tu caso de uso",
      "readMinutes": 3
    },
    {
      "id": "agent-access",
      "title": "Recursos para motores de búsqueda e IA",
      "summary": "La información pública de Kevmi está disponible en HTML renderizado en el servidor, texto plano y formatos estructurados. Estos formatos comparten una versión del conocimiento y los mismos hechos comerciales.",
      "group": "developers",
      "url": "/docs/agent-access",
      "tags": [
        "SEO",
        "indexación",
        "llms",
        "robots",
        "sitemap",
        "agente",
        "JSON"
      ],
      "sections": [
        {
          "id": "files",
          "title": "Recursos públicos",
          "paragraphs": [],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Dirección",
              "Contenido"
            ],
            "rows": [
              [
                "/docs y /en/docs",
                "Ediciones completas de la guía en ruso e inglés"
              ],
              [
                "/llms.txt",
                "Índice en inglés y datos esenciales"
              ],
              [
                "/llms-full.txt",
                "Texto completo de conocimiento en inglés"
              ],
              [
                "/knowledge.json",
                "Datos, tarifas, artículos y versión"
              ],
              [
                "/openapi.json",
                "Contrato de API de servidor implementado"
              ],
              [
                "/sitemap.xml",
                "Páginas públicas publicadas"
              ],
              [
                "/robots.txt",
                "Directivas del rastreador"
              ]
            ]
          },
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "facts",
          "title": "Lectura de datos estructurados",
          "paragraphs": [
            "knowledge.facts.countries.card describe la cobertura mundial con restricciones explícitas. countryCount cuenta las entradas del directorio, coverageLabel es 190+, y exactList contiene las entradas ISO admitidas. restrictions conserva la lista de exclusión del proveedor.",
            "source=owner_provided y status=owner_list_received registran el origen de la lista. independentlyVerified=false y verifiedCountryCount=null significan que la lista no ha sido verificada de forma independiente contra una pasarela en vivo; sigue siendo una lista recibida y publicada.",
            "partialCoverage contiene ** países con cobertura de ubicación incompleta. unresolvedFootnotes conserva el marcador separado * para China. coverage=listed significa inclusión en la lista; partial_locations denota restricciones de ubicación; footnote_pending denota el significado separado no confirmado de un marcador. None garantiza la aprobación de cada tarjeta.",
            "gatewayConnected=null y gatewayIntegration.liveConfigurationProvided=null significan que la base de conocimiento estática no contiene el estado actual de un despliegue. gatewayIntegration.availability identifica los puntos finales para verificaciones actuales. gateway.configured en /api/config informa ajustes, no conectividad del proveedor. invoice.availability en la respuesta de pago describe los términos de factura elegibles, mientras que el campo de compatibilidad invoice.gatewayConnected refleja availability.available. Ninguno reemplaza la confirmación de operación. gatewayIntegration.adapterImplemented=true describe el soporte del protocolo v3; subscriptionsSupported=false excluye cargos recurrentes."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": {
            "language": "JSON · fact excerpt",
            "code": "{\n  \"subscriptionsSupported\": false,\n  \"gatewayConnected\": null,\n  \"countries\": {\n    \"card\": {\n      \"coverageLabel\": \"190+\",\n      \"policy\": \"worldwide_except_restrictions\",\n      \"restrictions\": [\n        {\n          \"code\": \"AF\",\n          \"name\": \"Afghanistan\"\n        },\n        {\n          \"code\": \"AQ\",\n          \"name\": \"Antarctica\"\n        },\n        {\n          \"code\": \"BY\",\n          \"name\": \"Belarus\"\n        },\n        {\n          \"code\": \"MM\",\n          \"name\": \"Burma (Myanmar)\"\n        },\n        {\n          \"code\": \"BI\",\n          \"name\": \"Burundi\"\n        },\n        {\n          \"code\": \"CF\",\n          \"name\": \"Central African Republic\"\n        },\n        {\n          \"code\": \"TD\",\n          \"name\": \"Chad\"\n        },\n        {\n          \"code\": \"CU\",\n          \"name\": \"Cuba\"\n        },\n        {\n          \"code\": \"CD\",\n          \"name\": \"Democratic Republic of Congo\"\n        },\n        {\n          \"code\": \"CG\",\n          \"name\": \"Republic of Congo\"\n        },\n        {\n          \"code\": \"ER\",\n          \"name\": \"Eritrea\"\n        },\n        {\n          \"code\": \"HT\",\n          \"name\": \"Haiti\"\n        },\n        {\n          \"code\": \"IR\",\n          \"name\": \"Iran\"\n        },\n        {\n          \"code\": \"IQ\",\n          \"name\": \"Iraq\"\n        },\n        {\n          \"code\": \"LY\",\n          \"name\": \"Libya\"\n        },\n        {\n          \"code\": \"ML\",\n          \"name\": \"Mali\"\n        },\n        {\n          \"code\": \"NI\",\n          \"name\": \"Nicaragua\"\n        },\n        {\n          \"code\": \"KP\",\n          \"name\": \"North Korea\"\n        },\n        {\n          \"code\": \"RU\",\n          \"name\": \"Russia\"\n        },\n        {\n          \"code\": \"SO\",\n          \"name\": \"Somalia\"\n        },\n        {\n          \"code\": \"SS\",\n          \"name\": \"South Sudan\"\n        },\n        {\n          \"code\": \"SD\",\n          \"name\": \"Sudan\"\n        },\n        {\n          \"code\": \"SY\",\n          \"name\": \"Syria\"\n        },\n        {\n          \"code\": \"VE\",\n          \"name\": \"Venezuela\"\n        },\n        {\n          \"code\": \"YE\",\n          \"name\": \"Yemen\"\n        },\n        {\n          \"code\": \"ZW\",\n          \"name\": \"Zimbabwe\"\n        },\n        {\n          \"code\": \"UA-43\",\n          \"name\": \"Crimea (Region of Ukraine)\"\n        },\n        {\n          \"code\": \"UA-14\",\n          \"name\": \"Donetsk (Region of Ukraine)\"\n        },\n        {\n          \"code\": \"UA-65\",\n          \"name\": \"Kherson (Region of Ukraine)\"\n        },\n        {\n          \"code\": \"UA-09\",\n          \"name\": \"Luhansk (Region of Ukraine)\"\n        },\n        {\n          \"code\": \"UA-23\",\n          \"name\": \"Zaporizhzhia (Region of Ukraine)\"\n        },\n        {\n          \"code\": \"AN\",\n          \"name\": \"Netherlands Antilles\"\n        }\n      ],\n      \"independentlyVerified\": false,\n      \"approvalGuaranteed\": false\n    }\n  },\n  \"gatewayIntegration\": {\n    \"adapterImplemented\": true,\n    \"contract\": \"v3\",\n    \"liveConfigurationProvided\": null,\n    \"availability\": {\n      \"source\": \"runtime\",\n      \"configurationEndpoint\": \"/api/config\",\n      \"configurationIncludesHealthCheck\": false,\n      \"checkoutEndpoint\": \"/api/checkout/{token}\",\n      \"checkoutIncludesProviderApproval\": false\n    }\n  }\n}"
          },
          "note": "",
          "links": []
        },
        {
          "id": "privacy",
          "title": "Límites de información pública",
          "paragraphs": [
            "El texto plano y JSON no contienen sesiones, tokens, solicitudes de soporte privadas, registros de pago de usuarios ni secretos de integración. Las páginas de inicio de sesión, cuenta y pago están excluidas de la indexación de búsqueda.",
            "Leer la documentación pública no otorga permisos de gestión de tienda. Los registros personales requieren una sesión válida y las mutaciones requieren verificaciones adicionales del servidor."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "updates",
          "title": "Actualizaciones y citas",
          "paragraphs": [
            "Los artículos tienen IDs estables, URLs, títulos y una fecha de actualización. Enlace a la guía pertinente al citar una respuesta y conserve las calificaciones sobre las condiciones de transacción.",
            "Los mapas del sitio, recursos llms y HTML renderizado por servidor facilitan la extracción del contenido. No garantizan indexación, posición en búsqueda ni uso por un sistema de IA externo.",
            "Solo las traducciones publicadas tienen URLs canónicas, alternativas hreflang y entradas en el mapa del sitio. Una configuración regional configurada para traducción futura no es una edición de idioma publicada."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "assistant-admin-v16",
          "title": "Asistencia, soporte y administración de proyectos",
          "paragraphs": [
            "Habilitar Permite el acceso a mis datos en el chat cuando necesites ayuda con operaciones privadas. Una solicitud web con includeAccount=true requiere una sesión válida, Origin y X-CSRF-Token; X-Kevmi-Store selecciona una tienda propia o todas las tiendas propias. Sin permiso, el asistente usa documentación pública. En Telegram, un botón separado habilita el acceso después de identificar al remitente.",
            "La herramienta read_account lee tiendas propias, facturas con estado de recibo verificado, eventos, solicitudes y solicitudes de soporte con respuestas de especialistas. Devuelve 30 registros y nextPage; los registros más antiguos están disponibles mediante paginación. Las lecturas por respuesta están limitadas, por lo que una muestra incompleta debe revelarse. Las claves de API, secretos de webhook, datos de tarjetas y sesiones no se proporcionan a la herramienta. No puede cobrar, pagar, reembolsar ni cambiar la configuración.",
            "Crear una solicitud de soporte en el espacio de trabajo o en Telegram coloca una alerta de administrador separada en una cola duradera. Se enlaza a /admin/tickets?ticket=<id>; los fallos temporales de Telegram se reintentan. La recuperación también recoge solicitudes abiertas antiguas sin alerta. Los administradores responden en la página de la solicitud; la respuesta se guarda en el espacio de trabajo del usuario y se envía por Telegram cuando las notificaciones de soporte están habilitadas.",
            "El bot usa botones en línea para el menú principal, tiendas, notificaciones, soporte, seguridad e idioma. La navegación edita el mensaje actual; un menú antiguo no disponible se reemplaza. Las notificaciones de pago y seguridad no se tratan como navegación desechable. Cerrar sesión a través del menú requiere confirmación. El comando explícito /logout sigue terminando cada sesión de cuenta.",
            "El panel /admin/project está restringido a IDs de Telegram en la lista de permitidos MODERATOR_TELEGRAM_IDS del lado del servidor. Incluye usuarios, tiendas, operaciones, revocación de claves, deshabilitación de webhooks, pausa de facturas, controles de aceptación y un registro de auditoría. Las mutaciones requieren CSRF y un motivo. El panel no puede restringir a un administrador ni declarar manualmente un pago como exitoso. Restringir a un propietario termina las sesiones y bloquea el acceso a claves de API; restringir una tienda detiene nuevas operaciones. El historial se conserva.",
            "La oferta pública está disponible en /public-offer y la política de privacidad en /privacy-policy en cada idioma habilitado. Busca monedas por nombre o ticker. Un selector de red aparece solo cuando hay múltiples redes en vivo disponibles. Una sola red se selecciona automáticamente y permanece nombrada en la confirmación. La disponibilidad en vivo de la pasarela determina los pares seleccionables; el catálogo de referencia no habilita un servicio.",
            "Usa update.sh para lanzamientos rutinarios de la aplicación web: compila el candidato, verifica el historial de migraciones, haz una copia de seguridad de SQLite en línea, inicia un segundo contenedor, verifícalo y cambia Caddy sin interrupciones. La pasarela, PostgreSQL y el correo no se reinician. Los activos estáticos anteriores siguen disponibles para pestañas abiertas. Una nueva migración requiere autorización revisada explícita; un cambio de esquema incompatible no es un despliegue sin interrupciones."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Oferta pública",
              "href": "/public-offer"
            },
            {
              "label": "Política de privacidad",
              "href": "/privacy-policy"
            }
          ]
        }
      ],
      "body": "Recursos públicos\n\nDirección · Contenido\n/docs y /en/docs · Ediciones completas de la guía en ruso e inglés\n/llms.txt · Índice en inglés y datos esenciales\n/llms-full.txt · Texto completo de conocimiento en inglés\n/knowledge.json · Datos, tarifas, artículos y versión\n/openapi.json · Contrato de API de servidor implementado\n/sitemap.xml · Páginas públicas publicadas\n/robots.txt · Directivas del rastreador\n\nLectura de datos estructurados\n\nknowledge.facts.countries.card describe la cobertura mundial con restricciones explícitas. countryCount cuenta las entradas del directorio, coverageLabel es 190+, y exactList contiene las entradas ISO admitidas. restrictions conserva la lista de exclusión del proveedor.\n\nsource=owner_provided y status=owner_list_received registran el origen de la lista. independentlyVerified=false y verifiedCountryCount=null significan que la lista no ha sido verificada de forma independiente contra una pasarela en vivo; sigue siendo una lista recibida y publicada.\n\npartialCoverage contiene ** países con cobertura de ubicación incompleta. unresolvedFootnotes conserva el marcador separado * para China. coverage=listed significa inclusión en la lista; partial_locations denota restricciones de ubicación; footnote_pending denota el significado separado no confirmado de un marcador. None garantiza la aprobación de cada tarjeta.\n\ngatewayConnected=null y gatewayIntegration.liveConfigurationProvided=null significan que la base de conocimiento estática no contiene el estado actual de un despliegue. gatewayIntegration.availability identifica los puntos finales para verificaciones actuales. gateway.configured en /api/config informa ajustes, no conectividad del proveedor. invoice.availability en la respuesta de pago describe los términos de factura elegibles, mientras que el campo de compatibilidad invoice.gatewayConnected refleja availability.available. Ninguno reemplaza la confirmación de operación. gatewayIntegration.adapterImplemented=true describe el soporte del protocolo v3; subscriptionsSupported=false excluye cargos recurrentes.\n\n{\n  \"subscriptionsSupported\": false,\n  \"gatewayConnected\": null,\n  \"countries\": {\n    \"card\": {\n      \"coverageLabel\": \"190+\",\n      \"policy\": \"worldwide_except_restrictions\",\n      \"restrictions\": [\n        {\n          \"code\": \"AF\",\n          \"name\": \"Afghanistan\"\n        },\n        {\n          \"code\": \"AQ\",\n          \"name\": \"Antarctica\"\n        },\n        {\n          \"code\": \"BY\",\n          \"name\": \"Belarus\"\n        },\n        {\n          \"code\": \"MM\",\n          \"name\": \"Burma (Myanmar)\"\n        },\n        {\n          \"code\": \"BI\",\n          \"name\": \"Burundi\"\n        },\n        {\n          \"code\": \"CF\",\n          \"name\": \"Central African Republic\"\n        },\n        {\n          \"code\": \"TD\",\n          \"name\": \"Chad\"\n        },\n        {\n          \"code\": \"CU\",\n          \"name\": \"Cuba\"\n        },\n        {\n          \"code\": \"CD\",\n          \"name\": \"Democratic Republic of Congo\"\n        },\n        {\n          \"code\": \"CG\",\n          \"name\": \"Republic of Congo\"\n        },\n        {\n          \"code\": \"ER\",\n          \"name\": \"Eritrea\"\n        },\n        {\n          \"code\": \"HT\",\n          \"name\": \"Haiti\"\n        },\n        {\n          \"code\": \"IR\",\n          \"name\": \"Iran\"\n        },\n        {\n          \"code\": \"IQ\",\n          \"name\": \"Iraq\"\n        },\n        {\n          \"code\": \"LY\",\n          \"name\": \"Libya\"\n        },\n        {\n          \"code\": \"ML\",\n          \"name\": \"Mali\"\n        },\n        {\n          \"code\": \"NI\",\n          \"name\": \"Nicaragua\"\n        },\n        {\n          \"code\": \"KP\",\n          \"name\": \"North Korea\"\n        },\n        {\n          \"code\": \"RU\",\n          \"name\": \"Russia\"\n        },\n        {\n          \"code\": \"SO\",\n          \"name\": \"Somalia\"\n        },\n        {\n          \"code\": \"SS\",\n          \"name\": \"South Sudan\"\n        },\n        {\n          \"code\": \"SD\",\n          \"name\": \"Sudan\"\n        },\n        {\n          \"code\": \"SY\",\n          \"name\": \"Syria\"\n        },\n        {\n          \"code\": \"VE\",\n          \"name\": \"Venezuela\"\n        },\n        {\n          \"code\": \"YE\",\n          \"name\": \"Yemen\"\n        },\n        {\n          \"code\": \"ZW\",\n          \"name\": \"Zimbabwe\"\n        },\n        {\n          \"code\": \"UA-43\",\n          \"name\": \"Crimea (Region of Ukraine)\"\n        },\n        {\n          \"code\": \"UA-14\",\n          \"name\": \"Donetsk (Region of Ukraine)\"\n        },\n        {\n          \"code\": \"UA-65\",\n          \"name\": \"Kherson (Region of Ukraine)\"\n        },\n        {\n          \"code\": \"UA-09\",\n          \"name\": \"Luhansk (Region of Ukraine)\"\n        },\n        {\n          \"code\": \"UA-23\",\n          \"name\": \"Zaporizhzhia (Region of Ukraine)\"\n        },\n        {\n          \"code\": \"AN\",\n          \"name\": \"Netherlands Antilles\"\n        }\n      ],\n      \"independentlyVerified\": false,\n      \"approvalGuaranteed\": false\n    }\n  },\n  \"gatewayIntegration\": {\n    \"adapterImplemented\": true,\n    \"contract\": \"v3\",\n    \"liveConfigurationProvided\": null,\n    \"availability\": {\n      \"source\": \"runtime\",\n      \"configurationEndpoint\": \"/api/config\",\n      \"configurationIncludesHealthCheck\": false,\n      \"checkoutEndpoint\": \"/api/checkout/{token}\",\n      \"checkoutIncludesProviderApproval\": false\n    }\n  }\n}\n\nLímites de información pública\n\nEl texto plano y JSON no contienen sesiones, tokens, solicitudes de soporte privadas, registros de pago de usuarios ni secretos de integración. Las páginas de inicio de sesión, cuenta y pago están excluidas de la indexación de búsqueda.\n\nLeer la documentación pública no otorga permisos de gestión de tienda. Los registros personales requieren una sesión válida y las mutaciones requieren verificaciones adicionales del servidor.\n\nActualizaciones y citas\n\nLos artículos tienen IDs estables, URLs, títulos y una fecha de actualización. Enlace a la guía pertinente al citar una respuesta y conserve las calificaciones sobre las condiciones de transacción.\n\nLos mapas del sitio, recursos llms y HTML renderizado por servidor facilitan la extracción del contenido. No garantizan indexación, posición en búsqueda ni uso por un sistema de IA externo.\n\nSolo las traducciones publicadas tienen URLs canónicas, alternativas hreflang y entradas en el mapa del sitio. Una configuración regional configurada para traducción futura no es una edición de idioma publicada.\n\nAsistencia, soporte y administración de proyectos\n\nHabilitar Permite el acceso a mis datos en el chat cuando necesites ayuda con operaciones privadas. Una solicitud web con includeAccount=true requiere una sesión válida, Origin y X-CSRF-Token; X-Kevmi-Store selecciona una tienda propia o todas las tiendas propias. Sin permiso, el asistente usa documentación pública. En Telegram, un botón separado habilita el acceso después de identificar al remitente.\n\nLa herramienta read_account lee tiendas propias, facturas con estado de recibo verificado, eventos, solicitudes y solicitudes de soporte con respuestas de especialistas. Devuelve 30 registros y nextPage; los registros más antiguos están disponibles mediante paginación. Las lecturas por respuesta están limitadas, por lo que una muestra incompleta debe revelarse. Las claves de API, secretos de webhook, datos de tarjetas y sesiones no se proporcionan a la herramienta. No puede cobrar, pagar, reembolsar ni cambiar la configuración.\n\nCrear una solicitud de soporte en el espacio de trabajo o en Telegram coloca una alerta de administrador separada en una cola duradera. Se enlaza a /admin/tickets?ticket=<id>; los fallos temporales de Telegram se reintentan. La recuperación también recoge solicitudes abiertas antiguas sin alerta. Los administradores responden en la página de la solicitud; la respuesta se guarda en el espacio de trabajo del usuario y se envía por Telegram cuando las notificaciones de soporte están habilitadas.\n\nEl bot usa botones en línea para el menú principal, tiendas, notificaciones, soporte, seguridad e idioma. La navegación edita el mensaje actual; un menú antiguo no disponible se reemplaza. Las notificaciones de pago y seguridad no se tratan como navegación desechable. Cerrar sesión a través del menú requiere confirmación. El comando explícito /logout sigue terminando cada sesión de cuenta.\n\nEl panel /admin/project está restringido a IDs de Telegram en la lista de permitidos MODERATOR_TELEGRAM_IDS del lado del servidor. Incluye usuarios, tiendas, operaciones, revocación de claves, deshabilitación de webhooks, pausa de facturas, controles de aceptación y un registro de auditoría. Las mutaciones requieren CSRF y un motivo. El panel no puede restringir a un administrador ni declarar manualmente un pago como exitoso. Restringir a un propietario termina las sesiones y bloquea el acceso a claves de API; restringir una tienda detiene nuevas operaciones. El historial se conserva.\n\nLa oferta pública está disponible en /public-offer y la política de privacidad en /privacy-policy en cada idioma habilitado. Busca monedas por nombre o ticker. Un selector de red aparece solo cuando hay múltiples redes en vivo disponibles. Una sola red se selecciona automáticamente y permanece nombrada en la confirmación. La disponibilidad en vivo de la pasarela determina los pares seleccionables; el catálogo de referencia no habilita un servicio.\n\nUsa update.sh para lanzamientos rutinarios de la aplicación web: compila el candidato, verifica el historial de migraciones, haz una copia de seguridad de SQLite en línea, inicia un segundo contenedor, verifícalo y cambia Caddy sin interrupciones. La pasarela, PostgreSQL y el correo no se reinician. Los activos estáticos anteriores siguen disponibles para pestañas abiertas. Una nueva migración requiere autorización revisada explícita; un cambio de esquema incompatible no es un despliegue sin interrupciones.\n\nOferta pública\n\nPolítica de privacidad",
      "readMinutes": 5
    },
    {
      "id": "cost-sharing",
      "title": "Dividir las tarifas de procesamiento y el IVA",
      "summary": "Elija de forma independiente cuánto de la tarifa de procesamiento y el IVA paga su cliente en cada factura. Dos controles deslizantes asignan cada costo de 0 a 100% en pasos de uno por ciento, con el resultado visible antes de crear el enlace.",
      "tags": [
        "reparto de costos",
        "tarifa de procesamiento",
        "VAT",
        "porcentaje",
        "control deslizante",
        "feeCustomerPercent",
        "vatCustomerPercent"
      ],
      "sections": [
        {
          "id": "controls",
          "title": "Dos controles para un pedido",
          "paragraphs": [
            "El control de tarifa de procesamiento asigna la tarifa de aceptación completa, incluidos sus componentes de porcentaje y fijo. El control de IVA asigna solo impuestos. Ningún control cambia la tarifa, la tasa impositiva ni el precio base del producto.",
            "Totalmente a la izquierda asigna el costo al cliente; totalmente a la derecha lo asigna al comerciante. Las etiquetas muestran los porcentajes exactos de ambas partes y los montos monetarios. Las preconfiguraciones Cliente, Dividir equitativamente y Comerciante ofrecen una elección rápida."
          ],
          "bullets": [
            "La parte del cliente se suma al total del pago.",
            "La parte del comerciante se deduce del precio base del pedido.",
            "SBP y criptomoneda tienen IVA cero, por lo que el control de IVA no afecta su total.",
            "Los botones y controles deslizantes funcionan con el teclado; la animación no es necesaria para entender el resultado."
          ],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Abrir la calculadora",
              "href": "/pricing"
            }
          ]
        },
        {
          "id": "base",
          "title": "Un precio base, dos costos separados",
          "paragraphs": [
            "Las tarjetas internacionales y Alipay cuestan 10% del precio base más $0.50, con IVA de 16% del precio base. SBP cuesta 8% y la criptomoneda cuesta 4%; ninguna tiene IVA según el modelo de precios publicado.",
            "El IVA se añade desde el precio base, no se extrae usando 16/116. La tarifa no se recalcula sobre un total que incluya IVA ni la parte de tarifa del cliente. La comisión de Kevmi ya está incluida en la tarifa publicada; no se añade otro 5%."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": {
            "language": "Formula · integer minor units",
            "code": "fee = roundHalfUp(base × rate / 100) + fixed\nvat = vatApplies ? roundHalfUp(base × 16 / 100) : 0\ncustomerFee = roundHalfUp(fee × feeCustomerPercent / 100)\ncustomerVat = roundHalfUp(vat × vatCustomerPercent / 100)\nmerchantFee = fee − customerFee\nmerchantVat = vat − customerVat\ncustomerTotal = base + customerFee + customerVat\nmerchantNet = base − merchantFee − merchantVat"
          },
          "note": "",
          "links": []
        },
        {
          "id": "example",
          "title": "Asignar un pedido de tarjeta de $5",
          "paragraphs": [
            "Cada ejemplo siguiente usa un precio base de $5.00, una tarifa total de tarjeta de $1.00 e IVA de $0.80. Los porcentajes solo cambian quién cubre esos costos."
          ],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Partes del cliente: IVA / tarifa",
              "El cliente paga",
              "Comerciante después de deducciones"
            ],
            "rows": [
              [
                "100% / 0% · predeterminado original",
                "$5.80",
                "$4.00"
              ],
              [
                "0% / 0% · el comerciante cubre todo",
                "$5.00",
                "$3.20"
              ],
              [
                "100% / 100% · el cliente cubre todo",
                "$6.80",
                "$5.00"
              ],
              [
                "50% / 23% · reparto personalizado",
                "$5.63",
                "$3.83"
              ]
            ]
          },
          "code": null,
          "note": "La tabla ilustra la aritmética del reparto. De estas configuraciones de tarjeta, la pasarela actual solo puede ejecutar 100% IVA del cliente / 0% tarifa del cliente. Este cálculo no inicia un pago; no hay conversión automática de USD a USDT.",
          "links": []
        },
        {
          "id": "rounding",
          "title": "Redondeo sin perder un centavo",
          "paragraphs": [
            "Los montos son unidades monetarias menores enteras. La tarifa total y el IVA total se redondean por separado primero. Cada parte del cliente usa luego redondeo hacia arriba en medios, y el comerciante recibe el resto exacto de ese costo. Por lo tanto, las dos partes siempre suman el monto original.",
            "Para un costo de un centavo dividido 50/50, al cliente se le asigna un centavo y al comerciante cero. El porcentaje permanece en 50%, mientras que los montos monetarios reflejan la precisión disponible de la moneda. El servidor rechaza cálculos con ganancias negativas para el comerciante."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "api",
          "title": "Establezca el reparto a través de la API",
          "paragraphs": [
            "Envíe vatCustomerPercent y feeCustomerPercent como enteros de 0 a 100. Cada uno se aplica a la factura que se está creando. Las cadenas vacías, porcentajes fraccionarios y números fuera de rango se rechazan.",
            "Omitir feeCustomerPercent asigna toda la tarifa al comerciante. Omitir vatCustomerPercent usa el campo heredado vatPayer o el valor predeterminado de la cuenta. Los valores heredados de cliente y comerciante corresponden a 100% y 0% de IVA del cliente. No envíe valores conflictivos de vatPayer y vatCustomerPercent.",
            "Las respuestas describen una parte de IVA intermedia como vatPayer=shared. Use el porcentaje numérico para nuevas solicitudes; shared no se acepta como valor de entrada heredado vatPayer."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": {
            "language": "JSON",
            "code": "{\n  \"title\": \"Design project · order 1042\",\n  \"description\": \"One-time payment for the agreed design work\",\n  \"amountMinor\": 500,\n  \"currency\": \"USD\",\n  \"methods\": [\n    \"card\",\n    \"alipay\"\n  ],\n  \"vatCustomerPercent\": 100,\n  \"feeCustomerPercent\": 0,\n  \"orderId\": \"order-1042\",\n  \"metadata\": {\n    \"campaign\": \"autumn\"\n  }\n}"
          },
          "note": "El ejemplo usa la asignación admitida del canal de tarjeta: todo el IVA al cliente y la tarifa completa de procesamiento al comerciante. Guardar otros porcentajes no los hace ejecutables.",
          "links": [
            {
              "label": "Cree una factura a través de la API",
              "href": "/docs/payment-links-api"
            }
          ]
        },
        {
          "id": "snapshot",
          "title": "Los términos permanecen con la factura",
          "paragraphs": [
            "La factura congela el monto, la moneda, los métodos y ambas partes. Cambiar las preferencias de la tienda no modifica los enlaces emitidos. Los controles deslizantes calculan la asignación; la ejecución en vivo depende de las capacidades del canal conectado.",
            "Para un pago nuevo en vivo con tarjeta o Alipay, la pasarela actual solo admite feeCustomerPercent=0 y vatCustomerPercent=100: el comerciante cubre toda la comisión de procesamiento y el IVA se añade completo para el cliente. Otras participaciones se pueden guardar y calcular en una factura, pero la ejecución está bloqueada con unsupported_allocation. El servidor nunca cambia silenciosamente los términos guardados. Los pagos cripto SBP y USDT admiten todas las participaciones de comisión de procesamiento y no tienen IVA."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        }
      ],
      "group": "payments",
      "url": "/docs/cost-sharing",
      "body": "Dos controles para un pedido\n\nEl control de tarifa de procesamiento asigna la tarifa de aceptación completa, incluidos sus componentes de porcentaje y fijo. El control de IVA asigna solo impuestos. Ningún control cambia la tarifa, la tasa impositiva ni el precio base del producto.\n\nTotalmente a la izquierda asigna el costo al cliente; totalmente a la derecha lo asigna al comerciante. Las etiquetas muestran los porcentajes exactos de ambas partes y los montos monetarios. Las preconfiguraciones Cliente, Dividir equitativamente y Comerciante ofrecen una elección rápida.\n\nLa parte del cliente se suma al total del pago.\n\nLa parte del comerciante se deduce del precio base del pedido.\n\nSBP y criptomoneda tienen IVA cero, por lo que el control de IVA no afecta su total.\n\nLos botones y controles deslizantes funcionan con el teclado; la animación no es necesaria para entender el resultado.\n\nAbrir la calculadora\n\nUn precio base, dos costos separados\n\nLas tarjetas internacionales y Alipay cuestan 10% del precio base más $0.50, con IVA de 16% del precio base. SBP cuesta 8% y la criptomoneda cuesta 4%; ninguna tiene IVA según el modelo de precios publicado.\n\nEl IVA se añade desde el precio base, no se extrae usando 16/116. La tarifa no se recalcula sobre un total que incluya IVA ni la parte de tarifa del cliente. La comisión de Kevmi ya está incluida en la tarifa publicada; no se añade otro 5%.\n\nfee = roundHalfUp(base × rate / 100) + fixed\nvat = vatApplies ? roundHalfUp(base × 16 / 100) : 0\ncustomerFee = roundHalfUp(fee × feeCustomerPercent / 100)\ncustomerVat = roundHalfUp(vat × vatCustomerPercent / 100)\nmerchantFee = fee − customerFee\nmerchantVat = vat − customerVat\ncustomerTotal = base + customerFee + customerVat\nmerchantNet = base − merchantFee − merchantVat\n\nAsignar un pedido de tarjeta de $5\n\nCada ejemplo siguiente usa un precio base de $5.00, una tarifa total de tarjeta de $1.00 e IVA de $0.80. Los porcentajes solo cambian quién cubre esos costos.\n\nPartes del cliente: IVA / tarifa · El cliente paga · Comerciante después de deducciones\n100% / 0% · predeterminado original · $5.80 · $4.00\n0% / 0% · el comerciante cubre todo · $5.00 · $3.20\n100% / 100% · el cliente cubre todo · $6.80 · $5.00\n50% / 23% · reparto personalizado · $5.63 · $3.83\n\nLa tabla ilustra la aritmética del reparto. De estas configuraciones de tarjeta, la pasarela actual solo puede ejecutar 100% IVA del cliente / 0% tarifa del cliente. Este cálculo no inicia un pago; no hay conversión automática de USD a USDT.\n\nRedondeo sin perder un centavo\n\nLos montos son unidades monetarias menores enteras. La tarifa total y el IVA total se redondean por separado primero. Cada parte del cliente usa luego redondeo hacia arriba en medios, y el comerciante recibe el resto exacto de ese costo. Por lo tanto, las dos partes siempre suman el monto original.\n\nPara un costo de un centavo dividido 50/50, al cliente se le asigna un centavo y al comerciante cero. El porcentaje permanece en 50%, mientras que los montos monetarios reflejan la precisión disponible de la moneda. El servidor rechaza cálculos con ganancias negativas para el comerciante.\n\nEstablezca el reparto a través de la API\n\nEnvíe vatCustomerPercent y feeCustomerPercent como enteros de 0 a 100. Cada uno se aplica a la factura que se está creando. Las cadenas vacías, porcentajes fraccionarios y números fuera de rango se rechazan.\n\nOmitir feeCustomerPercent asigna toda la tarifa al comerciante. Omitir vatCustomerPercent usa el campo heredado vatPayer o el valor predeterminado de la cuenta. Los valores heredados de cliente y comerciante corresponden a 100% y 0% de IVA del cliente. No envíe valores conflictivos de vatPayer y vatCustomerPercent.\n\nLas respuestas describen una parte de IVA intermedia como vatPayer=shared. Use el porcentaje numérico para nuevas solicitudes; shared no se acepta como valor de entrada heredado vatPayer.\n\n{\n  \"title\": \"Design project · order 1042\",\n  \"description\": \"One-time payment for the agreed design work\",\n  \"amountMinor\": 500,\n  \"currency\": \"USD\",\n  \"methods\": [\n    \"card\",\n    \"alipay\"\n  ],\n  \"vatCustomerPercent\": 100,\n  \"feeCustomerPercent\": 0,\n  \"orderId\": \"order-1042\",\n  \"metadata\": {\n    \"campaign\": \"autumn\"\n  }\n}\n\nEl ejemplo usa la asignación admitida del canal de tarjeta: todo el IVA al cliente y la tarifa completa de procesamiento al comerciante. Guardar otros porcentajes no los hace ejecutables.\n\nCree una factura a través de la API\n\nLos términos permanecen con la factura\n\nLa factura congela el monto, la moneda, los métodos y ambas partes. Cambiar las preferencias de la tienda no modifica los enlaces emitidos. Los controles deslizantes calculan la asignación; la ejecución en vivo depende de las capacidades del canal conectado.\n\nPara un pago nuevo en vivo con tarjeta o Alipay, la pasarela actual solo admite feeCustomerPercent=0 y vatCustomerPercent=100: el comerciante cubre toda la comisión de procesamiento y el IVA se añade completo para el cliente. Otras participaciones se pueden guardar y calcular en una factura, pero la ejecución está bloqueada con unsupported_allocation. El servidor nunca cambia silenciosamente los términos guardados. Los pagos cripto SBP y USDT admiten todas las participaciones de comisión de procesamiento y no tienen IVA.",
      "readMinutes": 6
    },
    {
      "id": "widgets",
      "title": "Incruste el pago en su sitio web",
      "summary": "Abre el pago en un modal, incrústalo en una página o envía al cliente a una página de pago dedicada. El widget utiliza una URL de pago pública y nunca necesita una clave de API de comerciante en el navegador.",
      "tags": [
        "widget",
        "iframe",
        "incrustar",
        "HTML",
        "integración",
        "modal",
        "pago"
      ],
      "sections": [
        {
          "id": "flow",
          "title": "De factura a pago",
          "paragraphs": [
            "Crea una factura en /account#links y recibe inmediatamente checkoutUrl. Abre /account#widget, pega el enlace y elige un modal, bloque en línea o redirección. Las claves y los webhooks están disponibles en las secciones de cuenta adyacentes.",
            "La vista previa del constructor siempre usa un pedido de demostración sin cobrar. El código del widget generado conserva tu enlace de producción, cuyos términos provienen de la factura guardada en el servidor.",
            "Para una factura nueva en la interfaz, USD ofrece tarjetas y Alipay; RUB ofrece SBP; USDT ofrece criptomonedas. La API también puede guardar USD + criptomonedas por compatibilidad, pero su pago cripto en vivo está bloqueado con crypto_requires_usdt. USD y USDT son distintos, sin conversión automática ni supuesta tasa 1:1. Un pago cripto requiere una factura USDT separada."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Constructor de integración",
              "href": "/account#widget"
            },
            {
              "label": "API de enlaces de pago",
              "href": "/docs/payment-links-api"
            }
          ]
        },
        {
          "id": "markup",
          "title": "Un botón con respaldo de enlace normal",
          "paragraphs": [
            "Este ejemplo abre una demostración sin cobrar dinero. Reemplaza ambos valores de URL con checkoutUrl de tu respuesta de factura. Carga el script desde el mismo origen Kevmi que la URL de pago.",
            "El href abre el pago cuando JavaScript no está disponible. data-kevmi-label le da al iframe un nombre accesible. Incluye el script una vez por página."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": {
            "language": "HTML",
            "code": "<script src=\"https://kevmi.maxeevmax1.chatgpt.site/widgets/kevmi.js\" defer></script>\n<a href=\"https://kevmi.maxeevmax1.chatgpt.site/en/pay/demo\"\n   data-kevmi-checkout=\"https://kevmi.maxeevmax1.chatgpt.site/en/pay/demo\"\n   data-kevmi-mode=\"modal\"\n   data-kevmi-label=\"Order checkout\">Pay securely</a>"
          },
          "note": "",
          "links": []
        },
        {
          "id": "modes",
          "title": "Tres formas de abrir el pago",
          "paragraphs": [
            "Usa un contenedor como div para el modo en línea y reemplaza CHECKOUT_URL_FROM_API con una URL real. El marco se adapta al ancho de su contenedor; los mensajes de pago pueden ajustar su altura dentro de un rango limitado.",
            "El modal se cierra con su botón, Escape o un clic en el fondo. El enfoque regresa al disparador original después de cerrar. La configuración de movimiento reducido acorta la transición."
          ],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "data-kevmi-mode",
              "Comportamiento",
              "Útil para"
            ],
            "rows": [
              [
                "modal",
                "Un diálogo superpuesto; el modo predeterminado",
                "Un botón de pago a nivel de pedido"
              ],
              [
                "en línea",
                "Un iframe dentro del contenedor seleccionado",
                "Un paso de pago en tu sitio"
              ],
              [
                "redirección",
                "Navegación a Kevmi en la pestaña actual",
                "Una página de pago completa"
              ]
            ]
          },
          "code": {
            "language": "HTML",
            "code": "<div data-kevmi-checkout=\"CHECKOUT_URL_FROM_API\"\n     data-kevmi-mode=\"inline\"\n     data-kevmi-label=\"Order checkout\"></div>"
          },
          "note": "",
          "links": []
        },
        {
          "id": "javascript",
          "title": "Abre el pago desde tu interfaz",
          "paragraphs": [
            "Los eventos de documento kevmi:opened y kevmi:closed permiten que tu interfaz reaccione al abrir y cerrar. Un evento kevmi:error en el disparador informa una URL de pago no válida. Ninguno prueba el pago. Llama a la API de JavaScript después de que el script del widget se haya cargado."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": {
            "language": "JavaScript",
            "code": "window.Kevmi.open(checkoutUrl, {\n  mode: 'modal',\n  label: 'Order checkout',\n  closeLabel: 'Close checkout'\n});\n\n// Inline blocks added after page load are detected automatically.\n// You may also request mounting explicitly:\nwindow.Kevmi.mount(document);"
          },
          "note": "",
          "links": []
        },
        {
          "id": "security",
          "title": "Qué prueba un pago exitoso",
          "paragraphs": [
            "No pongas claves de API ni secretos de firma en HTML. El widget recibe solo un enlace público a una factura. El pago cifra los datos de la tarjeta y los códigos bancarios con la clave de la pasarela; el servidor de Kevmi no los acepta en texto plano.",
            "postMessage actualiza el estado de la interfaz, no el cumplimiento del pedido. Verifica el origen del mensaje y la ventana de origen antes de procesarlo. Usa un evento verificado payment.succeeded o un estado de éxito en el resumen GET link.payment del servidor para el resultado final."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "Abrir el pago, cerrar un widget o volver al sitio del comerciante no prueba que se recibió dinero.",
          "links": [
            {
              "label": "Firmas y entrega de webhooks",
              "href": "/docs/webhooks"
            }
          ]
        },
        {
          "id": "deployment",
          "title": "Antes de añadir el widget a producción",
          "paragraphs": [],
          "bullets": [
            "Permite el origen de Kevmi en las directivas script-src y frame-src de tu Política de Seguridad de Contenido sin ampliar políticas no relacionadas.",
            "Verifica pantallas estrechas, acceso con teclado y temas claros y oscuros.",
            "Confirma que la factura esté activa, sin vencer y con el precio y las participaciones de costo correctos.",
            "Mantén un enlace de pago normal como respaldo.",
            "Prueba entregas fallidas y eventos de webhook duplicados sin emitir un pedido dos veces."
          ],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        }
      ],
      "group": "developers",
      "url": "/docs/widgets",
      "body": "De factura a pago\n\nCrea una factura en /account#links y recibe inmediatamente checkoutUrl. Abre /account#widget, pega el enlace y elige un modal, bloque en línea o redirección. Las claves y los webhooks están disponibles en las secciones de cuenta adyacentes.\n\nLa vista previa del constructor siempre usa un pedido de demostración sin cobrar. El código del widget generado conserva tu enlace de producción, cuyos términos provienen de la factura guardada en el servidor.\n\nPara una factura nueva en la interfaz, USD ofrece tarjetas y Alipay; RUB ofrece SBP; USDT ofrece criptomonedas. La API también puede guardar USD + criptomonedas por compatibilidad, pero su pago cripto en vivo está bloqueado con crypto_requires_usdt. USD y USDT son distintos, sin conversión automática ni supuesta tasa 1:1. Un pago cripto requiere una factura USDT separada.\n\nConstructor de integración\n\nAPI de enlaces de pago\n\nUn botón con respaldo de enlace normal\n\nEste ejemplo abre una demostración sin cobrar dinero. Reemplaza ambos valores de URL con checkoutUrl de tu respuesta de factura. Carga el script desde el mismo origen Kevmi que la URL de pago.\n\nEl href abre el pago cuando JavaScript no está disponible. data-kevmi-label le da al iframe un nombre accesible. Incluye el script una vez por página.\n\n<script src=\"https://kevmi.maxeevmax1.chatgpt.site/widgets/kevmi.js\" defer></script>\n<a href=\"https://kevmi.maxeevmax1.chatgpt.site/en/pay/demo\"\n   data-kevmi-checkout=\"https://kevmi.maxeevmax1.chatgpt.site/en/pay/demo\"\n   data-kevmi-mode=\"modal\"\n   data-kevmi-label=\"Order checkout\">Pay securely</a>\n\nTres formas de abrir el pago\n\nUsa un contenedor como div para el modo en línea y reemplaza CHECKOUT_URL_FROM_API con una URL real. El marco se adapta al ancho de su contenedor; los mensajes de pago pueden ajustar su altura dentro de un rango limitado.\n\nEl modal se cierra con su botón, Escape o un clic en el fondo. El enfoque regresa al disparador original después de cerrar. La configuración de movimiento reducido acorta la transición.\n\ndata-kevmi-mode · Comportamiento · Útil para\nmodal · Un diálogo superpuesto; el modo predeterminado · Un botón de pago a nivel de pedido\nen línea · Un iframe dentro del contenedor seleccionado · Un paso de pago en tu sitio\nredirección · Navegación a Kevmi en la pestaña actual · Una página de pago completa\n\n<div data-kevmi-checkout=\"CHECKOUT_URL_FROM_API\"\n     data-kevmi-mode=\"inline\"\n     data-kevmi-label=\"Order checkout\"></div>\n\nAbre el pago desde tu interfaz\n\nLos eventos de documento kevmi:opened y kevmi:closed permiten que tu interfaz reaccione al abrir y cerrar. Un evento kevmi:error en el disparador informa una URL de pago no válida. Ninguno prueba el pago. Llama a la API de JavaScript después de que el script del widget se haya cargado.\n\nwindow.Kevmi.open(checkoutUrl, {\n  mode: 'modal',\n  label: 'Order checkout',\n  closeLabel: 'Close checkout'\n});\n\n// Inline blocks added after page load are detected automatically.\n// You may also request mounting explicitly:\nwindow.Kevmi.mount(document);\n\nQué prueba un pago exitoso\n\nNo pongas claves de API ni secretos de firma en HTML. El widget recibe solo un enlace público a una factura. El pago cifra los datos de la tarjeta y los códigos bancarios con la clave de la pasarela; el servidor de Kevmi no los acepta en texto plano.\n\npostMessage actualiza el estado de la interfaz, no el cumplimiento del pedido. Verifica el origen del mensaje y la ventana de origen antes de procesarlo. Usa un evento verificado payment.succeeded o un estado de éxito en el resumen GET link.payment del servidor para el resultado final.\n\nAbrir el pago, cerrar un widget o volver al sitio del comerciante no prueba que se recibió dinero.\n\nFirmas y entrega de webhooks\n\nAntes de añadir el widget a producción\n\nPermite el origen de Kevmi en las directivas script-src y frame-src de tu Política de Seguridad de Contenido sin ampliar políticas no relacionadas.\n\nVerifica pantallas estrechas, acceso con teclado y temas claros y oscuros.\n\nConfirma que la factura esté activa, sin vencer y con el precio y las participaciones de costo correctos.\n\nMantén un enlace de pago normal como respaldo.\n\nPrueba entregas fallidas y eventos de webhook duplicados sin emitir un pedido dos veces.",
      "readMinutes": 4
    },
    {
      "id": "applications",
      "title": "Solicita conectar tu tienda",
      "summary": "Envía tu sitio web después de iniciar sesión con Telegram y sigue cada etapa de revisión en una URL privada. Las verificaciones automáticas apoyan al revisor; un moderador siempre toma la decisión final.",
      "tags": [
        "solicitud",
        "incorporación",
        "moderación",
        "revisión del sitio web",
        "estado",
        "Telegram",
        "AI"
      ],
      "sections": [
        {
          "id": "submit",
          "title": "Envía una solicitud",
          "paragraphs": [
            "Las descripciones requieren de 40 a 3000 caracteres; los nombres de proyecto permiten hasta 100. El sitio web debe ser accesible sin iniciar sesión. Las URLs que contienen credenciales, hosts privados, puertos no estándar o parámetros de consulta no se aceptan.",
            "La cuenta verificada es dueña de la solicitud. El contacto de Telegram ingresado es para comunicación y no cambia la propiedad. Reenviar la URL de seguimiento no otorga acceso a otra cuenta."
          ],
          "bullets": [],
          "steps": [
            "Inicia sesión o regístrate con Telegram, luego abre /account#applications.",
            "Ingresa una dirección de sitio web HTTPS pública, nombre del proyecto, categoría y una descripción de tus productos o servicios.",
            "Añade un contacto de Telegram. Explica qué reciben los clientes y cómo se cumplen los pedidos.",
            "Confirma tu autoridad para enviar el sitio y envía el formulario.",
            "Guarda la dirección /account#applications/{id} que se abre inmediatamente después del envío."
          ],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Envía tu sitio web",
              "href": "/account#applications"
            }
          ]
        },
        {
          "id": "stages",
          "title": "Cuatro etapas de revisión",
          "paragraphs": [
            "La línea de conexión y los marcadores de etapa reflejan estados persistidos en el servidor. Reabrir la página continúa el mismo proceso. Cerrar la pestaña no cancela tu solicitud; los trabajos en segundo plano continúan y recuperan etapas interrumpidas."
          ],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Etapa",
              "Qué sucede",
              "Estado mostrado"
            ],
            "rows": [
              [
                "Solicitud recibida",
                "Los detalles del envío y la URL privada están guardados",
                "La primera etapa está completa"
              ],
              [
                "Revisión de contenido",
                "La IA compara la descripción con el contenido del sitio web público",
                "En curso, completa o en espera de un especialista"
              ],
              [
                "Verificaciones técnicas",
                "Se examinan la disponibilidad y un conjunto acotado de enlaces",
                "Un resultado separado y la marca de tiempo de la etapa"
              ],
              [
                "Revisión de especialista",
                "Un moderador revisa el envío y los hallazgos",
                "En espera de decisión, aprobada o un motivo de rechazo"
              ]
            ]
          },
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "attention",
          "title": "Una etapa amarilla necesita un especialista",
          "paragraphs": [
            "Una marca amarilla significa que una etapa requiere atención, por ejemplo porque la información es insuficiente, un enlace no está disponible o un resultado automatizado no puede aceptarse con confianza. No es un rechazo definitivo. La página de estado explica el siguiente paso.",
            "Un moderador puede limpiar la etapa actual para que continúe la siguiente verificación. Una etapa rechazada muestra una cruz y un motivo visible para el usuario que el moderador puede editar antes de enviar. Limpiar una etapa intermedia nunca elimina la revisión manual final."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "scope",
          "title": "Qué cubren las verificaciones automatizadas",
          "paragraphs": [
            "Las verificaciones examinan la página de inicio pública: HTTPS, respuesta HTTP, título, texto y patrones de enlaces sospechosos. También solicitan encabezados de como máximo tres enlaces en el mismo sitio web. El número de redirecciones, el tamaño de la respuesta y el tiempo de solicitud están limitados.",
            "Las verificaciones no acceden a áreas con inicio de sesión, no ejecutan archivos descargados ni reemplazan una auditoría de seguridad o un escáner de malware. Completar una etapa no garantiza que cada página esté libre de contenido malicioso.",
            "El contenido del sitio web son datos no confiables. Las instrucciones en un sitio web no pueden asignar un administrador, cambiar los términos de Kevmi ni aprobar una solicitud. La IA no disponible y la salida del modelo mal formada requieren revisión de un especialista en lugar de pasar la etapa silenciosamente."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "updates",
          "title": "Actualizaciones de Telegram",
          "paragraphs": [
            "Recibir una solicitud, completar una etapa, solicitar atención de un especialista y tomar una decisión final generan notificaciones con un enlace de seguimiento privado. Estas usan la categoría Soporte en la configuración de notificaciones de la cuenta. Deshabilitar esa categoría detiene los mensajes.",
            "El evento de la solicitud y la entrada de la bandeja de salida de notificaciones se confirman juntos. La entrega por Telegram usa una cola de reintentos y requiere un bot conectado. La página de seguimiento sigue siendo la fuente del estado actual si Telegram no está disponible o el bot está bloqueado.",
            "La moderación recibe alertas separadas. Solo los usuarios en la lista de permitidos de moderación del servidor pueden limpiar una etapa desde Telegram; un botón antiguo no puede aplicar una decisión repetida. Los motivos de rechazo se editan en el espacio de trabajo de moderación."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Configuración de notificaciones",
              "href": "/docs/notifications"
            }
          ]
        },
        {
          "id": "api",
          "title": "Contrato de solicitud y decisión",
          "paragraphs": [
            "La propiedad proviene de la sesión. Los solicitantes no pueden enviar userId, estado, roles ni resultados de revisión. Repetir la creación con la misma Idempotency-Key y el mismo cuerpo devuelve la solicitud existente; cambiar el cuerpo con esa clave produce un conflicto.",
            "Una decisión de moderador se aplica solo a la versión esperada de la solicitud. Las decisiones simultáneas se guardan una vez; la otra solicitud recibe 409. Un motivo de rechazo es texto plano de 10 a 1500 caracteres. La evidencia de revisión interna está restringida a los moderadores."
          ],
          "bullets": [],
          "steps": [],
          "table": {
            "headers": [
              "Ruta",
              "Acceso y comportamiento"
            ],
            "rows": [
              [
                "POST /api/applications",
                "Sesión + CSRF + Idempotency-Key; 202 con una URL privada"
              ],
              [
                "GET /api/applications",
                "Solicitudes de la cuenta actual"
              ],
              [
                "GET /api/applications/{id}",
                "Envío propio, etapas e historial público"
              ],
              [
                "POST /api/applications/{id}/resume",
                "Sesión + CSRF; continúa solo las solicitudes en procesamiento"
              ],
              [
                "GET /api/moderation/applications",
                "Solo moderadores verificados"
              ],
              [
                "POST /api/moderation/applications/{id}/decision",
                "approve_step o reject, expectedVersion y un motivo de rechazo"
              ]
            ]
          },
          "code": null,
          "note": "",
          "links": []
        },
        {
          "id": "outcome",
          "title": "Después de la decisión",
          "paragraphs": [
            "Un nuevo pago e intento de tarjeta requieren que la última solicitud de revisión web del comerciante esté aprobada. La aprobación por sí sola no conecta la pasarela de pago. Si la revisión cambia después del envío, la operación existente permanece disponible para lecturas de estado, conciliación y un código bancario solicitado.",
            "Si se rechaza, el comerciante ve el motivo y puede corregir los materiales antes de volver a solicitarlo. Una etapa amarilla significa que un especialista aún debe decidir; no es una aprobación automática."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": [
            {
              "label": "Soporte",
              "href": "/?support=open"
            },
            {
              "label": "Disponibilidad de la pasarela",
              "href": "/docs/gateway"
            }
          ]
        },
        {
          "id": "stores-usd",
          "title": "Múltiples tiendas y un precio base en USD",
          "paragraphs": [
            "Elija Todas las tiendas para análisis y operaciones agregados, o seleccione una tienda para sus propios registros. Cada tienda tiene un storeId, nombre, IVA predeterminado, facturas, claves de API, endpoints de webhook, historial de eventos y aplicación web separados. Las notificaciones y tickets de soporte pertenecen a la cuenta. Una cuenta puede crear hasta 100 tiendas. Los registros existentes permanecen en su primera tienda.",
            "Las facturas del nuevo espacio de trabajo usan pricingMode=\"universal\" y un precio base en USD. Any incluye tarjeta, alipay, sbp y cripto; un comerciante puede seleccionar un subconjunto. Tarjetas y Alipay cobran en USD. SBP cobra en RUB usando el tipo de referencia USD/RUB del Banco de Rusia. Cripto cobra USDT bajo la regla explícita de factura 1 USD = 1 USDT. Esta es una regla de conversión de factura, no una cotización de mercado de USDT. La pasarela proporciona la tasa de la moneda seleccionada, el monto exacto de transferencia y las instrucciones antes de la transferencia.",
            "El tipo de referencia y ambos montos se congelan al crear. Las facturas que implican conversión de RUB vencen dentro de 24 horas. Si no se puede obtener el tipo de referencia, la creación falla con FX_UNAVAILABLE; no se usa ningún tipo de respaldo inventado o desactualizado. El monto en minor del propietario y las cotizaciones usan la moneda contable USD. quotes[method].settlement contiene la cotización de cargo nativa. El checkout público expone la moneda de cargo seleccionada en currency, el precio original en baseAmountMinor/baseCurrency y el tipo de referencia en fx. Una vez que un pago ha sido despachado, su método no se puede cambiar; una factura tiene una operación de pasarela.",
            "Cree una clave de API dentro de la tienda prevista y envíe Authorization: Bearer <key> desde su servidor. Su vinculación a tienda es inmutable; X-Kevmi-Store no puede otorgarle acceso a otra tienda. Las sesiones del navegador seleccionan X-Kevmi-Store: <storeId>; omitirlo selecciona la primera tienda. El valor all solo es aceptado por GET /api/account/dashboard y GET /api/payment-links. Las mutaciones requieren una tienda seleccionada, Origin y X-CSRF-Token. Los IDs de cuenta y los IDs de tienda son identificadores diferentes.",
            "Por compatibilidad, las solicitudes de API sin pricingMode=\"universal\" conservan el precio nativo y las restricciones de moneda originales. Las facturas existentes nunca se recalculan. Los recibos confirmados en análisis reflejan pagos verificados menos gastos de factura guardados; no son un saldo retirable. Las monedas de factura heredadas permanecen separadas y los pagos se gestionan con soporte. Cumpla un pedido solo después de verificar payment.fulfillmentReady=true y payment.status=\"succeeded\" a través de la API del servidor, el historial de eventos o un webhook firmado."
          ],
          "bullets": [],
          "steps": [],
          "table": null,
          "code": null,
          "note": "",
          "links": []
        }
      ],
      "group": "start",
      "url": "/docs/applications",
      "body": "Envía una solicitud\n\nLas descripciones requieren de 40 a 3000 caracteres; los nombres de proyecto permiten hasta 100. El sitio web debe ser accesible sin iniciar sesión. Las URLs que contienen credenciales, hosts privados, puertos no estándar o parámetros de consulta no se aceptan.\n\nLa cuenta verificada es dueña de la solicitud. El contacto de Telegram ingresado es para comunicación y no cambia la propiedad. Reenviar la URL de seguimiento no otorga acceso a otra cuenta.\n\nInicia sesión o regístrate con Telegram, luego abre /account#applications.\n\nIngresa una dirección de sitio web HTTPS pública, nombre del proyecto, categoría y una descripción de tus productos o servicios.\n\nAñade un contacto de Telegram. Explica qué reciben los clientes y cómo se cumplen los pedidos.\n\nConfirma tu autoridad para enviar el sitio y envía el formulario.\n\nGuarda la dirección /account#applications/{id} que se abre inmediatamente después del envío.\n\nEnvía tu sitio web\n\nCuatro etapas de revisión\n\nLa línea de conexión y los marcadores de etapa reflejan estados persistidos en el servidor. Reabrir la página continúa el mismo proceso. Cerrar la pestaña no cancela tu solicitud; los trabajos en segundo plano continúan y recuperan etapas interrumpidas.\n\nEtapa · Qué sucede · Estado mostrado\nSolicitud recibida · Los detalles del envío y la URL privada están guardados · La primera etapa está completa\nRevisión de contenido · La IA compara la descripción con el contenido del sitio web público · En curso, completa o en espera de un especialista\nVerificaciones técnicas · Se examinan la disponibilidad y un conjunto acotado de enlaces · Un resultado separado y la marca de tiempo de la etapa\nRevisión de especialista · Un moderador revisa el envío y los hallazgos · En espera de decisión, aprobada o un motivo de rechazo\n\nUna etapa amarilla necesita un especialista\n\nUna marca amarilla significa que una etapa requiere atención, por ejemplo porque la información es insuficiente, un enlace no está disponible o un resultado automatizado no puede aceptarse con confianza. No es un rechazo definitivo. La página de estado explica el siguiente paso.\n\nUn moderador puede limpiar la etapa actual para que continúe la siguiente verificación. Una etapa rechazada muestra una cruz y un motivo visible para el usuario que el moderador puede editar antes de enviar. Limpiar una etapa intermedia nunca elimina la revisión manual final.\n\nQué cubren las verificaciones automatizadas\n\nLas verificaciones examinan la página de inicio pública: HTTPS, respuesta HTTP, título, texto y patrones de enlaces sospechosos. También solicitan encabezados de como máximo tres enlaces en el mismo sitio web. El número de redirecciones, el tamaño de la respuesta y el tiempo de solicitud están limitados.\n\nLas verificaciones no acceden a áreas con inicio de sesión, no ejecutan archivos descargados ni reemplazan una auditoría de seguridad o un escáner de malware. Completar una etapa no garantiza que cada página esté libre de contenido malicioso.\n\nEl contenido del sitio web son datos no confiables. Las instrucciones en un sitio web no pueden asignar un administrador, cambiar los términos de Kevmi ni aprobar una solicitud. La IA no disponible y la salida del modelo mal formada requieren revisión de un especialista en lugar de pasar la etapa silenciosamente.\n\nActualizaciones de Telegram\n\nRecibir una solicitud, completar una etapa, solicitar atención de un especialista y tomar una decisión final generan notificaciones con un enlace de seguimiento privado. Estas usan la categoría Soporte en la configuración de notificaciones de la cuenta. Deshabilitar esa categoría detiene los mensajes.\n\nEl evento de la solicitud y la entrada de la bandeja de salida de notificaciones se confirman juntos. La entrega por Telegram usa una cola de reintentos y requiere un bot conectado. La página de seguimiento sigue siendo la fuente del estado actual si Telegram no está disponible o el bot está bloqueado.\n\nLa moderación recibe alertas separadas. Solo los usuarios en la lista de permitidos de moderación del servidor pueden limpiar una etapa desde Telegram; un botón antiguo no puede aplicar una decisión repetida. Los motivos de rechazo se editan en el espacio de trabajo de moderación.\n\nConfiguración de notificaciones\n\nContrato de solicitud y decisión\n\nLa propiedad proviene de la sesión. Los solicitantes no pueden enviar userId, estado, roles ni resultados de revisión. Repetir la creación con la misma Idempotency-Key y el mismo cuerpo devuelve la solicitud existente; cambiar el cuerpo con esa clave produce un conflicto.\n\nUna decisión de moderador se aplica solo a la versión esperada de la solicitud. Las decisiones simultáneas se guardan una vez; la otra solicitud recibe 409. Un motivo de rechazo es texto plano de 10 a 1500 caracteres. La evidencia de revisión interna está restringida a los moderadores.\n\nRuta · Acceso y comportamiento\nPOST /api/applications · Sesión + CSRF + Idempotency-Key; 202 con una URL privada\nGET /api/applications · Solicitudes de la cuenta actual\nGET /api/applications/{id} · Envío propio, etapas e historial público\nPOST /api/applications/{id}/resume · Sesión + CSRF; continúa solo las solicitudes en procesamiento\nGET /api/moderation/applications · Solo moderadores verificados\nPOST /api/moderation/applications/{id}/decision · approve_step o reject, expectedVersion y un motivo de rechazo\n\nDespués de la decisión\n\nUn nuevo pago e intento de tarjeta requieren que la última solicitud de revisión web del comerciante esté aprobada. La aprobación por sí sola no conecta la pasarela de pago. Si la revisión cambia después del envío, la operación existente permanece disponible para lecturas de estado, conciliación y un código bancario solicitado.\n\nSi se rechaza, el comerciante ve el motivo y puede corregir los materiales antes de volver a solicitarlo. Una etapa amarilla significa que un especialista aún debe decidir; no es una aprobación automática.\n\nSoporte\n\nDisponibilidad de la pasarela\n\nMúltiples tiendas y un precio base en USD\n\nElija Todas las tiendas para análisis y operaciones agregados, o seleccione una tienda para sus propios registros. Cada tienda tiene un storeId, nombre, IVA predeterminado, facturas, claves de API, endpoints de webhook, historial de eventos y aplicación web separados. Las notificaciones y tickets de soporte pertenecen a la cuenta. Una cuenta puede crear hasta 100 tiendas. Los registros existentes permanecen en su primera tienda.\n\nLas facturas del nuevo espacio de trabajo usan pricingMode=\"universal\" y un precio base en USD. Any incluye tarjeta, alipay, sbp y cripto; un comerciante puede seleccionar un subconjunto. Tarjetas y Alipay cobran en USD. SBP cobra en RUB usando el tipo de referencia USD/RUB del Banco de Rusia. Cripto cobra USDT bajo la regla explícita de factura 1 USD = 1 USDT. Esta es una regla de conversión de factura, no una cotización de mercado de USDT. La pasarela proporciona la tasa de la moneda seleccionada, el monto exacto de transferencia y las instrucciones antes de la transferencia.\n\nEl tipo de referencia y ambos montos se congelan al crear. Las facturas que implican conversión de RUB vencen dentro de 24 horas. Si no se puede obtener el tipo de referencia, la creación falla con FX_UNAVAILABLE; no se usa ningún tipo de respaldo inventado o desactualizado. El monto en minor del propietario y las cotizaciones usan la moneda contable USD. quotes[method].settlement contiene la cotización de cargo nativa. El checkout público expone la moneda de cargo seleccionada en currency, el precio original en baseAmountMinor/baseCurrency y el tipo de referencia en fx. Una vez que un pago ha sido despachado, su método no se puede cambiar; una factura tiene una operación de pasarela.\n\nCree una clave de API dentro de la tienda prevista y envíe Authorization: Bearer <key> desde su servidor. Su vinculación a tienda es inmutable; X-Kevmi-Store no puede otorgarle acceso a otra tienda. Las sesiones del navegador seleccionan X-Kevmi-Store: <storeId>; omitirlo selecciona la primera tienda. El valor all solo es aceptado por GET /api/account/dashboard y GET /api/payment-links. Las mutaciones requieren una tienda seleccionada, Origin y X-CSRF-Token. Los IDs de cuenta y los IDs de tienda son identificadores diferentes.\n\nPor compatibilidad, las solicitudes de API sin pricingMode=\"universal\" conservan el precio nativo y las restricciones de moneda originales. Las facturas existentes nunca se recalculan. Los recibos confirmados en análisis reflejan pagos verificados menos gastos de factura guardados; no son un saldo retirable. Las monedas de factura heredadas permanecen separadas y los pagos se gestionan con soporte. Cumpla un pedido solo después de verificar payment.fulfillmentReady=true y payment.status=\"succeeded\" a través de la API del servidor, el historial de eventos o un webhook firmado.",
      "readMinutes": 6
    }
  ],
  "facts": {
    "paymentType": "one_time",
    "subscriptionsSupported": false,
    "incomingFees": {
      "card": {
        "percent": 10,
        "fixedUsdMinor": 50,
        "vatApplies": true
      },
      "alipay": {
        "percent": 10,
        "fixedUsdMinor": 50,
        "vatApplies": true
      },
      "sbp": {
        "percent": 8,
        "fixedUsdMinor": 0,
        "vatApplies": false
      },
      "crypto": {
        "percent": 4,
        "fixedUsdMinor": 0,
        "vatApplies": false
      }
    },
    "vat": {
      "ratePercent": 16,
      "base": "order_base_amount",
      "defaultPayer": "customer",
      "payerOptions": [
        "customer",
        "merchant",
        "shared"
      ],
      "customerPercentRange": [
        0,
        100
      ],
      "customerPercentStep": 1,
      "feeBase": "order_base_amount",
      "source": "owner_confirmed",
      "example": {
        "baseUsdMinor": 500,
        "feeUsdMinor": 100,
        "vatUsdMinor": 80,
        "customerPayer": {
          "chargedUsdMinor": 580,
          "merchantNetUsdMinor": 400
        },
        "merchantPayer": {
          "chargedUsdMinor": 500,
          "merchantNetUsdMinor": 320
        }
      }
    },
    "payout": {
      "asset": "USDT",
      "network": "TRC20",
      "sourceFees": {
        "card": "4%",
        "alipay": "4%",
        "sbp": "5% + RUB 400",
        "crypto": "0% + $3"
      },
      "creationImplemented": false,
      "gatewayBalanceIsMerchantLedger": false,
      "fixedCryptoFeeCurrency": "USD"
    },
    "costSharing": {
      "pricingVersion": 2,
      "independent": [
        "vatCustomerPercent",
        "feeCustomerPercent"
      ],
      "range": [
        0,
        100
      ],
      "step": 1,
      "defaultVatCustomerPercent": 100,
      "defaultFeeCustomerPercent": 0,
      "customerSharesAddedToCharge": true,
      "merchantSharesDeductedFromBase": true,
      "rounding": "half_up_customer_share_then_exact_merchant_remainder",
      "invoiceTermsImmutable": true,
      "liveGatewayAllocation": {
        "card": {
          "vatCustomerPercent": 100,
          "feeCustomerPercent": 0
        },
        "alipay": {
          "vatCustomerPercent": 100,
          "feeCustomerPercent": 0
        },
        "sbp": {
          "feeCustomerPercent": [
            0,
            100
          ],
          "vatApplies": false
        },
        "crypto": {
          "feeCustomerPercent": [
            0,
            100
          ],
          "vatApplies": false
        },
        "otherSavedCardSplitsExecutable": false
      },
      "example": {
        "baseUsdMinor": 500,
        "vatCustomerPercent": 50,
        "feeCustomerPercent": 23,
        "customerVatMinor": 40,
        "customerFeeMinor": 23,
        "customerTotalMinor": 563,
        "merchantNetMinor": 383
      }
    },
    "paymentLinks": {
      "methodSelection": "customer_from_invoice_methods",
      "interfaceAnyMode": "all_methods_for_invoice_currency",
      "allowedMethodsByCurrency": {
        "USD": [
          "card",
          "alipay"
        ],
        "RUB": [
          "sbp"
        ],
        "USDT": [
          "crypto"
        ]
      },
      "apiCreateField": "methods",
      "legacyUsdCryptoApiSaveAccepted": true,
      "legacyUsdCryptoExecutable": false,
      "cryptoRequiresExplicitUsdt": true,
      "ownerGetPaymentField": "payment",
      "ownerGetPaymentNullable": true,
      "createAndPatchPaymentSummaryOptional": true,
      "apiAnyValueSupported": false,
      "quotesPerMethod": true,
      "automaticCurrencyConversion": false
    },
    "merchantAPI": {
      "basePath": "/api/v1",
      "createInvoicePath": "/api/v1/payments",
      "createsCharge": false,
      "returnsCheckoutUrl": true,
      "scopes": [
        "invoices:read",
        "invoices:write",
        "events:read"
      ],
      "defaultKeyLifetimeDays": 90,
      "maximumActiveKeys": 10,
      "keysStoredAsHashes": true
    },
    "widgets": {
      "script": "/widgets/kevmi.js",
      "modes": [
        "modal",
        "inline",
        "redirect"
      ],
      "publicCheckoutUrlOnly": true,
      "browserMessagesConfirmPayment": false
    },
    "webhooks": {
      "events": [
        "invoice.created",
        "invoice.updated",
        "payment.succeeded",
        "payment.failed",
        "payment.refunded",
        "payment.partially_refunded",
        "payment.disputed",
        "payment.review_required"
      ],
      "signatureHeader": "Kevmi-Signature",
      "signatureAlgorithm": "HMAC-SHA256",
      "signatureInput": "timestamp.rawBody",
      "timestampToleranceSeconds": 300,
      "delivery": "at_least_once",
      "maximumAttempts": 6,
      "retryDelaySeconds": [
        60,
        300,
        1800,
        7200,
        43200
      ],
      "endpointVerificationRequired": true,
      "paymentSource": "validated_gateway_receipt",
      "financialStatusFromBrowser": false
    },
    "applications": {
      "path": "/account#applications",
      "trackingPath": "/account#applications/{id}",
      "authentication": "telegram_session",
      "visibility": "owner_and_moderators",
      "stages": [
        "received",
        "ai_review",
        "technical_review",
        "manual_review"
      ],
      "manualFinalDecisionRequired": true,
      "businessTypes": [
        "digital_goods",
        "software",
        "services",
        "physical_goods",
        "education",
        "other"
      ],
      "submissionLimitPerDay": 5,
      "resumeLimitPerMinute": 30,
      "moderationLimitPerMinute": 30,
      "aiReviewsPerHour": 30,
      "unknownAutomatedResults": "needs_review",
      "checks": "bounded_public_content_and_same_origin_links",
      "safetyGuarantee": false,
      "notificationCategory": "support",
      "approvalActivatesGateway": false,
      "latestApprovalRequiredForNewPayment": true,
      "invoiceCreationBeforeApproval": true,
      "existingOperationReadableAfterApprovalChange": true
    },
    "countries": {
      "card": {
        "countryCount": 223,
        "ownerReportedCountryCount": null,
        "coverageLabel": "190+",
        "restrictions": [
          {
            "code": "AF",
            "name": "Afghanistan",
            "nameEn": "Afghanistan"
          },
          {
            "code": "AQ",
            "name": "Antarctica",
            "nameEn": "Antarctica"
          },
          {
            "code": "BY",
            "name": "Belarus",
            "nameEn": "Belarus"
          },
          {
            "code": "MM",
            "name": "Burma (Myanmar)",
            "nameEn": "Burma (Myanmar)"
          },
          {
            "code": "BI",
            "name": "Burundi",
            "nameEn": "Burundi"
          },
          {
            "code": "CF",
            "name": "Central African Republic",
            "nameEn": "Central African Republic"
          },
          {
            "code": "TD",
            "name": "Chad",
            "nameEn": "Chad"
          },
          {
            "code": "CU",
            "name": "Cuba",
            "nameEn": "Cuba"
          },
          {
            "code": "CD",
            "name": "Democratic Republic of Congo",
            "nameEn": "Democratic Republic of Congo"
          },
          {
            "code": "CG",
            "name": "Republic of Congo",
            "nameEn": "Republic of Congo"
          },
          {
            "code": "ER",
            "name": "Eritrea",
            "nameEn": "Eritrea"
          },
          {
            "code": "HT",
            "name": "Haiti",
            "nameEn": "Haiti"
          },
          {
            "code": "IR",
            "name": "Iran",
            "nameEn": "Iran"
          },
          {
            "code": "IQ",
            "name": "Iraq",
            "nameEn": "Iraq"
          },
          {
            "code": "LY",
            "name": "Libya",
            "nameEn": "Libya"
          },
          {
            "code": "ML",
            "name": "Mali",
            "nameEn": "Mali"
          },
          {
            "code": "NI",
            "name": "Nicaragua",
            "nameEn": "Nicaragua"
          },
          {
            "code": "KP",
            "name": "North Korea",
            "nameEn": "North Korea"
          },
          {
            "code": "RU",
            "name": "Russia",
            "nameEn": "Russia"
          },
          {
            "code": "SO",
            "name": "Somalia",
            "nameEn": "Somalia"
          },
          {
            "code": "SS",
            "name": "South Sudan",
            "nameEn": "South Sudan"
          },
          {
            "code": "SD",
            "name": "Sudan",
            "nameEn": "Sudan"
          },
          {
            "code": "SY",
            "name": "Syria",
            "nameEn": "Syria"
          },
          {
            "code": "VE",
            "name": "Venezuela",
            "nameEn": "Venezuela"
          },
          {
            "code": "YE",
            "name": "Yemen",
            "nameEn": "Yemen"
          },
          {
            "code": "ZW",
            "name": "Zimbabwe",
            "nameEn": "Zimbabwe"
          },
          {
            "code": "UA-43",
            "countryCode": "UA",
            "name": "Crimea (Region of Ukraine)",
            "nameEn": "Crimea (Region of Ukraine)"
          },
          {
            "code": "UA-14",
            "countryCode": "UA",
            "name": "Donetsk (Region of Ukraine)",
            "nameEn": "Donetsk (Region of Ukraine)"
          },
          {
            "code": "UA-65",
            "countryCode": "UA",
            "name": "Kherson (Region of Ukraine)",
            "nameEn": "Kherson (Region of Ukraine)"
          },
          {
            "code": "UA-09",
            "countryCode": "UA",
            "name": "Luhansk (Region of Ukraine)",
            "nameEn": "Luhansk (Region of Ukraine)"
          },
          {
            "code": "UA-23",
            "countryCode": "UA",
            "name": "Zaporizhzhia (Region of Ukraine)",
            "nameEn": "Zaporizhzhia (Region of Ukraine)"
          },
          {
            "code": "AN",
            "name": "Netherlands Antilles",
            "nameEn": "Netherlands Antilles"
          }
        ],
        "verifiedCountryCount": null,
        "exactList": [
          "AX",
          "AL",
          "DZ",
          "AS",
          "AD",
          "AO",
          "AI",
          "AG",
          "AR",
          "AM",
          "AW",
          "AU",
          "AT",
          "AZ",
          "BS",
          "BH",
          "BD",
          "BB",
          "BE",
          "BZ",
          "BJ",
          "BM",
          "BT",
          "BO",
          "BQ",
          "BA",
          "BW",
          "BV",
          "BR",
          "IO",
          "BN",
          "BG",
          "BF",
          "CV",
          "KH",
          "CM",
          "CA",
          "KY",
          "CL",
          "CN",
          "CX",
          "CC",
          "CO",
          "KM",
          "CK",
          "CR",
          "HR",
          "CW",
          "CY",
          "CZ",
          "CI",
          "DK",
          "DJ",
          "DM",
          "DO",
          "EC",
          "EG",
          "SV",
          "GQ",
          "EE",
          "SZ",
          "ET",
          "FK",
          "FO",
          "FM",
          "FJ",
          "FI",
          "FR",
          "GF",
          "PF",
          "TF",
          "GA",
          "GM",
          "GE",
          "DE",
          "GH",
          "GI",
          "GR",
          "GL",
          "GD",
          "GP",
          "GU",
          "GT",
          "GG",
          "GN",
          "GW",
          "GY",
          "HM",
          "VA",
          "HN",
          "HK",
          "HU",
          "IS",
          "IN",
          "ID",
          "IE",
          "IM",
          "IL",
          "IT",
          "JM",
          "JP",
          "JE",
          "JO",
          "KZ",
          "KE",
          "KI",
          "KW",
          "KG",
          "LA",
          "LV",
          "LB",
          "LS",
          "LR",
          "LI",
          "LT",
          "LU",
          "MO",
          "MG",
          "MW",
          "MY",
          "MV",
          "MT",
          "MH",
          "MQ",
          "MR",
          "MU",
          "YT",
          "MX",
          "MD",
          "MC",
          "MN",
          "ME",
          "MS",
          "MA",
          "MZ",
          "NA",
          "NR",
          "NP",
          "NL",
          "NC",
          "NZ",
          "NE",
          "NG",
          "NU",
          "NF",
          "MK",
          "MP",
          "NO",
          "OM",
          "PK",
          "PW",
          "PA",
          "PG",
          "PY",
          "PE",
          "PH",
          "PN",
          "PL",
          "PT",
          "PR",
          "QA",
          "RO",
          "RW",
          "RE",
          "BL",
          "SH",
          "KN",
          "LC",
          "MF",
          "PM",
          "VC",
          "WS",
          "SM",
          "ST",
          "SA",
          "SN",
          "RS",
          "SC",
          "SL",
          "SG",
          "SX",
          "SK",
          "SI",
          "SB",
          "ZA",
          "GS",
          "KR",
          "ES",
          "LK",
          "PS",
          "SR",
          "SJ",
          "SE",
          "CH",
          "TW",
          "TJ",
          "TZ",
          "TH",
          "TL",
          "TG",
          "TK",
          "TO",
          "TT",
          "TN",
          "TM",
          "TC",
          "TV",
          "TR",
          "UG",
          "UA",
          "AE",
          "GB",
          "UM",
          "US",
          "UY",
          "UZ",
          "VU",
          "VN",
          "VG",
          "VI",
          "WF",
          "EH",
          "ZM"
        ],
        "records": [
          {
            "code": "AX",
            "name": "Islas Aland",
            "nameEn": "Åland Islands",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "AL",
            "name": "Albania",
            "nameEn": "Albania",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "DZ",
            "name": "Argelia",
            "nameEn": "Algeria",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "AS",
            "name": "Samoa Americana",
            "nameEn": "American Samoa",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "AD",
            "name": "Andorra",
            "nameEn": "Andorra",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "AO",
            "name": "Angola",
            "nameEn": "Angola",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "AI",
            "name": "Anguila",
            "nameEn": "Anguilla",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "AG",
            "name": "Antigua y Barbuda",
            "nameEn": "Antigua & Barbuda",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "AR",
            "name": "Argentina",
            "nameEn": "Argentina",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "AM",
            "name": "Armenia",
            "nameEn": "Armenia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "AW",
            "name": "Aruba",
            "nameEn": "Aruba",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "AU",
            "name": "Australia",
            "nameEn": "Australia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "AT",
            "name": "Austria",
            "nameEn": "Austria",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "AZ",
            "name": "Azerbaiyán",
            "nameEn": "Azerbaijan",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "BS",
            "name": "Bahamas",
            "nameEn": "Bahamas",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "BH",
            "name": "Baréin",
            "nameEn": "Bahrain",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "BD",
            "name": "Bangladés",
            "nameEn": "Bangladesh",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "BB",
            "name": "Barbados",
            "nameEn": "Barbados",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "BE",
            "name": "Bélgica",
            "nameEn": "Belgium",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "BZ",
            "name": "Belice",
            "nameEn": "Belize",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "BJ",
            "name": "Benín",
            "nameEn": "Benin",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "BM",
            "name": "Bermudas",
            "nameEn": "Bermuda",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "BT",
            "name": "Bután",
            "nameEn": "Bhutan",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "BO",
            "name": "Bolivia",
            "nameEn": "Bolivia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "BQ",
            "name": "Caribe neerlandés",
            "nameEn": "Caribbean Netherlands",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "BA",
            "name": "Bosnia y Herzegovina",
            "nameEn": "Bosnia & Herzegovina",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "BW",
            "name": "Botsuana",
            "nameEn": "Botswana",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "BV",
            "name": "Isla Bouvet",
            "nameEn": "Bouvet Island",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "BR",
            "name": "Brasil",
            "nameEn": "Brazil",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "IO",
            "name": "Territorio Británico del Océano Índico",
            "nameEn": "British Indian Ocean Territory",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "BN",
            "name": "Brunéi",
            "nameEn": "Brunei",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "BG",
            "name": "Bulgaria",
            "nameEn": "Bulgaria",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "BF",
            "name": "Burkina Faso",
            "nameEn": "Burkina Faso",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "CV",
            "name": "Cabo Verde",
            "nameEn": "Cape Verde",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "KH",
            "name": "Camboya",
            "nameEn": "Cambodia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "CM",
            "name": "Camerún",
            "nameEn": "Cameroon",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "CA",
            "name": "Canadá",
            "nameEn": "Canada",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "KY",
            "name": "Islas Caimán",
            "nameEn": "Cayman Islands",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "CL",
            "name": "Chile",
            "nameEn": "Chile",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "CN",
            "name": "China",
            "nameEn": "China",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "CX",
            "name": "Isla de Navidad",
            "nameEn": "Christmas Island",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "CC",
            "name": "Islas Cocos",
            "nameEn": "Cocos (Keeling) Islands",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "CO",
            "name": "Colombia",
            "nameEn": "Colombia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "KM",
            "name": "Comoras",
            "nameEn": "Comoros",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "CK",
            "name": "Islas Cook",
            "nameEn": "Cook Islands",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "CR",
            "name": "Costa Rica",
            "nameEn": "Costa Rica",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "HR",
            "name": "Croacia",
            "nameEn": "Croatia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "CW",
            "name": "Curazao",
            "nameEn": "Curaçao",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "CY",
            "name": "Chipre",
            "nameEn": "Cyprus",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "CZ",
            "name": "Chequia",
            "nameEn": "Czechia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "CI",
            "name": "Côte d’Ivoire",
            "nameEn": "Côte d’Ivoire",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "DK",
            "name": "Dinamarca",
            "nameEn": "Denmark",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "DJ",
            "name": "Yibuti",
            "nameEn": "Djibouti",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "DM",
            "name": "Dominica",
            "nameEn": "Dominica",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "DO",
            "name": "República Dominicana",
            "nameEn": "Dominican Republic",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "EC",
            "name": "Ecuador",
            "nameEn": "Ecuador",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "EG",
            "name": "Egipto",
            "nameEn": "Egypt",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "SV",
            "name": "El Salvador",
            "nameEn": "El Salvador",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "GQ",
            "name": "Guinea Ecuatorial",
            "nameEn": "Equatorial Guinea",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "EE",
            "name": "Estonia",
            "nameEn": "Estonia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "SZ",
            "name": "Esuatini",
            "nameEn": "Eswatini",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "ET",
            "name": "Etiopía",
            "nameEn": "Ethiopia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "FK",
            "name": "Islas Malvinas",
            "nameEn": "Falkland Islands",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "FO",
            "name": "Islas Feroe",
            "nameEn": "Faroe Islands",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "FM",
            "name": "Micronesia",
            "nameEn": "Micronesia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "FJ",
            "name": "Fiyi",
            "nameEn": "Fiji",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "FI",
            "name": "Finlandia",
            "nameEn": "Finland",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "FR",
            "name": "Francia",
            "nameEn": "France",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "GF",
            "name": "Guayana Francesa",
            "nameEn": "French Guiana",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "PF",
            "name": "Polinesia Francesa",
            "nameEn": "French Polynesia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "TF",
            "name": "Territorios Australes Franceses",
            "nameEn": "French Southern Territories",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "GA",
            "name": "Gabón",
            "nameEn": "Gabon",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "GM",
            "name": "Gambia",
            "nameEn": "Gambia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "GE",
            "name": "Georgia",
            "nameEn": "Georgia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "DE",
            "name": "Alemania",
            "nameEn": "Germany",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "GH",
            "name": "Ghana",
            "nameEn": "Ghana",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "GI",
            "name": "Gibraltar",
            "nameEn": "Gibraltar",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "GR",
            "name": "Grecia",
            "nameEn": "Greece",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "GL",
            "name": "Groenlandia",
            "nameEn": "Greenland",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "GD",
            "name": "Granada",
            "nameEn": "Grenada",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "GP",
            "name": "Guadalupe",
            "nameEn": "Guadeloupe",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "GU",
            "name": "Guam",
            "nameEn": "Guam",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "GT",
            "name": "Guatemala",
            "nameEn": "Guatemala",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "GG",
            "name": "Guernesey",
            "nameEn": "Guernsey",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "GN",
            "name": "Guinea",
            "nameEn": "Guinea",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "GW",
            "name": "Guinea-Bisáu",
            "nameEn": "Guinea-Bissau",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "GY",
            "name": "Guyana",
            "nameEn": "Guyana",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "HM",
            "name": "Islas Heard y McDonald",
            "nameEn": "Heard & McDonald Islands",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "VA",
            "name": "Ciudad del Vaticano",
            "nameEn": "Vatican City",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "HN",
            "name": "Honduras",
            "nameEn": "Honduras",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "HK",
            "name": "RAE de Hong Kong (China)",
            "nameEn": "Hong Kong SAR China",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "HU",
            "name": "Hungría",
            "nameEn": "Hungary",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "IS",
            "name": "Islandia",
            "nameEn": "Iceland",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "IN",
            "name": "India",
            "nameEn": "India",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "ID",
            "name": "Indonesia",
            "nameEn": "Indonesia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "IE",
            "name": "Irlanda",
            "nameEn": "Ireland",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "IM",
            "name": "Isla de Man",
            "nameEn": "Isle of Man",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "IL",
            "name": "Israel",
            "nameEn": "Israel",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "IT",
            "name": "Italia",
            "nameEn": "Italy",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "JM",
            "name": "Jamaica",
            "nameEn": "Jamaica",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "JP",
            "name": "Japón",
            "nameEn": "Japan",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "JE",
            "name": "Jersey",
            "nameEn": "Jersey",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "JO",
            "name": "Jordania",
            "nameEn": "Jordan",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "KZ",
            "name": "Kazajistán",
            "nameEn": "Kazakhstan",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "KE",
            "name": "Kenia",
            "nameEn": "Kenya",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "KI",
            "name": "Kiribati",
            "nameEn": "Kiribati",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "KW",
            "name": "Kuwait",
            "nameEn": "Kuwait",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "KG",
            "name": "Kirguistán",
            "nameEn": "Kyrgyzstan",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "LA",
            "name": "Laos",
            "nameEn": "Laos",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "LV",
            "name": "Letonia",
            "nameEn": "Latvia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "LB",
            "name": "Líbano",
            "nameEn": "Lebanon",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "LS",
            "name": "Lesoto",
            "nameEn": "Lesotho",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "LR",
            "name": "Liberia",
            "nameEn": "Liberia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "LI",
            "name": "Liechtenstein",
            "nameEn": "Liechtenstein",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "LT",
            "name": "Lituania",
            "nameEn": "Lithuania",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "LU",
            "name": "Luxemburgo",
            "nameEn": "Luxembourg",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "MO",
            "name": "RAE de Macao (China)",
            "nameEn": "Macao SAR China",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "MG",
            "name": "Madagascar",
            "nameEn": "Madagascar",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "MW",
            "name": "Malaui",
            "nameEn": "Malawi",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "MY",
            "name": "Malasia",
            "nameEn": "Malaysia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "MV",
            "name": "Maldivas",
            "nameEn": "Maldives",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "MT",
            "name": "Malta",
            "nameEn": "Malta",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "MH",
            "name": "Islas Marshall",
            "nameEn": "Marshall Islands",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "MQ",
            "name": "Martinica",
            "nameEn": "Martinique",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "MR",
            "name": "Mauritania",
            "nameEn": "Mauritania",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "MU",
            "name": "Mauricio",
            "nameEn": "Mauritius",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "YT",
            "name": "Mayotte",
            "nameEn": "Mayotte",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "MX",
            "name": "México",
            "nameEn": "Mexico",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "MD",
            "name": "Moldavia",
            "nameEn": "Moldova",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "MC",
            "name": "Mónaco",
            "nameEn": "Monaco",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "MN",
            "name": "Mongolia",
            "nameEn": "Mongolia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "ME",
            "name": "Montenegro",
            "nameEn": "Montenegro",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "MS",
            "name": "Montserrat",
            "nameEn": "Montserrat",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "MA",
            "name": "Marruecos",
            "nameEn": "Morocco",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "MZ",
            "name": "Mozambique",
            "nameEn": "Mozambique",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "NA",
            "name": "Namibia",
            "nameEn": "Namibia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "NR",
            "name": "Nauru",
            "nameEn": "Nauru",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "NP",
            "name": "Nepal",
            "nameEn": "Nepal",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "NL",
            "name": "Países Bajos",
            "nameEn": "Netherlands",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "NC",
            "name": "Nueva Caledonia",
            "nameEn": "New Caledonia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "NZ",
            "name": "Nueva Zelanda",
            "nameEn": "New Zealand",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "NE",
            "name": "Níger",
            "nameEn": "Niger",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "NG",
            "name": "Nigeria",
            "nameEn": "Nigeria",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "NU",
            "name": "Niue",
            "nameEn": "Niue",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "NF",
            "name": "Isla Norfolk",
            "nameEn": "Norfolk Island",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "MK",
            "name": "Macedonia del Norte",
            "nameEn": "North Macedonia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "MP",
            "name": "Islas Marianas del Norte",
            "nameEn": "Northern Mariana Islands",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "NO",
            "name": "Noruega",
            "nameEn": "Norway",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "OM",
            "name": "Omán",
            "nameEn": "Oman",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "PK",
            "name": "Pakistán",
            "nameEn": "Pakistan",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "PW",
            "name": "Palaos",
            "nameEn": "Palau",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "PA",
            "name": "Panamá",
            "nameEn": "Panama",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "PG",
            "name": "Papúa Nueva Guinea",
            "nameEn": "Papua New Guinea",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "PY",
            "name": "Paraguay",
            "nameEn": "Paraguay",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "PE",
            "name": "Perú",
            "nameEn": "Peru",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "PH",
            "name": "Filipinas",
            "nameEn": "Philippines",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "PN",
            "name": "Islas Pitcairn",
            "nameEn": "Pitcairn Islands",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "PL",
            "name": "Polonia",
            "nameEn": "Poland",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "PT",
            "name": "Portugal",
            "nameEn": "Portugal",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "PR",
            "name": "Puerto Rico",
            "nameEn": "Puerto Rico",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "QA",
            "name": "Catar",
            "nameEn": "Qatar",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "RO",
            "name": "Rumanía",
            "nameEn": "Romania",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "RW",
            "name": "Ruanda",
            "nameEn": "Rwanda",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "RE",
            "name": "Reunión",
            "nameEn": "Réunion",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "BL",
            "name": "San Bartolomé",
            "nameEn": "St. Barthélemy",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "SH",
            "name": "Santa Elena",
            "nameEn": "St. Helena",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "KN",
            "name": "San Cristóbal y Nieves",
            "nameEn": "St. Kitts & Nevis",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "LC",
            "name": "Santa Lucía",
            "nameEn": "St. Lucia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "MF",
            "name": "San Martín",
            "nameEn": "St. Martin",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "PM",
            "name": "San Pedro y Miquelón",
            "nameEn": "St. Pierre & Miquelon",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "VC",
            "name": "San Vicente y las Granadinas",
            "nameEn": "St. Vincent & Grenadines",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "WS",
            "name": "Samoa",
            "nameEn": "Samoa",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "SM",
            "name": "San Marino",
            "nameEn": "San Marino",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "ST",
            "name": "Santo Tomé y Príncipe",
            "nameEn": "São Tomé & Príncipe",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "SA",
            "name": "Arabia Saudí",
            "nameEn": "Saudi Arabia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "SN",
            "name": "Senegal",
            "nameEn": "Senegal",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "RS",
            "name": "Serbia",
            "nameEn": "Serbia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "SC",
            "name": "Seychelles",
            "nameEn": "Seychelles",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "SL",
            "name": "Sierra Leona",
            "nameEn": "Sierra Leone",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "SG",
            "name": "Singapur",
            "nameEn": "Singapore",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "SX",
            "name": "Sint Maarten",
            "nameEn": "Sint Maarten",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "SK",
            "name": "Eslovaquia",
            "nameEn": "Slovakia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "SI",
            "name": "Eslovenia",
            "nameEn": "Slovenia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "SB",
            "name": "Islas Salomón",
            "nameEn": "Solomon Islands",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "ZA",
            "name": "Sudáfrica",
            "nameEn": "South Africa",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "GS",
            "name": "Islas Georgia del Sur y Sandwich del Sur",
            "nameEn": "South Georgia & South Sandwich Islands",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "KR",
            "name": "Corea del Sur",
            "nameEn": "South Korea",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "ES",
            "name": "España",
            "nameEn": "Spain",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "LK",
            "name": "Sri Lanka",
            "nameEn": "Sri Lanka",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "PS",
            "name": "Territorios Palestinos",
            "nameEn": "Palestinian Territories",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "SR",
            "name": "Surinam",
            "nameEn": "Suriname",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "SJ",
            "name": "Svalbard y Jan Mayen",
            "nameEn": "Svalbard & Jan Mayen",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "SE",
            "name": "Suecia",
            "nameEn": "Sweden",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "CH",
            "name": "Suiza",
            "nameEn": "Switzerland",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "TW",
            "name": "Taiwán",
            "nameEn": "Taiwan",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "TJ",
            "name": "Tayikistán",
            "nameEn": "Tajikistan",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "TZ",
            "name": "Tanzania",
            "nameEn": "Tanzania",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "TH",
            "name": "Tailandia",
            "nameEn": "Thailand",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "TL",
            "name": "Timor-Leste",
            "nameEn": "Timor-Leste",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "TG",
            "name": "Togo",
            "nameEn": "Togo",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "TK",
            "name": "Tokelau",
            "nameEn": "Tokelau",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "TO",
            "name": "Tonga",
            "nameEn": "Tonga",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "TT",
            "name": "Trinidad y Tobago",
            "nameEn": "Trinidad & Tobago",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "TN",
            "name": "Túnez",
            "nameEn": "Tunisia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "TM",
            "name": "Turkmenistán",
            "nameEn": "Turkmenistan",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "TC",
            "name": "Islas Turcas y Caicos",
            "nameEn": "Turks & Caicos Islands",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "TV",
            "name": "Tuvalu",
            "nameEn": "Tuvalu",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "TR",
            "name": "Turquía",
            "nameEn": "Türkiye",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "UG",
            "name": "Uganda",
            "nameEn": "Uganda",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "UA",
            "name": "Ucrania",
            "nameEn": "Ukraine",
            "marker": "**",
            "coverage": "partial_locations",
            "note": "Las tarjetas no están disponibles en Crimea, Donetsk, Luhansk, Jersón y Zaporiyia. El resto de Ucrania está disponible."
          },
          {
            "code": "AE",
            "name": "Emiratos Árabes Unidos",
            "nameEn": "United Arab Emirates",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "GB",
            "name": "Reino Unido",
            "nameEn": "United Kingdom",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "UM",
            "name": "Islas menores alejadas de EE. UU.",
            "nameEn": "U.S. Outlying Islands",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "US",
            "name": "Estados Unidos",
            "nameEn": "United States",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "UY",
            "name": "Uruguay",
            "nameEn": "Uruguay",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "UZ",
            "name": "Uzbekistán",
            "nameEn": "Uzbekistan",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "VU",
            "name": "Vanuatu",
            "nameEn": "Vanuatu",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "VN",
            "name": "Vietnam",
            "nameEn": "Vietnam",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "VG",
            "name": "Islas Vírgenes Británicas",
            "nameEn": "British Virgin Islands",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "VI",
            "name": "Islas Vírgenes de EE. UU.",
            "nameEn": "U.S. Virgin Islands",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "WF",
            "name": "Wallis y Futuna",
            "nameEn": "Wallis & Futuna",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "EH",
            "name": "Sáhara Occidental",
            "nameEn": "Western Sahara",
            "marker": "",
            "coverage": "listed",
            "note": ""
          },
          {
            "code": "ZM",
            "name": "Zambia",
            "nameEn": "Zambia",
            "marker": "",
            "coverage": "listed",
            "note": ""
          }
        ],
        "source": "owner_provided",
        "status": "owner_list_received",
        "policy": "worldwide_except_restrictions",
        "independentlyVerified": false,
        "partialCoverage": {
          "marker": "**",
          "countryCodes": [
            "UA"
          ],
          "note": "Las tarjetas no están disponibles en Crimea, Donetsk, Luhansk, Jersón y Zaporiyia. El resto de Ucrania está disponible."
        },
        "unresolvedFootnotes": [],
        "approvalGuaranteed": false
      },
      "sbp": [
        "RU"
      ],
      "alipay": [
        "CN"
      ],
      "crypto": {
        "exactList": null,
        "status": "live_catalog_required",
        "invoiceCurrency": "USDT",
        "cataloguePath": "/api/checkout/{token}/crypto-services"
      }
    },
    "cryptoAcceptance": {
      "invoiceCurrency": "USDT",
      "coinCount": 16,
      "pairCount": 31,
      "pairs": [
        {
          "currency": "AVAX",
          "network": "avalanche",
          "networkLabel": "Avalanche C-Chain"
        },
        {
          "currency": "BCH",
          "network": "bch",
          "networkLabel": "Bitcoin Cash"
        },
        {
          "currency": "BNB",
          "network": "bsc",
          "networkLabel": "BNB Smart Chain"
        },
        {
          "currency": "BTC",
          "network": "btc",
          "networkLabel": "Bitcoin"
        },
        {
          "currency": "DAI",
          "network": "bsc",
          "networkLabel": "BNB Smart Chain"
        },
        {
          "currency": "DAI",
          "network": "eth",
          "networkLabel": "Ethereum"
        },
        {
          "currency": "DAI",
          "network": "polygon",
          "networkLabel": "Polygon PoS"
        },
        {
          "currency": "DASH",
          "network": "dash",
          "networkLabel": "Dash"
        },
        {
          "currency": "DOGE",
          "network": "doge",
          "networkLabel": "Dogecoin"
        },
        {
          "currency": "ETH",
          "network": "eth",
          "networkLabel": "Ethereum"
        },
        {
          "currency": "ETH",
          "network": "arbitrum",
          "networkLabel": "Arbitrum One"
        },
        {
          "currency": "ETH",
          "network": "bsc",
          "networkLabel": "BNB Smart Chain"
        },
        {
          "currency": "GRAM",
          "network": "ton",
          "networkLabel": "TON"
        },
        {
          "currency": "LTC",
          "network": "ltc",
          "networkLabel": "Litecoin"
        },
        {
          "currency": "POL",
          "network": "eth",
          "networkLabel": "Ethereum"
        },
        {
          "currency": "POL",
          "network": "polygon",
          "networkLabel": "Polygon PoS"
        },
        {
          "currency": "SHIB",
          "network": "eth",
          "networkLabel": "Ethereum"
        },
        {
          "currency": "TRX",
          "network": "tron",
          "networkLabel": "TRON"
        },
        {
          "currency": "USDC",
          "network": "arbitrum",
          "networkLabel": "Arbitrum One"
        },
        {
          "currency": "USDC",
          "network": "bsc",
          "networkLabel": "BNB Smart Chain"
        },
        {
          "currency": "USDC",
          "network": "polygon",
          "networkLabel": "Polygon PoS"
        },
        {
          "currency": "USDC",
          "network": "eth",
          "networkLabel": "Ethereum"
        },
        {
          "currency": "USDC",
          "network": "avalanche",
          "networkLabel": "Avalanche C-Chain"
        },
        {
          "currency": "USDT",
          "network": "tron",
          "networkLabel": "TRON"
        },
        {
          "currency": "USDT",
          "network": "avalanche",
          "networkLabel": "Avalanche C-Chain"
        },
        {
          "currency": "USDT",
          "network": "bsc",
          "networkLabel": "BNB Smart Chain"
        },
        {
          "currency": "USDT",
          "network": "ton",
          "networkLabel": "TON"
        },
        {
          "currency": "USDT",
          "network": "polygon",
          "networkLabel": "Polygon PoS"
        },
        {
          "currency": "USDT",
          "network": "arbitrum",
          "networkLabel": "Arbitrum One"
        },
        {
          "currency": "USDT",
          "network": "eth",
          "networkLabel": "Ethereum"
        },
        {
          "currency": "XMR",
          "network": "xmr",
          "networkLabel": "Monero"
        }
      ],
      "catalogueSource": "owner_provided",
      "liveAvailabilitySource": "/api/checkout/{token}/crypto-services",
      "referenceCatalogueConfirmsAvailability": false,
      "transferInstructionsSource": "created_gateway_operation",
      "invoiceFixesOtherCoinExchangeRate": false,
      "exactTransferAmountRequired": true,
      "merchantPayout": {
        "asset": "USDT",
        "network": "TRC20",
        "distinctFromAcceptanceNetworks": true,
        "creationImplemented": false
      }
    },
    "support": {
      "knowledgeScope": "all_published_articles_and_facts",
      "articleCount": 25,
      "historyMessagesPerRequest": 6,
      "historyStorage": "browser_local_storage",
      "historySync": "device_only",
      "separateConversations": true,
      "perConversationDrafts": true,
      "pageContext": "safe_section_label_only",
      "privateAccountAccess": false,
      "financialActions": false,
      "fallback": "documentation_search",
      "readinessEndpoint": "/api/config"
    },
    "notifications": {
      "pageSize": 30,
      "readStateStorage": "server",
      "readStateAffectsTelegramDelivery": false,
      "readEndpoint": "/api/notifications/read"
    },
    "gatewayIntegration": {
      "adapterImplemented": true,
      "contract": "v3",
      "liveConfigurationProvided": null,
      "requiredEnvironment": [
        "GATEWAY_API_KEY",
        "GATEWAY_WEBHOOK_SECRET"
      ],
      "connectionModes": {
        "externalHttps": {
          "originEnvironment": "GATEWAY_BASE_URL"
        },
        "selfHostedService": {
          "capability": "GATEWAY_SERVICE",
          "fixedDestination": true,
          "publicGatewayApi": false
        }
      },
      "availability": {
        "source": "runtime",
        "configurationEndpoint": "/api/config",
        "configurationField": "gateway.configured",
        "configurationIncludesHealthCheck": false,
        "checkoutEndpoint": "/api/checkout/{token}",
        "checkoutField": "invoice.availability",
        "checkoutCompatibilityAlias": "invoice.gatewayConnected",
        "checkoutIncludesProviderApproval": false
      },
      "cardTransport": "browser_JWE_to_gateway",
      "cardPlaintextAcceptedByKevmi": false,
      "hostedCardApi": false,
      "sealedAlgorithms": [
        "RSA-OAEP-256",
        "A256GCM"
      ],
      "ingress": {
        "path": "/api/gateway/webhook",
        "signatureHeader": "X-Gateway-Signature",
        "timestampHeader": "X-Gateway-Timestamp",
        "eventIdHeader": "X-Gateway-Event-Id",
        "signatureAlgorithm": "HMAC-SHA256",
        "signatureInput": "timestamp.rawBody",
        "timestampToleranceSeconds": 300,
        "authenticatedOperationReadRequired": true
      },
      "successRequires": [
        "fulfillment_ready",
        "provider_confirmed",
        "exact_paid_amount",
        "no_dispute",
        "crypto_settlement_evidence_if_crypto"
      ],
      "statusDoesNotCharge": true,
      "reconciliationDoesNotCharge": true,
      "oneDispatchedOperationPerInvoice": true,
      "ledgerNotImplemented": true
    },
    "merchantWorkspace": {
      "multipleStores": true,
      "storeLimit": 100,
      "storeEndpoint": "/api/stores",
      "storeHeader": "X-Kevmi-Store",
      "aggregateReadOnly": true,
      "pricingMode": "universal",
      "baseCurrency": "USD",
      "sbpChargeCurrency": "RUB",
      "cryptoChargeCurrency": "USDT",
      "usdUsdtInvoiceRatio": "1:1",
      "referenceRateSource": "https://www.cbr.ru/scripts/XML_daily.asp",
      "fxInvoiceMaxHours": 24,
      "path": "/account",
      "sections": [
        "overview",
        "payments",
        "payouts",
        "pricing",
        "stores",
        "links",
        "applications",
        "keys",
        "webhooks",
        "widget",
        "events",
        "knowledge",
        "store",
        "notifications",
        "support"
      ]
    },
    "gatewayConnected": null,
    "limitsConfirmed": false,
    "scope": "Public product documentation only. No user records or secrets."
  },
  "locale": "es",
  "docGroups": [
    {
      "id": "start",
      "title": "Primeros pasos",
      "description": "Desde tu primera visita hasta una tienda configurada.",
      "icon": "bolt"
    },
    {
      "id": "payments",
      "title": "Pagos y condiciones",
      "description": "Enlaces, importes, IVA, métodos de pago y retiros.",
      "icon": "card"
    },
    {
      "id": "account",
      "title": "Cuenta y soporte",
      "description": "Telegram, notificaciones y ayuda con tus preguntas.",
      "icon": "settings"
    },
    {
      "id": "developers",
      "title": "Desarrolladores",
      "description": "API, seguridad, webhooks e integración de la pasarela.",
      "icon": "book"
    }
  ],
  "navPages": [
    {
      "href": "/",
      "title": "Resumen",
      "icon": "grid"
    },
    {
      "href": "/payment-methods",
      "title": "Métodos de pago",
      "icon": "card"
    },
    {
      "href": "/pricing",
      "title": "Tarifas",
      "icon": "percent"
    },
    {
      "href": "/payment-links",
      "title": "Enlaces de pago",
      "icon": "link"
    },
    {
      "href": "/countries",
      "title": "Cobertura",
      "icon": "globe"
    },
    {
      "href": "/docs",
      "title": "Documentación",
      "icon": "book"
    },
    {
      "href": "/?support=open",
      "title": "Soporte",
      "icon": "chat"
    },
    {
      "href": "/integrations",
      "title": "Integraciones",
      "icon": "code"
    }
  ],
  "paymentMethods": [
    {
      "id": "card",
      "name": "Tarjetas internacionales",
      "shortName": "Tarjetas internacionales",
      "description": "Pagos con tarjeta para clientes internacionales.",
      "incomingPercent": 10,
      "incomingFixedMinor": 50,
      "incomingFixedCurrency": "USD",
      "payoutPercent": 4,
      "payoutFixedMinor": 0,
      "payoutFixedCurrency": "USD",
      "vatApplies": true,
      "region": "Pagos internacionales",
      "symbol": "card",
      "geography": "Visa y Mastercard de más de 190 países, excepto la lista de restricciones y cinco regiones de Ucrania.",
      "countryCount": 223,
      "ownerReportedCountryCount": null,
      "coverageLabel": "190+"
    },
    {
      "id": "sbp",
      "name": "SBP",
      "shortName": "SBP",
      "description": "Paga a través de un banco con el Sistema de Pagos Rápidos de Rusia.",
      "incomingPercent": 8,
      "incomingFixedMinor": 0,
      "incomingFixedCurrency": "RUB",
      "payoutPercent": 5,
      "payoutFixedMinor": 40000,
      "payoutFixedCurrency": "RUB",
      "vatApplies": false,
      "region": "Rusia",
      "symbol": "sbp",
      "geography": "Rusia. La disponibilidad depende del banco y de la transacción.",
      "countryCount": 1
    },
    {
      "id": "alipay",
      "name": "Alipay",
      "shortName": "Alipay",
      "description": "Pagos Alipay para clientes en China.",
      "incomingPercent": 10,
      "incomingFixedMinor": 50,
      "incomingFixedCurrency": "USD",
      "payoutPercent": 4,
      "payoutFixedMinor": 0,
      "payoutFixedCurrency": "USD",
      "vatApplies": true,
      "region": "China",
      "symbol": "alipay",
      "geography": "China. La disponibilidad depende de la cuenta y de la transacción.",
      "countryCount": 1
    },
    {
      "id": "crypto",
      "name": "Criptomoneda",
      "shortName": "Cripto",
      "description": "Pagos únicos con criptomonedas, con una comisión del 4 % y sin IVA.",
      "incomingPercent": 4,
      "incomingFixedMinor": 0,
      "incomingFixedCurrency": "USD",
      "payoutPercent": 0,
      "payoutFixedMinor": 300,
      "payoutFixedCurrency": "USD",
      "vatApplies": false,
      "region": "Activos digitales",
      "symbol": "crypto",
      "geography": "Todos los países del mundo. Elige una moneda y red compatibles. Los pagos se realizan mediante USDT TRC20.",
      "countryCount": null
    }
  ],
  "payoutFees": {
    "card": "4%",
    "alipay": "4%",
    "sbp": "5% + RUB 400",
    "crypto": "0% + $3"
  },
  "documentationLocale": "es"
}
