// guía de integración

Documentación para integrar KeyPay

Consulta endpoints, autenticación, ejemplos de request/response y errores comunes para preparar tu integración.

Solicitar acceso →
BASE URL
api.innovapp-soft.com
AUTH
Bearer Key
FORMAT
JSON
VERSION
v2 + legacy
Inicio rápido
1
Obtén tu API key

Solicita acceso y usa la credencial activa de tu portal.

2
Autentica la petición

Envía Authorization: Bearer {API_KEY}.

3
Procesa la respuesta

Comprueba el estado HTTP y los campos success, code, data y error.

Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Referencia completa en texto plano

El mismo contenido del portal, preparado para asistentes de IA, automatizaciones y lectura sin interfaz gráfica.

Estados HTTP comunes

200 / 201Solicitud procesada o creada
400 / 422Datos inválidos
401 / 403Autenticación o permiso
409Conflicto de operación
429Límite de peticiones
500 / 502 / 503Error o servicio no disponible

Cada endpoint muestra debajo solamente sus errores y notas específicas.

Vista de endpoints
Rates APIs V2

Tasas normalizadas para aplicaciones y servicios externos. Solo lectura, sin coste y sin movimiento de saldo.

1 GET GET /v2/rates
Devuelve tasas V2 globales o por pais con secciones normalizadas, variacion y recursos de imagen.

Devuelve tasas V2 globales o por pais con secciones normalizadas, variacion y recursos de imagen.

Endpoint
https://api.innovapp-soft.com/v2/rates
Auth
Bearer API Key
Method
GET

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json

Query params

Nombre Requerido Tipo Descripción Ejemplo
country No string country=GLOBAL devuelve comparativas globales contra USD. country=CU devuelve las fuentes cubanas. Otros paises devuelven tasas contra la moneda local del pais. CU
scope No string Fuerza la vista devuelta: global, cuba, country, all u overview. Alias aceptado: view. Si se omite se deduce de country. cuba
section No string Filtra una fuente/seccion especifica. Ejemplos: innovapp, eltoque, bcc_segment1, global, usd_value. eltoque
full No string Usa 1 para incluir el snapshot normalizado completo ademas de las secciones visibles. 1

Ejemplo cURL

curl -X GET 'https://api.innovapp-soft.com/v2/rates?country=CU' \
  -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \
  -H 'Accept: application/json'

Ejemplo JavaScript

fetch('https://api.innovapp-soft.com/v2/rates?country=CU', {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx',
    'Accept': 'application/json'
  }
})
  .then(r => r.json())
  .then(res => {
    const sections = res.data.sections || [];
    const eltoque = sections.find(s => s.id === 'eltoque');
    console.log(res.data.date, eltoque && eltoque.rates);
  });

Esquema de respuesta verificado

{
    "success": true,
    "code": "ok",
    "message": "OK",
    "data": {
        "status": "true",
        "message": "ok",
        "version": "2",
        "scope": "cuba",
        "base": "USD",
        "date": "YYYY-MM-DD",
        "updated_at": "YYYY-MM-DD HH:MM:SS",
        "generated_at": "YYYY-MM-DD HH:MM:SS",
        "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
            }
        ],
        "history": {
            "today": {
                "date": "YYYY-MM-DD",
                "updated_at": "YYYY-MM-DD HH:MM:SS"
            },
            "yesterday": {
                "date": "YYYY-MM-DD",
                "updated_at": "YYYY-MM-DD HH:MM:SS"
            },
            "week": {
                "date": "YYYY-MM-DD",
                "updated_at": "YYYY-MM-DD HH:MM:SS"
            }
        },
        "sections": [
            {
                "id": "eltoque",
                "title": "elToque",
                "base": "CUP",
                "unit": "CUP per 1 unit",
                "rates": [
                    {
                        "code": "CUP",
                        "name": "Cuban Peso",
                        "country": "Cuba",
                        "type": "fiat",
                        "value": "dynamic",
                        "yesterday": "dynamic",
                        "week": "dynamic",
                        "change": "dynamic",
                        "change_week": "dynamic",
                        "source": "cu_eltoque_trmi",
                        "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"
                    }
                ]
            }
        ]
    },
    "error": [],
    "time": {
        "datetime": "2026-09-13T10:15:00-04:00",
        "date": "2026-09-13",
        "time": "10:15:00",
        "timezone": "America/Kentucky/Louisville",
        "offset": "-04:00",
        "timestamp": 1789222500
    }
}

Ejemplos de error

401 401 API key ausente o invalida
{
    "success": false,
    "code": 10023,
    "message": "Unauthorized",
    "data": [],
    "error": []
}
405 405 Metodo no permitido
{
    "success": false,
    "code": 40501,
    "message": "Method not allowed",
    "data": [],
    "error": {
        "details": "POST"
    }
}
200 200 sin snapshot de tasas disponible
{
    "success": false,
    "code": "rates_snapshot_unavailable",
    "message": "rates_snapshot_unavailable",
    "data": {
        "status": "false",
        "message": "rates_snapshot_unavailable",
        "version": "2",
        "scope": "global",
        "base": "USD",
        "date": "YYYY-MM-DD",
        "updated_at": null,
        "country": {
            "code": "GLOBAL",
            "name": "Global",
            "currency": "USD",
            "supported": true
        },
        "countries": [],
        "history": [],
        "sections": []
    },
    "error": []
}

Notas

  • Devuelve tasas globales y por pais en secciones normalizadas. Cuba incluye fuentes locales como InnovappSoft KeyCoin, elToque y segmentos BCC cuando hay data.
  • /v2/tasas es un alias compatible de /v2/rates.
  • data.sections es la parte recomendada para UI: cada seccion trae rates con value, yesterday, week, change y change_week.
  • Solo acepta GET. Cualquier otro metodo responde 405 con code 40501.
  • Paises soportados: GLOBAL, US, CU, MX, CO, BR, VE, UY, PE, GY, CA, CH, EU. Un valor no soportado, incluido country=auto, devuelve el scope global.
  • Las tasas salen del snapshot diario de KeyPay. No es un feed en tiempo real: lee siempre data.date y data.updated_at.
  • base es siempre USD y KCOIN vale 1 USD dentro del mapa global.
  • change y change_week son diferencias absolutas, no porcentajes.
  • Si falta el dato de ayer se reutiliza el de hoy, y si falta el de la semana se reutiliza el de ayer. En ese caso change o change_week salen en 0.
  • CUP dentro del mapa global se resuelve con la fuente cubana mas alta disponible, elToque o los segmentos del BCC. El origen exacto queda en sources_by_code.CUP cuando pides full=1.
  • Secciones de Cuba: innovapp, eltoque, bcc_segment1, bcc_segment2 y bcc_segment3. Secciones globales: global y usd_value. Un pais distinto de CU y GLOBAL devuelve una sola seccion country_local.
  • Una seccion solo aparece si tiene tasas. No asumas un numero fijo de elementos en sections: recorrelo buscando por id.
  • Los codigos se normalizan: USDT, TETHER y TRC20 llegan como USDT_TRC20, y KC o KEYCOIN llegan como KCOIN.
  • No cachees mas de unos minutos en el cliente y usa data.date como clave de cache.
  • Este endpoint no esta incluido en el Sandbox. Pruebalo con tu dk_live contra produccion: es de solo lectura y no mueve saldo.
Mercado V2

Catalogo, carrito e historial de pedidos del Mercado de KeyPay, sobre la misma cuenta KeyPay enlazada a tu API key. Flujo recomendado: locations y categories para conocer los filtros, products para listar, detail antes de anadir, y despues el carrito.

1 POST Estado del Mercado /v2/marketplace/status
Devuelve si el Mercado esta activo para la cuenta, las comisiones vigentes, las provincias, las categorias, el carrito actual, la direccion y el perfil de facturacion guardados, las tarifas de entrega y el credito disponible. Es la llamada de arranque.

Devuelve si el Mercado esta activo para la cuenta, las comisiones vigentes, las provincias, las categorias, el carrito actual, la direccion y el perfil de facturacion guardados, las tarifas de entrega y el credito disponible. Es la llamada de arranque.

Endpoint
https://api.innovapp-soft.com/v2/marketplace/status
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
language No string Idioma de los textos de la respuesta: es o en. es

Ejemplo cURL

curl -X POST 'https://api.innovapp-soft.com/v2/marketplace/status' \
  -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{"language":"es"}'

Ejemplo JavaScript

fetch('https://api.innovapp-soft.com/v2/marketplace/status', {
  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);

Esquema de respuesta verificado

{
    "success": true,
    "code": "marketplace.status.ok",
    "message": "OK",
    "data": {
        "api_version": 2,
        "enabled": true,
        "purchases_enabled": true,
        "currency": "USD",
        "fee": "dynamic",
        "price_includes_fee": false,
        "fee_basis": "products_subtotal",
        "locations": "dynamic",
        "categories": "dynamic",
        "cart": "dynamic",
        "address": "dynamic",
        "billing_profile": "dynamic",
        "delivery_rates": "dynamic",
        "marketplace_faq": "dynamic",
        "credito": "dynamic"
    },
    "error": [],
    "time": "2026-09-13T10:15:00-04:00"
}

Ejemplos de error

401 401 API key ausente o invalida
{
    "success": false,
    "code": 10023,
    "message": "Unauthorized",
    "data": [],
    "error": []
}
422 422 Campo requerido o invalido
{
    "success": false,
    "code": 48003,
    "message": "Required field is missing: product_token",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "cart-add"
    }
}
403 403 La cuenta no tiene acceso al Mercado
{
    "success": false,
    "code": "marketplace.status.failed",
    "message": "No tienes acceso al Mercado.",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "status"
    }
}
503 503 Servicio temporalmente no disponible
{
    "success": false,
    "code": "marketplace.products.failed",
    "message": "Marketplace is temporarily unavailable.",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "products"
    }
}
502 502 No se pudo contactar con KeyPay
{
    "success": false,
    "code": 47020,
    "message": "The Mercado service is temporarily unavailable.",
    "data": [],
    "error": []
}

Notas

  • No envies userIdentifier: la cuenta KeyPay sale de la API key autenticada.
  • Todas las rutas son POST con cuerpo JSON, incluidas las de solo lectura.
  • product_token va firmado y atado al province_id y al localities_key con los que pediste el catalogo. Caduca a los 30 minutos: no lo guardes ni lo compartas entre usuarios.
  • Sin localities_key el catalogo es de toda la provincia y el detalle no puede confirmar existencias en una bodega concreta. Manda siempre el municipio si lo conoces.
  • El carrito admite hasta 30 productos distintos y 20 unidades por producto. Muchos productos tienen ademas un minimo por bodega que el servidor aplica solo.
  • Los precios llegan sin la comision: price_includes_fee es false y fee_basis es products_subtotal. Calcula el total con los importes que devuelve el carrito, no sumando precios.
  • orders y order-get solo devuelven pedidos del Mercado, los que empiezan por MKT-. Los pedidos de Amazon no forman parte de esta API.
  • Crear el pedido no esta disponible en esta API todavia. Puedes montar el carrito, pero el cobro se cierra desde la app de KeyPay.
  • Antes de poder pedir hacen falta una direccion de envio y un perfil de facturacion guardados. Usa la familia de direcciones.
  • Las imagenes llegan como https://api.innovapp-soft.com/v2/media/<token>. Usalas tal cual en tu <img>: son publicas, no piden Authorization y se cachean una semana. No intentes construir el token ni deducir la URL de origen.
  • El producto trae el nombre en name y las traducciones en translations.es y translations.en. Si pides language=es, name y description ya vienen traducidos.
  • Cada producto pertenece a una bodega y esa bodega tiene un pedido minimo. El carrito devuelve bodega_groups y minimum_failures con lo que falta para alcanzarlo.
  • Disponible en el Sandbox: pon /sandbox delante de la ruta y usa una clave dk_test_. El catalogo de prueba tiene dos productos en Villa Clara (province_id 5, localities_key 77); llama antes a products para obtener un product_token valido.
  • En el Sandbox orders siempre viene vacio y order-get responde 404, porque el pedido no se puede crear desde esta API.
2 POST Provincias y municipios /v2/marketplace/locations
Lista las provincias con sus municipios. De aqui salen province_id y localities_key, que son los que fijan el contexto de precios y existencias del catalogo.

Lista las provincias con sus municipios. De aqui salen province_id y localities_key, que son los que fijan el contexto de precios y existencias del catalogo.

Endpoint
https://api.innovapp-soft.com/v2/marketplace/locations
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
language No string Idioma de los textos de la respuesta: es o en. es

Ejemplo cURL

curl -X POST 'https://api.innovapp-soft.com/v2/marketplace/locations' \
  -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{"language":"es"}'

Ejemplo JavaScript

fetch('https://api.innovapp-soft.com/v2/marketplace/locations', {
  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);

Esquema de respuesta verificado

{
    "success": true,
    "code": "marketplace.locations.ok",
    "message": "OK",
    "data": {
        "locations": [
            {
                "province_id": 5,
                "province": "La Habana",
                "municipalities": [
                    {
                        "localities_key": 512,
                        "municipality": "Playa"
                    }
                ]
            }
        ]
    },
    "error": [],
    "time": "2026-09-13T10:15:00-04:00"
}

Ejemplos de error

401 401 API key ausente o invalida
{
    "success": false,
    "code": 10023,
    "message": "Unauthorized",
    "data": [],
    "error": []
}
422 422 Campo requerido o invalido
{
    "success": false,
    "code": 48003,
    "message": "Required field is missing: product_token",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "cart-add"
    }
}
403 403 La cuenta no tiene acceso al Mercado
{
    "success": false,
    "code": "marketplace.status.failed",
    "message": "No tienes acceso al Mercado.",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "status"
    }
}
503 503 Servicio temporalmente no disponible
{
    "success": false,
    "code": "marketplace.products.failed",
    "message": "Marketplace is temporarily unavailable.",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "products"
    }
}
502 502 No se pudo contactar con KeyPay
{
    "success": false,
    "code": 47020,
    "message": "The Mercado service is temporarily unavailable.",
    "data": [],
    "error": []
}

Notas

  • No envies userIdentifier: la cuenta KeyPay sale de la API key autenticada.
  • Todas las rutas son POST con cuerpo JSON, incluidas las de solo lectura.
  • product_token va firmado y atado al province_id y al localities_key con los que pediste el catalogo. Caduca a los 30 minutos: no lo guardes ni lo compartas entre usuarios.
  • Sin localities_key el catalogo es de toda la provincia y el detalle no puede confirmar existencias en una bodega concreta. Manda siempre el municipio si lo conoces.
  • El carrito admite hasta 30 productos distintos y 20 unidades por producto. Muchos productos tienen ademas un minimo por bodega que el servidor aplica solo.
  • Los precios llegan sin la comision: price_includes_fee es false y fee_basis es products_subtotal. Calcula el total con los importes que devuelve el carrito, no sumando precios.
  • orders y order-get solo devuelven pedidos del Mercado, los que empiezan por MKT-. Los pedidos de Amazon no forman parte de esta API.
  • Crear el pedido no esta disponible en esta API todavia. Puedes montar el carrito, pero el cobro se cierra desde la app de KeyPay.
  • Antes de poder pedir hacen falta una direccion de envio y un perfil de facturacion guardados. Usa la familia de direcciones.
  • Las imagenes llegan como https://api.innovapp-soft.com/v2/media/<token>. Usalas tal cual en tu <img>: son publicas, no piden Authorization y se cachean una semana. No intentes construir el token ni deducir la URL de origen.
  • El producto trae el nombre en name y las traducciones en translations.es y translations.en. Si pides language=es, name y description ya vienen traducidos.
  • Cada producto pertenece a una bodega y esa bodega tiene un pedido minimo. El carrito devuelve bodega_groups y minimum_failures con lo que falta para alcanzarlo.
  • Disponible en el Sandbox: pon /sandbox delante de la ruta y usa una clave dk_test_. El catalogo de prueba tiene dos productos en Villa Clara (province_id 5, localities_key 77); llama antes a products para obtener un product_token valido.
  • En el Sandbox orders siempre viene vacio y order-get responde 404, porque el pedido no se puede crear desde esta API.
3 POST Categorias /v2/marketplace/categories
Lista las categorias del Mercado con sus clasificadores. Usa category_id y classifier_id en products.

Lista las categorias del Mercado con sus clasificadores. Usa category_id y classifier_id en products.

Endpoint
https://api.innovapp-soft.com/v2/marketplace/categories
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
language No string Idioma de los textos de la respuesta: es o en. es

Ejemplo cURL

curl -X POST 'https://api.innovapp-soft.com/v2/marketplace/categories' \
  -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{"language":"es"}'

Ejemplo JavaScript

fetch('https://api.innovapp-soft.com/v2/marketplace/categories', {
  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);

Esquema de respuesta verificado

{
    "success": true,
    "code": "marketplace.categories.ok",
    "message": "OK",
    "data": {
        "categories": [
            {
                "category_id": 18,
                "name": "dynamic",
                "classifiers": "dynamic"
            }
        ]
    },
    "error": [],
    "time": "2026-09-13T10:15:00-04:00"
}

Ejemplos de error

401 401 API key ausente o invalida
{
    "success": false,
    "code": 10023,
    "message": "Unauthorized",
    "data": [],
    "error": []
}
422 422 Campo requerido o invalido
{
    "success": false,
    "code": 48003,
    "message": "Required field is missing: product_token",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "cart-add"
    }
}
403 403 La cuenta no tiene acceso al Mercado
{
    "success": false,
    "code": "marketplace.status.failed",
    "message": "No tienes acceso al Mercado.",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "status"
    }
}
503 503 Servicio temporalmente no disponible
{
    "success": false,
    "code": "marketplace.products.failed",
    "message": "Marketplace is temporarily unavailable.",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "products"
    }
}
502 502 No se pudo contactar con KeyPay
{
    "success": false,
    "code": 47020,
    "message": "The Mercado service is temporarily unavailable.",
    "data": [],
    "error": []
}

Notas

  • No envies userIdentifier: la cuenta KeyPay sale de la API key autenticada.
  • Todas las rutas son POST con cuerpo JSON, incluidas las de solo lectura.
  • product_token va firmado y atado al province_id y al localities_key con los que pediste el catalogo. Caduca a los 30 minutos: no lo guardes ni lo compartas entre usuarios.
  • Sin localities_key el catalogo es de toda la provincia y el detalle no puede confirmar existencias en una bodega concreta. Manda siempre el municipio si lo conoces.
  • El carrito admite hasta 30 productos distintos y 20 unidades por producto. Muchos productos tienen ademas un minimo por bodega que el servidor aplica solo.
  • Los precios llegan sin la comision: price_includes_fee es false y fee_basis es products_subtotal. Calcula el total con los importes que devuelve el carrito, no sumando precios.
  • orders y order-get solo devuelven pedidos del Mercado, los que empiezan por MKT-. Los pedidos de Amazon no forman parte de esta API.
  • Crear el pedido no esta disponible en esta API todavia. Puedes montar el carrito, pero el cobro se cierra desde la app de KeyPay.
  • Antes de poder pedir hacen falta una direccion de envio y un perfil de facturacion guardados. Usa la familia de direcciones.
  • Las imagenes llegan como https://api.innovapp-soft.com/v2/media/<token>. Usalas tal cual en tu <img>: son publicas, no piden Authorization y se cachean una semana. No intentes construir el token ni deducir la URL de origen.
  • El producto trae el nombre en name y las traducciones en translations.es y translations.en. Si pides language=es, name y description ya vienen traducidos.
  • Cada producto pertenece a una bodega y esa bodega tiene un pedido minimo. El carrito devuelve bodega_groups y minimum_failures con lo que falta para alcanzarlo.
  • Disponible en el Sandbox: pon /sandbox delante de la ruta y usa una clave dk_test_. El catalogo de prueba tiene dos productos en Villa Clara (province_id 5, localities_key 77); llama antes a products para obtener un product_token valido.
  • En el Sandbox orders siempre viene vacio y order-get responde 404, porque el pedido no se puede crear desde esta API.
4 POST Listar productos /v2/marketplace/products
Lista los productos disponibles para una provincia y municipio, con filtros de categoria, texto y orden. Cada producto trae un token firmado que es lo unico que aceptan detail y cart-add.

Lista los productos disponibles para una provincia y municipio, con filtros de categoria, texto y orden. Cada producto trae un token firmado que es lo unico que aceptan detail y cart-add.

Endpoint
https://api.innovapp-soft.com/v2/marketplace/products
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
province_id No integer Id de la provincia devuelto por locations. Por defecto 5. 5
localities_key No integer Id del municipio devuelto por locations. Sin el, el catalogo es de toda la provincia y el detalle no puede confirmar existencias exactas. 512
category_id No integer Filtra por categoria. Usa el id devuelto por categories. 18
classifier_id No integer Filtra por subcategoria o clasificador dentro de la categoria. 204
q No string Texto de busqueda. Maximo 80 caracteres. arroz
page No integer Pagina solicitada. Empieza en 1. 1
page_size No integer Productos por pagina, entre 1 y 48. Por defecto 24. 24
sort No string Orden del listado: relevance, price_asc, price_desc o newest. price_asc
language No string Idioma de los textos de la respuesta: es o en. es

Ejemplo cURL

curl -X POST 'https://api.innovapp-soft.com/v2/marketplace/products' \
  -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{"province_id":5,"localities_key":512,"page":1,"language":"es"}'

Ejemplo JavaScript

fetch('https://api.innovapp-soft.com/v2/marketplace/products', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx',
    'Accept': 'application/json',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
      "province_id": 5,
      "localities_key": 512,
      "page": 1,
      "language": "es"
  })
}).then(r => r.json()).then(console.log);

Esquema de respuesta verificado

{
    "success": true,
    "code": "marketplace.products.ok",
    "message": "OK",
    "data": {
        "filters": {
            "province_id": 5,
            "province": "dynamic",
            "localities_key": 77,
            "municipality": "dynamic",
            "category_id": 0,
            "classifier_id": 0,
            "language": "es",
            "q": "",
            "sort": "relevance"
        },
        "pagination": {
            "page": 1,
            "page_size": 24,
            "total": "dynamic",
            "pages": "dynamic",
            "has_more": "dynamic"
        },
        "products": [
            {
                "id": 393121,
                "name": "dynamic",
                "language": "es",
                "translations": {
                    "es": {
                        "name": "dynamic",
                        "description": "dynamic"
                    },
                    "en": {
                        "name": "dynamic",
                        "description": "dynamic"
                    }
                },
                "description": "dynamic",
                "description_available": true,
                "price": "dynamic",
                "old_price": null,
                "price_includes_fee": false,
                "image": "https://api.innovapp-soft.com/v2/media/m1_...",
                "image_large": "https://api.innovapp-soft.com/v2/media/m1_...",
                "images": [
                    "https://api.innovapp-soft.com/v2/media/m1_..."
                ],
                "thumbnails": [
                    "https://api.innovapp-soft.com/v2/media/m1_..."
                ],
                "gallery": [
                    {
                        "id": "dynamic",
                        "main": true,
                        "display_order": 1,
                        "thumbnail": "https://api.innovapp-soft.com/v2/media/m1_...",
                        "middle": "https://api.innovapp-soft.com/v2/media/m1_..."
                    }
                ],
                "category": "dynamic",
                "brand": "dynamic",
                "available": true,
                "available_quantity": "dynamic",
                "availability": {
                    "available": true,
                    "status": "available",
                    "message": "dynamic",
                    "available_quantity": "dynamic",
                    "catalog_active": true,
                    "provider_active": true,
                    "bodega_active": true,
                    "preorder": null,
                    "distribution_provinces": [
                        {
                            "province_id": 5,
                            "province": "dynamic"
                        }
                    ]
                },
                "bodega": "dynamic",
                "bodega_id": "dynamic",
                "bodega_assignment": "assigned",
                "bodega_details": "dynamic",
                "bodega_minimum": {
                    "amount": "dynamic",
                    "currency": "USD",
                    "amounts": "dynamic"
                },
                "provider_id": "dynamic",
                "distributor_id": "dynamic",
                "shipping_group_key": "bodega:67",
                "quantity_limits": {
                    "minimum": 1,
                    "maximum_configured": "dynamic",
                    "maximum_current": "dynamic"
                },
                "is_bundle": false,
                "bundle": "dynamic",
                "has_purchase_options": false,
                "purchase_options": [
                    {
                        "product_id": 393121,
                        "package_units": 1,
                        "selected": true,
                        "name": "dynamic",
                        "price": "dynamic",
                        "available": true,
                        "available_quantity": "dynamic",
                        "status": "available",
                        "image": "https://api.innovapp-soft.com/v2/media/m1_...",
                        "component_product_ids": []
                    }
                ],
                "is_dairy": false,
                "requires_refrigeration": false,
                "weight": {
                    "grams": "dynamic",
                    "kilograms": "dynamic",
                    "source": "OtherInfo.Weight"
                },
                "logistics": "dynamic",
                "token": "sb_eyJwIjozOTMxMjEsImMiOjUsImwiOjc3fQ"
            }
        ],
        "fee": "dynamic",
        "price_includes_fee": false,
        "transport": "dynamic"
    },
    "error": [],
    "time": "2026-09-13T10:15:00-04:00"
}

Ejemplos de error

401 401 API key ausente o invalida
{
    "success": false,
    "code": 10023,
    "message": "Unauthorized",
    "data": [],
    "error": []
}
422 422 Campo requerido o invalido
{
    "success": false,
    "code": 48003,
    "message": "Required field is missing: product_token",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "cart-add"
    }
}
403 403 La cuenta no tiene acceso al Mercado
{
    "success": false,
    "code": "marketplace.status.failed",
    "message": "No tienes acceso al Mercado.",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "status"
    }
}
503 503 Servicio temporalmente no disponible
{
    "success": false,
    "code": "marketplace.products.failed",
    "message": "Marketplace is temporarily unavailable.",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "products"
    }
}
502 502 No se pudo contactar con KeyPay
{
    "success": false,
    "code": 47020,
    "message": "The Mercado service is temporarily unavailable.",
    "data": [],
    "error": []
}

Notas

  • No envies userIdentifier: la cuenta KeyPay sale de la API key autenticada.
  • Todas las rutas son POST con cuerpo JSON, incluidas las de solo lectura.
  • product_token va firmado y atado al province_id y al localities_key con los que pediste el catalogo. Caduca a los 30 minutos: no lo guardes ni lo compartas entre usuarios.
  • Sin localities_key el catalogo es de toda la provincia y el detalle no puede confirmar existencias en una bodega concreta. Manda siempre el municipio si lo conoces.
  • El carrito admite hasta 30 productos distintos y 20 unidades por producto. Muchos productos tienen ademas un minimo por bodega que el servidor aplica solo.
  • Los precios llegan sin la comision: price_includes_fee es false y fee_basis es products_subtotal. Calcula el total con los importes que devuelve el carrito, no sumando precios.
  • orders y order-get solo devuelven pedidos del Mercado, los que empiezan por MKT-. Los pedidos de Amazon no forman parte de esta API.
  • Crear el pedido no esta disponible en esta API todavia. Puedes montar el carrito, pero el cobro se cierra desde la app de KeyPay.
  • Antes de poder pedir hacen falta una direccion de envio y un perfil de facturacion guardados. Usa la familia de direcciones.
  • Las imagenes llegan como https://api.innovapp-soft.com/v2/media/<token>. Usalas tal cual en tu <img>: son publicas, no piden Authorization y se cachean una semana. No intentes construir el token ni deducir la URL de origen.
  • El producto trae el nombre en name y las traducciones en translations.es y translations.en. Si pides language=es, name y description ya vienen traducidos.
  • Cada producto pertenece a una bodega y esa bodega tiene un pedido minimo. El carrito devuelve bodega_groups y minimum_failures con lo que falta para alcanzarlo.
  • Disponible en el Sandbox: pon /sandbox delante de la ruta y usa una clave dk_test_. El catalogo de prueba tiene dos productos en Villa Clara (province_id 5, localities_key 77); llama antes a products para obtener un product_token valido.
  • En el Sandbox orders siempre viene vacio y order-get responde 404, porque el pedido no se puede crear desde esta API.
5 POST Detalle de un producto /v2/marketplace/detail
Devuelve la ficha completa de un producto a partir de su token: descripcion, imagenes, variantes de compra, minimos por bodega y disponibilidad confirmada.

Devuelve la ficha completa de un producto a partir de su token: descripcion, imagenes, variantes de compra, minimos por bodega y disponibilidad confirmada.

Endpoint
https://api.innovapp-soft.com/v2/marketplace/detail
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
product_token Si string Token firmado del producto devuelto por products. Caduca a los 30 minutos y va atado al contexto de provincia y municipio con el que se pidio. eyJwIjoxMiwiYyI6NX0.Zm9vYmFy
selected_product_id No integer Id de la variante concreta dentro de purchase_options. Por defecto, el producto del token. 90312
language No string Idioma de los textos de la respuesta: es o en. es

Ejemplo cURL

curl -X POST 'https://api.innovapp-soft.com/v2/marketplace/detail' \
  -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{"product_token":"eyJwIjoxMiwiYyI6NX0.Zm9vYmFy","language":"es"}'

Ejemplo JavaScript

fetch('https://api.innovapp-soft.com/v2/marketplace/detail', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx',
    'Accept': 'application/json',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
      "product_token": "eyJwIjoxMiwiYyI6NX0.Zm9vYmFy",
      "language": "es"
  })
}).then(r => r.json()).then(console.log);

Esquema de respuesta verificado

{
    "success": true,
    "code": "marketplace.detail.ok",
    "message": "OK",
    "data": {
        "product": {
            "id": 393121,
            "name": "dynamic",
            "language": "es",
            "translations": {
                "es": {
                    "name": "dynamic",
                    "description": "dynamic"
                },
                "en": {
                    "name": "dynamic",
                    "description": "dynamic"
                }
            },
            "description": "dynamic",
            "description_available": true,
            "price": "dynamic",
            "old_price": null,
            "price_includes_fee": false,
            "image": "https://api.innovapp-soft.com/v2/media/m1_...",
            "image_large": "https://api.innovapp-soft.com/v2/media/m1_...",
            "images": [
                "https://api.innovapp-soft.com/v2/media/m1_..."
            ],
            "thumbnails": [
                "https://api.innovapp-soft.com/v2/media/m1_..."
            ],
            "gallery": [
                {
                    "id": "dynamic",
                    "main": true,
                    "display_order": 1,
                    "thumbnail": "https://api.innovapp-soft.com/v2/media/m1_...",
                    "middle": "https://api.innovapp-soft.com/v2/media/m1_..."
                }
            ],
            "category": "dynamic",
            "brand": "dynamic",
            "available": true,
            "available_quantity": "dynamic",
            "availability": {
                "available": true,
                "status": "available",
                "message": "dynamic",
                "available_quantity": "dynamic",
                "catalog_active": true,
                "provider_active": true,
                "bodega_active": true,
                "preorder": null,
                "distribution_provinces": [
                    {
                        "province_id": 5,
                        "province": "dynamic"
                    }
                ]
            },
            "bodega": "dynamic",
            "bodega_id": "dynamic",
            "bodega_assignment": "assigned",
            "bodega_details": "dynamic",
            "bodega_minimum": {
                "amount": "dynamic",
                "currency": "USD",
                "amounts": "dynamic"
            },
            "provider_id": "dynamic",
            "distributor_id": "dynamic",
            "shipping_group_key": "bodega:67",
            "quantity_limits": {
                "minimum": 1,
                "maximum_configured": "dynamic",
                "maximum_current": "dynamic"
            },
            "is_bundle": false,
            "bundle": "dynamic",
            "has_purchase_options": false,
            "purchase_options": [
                {
                    "product_id": 393121,
                    "package_units": 1,
                    "selected": true,
                    "name": "dynamic",
                    "price": "dynamic",
                    "available": true,
                    "available_quantity": "dynamic",
                    "status": "available",
                    "image": "https://api.innovapp-soft.com/v2/media/m1_...",
                    "component_product_ids": []
                }
            ],
            "is_dairy": false,
            "requires_refrigeration": false,
            "weight": {
                "grams": "dynamic",
                "kilograms": "dynamic",
                "source": "OtherInfo.Weight"
            },
            "logistics": "dynamic",
            "token": "sb_eyJwIjozOTMxMjEsImMiOjUsImwiOjc3fQ",
            "context": {
                "province_id": 5,
                "localities_key": 77
            }
        }
    },
    "error": [],
    "time": "2026-09-13T10:15:00-04:00"
}

Ejemplos de error

401 401 API key ausente o invalida
{
    "success": false,
    "code": 10023,
    "message": "Unauthorized",
    "data": [],
    "error": []
}
422 422 Campo requerido o invalido
{
    "success": false,
    "code": 48003,
    "message": "Required field is missing: product_token",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "cart-add"
    }
}
403 403 La cuenta no tiene acceso al Mercado
{
    "success": false,
    "code": "marketplace.status.failed",
    "message": "No tienes acceso al Mercado.",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "status"
    }
}
503 503 Servicio temporalmente no disponible
{
    "success": false,
    "code": "marketplace.products.failed",
    "message": "Marketplace is temporarily unavailable.",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "products"
    }
}
502 502 No se pudo contactar con KeyPay
{
    "success": false,
    "code": 47020,
    "message": "The Mercado service is temporarily unavailable.",
    "data": [],
    "error": []
}

Notas

  • No envies userIdentifier: la cuenta KeyPay sale de la API key autenticada.
  • Todas las rutas son POST con cuerpo JSON, incluidas las de solo lectura.
  • product_token va firmado y atado al province_id y al localities_key con los que pediste el catalogo. Caduca a los 30 minutos: no lo guardes ni lo compartas entre usuarios.
  • Sin localities_key el catalogo es de toda la provincia y el detalle no puede confirmar existencias en una bodega concreta. Manda siempre el municipio si lo conoces.
  • El carrito admite hasta 30 productos distintos y 20 unidades por producto. Muchos productos tienen ademas un minimo por bodega que el servidor aplica solo.
  • Los precios llegan sin la comision: price_includes_fee es false y fee_basis es products_subtotal. Calcula el total con los importes que devuelve el carrito, no sumando precios.
  • orders y order-get solo devuelven pedidos del Mercado, los que empiezan por MKT-. Los pedidos de Amazon no forman parte de esta API.
  • Crear el pedido no esta disponible en esta API todavia. Puedes montar el carrito, pero el cobro se cierra desde la app de KeyPay.
  • Antes de poder pedir hacen falta una direccion de envio y un perfil de facturacion guardados. Usa la familia de direcciones.
  • Las imagenes llegan como https://api.innovapp-soft.com/v2/media/<token>. Usalas tal cual en tu <img>: son publicas, no piden Authorization y se cachean una semana. No intentes construir el token ni deducir la URL de origen.
  • El producto trae el nombre en name y las traducciones en translations.es y translations.en. Si pides language=es, name y description ya vienen traducidos.
  • Cada producto pertenece a una bodega y esa bodega tiene un pedido minimo. El carrito devuelve bodega_groups y minimum_failures con lo que falta para alcanzarlo.
  • Disponible en el Sandbox: pon /sandbox delante de la ruta y usa una clave dk_test_. El catalogo de prueba tiene dos productos en Villa Clara (province_id 5, localities_key 77); llama antes a products para obtener un product_token valido.
  • En el Sandbox orders siempre viene vacio y order-get responde 404, porque el pedido no se puede crear desde esta API.
6 POST Ver el carrito /v2/marketplace/cart
Devuelve el carrito actual de la cuenta con sus lineas, subtotales, comision y avisos de logistica.

Devuelve el carrito actual de la cuenta con sus lineas, subtotales, comision y avisos de logistica.

Endpoint
https://api.innovapp-soft.com/v2/marketplace/cart
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
language No string Idioma de los textos de la respuesta: es o en. es

Ejemplo cURL

curl -X POST 'https://api.innovapp-soft.com/v2/marketplace/cart' \
  -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{"language":"es"}'

Ejemplo JavaScript

fetch('https://api.innovapp-soft.com/v2/marketplace/cart', {
  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);

Esquema de respuesta verificado

{
    "success": true,
    "code": "marketplace.cart.ok",
    "message": "OK",
    "data": {
        "cart": {
            "items": [
                "dynamic"
            ],
            "products_subtotal": "dynamic",
            "fee": "dynamic"
        }
    },
    "error": [],
    "time": "2026-09-13T10:15:00-04:00"
}

Ejemplos de error

401 401 API key ausente o invalida
{
    "success": false,
    "code": 10023,
    "message": "Unauthorized",
    "data": [],
    "error": []
}
422 422 Campo requerido o invalido
{
    "success": false,
    "code": 48003,
    "message": "Required field is missing: product_token",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "cart-add"
    }
}
403 403 La cuenta no tiene acceso al Mercado
{
    "success": false,
    "code": "marketplace.status.failed",
    "message": "No tienes acceso al Mercado.",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "status"
    }
}
503 503 Servicio temporalmente no disponible
{
    "success": false,
    "code": "marketplace.products.failed",
    "message": "Marketplace is temporarily unavailable.",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "products"
    }
}
502 502 No se pudo contactar con KeyPay
{
    "success": false,
    "code": 47020,
    "message": "The Mercado service is temporarily unavailable.",
    "data": [],
    "error": []
}

Notas

  • No envies userIdentifier: la cuenta KeyPay sale de la API key autenticada.
  • Todas las rutas son POST con cuerpo JSON, incluidas las de solo lectura.
  • product_token va firmado y atado al province_id y al localities_key con los que pediste el catalogo. Caduca a los 30 minutos: no lo guardes ni lo compartas entre usuarios.
  • Sin localities_key el catalogo es de toda la provincia y el detalle no puede confirmar existencias en una bodega concreta. Manda siempre el municipio si lo conoces.
  • El carrito admite hasta 30 productos distintos y 20 unidades por producto. Muchos productos tienen ademas un minimo por bodega que el servidor aplica solo.
  • Los precios llegan sin la comision: price_includes_fee es false y fee_basis es products_subtotal. Calcula el total con los importes que devuelve el carrito, no sumando precios.
  • orders y order-get solo devuelven pedidos del Mercado, los que empiezan por MKT-. Los pedidos de Amazon no forman parte de esta API.
  • Crear el pedido no esta disponible en esta API todavia. Puedes montar el carrito, pero el cobro se cierra desde la app de KeyPay.
  • Antes de poder pedir hacen falta una direccion de envio y un perfil de facturacion guardados. Usa la familia de direcciones.
  • Las imagenes llegan como https://api.innovapp-soft.com/v2/media/<token>. Usalas tal cual en tu <img>: son publicas, no piden Authorization y se cachean una semana. No intentes construir el token ni deducir la URL de origen.
  • El producto trae el nombre en name y las traducciones en translations.es y translations.en. Si pides language=es, name y description ya vienen traducidos.
  • Cada producto pertenece a una bodega y esa bodega tiene un pedido minimo. El carrito devuelve bodega_groups y minimum_failures con lo que falta para alcanzarlo.
  • Disponible en el Sandbox: pon /sandbox delante de la ruta y usa una clave dk_test_. El catalogo de prueba tiene dos productos en Villa Clara (province_id 5, localities_key 77); llama antes a products para obtener un product_token valido.
  • En el Sandbox orders siempre viene vacio y order-get responde 404, porque el pedido no se puede crear desde esta API.
7 POST Anadir al carrito /v2/marketplace/cart-add
Anade un producto al carrito usando su token. Si el producto ya estaba, suma la cantidad. El servidor recorta al minimo y al maximo del producto y rechaza los que no esten disponibles.

Anade un producto al carrito usando su token. Si el producto ya estaba, suma la cantidad. El servidor recorta al minimo y al maximo del producto y rechaza los que no esten disponibles.

Endpoint
https://api.innovapp-soft.com/v2/marketplace/cart-add
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
product_token Si string Token firmado del producto devuelto por products. Caduca a los 30 minutos y va atado al contexto de provincia y municipio con el que se pidio. eyJwIjoxMiwiYyI6NX0.Zm9vYmFy
quantity No integer Cantidad, entre 1 y 20. El servidor la ajusta al minimo y al maximo del producto. 2
language No string Idioma de los textos de la respuesta: es o en. es

Ejemplo cURL

curl -X POST 'https://api.innovapp-soft.com/v2/marketplace/cart-add' \
  -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{"product_token":"eyJwIjoxMiwiYyI6NX0.Zm9vYmFy","quantity":2,"language":"es"}'

Ejemplo JavaScript

fetch('https://api.innovapp-soft.com/v2/marketplace/cart-add', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx',
    'Accept': 'application/json',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
      "product_token": "eyJwIjoxMiwiYyI6NX0.Zm9vYmFy",
      "quantity": 2,
      "language": "es"
  })
}).then(r => r.json()).then(console.log);

Esquema de respuesta verificado

{
    "success": true,
    "code": "marketplace.cart-add.ok",
    "message": "OK",
    "data": {
        "cart": "dynamic"
    },
    "error": [],
    "time": "2026-09-13T10:15:00-04:00"
}

Ejemplos de error

401 401 API key ausente o invalida
{
    "success": false,
    "code": 10023,
    "message": "Unauthorized",
    "data": [],
    "error": []
}
422 422 Campo requerido o invalido
{
    "success": false,
    "code": 48003,
    "message": "Required field is missing: product_token",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "cart-add"
    }
}
403 403 La cuenta no tiene acceso al Mercado
{
    "success": false,
    "code": "marketplace.status.failed",
    "message": "No tienes acceso al Mercado.",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "status"
    }
}
503 503 Servicio temporalmente no disponible
{
    "success": false,
    "code": "marketplace.products.failed",
    "message": "Marketplace is temporarily unavailable.",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "products"
    }
}
502 502 No se pudo contactar con KeyPay
{
    "success": false,
    "code": 47020,
    "message": "The Mercado service is temporarily unavailable.",
    "data": [],
    "error": []
}

Notas

  • No envies userIdentifier: la cuenta KeyPay sale de la API key autenticada.
  • Todas las rutas son POST con cuerpo JSON, incluidas las de solo lectura.
  • product_token va firmado y atado al province_id y al localities_key con los que pediste el catalogo. Caduca a los 30 minutos: no lo guardes ni lo compartas entre usuarios.
  • Sin localities_key el catalogo es de toda la provincia y el detalle no puede confirmar existencias en una bodega concreta. Manda siempre el municipio si lo conoces.
  • El carrito admite hasta 30 productos distintos y 20 unidades por producto. Muchos productos tienen ademas un minimo por bodega que el servidor aplica solo.
  • Los precios llegan sin la comision: price_includes_fee es false y fee_basis es products_subtotal. Calcula el total con los importes que devuelve el carrito, no sumando precios.
  • orders y order-get solo devuelven pedidos del Mercado, los que empiezan por MKT-. Los pedidos de Amazon no forman parte de esta API.
  • Crear el pedido no esta disponible en esta API todavia. Puedes montar el carrito, pero el cobro se cierra desde la app de KeyPay.
  • Antes de poder pedir hacen falta una direccion de envio y un perfil de facturacion guardados. Usa la familia de direcciones.
  • Las imagenes llegan como https://api.innovapp-soft.com/v2/media/<token>. Usalas tal cual en tu <img>: son publicas, no piden Authorization y se cachean una semana. No intentes construir el token ni deducir la URL de origen.
  • El producto trae el nombre en name y las traducciones en translations.es y translations.en. Si pides language=es, name y description ya vienen traducidos.
  • Cada producto pertenece a una bodega y esa bodega tiene un pedido minimo. El carrito devuelve bodega_groups y minimum_failures con lo que falta para alcanzarlo.
  • Disponible en el Sandbox: pon /sandbox delante de la ruta y usa una clave dk_test_. El catalogo de prueba tiene dos productos en Villa Clara (province_id 5, localities_key 77); llama antes a products para obtener un product_token valido.
  • En el Sandbox orders siempre viene vacio y order-get responde 404, porque el pedido no se puede crear desde esta API.
8 POST Cambiar la cantidad /v2/marketplace/cart-update
Fija la cantidad exacta de una linea del carrito. Con quantity 0 la elimina.

Fija la cantidad exacta de una linea del carrito. Con quantity 0 la elimina.

Endpoint
https://api.innovapp-soft.com/v2/marketplace/cart-update
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
product_id Si integer Id del producto tal y como viene en cart.items[].product_id. 90312
quantity Si integer Cantidad nueva, entre 0 y 20. Con 0 se elimina la linea del carrito. 3
language No string Idioma de los textos de la respuesta: es o en. es

Ejemplo cURL

curl -X POST 'https://api.innovapp-soft.com/v2/marketplace/cart-update' \
  -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{"product_id":90312,"quantity":3,"language":"es"}'

Ejemplo JavaScript

fetch('https://api.innovapp-soft.com/v2/marketplace/cart-update', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx',
    'Accept': 'application/json',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
      "product_id": 90312,
      "quantity": 3,
      "language": "es"
  })
}).then(r => r.json()).then(console.log);

Esquema de respuesta verificado

{
    "success": true,
    "code": "marketplace.cart-update.ok",
    "message": "OK",
    "data": {
        "cart": "dynamic"
    },
    "error": [],
    "time": "2026-09-13T10:15:00-04:00"
}

Ejemplos de error

401 401 API key ausente o invalida
{
    "success": false,
    "code": 10023,
    "message": "Unauthorized",
    "data": [],
    "error": []
}
422 422 Campo requerido o invalido
{
    "success": false,
    "code": 48003,
    "message": "Required field is missing: product_token",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "cart-add"
    }
}
403 403 La cuenta no tiene acceso al Mercado
{
    "success": false,
    "code": "marketplace.status.failed",
    "message": "No tienes acceso al Mercado.",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "status"
    }
}
503 503 Servicio temporalmente no disponible
{
    "success": false,
    "code": "marketplace.products.failed",
    "message": "Marketplace is temporarily unavailable.",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "products"
    }
}
502 502 No se pudo contactar con KeyPay
{
    "success": false,
    "code": 47020,
    "message": "The Mercado service is temporarily unavailable.",
    "data": [],
    "error": []
}

Notas

  • No envies userIdentifier: la cuenta KeyPay sale de la API key autenticada.
  • Todas las rutas son POST con cuerpo JSON, incluidas las de solo lectura.
  • product_token va firmado y atado al province_id y al localities_key con los que pediste el catalogo. Caduca a los 30 minutos: no lo guardes ni lo compartas entre usuarios.
  • Sin localities_key el catalogo es de toda la provincia y el detalle no puede confirmar existencias en una bodega concreta. Manda siempre el municipio si lo conoces.
  • El carrito admite hasta 30 productos distintos y 20 unidades por producto. Muchos productos tienen ademas un minimo por bodega que el servidor aplica solo.
  • Los precios llegan sin la comision: price_includes_fee es false y fee_basis es products_subtotal. Calcula el total con los importes que devuelve el carrito, no sumando precios.
  • orders y order-get solo devuelven pedidos del Mercado, los que empiezan por MKT-. Los pedidos de Amazon no forman parte de esta API.
  • Crear el pedido no esta disponible en esta API todavia. Puedes montar el carrito, pero el cobro se cierra desde la app de KeyPay.
  • Antes de poder pedir hacen falta una direccion de envio y un perfil de facturacion guardados. Usa la familia de direcciones.
  • Las imagenes llegan como https://api.innovapp-soft.com/v2/media/<token>. Usalas tal cual en tu <img>: son publicas, no piden Authorization y se cachean una semana. No intentes construir el token ni deducir la URL de origen.
  • El producto trae el nombre en name y las traducciones en translations.es y translations.en. Si pides language=es, name y description ya vienen traducidos.
  • Cada producto pertenece a una bodega y esa bodega tiene un pedido minimo. El carrito devuelve bodega_groups y minimum_failures con lo que falta para alcanzarlo.
  • Disponible en el Sandbox: pon /sandbox delante de la ruta y usa una clave dk_test_. El catalogo de prueba tiene dos productos en Villa Clara (province_id 5, localities_key 77); llama antes a products para obtener un product_token valido.
  • En el Sandbox orders siempre viene vacio y order-get responde 404, porque el pedido no se puede crear desde esta API.
9 POST Quitar del carrito /v2/marketplace/cart-remove
Elimina una linea del carrito.

Elimina una linea del carrito.

Endpoint
https://api.innovapp-soft.com/v2/marketplace/cart-remove
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
product_id Si integer Id del producto tal y como viene en cart.items[].product_id. 90312
language No string Idioma de los textos de la respuesta: es o en. es

Ejemplo cURL

curl -X POST 'https://api.innovapp-soft.com/v2/marketplace/cart-remove' \
  -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{"product_id":90312,"language":"es"}'

Ejemplo JavaScript

fetch('https://api.innovapp-soft.com/v2/marketplace/cart-remove', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx',
    'Accept': 'application/json',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
      "product_id": 90312,
      "language": "es"
  })
}).then(r => r.json()).then(console.log);

Esquema de respuesta verificado

{
    "success": true,
    "code": "marketplace.cart-remove.ok",
    "message": "OK",
    "data": {
        "cart": "dynamic"
    },
    "error": [],
    "time": "2026-09-13T10:15:00-04:00"
}

Ejemplos de error

401 401 API key ausente o invalida
{
    "success": false,
    "code": 10023,
    "message": "Unauthorized",
    "data": [],
    "error": []
}
422 422 Campo requerido o invalido
{
    "success": false,
    "code": 48003,
    "message": "Required field is missing: product_token",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "cart-add"
    }
}
403 403 La cuenta no tiene acceso al Mercado
{
    "success": false,
    "code": "marketplace.status.failed",
    "message": "No tienes acceso al Mercado.",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "status"
    }
}
503 503 Servicio temporalmente no disponible
{
    "success": false,
    "code": "marketplace.products.failed",
    "message": "Marketplace is temporarily unavailable.",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "products"
    }
}
502 502 No se pudo contactar con KeyPay
{
    "success": false,
    "code": 47020,
    "message": "The Mercado service is temporarily unavailable.",
    "data": [],
    "error": []
}

Notas

  • No envies userIdentifier: la cuenta KeyPay sale de la API key autenticada.
  • Todas las rutas son POST con cuerpo JSON, incluidas las de solo lectura.
  • product_token va firmado y atado al province_id y al localities_key con los que pediste el catalogo. Caduca a los 30 minutos: no lo guardes ni lo compartas entre usuarios.
  • Sin localities_key el catalogo es de toda la provincia y el detalle no puede confirmar existencias en una bodega concreta. Manda siempre el municipio si lo conoces.
  • El carrito admite hasta 30 productos distintos y 20 unidades por producto. Muchos productos tienen ademas un minimo por bodega que el servidor aplica solo.
  • Los precios llegan sin la comision: price_includes_fee es false y fee_basis es products_subtotal. Calcula el total con los importes que devuelve el carrito, no sumando precios.
  • orders y order-get solo devuelven pedidos del Mercado, los que empiezan por MKT-. Los pedidos de Amazon no forman parte de esta API.
  • Crear el pedido no esta disponible en esta API todavia. Puedes montar el carrito, pero el cobro se cierra desde la app de KeyPay.
  • Antes de poder pedir hacen falta una direccion de envio y un perfil de facturacion guardados. Usa la familia de direcciones.
  • Las imagenes llegan como https://api.innovapp-soft.com/v2/media/<token>. Usalas tal cual en tu <img>: son publicas, no piden Authorization y se cachean una semana. No intentes construir el token ni deducir la URL de origen.
  • El producto trae el nombre en name y las traducciones en translations.es y translations.en. Si pides language=es, name y description ya vienen traducidos.
  • Cada producto pertenece a una bodega y esa bodega tiene un pedido minimo. El carrito devuelve bodega_groups y minimum_failures con lo que falta para alcanzarlo.
  • Disponible en el Sandbox: pon /sandbox delante de la ruta y usa una clave dk_test_. El catalogo de prueba tiene dos productos en Villa Clara (province_id 5, localities_key 77); llama antes a products para obtener un product_token valido.
  • En el Sandbox orders siempre viene vacio y order-get responde 404, porque el pedido no se puede crear desde esta API.
10 POST Vaciar el carrito /v2/marketplace/cart-clear
Vacia el carrito de la cuenta.

Vacia el carrito de la cuenta.

Endpoint
https://api.innovapp-soft.com/v2/marketplace/cart-clear
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
language No string Idioma de los textos de la respuesta: es o en. es

Ejemplo cURL

curl -X POST 'https://api.innovapp-soft.com/v2/marketplace/cart-clear' \
  -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{"language":"es"}'

Ejemplo JavaScript

fetch('https://api.innovapp-soft.com/v2/marketplace/cart-clear', {
  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);

Esquema de respuesta verificado

{
    "success": true,
    "code": "marketplace.cart-clear.ok",
    "message": "OK",
    "data": {
        "cart": {
            "items": []
        }
    },
    "error": [],
    "time": "2026-09-13T10:15:00-04:00"
}

Ejemplos de error

401 401 API key ausente o invalida
{
    "success": false,
    "code": 10023,
    "message": "Unauthorized",
    "data": [],
    "error": []
}
422 422 Campo requerido o invalido
{
    "success": false,
    "code": 48003,
    "message": "Required field is missing: product_token",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "cart-add"
    }
}
403 403 La cuenta no tiene acceso al Mercado
{
    "success": false,
    "code": "marketplace.status.failed",
    "message": "No tienes acceso al Mercado.",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "status"
    }
}
503 503 Servicio temporalmente no disponible
{
    "success": false,
    "code": "marketplace.products.failed",
    "message": "Marketplace is temporarily unavailable.",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "products"
    }
}
502 502 No se pudo contactar con KeyPay
{
    "success": false,
    "code": 47020,
    "message": "The Mercado service is temporarily unavailable.",
    "data": [],
    "error": []
}

Notas

  • No envies userIdentifier: la cuenta KeyPay sale de la API key autenticada.
  • Todas las rutas son POST con cuerpo JSON, incluidas las de solo lectura.
  • product_token va firmado y atado al province_id y al localities_key con los que pediste el catalogo. Caduca a los 30 minutos: no lo guardes ni lo compartas entre usuarios.
  • Sin localities_key el catalogo es de toda la provincia y el detalle no puede confirmar existencias en una bodega concreta. Manda siempre el municipio si lo conoces.
  • El carrito admite hasta 30 productos distintos y 20 unidades por producto. Muchos productos tienen ademas un minimo por bodega que el servidor aplica solo.
  • Los precios llegan sin la comision: price_includes_fee es false y fee_basis es products_subtotal. Calcula el total con los importes que devuelve el carrito, no sumando precios.
  • orders y order-get solo devuelven pedidos del Mercado, los que empiezan por MKT-. Los pedidos de Amazon no forman parte de esta API.
  • Crear el pedido no esta disponible en esta API todavia. Puedes montar el carrito, pero el cobro se cierra desde la app de KeyPay.
  • Antes de poder pedir hacen falta una direccion de envio y un perfil de facturacion guardados. Usa la familia de direcciones.
  • Las imagenes llegan como https://api.innovapp-soft.com/v2/media/<token>. Usalas tal cual en tu <img>: son publicas, no piden Authorization y se cachean una semana. No intentes construir el token ni deducir la URL de origen.
  • El producto trae el nombre en name y las traducciones en translations.es y translations.en. Si pides language=es, name y description ya vienen traducidos.
  • Cada producto pertenece a una bodega y esa bodega tiene un pedido minimo. El carrito devuelve bodega_groups y minimum_failures con lo que falta para alcanzarlo.
  • Disponible en el Sandbox: pon /sandbox delante de la ruta y usa una clave dk_test_. El catalogo de prueba tiene dos productos en Villa Clara (province_id 5, localities_key 77); llama antes a products para obtener un product_token valido.
  • En el Sandbox orders siempre viene vacio y order-get responde 404, porque el pedido no se puede crear desde esta API.
11 POST Historial de pedidos /v2/marketplace/orders
Lista los pedidos del Mercado de la cuenta, paginados y con sus estados. Solo devuelve pedidos del Mercado; los de Amazon no entran en esta API.

Lista los pedidos del Mercado de la cuenta, paginados y con sus estados. Solo devuelve pedidos del Mercado; los de Amazon no entran en esta API.

Endpoint
https://api.innovapp-soft.com/v2/marketplace/orders
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
page No integer Pagina solicitada. Empieza en 1. 1
per_page No integer Pedidos por pagina, entre 1 y 50. Por defecto 12. 20
query No string Filtra los pedidos por numero o por producto. Maximo 120 caracteres. MKT-
language No string Idioma de los textos de la respuesta: es o en. es

Ejemplo cURL

curl -X POST 'https://api.innovapp-soft.com/v2/marketplace/orders' \
  -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{"page":1,"language":"es"}'

Ejemplo JavaScript

fetch('https://api.innovapp-soft.com/v2/marketplace/orders', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx',
    'Accept': 'application/json',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
      "page": 1,
      "language": "es"
  })
}).then(r => r.json()).then(console.log);

Esquema de respuesta verificado

{
    "success": true,
    "code": "marketplace.orders.ok",
    "message": "OK",
    "data": {
        "orders": [
            {
                "id": 4471,
                "order_number": "MKT-000000",
                "status": "pending",
                "total": "dynamic",
                "created_at": "dynamic"
            }
        ],
        "pagination": {
            "page": 1,
            "per_page": 12,
            "total": "dynamic",
            "pages": "dynamic"
        },
        "status_labels": "dynamic",
        "unread_count": "dynamic"
    },
    "error": [],
    "time": "2026-09-13T10:15:00-04:00"
}

Ejemplos de error

401 401 API key ausente o invalida
{
    "success": false,
    "code": 10023,
    "message": "Unauthorized",
    "data": [],
    "error": []
}
422 422 Campo requerido o invalido
{
    "success": false,
    "code": 48003,
    "message": "Required field is missing: product_token",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "cart-add"
    }
}
403 403 La cuenta no tiene acceso al Mercado
{
    "success": false,
    "code": "marketplace.status.failed",
    "message": "No tienes acceso al Mercado.",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "status"
    }
}
503 503 Servicio temporalmente no disponible
{
    "success": false,
    "code": "marketplace.products.failed",
    "message": "Marketplace is temporarily unavailable.",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "products"
    }
}
502 502 No se pudo contactar con KeyPay
{
    "success": false,
    "code": 47020,
    "message": "The Mercado service is temporarily unavailable.",
    "data": [],
    "error": []
}

Notas

  • No envies userIdentifier: la cuenta KeyPay sale de la API key autenticada.
  • Todas las rutas son POST con cuerpo JSON, incluidas las de solo lectura.
  • product_token va firmado y atado al province_id y al localities_key con los que pediste el catalogo. Caduca a los 30 minutos: no lo guardes ni lo compartas entre usuarios.
  • Sin localities_key el catalogo es de toda la provincia y el detalle no puede confirmar existencias en una bodega concreta. Manda siempre el municipio si lo conoces.
  • El carrito admite hasta 30 productos distintos y 20 unidades por producto. Muchos productos tienen ademas un minimo por bodega que el servidor aplica solo.
  • Los precios llegan sin la comision: price_includes_fee es false y fee_basis es products_subtotal. Calcula el total con los importes que devuelve el carrito, no sumando precios.
  • orders y order-get solo devuelven pedidos del Mercado, los que empiezan por MKT-. Los pedidos de Amazon no forman parte de esta API.
  • Crear el pedido no esta disponible en esta API todavia. Puedes montar el carrito, pero el cobro se cierra desde la app de KeyPay.
  • Antes de poder pedir hacen falta una direccion de envio y un perfil de facturacion guardados. Usa la familia de direcciones.
  • Las imagenes llegan como https://api.innovapp-soft.com/v2/media/<token>. Usalas tal cual en tu <img>: son publicas, no piden Authorization y se cachean una semana. No intentes construir el token ni deducir la URL de origen.
  • El producto trae el nombre en name y las traducciones en translations.es y translations.en. Si pides language=es, name y description ya vienen traducidos.
  • Cada producto pertenece a una bodega y esa bodega tiene un pedido minimo. El carrito devuelve bodega_groups y minimum_failures con lo que falta para alcanzarlo.
  • Disponible en el Sandbox: pon /sandbox delante de la ruta y usa una clave dk_test_. El catalogo de prueba tiene dos productos en Villa Clara (province_id 5, localities_key 77); llama antes a products para obtener un product_token valido.
  • En el Sandbox orders siempre viene vacio y order-get responde 404, porque el pedido no se puede crear desde esta API.
12 POST Detalle de un pedido /v2/marketplace/order-get
Devuelve un pedido del Mercado con sus productos, direccion de entrega, facturacion, comisiones y estado.

Devuelve un pedido del Mercado con sus productos, direccion de entrega, facturacion, comisiones y estado.

Endpoint
https://api.innovapp-soft.com/v2/marketplace/order-get
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
order_id Si integer Id del pedido devuelto por orders. 4471
language No string Idioma de los textos de la respuesta: es o en. es

Ejemplo cURL

curl -X POST 'https://api.innovapp-soft.com/v2/marketplace/order-get' \
  -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{"order_id":4471,"language":"es"}'

Ejemplo JavaScript

fetch('https://api.innovapp-soft.com/v2/marketplace/order-get', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx',
    'Accept': 'application/json',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
      "order_id": 4471,
      "language": "es"
  })
}).then(r => r.json()).then(console.log);

Esquema de respuesta verificado

{
    "success": true,
    "code": "marketplace.order-get.ok",
    "message": "OK",
    "data": {
        "order": {
            "id": 4471,
            "order_number": "MKT-000000",
            "status": "pending",
            "items": [
                "dynamic"
            ],
            "address": "dynamic",
            "billing_profile": "dynamic",
            "total": "dynamic"
        },
        "status_labels": "dynamic",
        "unread_count": "dynamic"
    },
    "error": [],
    "time": "2026-09-13T10:15:00-04:00"
}

Ejemplos de error

401 401 API key ausente o invalida
{
    "success": false,
    "code": 10023,
    "message": "Unauthorized",
    "data": [],
    "error": []
}
422 422 Campo requerido o invalido
{
    "success": false,
    "code": 48003,
    "message": "Required field is missing: product_token",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "cart-add"
    }
}
403 403 La cuenta no tiene acceso al Mercado
{
    "success": false,
    "code": "marketplace.status.failed",
    "message": "No tienes acceso al Mercado.",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "status"
    }
}
503 503 Servicio temporalmente no disponible
{
    "success": false,
    "code": "marketplace.products.failed",
    "message": "Marketplace is temporarily unavailable.",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "products"
    }
}
502 502 No se pudo contactar con KeyPay
{
    "success": false,
    "code": 47020,
    "message": "The Mercado service is temporarily unavailable.",
    "data": [],
    "error": []
}

Notas

  • No envies userIdentifier: la cuenta KeyPay sale de la API key autenticada.
  • Todas las rutas son POST con cuerpo JSON, incluidas las de solo lectura.
  • product_token va firmado y atado al province_id y al localities_key con los que pediste el catalogo. Caduca a los 30 minutos: no lo guardes ni lo compartas entre usuarios.
  • Sin localities_key el catalogo es de toda la provincia y el detalle no puede confirmar existencias en una bodega concreta. Manda siempre el municipio si lo conoces.
  • El carrito admite hasta 30 productos distintos y 20 unidades por producto. Muchos productos tienen ademas un minimo por bodega que el servidor aplica solo.
  • Los precios llegan sin la comision: price_includes_fee es false y fee_basis es products_subtotal. Calcula el total con los importes que devuelve el carrito, no sumando precios.
  • orders y order-get solo devuelven pedidos del Mercado, los que empiezan por MKT-. Los pedidos de Amazon no forman parte de esta API.
  • Crear el pedido no esta disponible en esta API todavia. Puedes montar el carrito, pero el cobro se cierra desde la app de KeyPay.
  • Antes de poder pedir hacen falta una direccion de envio y un perfil de facturacion guardados. Usa la familia de direcciones.
  • Las imagenes llegan como https://api.innovapp-soft.com/v2/media/<token>. Usalas tal cual en tu <img>: son publicas, no piden Authorization y se cachean una semana. No intentes construir el token ni deducir la URL de origen.
  • El producto trae el nombre en name y las traducciones en translations.es y translations.en. Si pides language=es, name y description ya vienen traducidos.
  • Cada producto pertenece a una bodega y esa bodega tiene un pedido minimo. El carrito devuelve bodega_groups y minimum_failures con lo que falta para alcanzarlo.
  • Disponible en el Sandbox: pon /sandbox delante de la ruta y usa una clave dk_test_. El catalogo de prueba tiene dos productos en Villa Clara (province_id 5, localities_key 77); llama antes a products para obtener un product_token valido.
  • En el Sandbox orders siempre viene vacio y order-get responde 404, porque el pedido no se puede crear desde esta API.
Direcciones y facturacion

Libreta de direcciones de envio y perfil de facturacion de la cuenta KeyPay enlazada a tu API key. Es exactamente la misma libreta que usan las apps moviles: lo que guardes aqui lo ve el usuario en su app y al reves.

1 POST Campos y ubicaciones /v2/addresses/config
Devuelve el esquema de campos de direccion y de facturacion, los paises aceptados y el arbol de provincias y municipios. Pidelo antes de pintar un formulario en lugar de codificar las reglas a mano.

Devuelve el esquema de campos de direccion y de facturacion, los paises aceptados y el arbol de provincias y municipios. Pidelo antes de pintar un formulario en lugar de codificar las reglas a mano.

Endpoint
https://api.innovapp-soft.com/v2/addresses/config
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
language No string Idioma de los textos de la respuesta: es o en. es

Ejemplo cURL

curl -X POST 'https://api.innovapp-soft.com/v2/addresses/config' \
  -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{"language":"es"}'

Ejemplo JavaScript

fetch('https://api.innovapp-soft.com/v2/addresses/config', {
  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);

Esquema de respuesta verificado

{
    "success": true,
    "code": "addresses.config.ok",
    "message": "OK",
    "data": {
        "address": "dynamic",
        "addresses": [
            "dynamic"
        ],
        "address_config": {
            "country": "dynamic",
            "countries": "dynamic",
            "fields": "dynamic"
        },
        "billing_profile": "dynamic",
        "billing_config": {
            "countries": "dynamic",
            "required_fields": "dynamic"
        },
        "locations": "dynamic"
    },
    "error": [],
    "time": "2026-09-13T10:15:00-04:00"
}

Ejemplos de error

401 401 API key ausente o invalida
{
    "success": false,
    "code": 10023,
    "message": "Unauthorized",
    "data": [],
    "error": []
}
422 422 Campo requerido o invalido
{
    "success": false,
    "code": 48003,
    "message": "Required field is missing: product_token",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "cart-add"
    }
}
403 403 La cuenta no tiene acceso al Mercado
{
    "success": false,
    "code": "marketplace.status.failed",
    "message": "No tienes acceso al Mercado.",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "status"
    }
}
503 503 Servicio temporalmente no disponible
{
    "success": false,
    "code": "marketplace.products.failed",
    "message": "Marketplace is temporarily unavailable.",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "products"
    }
}
502 502 No se pudo contactar con KeyPay
{
    "success": false,
    "code": 47020,
    "message": "The Mercado service is temporarily unavailable.",
    "data": [],
    "error": []
}

Notas

  • No envies userIdentifier: la cuenta KeyPay sale de la API key autenticada.
  • Todas las rutas son POST con cuerpo JSON, incluidas las de solo lectura.
  • Solo se aceptan direcciones de CU y US. En CU la provincia y el municipio se validan contra locations y el telefono tiene que ser de 8 digitos.
  • Los campos alternate son un segundo receptor opcional, pero van en bloque: si mandas uno tienes que mandar los cuatro.
  • No hay borrado de direcciones. Las apps moviles tampoco lo tienen: se edita la que sobra o se marca otra como predeterminada.
  • save sin address_id crea; save con address_id edita esa direccion. Una direccion que ya es predeterminada no deja de serlo al editarla.
  • El perfil de facturacion es unico por cuenta: billing-save sobrescribe siempre.
  • Esta libreta es la misma que usan las apps moviles de KeyPay. Un cambio hecho por API lo ve el usuario en su app.
  • Disponible en el Sandbox: pon /sandbox delante de la ruta y usa una clave dk_test_. La libreta de prueba admite hasta 20 direcciones y valida provincia y municipio contra las ubicaciones del Sandbox, no contra las reales.
2 POST Listar direcciones /v2/addresses/list
Devuelve todas las direcciones de envio de la cuenta. address es la predeterminada y siempre es la primera de addresses.

Devuelve todas las direcciones de envio de la cuenta. address es la predeterminada y siempre es la primera de addresses.

Endpoint
https://api.innovapp-soft.com/v2/addresses/list
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
language No string Idioma de los textos de la respuesta: es o en. es

Ejemplo cURL

curl -X POST 'https://api.innovapp-soft.com/v2/addresses/list' \
  -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{"language":"es"}'

Ejemplo JavaScript

fetch('https://api.innovapp-soft.com/v2/addresses/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);

Esquema de respuesta verificado

{
    "success": true,
    "code": "addresses.list.ok",
    "message": "OK",
    "data": {
        "address": "dynamic",
        "addresses": [
            {
                "id": 12,
                "country_code": "CU",
                "first_name": "Ana",
                "last_name": "Perez Diaz",
                "phone": "55512345",
                "province": "La Habana",
                "municipality": "Playa",
                "address_line": "Calle 42 #1706 e/ 17 y 19",
                "address_extra": "Apto 3B",
                "identity_number": "85010112345",
                "neighborhood": "Miramar",
                "delivery_notes": "dynamic",
                "is_default": true,
                "created_at": "dynamic",
                "updated_at": "dynamic"
            }
        ]
    },
    "error": [],
    "time": "2026-09-13T10:15:00-04:00"
}

Ejemplos de error

401 401 API key ausente o invalida
{
    "success": false,
    "code": 10023,
    "message": "Unauthorized",
    "data": [],
    "error": []
}
422 422 Campo requerido o invalido
{
    "success": false,
    "code": 48003,
    "message": "Required field is missing: product_token",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "cart-add"
    }
}
403 403 La cuenta no tiene acceso al Mercado
{
    "success": false,
    "code": "marketplace.status.failed",
    "message": "No tienes acceso al Mercado.",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "status"
    }
}
503 503 Servicio temporalmente no disponible
{
    "success": false,
    "code": "marketplace.products.failed",
    "message": "Marketplace is temporarily unavailable.",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "products"
    }
}
502 502 No se pudo contactar con KeyPay
{
    "success": false,
    "code": 47020,
    "message": "The Mercado service is temporarily unavailable.",
    "data": [],
    "error": []
}

Notas

  • No envies userIdentifier: la cuenta KeyPay sale de la API key autenticada.
  • Todas las rutas son POST con cuerpo JSON, incluidas las de solo lectura.
  • Solo se aceptan direcciones de CU y US. En CU la provincia y el municipio se validan contra locations y el telefono tiene que ser de 8 digitos.
  • Los campos alternate son un segundo receptor opcional, pero van en bloque: si mandas uno tienes que mandar los cuatro.
  • No hay borrado de direcciones. Las apps moviles tampoco lo tienen: se edita la que sobra o se marca otra como predeterminada.
  • save sin address_id crea; save con address_id edita esa direccion. Una direccion que ya es predeterminada no deja de serlo al editarla.
  • El perfil de facturacion es unico por cuenta: billing-save sobrescribe siempre.
  • Esta libreta es la misma que usan las apps moviles de KeyPay. Un cambio hecho por API lo ve el usuario en su app.
  • Disponible en el Sandbox: pon /sandbox delante de la ruta y usa una clave dk_test_. La libreta de prueba admite hasta 20 direcciones y valida provincia y municipio contra las ubicaciones del Sandbox, no contra las reales.
3 POST Crear o editar una direccion /v2/addresses/save
Crea una direccion de envio, o edita una existente si envias address_id. La primera direccion de la cuenta queda como predeterminada automaticamente.

Crea una direccion de envio, o edita una existente si envias address_id. La primera direccion de la cuenta queda como predeterminada automaticamente.

Endpoint
https://api.innovapp-soft.com/v2/addresses/save
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
address_id No integer Id de una direccion existente. Sin el se crea una nueva; con el se edita esa. 12
country_code Si string Pais de la direccion. Solo se aceptan CU y US. CU
first_name Si string Nombre de quien recibe. Minimo 2 caracteres. Ana
last_name Si string Apellidos de quien recibe. Minimo 2 caracteres. Perez Diaz
phone Si string Telefono de contacto. En CU son 8 digitos; en US entre 7 y 15. 55512345
province Si string Provincia. En CU tiene que coincidir con una de locations. La Habana
municipality Si string Municipio. En CU tiene que pertenecer a la provincia enviada. Playa
address_line Si string Calle, numero y entre calles. Minimo 5 caracteres. Calle 42 #1706 e/ 17 y 19
address_extra No string Apartamento, piso o referencia adicional. Apto 3B
identity_number Si string Carne de identidad o documento de quien recibe. Solo letras y numeros. 85010112345
neighborhood No string Reparto o barrio. Miramar
alternate_first_name No string Nombre de un segundo receptor. Si envias uno de los campos alternate hay que enviarlos todos. Luis
alternate_last_name No string Apellidos del segundo receptor. Gomez
alternate_phone No string Telefono del segundo receptor. 55598765
alternate_identity_number No string Documento del segundo receptor. 90020254321
delivery_notes No string Indicaciones para el mensajero. Maximo 300 caracteres. Tocar el timbre del 3B
is_default No boolean Marca la direccion como predeterminada. La primera direccion de la cuenta siempre lo es. true
language No string Idioma de los textos de la respuesta: es o en. es

Ejemplo cURL

curl -X POST 'https://api.innovapp-soft.com/v2/addresses/save' \
  -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{"country_code":"CU","first_name":"Ana","last_name":"Perez Diaz","phone":"55512345","province":"La Habana","municipality":"Playa","address_line":"Calle 42 #1706 e/ 17 y 19","identity_number":"85010112345","language":"es"}'

Ejemplo JavaScript

fetch('https://api.innovapp-soft.com/v2/addresses/save', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx',
    'Accept': 'application/json',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
      "country_code": "CU",
      "first_name": "Ana",
      "last_name": "Perez Diaz",
      "phone": "55512345",
      "province": "La Habana",
      "municipality": "Playa",
      "address_line": "Calle 42 #1706 e/ 17 y 19",
      "identity_number": "85010112345",
      "language": "es"
  })
}).then(r => r.json()).then(console.log);

Esquema de respuesta verificado

{
    "success": true,
    "code": "addresses.save.ok",
    "message": "OK",
    "data": {
        "saved_address": "dynamic",
        "address": "dynamic",
        "addresses": [
            "dynamic"
        ]
    },
    "error": [],
    "time": "2026-09-13T10:15:00-04:00"
}

Ejemplos de error

401 401 API key ausente o invalida
{
    "success": false,
    "code": 10023,
    "message": "Unauthorized",
    "data": [],
    "error": []
}
422 422 Campo requerido o invalido
{
    "success": false,
    "code": 48003,
    "message": "Required field is missing: product_token",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "cart-add"
    }
}
403 403 La cuenta no tiene acceso al Mercado
{
    "success": false,
    "code": "marketplace.status.failed",
    "message": "No tienes acceso al Mercado.",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "status"
    }
}
503 503 Servicio temporalmente no disponible
{
    "success": false,
    "code": "marketplace.products.failed",
    "message": "Marketplace is temporarily unavailable.",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "products"
    }
}
502 502 No se pudo contactar con KeyPay
{
    "success": false,
    "code": 47020,
    "message": "The Mercado service is temporarily unavailable.",
    "data": [],
    "error": []
}

Notas

  • No envies userIdentifier: la cuenta KeyPay sale de la API key autenticada.
  • Todas las rutas son POST con cuerpo JSON, incluidas las de solo lectura.
  • Solo se aceptan direcciones de CU y US. En CU la provincia y el municipio se validan contra locations y el telefono tiene que ser de 8 digitos.
  • Los campos alternate son un segundo receptor opcional, pero van en bloque: si mandas uno tienes que mandar los cuatro.
  • No hay borrado de direcciones. Las apps moviles tampoco lo tienen: se edita la que sobra o se marca otra como predeterminada.
  • save sin address_id crea; save con address_id edita esa direccion. Una direccion que ya es predeterminada no deja de serlo al editarla.
  • El perfil de facturacion es unico por cuenta: billing-save sobrescribe siempre.
  • Esta libreta es la misma que usan las apps moviles de KeyPay. Un cambio hecho por API lo ve el usuario en su app.
  • Disponible en el Sandbox: pon /sandbox delante de la ruta y usa una clave dk_test_. La libreta de prueba admite hasta 20 direcciones y valida provincia y municipio contra las ubicaciones del Sandbox, no contra las reales.
4 POST Marcar como predeterminada /v2/addresses/select
Marca una direccion como predeterminada. Es la que el Mercado usa para calcular la entrega.

Marca una direccion como predeterminada. Es la que el Mercado usa para calcular la entrega.

Endpoint
https://api.innovapp-soft.com/v2/addresses/select
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
address_id Si integer Id de la direccion devuelta por list. 12
language No string Idioma de los textos de la respuesta: es o en. es

Ejemplo cURL

curl -X POST 'https://api.innovapp-soft.com/v2/addresses/select' \
  -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{"address_id":12,"language":"es"}'

Ejemplo JavaScript

fetch('https://api.innovapp-soft.com/v2/addresses/select', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx',
    'Accept': 'application/json',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
      "address_id": 12,
      "language": "es"
  })
}).then(r => r.json()).then(console.log);

Esquema de respuesta verificado

{
    "success": true,
    "code": "addresses.select.ok",
    "message": "OK",
    "data": {
        "address": "dynamic",
        "addresses": [
            "dynamic"
        ]
    },
    "error": [],
    "time": "2026-09-13T10:15:00-04:00"
}

Ejemplos de error

401 401 API key ausente o invalida
{
    "success": false,
    "code": 10023,
    "message": "Unauthorized",
    "data": [],
    "error": []
}
422 422 Campo requerido o invalido
{
    "success": false,
    "code": 48003,
    "message": "Required field is missing: product_token",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "cart-add"
    }
}
403 403 La cuenta no tiene acceso al Mercado
{
    "success": false,
    "code": "marketplace.status.failed",
    "message": "No tienes acceso al Mercado.",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "status"
    }
}
503 503 Servicio temporalmente no disponible
{
    "success": false,
    "code": "marketplace.products.failed",
    "message": "Marketplace is temporarily unavailable.",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "products"
    }
}
502 502 No se pudo contactar con KeyPay
{
    "success": false,
    "code": 47020,
    "message": "The Mercado service is temporarily unavailable.",
    "data": [],
    "error": []
}

Notas

  • No envies userIdentifier: la cuenta KeyPay sale de la API key autenticada.
  • Todas las rutas son POST con cuerpo JSON, incluidas las de solo lectura.
  • Solo se aceptan direcciones de CU y US. En CU la provincia y el municipio se validan contra locations y el telefono tiene que ser de 8 digitos.
  • Los campos alternate son un segundo receptor opcional, pero van en bloque: si mandas uno tienes que mandar los cuatro.
  • No hay borrado de direcciones. Las apps moviles tampoco lo tienen: se edita la que sobra o se marca otra como predeterminada.
  • save sin address_id crea; save con address_id edita esa direccion. Una direccion que ya es predeterminada no deja de serlo al editarla.
  • El perfil de facturacion es unico por cuenta: billing-save sobrescribe siempre.
  • Esta libreta es la misma que usan las apps moviles de KeyPay. Un cambio hecho por API lo ve el usuario en su app.
  • Disponible en el Sandbox: pon /sandbox delante de la ruta y usa una clave dk_test_. La libreta de prueba admite hasta 20 direcciones y valida provincia y municipio contra las ubicaciones del Sandbox, no contra las reales.
5 POST Ver la facturacion /v2/addresses/billing
Devuelve el perfil de facturacion de la cuenta, o null si todavia no hay ninguno.

Devuelve el perfil de facturacion de la cuenta, o null si todavia no hay ninguno.

Endpoint
https://api.innovapp-soft.com/v2/addresses/billing
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
language No string Idioma de los textos de la respuesta: es o en. es

Ejemplo cURL

curl -X POST 'https://api.innovapp-soft.com/v2/addresses/billing' \
  -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{"language":"es"}'

Ejemplo JavaScript

fetch('https://api.innovapp-soft.com/v2/addresses/billing', {
  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);

Esquema de respuesta verificado

{
    "success": true,
    "code": "addresses.billing.ok",
    "message": "OK",
    "data": {
        "billing_profile": {
            "first_name": "Ana",
            "last_name": "Perez Diaz",
            "country_code": "US",
            "identity_number": "A1234567",
            "address_line": "1200 Brickell Ave",
            "address_extra": "",
            "city": "Miami",
            "state": "FL",
            "postal_code": "33131",
            "phone": "+13055551234",
            "updated_at": "dynamic"
        }
    },
    "error": [],
    "time": "2026-09-13T10:15:00-04:00"
}

Ejemplos de error

401 401 API key ausente o invalida
{
    "success": false,
    "code": 10023,
    "message": "Unauthorized",
    "data": [],
    "error": []
}
422 422 Campo requerido o invalido
{
    "success": false,
    "code": 48003,
    "message": "Required field is missing: product_token",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "cart-add"
    }
}
403 403 La cuenta no tiene acceso al Mercado
{
    "success": false,
    "code": "marketplace.status.failed",
    "message": "No tienes acceso al Mercado.",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "status"
    }
}
503 503 Servicio temporalmente no disponible
{
    "success": false,
    "code": "marketplace.products.failed",
    "message": "Marketplace is temporarily unavailable.",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "products"
    }
}
502 502 No se pudo contactar con KeyPay
{
    "success": false,
    "code": 47020,
    "message": "The Mercado service is temporarily unavailable.",
    "data": [],
    "error": []
}

Notas

  • No envies userIdentifier: la cuenta KeyPay sale de la API key autenticada.
  • Todas las rutas son POST con cuerpo JSON, incluidas las de solo lectura.
  • Solo se aceptan direcciones de CU y US. En CU la provincia y el municipio se validan contra locations y el telefono tiene que ser de 8 digitos.
  • Los campos alternate son un segundo receptor opcional, pero van en bloque: si mandas uno tienes que mandar los cuatro.
  • No hay borrado de direcciones. Las apps moviles tampoco lo tienen: se edita la que sobra o se marca otra como predeterminada.
  • save sin address_id crea; save con address_id edita esa direccion. Una direccion que ya es predeterminada no deja de serlo al editarla.
  • El perfil de facturacion es unico por cuenta: billing-save sobrescribe siempre.
  • Esta libreta es la misma que usan las apps moviles de KeyPay. Un cambio hecho por API lo ve el usuario en su app.
  • Disponible en el Sandbox: pon /sandbox delante de la ruta y usa una clave dk_test_. La libreta de prueba admite hasta 20 direcciones y valida provincia y municipio contra las ubicaciones del Sandbox, no contra las reales.
6 POST Guardar la facturacion /v2/addresses/billing-save
Crea o reemplaza el perfil de facturacion. Solo hay uno por cuenta, asi que esta llamada siempre sobrescribe el anterior.

Crea o reemplaza el perfil de facturacion. Solo hay uno por cuenta, asi que esta llamada siempre sobrescribe el anterior.

Endpoint
https://api.innovapp-soft.com/v2/addresses/billing-save
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
first_name Si string Nombre del titular de la facturacion. Ana
last_name Si string Apellidos del titular de la facturacion. Perez Diaz
country_code Si string Pais de facturacion. Solo se aceptan CU y US. US
identity_number Si string Documento fiscal o de identidad del titular. A1234567
address_line Si string Direccion de facturacion. 1200 Brickell Ave
address_extra No string Apartamento, piso o referencia adicional. Apto 3B
city Si string Ciudad de facturacion. Miami
state Si string Estado o provincia de facturacion. FL
postal_code Si string Codigo postal. 33131
phone Si string Telefono de facturacion. +13055551234
language No string Idioma de los textos de la respuesta: es o en. es

Ejemplo cURL

curl -X POST 'https://api.innovapp-soft.com/v2/addresses/billing-save' \
  -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{"first_name":"Ana","last_name":"Perez Diaz","country_code":"US","identity_number":"A1234567","address_line":"1200 Brickell Ave","city":"Miami","state":"FL","postal_code":"33131","phone":"+13055551234","language":"es"}'

Ejemplo JavaScript

fetch('https://api.innovapp-soft.com/v2/addresses/billing-save', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx',
    'Accept': 'application/json',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
      "first_name": "Ana",
      "last_name": "Perez Diaz",
      "country_code": "US",
      "identity_number": "A1234567",
      "address_line": "1200 Brickell Ave",
      "city": "Miami",
      "state": "FL",
      "postal_code": "33131",
      "phone": "+13055551234",
      "language": "es"
  })
}).then(r => r.json()).then(console.log);

Esquema de respuesta verificado

{
    "success": true,
    "code": "addresses.billing-save.ok",
    "message": "OK",
    "data": {
        "billing_profile": "dynamic"
    },
    "error": [],
    "time": "2026-09-13T10:15:00-04:00"
}

Ejemplos de error

401 401 API key ausente o invalida
{
    "success": false,
    "code": 10023,
    "message": "Unauthorized",
    "data": [],
    "error": []
}
422 422 Campo requerido o invalido
{
    "success": false,
    "code": 48003,
    "message": "Required field is missing: product_token",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "cart-add"
    }
}
403 403 La cuenta no tiene acceso al Mercado
{
    "success": false,
    "code": "marketplace.status.failed",
    "message": "No tienes acceso al Mercado.",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "status"
    }
}
503 503 Servicio temporalmente no disponible
{
    "success": false,
    "code": "marketplace.products.failed",
    "message": "Marketplace is temporarily unavailable.",
    "data": [],
    "error": {
        "service": "marketplace",
        "action": "products"
    }
}
502 502 No se pudo contactar con KeyPay
{
    "success": false,
    "code": 47020,
    "message": "The Mercado service is temporarily unavailable.",
    "data": [],
    "error": []
}

Notas

  • No envies userIdentifier: la cuenta KeyPay sale de la API key autenticada.
  • Todas las rutas son POST con cuerpo JSON, incluidas las de solo lectura.
  • Solo se aceptan direcciones de CU y US. En CU la provincia y el municipio se validan contra locations y el telefono tiene que ser de 8 digitos.
  • Los campos alternate son un segundo receptor opcional, pero van en bloque: si mandas uno tienes que mandar los cuatro.
  • No hay borrado de direcciones. Las apps moviles tampoco lo tienen: se edita la que sobra o se marca otra como predeterminada.
  • save sin address_id crea; save con address_id edita esa direccion. Una direccion que ya es predeterminada no deja de serlo al editarla.
  • El perfil de facturacion es unico por cuenta: billing-save sobrescribe siempre.
  • Esta libreta es la misma que usan las apps moviles de KeyPay. Un cambio hecho por API lo ve el usuario en su app.
  • Disponible en el Sandbox: pon /sandbox delante de la ruta y usa una clave dk_test_. La libreta de prueba admite hasta 20 direcciones y valida provincia y municipio contra las ubicaciones del Sandbox, no contra las reales.
Store V2 · Catálogo general KeyStore

Empieza aquí para conocer todos los productos habilitados antes de abrir un flujo específico.

1 POST Catálogo completo /v2/store/catalog/list
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.

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.

Endpoint
https://api.innovapp-soft.com/v2/store/catalog/list
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
language No string Idioma de la respuesta: es o en. es

Ejemplo cURL

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 JavaScript

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);

Esquema de respuesta verificado

[
    {
        "success": "boolean",
        "code": "string | integer",
        "message": "string",
        "data": "{items:[native catalog row],count:int}",
        "error": "object | array",
        "time": "object"
    },
    []
]

Ejemplos de error

401 API key invalida
{
    "success": false,
    "code": 40101,
    "message": "Invalid API key."
}
422 Parametro requerido
{
    "success": false,
    "code": 47017,
    "message": "Required field is missing: client_purchase_id"
}
502 Servicio temporalmente no disponible
{
    "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.
  • Esquema parcial verificado en el código de KeyPay. Los valores dynamic se resuelven en ejecución; no representan una respuesta JSON de producción. Los datos externos sin contrato verificable se omiten.
Store V2 · Recargas internacionales

Flujo recomendado: consultar catálogo, validar promoción si existe, comprar y después consultar la orden o su estado.

1 POST Consultar catálogo /v2/store/topups/catalog
Recargas internacionales: Lista paises, operadores y ofertas. Usa mode=countries para iniciar; despues envia country y finalmente country + brand.

Recargas internacionales: Lista paises, operadores y ofertas. Usa mode=countries para iniciar; despues envia country y finalmente country + brand.

Endpoint
https://api.innovapp-soft.com/v2/store/topups/catalog
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
mode No string Vista del catalogo. En eSIM usa countries para listar destinos y plans (u offers como alias) para listar los planes del country enviado. countries
country Depende string Codigo ISO 3166-1 alpha-2 del pais. En el catalogo eSIM es obligatorio cuando mode es plans u offers. CU
brand Depende string Marca u operador devuelto por el catalogo. Cubacel
sub_type No string Subtipo de producto dentro de una marca. MOBILE
language No string Idioma de la respuesta: es o en. es

Ejemplo cURL

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 JavaScript

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);

Esquema de respuesta verificado

[
    {
        "success": "boolean",
        "code": "string | integer",
        "message": "string",
        "data": "Mode/resource-specific local object; catalog arrays are named data, not generic items. See controller source and local model.",
        "error": "object | array",
        "time": "object"
    },
    {
        "topup_offer": {
            "offer_id": "dynamic",
            "source": "dynamic",
            "name": "dynamic",
            "notes": "dynamic",
            "sent_benefits": "dynamic",
            "sub_type": "dynamic",
            "price_type": "dynamic",
            "margin_percent": "dynamic",
            "is_promotional": "dynamic",
            "promotion_label": "dynamic",
            "price": "dynamic",
            "amount_min": "dynamic",
            "amount_max": "dynamic",
            "provider_service_fee_percent": "dynamic",
            "price_min": "dynamic",
            "price_max": "dynamic"
        }
    }
]

Ejemplos de error

401 API key invalida
{
    "success": false,
    "code": 40101,
    "message": "Invalid API key."
}
422 Parametro requerido
{
    "success": false,
    "code": 47017,
    "message": "Required field is missing: client_purchase_id"
}
502 Servicio temporalmente no disponible
{
    "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.
  • Esquema parcial verificado en el código de KeyPay. Los valores dynamic se resuelven en ejecución; no representan una respuesta JSON de producción. Los datos externos sin contrato verificable se omiten.
2 POST Validar promoción /v2/store/topups/promo
Recargas internacionales: Valida un codigo promocional para una oferta antes de comprar.

Recargas internacionales: Valida un codigo promocional para una oferta antes de comprar.

Endpoint
https://api.innovapp-soft.com/v2/store/topups/promo
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
country Depende string Codigo ISO 3166-1 alpha-2 del pais. En el catalogo eSIM es obligatorio cuando mode es plans u offers. CU
brand Depende string Marca u operador devuelto por el catalogo. Cubacel
offer_id Si en compra string Identificador exacto de la oferta seleccionada. 61
promo_code Depende string Codigo promocional que se desea validar o aplicar. PROMO2026
amount No number Monto elegido cuando la oferta permite un rango. 25.00
language No string Idioma de la respuesta: es o en. es

Ejemplo cURL

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 JavaScript

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);

Esquema de respuesta verificado

[
    {
        "success": "boolean",
        "code": "string | integer",
        "message": "string",
        "data": "Direct record fields under Developer data (no extra order wrapper). Status adds credito; eSIM/number status adds poll_after_seconds.",
        "error": "object | array",
        "time": "object"
    },
    []
]

Ejemplos de error

401 API key invalida
{
    "success": false,
    "code": 40101,
    "message": "Invalid API key."
}
422 Parametro requerido
{
    "success": false,
    "code": 47017,
    "message": "Required field is missing: client_purchase_id"
}
502 Servicio temporalmente no disponible
{
    "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.
  • Esquema parcial verificado en el código de KeyPay. Los valores dynamic se resuelven en ejecución; no representan una respuesta JSON de producción. Los datos externos sin contrato verificable se omiten.
3 POST Comprar /v2/store/topups/buy
Recargas internacionales: Compra una recarga internacional. client_purchase_id hace la operacion idempotente y no debe reutilizarse para otra compra.

Recargas internacionales: Compra una recarga internacional. client_purchase_id hace la operacion idempotente y no debe reutilizarse para otra compra.

Endpoint
https://api.innovapp-soft.com/v2/store/topups/buy
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
country Depende string Codigo ISO 3166-1 alpha-2 del pais. En el catalogo eSIM es obligatorio cuando mode es plans u offers. CU
brand Depende string Marca u operador devuelto por el catalogo. Cubacel
offer_id Si en compra string Identificador exacto de la oferta seleccionada. 61
phone_number Si en compra string Numero de telefono que recibira la recarga. +5351234567
client_purchase_id Si en compra string Idempotency key unica creada por tu sistema para esta compra. order-2026-000184
promo_code Depende string Codigo promocional que se desea validar o aplicar. PROMO2026
amount No number Monto elegido cuando la oferta permite un rango. 25.00
language No string Idioma de la respuesta: es o en. es

Ejemplo cURL

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 JavaScript

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);

Esquema de respuesta verificado

[
    {
        "success": "boolean",
        "code": "string | integer",
        "message": "string",
        "data": "Direct record fields under Developer data (no extra order wrapper). Status adds credito; eSIM/number status adds poll_after_seconds.",
        "error": "object | array",
        "time": "object"
    },
    {
        "topup_buy_pending": {
            "order_id": "dynamic",
            "order_status": "dynamic",
            "brand": "dynamic",
            "sent_benefits": "dynamic",
            "phone_masked": "dynamic",
            "charged_amount": "dynamic",
            "price_before_discount": "dynamic",
            "discount_amount": "dynamic",
            "promo_code": "dynamic",
            "credito": "dynamic"
        }
    }
]

Ejemplos de error

401 API key invalida
{
    "success": false,
    "code": 40101,
    "message": "Invalid API key."
}
422 Parametro requerido
{
    "success": false,
    "code": 47017,
    "message": "Required field is missing: client_purchase_id"
}
502 Servicio temporalmente no disponible
{
    "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.
  • Esquema parcial verificado en el código de KeyPay. Los valores dynamic se resuelven en ejecución; no representan una respuesta JSON de producción. Los datos externos sin contrato verificable se omiten.
4 POST Consultar órdenes /v2/store/topups/orders
Recargas internacionales: Devuelve el historial paginado de recargas del usuario KeyPay vinculado al developer.

Recargas internacionales: Devuelve el historial paginado de recargas del usuario KeyPay vinculado al developer.

Endpoint
https://api.innovapp-soft.com/v2/store/topups/orders
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
page No integer Pagina del historial. 1
per_page No integer Resultados por pagina, maximo 100. 20
language No string Idioma de la respuesta: es o en. es

Ejemplo cURL

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 JavaScript

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);

Esquema de respuesta verificado

[
    {
        "success": "boolean",
        "code": "string | integer",
        "message": "string",
        "data": "{data:[record],page,per_page,total,total_pages}",
        "error": "object | array",
        "time": "object"
    },
    {
        "topup_order": {
            "order_id": "dynamic",
            "order_status": "dynamic",
            "country": "dynamic",
            "brand": "dynamic",
            "offer_name": "dynamic",
            "sent_benefits": "dynamic",
            "phone_masked": "dynamic",
            "requested_amount": "dynamic",
            "charged_amount": "dynamic",
            "price_before_discount": "dynamic",
            "discount_amount": "dynamic",
            "promo_code": "dynamic",
            "mensaje": "dynamic"
        }
    }
]

Ejemplos de error

401 API key invalida
{
    "success": false,
    "code": 40101,
    "message": "Invalid API key."
}
422 Parametro requerido
{
    "success": false,
    "code": 47017,
    "message": "Required field is missing: client_purchase_id"
}
502 Servicio temporalmente no disponible
{
    "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.
  • Esquema parcial verificado en el código de KeyPay. Los valores dynamic se resuelven en ejecución; no representan una respuesta JSON de producción. Los datos externos sin contrato verificable se omiten.
5 POST Consultar estado /v2/store/topups/status
Recargas internacionales: Consulta el estado actualizado de una recarga.

Recargas internacionales: Consulta el estado actualizado de una recarga.

Endpoint
https://api.innovapp-soft.com/v2/store/topups/status
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
order_id Si en status string Identificador de la orden devuelto al crearla. 1842
language No string Idioma de la respuesta: es o en. es

Ejemplo cURL

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 JavaScript

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);

Esquema de respuesta verificado

[
    {
        "success": "boolean",
        "code": "string | integer",
        "message": "string",
        "data": "Direct record fields under Developer data (no extra order wrapper). Status adds credito; eSIM/number status adds poll_after_seconds.",
        "error": "object | array",
        "time": "object"
    },
    {
        "topup_order": {
            "order_id": "dynamic",
            "order_status": "dynamic",
            "country": "dynamic",
            "brand": "dynamic",
            "offer_name": "dynamic",
            "sent_benefits": "dynamic",
            "phone_masked": "dynamic",
            "requested_amount": "dynamic",
            "charged_amount": "dynamic",
            "price_before_discount": "dynamic",
            "discount_amount": "dynamic",
            "promo_code": "dynamic",
            "mensaje": "dynamic"
        }
    }
]

Ejemplos de error

401 API key invalida
{
    "success": false,
    "code": 40101,
    "message": "Invalid API key."
}
422 Parametro requerido
{
    "success": false,
    "code": 47017,
    "message": "Required field is missing: client_purchase_id"
}
502 Servicio temporalmente no disponible
{
    "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.
  • Esquema parcial verificado en el código de KeyPay. Los valores dynamic se resuelven en ejecución; no representan una respuesta JSON de producción. Los datos externos sin contrato verificable se omiten.
Store V2 · Gift Cards

Flujo recomendado: consultar marcas y ofertas, comprar y después consultar las órdenes o el estado de entrega.

1 POST Consultar catálogo /v2/store/giftcards/catalog
Gift Cards: Lista marcas y ofertas de Gift Cards V2 por pais, categoria o busqueda.

Gift Cards: Lista marcas y ofertas de Gift Cards V2 por pais, categoria o busqueda.

Endpoint
https://api.innovapp-soft.com/v2/store/giftcards/catalog
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
mode No string Vista del catalogo. En eSIM usa countries para listar destinos y plans (u offers como alias) para listar los planes del country enviado. countries
country Depende string Codigo ISO 3166-1 alpha-2 del pais. En el catalogo eSIM es obligatorio cuando mode es plans u offers. CU
brand Depende string Marca u operador devuelto por el catalogo. Cubacel
query No string Texto para filtrar el catalogo. BRAND_FROM_CATALOG
category No string Categoria del catalogo. Gaming
page No integer Pagina del historial. 1
per_page No integer Resultados por pagina, maximo 100. 20
language No string Idioma de la respuesta: es o en. es

Ejemplo cURL

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 JavaScript

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);

Esquema de respuesta verificado

[
    {
        "success": "boolean",
        "code": "string | integer",
        "message": "string",
        "data": "Mode/resource-specific local object; catalog arrays are named data, not generic items. See controller source and local model.",
        "error": "object | array",
        "time": "object"
    },
    {
        "giftcard_offer": {
            "id": "dynamic",
            "offer_id": "dynamic",
            "name": "dynamic",
            "notes": "dynamic",
            "sent_benefits": "dynamic",
            "sub_type": "dynamic",
            "price_type": "dynamic",
            "denomination": "dynamic",
            "currency": "dynamic",
            "price": "dynamic",
            "fee_percent": "dynamic",
            "image": "dynamic"
        }
    }
]

Ejemplos de error

401 API key invalida
{
    "success": false,
    "code": 40101,
    "message": "Invalid API key."
}
422 Parametro requerido
{
    "success": false,
    "code": 47017,
    "message": "Required field is missing: client_purchase_id"
}
502 Servicio temporalmente no disponible
{
    "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.
  • Esquema parcial verificado en el código de KeyPay. Los valores dynamic se resuelven en ejecución; no representan una respuesta JSON de producción. Los datos externos sin contrato verificable se omiten.
2 POST Comprar /v2/store/giftcards/buy
Gift Cards: Compra una Gift Card fija o de rango. KeyPay requiere amount mayor que cero.

Gift Cards: Compra una Gift Card fija o de rango. KeyPay requiere amount mayor que cero.

Endpoint
https://api.innovapp-soft.com/v2/store/giftcards/buy
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
brand Depende string Marca u operador devuelto por el catalogo. Cubacel
country Depende string Codigo ISO 3166-1 alpha-2 del pais. En el catalogo eSIM es obligatorio cuando mode es plans u offers. CU
offer_id Si en compra string Identificador exacto de la oferta seleccionada. 61
client_purchase_id Si en compra string Idempotency key unica creada por tu sistema para esta compra. order-2026-000184
amount number Importe mayor que cero requerido por KeyPay para la compra. 25.00
language No string Idioma de la respuesta: es o en. es

Ejemplo cURL

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":"BRAND_FROM_CATALOG","country":"US","offer_id":"OFFER_ID_FROM_CATALOG","client_purchase_id":"gift-2026-000184","amount":25,"language":"es"}'

Ejemplo JavaScript

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": "BRAND_FROM_CATALOG",
    "country": "US",
    "offer_id": "OFFER_ID_FROM_CATALOG",
    "client_purchase_id": "gift-2026-000184",
    "amount": 25,
    "language": "es"
})
}).then(r => r.json()).then(console.log);

Esquema de respuesta verificado

[
    {
        "success": "boolean",
        "code": "string | integer",
        "message": "string",
        "data": "Direct record fields under Developer data (no extra order wrapper). Status adds credito; eSIM/number status adds poll_after_seconds.",
        "error": "object | array",
        "time": "object"
    },
    {
        "giftcard_order": {
            "order_id": "dynamic",
            "order_status": "dynamic",
            "brand": "dynamic",
            "country": "dynamic",
            "denomination": "dynamic",
            "charged_amount": "dynamic",
            "mensaje": "dynamic",
            "details": "dynamic"
        },
        "giftcard_detail": {
            "titulo": "dynamic",
            "value": "dynamic",
            "copy": "dynamic",
            "url": "dynamic"
        }
    }
]

Ejemplos de error

401 API key invalida
{
    "success": false,
    "code": 40101,
    "message": "Invalid API key."
}
422 Parametro requerido
{
    "success": false,
    "code": 47017,
    "message": "Required field is missing: client_purchase_id"
}
502 Servicio temporalmente no disponible
{
    "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.
  • Esquema parcial verificado en el código de KeyPay. Los valores dynamic se resuelven en ejecución; no representan una respuesta JSON de producción. Los datos externos sin contrato verificable se omiten.
3 POST Consultar órdenes /v2/store/giftcards/orders
Gift Cards: Devuelve las ordenes de Gift Cards del usuario vinculado.

Gift Cards: Devuelve las ordenes de Gift Cards del usuario vinculado.

Endpoint
https://api.innovapp-soft.com/v2/store/giftcards/orders
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
page No integer Pagina del historial. 1
per_page No integer Resultados por pagina, maximo 100. 20
language No string Idioma de la respuesta: es o en. es

Ejemplo cURL

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 JavaScript

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);

Esquema de respuesta verificado

[
    {
        "success": "boolean",
        "code": "string | integer",
        "message": "string",
        "data": "{data:[record],page,per_page,total,total_pages}",
        "error": "object | array",
        "time": "object"
    },
    {
        "giftcard_order": {
            "order_id": "dynamic",
            "order_status": "dynamic",
            "brand": "dynamic",
            "country": "dynamic",
            "denomination": "dynamic",
            "charged_amount": "dynamic",
            "mensaje": "dynamic",
            "details": "dynamic"
        },
        "giftcard_detail": {
            "titulo": "dynamic",
            "value": "dynamic",
            "copy": "dynamic",
            "url": "dynamic"
        }
    }
]

Ejemplos de error

401 API key invalida
{
    "success": false,
    "code": 40101,
    "message": "Invalid API key."
}
422 Parametro requerido
{
    "success": false,
    "code": 47017,
    "message": "Required field is missing: client_purchase_id"
}
502 Servicio temporalmente no disponible
{
    "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.
  • Esquema parcial verificado en el código de KeyPay. Los valores dynamic se resuelven en ejecución; no representan una respuesta JSON de producción. Los datos externos sin contrato verificable se omiten.
4 POST Consultar estado /v2/store/giftcards/status
Gift Cards: Consulta una orden y sus datos de entrega cuando ya estan disponibles.

Gift Cards: Consulta una orden y sus datos de entrega cuando ya estan disponibles.

Endpoint
https://api.innovapp-soft.com/v2/store/giftcards/status
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
order_id Si en status string Identificador de la orden devuelto al crearla. 1842
language No string Idioma de la respuesta: es o en. es

Ejemplo cURL

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 JavaScript

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);

Esquema de respuesta verificado

[
    {
        "success": "boolean",
        "code": "string | integer",
        "message": "string",
        "data": "Direct record fields under Developer data (no extra order wrapper). Status adds credito; eSIM/number status adds poll_after_seconds.",
        "error": "object | array",
        "time": "object"
    },
    {
        "giftcard_order": {
            "order_id": "dynamic",
            "order_status": "dynamic",
            "brand": "dynamic",
            "country": "dynamic",
            "denomination": "dynamic",
            "charged_amount": "dynamic",
            "mensaje": "dynamic",
            "details": "dynamic"
        },
        "giftcard_detail": {
            "titulo": "dynamic",
            "value": "dynamic",
            "copy": "dynamic",
            "url": "dynamic"
        }
    }
]

Ejemplos de error

401 API key invalida
{
    "success": false,
    "code": 40101,
    "message": "Invalid API key."
}
422 Parametro requerido
{
    "success": false,
    "code": 47017,
    "message": "Required field is missing: client_purchase_id"
}
502 Servicio temporalmente no disponible
{
    "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.
  • Esquema parcial verificado en el código de KeyPay. Los valores dynamic se resuelven en ejecución; no representan una respuesta JSON de producción. Los datos externos sin contrato verificable se omiten.
Store V2 · Servicios IMEI

Flujo recomendado: consultar servicios y campos requeridos, crear la solicitud y después revisar su resultado.

1 POST Consultar catálogo /v2/store/imei/catalog
Servicios IMEI: Lista los servicios IMEI disponibles y los campos que requiere cada uno.

Servicios IMEI: Lista los servicios IMEI disponibles y los campos que requiere cada uno.

Endpoint
https://api.innovapp-soft.com/v2/store/imei/catalog
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
page No integer Pagina del historial. 1
per_page No integer Resultados por pagina, maximo 100. 20
search No string Texto para buscar un servicio IMEI. iPhone
language No string Idioma de la respuesta: es o en. es

Ejemplo cURL

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 JavaScript

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);

Esquema de respuesta verificado

[
    {
        "success": "boolean",
        "code": "string | integer",
        "message": "string",
        "data": "Mode/resource-specific local object; catalog arrays are named data, not generic items. See controller source and local model.",
        "error": "object | array",
        "time": "object"
    },
    {
        "imei_offer": {
            "id": "dynamic",
            "service_id": "dynamic",
            "titulo": "dynamic",
            "detalles": "dynamic",
            "categoria": "dynamic",
            "precio": "dynamic",
            "discoin": "dynamic",
            "currency": "dynamic",
            "disponibles": "dynamic",
            "input": "dynamic",
            "inputtypes": "dynamic",
            "required_input_type": "dynamic"
        }
    }
]

Ejemplos de error

401 API key invalida
{
    "success": false,
    "code": 40101,
    "message": "Invalid API key."
}
422 Parametro requerido
{
    "success": false,
    "code": 47017,
    "message": "Required field is missing: client_purchase_id"
}
502 Servicio temporalmente no disponible
{
    "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.
  • Esquema parcial verificado en el código de KeyPay. Los valores dynamic se resuelven en ejecución; no representan una respuesta JSON de producción. Los datos externos sin contrato verificable se omiten.
2 POST Comprar /v2/store/imei/buy
Servicios IMEI: Solicita un servicio IMEI. Envia input con los mismos nombres de campo entregados por el catalogo.

Servicios IMEI: Solicita un servicio IMEI. Envia input con los mismos nombres de campo entregados por el catalogo.

Endpoint
https://api.innovapp-soft.com/v2/store/imei/buy
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
service_id Si en compra string Identificador del servicio IMEI. 115
device_id Depende string IMEI, serial u otro identificador solicitado por el servicio. 356938035643809
input Depende object Campos dinamicos solicitados por el servicio IMEI. {"IMEI":"356938035643809"}
client_purchase_id Si en compra string Idempotency key unica creada por tu sistema para esta compra. order-2026-000184
language No string Idioma de la respuesta: es o en. es

Ejemplo cURL

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 JavaScript

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);

Esquema de respuesta verificado

[
    {
        "success": "boolean",
        "code": "string | integer",
        "message": "string",
        "data": "Direct record fields under Developer data (no extra order wrapper). Status adds credito; eSIM/number status adds poll_after_seconds.",
        "error": "object | array",
        "time": "object"
    },
    {
        "imei_order": {
            "order_id": "dynamic",
            "order_status": "dynamic",
            "service_id": "dynamic",
            "service_name": "dynamic",
            "device_id": "dynamic",
            "charged_amount": "dynamic",
            "created_at": "dynamic",
            "completed_at": "dynamic",
            "details": "dynamic",
            "mensaje": "dynamic"
        }
    }
]

Ejemplos de error

401 API key invalida
{
    "success": false,
    "code": 40101,
    "message": "Invalid API key."
}
422 Parametro requerido
{
    "success": false,
    "code": 47017,
    "message": "Required field is missing: client_purchase_id"
}
502 Servicio temporalmente no disponible
{
    "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.
  • Esquema parcial verificado en el código de KeyPay. Los valores dynamic se resuelven en ejecución; no representan una respuesta JSON de producción. Los datos externos sin contrato verificable se omiten.
3 POST Consultar órdenes /v2/store/imei/orders
Servicios IMEI: Devuelve el historial paginado de solicitudes IMEI.

Servicios IMEI: Devuelve el historial paginado de solicitudes IMEI.

Endpoint
https://api.innovapp-soft.com/v2/store/imei/orders
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
page No integer Pagina del historial. 1
per_page No integer Resultados por pagina, maximo 100. 20
language No string Idioma de la respuesta: es o en. es

Ejemplo cURL

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 JavaScript

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);

Esquema de respuesta verificado

[
    {
        "success": "boolean",
        "code": "string | integer",
        "message": "string",
        "data": "{data:[record],pagination:{page,per_page,total,total_pages,has_more}}",
        "error": "object | array",
        "time": "object"
    },
    {
        "imei_order": {
            "order_id": "dynamic",
            "order_status": "dynamic",
            "service_id": "dynamic",
            "service_name": "dynamic",
            "device_id": "dynamic",
            "charged_amount": "dynamic",
            "created_at": "dynamic",
            "completed_at": "dynamic",
            "details": "dynamic",
            "mensaje": "dynamic"
        }
    }
]

Ejemplos de error

401 API key invalida
{
    "success": false,
    "code": 40101,
    "message": "Invalid API key."
}
422 Parametro requerido
{
    "success": false,
    "code": 47017,
    "message": "Required field is missing: client_purchase_id"
}
502 Servicio temporalmente no disponible
{
    "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.
  • Esquema parcial verificado en el código de KeyPay. Los valores dynamic se resuelven en ejecución; no representan una respuesta JSON de producción. Los datos externos sin contrato verificable se omiten.
4 POST Consultar estado /v2/store/imei/status
Servicios IMEI: Consulta el estado y el resultado de una solicitud IMEI.

Servicios IMEI: Consulta el estado y el resultado de una solicitud IMEI.

Endpoint
https://api.innovapp-soft.com/v2/store/imei/status
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
order_id Si en status string Identificador de la orden devuelto al crearla. 1842
language No string Idioma de la respuesta: es o en. es

Ejemplo cURL

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 JavaScript

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);

Esquema de respuesta verificado

[
    {
        "success": "boolean",
        "code": "string | integer",
        "message": "string",
        "data": "Direct record fields under Developer data (no extra order wrapper). Status adds credito; eSIM/number status adds poll_after_seconds.",
        "error": "object | array",
        "time": "object"
    },
    {
        "imei_order": {
            "order_id": "dynamic",
            "order_status": "dynamic",
            "service_id": "dynamic",
            "service_name": "dynamic",
            "device_id": "dynamic",
            "charged_amount": "dynamic",
            "created_at": "dynamic",
            "completed_at": "dynamic",
            "details": "dynamic",
            "mensaje": "dynamic"
        }
    }
]

Ejemplos de error

401 API key invalida
{
    "success": false,
    "code": 40101,
    "message": "Invalid API key."
}
422 Parametro requerido
{
    "success": false,
    "code": 47017,
    "message": "Required field is missing: client_purchase_id"
}
502 Servicio temporalmente no disponible
{
    "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.
  • Esquema parcial verificado en el código de KeyPay. Los valores dynamic se resuelven en ejecución; no representan una respuesta JSON de producción. Los datos externos sin contrato verificable se omiten.
Store V2 · eSIM

Flujo recomendado: consultar destinos y planes, comprar la eSIM y después consultar sus datos de instalación.

1 POST Consultar catálogo /v2/store/esim/catalog
eSIM: Consulta los paises o los planes disponibles del catalogo eSIM.

eSIM: Consulta los paises o los planes disponibles del catalogo eSIM.

Endpoint
https://api.innovapp-soft.com/v2/store/esim/catalog
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
mode No enum<string> Valores permitidos: countries (lista paises), plans (lista planes del country) y offers (alias de plans). Predeterminado: countries. plans
country Si para plans/offers string(2) Codigo ISO 3166-1 alpha-2. Omitir con countries; obligatorio con plans u offers. US
language No string Idioma de la respuesta: es o en. es

Ejemplo cURL

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":"plans","country":"US","language":"es"}'

Ejemplo JavaScript

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": "plans",
    "country": "US",
    "language": "es"
})
}).then(r => r.json()).then(console.log);

Esquema de respuesta verificado

[
    {
        "success": "boolean",
        "code": "string | integer",
        "message": "string",
        "data": "Mode/resource-specific local object; catalog arrays are named data, not generic items. See controller source and local model.",
        "error": "object | array",
        "time": "object"
    },
    {
        "esim_offer": {
            "id": "dynamic",
            "offer_id": "dynamic",
            "name": "dynamic",
            "sent_benefits": "dynamic",
            "region": "dynamic",
            "sub_type": "dynamic",
            "price_type": "dynamic",
            "price": "dynamic",
            "fee_percent": "dynamic"
        }
    }
]

Ejemplos de error

401 API key invalida
{
    "success": false,
    "code": 40101,
    "message": "Invalid API key."
}
422 Parametro requerido
{
    "success": false,
    "code": 47017,
    "message": "Required field is missing: client_purchase_id"
}
502 Servicio temporalmente no disponible
{
    "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.
  • Esquema parcial verificado en el código de KeyPay. Los valores dynamic se resuelven en ejecución; no representan una respuesta JSON de producción. Los datos externos sin contrato verificable se omiten.
2 POST Comprar /v2/store/esim/buy
eSIM: Compra uno de los planes devueltos por el catalogo eSIM.

eSIM: Compra uno de los planes devueltos por el catalogo eSIM.

Endpoint
https://api.innovapp-soft.com/v2/store/esim/buy
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
country Si string(2) Mismo codigo ISO utilizado para consultar los planes. US
offer_id Si string Valor exacto de offer_id devuelto por el catalogo con mode=plans. OFFER_ID_FROM_CATALOG
client_purchase_id Si string(8..100) Clave de idempotencia creada por tu sistema. Admite letras, numeros, punto, guion bajo, dos puntos y guion. Reutilizar solo al reintentar la misma compra. esim-2026-000184
language No string Idioma de la respuesta: es o en. es

Ejemplo cURL

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":"OFFER_ID_FROM_CATALOG","client_purchase_id":"esim-2026-000184","language":"es"}'

Ejemplo JavaScript

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": "OFFER_ID_FROM_CATALOG",
    "client_purchase_id": "esim-2026-000184",
    "language": "es"
})
}).then(r => r.json()).then(console.log);

Esquema de respuesta verificado

[
    {
        "success": "boolean",
        "code": "string | integer",
        "message": "string",
        "data": "Direct record fields under Developer data (no extra order wrapper). Status adds credito; eSIM/number status adds poll_after_seconds.",
        "error": "object | array",
        "time": "object"
    },
    {
        "esim_order": {
            "order_id": "dynamic",
            "order_status": "dynamic",
            "country": "dynamic",
            "offer_id": "dynamic",
            "plan": "dynamic",
            "region": "dynamic",
            "sub_type": "dynamic",
            "charged_amount": "dynamic",
            "mensaje": "dynamic",
            "activation": "dynamic"
        },
        "esim_activation": {
            "lpa": "dynamic",
            "smdp_address": "dynamic",
            "activation_code": "dynamic",
            "iccid": "dynamic"
        }
    }
]

Ejemplos de error

401 API key invalida
{
    "success": false,
    "code": 40101,
    "message": "Invalid API key."
}
422 Parametro requerido
{
    "success": false,
    "code": 47017,
    "message": "Required field is missing: client_purchase_id"
}
502 Servicio temporalmente no disponible
{
    "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.
  • Esquema parcial verificado en el código de KeyPay. Los valores dynamic se resuelven en ejecución; no representan una respuesta JSON de producción. Los datos externos sin contrato verificable se omiten.
3 POST Consultar órdenes /v2/store/esim/orders
eSIM: Devuelve las ordenes eSIM del usuario vinculado.

eSIM: Devuelve las ordenes eSIM del usuario vinculado.

Endpoint
https://api.innovapp-soft.com/v2/store/esim/orders
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
page No integer Pagina del historial. 1
per_page No integer Resultados por pagina, maximo 100. 20
language No string Idioma de la respuesta: es o en. es

Ejemplo cURL

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 JavaScript

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);

Esquema de respuesta verificado

[
    {
        "success": "boolean",
        "code": "string | integer",
        "message": "string",
        "data": "{data:[record],page,per_page,total,total_pages}",
        "error": "object | array",
        "time": "object"
    },
    {
        "esim_order": {
            "order_id": "dynamic",
            "order_status": "dynamic",
            "country": "dynamic",
            "offer_id": "dynamic",
            "plan": "dynamic",
            "region": "dynamic",
            "sub_type": "dynamic",
            "charged_amount": "dynamic",
            "mensaje": "dynamic",
            "activation": "dynamic"
        },
        "esim_activation": {
            "lpa": "dynamic",
            "smdp_address": "dynamic",
            "activation_code": "dynamic",
            "iccid": "dynamic"
        }
    }
]

Ejemplos de error

401 API key invalida
{
    "success": false,
    "code": 40101,
    "message": "Invalid API key."
}
422 Parametro requerido
{
    "success": false,
    "code": 47017,
    "message": "Required field is missing: client_purchase_id"
}
502 Servicio temporalmente no disponible
{
    "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.
  • Esquema parcial verificado en el código de KeyPay. Los valores dynamic se resuelven en ejecución; no representan una respuesta JSON de producción. Los datos externos sin contrato verificable se omiten.
4 POST Consultar estado /v2/store/esim/status
eSIM: Consulta una orden eSIM y sus datos de instalacion cuando esten disponibles.

eSIM: Consulta una orden eSIM y sus datos de instalacion cuando esten disponibles.

Endpoint
https://api.innovapp-soft.com/v2/store/esim/status
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
order_id Si string Identificador publico devuelto por la compra; comienza con esimv2_. esimv2_0123456789abcdef0123456789abcdef
language No string Idioma de la respuesta: es o en. es

Ejemplo cURL

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":"esimv2_0123456789abcdef0123456789abcdef","language":"es"}'

Ejemplo JavaScript

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": "esimv2_0123456789abcdef0123456789abcdef",
    "language": "es"
})
}).then(r => r.json()).then(console.log);

Esquema de respuesta verificado

[
    {
        "success": "boolean",
        "code": "string | integer",
        "message": "string",
        "data": "Direct record fields under Developer data (no extra order wrapper). Status adds credito; eSIM/number status adds poll_after_seconds.",
        "error": "object | array",
        "time": "object"
    },
    {
        "esim_order": {
            "order_id": "dynamic",
            "order_status": "dynamic",
            "country": "dynamic",
            "offer_id": "dynamic",
            "plan": "dynamic",
            "region": "dynamic",
            "sub_type": "dynamic",
            "charged_amount": "dynamic",
            "mensaje": "dynamic",
            "activation": "dynamic"
        },
        "esim_activation": {
            "lpa": "dynamic",
            "smdp_address": "dynamic",
            "activation_code": "dynamic",
            "iccid": "dynamic"
        }
    }
]

Ejemplos de error

401 API key invalida
{
    "success": false,
    "code": 40101,
    "message": "Invalid API key."
}
422 Parametro requerido
{
    "success": false,
    "code": 47017,
    "message": "Required field is missing: client_purchase_id"
}
502 Servicio temporalmente no disponible
{
    "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.
  • Esquema parcial verificado en el código de KeyPay. Los valores dynamic se resuelven en ejecución; no representan una respuesta JSON de producción. Los datos externos sin contrato verificable se omiten.
Store V2 · Números virtuales

Flujo recomendado: consultar disponibilidad, alquilar, listar tus números y después gestionar renovación, estado, conversaciones y mensajes.

1 POST Consultar catálogo /v2/store/virtual-numbers/catalog
Números virtuales: Lista los numeros virtuales que se pueden alquilar por pais.

Números virtuales: Lista los numeros virtuales que se pueden alquilar por pais.

Endpoint
https://api.innovapp-soft.com/v2/store/virtual-numbers/catalog
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
country Depende string Codigo ISO 3166-1 alpha-2 del pais. En el catalogo eSIM es obligatorio cuando mode es plans u offers. CU
limit No integer Cantidad maxima de resultados, maximo 100. 20
language No string Idioma de la respuesta: es o en. es

Ejemplo cURL

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 JavaScript

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);

Esquema de respuesta verificado

[
    {
        "success": "boolean",
        "code": "string | integer",
        "message": "string",
        "data": "Mode/resource-specific local object; catalog arrays are named data, not generic items. See controller source and local model.",
        "error": "object | array",
        "time": "object"
    },
    {
        "number_offer": {
            "country": "dynamic",
            "e164": "dynamic",
            "number_type": "dynamic",
            "price": "dynamic",
            "price_cents": "dynamic",
            "monthly_price": "dynamic",
            "monthly_price_cents": "dynamic",
            "billing_period_days": "dynamic",
            "recurring": "dynamic",
            "capabilities": "dynamic"
        }
    }
]

Ejemplos de error

401 API key invalida
{
    "success": false,
    "code": 40101,
    "message": "Invalid API key."
}
422 Parametro requerido
{
    "success": false,
    "code": 47017,
    "message": "Required field is missing: client_purchase_id"
}
502 Servicio temporalmente no disponible
{
    "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.
  • Esquema parcial verificado en el código de KeyPay. Los valores dynamic se resuelven en ejecución; no representan una respuesta JSON de producción. Los datos externos sin contrato verificable se omiten.
2 POST Alquilar número /v2/store/virtual-numbers/rent
Números virtuales: Alquila el numero E.164 seleccionado en el catalogo.

Números virtuales: Alquila el numero E.164 seleccionado en el catalogo.

Endpoint
https://api.innovapp-soft.com/v2/store/virtual-numbers/rent
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
country Depende string Codigo ISO 3166-1 alpha-2 del pais. En el catalogo eSIM es obligatorio cuando mode es plans u offers. CU
e164 Si en rent string Numero internacional E.164 seleccionado en el catalogo. +12125550123
client_purchase_id Si en compra string Idempotency key unica creada por tu sistema para esta compra. order-2026-000184
language No string Idioma de la respuesta: es o en. es

Ejemplo cURL

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 JavaScript

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);

Esquema de respuesta verificado

[
    {
        "success": false,
        "code": "store.virtual_numbers.rent.failed",
        "message": "string",
        "data": [],
        "error": {
            "service": "virtual_numbers",
            "action": "string"
        },
        "time": "object"
    }
]

Ejemplos de error

401 API key invalida
{
    "success": false,
    "code": 40101,
    "message": "Invalid API key."
}
422 Parametro requerido
{
    "success": false,
    "code": 47017,
    "message": "Required field is missing: client_purchase_id"
}
502 Servicio temporalmente no disponible
{
    "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.
  • Contrato con incidencia detectada: KeyPay sobrescribe status con el estado del número y el adaptador Developer lo interpreta como fallo. Esta respuesta no se simula como éxito.
  • Esquema parcial verificado en el código de KeyPay. Los valores dynamic se resuelven en ejecución; no representan una respuesta JSON de producción. Los datos externos sin contrato verificable se omiten.
3 POST Mis números /v2/store/virtual-numbers/numbers
Números virtuales: Lista los numeros virtuales alquilados por el usuario vinculado.

Números virtuales: Lista los numeros virtuales alquilados por el usuario vinculado.

Endpoint
https://api.innovapp-soft.com/v2/store/virtual-numbers/numbers
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
page No integer Pagina del historial. 1
per_page No integer Resultados por pagina, maximo 100. 20
language No string Idioma de la respuesta: es o en. es

Ejemplo cURL

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 JavaScript

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);

Esquema de respuesta verificado

[
    {
        "success": "boolean",
        "code": "string | integer",
        "message": "string",
        "data": "{data:[record],page,per_page,total,total_pages}",
        "error": "object | array",
        "time": "object"
    },
    {
        "number_order": {
            "order_id": "dynamic",
            "number_id": "dynamic",
            "country": "dynamic",
            "e164": "dynamic",
            "status": "dynamic",
            "provider_status": "dynamic",
            "price": "dynamic",
            "renewal_price": "dynamic",
            "renews_at": "dynamic",
            "renewal_status": "dynamic",
            "auto_renew": "dynamic",
            "billing_period_days": "dynamic",
            "created_at": "dynamic",
            "activated_at": "dynamic",
            "capabilities": "dynamic"
        }
    }
]

Ejemplos de error

401 API key invalida
{
    "success": false,
    "code": 40101,
    "message": "Invalid API key."
}
422 Parametro requerido
{
    "success": false,
    "code": 47017,
    "message": "Required field is missing: client_purchase_id"
}
502 Servicio temporalmente no disponible
{
    "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.
  • Esquema parcial verificado en el código de KeyPay. Los valores dynamic se resuelven en ejecución; no representan una respuesta JSON de producción. Los datos externos sin contrato verificable se omiten.
4 POST Consultar estado /v2/store/virtual-numbers/status
Números virtuales: Consulta el estado de un numero virtual o de su orden.

Números virtuales: Consulta el estado de un numero virtual o de su orden.

Endpoint
https://api.innovapp-soft.com/v2/store/virtual-numbers/status
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
number_id Depende string Identificador del numero virtual alquilado. vn_1842
order_id Si en status string Identificador de la orden devuelto al crearla. 1842
language No string Idioma de la respuesta: es o en. es

Ejemplo cURL

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 JavaScript

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);

Esquema de respuesta verificado

[
    {
        "success": false,
        "code": "store.virtual_numbers.status.failed",
        "message": "string",
        "data": [],
        "error": {
            "service": "virtual_numbers",
            "action": "string"
        },
        "time": "object"
    }
]

Ejemplos de error

401 API key invalida
{
    "success": false,
    "code": 40101,
    "message": "Invalid API key."
}
422 Parametro requerido
{
    "success": false,
    "code": 47017,
    "message": "Required field is missing: client_purchase_id"
}
502 Servicio temporalmente no disponible
{
    "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.
  • Contrato con incidencia detectada: KeyPay sobrescribe status con el estado del número y el adaptador Developer lo interpreta como fallo. Esta respuesta no se simula como éxito.
  • Esquema parcial verificado en el código de KeyPay. Los valores dynamic se resuelven en ejecución; no representan una respuesta JSON de producción. Los datos externos sin contrato verificable se omiten.
5 POST Mensajes recibidos /v2/store/virtual-numbers/messages
Números virtuales: Obtiene los mensajes recibidos por un numero virtual.

Números virtuales: Obtiene los mensajes recibidos por un numero virtual.

Endpoint
https://api.innovapp-soft.com/v2/store/virtual-numbers/messages
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
number_id Depende string Identificador del numero virtual alquilado. vn_1842
limit No integer Cantidad maxima de resultados, maximo 100. 20
cursor No integer Cursor para continuar una lista de mensajes. 0
conversation_id No string Conversacion que se desea consultar. conv_102
language No string Idioma de la respuesta: es o en. es

Ejemplo cURL

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 JavaScript

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);

Esquema de respuesta verificado

[
    {
        "success": "boolean",
        "code": "string | integer",
        "message": "string",
        "data": "{number:number_order,data:[number_message],next_cursor:int|null,has_more:bool}",
        "error": "object | array",
        "time": "object"
    },
    {
        "number_message": {
            "id": "dynamic",
            "conversation_id": "dynamic",
            "direction": "dynamic",
            "from": "dynamic",
            "to": "dynamic",
            "body": "dynamic",
            "attachments": "dynamic",
            "attachment_count": "dynamic",
            "segments": "dynamic",
            "status": "dynamic",
            "created_at": "dynamic",
            "is_read": "dynamic"
        }
    }
]

Ejemplos de error

401 API key invalida
{
    "success": false,
    "code": 40101,
    "message": "Invalid API key."
}
422 Parametro requerido
{
    "success": false,
    "code": 47017,
    "message": "Required field is missing: client_purchase_id"
}
502 Servicio temporalmente no disponible
{
    "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.
  • Esquema parcial verificado en el código de KeyPay. Los valores dynamic se resuelven en ejecución; no representan una respuesta JSON de producción. Los datos externos sin contrato verificable se omiten.
6 POST Conversaciones /v2/store/virtual-numbers/conversations
Números virtuales: Lista las conversaciones agrupadas de un numero virtual.

Números virtuales: Lista las conversaciones agrupadas de un numero virtual.

Endpoint
https://api.innovapp-soft.com/v2/store/virtual-numbers/conversations
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
number_id Depende string Identificador del numero virtual alquilado. vn_1842
page No integer Pagina del historial. 1
per_page No integer Resultados por pagina, maximo 100. 20
language No string Idioma de la respuesta: es o en. es

Ejemplo cURL

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 JavaScript

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);

Esquema de respuesta verificado

[
    {
        "success": "boolean",
        "code": "string | integer",
        "message": "string",
        "data": "{number:number_order,data:[number_conversation],page,per_page,total,total_pages}",
        "error": "object | array",
        "time": "object"
    },
    {
        "number_conversation": {
            "conversation_id": "dynamic",
            "contact": "dynamic",
            "last_message": "dynamic",
            "has_attachments": "dynamic",
            "last_direction": "dynamic",
            "last_message_at": "dynamic",
            "unread_count": "dynamic"
        }
    }
]

Ejemplos de error

401 API key invalida
{
    "success": false,
    "code": 40101,
    "message": "Invalid API key."
}
422 Parametro requerido
{
    "success": false,
    "code": 47017,
    "message": "Required field is missing: client_purchase_id"
}
502 Servicio temporalmente no disponible
{
    "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.
  • Esquema parcial verificado en el código de KeyPay. Los valores dynamic se resuelven en ejecución; no representan una respuesta JSON de producción. Los datos externos sin contrato verificable se omiten.
7 POST Marcar mensajes leídos /v2/store/virtual-numbers/mark-read
Números virtuales: Marca como leidos los mensajes de un numero virtual.

Números virtuales: Marca como leidos los mensajes de un numero virtual.

Endpoint
https://api.innovapp-soft.com/v2/store/virtual-numbers/mark-read
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
number_id Depende string Identificador del numero virtual alquilado. vn_1842
message_id No integer Mensaje hasta el cual se marcara como leido. 509
language No string Idioma de la respuesta: es o en. es

Ejemplo cURL

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 JavaScript

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);

Esquema de respuesta verificado

[
    {
        "success": "boolean",
        "code": "string | integer",
        "message": "string",
        "data": "{unread_count:int}",
        "error": "object | array",
        "time": "object"
    },
    []
]

Ejemplos de error

401 API key invalida
{
    "success": false,
    "code": 40101,
    "message": "Invalid API key."
}
422 Parametro requerido
{
    "success": false,
    "code": 47017,
    "message": "Required field is missing: client_purchase_id"
}
502 Servicio temporalmente no disponible
{
    "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.
  • Esquema parcial verificado en el código de KeyPay. Los valores dynamic se resuelven en ejecución; no representan una respuesta JSON de producción. Los datos externos sin contrato verificable se omiten.
8 POST Configurar renovación /v2/store/virtual-numbers/auto-renew
Números virtuales: Activa o desactiva la renovacion automatica de un numero virtual alquilado. Al desactivarla, el numero permanece activo hasta su vencimiento.

Números virtuales: Activa o desactiva la renovacion automatica de un numero virtual alquilado. Al desactivarla, el numero permanece activo hasta su vencimiento.

Endpoint
https://api.innovapp-soft.com/v2/store/virtual-numbers/auto-renew
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
number_id Depende string Identificador del numero virtual alquilado. vn_1842
auto_renew Si boolean Usa true para activar la renovacion automatica o false para desactivarla. 1
client_request_id No string Identificador opcional de la solicitud generado por tu sistema. renew-2026-000184
language No string Idioma de la respuesta: es o en. es

Ejemplo cURL

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 JavaScript

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);

Esquema de respuesta verificado

[
    {
        "success": false,
        "code": "store.virtual_numbers.auto_renew.failed",
        "message": "string",
        "data": [],
        "error": {
            "service": "virtual_numbers",
            "action": "string"
        },
        "time": "object"
    }
]

Ejemplos de error

401 API key invalida
{
    "success": false,
    "code": 40101,
    "message": "Invalid API key."
}
422 Parametro requerido
{
    "success": false,
    "code": 47017,
    "message": "Required field is missing: client_purchase_id"
}
502 Servicio temporalmente no disponible
{
    "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.
  • Contrato con incidencia detectada: KeyPay sobrescribe status con el estado del número y el adaptador Developer lo interpreta como fallo. Esta respuesta no se simula como éxito.
  • Esquema parcial verificado en el código de KeyPay. Los valores dynamic se resuelven en ejecución; no representan una respuesta JSON de producción. Los datos externos sin contrato verificable se omiten.
Store APIs V1 (legacy)

Version anterior de recargas moviles. Para integraciones nuevas usa Store APIs V2.

1 GET GET /v1/store/mobile_topup
Devuelve los planes disponibles para recarga móvil. Permite filtrar opcionalmente por categoría.

Devuelve los planes disponibles para recarga móvil. Permite filtrar opcionalmente por categoría.

Endpoint
https://api.innovapp-soft.com/v1/store/mobile_topup
Auth
Bearer API Key
Method
GET

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json

Query params

Nombre Requerido Tipo Descripción Ejemplo
category No string Filtra los productos por categoría. Mobile-Top-Up

Ejemplo cURL

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 JavaScript

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

{
    "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
    }
}

Ejemplos de error

401 401 Unauthorized
{
    "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
    }
}
405 405 Method Not Allowed
{
    "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.
2 POST POST /v1/store/mobile_topup
Procesa la compra de una recarga móvil a partir del id del plan y el número telefónico.

Procesa la compra de una recarga móvil a partir del id del plan y el número telefónico.

Endpoint
https://api.innovapp-soft.com/v1/store/mobile_topup
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
id string Identificador del plan, obtenido desde el GET. 4f
phone string Número móvil destino a recargar. 51234567

Ejemplo cURL

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 JavaScript

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

{
    "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
    }
}

Ejemplos de error

409 409 Operation In Process
{
    "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
    }
}
422 422 Invalid Phone
{
    "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
    }
}
409 409 Insufficient Credit
{
    "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.
Payments APIs

Endpoints para crear enlaces de pago y gestionar cobros.

1 POST POST /v1/payment_links
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.

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.

Endpoint
https://api.innovapp-soft.com/v1/payment_links
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
amount string Monto a cobrar. Acepta hasta 3 decimales. 25.00
currency No string Moneda del cobro. Actualmente soportado: KCOIN. KCOIN
external_reference No string Referencia interna del comercio o sistema externo. ORDER-10045
title No string Título corto del cobro. Payment request
description No string Descripción corta del cobro. Recharge order
message No string Mensaje opcional asociado al enlace. Complete the payment from your KeyCard app
expires_in_minutes No integer Tiempo de expiración del enlace en minutos. 60
metadata No object Objeto JSON libre para información auxiliar del comercio. {"customer_id":"CUST-88"}

Ejemplo cURL

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 JavaScript

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

{
    "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
    }
}

Ejemplos de error

400 400 Amount Required
{
    "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
    }
}
422 422 Invalid Amount
{
    "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
    }
}
422 422 Invalid Metadata
{
    "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
    }
}
405 405 Method Not Allowed
{
    "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.
2 GET GET /v1/transactions
Devuelve las últimas 10 transacciones creadas por el developer autenticado.

Devuelve las últimas 10 transacciones creadas por el developer autenticado.

Endpoint
https://api.innovapp-soft.com/v1/transactions
Auth
Bearer API Key
Method
GET

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json

Ejemplo cURL

curl -X GET 'https://api.innovapp-soft.com/v1/transactions' \
  -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \
  -H 'Accept: application/json'

Ejemplo JavaScript

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

{
    "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
    }
}

Ejemplos de error

401 401 Unauthorized
{
    "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
    }
}
405 405 Method Not Allowed
{
    "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.
3 GET GET /v1/transactions/{public_id}
Devuelve el detalle de una transacción específica usando su payment_id/public_id.

Devuelve el detalle de una transacción específica usando su payment_id/public_id.

Endpoint
https://api.innovapp-soft.com/v1/transactions/{public_id}
Auth
Bearer API Key
Method
GET

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json

Ejemplo cURL

curl -X GET 'https://api.innovapp-soft.com/v1/transactions/6d4f21d15e7bc3d9276ea4f0d89ab21c' \
  -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \
  -H 'Accept: application/json'

Ejemplo JavaScript

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

{
    "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
    }
}

Ejemplos de error

404 404 Transaction Not Found
{
    "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
    }
}
422 422 Invalid Public ID
{
    "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.
PaymentIntent SDK APIs

Endpoints para crear cobros con client_secret y abrir checkout desde SDK iOS/Android.

1 POST POST /v1/payment_intents
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.

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.

Endpoint
https://api.innovapp-soft.com/v1/payment_intents
Auth
Bearer API Key
Method
POST

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json
Content-Type application/json

Body params

Nombre Requerido Tipo Descripción Ejemplo
amount string Monto a cobrar. Acepta hasta 3 decimales. 10.00
currency No string Moneda del cobro. Actualmente soportado: KCOIN. KCOIN
external_reference No string Referencia interna del comercio. ORDER-1001
title No string Título corto del cobro. Premium purchase
return_url No string Deep link o URL de retorno de la app. myapp://keypay-return
platform No string ios, android o web. ios
bundle_id No string Bundle ID iOS. com.example.app
package_name No string Package Android. com.example.app
metadata No object JSON libre para tu orden. {"order_id":"1001"}

Ejemplo cURL

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 JavaScript

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

{
    "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}.
2 SDK SwiftUI SDK KeyPayPaymentSDK
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.

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.

Endpoint
https://github.com/innovappsoft/KeyPayPaymentSDK.git
Auth
Developer Backend
Method
SDK

Headers requeridos

Header Valor
Package URL https://github.com/innovappsoft/KeyPayPaymentSDK.git
Version v1.0.0 o superior
Import import KeyPayPaymentSDK

Body params

Nombre Requerido Tipo Descripción Ejemplo
paymentIntentEndpoint URL Endpoint de tu backend que crea PaymentIntent con dk_live. https://tuapp.com/api/keypay/payment-intents
paymentStatusEndpoint Recomendado URL Endpoint de tu backend que consulta GET /v1/payment_intents/{id}. https://tuapp.com/api/keypay/payment-intents
returnURLScheme string URL Scheme registrado en Xcode para volver a la app. myapp
merchantDisplayName string Nombre visible del comercio dentro del sheet. My App

Ejemplo cURL

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

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

{
    "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.
3 SDK Android SDK KeyPayPaymentAndroidSDK
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.

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.

Endpoint
https://github.com/innovappsoft/KeyPayPaymentAndroidSDK.git
Auth
Developer Backend
Method
SDK

Headers requeridos

Header Valor
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 params

Nombre Requerido Tipo Descripción Ejemplo
paymentIntentEndpoint String Endpoint de tu backend que crea PaymentIntent con dk_live. https://tuapp.com/api/keypay/payment-intents
paymentStatusEndpoint Recomendado String Endpoint de tu backend que consulta GET /v1/payment_intents/{id}. https://tuapp.com/api/keypay/payment-intents
returnUrlScheme String Scheme registrado en AndroidManifest para volver a la app. myapp
merchantDisplayName String Nombre visible del comercio dentro del checkout. My App
package_name Recomendado String Package name Android de la app del developer. com.example.app

Ejemplo cURL

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

<activity android:name="com.innovappsoft.keypay.payment.KeyPayReturnActivity" android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="myapp" android:host="keypay-return" />
    </intent-filter>
</activity>

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

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

{
    "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": "<activity android:name=\"com.innovappsoft.keypay.payment.KeyPayReturnActivity\" android:exported=\"true\"><intent-filter><action android:name=\"android.intent.action.VIEW\"/><category android:name=\"android.intent.category.DEFAULT\"/><category android:name=\"android.intent.category.BROWSABLE\"/><data android:scheme=\"myapp\" android:host=\"keypay-return\"/></intent-filter></activity>"
}

Ejemplos de error

0
[]
0
[]
0
[]
0
[]

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.
4 GET GET /v1/payment_intents/{id}
Consulta el estado de un PaymentIntent creado por tu cuenta.

Consulta el estado de un PaymentIntent creado por tu cuenta.

Endpoint
https://api.innovapp-soft.com/v1/payment_intents/{id}
Auth
Bearer API Key
Method
GET

Headers requeridos

Header Valor
Authorization Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx
Accept application/json

Ejemplo cURL

curl -X GET 'https://api.innovapp-soft.com/v1/payment_intents/pi_6d4f21d15e7bc3d9276ea4f0d89ab21c' \
  -H 'Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxxxx' \
  -H 'Accept: application/json'

Ejemplo JavaScript

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

{
    "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.
Sandbox

Pruebas con saldo virtual, claves independientes y respuestas simuladas.

1 POST Sandbox · Inicio rápido /sandbox/v2/store/esim/catalog
Abre Sandbox en tu panel, crea una clave de prueba y añade /sandbox a la URL base. Conserva la versión y la ruta del endpoint.

Abre Sandbox en tu panel, crea una clave de prueba y añade /sandbox a la URL base. Conserva la versión y la ruta del endpoint.

Endpoint
https://api.innovapp-soft.com/sandbox/v2/store/esim/catalog
Auth
Bearer dk_test_
Method
POST

Headers requeridos

Header Valor
Authorization Bearer YOUR_SANDBOX_KEY
Accept application/json
Content-Type application/json
X-Sandbox-Scenario success

Body params

Nombre Requerido Tipo Descripción Ejemplo
mode No string Usa plans para consultar planes de un país. plans
country Sí para plans string Código ISO alpha-2 del país. US
language No string Idioma: es o en. es

Ejemplo cURL

curl -X POST 'https://api.innovapp-soft.com/sandbox/v2/store/esim/catalog' \
  -H 'Authorization: Bearer YOUR_SANDBOX_KEY' \
  -H 'Content-Type: application/json' \
  -H 'X-Sandbox-Scenario: success' \
  --data '{"mode":"plans","country":"US","language":"es"}'

Ejemplo JavaScript

// Backend only: keep the test key on your server.
const response = await fetch('https://api.innovapp-soft.com/sandbox/v2/store/esim/catalog', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer YOUR_SANDBOX_KEY',
    'Content-Type': 'application/json',
    'X-Sandbox-Scenario': 'success'
  },
  body: JSON.stringify({ mode: 'plans', country: 'US', language: 'es' })
});
const result = await response.json();

Notas

  • El Sandbox cubre unicamente las APIs Developer publicadas en esta documentacion. Las APIs internas de las apps de KeyPay no se simulan aqui ni son accesibles con una clave de developer.
  • Las claves dk_test_ solo funcionan en /sandbox. Las claves dk_live_ se rechazan en Sandbox. No uses claves secretas en aplicaciones públicas.
  • El saldo inicial es 10 000 KC virtuales. No se modifica tu saldo real ni se envían compras, retiros, depósitos, notificaciones o webhooks a servicios externos.
  • Los escenarios disponibles dependen del endpoint y se muestran en el selector. Solo las operaciones que lo admiten permiten transiciones pending, success o failed.
  • Todas las respuestas incluyen sandbox.simulated = true y se identifican con X-API-Environment: sandbox. Solo se reproducen campos verificados; las cantidades e identificadores son valores de prueba.
  • Usa los identificadores que devuelve cada creación en get, status y list. En Store, repite la referencia de cliente con el mismo cuerpo para probar idempotencia; cambia el cuerpo para probar un conflicto.
  • Los datos de prueba se comparten dentro de tu cuenta developer. Reiniciar borra las operaciones simuladas y restaura el saldo virtual; conserva las claves de prueba.
  • Límites: 120 peticiones por minuto por developer, 64 KB por cuerpo JSON y 200 operaciones. Reinicia los datos cuando alcances el límite de operaciones.
  • Envía un objeto JSON con Content-Type: application/json para POST y parámetros de consulta para GET. Las rutas no disponibles devuelven un error y nunca se reenvían a producción.
  • Los estados pendientes no avanzan por sí solos. El Sandbox simula contratos y escenarios; no valida entregas reales, firmas de webhook ni tiempos de proveedores.

¿Necesitas ayuda?
Estamos disponibles.

Nuestro equipo está listo para asistirte. Escríbenos por canales oficiales o por correo.