# InnovappSoft Developer API DOCUMENT_TYPE: complete_api_reference FORMAT: Markdown-compatible plain text LANGUAGE: es BASE_URL: https://api.innovapp-soft.com AUTHENTICATION: Authorization: Bearer {API_KEY} CONTENT_TYPE: application/json for requests with body ## Instrucciones para agentes y asistentes de IA - Esta es la fuente completa de la documentación publicada en el portal Developer. - No inventes rutas, parámetros, estados ni campos que no aparezcan aquí. - Sustituye los valores de ejemplo; nunca uses la API key de ejemplo en producción. - Nunca envíes userIdentifier: el backend obtiene el usuario KeyPay vinculado a la API key. - Usa primero los endpoints de catálogo y reutiliza exactamente los identificadores devueltos. - En operaciones con client_purchase_id, reutiliza la misma clave solamente al reintentar la misma compra. - Considera el HTTP status y también success, code, message, data y error. ## Respuesta general ```json { "success": true, "code": "operation.ok", "message": "OK", "data": [], "error": [], "time": "ISO-8601 or structured server time" } ``` ## Estados HTTP comunes - 200 / 201: solicitud procesada o recurso creado. - 400: JSON, ruta o parámetros inválidos. - 401: API key ausente, inválida o inactiva. - 403: operación no autorizada o verificación adicional requerida. - 404: ruta o recurso inexistente. - 409: conflicto lógico, operación en proceso o saldo insuficiente. - 422: datos válidos en JSON pero rechazados por las reglas del endpoint. - 429: límite de peticiones alcanzado. - 500: error interno. - 502: respuesta inválida o fallo de comunicación con un servicio interno. - 503: servicio temporalmente no disponible. # Grupo: Rates API V2 Tasas normalizadas para aplicaciones y servicios externos. ## Endpoint: GET /v2/rates ID: rates-v2 ACTION: GET /v2/rates METHOD: GET PATH: /v2/rates URL: https://api.innovapp-soft.com/v2/rates AUTH: Bearer API Key DESCRIPTION: Devuelve tasas V2 globales o por pais con secciones normalizadas, variacion y recursos de imagen. ### Headers - Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx - Accept: application/json ### Query parameters - country | required=No | type=string | description=Codigo ISO alpha-2 o GLOBAL. | example=CU - base | required=No | type=string | description=Moneda base solicitada. | example=USD - include_snapshot | required=No | type=integer | description=Usa 1 para incluir el snapshot completo. | example=1 ### cURL ```bash curl -X GET 'https://api.innovapp-soft.com/v2/rates?country=CU' \ -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \ -H 'Accept: application/json' ``` ### Ejemplo de código ```text fetch('https://api.innovapp-soft.com/v2/rates?country=CU', { headers: { 'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx', 'Accept': 'application/json' } }).then(r => r.json()).then(console.log); ``` ### Respuesta exitosa ```json { "success": true, "code": "ok", "message": "OK", "data": { "version": 2, "country": "CU", "base": "USD", "sections": [] }, "error": [], "time": "2026-07-29T15:30:00-04:00" } ``` ### Errores específicos - HTTP 401 | API key invalida ```json { "success": false, "code": 40101, "message": "Invalid API key." } ``` ### Notas - /v2/tasas es un alias compatible de /v2/rates. - Para nuevas integraciones usa /v2/rates. --- # Grupo: Store V2 · Catálogo general KeyStore Empieza aquí para conocer todos los productos habilitados antes de abrir un flujo específico. ## Endpoint: POST /v2/store/catalog/list ID: store-v2-catalog-list ACTION: Catálogo completo METHOD: POST PATH: /v2/store/catalog/list URL: https://api.innovapp-soft.com/v2/store/catalog/list AUTH: Bearer API Key DESCRIPTION: Catálogo general KeyStore: Devuelve el catálogo completo habilitado en KeyStore, incluidos VPN, KeyCode, productos físicos y las entradas V2 disponibles. La visibilidad sigue la configuración activa del Dashboard. ### Headers - Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx - Accept: application/json - Content-Type: application/json ### Body parameters - language | required=No | type=string | description=Idioma de la respuesta: es o en. | example=es ### cURL ```bash curl -X POST 'https://api.innovapp-soft.com/v2/store/catalog/list' \ -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -d '{"language":"es"}' ``` ### Ejemplo de código ```text fetch('https://api.innovapp-soft.com/v2/store/catalog/list', { method: 'POST', headers: { 'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx', 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({ "language": "es" }) }).then(r => r.json()).then(console.log); ``` ### Respuesta exitosa ```json { "success": true, "code": "store.catalog.list.ok", "message": "OK", "data": { "status": "available", "items": [] }, "error": [], "time": "2026-07-29T15:30:00-04:00" } ``` ### Errores específicos - HTTP 401 | API key invalida ```json { "success": false, "code": 40101, "message": "Invalid API key." } ``` - HTTP 422 | Parametro requerido ```json { "success": false, "code": 47017, "message": "Required field is missing: client_purchase_id" } ``` - HTTP 502 | Servicio temporalmente no disponible ```json { "success": false, "code": 47020, "message": "The Store service is temporarily unavailable." } ``` ### Notas - No envies userIdentifier: el usuario KeyPay se obtiene del developer autenticado. - Las compras requieren client_purchase_id unico. Si repites la misma solicitud usa exactamente el mismo valor. - El catalogo determina los identificadores, montos y campos validos; no construyas offer_id, service_id ni e164 manualmente. - La API puede devolver pending, processing, completed, failed o refunded segun el producto. --- # Grupo: Store V2 · Recargas internacionales Flujo recomendado: consultar catálogo, validar promoción si existe, comprar y después consultar la orden o su estado. ## Endpoint: POST /v2/store/topups/catalog ID: store-v2-topups-catalog ACTION: Consultar catálogo METHOD: POST PATH: /v2/store/topups/catalog URL: https://api.innovapp-soft.com/v2/store/topups/catalog AUTH: Bearer API Key DESCRIPTION: Recargas internacionales: Lista paises, operadores y ofertas. Usa mode=countries para iniciar; despues envia country y finalmente country + brand. ### Headers - Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx - Accept: application/json - Content-Type: application/json ### Body parameters - mode | required=No | type=string | description=Vista del catalogo solicitada. | example=countries - country | required=Depende | type=string | description=Codigo ISO 3166-1 alpha-2 del pais. | example=CU - brand | required=Depende | type=string | description=Marca u operador devuelto por el catalogo. | example=Cubacel - sub_type | required=No | type=string | description=Subtipo de producto dentro de una marca. | example=MOBILE - language | required=No | type=string | description=Idioma de la respuesta: es o en. | example=es ### cURL ```bash curl -X POST 'https://api.innovapp-soft.com/v2/store/topups/catalog' \ -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -d '{"mode":"countries","language":"es"}' ``` ### Ejemplo de código ```text fetch('https://api.innovapp-soft.com/v2/store/topups/catalog', { method: 'POST', headers: { 'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx', 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({ "mode": "countries", "language": "es" }) }).then(r => r.json()).then(console.log); ``` ### Respuesta exitosa ```json { "success": true, "code": "store.topups.catalog.ok", "message": "OK", "data": { "status": "available", "items": [] }, "error": [], "time": "2026-07-29T15:30:00-04:00" } ``` ### Errores específicos - HTTP 401 | API key invalida ```json { "success": false, "code": 40101, "message": "Invalid API key." } ``` - HTTP 422 | Parametro requerido ```json { "success": false, "code": 47017, "message": "Required field is missing: client_purchase_id" } ``` - HTTP 502 | Servicio temporalmente no disponible ```json { "success": false, "code": 47020, "message": "The Store service is temporarily unavailable." } ``` ### Notas - No envies userIdentifier: el usuario KeyPay se obtiene del developer autenticado. - Las compras requieren client_purchase_id unico. Si repites la misma solicitud usa exactamente el mismo valor. - El catalogo determina los identificadores, montos y campos validos; no construyas offer_id, service_id ni e164 manualmente. - La API puede devolver pending, processing, completed, failed o refunded segun el producto. --- ## Endpoint: POST /v2/store/topups/promo ID: store-v2-topups-promo ACTION: Validar promoción METHOD: POST PATH: /v2/store/topups/promo URL: https://api.innovapp-soft.com/v2/store/topups/promo AUTH: Bearer API Key DESCRIPTION: Recargas internacionales: Valida un codigo promocional para una oferta antes de comprar. ### Headers - Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx - Accept: application/json - Content-Type: application/json ### Body parameters - country | required=Depende | type=string | description=Codigo ISO 3166-1 alpha-2 del pais. | example=CU - brand | required=Depende | type=string | description=Marca u operador devuelto por el catalogo. | example=Cubacel - offer_id | required=Si en compra | type=string | description=Identificador exacto de la oferta seleccionada. | example=61 - promo_code | required=Depende | type=string | description=Codigo promocional que se desea validar o aplicar. | example=PROMO2026 - amount | required=No | type=number | description=Monto elegido cuando la oferta permite un rango. | example=25.00 - language | required=No | type=string | description=Idioma de la respuesta: es o en. | example=es ### cURL ```bash curl -X POST 'https://api.innovapp-soft.com/v2/store/topups/promo' \ -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -d '{"country":"CU","brand":"Cubacel","offer_id":"61","promo_code":"PROMO2026","language":"es"}' ``` ### Ejemplo de código ```text fetch('https://api.innovapp-soft.com/v2/store/topups/promo', { method: 'POST', headers: { 'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx', 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({ "country": "CU", "brand": "Cubacel", "offer_id": "61", "promo_code": "PROMO2026", "language": "es" }) }).then(r => r.json()).then(console.log); ``` ### Respuesta exitosa ```json { "success": true, "code": "store.topups.promo.ok", "message": "OK", "data": { "status": "available", "items": [] }, "error": [], "time": "2026-07-29T15:30:00-04:00" } ``` ### Errores específicos - HTTP 401 | API key invalida ```json { "success": false, "code": 40101, "message": "Invalid API key." } ``` - HTTP 422 | Parametro requerido ```json { "success": false, "code": 47017, "message": "Required field is missing: client_purchase_id" } ``` - HTTP 502 | Servicio temporalmente no disponible ```json { "success": false, "code": 47020, "message": "The Store service is temporarily unavailable." } ``` ### Notas - No envies userIdentifier: el usuario KeyPay se obtiene del developer autenticado. - Las compras requieren client_purchase_id unico. Si repites la misma solicitud usa exactamente el mismo valor. - El catalogo determina los identificadores, montos y campos validos; no construyas offer_id, service_id ni e164 manualmente. - La API puede devolver pending, processing, completed, failed o refunded segun el producto. --- ## Endpoint: POST /v2/store/topups/buy ID: store-v2-topups-buy ACTION: Comprar METHOD: POST PATH: /v2/store/topups/buy URL: https://api.innovapp-soft.com/v2/store/topups/buy AUTH: Bearer API Key DESCRIPTION: Recargas internacionales: Compra una recarga internacional. client_purchase_id hace la operacion idempotente y no debe reutilizarse para otra compra. ### Headers - Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx - Accept: application/json - Content-Type: application/json ### Body parameters - country | required=Depende | type=string | description=Codigo ISO 3166-1 alpha-2 del pais. | example=CU - brand | required=Depende | type=string | description=Marca u operador devuelto por el catalogo. | example=Cubacel - offer_id | required=Si en compra | type=string | description=Identificador exacto de la oferta seleccionada. | example=61 - phone_number | required=Si en compra | type=string | description=Numero de telefono que recibira la recarga. | example=+5351234567 - client_purchase_id | required=Si en compra | type=string | description=Idempotency key unica creada por tu sistema para esta compra. | example=order-2026-000184 - promo_code | required=Depende | type=string | description=Codigo promocional que se desea validar o aplicar. | example=PROMO2026 - amount | required=No | type=number | description=Monto elegido cuando la oferta permite un rango. | example=25.00 - language | required=No | type=string | description=Idioma de la respuesta: es o en. | example=es ### cURL ```bash curl -X POST 'https://api.innovapp-soft.com/v2/store/topups/buy' \ -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -d '{"country":"CU","brand":"Cubacel","offer_id":"61","phone_number":"+5351234567","client_purchase_id":"topup-2026-000184","language":"es"}' ``` ### Ejemplo de código ```text fetch('https://api.innovapp-soft.com/v2/store/topups/buy', { method: 'POST', headers: { 'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx', 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({ "country": "CU", "brand": "Cubacel", "offer_id": "61", "phone_number": "+5351234567", "client_purchase_id": "topup-2026-000184", "language": "es" }) }).then(r => r.json()).then(console.log); ``` ### Respuesta exitosa ```json { "success": true, "code": "store.topups.buy.ok", "message": "OK", "data": { "status": "pending", "items": [] }, "error": [], "time": "2026-07-29T15:30:00-04:00" } ``` ### Errores específicos - HTTP 401 | API key invalida ```json { "success": false, "code": 40101, "message": "Invalid API key." } ``` - HTTP 422 | Parametro requerido ```json { "success": false, "code": 47017, "message": "Required field is missing: client_purchase_id" } ``` - HTTP 502 | Servicio temporalmente no disponible ```json { "success": false, "code": 47020, "message": "The Store service is temporarily unavailable." } ``` ### Notas - No envies userIdentifier: el usuario KeyPay se obtiene del developer autenticado. - Las compras requieren client_purchase_id unico. Si repites la misma solicitud usa exactamente el mismo valor. - El catalogo determina los identificadores, montos y campos validos; no construyas offer_id, service_id ni e164 manualmente. - La API puede devolver pending, processing, completed, failed o refunded segun el producto. --- ## Endpoint: POST /v2/store/topups/orders ID: store-v2-topups-orders ACTION: Consultar órdenes METHOD: POST PATH: /v2/store/topups/orders URL: https://api.innovapp-soft.com/v2/store/topups/orders AUTH: Bearer API Key DESCRIPTION: Recargas internacionales: Devuelve el historial paginado de recargas del usuario KeyPay vinculado al developer. ### Headers - Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx - Accept: application/json - Content-Type: application/json ### Body parameters - page | required=No | type=integer | description=Pagina del historial. | example=1 - per_page | required=No | type=integer | description=Resultados por pagina, maximo 100. | example=20 - language | required=No | type=string | description=Idioma de la respuesta: es o en. | example=es ### cURL ```bash curl -X POST 'https://api.innovapp-soft.com/v2/store/topups/orders' \ -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -d '{"page":1,"per_page":20,"language":"es"}' ``` ### Ejemplo de código ```text fetch('https://api.innovapp-soft.com/v2/store/topups/orders', { method: 'POST', headers: { 'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx', 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({ "page": 1, "per_page": 20, "language": "es" }) }).then(r => r.json()).then(console.log); ``` ### Respuesta exitosa ```json { "success": true, "code": "store.topups.orders.ok", "message": "OK", "data": { "status": "available", "items": [] }, "error": [], "time": "2026-07-29T15:30:00-04:00" } ``` ### Errores específicos - HTTP 401 | API key invalida ```json { "success": false, "code": 40101, "message": "Invalid API key." } ``` - HTTP 422 | Parametro requerido ```json { "success": false, "code": 47017, "message": "Required field is missing: client_purchase_id" } ``` - HTTP 502 | Servicio temporalmente no disponible ```json { "success": false, "code": 47020, "message": "The Store service is temporarily unavailable." } ``` ### Notas - No envies userIdentifier: el usuario KeyPay se obtiene del developer autenticado. - Las compras requieren client_purchase_id unico. Si repites la misma solicitud usa exactamente el mismo valor. - El catalogo determina los identificadores, montos y campos validos; no construyas offer_id, service_id ni e164 manualmente. - La API puede devolver pending, processing, completed, failed o refunded segun el producto. --- ## Endpoint: POST /v2/store/topups/status ID: store-v2-topups-status ACTION: Consultar estado METHOD: POST PATH: /v2/store/topups/status URL: https://api.innovapp-soft.com/v2/store/topups/status AUTH: Bearer API Key DESCRIPTION: Recargas internacionales: Consulta el estado actualizado de una recarga. ### Headers - Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx - Accept: application/json - Content-Type: application/json ### Body parameters - order_id | required=Si en status | type=string | description=Identificador de la orden devuelto al crearla. | example=1842 - language | required=No | type=string | description=Idioma de la respuesta: es o en. | example=es ### cURL ```bash curl -X POST 'https://api.innovapp-soft.com/v2/store/topups/status' \ -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -d '{"order_id":"1842","language":"es"}' ``` ### Ejemplo de código ```text fetch('https://api.innovapp-soft.com/v2/store/topups/status', { method: 'POST', headers: { 'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx', 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({ "order_id": "1842", "language": "es" }) }).then(r => r.json()).then(console.log); ``` ### Respuesta exitosa ```json { "success": true, "code": "store.topups.status.ok", "message": "OK", "data": { "status": "available", "items": [] }, "error": [], "time": "2026-07-29T15:30:00-04:00" } ``` ### Errores específicos - HTTP 401 | API key invalida ```json { "success": false, "code": 40101, "message": "Invalid API key." } ``` - HTTP 422 | Parametro requerido ```json { "success": false, "code": 47017, "message": "Required field is missing: client_purchase_id" } ``` - HTTP 502 | Servicio temporalmente no disponible ```json { "success": false, "code": 47020, "message": "The Store service is temporarily unavailable." } ``` ### Notas - No envies userIdentifier: el usuario KeyPay se obtiene del developer autenticado. - Las compras requieren client_purchase_id unico. Si repites la misma solicitud usa exactamente el mismo valor. - El catalogo determina los identificadores, montos y campos validos; no construyas offer_id, service_id ni e164 manualmente. - La API puede devolver pending, processing, completed, failed o refunded segun el producto. --- # Grupo: Store V2 · Gift Cards Flujo recomendado: consultar marcas y ofertas, comprar y después consultar las órdenes o el estado de entrega. ## Endpoint: POST /v2/store/giftcards/catalog ID: store-v2-giftcards-catalog ACTION: Consultar catálogo METHOD: POST PATH: /v2/store/giftcards/catalog URL: https://api.innovapp-soft.com/v2/store/giftcards/catalog AUTH: Bearer API Key DESCRIPTION: Gift Cards: Lista marcas y ofertas de Gift Cards V2 por pais, categoria o busqueda. ### Headers - Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx - Accept: application/json - Content-Type: application/json ### Body parameters - mode | required=No | type=string | description=Vista del catalogo solicitada. | example=countries - country | required=Depende | type=string | description=Codigo ISO 3166-1 alpha-2 del pais. | example=CU - brand | required=Depende | type=string | description=Marca u operador devuelto por el catalogo. | example=Cubacel - query | required=No | type=string | description=Texto para filtrar el catalogo. | example=Amazon - category | required=No | type=string | description=Categoria del catalogo. | example=Gaming - page | required=No | type=integer | description=Pagina del historial. | example=1 - per_page | required=No | type=integer | description=Resultados por pagina, maximo 100. | example=20 - language | required=No | type=string | description=Idioma de la respuesta: es o en. | example=es ### cURL ```bash curl -X POST 'https://api.innovapp-soft.com/v2/store/giftcards/catalog' \ -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -d '{"mode":"countries","country":"US","page":1,"per_page":20,"language":"es"}' ``` ### Ejemplo de código ```text fetch('https://api.innovapp-soft.com/v2/store/giftcards/catalog', { method: 'POST', headers: { 'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx', 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({ "mode": "countries", "country": "US", "page": 1, "per_page": 20, "language": "es" }) }).then(r => r.json()).then(console.log); ``` ### Respuesta exitosa ```json { "success": true, "code": "store.giftcards.catalog.ok", "message": "OK", "data": { "status": "available", "items": [] }, "error": [], "time": "2026-07-29T15:30:00-04:00" } ``` ### Errores específicos - HTTP 401 | API key invalida ```json { "success": false, "code": 40101, "message": "Invalid API key." } ``` - HTTP 422 | Parametro requerido ```json { "success": false, "code": 47017, "message": "Required field is missing: client_purchase_id" } ``` - HTTP 502 | Servicio temporalmente no disponible ```json { "success": false, "code": 47020, "message": "The Store service is temporarily unavailable." } ``` ### Notas - No envies userIdentifier: el usuario KeyPay se obtiene del developer autenticado. - Las compras requieren client_purchase_id unico. Si repites la misma solicitud usa exactamente el mismo valor. - El catalogo determina los identificadores, montos y campos validos; no construyas offer_id, service_id ni e164 manualmente. - La API puede devolver pending, processing, completed, failed o refunded segun el producto. --- ## Endpoint: POST /v2/store/giftcards/buy ID: store-v2-giftcards-buy ACTION: Comprar METHOD: POST PATH: /v2/store/giftcards/buy URL: https://api.innovapp-soft.com/v2/store/giftcards/buy AUTH: Bearer API Key DESCRIPTION: Gift Cards: Compra una Gift Card fija o de rango. En ofertas de rango envia amount. ### Headers - Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx - Accept: application/json - Content-Type: application/json ### Body parameters - brand | required=Depende | type=string | description=Marca u operador devuelto por el catalogo. | example=Cubacel - country | required=Depende | type=string | description=Codigo ISO 3166-1 alpha-2 del pais. | example=CU - offer_id | required=Si en compra | type=string | description=Identificador exacto de la oferta seleccionada. | example=61 - client_purchase_id | required=Si en compra | type=string | description=Idempotency key unica creada por tu sistema para esta compra. | example=order-2026-000184 - amount | required=No | type=number | description=Monto elegido cuando la oferta permite un rango. | example=25.00 - language | required=No | type=string | description=Idioma de la respuesta: es o en. | example=es ### cURL ```bash curl -X POST 'https://api.innovapp-soft.com/v2/store/giftcards/buy' \ -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -d '{"brand":"Amazon","country":"US","offer_id":"amazon-us-25","client_purchase_id":"gift-2026-000184","language":"es"}' ``` ### Ejemplo de código ```text fetch('https://api.innovapp-soft.com/v2/store/giftcards/buy', { method: 'POST', headers: { 'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx', 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({ "brand": "Amazon", "country": "US", "offer_id": "amazon-us-25", "client_purchase_id": "gift-2026-000184", "language": "es" }) }).then(r => r.json()).then(console.log); ``` ### Respuesta exitosa ```json { "success": true, "code": "store.giftcards.buy.ok", "message": "OK", "data": { "status": "pending", "items": [] }, "error": [], "time": "2026-07-29T15:30:00-04:00" } ``` ### Errores específicos - HTTP 401 | API key invalida ```json { "success": false, "code": 40101, "message": "Invalid API key." } ``` - HTTP 422 | Parametro requerido ```json { "success": false, "code": 47017, "message": "Required field is missing: client_purchase_id" } ``` - HTTP 502 | Servicio temporalmente no disponible ```json { "success": false, "code": 47020, "message": "The Store service is temporarily unavailable." } ``` ### Notas - No envies userIdentifier: el usuario KeyPay se obtiene del developer autenticado. - Las compras requieren client_purchase_id unico. Si repites la misma solicitud usa exactamente el mismo valor. - El catalogo determina los identificadores, montos y campos validos; no construyas offer_id, service_id ni e164 manualmente. - La API puede devolver pending, processing, completed, failed o refunded segun el producto. --- ## Endpoint: POST /v2/store/giftcards/orders ID: store-v2-giftcards-orders ACTION: Consultar órdenes METHOD: POST PATH: /v2/store/giftcards/orders URL: https://api.innovapp-soft.com/v2/store/giftcards/orders AUTH: Bearer API Key DESCRIPTION: Gift Cards: Devuelve las ordenes de Gift Cards del usuario vinculado. ### Headers - Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx - Accept: application/json - Content-Type: application/json ### Body parameters - page | required=No | type=integer | description=Pagina del historial. | example=1 - per_page | required=No | type=integer | description=Resultados por pagina, maximo 100. | example=20 - language | required=No | type=string | description=Idioma de la respuesta: es o en. | example=es ### cURL ```bash curl -X POST 'https://api.innovapp-soft.com/v2/store/giftcards/orders' \ -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -d '{"page":1,"per_page":20,"language":"es"}' ``` ### Ejemplo de código ```text fetch('https://api.innovapp-soft.com/v2/store/giftcards/orders', { method: 'POST', headers: { 'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx', 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({ "page": 1, "per_page": 20, "language": "es" }) }).then(r => r.json()).then(console.log); ``` ### Respuesta exitosa ```json { "success": true, "code": "store.giftcards.orders.ok", "message": "OK", "data": { "status": "available", "items": [] }, "error": [], "time": "2026-07-29T15:30:00-04:00" } ``` ### Errores específicos - HTTP 401 | API key invalida ```json { "success": false, "code": 40101, "message": "Invalid API key." } ``` - HTTP 422 | Parametro requerido ```json { "success": false, "code": 47017, "message": "Required field is missing: client_purchase_id" } ``` - HTTP 502 | Servicio temporalmente no disponible ```json { "success": false, "code": 47020, "message": "The Store service is temporarily unavailable." } ``` ### Notas - No envies userIdentifier: el usuario KeyPay se obtiene del developer autenticado. - Las compras requieren client_purchase_id unico. Si repites la misma solicitud usa exactamente el mismo valor. - El catalogo determina los identificadores, montos y campos validos; no construyas offer_id, service_id ni e164 manualmente. - La API puede devolver pending, processing, completed, failed o refunded segun el producto. --- ## Endpoint: POST /v2/store/giftcards/status ID: store-v2-giftcards-status ACTION: Consultar estado METHOD: POST PATH: /v2/store/giftcards/status URL: https://api.innovapp-soft.com/v2/store/giftcards/status AUTH: Bearer API Key DESCRIPTION: Gift Cards: Consulta una orden y sus datos de entrega cuando ya estan disponibles. ### Headers - Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx - Accept: application/json - Content-Type: application/json ### Body parameters - order_id | required=Si en status | type=string | description=Identificador de la orden devuelto al crearla. | example=1842 - language | required=No | type=string | description=Idioma de la respuesta: es o en. | example=es ### cURL ```bash curl -X POST 'https://api.innovapp-soft.com/v2/store/giftcards/status' \ -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -d '{"order_id":"1842","language":"es"}' ``` ### Ejemplo de código ```text fetch('https://api.innovapp-soft.com/v2/store/giftcards/status', { method: 'POST', headers: { 'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx', 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({ "order_id": "1842", "language": "es" }) }).then(r => r.json()).then(console.log); ``` ### Respuesta exitosa ```json { "success": true, "code": "store.giftcards.status.ok", "message": "OK", "data": { "status": "available", "items": [] }, "error": [], "time": "2026-07-29T15:30:00-04:00" } ``` ### Errores específicos - HTTP 401 | API key invalida ```json { "success": false, "code": 40101, "message": "Invalid API key." } ``` - HTTP 422 | Parametro requerido ```json { "success": false, "code": 47017, "message": "Required field is missing: client_purchase_id" } ``` - HTTP 502 | Servicio temporalmente no disponible ```json { "success": false, "code": 47020, "message": "The Store service is temporarily unavailable." } ``` ### Notas - No envies userIdentifier: el usuario KeyPay se obtiene del developer autenticado. - Las compras requieren client_purchase_id unico. Si repites la misma solicitud usa exactamente el mismo valor. - El catalogo determina los identificadores, montos y campos validos; no construyas offer_id, service_id ni e164 manualmente. - La API puede devolver pending, processing, completed, failed o refunded segun el producto. --- # Grupo: Store V2 · Servicios IMEI Flujo recomendado: consultar servicios y campos requeridos, crear la solicitud y después revisar su resultado. ## Endpoint: POST /v2/store/imei/catalog ID: store-v2-imei-catalog ACTION: Consultar catálogo METHOD: POST PATH: /v2/store/imei/catalog URL: https://api.innovapp-soft.com/v2/store/imei/catalog AUTH: Bearer API Key DESCRIPTION: Servicios IMEI: Lista los servicios IMEI disponibles y los campos que requiere cada uno. ### Headers - Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx - Accept: application/json - Content-Type: application/json ### Body parameters - page | required=No | type=integer | description=Pagina del historial. | example=1 - per_page | required=No | type=integer | description=Resultados por pagina, maximo 100. | example=20 - search | required=No | type=string | description=Texto para buscar un servicio IMEI. | example=iPhone - language | required=No | type=string | description=Idioma de la respuesta: es o en. | example=es ### cURL ```bash curl -X POST 'https://api.innovapp-soft.com/v2/store/imei/catalog' \ -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -d '{"page":1,"per_page":20,"search":"iPhone","language":"es"}' ``` ### Ejemplo de código ```text fetch('https://api.innovapp-soft.com/v2/store/imei/catalog', { method: 'POST', headers: { 'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx', 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({ "page": 1, "per_page": 20, "search": "iPhone", "language": "es" }) }).then(r => r.json()).then(console.log); ``` ### Respuesta exitosa ```json { "success": true, "code": "store.imei.catalog.ok", "message": "OK", "data": { "status": "available", "items": [] }, "error": [], "time": "2026-07-29T15:30:00-04:00" } ``` ### Errores específicos - HTTP 401 | API key invalida ```json { "success": false, "code": 40101, "message": "Invalid API key." } ``` - HTTP 422 | Parametro requerido ```json { "success": false, "code": 47017, "message": "Required field is missing: client_purchase_id" } ``` - HTTP 502 | Servicio temporalmente no disponible ```json { "success": false, "code": 47020, "message": "The Store service is temporarily unavailable." } ``` ### Notas - No envies userIdentifier: el usuario KeyPay se obtiene del developer autenticado. - Las compras requieren client_purchase_id unico. Si repites la misma solicitud usa exactamente el mismo valor. - El catalogo determina los identificadores, montos y campos validos; no construyas offer_id, service_id ni e164 manualmente. - La API puede devolver pending, processing, completed, failed o refunded segun el producto. --- ## Endpoint: POST /v2/store/imei/buy ID: store-v2-imei-buy ACTION: Comprar METHOD: POST PATH: /v2/store/imei/buy URL: https://api.innovapp-soft.com/v2/store/imei/buy AUTH: Bearer API Key DESCRIPTION: Servicios IMEI: Solicita un servicio IMEI. Envia input con los mismos nombres de campo entregados por el catalogo. ### Headers - Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx - Accept: application/json - Content-Type: application/json ### Body parameters - service_id | required=Si en compra | type=string | description=Identificador del servicio IMEI. | example=115 - device_id | required=Depende | type=string | description=IMEI, serial u otro identificador solicitado por el servicio. | example=356938035643809 - input | required=Depende | type=object | description=Campos dinamicos solicitados por el servicio IMEI. | example={"IMEI":"356938035643809"} - client_purchase_id | required=Si en compra | type=string | description=Idempotency key unica creada por tu sistema para esta compra. | example=order-2026-000184 - language | required=No | type=string | description=Idioma de la respuesta: es o en. | example=es ### cURL ```bash curl -X POST 'https://api.innovapp-soft.com/v2/store/imei/buy' \ -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -d '{"service_id":"115","input":{"IMEI":"356938035643809"},"client_purchase_id":"imei-2026-000184","language":"es"}' ``` ### Ejemplo de código ```text fetch('https://api.innovapp-soft.com/v2/store/imei/buy', { method: 'POST', headers: { 'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx', 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({ "service_id": "115", "input": { "IMEI": "356938035643809" }, "client_purchase_id": "imei-2026-000184", "language": "es" }) }).then(r => r.json()).then(console.log); ``` ### Respuesta exitosa ```json { "success": true, "code": "store.imei.buy.ok", "message": "OK", "data": { "status": "pending", "items": [] }, "error": [], "time": "2026-07-29T15:30:00-04:00" } ``` ### Errores específicos - HTTP 401 | API key invalida ```json { "success": false, "code": 40101, "message": "Invalid API key." } ``` - HTTP 422 | Parametro requerido ```json { "success": false, "code": 47017, "message": "Required field is missing: client_purchase_id" } ``` - HTTP 502 | Servicio temporalmente no disponible ```json { "success": false, "code": 47020, "message": "The Store service is temporarily unavailable." } ``` ### Notas - No envies userIdentifier: el usuario KeyPay se obtiene del developer autenticado. - Las compras requieren client_purchase_id unico. Si repites la misma solicitud usa exactamente el mismo valor. - El catalogo determina los identificadores, montos y campos validos; no construyas offer_id, service_id ni e164 manualmente. - La API puede devolver pending, processing, completed, failed o refunded segun el producto. --- ## Endpoint: POST /v2/store/imei/orders ID: store-v2-imei-orders ACTION: Consultar órdenes METHOD: POST PATH: /v2/store/imei/orders URL: https://api.innovapp-soft.com/v2/store/imei/orders AUTH: Bearer API Key DESCRIPTION: Servicios IMEI: Devuelve el historial paginado de solicitudes IMEI. ### Headers - Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx - Accept: application/json - Content-Type: application/json ### Body parameters - page | required=No | type=integer | description=Pagina del historial. | example=1 - per_page | required=No | type=integer | description=Resultados por pagina, maximo 100. | example=20 - language | required=No | type=string | description=Idioma de la respuesta: es o en. | example=es ### cURL ```bash curl -X POST 'https://api.innovapp-soft.com/v2/store/imei/orders' \ -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -d '{"page":1,"per_page":20,"language":"es"}' ``` ### Ejemplo de código ```text fetch('https://api.innovapp-soft.com/v2/store/imei/orders', { method: 'POST', headers: { 'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx', 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({ "page": 1, "per_page": 20, "language": "es" }) }).then(r => r.json()).then(console.log); ``` ### Respuesta exitosa ```json { "success": true, "code": "store.imei.orders.ok", "message": "OK", "data": { "status": "available", "items": [] }, "error": [], "time": "2026-07-29T15:30:00-04:00" } ``` ### Errores específicos - HTTP 401 | API key invalida ```json { "success": false, "code": 40101, "message": "Invalid API key." } ``` - HTTP 422 | Parametro requerido ```json { "success": false, "code": 47017, "message": "Required field is missing: client_purchase_id" } ``` - HTTP 502 | Servicio temporalmente no disponible ```json { "success": false, "code": 47020, "message": "The Store service is temporarily unavailable." } ``` ### Notas - No envies userIdentifier: el usuario KeyPay se obtiene del developer autenticado. - Las compras requieren client_purchase_id unico. Si repites la misma solicitud usa exactamente el mismo valor. - El catalogo determina los identificadores, montos y campos validos; no construyas offer_id, service_id ni e164 manualmente. - La API puede devolver pending, processing, completed, failed o refunded segun el producto. --- ## Endpoint: POST /v2/store/imei/status ID: store-v2-imei-status ACTION: Consultar estado METHOD: POST PATH: /v2/store/imei/status URL: https://api.innovapp-soft.com/v2/store/imei/status AUTH: Bearer API Key DESCRIPTION: Servicios IMEI: Consulta el estado y el resultado de una solicitud IMEI. ### Headers - Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx - Accept: application/json - Content-Type: application/json ### Body parameters - order_id | required=Si en status | type=string | description=Identificador de la orden devuelto al crearla. | example=1842 - language | required=No | type=string | description=Idioma de la respuesta: es o en. | example=es ### cURL ```bash curl -X POST 'https://api.innovapp-soft.com/v2/store/imei/status' \ -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -d '{"order_id":"1842","language":"es"}' ``` ### Ejemplo de código ```text fetch('https://api.innovapp-soft.com/v2/store/imei/status', { method: 'POST', headers: { 'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx', 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({ "order_id": "1842", "language": "es" }) }).then(r => r.json()).then(console.log); ``` ### Respuesta exitosa ```json { "success": true, "code": "store.imei.status.ok", "message": "OK", "data": { "status": "available", "items": [] }, "error": [], "time": "2026-07-29T15:30:00-04:00" } ``` ### Errores específicos - HTTP 401 | API key invalida ```json { "success": false, "code": 40101, "message": "Invalid API key." } ``` - HTTP 422 | Parametro requerido ```json { "success": false, "code": 47017, "message": "Required field is missing: client_purchase_id" } ``` - HTTP 502 | Servicio temporalmente no disponible ```json { "success": false, "code": 47020, "message": "The Store service is temporarily unavailable." } ``` ### Notas - No envies userIdentifier: el usuario KeyPay se obtiene del developer autenticado. - Las compras requieren client_purchase_id unico. Si repites la misma solicitud usa exactamente el mismo valor. - El catalogo determina los identificadores, montos y campos validos; no construyas offer_id, service_id ni e164 manualmente. - La API puede devolver pending, processing, completed, failed o refunded segun el producto. --- # Grupo: Store V2 · eSIM Flujo recomendado: consultar destinos y planes, comprar la eSIM y después consultar sus datos de instalación. ## Endpoint: POST /v2/store/esim/catalog ID: store-v2-esim-catalog ACTION: Consultar catálogo METHOD: POST PATH: /v2/store/esim/catalog URL: https://api.innovapp-soft.com/v2/store/esim/catalog AUTH: Bearer API Key DESCRIPTION: eSIM: Lista destinos y planes eSIM disponibles. ### Headers - Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx - Accept: application/json - Content-Type: application/json ### Body parameters - mode | required=No | type=string | description=Vista del catalogo solicitada. | example=countries - country | required=Depende | type=string | description=Codigo ISO 3166-1 alpha-2 del pais. | example=CU - language | required=No | type=string | description=Idioma de la respuesta: es o en. | example=es ### cURL ```bash curl -X POST 'https://api.innovapp-soft.com/v2/store/esim/catalog' \ -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -d '{"mode":"countries","language":"es"}' ``` ### Ejemplo de código ```text fetch('https://api.innovapp-soft.com/v2/store/esim/catalog', { method: 'POST', headers: { 'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx', 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({ "mode": "countries", "language": "es" }) }).then(r => r.json()).then(console.log); ``` ### Respuesta exitosa ```json { "success": true, "code": "store.esim.catalog.ok", "message": "OK", "data": { "status": "available", "items": [] }, "error": [], "time": "2026-07-29T15:30:00-04:00" } ``` ### Errores específicos - HTTP 401 | API key invalida ```json { "success": false, "code": 40101, "message": "Invalid API key." } ``` - HTTP 422 | Parametro requerido ```json { "success": false, "code": 47017, "message": "Required field is missing: client_purchase_id" } ``` - HTTP 502 | Servicio temporalmente no disponible ```json { "success": false, "code": 47020, "message": "The Store service is temporarily unavailable." } ``` ### Notas - No envies userIdentifier: el usuario KeyPay se obtiene del developer autenticado. - Las compras requieren client_purchase_id unico. Si repites la misma solicitud usa exactamente el mismo valor. - El catalogo determina los identificadores, montos y campos validos; no construyas offer_id, service_id ni e164 manualmente. - La API puede devolver pending, processing, completed, failed o refunded segun el producto. --- ## Endpoint: POST /v2/store/esim/buy ID: store-v2-esim-buy ACTION: Comprar METHOD: POST PATH: /v2/store/esim/buy URL: https://api.innovapp-soft.com/v2/store/esim/buy AUTH: Bearer API Key DESCRIPTION: eSIM: Compra un plan eSIM para el pais seleccionado. ### Headers - Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx - Accept: application/json - Content-Type: application/json ### Body parameters - country | required=Depende | type=string | description=Codigo ISO 3166-1 alpha-2 del pais. | example=CU - offer_id | required=Si en compra | type=string | description=Identificador exacto de la oferta seleccionada. | example=61 - client_purchase_id | required=Si en compra | type=string | description=Idempotency key unica creada por tu sistema para esta compra. | example=order-2026-000184 - language | required=No | type=string | description=Idioma de la respuesta: es o en. | example=es ### cURL ```bash curl -X POST 'https://api.innovapp-soft.com/v2/store/esim/buy' \ -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -d '{"country":"US","offer_id":"esim-us-10gb","client_purchase_id":"esim-2026-000184","language":"es"}' ``` ### Ejemplo de código ```text fetch('https://api.innovapp-soft.com/v2/store/esim/buy', { method: 'POST', headers: { 'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx', 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({ "country": "US", "offer_id": "esim-us-10gb", "client_purchase_id": "esim-2026-000184", "language": "es" }) }).then(r => r.json()).then(console.log); ``` ### Respuesta exitosa ```json { "success": true, "code": "store.esim.buy.ok", "message": "OK", "data": { "status": "pending", "items": [] }, "error": [], "time": "2026-07-29T15:30:00-04:00" } ``` ### Errores específicos - HTTP 401 | API key invalida ```json { "success": false, "code": 40101, "message": "Invalid API key." } ``` - HTTP 422 | Parametro requerido ```json { "success": false, "code": 47017, "message": "Required field is missing: client_purchase_id" } ``` - HTTP 502 | Servicio temporalmente no disponible ```json { "success": false, "code": 47020, "message": "The Store service is temporarily unavailable." } ``` ### Notas - No envies userIdentifier: el usuario KeyPay se obtiene del developer autenticado. - Las compras requieren client_purchase_id unico. Si repites la misma solicitud usa exactamente el mismo valor. - El catalogo determina los identificadores, montos y campos validos; no construyas offer_id, service_id ni e164 manualmente. - La API puede devolver pending, processing, completed, failed o refunded segun el producto. --- ## Endpoint: POST /v2/store/esim/orders ID: store-v2-esim-orders ACTION: Consultar órdenes METHOD: POST PATH: /v2/store/esim/orders URL: https://api.innovapp-soft.com/v2/store/esim/orders AUTH: Bearer API Key DESCRIPTION: eSIM: Devuelve las ordenes eSIM del usuario vinculado. ### Headers - Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx - Accept: application/json - Content-Type: application/json ### Body parameters - page | required=No | type=integer | description=Pagina del historial. | example=1 - per_page | required=No | type=integer | description=Resultados por pagina, maximo 100. | example=20 - language | required=No | type=string | description=Idioma de la respuesta: es o en. | example=es ### cURL ```bash curl -X POST 'https://api.innovapp-soft.com/v2/store/esim/orders' \ -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -d '{"page":1,"per_page":20,"language":"es"}' ``` ### Ejemplo de código ```text fetch('https://api.innovapp-soft.com/v2/store/esim/orders', { method: 'POST', headers: { 'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx', 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({ "page": 1, "per_page": 20, "language": "es" }) }).then(r => r.json()).then(console.log); ``` ### Respuesta exitosa ```json { "success": true, "code": "store.esim.orders.ok", "message": "OK", "data": { "status": "available", "items": [] }, "error": [], "time": "2026-07-29T15:30:00-04:00" } ``` ### Errores específicos - HTTP 401 | API key invalida ```json { "success": false, "code": 40101, "message": "Invalid API key." } ``` - HTTP 422 | Parametro requerido ```json { "success": false, "code": 47017, "message": "Required field is missing: client_purchase_id" } ``` - HTTP 502 | Servicio temporalmente no disponible ```json { "success": false, "code": 47020, "message": "The Store service is temporarily unavailable." } ``` ### Notas - No envies userIdentifier: el usuario KeyPay se obtiene del developer autenticado. - Las compras requieren client_purchase_id unico. Si repites la misma solicitud usa exactamente el mismo valor. - El catalogo determina los identificadores, montos y campos validos; no construyas offer_id, service_id ni e164 manualmente. - La API puede devolver pending, processing, completed, failed o refunded segun el producto. --- ## Endpoint: POST /v2/store/esim/status ID: store-v2-esim-status ACTION: Consultar estado METHOD: POST PATH: /v2/store/esim/status URL: https://api.innovapp-soft.com/v2/store/esim/status AUTH: Bearer API Key DESCRIPTION: eSIM: Consulta una orden eSIM y sus datos de instalacion cuando esten disponibles. ### Headers - Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx - Accept: application/json - Content-Type: application/json ### Body parameters - order_id | required=Si en status | type=string | description=Identificador de la orden devuelto al crearla. | example=1842 - language | required=No | type=string | description=Idioma de la respuesta: es o en. | example=es ### cURL ```bash curl -X POST 'https://api.innovapp-soft.com/v2/store/esim/status' \ -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -d '{"order_id":"1842","language":"es"}' ``` ### Ejemplo de código ```text fetch('https://api.innovapp-soft.com/v2/store/esim/status', { method: 'POST', headers: { 'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx', 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({ "order_id": "1842", "language": "es" }) }).then(r => r.json()).then(console.log); ``` ### Respuesta exitosa ```json { "success": true, "code": "store.esim.status.ok", "message": "OK", "data": { "status": "available", "items": [] }, "error": [], "time": "2026-07-29T15:30:00-04:00" } ``` ### Errores específicos - HTTP 401 | API key invalida ```json { "success": false, "code": 40101, "message": "Invalid API key." } ``` - HTTP 422 | Parametro requerido ```json { "success": false, "code": 47017, "message": "Required field is missing: client_purchase_id" } ``` - HTTP 502 | Servicio temporalmente no disponible ```json { "success": false, "code": 47020, "message": "The Store service is temporarily unavailable." } ``` ### Notas - No envies userIdentifier: el usuario KeyPay se obtiene del developer autenticado. - Las compras requieren client_purchase_id unico. Si repites la misma solicitud usa exactamente el mismo valor. - El catalogo determina los identificadores, montos y campos validos; no construyas offer_id, service_id ni e164 manualmente. - La API puede devolver pending, processing, completed, failed o refunded segun el producto. --- # Grupo: Store V2 · Números virtuales Flujo recomendado: consultar disponibilidad, alquilar, listar tus números y después gestionar renovación, estado, conversaciones y mensajes. ## Endpoint: POST /v2/store/virtual-numbers/catalog ID: store-v2-virtual-numbers-catalog ACTION: Consultar catálogo METHOD: POST PATH: /v2/store/virtual-numbers/catalog URL: https://api.innovapp-soft.com/v2/store/virtual-numbers/catalog AUTH: Bearer API Key DESCRIPTION: Números virtuales: Lista los numeros virtuales que se pueden alquilar por pais. ### Headers - Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx - Accept: application/json - Content-Type: application/json ### Body parameters - country | required=Depende | type=string | description=Codigo ISO 3166-1 alpha-2 del pais. | example=CU - limit | required=No | type=integer | description=Cantidad maxima de resultados, maximo 100. | example=20 - language | required=No | type=string | description=Idioma de la respuesta: es o en. | example=es ### cURL ```bash curl -X POST 'https://api.innovapp-soft.com/v2/store/virtual-numbers/catalog' \ -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -d '{"country":"US","limit":20,"language":"es"}' ``` ### Ejemplo de código ```text fetch('https://api.innovapp-soft.com/v2/store/virtual-numbers/catalog', { method: 'POST', headers: { 'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx', 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({ "country": "US", "limit": 20, "language": "es" }) }).then(r => r.json()).then(console.log); ``` ### Respuesta exitosa ```json { "success": true, "code": "store.virtual_numbers.catalog.ok", "message": "OK", "data": { "status": "available", "items": [] }, "error": [], "time": "2026-07-29T15:30:00-04:00" } ``` ### Errores específicos - HTTP 401 | API key invalida ```json { "success": false, "code": 40101, "message": "Invalid API key." } ``` - HTTP 422 | Parametro requerido ```json { "success": false, "code": 47017, "message": "Required field is missing: client_purchase_id" } ``` - HTTP 502 | Servicio temporalmente no disponible ```json { "success": false, "code": 47020, "message": "The Store service is temporarily unavailable." } ``` ### Notas - No envies userIdentifier: el usuario KeyPay se obtiene del developer autenticado. - Las compras requieren client_purchase_id unico. Si repites la misma solicitud usa exactamente el mismo valor. - El catalogo determina los identificadores, montos y campos validos; no construyas offer_id, service_id ni e164 manualmente. - La API puede devolver pending, processing, completed, failed o refunded segun el producto. --- ## Endpoint: POST /v2/store/virtual-numbers/rent ID: store-v2-virtual-numbers-rent ACTION: Alquilar número METHOD: POST PATH: /v2/store/virtual-numbers/rent URL: https://api.innovapp-soft.com/v2/store/virtual-numbers/rent AUTH: Bearer API Key DESCRIPTION: Números virtuales: Alquila el numero E.164 seleccionado en el catalogo. ### Headers - Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx - Accept: application/json - Content-Type: application/json ### Body parameters - country | required=Depende | type=string | description=Codigo ISO 3166-1 alpha-2 del pais. | example=CU - e164 | required=Si en rent | type=string | description=Numero internacional E.164 seleccionado en el catalogo. | example=+12125550123 - client_purchase_id | required=Si en compra | type=string | description=Idempotency key unica creada por tu sistema para esta compra. | example=order-2026-000184 - language | required=No | type=string | description=Idioma de la respuesta: es o en. | example=es ### cURL ```bash curl -X POST 'https://api.innovapp-soft.com/v2/store/virtual-numbers/rent' \ -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -d '{"country":"US","e164":"+12125550123","client_purchase_id":"number-2026-000184","language":"es"}' ``` ### Ejemplo de código ```text fetch('https://api.innovapp-soft.com/v2/store/virtual-numbers/rent', { method: 'POST', headers: { 'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx', 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({ "country": "US", "e164": "+12125550123", "client_purchase_id": "number-2026-000184", "language": "es" }) }).then(r => r.json()).then(console.log); ``` ### Respuesta exitosa ```json { "success": true, "code": "store.virtual_numbers.rent.ok", "message": "OK", "data": { "status": "pending", "items": [] }, "error": [], "time": "2026-07-29T15:30:00-04:00" } ``` ### Errores específicos - HTTP 401 | API key invalida ```json { "success": false, "code": 40101, "message": "Invalid API key." } ``` - HTTP 422 | Parametro requerido ```json { "success": false, "code": 47017, "message": "Required field is missing: client_purchase_id" } ``` - HTTP 502 | Servicio temporalmente no disponible ```json { "success": false, "code": 47020, "message": "The Store service is temporarily unavailable." } ``` ### Notas - No envies userIdentifier: el usuario KeyPay se obtiene del developer autenticado. - Las compras requieren client_purchase_id unico. Si repites la misma solicitud usa exactamente el mismo valor. - El catalogo determina los identificadores, montos y campos validos; no construyas offer_id, service_id ni e164 manualmente. - La API puede devolver pending, processing, completed, failed o refunded segun el producto. --- ## Endpoint: POST /v2/store/virtual-numbers/numbers ID: store-v2-virtual-numbers-numbers ACTION: Mis números METHOD: POST PATH: /v2/store/virtual-numbers/numbers URL: https://api.innovapp-soft.com/v2/store/virtual-numbers/numbers AUTH: Bearer API Key DESCRIPTION: Números virtuales: Lista los numeros virtuales alquilados por el usuario vinculado. ### Headers - Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx - Accept: application/json - Content-Type: application/json ### Body parameters - page | required=No | type=integer | description=Pagina del historial. | example=1 - per_page | required=No | type=integer | description=Resultados por pagina, maximo 100. | example=20 - language | required=No | type=string | description=Idioma de la respuesta: es o en. | example=es ### cURL ```bash curl -X POST 'https://api.innovapp-soft.com/v2/store/virtual-numbers/numbers' \ -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -d '{"page":1,"per_page":20,"language":"es"}' ``` ### Ejemplo de código ```text fetch('https://api.innovapp-soft.com/v2/store/virtual-numbers/numbers', { method: 'POST', headers: { 'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx', 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({ "page": 1, "per_page": 20, "language": "es" }) }).then(r => r.json()).then(console.log); ``` ### Respuesta exitosa ```json { "success": true, "code": "store.virtual_numbers.numbers.ok", "message": "OK", "data": { "status": "available", "items": [] }, "error": [], "time": "2026-07-29T15:30:00-04:00" } ``` ### Errores específicos - HTTP 401 | API key invalida ```json { "success": false, "code": 40101, "message": "Invalid API key." } ``` - HTTP 422 | Parametro requerido ```json { "success": false, "code": 47017, "message": "Required field is missing: client_purchase_id" } ``` - HTTP 502 | Servicio temporalmente no disponible ```json { "success": false, "code": 47020, "message": "The Store service is temporarily unavailable." } ``` ### Notas - No envies userIdentifier: el usuario KeyPay se obtiene del developer autenticado. - Las compras requieren client_purchase_id unico. Si repites la misma solicitud usa exactamente el mismo valor. - El catalogo determina los identificadores, montos y campos validos; no construyas offer_id, service_id ni e164 manualmente. - La API puede devolver pending, processing, completed, failed o refunded segun el producto. --- ## Endpoint: POST /v2/store/virtual-numbers/status ID: store-v2-virtual-numbers-status ACTION: Consultar estado METHOD: POST PATH: /v2/store/virtual-numbers/status URL: https://api.innovapp-soft.com/v2/store/virtual-numbers/status AUTH: Bearer API Key DESCRIPTION: Números virtuales: Consulta el estado de un numero virtual o de su orden. ### Headers - Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx - Accept: application/json - Content-Type: application/json ### Body parameters - number_id | required=Depende | type=string | description=Identificador del numero virtual alquilado. | example=vn_1842 - order_id | required=Si en status | type=string | description=Identificador de la orden devuelto al crearla. | example=1842 - language | required=No | type=string | description=Idioma de la respuesta: es o en. | example=es ### cURL ```bash curl -X POST 'https://api.innovapp-soft.com/v2/store/virtual-numbers/status' \ -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -d '{"number_id":"vn_1842","language":"es"}' ``` ### Ejemplo de código ```text fetch('https://api.innovapp-soft.com/v2/store/virtual-numbers/status', { method: 'POST', headers: { 'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx', 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({ "number_id": "vn_1842", "language": "es" }) }).then(r => r.json()).then(console.log); ``` ### Respuesta exitosa ```json { "success": true, "code": "store.virtual_numbers.status.ok", "message": "OK", "data": { "status": "available", "items": [] }, "error": [], "time": "2026-07-29T15:30:00-04:00" } ``` ### Errores específicos - HTTP 401 | API key invalida ```json { "success": false, "code": 40101, "message": "Invalid API key." } ``` - HTTP 422 | Parametro requerido ```json { "success": false, "code": 47017, "message": "Required field is missing: client_purchase_id" } ``` - HTTP 502 | Servicio temporalmente no disponible ```json { "success": false, "code": 47020, "message": "The Store service is temporarily unavailable." } ``` ### Notas - No envies userIdentifier: el usuario KeyPay se obtiene del developer autenticado. - Las compras requieren client_purchase_id unico. Si repites la misma solicitud usa exactamente el mismo valor. - El catalogo determina los identificadores, montos y campos validos; no construyas offer_id, service_id ni e164 manualmente. - La API puede devolver pending, processing, completed, failed o refunded segun el producto. --- ## Endpoint: POST /v2/store/virtual-numbers/messages ID: store-v2-virtual-numbers-messages ACTION: Mensajes recibidos METHOD: POST PATH: /v2/store/virtual-numbers/messages URL: https://api.innovapp-soft.com/v2/store/virtual-numbers/messages AUTH: Bearer API Key DESCRIPTION: Números virtuales: Obtiene los mensajes recibidos por un numero virtual. ### Headers - Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx - Accept: application/json - Content-Type: application/json ### Body parameters - number_id | required=Depende | type=string | description=Identificador del numero virtual alquilado. | example=vn_1842 - limit | required=No | type=integer | description=Cantidad maxima de resultados, maximo 100. | example=20 - cursor | required=No | type=integer | description=Cursor para continuar una lista de mensajes. | example=0 - conversation_id | required=No | type=string | description=Conversacion que se desea consultar. | example=conv_102 - language | required=No | type=string | description=Idioma de la respuesta: es o en. | example=es ### cURL ```bash curl -X POST 'https://api.innovapp-soft.com/v2/store/virtual-numbers/messages' \ -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -d '{"number_id":"vn_1842","limit":20,"cursor":0,"language":"es"}' ``` ### Ejemplo de código ```text fetch('https://api.innovapp-soft.com/v2/store/virtual-numbers/messages', { method: 'POST', headers: { 'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx', 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({ "number_id": "vn_1842", "limit": 20, "cursor": 0, "language": "es" }) }).then(r => r.json()).then(console.log); ``` ### Respuesta exitosa ```json { "success": true, "code": "store.virtual_numbers.messages.ok", "message": "OK", "data": { "status": "available", "items": [] }, "error": [], "time": "2026-07-29T15:30:00-04:00" } ``` ### Errores específicos - HTTP 401 | API key invalida ```json { "success": false, "code": 40101, "message": "Invalid API key." } ``` - HTTP 422 | Parametro requerido ```json { "success": false, "code": 47017, "message": "Required field is missing: client_purchase_id" } ``` - HTTP 502 | Servicio temporalmente no disponible ```json { "success": false, "code": 47020, "message": "The Store service is temporarily unavailable." } ``` ### Notas - No envies userIdentifier: el usuario KeyPay se obtiene del developer autenticado. - Las compras requieren client_purchase_id unico. Si repites la misma solicitud usa exactamente el mismo valor. - El catalogo determina los identificadores, montos y campos validos; no construyas offer_id, service_id ni e164 manualmente. - La API puede devolver pending, processing, completed, failed o refunded segun el producto. --- ## Endpoint: POST /v2/store/virtual-numbers/conversations ID: store-v2-virtual-numbers-conversations ACTION: Conversaciones METHOD: POST PATH: /v2/store/virtual-numbers/conversations URL: https://api.innovapp-soft.com/v2/store/virtual-numbers/conversations AUTH: Bearer API Key DESCRIPTION: Números virtuales: Lista las conversaciones agrupadas de un numero virtual. ### Headers - Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx - Accept: application/json - Content-Type: application/json ### Body parameters - number_id | required=Depende | type=string | description=Identificador del numero virtual alquilado. | example=vn_1842 - page | required=No | type=integer | description=Pagina del historial. | example=1 - per_page | required=No | type=integer | description=Resultados por pagina, maximo 100. | example=20 - language | required=No | type=string | description=Idioma de la respuesta: es o en. | example=es ### cURL ```bash curl -X POST 'https://api.innovapp-soft.com/v2/store/virtual-numbers/conversations' \ -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -d '{"number_id":"vn_1842","page":1,"per_page":20,"language":"es"}' ``` ### Ejemplo de código ```text fetch('https://api.innovapp-soft.com/v2/store/virtual-numbers/conversations', { method: 'POST', headers: { 'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx', 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({ "number_id": "vn_1842", "page": 1, "per_page": 20, "language": "es" }) }).then(r => r.json()).then(console.log); ``` ### Respuesta exitosa ```json { "success": true, "code": "store.virtual_numbers.conversations.ok", "message": "OK", "data": { "status": "available", "items": [] }, "error": [], "time": "2026-07-29T15:30:00-04:00" } ``` ### Errores específicos - HTTP 401 | API key invalida ```json { "success": false, "code": 40101, "message": "Invalid API key." } ``` - HTTP 422 | Parametro requerido ```json { "success": false, "code": 47017, "message": "Required field is missing: client_purchase_id" } ``` - HTTP 502 | Servicio temporalmente no disponible ```json { "success": false, "code": 47020, "message": "The Store service is temporarily unavailable." } ``` ### Notas - No envies userIdentifier: el usuario KeyPay se obtiene del developer autenticado. - Las compras requieren client_purchase_id unico. Si repites la misma solicitud usa exactamente el mismo valor. - El catalogo determina los identificadores, montos y campos validos; no construyas offer_id, service_id ni e164 manualmente. - La API puede devolver pending, processing, completed, failed o refunded segun el producto. --- ## Endpoint: POST /v2/store/virtual-numbers/mark-read ID: store-v2-virtual-numbers-mark-read ACTION: Marcar mensajes leídos METHOD: POST PATH: /v2/store/virtual-numbers/mark-read URL: https://api.innovapp-soft.com/v2/store/virtual-numbers/mark-read AUTH: Bearer API Key DESCRIPTION: Números virtuales: Marca como leidos los mensajes de un numero virtual. ### Headers - Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx - Accept: application/json - Content-Type: application/json ### Body parameters - number_id | required=Depende | type=string | description=Identificador del numero virtual alquilado. | example=vn_1842 - message_id | required=No | type=integer | description=Mensaje hasta el cual se marcara como leido. | example=509 - language | required=No | type=string | description=Idioma de la respuesta: es o en. | example=es ### cURL ```bash curl -X POST 'https://api.innovapp-soft.com/v2/store/virtual-numbers/mark-read' \ -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -d '{"number_id":"vn_1842","message_id":509,"language":"es"}' ``` ### Ejemplo de código ```text fetch('https://api.innovapp-soft.com/v2/store/virtual-numbers/mark-read', { method: 'POST', headers: { 'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx', 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({ "number_id": "vn_1842", "message_id": 509, "language": "es" }) }).then(r => r.json()).then(console.log); ``` ### Respuesta exitosa ```json { "success": true, "code": "store.virtual_numbers.mark_read.ok", "message": "OK", "data": { "status": "available", "items": [] }, "error": [], "time": "2026-07-29T15:30:00-04:00" } ``` ### Errores específicos - HTTP 401 | API key invalida ```json { "success": false, "code": 40101, "message": "Invalid API key." } ``` - HTTP 422 | Parametro requerido ```json { "success": false, "code": 47017, "message": "Required field is missing: client_purchase_id" } ``` - HTTP 502 | Servicio temporalmente no disponible ```json { "success": false, "code": 47020, "message": "The Store service is temporarily unavailable." } ``` ### Notas - No envies userIdentifier: el usuario KeyPay se obtiene del developer autenticado. - Las compras requieren client_purchase_id unico. Si repites la misma solicitud usa exactamente el mismo valor. - El catalogo determina los identificadores, montos y campos validos; no construyas offer_id, service_id ni e164 manualmente. - La API puede devolver pending, processing, completed, failed o refunded segun el producto. --- ## Endpoint: POST /v2/store/virtual-numbers/auto-renew ID: store-v2-virtual-numbers-auto-renew ACTION: Configurar renovación METHOD: POST PATH: /v2/store/virtual-numbers/auto-renew URL: https://api.innovapp-soft.com/v2/store/virtual-numbers/auto-renew AUTH: Bearer API Key DESCRIPTION: Números virtuales: Activa o desactiva la renovacion automatica de un numero virtual alquilado. Al desactivarla, el numero permanece activo hasta su vencimiento. ### Headers - Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx - Accept: application/json - Content-Type: application/json ### Body parameters - number_id | required=Depende | type=string | description=Identificador del numero virtual alquilado. | example=vn_1842 - auto_renew | required=Si | type=boolean | description=Usa true para activar la renovacion automatica o false para desactivarla. | example=1 - client_request_id | required=No | type=string | description=Identificador opcional de la solicitud generado por tu sistema. | example=renew-2026-000184 - language | required=No | type=string | description=Idioma de la respuesta: es o en. | example=es ### cURL ```bash curl -X POST 'https://api.innovapp-soft.com/v2/store/virtual-numbers/auto-renew' \ -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -d '{"number_id":"vn_1842","auto_renew":true,"client_request_id":"renew-2026-000184","language":"es"}' ``` ### Ejemplo de código ```text fetch('https://api.innovapp-soft.com/v2/store/virtual-numbers/auto-renew', { method: 'POST', headers: { 'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx', 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({ "number_id": "vn_1842", "auto_renew": true, "client_request_id": "renew-2026-000184", "language": "es" }) }).then(r => r.json()).then(console.log); ``` ### Respuesta exitosa ```json { "success": true, "code": "store.virtual_numbers.auto_renew.ok", "message": "OK", "data": { "status": "available", "items": [] }, "error": [], "time": "2026-07-29T15:30:00-04:00" } ``` ### Errores específicos - HTTP 401 | API key invalida ```json { "success": false, "code": 40101, "message": "Invalid API key." } ``` - HTTP 422 | Parametro requerido ```json { "success": false, "code": 47017, "message": "Required field is missing: client_purchase_id" } ``` - HTTP 502 | Servicio temporalmente no disponible ```json { "success": false, "code": 47020, "message": "The Store service is temporarily unavailable." } ``` ### Notas - No envies userIdentifier: el usuario KeyPay se obtiene del developer autenticado. - Las compras requieren client_purchase_id unico. Si repites la misma solicitud usa exactamente el mismo valor. - El catalogo determina los identificadores, montos y campos validos; no construyas offer_id, service_id ni e164 manualmente. - La API puede devolver pending, processing, completed, failed o refunded segun el producto. --- # Grupo: Finance V2 · Depositos cripto Flujo: consulta monedas, crea el deposito, muestra wallet/memo y verifica el estado por ID. ## Endpoint: POST /v2/deposits/crypto/methods ID: deposits-crypto-methods ACTION: Listar monedas de deposito METHOD: POST PATH: /v2/deposits/crypto/methods URL: https://api.innovapp-soft.com/v2/deposits/crypto/methods AUTH: Bearer API Key DESCRIPTION: Listar monedas de deposito. ### Headers - Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx - Accept: application/json - Content-Type: application/json ### Body parameters - language | required=No | type=string | description=Idioma de la respuesta: es o en. | example=es ### cURL ```bash curl -X POST 'https://api.innovapp-soft.com/v2/deposits/crypto/methods' \ -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \ -H 'Content-Type: application/json' \ -d '{ "language": "es" }' ``` ### Ejemplo de código ```text fetch('https://api.innovapp-soft.com/v2/deposits/crypto/methods', { method: 'POST', headers: { 'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx', 'Content-Type': 'application/json' }, body: JSON.stringify({"language":"es"}) }).then(r => r.json()).then(console.log); ``` ### Respuesta exitosa ```json { "success": true, "code": "deposits.crypto.methods.ok", "message": "OK", "data": { "catalog": [ { "name": "Criptomonedas", "methods": [ { "tick": "USDT", "min_amount": 20, "max_amount": "1000000.000" } ] } ] }, "error": [], "time": "2026-07-31T10:00:00-04:00" } ``` ### Errores específicos - HTTP 401 | API key invalida ```json { "success": false, "code": 10023, "message": "Unauthorized." } ``` - HTTP 422 | Datos invalidos ```json { "success": false, "code": 48007, "message": "The amount is invalid." } ``` - HTTP 503 | Servicio no disponible ```json { "success": false, "code": 48012, "message": "Finance API V2 is not ready. Apply the finance migration first." } ``` ### Notas - No envies userIdentifier: se usa el usuario KeyPay vinculado al developer autenticado. - client_reference es obligatoria al crear y evita duplicar la operacion. Reutilizala solamente para reintentar la misma solicitud. - Guarda siempre el campo data.id. Las consultas get aceptan el ID Developer, no el identificador interno de KeyPay. --- ## Endpoint: POST /v2/deposits/crypto/create ID: deposits-crypto-create ACTION: Crear deposito cripto METHOD: POST PATH: /v2/deposits/crypto/create URL: https://api.innovapp-soft.com/v2/deposits/crypto/create AUTH: Bearer API Key DESCRIPTION: Crear deposito cripto. ### Headers - Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx - Accept: application/json - Content-Type: application/json ### Body parameters - amount | required=Si | type=number | description=Monto solicitado. | example=100.00 - currency | required=Si en deposito | type=string | description=Tick exacto devuelto por el catalogo cripto. | example=USDT - client_reference | required=Si al crear | type=string | description=Referencia idempotente unica generada por tu sistema. | example=finance-2026-000184 - customer_reference | required=No | type=string | description=Identificador interno de tu usuario o cliente. | example=customer-8291 - description | required=No | type=string | description=Descripcion visible para conciliar la operacion. | example=Retiro solicitado por customer-8291 - metadata | required=No | type=object | description=Hasta 20 pares clave/valor para conciliacion. | example={"invoice_id":"INV-184"} - language | required=No | type=string | description=Idioma de la respuesta: es o en. | example=es ### cURL ```bash curl -X POST 'https://api.innovapp-soft.com/v2/deposits/crypto/create' \ -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \ -H 'Content-Type: application/json' \ -d '{ "amount": 100, "currency": "USDT", "client_reference": "deposit-2026-000184", "customer_reference": "customer-8291", "description": "Recarga de saldo", "metadata": { "invoice_id": "INV-184" }, "language": "es" }' ``` ### Ejemplo de código ```text fetch('https://api.innovapp-soft.com/v2/deposits/crypto/create', { method: 'POST', headers: { 'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx', 'Content-Type': 'application/json' }, body: JSON.stringify({"amount":100,"currency":"USDT","client_reference":"deposit-2026-000184","customer_reference":"customer-8291","description":"Recarga de saldo","metadata":{"invoice_id":"INV-184"},"language":"es"}) }).then(r => r.json()).then(console.log); ``` ### Respuesta exitosa ```json { "success": true, "code": "deposits.crypto.create.ok", "message": "OK", "data": { "deposit": { "id": "dep_09f4c71092d30b86e30e6ee284c491dd", "type": "crypto_deposit", "status": "pending", "client_reference": "deposit-2026-000184", "details": { "crypto": { "wallet": "TXxxxxxxxx", "memo": "", "coin_amount": "99.50", "expires_at": "2026-07-31 10:29:00" }, "next_action": "check_crypto" } }, "idempotent_replay": false }, "error": [], "time": "2026-07-31T10:00:00-04:00" } ``` ### Errores específicos - HTTP 401 | API key invalida ```json { "success": false, "code": 10023, "message": "Unauthorized." } ``` - HTTP 422 | Datos invalidos ```json { "success": false, "code": 48007, "message": "The amount is invalid." } ``` - HTTP 503 | Servicio no disponible ```json { "success": false, "code": 48012, "message": "Finance API V2 is not ready. Apply the finance migration first." } ``` ### Notas - No envies userIdentifier: se usa el usuario KeyPay vinculado al developer autenticado. - client_reference es obligatoria al crear y evita duplicar la operacion. Reutilizala solamente para reintentar la misma solicitud. - Guarda siempre el campo data.id. Las consultas get aceptan el ID Developer, no el identificador interno de KeyPay. --- ## Endpoint: POST /v2/deposits/crypto/list ID: deposits-crypto-list ACTION: Listar depositos cripto METHOD: POST PATH: /v2/deposits/crypto/list URL: https://api.innovapp-soft.com/v2/deposits/crypto/list AUTH: Bearer API Key DESCRIPTION: Listar depositos cripto. ### Headers - Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx - Accept: application/json - Content-Type: application/json ### Body parameters - page | required=No | type=integer | description=Pagina del historial. | example=1 - per_page | required=No | type=integer | description=Resultados por pagina, maximo 100. | example=20 - status | required=No | type=string | description=Filtra el historial por estado exacto. | example=completed - client_reference | required=Si al crear | type=string | description=Referencia idempotente unica generada por tu sistema. | example=finance-2026-000184 - customer_reference | required=No | type=string | description=Identificador interno de tu usuario o cliente. | example=customer-8291 - language | required=No | type=string | description=Idioma de la respuesta: es o en. | example=es ### cURL ```bash curl -X POST 'https://api.innovapp-soft.com/v2/deposits/crypto/list' \ -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \ -H 'Content-Type: application/json' \ -d '{ "page": 1, "per_page": 20, "status": "completed", "customer_reference": "customer-8291", "language": "es" }' ``` ### Ejemplo de código ```text fetch('https://api.innovapp-soft.com/v2/deposits/crypto/list', { method: 'POST', headers: { 'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx', 'Content-Type': 'application/json' }, body: JSON.stringify({"page":1,"per_page":20,"status":"completed","customer_reference":"customer-8291","language":"es"}) }).then(r => r.json()).then(console.log); ``` ### Respuesta exitosa ```json { "success": true, "code": "deposits.crypto.list.ok", "message": "OK", "data": { "items": [], "pagination": { "page": 1, "per_page": 20, "total": 0 } }, "error": [], "time": "2026-07-31T10:00:00-04:00" } ``` ### Errores específicos - HTTP 401 | API key invalida ```json { "success": false, "code": 10023, "message": "Unauthorized." } ``` - HTTP 422 | Datos invalidos ```json { "success": false, "code": 48007, "message": "The amount is invalid." } ``` - HTTP 503 | Servicio no disponible ```json { "success": false, "code": 48012, "message": "Finance API V2 is not ready. Apply the finance migration first." } ``` ### Notas - No envies userIdentifier: se usa el usuario KeyPay vinculado al developer autenticado. - client_reference es obligatoria al crear y evita duplicar la operacion. Reutilizala solamente para reintentar la misma solicitud. - Guarda siempre el campo data.id. Las consultas get aceptan el ID Developer, no el identificador interno de KeyPay. --- ## Endpoint: POST /v2/deposits/crypto/get ID: deposits-crypto-get ACTION: Consultar deposito y verificar estado METHOD: POST PATH: /v2/deposits/crypto/get URL: https://api.innovapp-soft.com/v2/deposits/crypto/get AUTH: Bearer API Key DESCRIPTION: Consultar deposito y verificar estado. ### Headers - Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx - Accept: application/json - Content-Type: application/json ### Body parameters - id | required=Si en get | type=string | description=ID publico Developer devuelto al crear. | example=dep_09f4c71092d30b86e30e6ee284c491dd - language | required=No | type=string | description=Idioma de la respuesta: es o en. | example=es ### cURL ```bash curl -X POST 'https://api.innovapp-soft.com/v2/deposits/crypto/get' \ -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \ -H 'Content-Type: application/json' \ -d '{ "id": "dep_09f4c71092d30b86e30e6ee284c491dd", "language": "es" }' ``` ### Ejemplo de código ```text fetch('https://api.innovapp-soft.com/v2/deposits/crypto/get', { method: 'POST', headers: { 'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx', 'Content-Type': 'application/json' }, body: JSON.stringify({"id":"dep_09f4c71092d30b86e30e6ee284c491dd","language":"es"}) }).then(r => r.json()).then(console.log); ``` ### Respuesta exitosa ```json { "success": true, "code": "deposits.crypto.get.ok", "message": "OK", "data": { "deposit": { "id": "dep_09f4c71092d30b86e30e6ee284c491dd", "status": "completed", "client_reference": "deposit-2026-000184" } }, "error": [], "time": "2026-07-31T10:00:00-04:00" } ``` ### Errores específicos - HTTP 401 | API key invalida ```json { "success": false, "code": 10023, "message": "Unauthorized." } ``` - HTTP 422 | Datos invalidos ```json { "success": false, "code": 48007, "message": "The amount is invalid." } ``` - HTTP 503 | Servicio no disponible ```json { "success": false, "code": 48012, "message": "Finance API V2 is not ready. Apply the finance migration first." } ``` ### Notas - No envies userIdentifier: se usa el usuario KeyPay vinculado al developer autenticado. - client_reference es obligatoria al crear y evita duplicar la operacion. Reutilizala solamente para reintentar la misma solicitud. - Guarda siempre el campo data.id. Las consultas get aceptan el ID Developer, no el identificador interno de KeyPay. --- # Grupo: Finance V2 · Retiros Flujo: lista metodos, consulta los campos del metodo elegido, calcula preview, crea con referencia unica y consulta historial o estado. ## Endpoint: POST /v2/withdrawals/methods ID: withdrawals-methods ACTION: Listar metodos de retiro METHOD: POST PATH: /v2/withdrawals/methods URL: https://api.innovapp-soft.com/v2/withdrawals/methods AUTH: Bearer API Key DESCRIPTION: Listar metodos de retiro. ### Headers - Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx - Accept: application/json - Content-Type: application/json ### Body parameters - language | required=No | type=string | description=Idioma de la respuesta: es o en. | example=es ### cURL ```bash curl -X POST 'https://api.innovapp-soft.com/v2/withdrawals/methods' \ -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \ -H 'Content-Type: application/json' \ -d '{ "language": "es" }' ``` ### Ejemplo de código ```text fetch('https://api.innovapp-soft.com/v2/withdrawals/methods', { method: 'POST', headers: { 'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx', 'Content-Type': 'application/json' }, body: JSON.stringify({"language":"es"}) }).then(r => r.json()).then(console.log); ``` ### Respuesta exitosa ```json { "success": true, "code": "withdrawals.methods.ok", "message": "OK", "data": { "groups": [ { "name": "Criptomonedas", "methods": [ { "tick": "TRX", "min_amount": "5.000", "max_amount": "5000.000" } ] } ] }, "error": [], "time": "2026-07-31T10:00:00-04:00" } ``` ### Errores específicos - HTTP 401 | API key invalida ```json { "success": false, "code": 10023, "message": "Unauthorized." } ``` - HTTP 422 | Datos invalidos ```json { "success": false, "code": 48007, "message": "The amount is invalid." } ``` - HTTP 503 | Servicio no disponible ```json { "success": false, "code": 48012, "message": "Finance API V2 is not ready. Apply the finance migration first." } ``` ### Notas - No envies userIdentifier: se usa el usuario KeyPay vinculado al developer autenticado. - client_reference es obligatoria al crear y evita duplicar la operacion. Reutilizala solamente para reintentar la misma solicitud. - Guarda siempre el campo data.id. Las consultas get aceptan el ID Developer, no el identificador interno de KeyPay. --- ## Endpoint: POST /v2/withdrawals/method ID: withdrawals-method ACTION: Consultar campos del metodo METHOD: POST PATH: /v2/withdrawals/method URL: https://api.innovapp-soft.com/v2/withdrawals/method AUTH: Bearer API Key DESCRIPTION: Consultar campos del metodo. ### Headers - Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx - Accept: application/json - Content-Type: application/json ### Body parameters - tick | required=Si en retiro | type=string | description=Tick exacto devuelto por methods. | example=TRX - language | required=No | type=string | description=Idioma de la respuesta: es o en. | example=es ### cURL ```bash curl -X POST 'https://api.innovapp-soft.com/v2/withdrawals/method' \ -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \ -H 'Content-Type: application/json' \ -d '{ "tick": "TRX", "language": "es" }' ``` ### Ejemplo de código ```text fetch('https://api.innovapp-soft.com/v2/withdrawals/method', { method: 'POST', headers: { 'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx', 'Content-Type': 'application/json' }, body: JSON.stringify({"tick":"TRX","language":"es"}) }).then(r => r.json()).then(console.log); ``` ### Respuesta exitosa ```json { "success": true, "code": "withdrawals.method.ok", "message": "OK", "data": { "membership_tier": "gold", "method": { "tick": "TRX", "name": "TRX", "destination": { "label": "Wallet", "fields": [ { "key": "Wallet", "label": "Wallet", "type": "text", "required": true } ] } } }, "error": [], "time": "2026-07-31T10:00:00-04:00" } ``` ### Errores específicos - HTTP 401 | API key invalida ```json { "success": false, "code": 10023, "message": "Unauthorized." } ``` - HTTP 422 | Datos invalidos ```json { "success": false, "code": 48007, "message": "The amount is invalid." } ``` - HTTP 503 | Servicio no disponible ```json { "success": false, "code": 48012, "message": "Finance API V2 is not ready. Apply the finance migration first." } ``` ### Notas - No envies userIdentifier: se usa el usuario KeyPay vinculado al developer autenticado. - client_reference es obligatoria al crear y evita duplicar la operacion. Reutilizala solamente para reintentar la misma solicitud. - Guarda siempre el campo data.id. Las consultas get aceptan el ID Developer, no el identificador interno de KeyPay. --- ## Endpoint: POST /v2/withdrawals/preview ID: withdrawals-preview ACTION: Calcular retiro METHOD: POST PATH: /v2/withdrawals/preview URL: https://api.innovapp-soft.com/v2/withdrawals/preview AUTH: Bearer API Key DESCRIPTION: Calcular retiro. ### Headers - Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx - Accept: application/json - Content-Type: application/json ### Body parameters - tick | required=Si en retiro | type=string | description=Tick exacto devuelto por methods. | example=TRX - amount | required=Si | type=number | description=Monto solicitado. | example=100.00 - language | required=No | type=string | description=Idioma de la respuesta: es o en. | example=es ### cURL ```bash curl -X POST 'https://api.innovapp-soft.com/v2/withdrawals/preview' \ -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \ -H 'Content-Type: application/json' \ -d '{ "tick": "TRX", "amount": 100, "language": "es" }' ``` ### Ejemplo de código ```text fetch('https://api.innovapp-soft.com/v2/withdrawals/preview', { method: 'POST', headers: { 'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx', 'Content-Type': 'application/json' }, body: JSON.stringify({"tick":"TRX","amount":100,"language":"es"}) }).then(r => r.json()).then(console.log); ``` ### Respuesta exitosa ```json { "success": true, "code": "withdrawals.preview.ok", "message": "OK", "data": { "amount_requested": "100.000", "system_fee_percent": "1.0000", "amount_after_system_fee": "99.000", "amount_to_send_usd": "97.218" }, "error": [], "time": "2026-07-31T10:00:00-04:00" } ``` ### Errores específicos - HTTP 401 | API key invalida ```json { "success": false, "code": 10023, "message": "Unauthorized." } ``` - HTTP 422 | Datos invalidos ```json { "success": false, "code": 48007, "message": "The amount is invalid." } ``` - HTTP 503 | Servicio no disponible ```json { "success": false, "code": 48012, "message": "Finance API V2 is not ready. Apply the finance migration first." } ``` ### Notas - No envies userIdentifier: se usa el usuario KeyPay vinculado al developer autenticado. - client_reference es obligatoria al crear y evita duplicar la operacion. Reutilizala solamente para reintentar la misma solicitud. - Guarda siempre el campo data.id. Las consultas get aceptan el ID Developer, no el identificador interno de KeyPay. --- ## Endpoint: POST /v2/withdrawals/create ID: withdrawals-create ACTION: Crear retiro METHOD: POST PATH: /v2/withdrawals/create URL: https://api.innovapp-soft.com/v2/withdrawals/create AUTH: Bearer API Key DESCRIPTION: Crear retiro. ### Headers - Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx - Accept: application/json - Content-Type: application/json ### Body parameters - tick | required=Si en retiro | type=string | description=Tick exacto devuelto por methods. | example=TRX - amount | required=Si | type=number | description=Monto solicitado. | example=100.00 - destination | required=Si en retiro | type=object | description=Campos exactos solicitados por working_data. | example={"Wallet":"TXxxxxxxxx"} - client_reference | required=Si al crear | type=string | description=Referencia idempotente unica generada por tu sistema. | example=finance-2026-000184 - customer_reference | required=No | type=string | description=Identificador interno de tu usuario o cliente. | example=customer-8291 - description | required=No | type=string | description=Descripcion visible para conciliar la operacion. | example=Retiro solicitado por customer-8291 - metadata | required=No | type=object | description=Hasta 20 pares clave/valor para conciliacion. | example={"invoice_id":"INV-184"} - pingpass | required=Depende | type=string | description=Contrasena segura si el usuario tiene este 2FA activo. | example=****** - pingemail | required=Depende | type=string | description=Codigo enviado por correo si esta activo. | example=123456 - pingtelegram | required=Depende | type=string | description=Codigo enviado por Telegram si esta activo. | example=123456 - pinggoogle | required=Depende | type=string | description=Codigo de Google Authenticator si esta activo. | example=123456 - language | required=No | type=string | description=Idioma de la respuesta: es o en. | example=es ### cURL ```bash curl -X POST 'https://api.innovapp-soft.com/v2/withdrawals/create' \ -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \ -H 'Content-Type: application/json' \ -d '{ "tick": "TRX", "amount": 100, "destination": { "Wallet": "TXxxxxxxxx" }, "client_reference": "withdraw-2026-000184", "customer_reference": "customer-8291", "description": "Retiro semanal", "metadata": { "invoice_id": "INV-184" }, "language": "es" }' ``` ### Ejemplo de código ```text fetch('https://api.innovapp-soft.com/v2/withdrawals/create', { method: 'POST', headers: { 'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx', 'Content-Type': 'application/json' }, body: JSON.stringify({"tick":"TRX","amount":100,"destination":{"Wallet":"TXxxxxxxxx"},"client_reference":"withdraw-2026-000184","customer_reference":"customer-8291","description":"Retiro semanal","metadata":{"invoice_id":"INV-184"},"language":"es"}) }).then(r => r.json()).then(console.log); ``` ### Respuesta exitosa ```json { "success": true, "code": "withdrawals.create.ok", "message": "OK", "data": { "withdrawal": { "id": "wd_09f4c71092d30b86e30e6ee284c491dd", "type": "withdrawal", "status": "processing", "client_reference": "withdraw-2026-000184" }, "idempotent_replay": false }, "error": [], "time": "2026-07-31T10:00:00-04:00" } ``` ### Errores específicos - HTTP 401 | API key invalida ```json { "success": false, "code": 10023, "message": "Unauthorized." } ``` - HTTP 422 | Datos invalidos ```json { "success": false, "code": 48007, "message": "The amount is invalid." } ``` - HTTP 503 | Servicio no disponible ```json { "success": false, "code": 48012, "message": "Finance API V2 is not ready. Apply the finance migration first." } ``` ### Notas - No envies userIdentifier: se usa el usuario KeyPay vinculado al developer autenticado. - client_reference es obligatoria al crear y evita duplicar la operacion. Reutilizala solamente para reintentar la misma solicitud. - Guarda siempre el campo data.id. Las consultas get aceptan el ID Developer, no el identificador interno de KeyPay. --- ## Endpoint: POST /v2/withdrawals/list ID: withdrawals-list ACTION: Listar retiros METHOD: POST PATH: /v2/withdrawals/list URL: https://api.innovapp-soft.com/v2/withdrawals/list AUTH: Bearer API Key DESCRIPTION: Listar retiros. ### Headers - Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx - Accept: application/json - Content-Type: application/json ### Body parameters - page | required=No | type=integer | description=Pagina del historial. | example=1 - per_page | required=No | type=integer | description=Resultados por pagina, maximo 100. | example=20 - status | required=No | type=string | description=Filtra el historial por estado exacto. | example=completed - client_reference | required=Si al crear | type=string | description=Referencia idempotente unica generada por tu sistema. | example=finance-2026-000184 - customer_reference | required=No | type=string | description=Identificador interno de tu usuario o cliente. | example=customer-8291 - language | required=No | type=string | description=Idioma de la respuesta: es o en. | example=es ### cURL ```bash curl -X POST 'https://api.innovapp-soft.com/v2/withdrawals/list' \ -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \ -H 'Content-Type: application/json' \ -d '{ "page": 1, "per_page": 20, "status": "completed", "customer_reference": "customer-8291", "language": "es" }' ``` ### Ejemplo de código ```text fetch('https://api.innovapp-soft.com/v2/withdrawals/list', { method: 'POST', headers: { 'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx', 'Content-Type': 'application/json' }, body: JSON.stringify({"page":1,"per_page":20,"status":"completed","customer_reference":"customer-8291","language":"es"}) }).then(r => r.json()).then(console.log); ``` ### Respuesta exitosa ```json { "success": true, "code": "withdrawals.list.ok", "message": "OK", "data": { "items": [], "pagination": { "page": 1, "per_page": 20, "total": 0 } }, "error": [], "time": "2026-07-31T10:00:00-04:00" } ``` ### Errores específicos - HTTP 401 | API key invalida ```json { "success": false, "code": 10023, "message": "Unauthorized." } ``` - HTTP 422 | Datos invalidos ```json { "success": false, "code": 48007, "message": "The amount is invalid." } ``` - HTTP 503 | Servicio no disponible ```json { "success": false, "code": 48012, "message": "Finance API V2 is not ready. Apply the finance migration first." } ``` ### Notas - No envies userIdentifier: se usa el usuario KeyPay vinculado al developer autenticado. - client_reference es obligatoria al crear y evita duplicar la operacion. Reutilizala solamente para reintentar la misma solicitud. - Guarda siempre el campo data.id. Las consultas get aceptan el ID Developer, no el identificador interno de KeyPay. --- ## Endpoint: POST /v2/withdrawals/get ID: withdrawals-get ACTION: Consultar retiro METHOD: POST PATH: /v2/withdrawals/get URL: https://api.innovapp-soft.com/v2/withdrawals/get AUTH: Bearer API Key DESCRIPTION: Consultar retiro. ### Headers - Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx - Accept: application/json - Content-Type: application/json ### Body parameters - id | required=Si en get | type=string | description=ID publico Developer devuelto al crear. | example=dep_09f4c71092d30b86e30e6ee284c491dd - language | required=No | type=string | description=Idioma de la respuesta: es o en. | example=es ### cURL ```bash curl -X POST 'https://api.innovapp-soft.com/v2/withdrawals/get' \ -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \ -H 'Content-Type: application/json' \ -d '{ "id": "wd_09f4c71092d30b86e30e6ee284c491dd", "language": "es" }' ``` ### Ejemplo de código ```text fetch('https://api.innovapp-soft.com/v2/withdrawals/get', { method: 'POST', headers: { 'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx', 'Content-Type': 'application/json' }, body: JSON.stringify({"id":"wd_09f4c71092d30b86e30e6ee284c491dd","language":"es"}) }).then(r => r.json()).then(console.log); ``` ### Respuesta exitosa ```json { "success": true, "code": "withdrawals.get.ok", "message": "OK", "data": { "withdrawal": { "id": "wd_09f4c71092d30b86e30e6ee284c491dd", "status": "completed", "client_reference": "withdraw-2026-000184" } }, "error": [], "time": "2026-07-31T10:00:00-04:00" } ``` ### Errores específicos - HTTP 401 | API key invalida ```json { "success": false, "code": 10023, "message": "Unauthorized." } ``` - HTTP 422 | Datos invalidos ```json { "success": false, "code": 48007, "message": "The amount is invalid." } ``` - HTTP 503 | Servicio no disponible ```json { "success": false, "code": 48012, "message": "Finance API V2 is not ready. Apply the finance migration first." } ``` ### Notas - No envies userIdentifier: se usa el usuario KeyPay vinculado al developer autenticado. - client_reference es obligatoria al crear y evita duplicar la operacion. Reutilizala solamente para reintentar la misma solicitud. - Guarda siempre el campo data.id. Las consultas get aceptan el ID Developer, no el identificador interno de KeyPay. --- # Grupo: Finance V2 · Webhooks Eventos finales enviados al webhook de la API key que creo la operacion. Si esa key no tiene webhook, se usa el webhook general del developer. ## Endpoint: POST URL de webhook configurada ID: finance-webhooks-final-events ACTION: Eventos finales de depositos y retiros METHOD: POST PATH: URL de webhook configurada URL: Webhook por API key; fallback al webhook general AUTH: Firma HMAC del webhook DESCRIPTION: Se envia un evento cuando una operacion alcanza un estado final. ### Headers - X-InnovappSoft-Event: crypto_deposit.completed - X-InnovappSoft-Delivery: whd_xxxxxxxxxxxxxxxx - X-InnovappSoft-Timestamp: 1785506400 - X-InnovappSoft-Signature: HMAC-SHA256(timestamp.body, secret) ### Body parameters - event | required=Si | type=string | description=Nombre del evento final. | example=withdrawal.completed - sent_at | required=Si | type=datetime | description=Fecha de envio. | example=2026-07-31 10:00:00 - data.id | required=Si | type=string | description=ID publico Developer de la operacion. | example=wd_09f4c71092d30b86e30e6ee284c491dd - data.client_reference | required=Si | type=string | description=Referencia idempotente enviada al crear. | example=withdraw-2026-000184 - data.destination | required=Si | type=object | description=Destino asociado a la operacion. | example={"Wallet":"TXxxxxxxxx"} - data.metadata | required=Si | type=object | description=Metadatos enviados al crear. | example={"invoice_id":"INV-184"} ### cURL ```bash # Tu servidor recibe un POST en la URL configurada. # Verifica X-InnovappSoft-Signature antes de procesar el body. ``` ### Ejemplo de código ```text const expected = hmacSha256(secret, timestamp + '.' + rawBody); if (!timingSafeEqual(signature, expected)) throw new Error('Invalid signature'); ``` ### Respuesta exitosa ```json { "event": "withdrawal.completed", "sent_at": "2026-07-31 10:00:00", "developer": { "id": 4, "name": "Mi empresa", "app_name": "Mi aplicacion" }, "api_key": { "id": 14, "label": "Produccion", "key_prefix": "dk_live_0c953c" }, "data": { "id": "wd_09f4c71092d30b86e30e6ee284c491dd", "type": "withdrawal", "status": "completed", "client_reference": "withdraw-2026-000184", "customer_reference": "customer-8291", "description": "Retiro semanal", "amount": "100.000", "currency": "TRX", "destination": { "Wallet": "TXxxxxxxxx" }, "metadata": { "invoice_id": "INV-184" } } } ``` ### Notas - Eventos: crypto_deposit.completed, crypto_deposit.expired, withdrawal.completed, withdrawal.cancelled y withdrawal.failed_refunded. - La firma es HMAC-SHA256 usando como mensaje timestamp + punto + body JSON crudo y como clave el secret del webhook. - Responde con HTTP 2xx. Las entregas fallidas quedan registradas y pueden reenviarse desde el portal. - Los webhooks pueden entregarse mas de una vez ante fallos de red. Deduplica usando X-InnovappSoft-Delivery o la combinacion event + data.id. --- # Grupo: Rates API V1 (legacy) Version anterior conservada por compatibilidad. Para integraciones nuevas usa GET /v2/rates. ## Endpoint: GET /v1/tasas ID: tasas ACTION: GET /v1/tasas METHOD: GET PATH: /v1/tasas URL: https://api.innovapp-soft.com/v1/tasas AUTH: Bearer API Key DESCRIPTION: Devuelve tasas globales y por pais en secciones normalizadas. Cuba incluye fuentes locales como InnovappSoft KeyCoin, elToque y segmentos BCC cuando hay data. ### Headers - Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx - Accept: application/json ### Query parameters - country | required=No | type=string | description=Codigo del pais o mercado. Ejemplos: GLOBAL, CU, US, MX, CO, BR, VE, UY, PE, GY, CA, CH, EU. | example=CU - scope | required=No | type=string | description=Vista a devolver: global, cuba, country u overview. | example=cuba - section | required=No | type=string | description=Filtra una fuente/seccion especifica. Ejemplos: innovapp, eltoque, bcc_segment1, global, usd_value. | example=innovapp - full | required=No | type=integer | description=Usa 1 para incluir el snapshot normalizado completo ademas de las secciones visibles. | example=1 ### cURL ```bash curl -X GET 'https://api.innovapp-soft.com/v1/tasas?country=CU' \ -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \ -H 'Accept: application/json' ``` ### Ejemplo de código ```text fetch('https://api.innovapp-soft.com/v1/tasas?country=CU', { method: 'GET', headers: { 'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx', 'Accept': 'application/json' } }) .then(r => r.json()) .then(console.log); ``` ### Respuesta exitosa ```json { "success": true, "code": "ok", "message": "OK", "data": { "status": "true", "message": "ok", "version": "1", "scope": "cuba", "base": "USD", "date": "2026-06-22", "updated_at": "2026-06-22 20:30:53", "country": { "code": "CU", "name": "Cuba", "currency": "CUP", "supported": true }, "countries": [ { "code": "GLOBAL", "name": "Global", "currency": "USD", "supported": true }, { "code": "CU", "name": "Cuba", "currency": "CUP", "supported": true }, { "code": "MX", "name": "Mexico", "currency": "MXN", "supported": true } ], "history": { "today": { "date": "2026-06-22", "updated_at": "2026-06-22 20:30:53" }, "yesterday": { "date": "2026-06-21", "updated_at": "2026-06-21 20:30:53" }, "week": { "date": "2026-06-15", "updated_at": "2026-06-15 20:30:53" } }, "sections": [ { "id": "innovapp", "title": "InnovappSoft KeyCoin", "base": "KCOIN", "unit": "currency per 1 KCOIN", "rates": [ { "code": "CUP", "name": "Cuban Peso", "value": 700, "yesterday": 690, "week": 680, "change": 10, "change_week": 20, "source": "cuba_p2p_kcoin", "image_url": "https://innovapp-soft.com/assets/img/tasas/CUP.png", "image_png": "https://innovapp-soft.com/assets/img/tasas/CUP.png", "image_jpg": "https://innovapp-soft.com/assets/img/tasas/CUP.jpg", "image_fallback": "CU" } ] }, { "id": "eltoque", "title": "elToque", "base": "CUP", "unit": "CUP per 1 unit", "rates": [ { "code": "USD", "name": "US Dollar", "value": 695, "yesterday": 690, "week": 680, "change": 5, "change_week": 15, "source": "cu_eltoque_trmi", "image_url": "https://innovapp-soft.com/assets/img/tasas/USD.png", "image_png": "https://innovapp-soft.com/assets/img/tasas/USD.png", "image_jpg": "https://innovapp-soft.com/assets/img/tasas/USD.jpg", "image_fallback": "US" } ] } ] }, "error": [] } ``` ### Errores específicos - HTTP 401 | 401 Unauthorized ```json { "success": false, "code": 10023, "message": "Unauthorized", "data": [], "error": [] } ``` ### Notas - La autenticacion se envia siempre en el header Authorization con formato Bearer. - data.sections es la parte recomendada para UI: cada seccion trae rates con value, yesterday, week, change y change_week. - country=GLOBAL devuelve comparativas globales contra USD. country=CU devuelve las fuentes cubanas. Otros paises devuelven tasas contra la moneda local del pais. - EUR y ECU se normalizan como EUR. - Cada rate incluye image_url, image_png, image_jpg e image_fallback para que la app pueda mostrar iconos de moneda con fallback. --- # Grupo: Store APIs V1 (legacy) Version anterior de recargas moviles. Para integraciones nuevas usa Store APIs V2. ## Endpoint: GET /v1/store/mobile_topup ID: store-mobile-topup-get ACTION: GET /v1/store/mobile_topup METHOD: GET PATH: /v1/store/mobile_topup URL: https://api.innovapp-soft.com/v1/store/mobile_topup AUTH: Bearer API Key DESCRIPTION: Devuelve los planes disponibles para recarga móvil. Permite filtrar opcionalmente por categoría. ### Headers - Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx - Accept: application/json ### Query parameters - category | required=No | type=string | description=Filtra los productos por categoría. | example=Mobile-Top-Up ### cURL ```bash curl -X GET 'https://api.innovapp-soft.com/v1/store/mobile_topup?category=Mobile-Top-Up' \ -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \ -H 'Accept: application/json' ``` ### Ejemplo de código ```text fetch('https://api.innovapp-soft.com/v1/store/mobile_topup?category=Mobile-Top-Up', { method: 'GET', headers: { 'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx', 'Accept': 'application/json' } }) .then(r => r.json()) .then(console.log); ``` ### Respuesta exitosa ```json { "success": true, "code": "ok", "message": "OK", "data": [ { "id": "4f", "category": "Mobile-Top-Up", "title": "SUPER OFERTA 6GB 60 MIN 60 SMS", "details": [ "6GB", "60 MIN", "60 SMS" ], "price": "21.00" }, { "id": "4g", "category": "Mobile-Micro-Top-Up", "title": "Plan de saldo 250 CUP", "details": [ "250 CUP" ], "price": "5.25" } ], "error": [], "time": { "datetime": "2026-04-22T18:10:00-04:00", "date": "2026-04-22", "time": "18:10:00", "timezone": "America/Kentucky/Louisville", "offset": "-04:00", "timestamp": 1776895800 } } ``` ### Errores específicos - HTTP 401 | 401 Unauthorized ```json { "success": false, "code": 10023, "message": "Unauthorized", "data": [], "error": [], "time": { "datetime": "2026-04-22T18:10:00-04:00", "date": "2026-04-22", "time": "18:10:00", "timezone": "America/Kentucky/Louisville", "offset": "-04:00", "timestamp": 1776895800 } } ``` - HTTP 405 | 405 Method Not Allowed ```json { "success": false, "code": 45001, "message": "Method not allowed", "data": [], "error": { "details": "PUT" }, "time": { "datetime": "2026-04-22T18:10:00-04:00", "date": "2026-04-22", "time": "18:10:00", "timezone": "America/Kentucky/Louisville", "offset": "-04:00", "timestamp": 1776895800 } } ``` ### Notas - El parámetro category es opcional. - Valores soportados actualmente para category: Mobile-Top-Up y Mobile-Micro-Top-Up. - El campo details puede traer un array descriptivo del plan. --- ## Endpoint: POST /v1/store/mobile_topup ID: store-mobile-topup-post ACTION: POST /v1/store/mobile_topup METHOD: POST PATH: /v1/store/mobile_topup URL: https://api.innovapp-soft.com/v1/store/mobile_topup AUTH: Bearer API Key DESCRIPTION: Procesa la compra de una recarga móvil a partir del id del plan y el número telefónico. ### Headers - Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx - Accept: application/json - Content-Type: application/json ### Body parameters - id | required=Sí | type=string | description=Identificador del plan, obtenido desde el GET. | example=4f - phone | required=Sí | type=string | description=Número móvil destino a recargar. | example=51234567 ### cURL ```bash curl -X POST 'https://api.innovapp-soft.com/v1/store/mobile_topup' \ -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -d '{"id":"4f","phone":"51234567"}' ``` ### Ejemplo de código ```text fetch('https://api.innovapp-soft.com/v1/store/mobile_topup', { method: 'POST', headers: { 'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx', 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({ id: '4f', phone: '51234567' }) }) .then(r => r.json()) .then(console.log); ``` ### Respuesta exitosa ```json { "success": true, "code": "ok", "message": "Purchase completed successfully.", "data": { "transation_id": "et_153_x9Ab3Kp2", "recharge_status": "Completed" }, "error": [], "time": { "datetime": "2026-04-22T18:14:00-04:00", "date": "2026-04-22", "time": "18:14:00", "timezone": "America/Kentucky/Louisville", "offset": "-04:00", "timestamp": 1776896040 } } ``` ### Errores específicos - HTTP 409 | 409 Operation In Process ```json { "success": false, "code": 46001, "message": "Operation in progress. Please check your history before buying again.", "data": [], "error": [], "time": { "datetime": "2026-04-22T18:14:00-04:00", "date": "2026-04-22", "time": "18:14:00", "timezone": "America/Kentucky/Louisville", "offset": "-04:00", "timestamp": 1776896040 } } ``` - HTTP 422 | 422 Invalid Phone ```json { "success": false, "code": 46009, "message": "The phone number is invalid.", "data": [], "error": [], "time": { "datetime": "2026-04-22T18:14:00-04:00", "date": "2026-04-22", "time": "18:14:00", "timezone": "America/Kentucky/Louisville", "offset": "-04:00", "timestamp": 1776896040 } } ``` - HTTP 409 | 409 Insufficient Credit ```json { "success": false, "code": 46012, "message": "Insufficient credit.", "data": [], "error": [], "time": { "datetime": "2026-04-22T18:14:00-04:00", "date": "2026-04-22", "time": "18:14:00", "timezone": "America/Kentucky/Louisville", "offset": "-04:00", "timestamp": 1776896040 } } ``` ### Notas - El campo id debe ser exactamente el id devuelto por GET /v1/store/mobile_topup. - El campo phone se valida y normaliza antes de enviar la recarga. - El endpoint usa control de concurrencia por lock para evitar compras duplicadas. - Si el débito de crédito ocurre y luego falla la compra, el crédito se revierte. - El estado final devuelto hoy es transation_id + recharge_status. --- # Grupo: Payments APIs Endpoints para crear enlaces de pago y gestionar cobros. ## Endpoint: POST /v1/payment_links ID: payment-links-post ACTION: POST /v1/payment_links METHOD: POST PATH: /v1/payment_links URL: https://api.innovapp-soft.com/v1/payment_links AUTH: Bearer API Key DESCRIPTION: Crea un enlace de pago único para que un usuario realice una transferencia hacia tu cuenta. El sistema genera un payment_id no predecible, guarda la solicitud en estado pending y devuelve la URL pública de pago. ### Headers - Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx - Accept: application/json - Content-Type: application/json ### Body parameters - amount | required=Sí | type=string | description=Monto a cobrar. Acepta hasta 3 decimales. | example=25.00 - currency | required=No | type=string | description=Moneda del cobro. Actualmente soportado: KCOIN. | example=KCOIN - external_reference | required=No | type=string | description=Referencia interna del comercio o sistema externo. | example=ORDER-10045 - title | required=No | type=string | description=Título corto del cobro. | example=Payment request - description | required=No | type=string | description=Descripción corta del cobro. | example=Recharge order - message | required=No | type=string | description=Mensaje opcional asociado al enlace. | example=Complete the payment from your KeyCard app - expires_in_minutes | required=No | type=integer | description=Tiempo de expiración del enlace en minutos. | example=60 - metadata | required=No | type=object | description=Objeto JSON libre para información auxiliar del comercio. | example={"customer_id":"CUST-88"} ### cURL ```bash curl -X POST 'https://api.innovapp-soft.com/v1/payment_links' \ -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -d '{"amount":"25.00","currency":"KCOIN","external_reference":"ORDER-10045","title":"Payment request","description":"Recharge order","message":"Complete the payment from your KeyCard app","expires_in_minutes":60,"metadata":{"customer_id":"CUST-88"}}' ``` ### Ejemplo de código ```text fetch('https://api.innovapp-soft.com/v1/payment_links', { method: 'POST', headers: { 'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx', 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({ amount: '25.00', currency: 'KCOIN', external_reference: 'ORDER-10045', title: 'Payment request', description: 'Recharge order', message: 'Complete the payment from your KeyCard app', expires_in_minutes: 60, metadata: { customer_id: 'CUST-88' } }) }) .then(r => r.json()) .then(console.log); ``` ### Respuesta exitosa ```json { "success": true, "code": "ok", "message": "Payment link created successfully.", "data": { "payment_id": "6d4f21d15e7bc3d9276ea4f0d89ab21c", "payment_url": "https://keypay.innovapp-soft.com/pay/6d4f21d15e7bc3d9276ea4f0d89ab21c", "status": "pending", "amount": "25.000", "currency": "KCOIN", "external_reference": "ORDER-10045", "title": "Payment request", "description": "Recharge order", "message": "Complete the payment from your KeyCard app", "expires_at": "2026-06-02 19:30:00", "created_at": "2026-06-02 18:30:00" }, "error": [], "time": { "datetime": "2026-06-02T18:30:00-04:00", "date": "2026-06-02", "time": "18:30:00", "timezone": "America/Kentucky/Louisville", "offset": "-04:00", "timestamp": 1770100200 } } ``` ### Errores específicos - HTTP 400 | 400 Amount Required ```json { "success": false, "code": 47001, "message": "Amount is required.", "data": [], "error": [], "time": { "datetime": "2026-06-02T18:30:00-04:00", "date": "2026-06-02", "time": "18:30:00", "timezone": "America/Kentucky/Louisville", "offset": "-04:00", "timestamp": 1770100200 } } ``` - HTTP 422 | 422 Invalid Amount ```json { "success": false, "code": 47002, "message": "The amount is invalid.", "data": [], "error": [], "time": { "datetime": "2026-06-02T18:30:00-04:00", "date": "2026-06-02", "time": "18:30:00", "timezone": "America/Kentucky/Louisville", "offset": "-04:00", "timestamp": 1770100200 } } ``` - HTTP 422 | 422 Invalid Metadata ```json { "success": false, "code": 47009, "message": "The metadata is invalid.", "data": [], "error": [], "time": { "datetime": "2026-06-02T18:30:00-04:00", "date": "2026-06-02", "time": "18:30:00", "timezone": "America/Kentucky/Louisville", "offset": "-04:00", "timestamp": 1770100200 } } ``` - HTTP 405 | 405 Method Not Allowed ```json { "success": false, "code": 47012, "message": "Method not allowed", "data": [], "error": { "details": "GET" }, "time": { "datetime": "2026-06-02T18:30:00-04:00", "date": "2026-06-02", "time": "18:30:00", "timezone": "America/Kentucky/Louisville", "offset": "-04:00", "timestamp": 1770100200 } } ``` ### Notas - El campo amount es obligatorio y acepta hasta 3 decimales. - El campo currency hoy soporta KCOIN. - El campo payment_id es generado por el sistema y no es predecible. - El enlace público devuelto en payment_url debe abrirse desde la app o el flujo externo de pago. - El cobro se crea inicialmente en estado pending. - El usuario paga el monto del enlace. La liquidación al developer puede descontar el fee de payment link configurado por la plataforma. - Ejemplo: si el enlace es de 100.000 KCOIN y el fee configurado es 2%, el usuario paga 100.000 KCOIN y el developer recibe 98.000 KCOIN. --- ## Endpoint: GET /v1/transactions ID: transactions-get ACTION: GET /v1/transactions METHOD: GET PATH: /v1/transactions URL: https://api.innovapp-soft.com/v1/transactions AUTH: Bearer API Key DESCRIPTION: Devuelve las últimas 10 transacciones creadas por el developer autenticado. ### Headers - Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx - Accept: application/json ### cURL ```bash curl -X GET 'https://api.innovapp-soft.com/v1/transactions' \ -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \ -H 'Accept: application/json' ``` ### Ejemplo de código ```text fetch('https://api.innovapp-soft.com/v1/transactions', { method: 'GET', headers: { 'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx', 'Accept': 'application/json' } }) .then(r => r.json()) .then(console.log); ``` ### Respuesta exitosa ```json { "success": true, "code": "ok", "message": "OK", "data": [ { "payment_id": "6d4f21d15e7bc3d9276ea4f0d89ab21c", "status": "pending", "amount": "25.000", "currency": "KCOIN", "external_reference": "ORDER-10045", "title": "Payment request", "description": "Recharge order", "message": "Complete the payment from your KeyCard app", "paid_transaction_id": null, "paid_at": null, "expires_at": "2026-06-02 19:30:00", "created_at": "2026-06-02 18:30:00", "updated_at": "2026-06-02 18:30:00" }, { "payment_id": "9f61ad13db19e6d2a80b8b6248ca5f88", "status": "paid", "amount": "14.500", "currency": "KCOIN", "external_reference": "ORDER-10046", "title": "Service payment", "description": "Premium service", "message": "Please complete your payment", "paid_transaction_id": "trx_4K91AB2", "paid_at": "2026-06-02 18:42:11", "expires_at": "2026-06-02 19:10:00", "created_at": "2026-06-02 18:10:00", "updated_at": "2026-06-02 18:42:11" } ], "error": [], "time": { "datetime": "2026-06-02T18:45:00-04:00", "date": "2026-06-02", "time": "18:45:00", "timezone": "America/Kentucky/Louisville", "offset": "-04:00", "timestamp": 1770101100 } } ``` ### Errores específicos - HTTP 401 | 401 Unauthorized ```json { "success": false, "code": 47110, "message": "Unauthorized", "data": [], "error": [], "time": { "datetime": "2026-06-02T18:45:00-04:00", "date": "2026-06-02", "time": "18:45:00", "timezone": "America/Kentucky/Louisville", "offset": "-04:00", "timestamp": 1770101100 } } ``` - HTTP 405 | 405 Method Not Allowed ```json { "success": false, "code": 47111, "message": "Method not allowed", "data": [], "error": { "details": "POST" }, "time": { "datetime": "2026-06-02T18:45:00-04:00", "date": "2026-06-02", "time": "18:45:00", "timezone": "America/Kentucky/Louisville", "offset": "-04:00", "timestamp": 1770101100 } } ``` ### Notas - Si no se envía un public_id en la ruta, el endpoint devuelve las últimas 10 transacciones del developer autenticado. - La respuesta en data es un array. - Cada elemento representa un payment link creado previamente. --- ## Endpoint: GET /v1/transactions/{public_id} ID: transactions-public-id-get ACTION: GET /v1/transactions/{public_id} METHOD: GET PATH: /v1/transactions/{public_id} URL: https://api.innovapp-soft.com/v1/transactions/{public_id} AUTH: Bearer API Key DESCRIPTION: Devuelve el detalle de una transacción específica usando su payment_id/public_id. ### Headers - Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx - Accept: application/json ### cURL ```bash curl -X GET 'https://api.innovapp-soft.com/v1/transactions/6d4f21d15e7bc3d9276ea4f0d89ab21c' \ -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \ -H 'Accept: application/json' ``` ### Ejemplo de código ```text fetch('https://api.innovapp-soft.com/v1/transactions/6d4f21d15e7bc3d9276ea4f0d89ab21c', { method: 'GET', headers: { 'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx', 'Accept': 'application/json' } }) .then(r => r.json()) .then(console.log); ``` ### Respuesta exitosa ```json { "success": true, "code": "ok", "message": "OK", "data": { "payment_id": "6d4f21d15e7bc3d9276ea4f0d89ab21c", "status": "pending", "amount": "25.000", "currency": "KCOIN", "external_reference": "ORDER-10045", "title": "Payment request", "description": "Recharge order", "message": "Complete the payment from your KeyCard app", "metadata": { "customer_id": "CUST-88" }, "paid_transaction_id": null, "paid_at": null, "expires_at": "2026-06-02 19:30:00", "created_at": "2026-06-02 18:30:00", "updated_at": "2026-06-02 18:30:00" }, "error": [], "time": { "datetime": "2026-06-02T18:45:00-04:00", "date": "2026-06-02", "time": "18:45:00", "timezone": "America/Kentucky/Louisville", "offset": "-04:00", "timestamp": 1770101100 } } ``` ### Errores específicos - HTTP 404 | 404 Transaction Not Found ```json { "success": false, "code": 47103, "message": "The transaction does not exist.", "data": [], "error": [], "time": { "datetime": "2026-06-02T18:45:00-04:00", "date": "2026-06-02", "time": "18:45:00", "timezone": "America/Kentucky/Louisville", "offset": "-04:00", "timestamp": 1770101100 } } ``` - HTTP 422 | 422 Invalid Public ID ```json { "success": false, "code": 47102, "message": "The transaction identifier is invalid.", "data": [], "error": [], "time": { "datetime": "2026-06-02T18:45:00-04:00", "date": "2026-06-02", "time": "18:45:00", "timezone": "America/Kentucky/Louisville", "offset": "-04:00", "timestamp": 1770101100 } } ``` ### Notas - El valor {public_id} debe ser el payment_id generado al crear el payment link. - La respuesta en data es un objeto único. - Solo el developer dueño de la transacción puede consultarla. --- # Grupo: PaymentIntent SDK APIs Endpoints para crear cobros con client_secret y abrir checkout desde SDK iOS/Android. ## Endpoint: POST /v1/payment_intents ID: payment-intents-post ACTION: POST /v1/payment_intents METHOD: POST PATH: /v1/payment_intents URL: https://api.innovapp-soft.com/v1/payment_intents AUTH: Bearer API Key DESCRIPTION: Crea un PaymentIntent para SDK. El backend del developer usa su API key secreta y devuelve client_secret + checkout_url a la app móvil. ### Headers - Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx - Accept: application/json - Content-Type: application/json ### Body parameters - amount | required=Sí | type=string | description=Monto a cobrar. Acepta hasta 3 decimales. | example=10.00 - currency | required=No | type=string | description=Moneda del cobro. Actualmente soportado: KCOIN. | example=KCOIN - external_reference | required=No | type=string | description=Referencia interna del comercio. | example=ORDER-1001 - title | required=No | type=string | description=Título corto del cobro. | example=Premium purchase - return_url | required=No | type=string | description=Deep link o URL de retorno de la app. | example=myapp://keypay-return - platform | required=No | type=string | description=ios, android o web. | example=ios - bundle_id | required=No | type=string | description=Bundle ID iOS. | example=com.example.app - package_name | required=No | type=string | description=Package Android. | example=com.example.app - metadata | required=No | type=object | description=JSON libre para tu orden. | example={"order_id":"1001"} ### cURL ```bash curl -X POST 'https://api.innovapp-soft.com/v1/payment_intents' \ -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -d '{"amount":"10.00","currency":"KCOIN","external_reference":"ORDER-1001","title":"Premium purchase","return_url":"myapp://keypay-return","platform":"ios","bundle_id":"com.example.app","metadata":{"order_id":"1001"}}' ``` ### Ejemplo de código ```text fetch('https://api.innovapp-soft.com/v1/payment_intents', { method: 'POST', headers: { 'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx', 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({ amount: '10.00', currency: 'KCOIN', external_reference: 'ORDER-1001', title: 'Premium purchase', return_url: 'myapp://keypay-return', platform: 'ios', bundle_id: 'com.example.app', metadata: { order_id: '1001' } }) }).then(r => r.json()).then(console.log); ``` ### Respuesta exitosa ```json { "success": true, "code": "ok", "message": "PaymentIntent created successfully.", "data": { "id": "pi_6d4f21d15e7bc3d9276ea4f0d89ab21c", "object": "payment_intent", "status": "requires_payment", "amount": "10.000", "currency": "KCOIN", "client_secret": "kpi_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "checkout_url": "https://keypay.innovapp-soft.com/pay/6d4f21d15e7bc3d9276ea4f0d89ab21c?intent=pi_...", "payment_link_id": "6d4f21d15e7bc3d9276ea4f0d89ab21c", "expires_at": "2026-06-16 19:30:00", "created_at": "2026-06-16 18:30:00" }, "error": [] } ``` ### Notas - Nunca coloques la API key dk_live dentro de iOS o Android. - El backend del developer crea el PaymentIntent y entrega a la app solo client_secret + checkout_url. - En esta versión el PaymentIntent está respaldado por el flujo existente de payment links. - La confirmación final debe hacerse por webhook o consultando GET /v1/payment_intents/{id}. --- ## Endpoint: SDK KeyPayPaymentSDK ID: payment-intents-swiftui-sdk ACTION: SwiftUI SDK METHOD: SDK PATH: KeyPayPaymentSDK URL: https://github.com/innovappsoft/KeyPayPaymentSDK.git AUTH: Developer Backend DESCRIPTION: SDK oficial para integrar PaymentIntent en apps SwiftUI. El developer instala el paquete desde GitHub, configura su backend y usa KeyPayPaymentButton para abrir el sheet de pago listo. ### Headers - Package URL: https://github.com/innovappsoft/KeyPayPaymentSDK.git - Version: v1.0.0 o superior - Import: import KeyPayPaymentSDK ### Body parameters - paymentIntentEndpoint | required=Sí | type=URL | description=Endpoint de tu backend que crea PaymentIntent con dk_live. | example=https://tuapp.com/api/keypay/payment-intents - paymentStatusEndpoint | required=Recomendado | type=URL | description=Endpoint de tu backend que consulta GET /v1/payment_intents/{id}. | example=https://tuapp.com/api/keypay/payment-intents - returnURLScheme | required=Sí | type=string | description=URL Scheme registrado en Xcode para volver a la app. | example=myapp - merchantDisplayName | required=Sí | type=string | description=Nombre visible del comercio dentro del sheet. | example=My App ### cURL ```bash git clone https://github.com/innovappsoft/KeyPayPaymentSDK.git # O en Xcode: # File > Add Package Dependencies > https://github.com/innovappsoft/KeyPayPaymentSDK.git # Version: Up to Next Major desde 1.0.0 ``` ### Ejemplo SwiftUI ```text import SwiftUI import KeyPayPaymentSDK @main struct MyApp: App { init() { KeyPay.configure( paymentIntentEndpoint: URL(string: "https://tuapp.com/api/keypay/payment-intents")!, paymentStatusEndpoint: URL(string: "https://tuapp.com/api/keypay/payment-intents")!, returnURLScheme: "myapp", merchantDisplayName: "My App" ) } var body: some Scene { WindowGroup { ContentView() } } } struct ContentView: View { @State private var status = "" var body: some View { KeyPayPaymentButton( request: KeyPayPaymentRequest( amount: 10, title: "Premium Plan", description: "Monthly subscription", externalReference: "order_1001", metadata: ["order_id": "1001"] ) ) { result in switch result { case .succeeded(let intent): status = "Paid: \(intent.id)" case .pending(let intent): status = "Pending: \(intent.id)" case .cancelled: status = "Cancelled" case .failed(let error): status = error.localizedDescription } } } } ``` ### Respuesta exitosa ```json { "package": "KeyPayPaymentSDK", "github": "https://github.com/innovappsoft/KeyPayPaymentSDK.git", "current_version": "v1.0.0", "product": "KeyPayPaymentSDK", "minimum_ios": "15.0", "main_components": [ "KeyPay.configure", "KeyPayPaymentButton", "KeyPayPaymentSheet", "KeyPayPaymentRequest", "KeyPayPaymentResult" ] } ``` ### Notas - El proyecto del SDK está en GitHub: https://github.com/innovappsoft/KeyPayPaymentSDK.git - Para instalar en Xcode usa File > Add Package Dependencies y pega la URL del repo. - El developer no debe poner dk_live dentro de la app; dk_live vive solo en su backend. - El backend del developer debe exponer POST /payment-intents y GET /payment-intents/{id}. - El SDK incluye UI SwiftUI lista, traducciones EN/ES y sheet de pago tipo plug-and-play. - Para publicar nuevas versiones crea tags semánticos como v1.0.1, v1.1.0 o v2.0.0. --- ## Endpoint: SDK KeyPayPaymentAndroidSDK ID: payment-intents-android-sdk ACTION: Android SDK METHOD: SDK PATH: KeyPayPaymentAndroidSDK URL: https://github.com/innovappsoft/KeyPayPaymentAndroidSDK.git AUTH: Developer Backend DESCRIPTION: SDK oficial para integrar PaymentIntent en apps Android con Kotlin o Java. El developer instala la librería desde GitHub, configura su backend y usa KeyPayCheckoutButton para abrir el checkout nativo listo. ### Headers - Repository URL: https://github.com/innovappsoft/KeyPayPaymentAndroidSDK.git - Version: v1.0.1 o superior - Package: com.innovappsoft.keypay.payment - Main module: keypay-payment-sdk ### Body parameters - paymentIntentEndpoint | required=Sí | type=String | description=Endpoint de tu backend que crea PaymentIntent con dk_live. | example=https://tuapp.com/api/keypay/payment-intents - paymentStatusEndpoint | required=Recomendado | type=String | description=Endpoint de tu backend que consulta GET /v1/payment_intents/{id}. | example=https://tuapp.com/api/keypay/payment-intents - returnUrlScheme | required=Sí | type=String | description=Scheme registrado en AndroidManifest para volver a la app. | example=myapp - merchantDisplayName | required=Sí | type=String | description=Nombre visible del comercio dentro del checkout. | example=My App - package_name | required=Recomendado | type=String | description=Package name Android de la app del developer. | example=com.example.app ### cURL ```bash 1) Instalación recomendada con JitPack settings.gradle.kts: dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() maven { url = uri("https://jitpack.io") } } } gradle/libs.versions.toml: [versions] keypaySdkVersion = "v1.0.1" [libraries] keypay-android-sdk = { module = "com.github.innovappsoft.KeyPayPaymentAndroidSDK:keypay-payment-sdk", version.ref = "keypaySdkVersion" } app/build.gradle.kts: dependencies { implementation(libs.keypay.android.sdk) } Importante: - Usa v1.0.1 o superior. v1.0.0 no se debe usar para Gradle porque fue source-only y no tenía metadata Maven para JitPack. - El módulo que se importa es keypay-payment-sdk. El módulo sample-app es solo una demo. - Si JitPack todavía no terminó de construir el tag, espera unos minutos o usa la opción AAR local. 2) AndroidManifest para recibir el callback El returnUrlScheme configurado en el SDK debe coincidir con android:scheme. Ejemplo: returnUrlScheme = "myapp" usa myapp://keypay-return. 3) Opción de prueba local con AAR En el repo del SDK: ./gradlew :keypay-payment-sdk:assembleRelease Copia: keypay-payment-sdk/build/outputs/aar/keypay-payment-sdk-release.aar a: app/libs/keypay-payment-sdk-release.aar app/build.gradle.kts: dependencies { implementation(files("libs/keypay-payment-sdk-release.aar")) implementation(libs.androidx.appcompat) implementation(libs.material) } Cuando se usa AAR local, Android no descarga dependencias transitivas automáticamente, por eso appcompat y material deben estar en la app. 4) Backend requerido del developer La app nunca debe guardar dk_live. La API key vive en el backend del developer. El backend debe exponer: - POST /payment-intents para crear el PaymentIntent usando dk_live. - GET /payment-intents/{id} para consultar estado y devolverlo a la app. 5) Errores comunes Could not find com.github.innovappsoft.KeyPayPaymentAndroidSDK:keypay-payment-sdk:v1.0.0 Solución: usar v1.0.1 o superior, o probar con AAR local. KeyPayReturnActivity aparece en rojo en Android Studio Solución: la dependencia no está resuelta. Revisa JitPack, Sync Gradle o usa el AAR local. Cannot generate dependency accessors Solución: no dupliques alias en libs.versions.toml. Usa keypaySdkVersion para la versión y keypay-android-sdk para la librería. AndroidX core 1.19 pide compileSdk 37 / AGP 9.1 Solución: baja coreKtx a 1.17.0 o actualiza compileSdk y Android Gradle Plugin. ``` ### Ejemplo Kotlin / Java ```text import com.innovappsoft.keypay.payment.KeyPay import com.innovappsoft.keypay.payment.KeyPayCheckoutButton import com.innovappsoft.keypay.payment.KeyPayConfiguration import com.innovappsoft.keypay.payment.KeyPayPaymentRequest import com.innovappsoft.keypay.payment.KeyPayPaymentResult KeyPay.configure( KeyPayConfiguration( paymentIntentEndpoint = "https://tuapp.com/api/keypay/payment-intents", paymentStatusEndpoint = "https://tuapp.com/api/keypay/payment-intents", returnUrlScheme = "myapp", merchantDisplayName = "My App" ) ) val request = KeyPayPaymentRequest( amount = "10.00", title = "Premium Plan", description = "Monthly subscription", externalReference = "order_1001", metadata = mapOf("order_id" to "1001") ) val button = KeyPayCheckoutButton(this).apply { configure( activity = this@MainActivity, request = request, callback = { result -> when (result.status) { KeyPayPaymentResult.Status.SUCCEEDED -> {} KeyPayPaymentResult.Status.PENDING -> {} KeyPayPaymentResult.Status.CANCELLED -> {} KeyPayPaymentResult.Status.FAILED -> {} } }, title = "Pay with KeyPay" ) } // Java compatible: // KeyPay.configure(new KeyPayConfiguration( // "https://tuapp.com/api/keypay/payment-intents", // "https://tuapp.com/api/keypay/payment-intents", // "myapp", // "My App" // )); // KeyPay.startCheckout(this, request, result -> { }); ``` ### Respuesta exitosa ```json { "package": "KeyPayPaymentAndroidSDK", "github": "https://github.com/innovappsoft/KeyPayPaymentAndroidSDK.git", "current_version": "v1.0.1", "product": "keypay-payment-sdk", "minimum_sdk": "API 24 / Android 7.0", "languages": [ "Kotlin", "Java" ], "modules": [ "keypay-payment-sdk", "sample-app" ], "main_components": [ "KeyPay.configure", "KeyPayCheckoutButton", "KeyPayCheckoutActivity", "KeyPayPaymentRequest", "KeyPayPaymentResult", "KeyPayReturnActivity" ], "manifest_callback": "" } ``` ### Errores específicos - HTTP | dependency_not_found ```json { "code": "dependency_not_found", "message": "Gradle no encuentra com.github.innovappsoft.KeyPayPaymentAndroidSDK:keypay-payment-sdk:v1.0.0.", "fix": "Usa v1.0.1 o superior. v1.0.0 fue source-only y no tenía metadata Maven para JitPack." } ``` - HTTP | return_activity_unresolved ```json { "code": "return_activity_unresolved", "message": "Android Studio muestra KeyPayReturnActivity en rojo.", "fix": "La dependencia no está resuelta. Ejecuta Sync Gradle, revisa JitPack o usa AAR local." } ``` - HTTP | duplicate_version_catalog_alias ```json { "code": "duplicate_version_catalog_alias", "message": "Cannot generate dependency accessors.", "fix": "Evita alias duplicados en libs.versions.toml. Usa keypaySdkVersion para la versión y keypay-android-sdk para la librería." } ``` - HTTP | androidx_core_compile_sdk ```json { "code": "androidx_core_compile_sdk", "message": "AndroidX core 1.19 exige compileSdk 37 o AGP 9.1.", "fix": "Baja coreKtx a 1.17.0 o actualiza compileSdk y Android Gradle Plugin." } ``` ### Notas - El proyecto del SDK Android está en GitHub: https://github.com/innovappsoft/KeyPayPaymentAndroidSDK.git - Usa v1.0.1 o superior para JitPack. v1.0.0 fue una versión source-only y no tenía metadata Maven para Gradle. - El módulo real de la librería es keypay-payment-sdk; sample-app es solo una app de ejemplo. - Si Android Studio marca KeyPayReturnActivity en rojo, la dependencia no está resuelta: revisa JitPack, Sync Gradle o usa AAR local. - Si Gradle dice Could not find com.github..., usa v1.0.1 o genera/copias el AAR local. - Si Gradle dice Cannot generate dependency accessors, evita alias duplicados: usa keypaySdkVersion para la versión y keypay-android-sdk para la librería. - Si AndroidX core 1.19 exige compileSdk 37 / AGP 9.1, baja coreKtx a 1.17.0 o actualiza AGP/compileSdk. - El SDK incluye UI Android nativa, traducciones EN/ES y botón plug-and-play KeyPayCheckoutButton. - Compatible con Kotlin y Java mediante API pública Java-friendly. - El developer debe registrar el returnUrlScheme en AndroidManifest usando KeyPayReturnActivity. - El developer no debe poner dk_live dentro de la app; dk_live vive solo en su backend. - El backend del developer debe exponer POST /payment-intents y GET /payment-intents/{id}. - Para publicar nuevas versiones crea tags semánticos como v1.0.2, v1.1.0 o v2.0.0. --- ## Endpoint: GET /v1/payment_intents/{id} ID: payment-intents-get ACTION: GET /v1/payment_intents/{id} METHOD: GET PATH: /v1/payment_intents/{id} URL: https://api.innovapp-soft.com/v1/payment_intents/{id} AUTH: Bearer API Key DESCRIPTION: Consulta el estado de un PaymentIntent creado por tu cuenta. ### Headers - Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx - Accept: application/json ### cURL ```bash curl -X GET 'https://api.innovapp-soft.com/v1/payment_intents/pi_6d4f21d15e7bc3d9276ea4f0d89ab21c' \ -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \ -H 'Accept: application/json' ``` ### Ejemplo de código ```text fetch('https://api.innovapp-soft.com/v1/payment_intents/pi_6d4f21d15e7bc3d9276ea4f0d89ab21c', { headers: { 'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx', 'Accept': 'application/json' } }).then(r => r.json()).then(console.log); ``` ### Respuesta exitosa ```json { "success": true, "code": "ok", "message": "OK", "data": { "id": "pi_6d4f21d15e7bc3d9276ea4f0d89ab21c", "object": "payment_intent", "status": "succeeded", "amount": "10.000", "currency": "KCOIN", "paid_transaction_id": "trx_4K91AB2", "paid_at": "2026-06-16 18:42:11" }, "error": [] } ``` ### Notas - Este endpoint es para backend. No lo llames desde la app móvil con dk_live. - El SDK móvil debe devolver control a tu app; tu backend confirma el estado real. ---