Cada llamada lleva tu usuario y tu clave en dos cabeceras HTTP. No hay tokens que renovar.
| Cabecera | Valor |
|---|---|
X-API-USER obligatoria | Tu usuario de API. |
X-API-KEY obligatoria | Tu clave de API. |
Content-Type | application/json en las acciones POST que reciben JSON. |
Las credenciales solo se aceptan en cabeceras. Si las pones en la URL o en el cuerpo, se ignoran (y quedarían expuestas en registros).
curl -s "{{API_URL}}?accion=productos" \
-H "X-API-USER: $API_USER" \
-H "X-API-KEY: $API_KEY"
401 API_CREDENTIALS_REQUIRED.401 API_CLIENT_NOT_FOUND. Cuenta desactivada: 403 API_CLIENT_INACTIVE.401 API_KEY_INVALID.403 API_IP_NOT_ALLOWED.403 API_SERVICE_NOT_ALLOWED.{
"ok": false,
"success": false,
"message": "Credenciales API requeridas",
"error_code": "API_CREDENTIALS_REQUIRED"
}
{
"ok": false,
"success": false,
"message": "Credenciales API invalidas",
"error_code": "API_KEY_INVALID"
}
{
"ok": false,
"success": false,
"message": "Servicio no habilitado para este cliente API",
"error_code": "API_SERVICE_NOT_ALLOWED"
}
Solo ping, que sirve para comprobar que la API está en línea.
404 RECARGA_NOT_FOUND, como si no existiera.Una integración de recargas mueve dinero. Estas prácticas protegen tu negocio y el de tus clientes.
| Acción | Timeout recomendado en tu cliente HTTP |
|---|---|
ejecutar | 150 segundos (algunos operadores tardan hasta 2 minutos) |
servicios, crear | 60 segundos (consultan al operador) |
| Resto | 30 segundos |
recarga_id junto a tu venta, y usa tu propio ID como id_externo e idempotency_key.procesando, revision_manual) con estado.ejecutar y queda disponible en estado (campo proveedor_respuesta).message: usa error_code y estado.idempotency_key único por venta.ejecutar, y consulta de estado ante timeout o 502.procesada, fallida, revision_manual) manejados en tu interfaz.Cambios de la API y de esta documentación. Los cambios que puedan afectar tu integración se anuncian aquí con anticipación.
X-Forwarded-For enviada por el cliente ya no se toma en cuenta.403 ACCION_NO_PERMITIDA para el resto). No afecta a las integraciones existentes.Cada recarga es una orden que pasa por estados fijos. Conocerlos te permite mostrar el resultado correcto a tu cliente y conciliar sin errores.
| estado | Qué significa | ¿Final? |
|---|---|---|
pendiente_pago | La orden existe, pero aún no confirmas el cobro. No se ha enviado nada. | No |
pagada | Confirmaste el cobro. Lista para ejecutar. | No |
procesando | Se está enviando al operador. Estado breve. | No |
procesada | ✅ La recarga llegó al destinatario. | Sí |
fallida | ❌ El operador la rechazó. No se entregó saldo. | Sí |
revision_manual | ⚠️ No pudimos confirmar el resultado con el operador (corte de conexión, demora). Nuestro equipo lo verifica. | Sí, vía API |
crear ──► pendiente_pago ──marcar_pagada──► pagada ──ejecutar──► procesando ──┬──► procesada
├──► fallida
└──► revision_manualpagada. En cualquier otro estado, ejecutar responde 409 ESTADO_INVALIDO.200 con "duplicada": true.fallida no se reintenta. Si quieres volver a intentarlo, crea una orden nueva con otro idempotency_key.revision_manual no es un fracaso. La recarga pudo haber llegado. No la repitas: espera la verificación o contacta a {{SUPPORT_TEXT}} con el recarga_id.pendiente_pago que no confirmes simplemente nunca se ejecuta.| estado | Mensaje sugerido |
|---|---|
procesada | "Recarga exitosa." |
fallida | "La recarga no se pudo realizar. No se cargó saldo." (y devolver el dinero según tu política) |
revision_manual / procesando | "Tu recarga está en verificación. Te confirmamos en breve." No devuelvas el dinero todavía. |
Las respuestas traen estado (el que debes usar), y además api_status y status_legacy, de uso interno. Basa tu lógica solo en estado.
Cada empresa integradora recibe un par de credenciales de API y una lista de productos habilitados.
| Dato | Ejemplo | Para qué sirve |
|---|---|---|
| Usuario de API | api_pv_123 | Va en la cabecera X-API-USER. No es secreto. |
| Clave de API | 32 caracteres | Va en la cabecera X-API-KEY. Es secreta. |
| Productos habilitados | internacional, voznet | Qué puedes vender. Los ves con productos. |
| IPs autorizadas (opcional, recomendado) | 200.1.2.3, 200.1.2.4 | Solo esas IPs pueden usar tus credenciales. |
Si registramos IPs para tu cuenta, cualquier llamada desde otra IP responde 403 API_IP_NOT_ALLOWED, aunque la clave sea correcta. La respuesta incluye la IP que vimos, útil para diagnosticar:
{
"ok": false,
"success": false,
"message": "IP no autorizada para este cliente API",
"error_code": "API_IP_NOT_ALLOWED",
"ip": "200.1.2.99"
}Si sospechas que tu clave se filtró, pide de inmediato una clave nueva. La anterior deja de funcionar apenas generamos la nueva. También podemos desactivar tu acceso por completo mientras lo revisas (403 API_CLIENT_INACTIVE).
Quien tenga tu clave puede crear y ejecutar recargas a tu nombre. Las llamadas deben salir siempre desde tu servidor. Si tienes una app móvil, esta habla con tu servidor y tu servidor habla con nosotros.
La regla de oro: ante cualquier duda después de ejecutar, consulta estado; nunca repitas la recarga a ciegas.
{
"ok": false,
"success": false,
"message": "Texto legible, en español",
"error_code": "CODIGO_DEL_ERROR"
}Basa tu lógica en el código HTTP y en error_code. El message es para personas y puede cambiar. Algunos errores traen campos extra (por ejemplo montos_disponibles); ignora los que no uses.
| HTTP | Significado | Qué hacer |
|---|---|---|
200 | Operación correcta | Revisa estado en la respuesta. |
400 | Datos inválidos (falta un campo, monto o número incorrecto) | Corrige y vuelve a intentar. No reintentes igual. |
401 / 403 | Credenciales, IP o producto no autorizados | Revisa la configuración. No reintentes. |
404 | Orden, producto u operador inexistente | Revisa el identificador o el número. |
405 | Método incorrecto (GET en vez de POST) | Corrige tu integración. |
409 | La orden no está en el estado necesario | Consulta estado: probablemente ya avanzó. |
502 | Problema con el operador | En ejecutar: consulta estado. En catálogo: reintenta en unos segundos. |
500 | Error interno | Reintenta más tarde; si persiste, avisa a soporte. |
| Timeout / conexión cortada | No sabes el resultado | Consulta estado. |
| Acción | ¿Se puede repetir? |
|---|---|
productos, paises, servicios, estado, cliente | Sí, son solo consultas. |
crear | Sí, con el mismo idempotency_key. |
marcar_pagada | Sí: si ya estaba pagada responde 409 y no pasa nada. |
ejecutar | No a ciegas. Primero estado. Solo si sigue en pagada puedes volver a ejecutar. |
ejecutarres = ejecutar(recarga_id) # timeout 150 s
if res es timeout o http 502 o res.estado == "revision_manual":
for intento in 1..10: # durante unos minutos
e = estado(recarga_id)
if e.estado in ("procesada", "fallida"):
break # resultado final
esperar(30 segundos)
else:
marcar venta "en verificación" y avisar a soporte con el recarga_idLa lista completa de códigos está en Códigos de error.
Términos que usamos en la documentación.
| Término | Significado |
|---|---|
| Acción | Cada operación de la API (crear, estado…). Va en el parámetro accion. |
| Producto | Familia de recargas: internacional, icargas, movilservicios, voznet. |
| Ítem de catálogo | Una recarga concreta dentro de un producto, con su codigo_producto y monto. |
| Operador | La compañía de telefonía del destinatario (Claro, Movistar, Tigo…). |
| Orden | Una recarga registrada en la API, identificada por recarga_id. |
| Monto destino | Lo que recibe el destinatario, en la moneda de su país. |
| Total a pagar | Lo que cuesta la recarga para tu cuenta, en CLP. |
| Idempotencia | Poder repetir una llamada sin crear duplicados. Ver Idempotencia. |
| Revisión manual | Estado de una orden cuyo resultado no se pudo confirmar automáticamente. No se debe repetir. |
| PIN | Código que se entrega al cliente en productos de tipo PIN o tarjeta, en lugar de cargarse a un número. |
El flujo completo de un punto de venta: el cliente dicta un número del extranjero, eliges el monto, cobras y recargas.
Usa paises para armar el selector de país (bandera, prefijo, máscara). Une prefijo + número local: 57 + 3001234567 = 573001234567.
curl -s "{{API_URL}}?accion=servicios&producto=internacional&numero=573001234567" \
-H "X-API-USER: $API_USER" -H "X-API-KEY: $API_KEY"Muestra cada ítem con su nombre, lo que recibe el destinatario (monto_destino + moneda_destino) y lo que cuesta (total_pagar en CLP). Si la respuesta es 404 DTONE_OPERATOR_NOT_FOUND, el número no es válido o no tiene cobertura: pide al cliente que lo revise.
{
"producto": "internacional",
"numero": "573001234567",
"codigo_producto": "12345",
"monto": 10000,
"id_externo": "boleta-5521",
"idempotency_key": "boleta-5521"
}Guarda el recarga_id junto a tu venta.
Cuando el cliente pagó, llama marcar_pagada con el recarga_id (y opcionalmente tu referencia_pago).
Llama ejecutar con un tiempo de espera de al menos 150 segundos. Según el estado:
procesada → imprime el comprobante.fallida → informa al cliente y devuelve el dinero.revision_manual, error 502 o timeout → consulta estado. Si sigue sin resultado final, dile al cliente que está en verificación y no repitas la recarga.Mantén una tarea que, cada pocos minutos, consulte estado de tus órdenes que quedaron sin resultado final. Así cierras las ventas pendientes sin intervención manual.
Voznet es la app de telefonía de Callpcs. Sus usuarios se identifican por su número chileno y el saldo se carga en CLP, con monto libre.
curl -s "{{API_URL}}?accion=cliente&producto=voznet&numero=56912345678" \
-H "X-API-USER: $API_USER" -H "X-API-KEY: $API_KEY"
Los datos del cliente vienen en cliente.cliente: nombre, cuenta y saldo actual. Si el número coincide con varias cuentas, la respuesta trae cliente.multiple: true y la lista en cliente.clientes: pide al cliente que confirme cuál es la suya.
Cuando cliente.cliente.requiere_nombre es true, pide el nombre y guárdalo con cliente_actualizar. Es opcional para recargar, pero ayuda a identificar la cuenta.
{
"producto": "voznet",
"numero": "56912345678",
"monto": 5000,
"idempotency_key": "boleta-5522"
}Luego marcar_pagada y ejecutar, igual que cualquier producto. La respuesta de ejecutar incluye, dentro de voznet_response, el saldo nuevo del cliente (saldo_nuevo).
En Voznet el monto es libre y en CLP. No hay catálogo: servicios responde 501 CATALOGO_NO_IMPLEMENTADO para este producto.
Si una llamada a crear se corta y la repites, no quieres dos órdenes. El idempotency_key lo evita.
venta-000981.crearComo idempotency_key."duplicada": true.{
"ok": true,
"recarga_id": 245871,
"estado": "pendiente_pago",
"duplicada": true,
"message": "La orden ya existia para esa idempotency_key"
}idempotency_key, la API genera una, pero entonces una repetición sí crea otra orden.id_externoEs tu referencia libre para conciliar (número de boleta, ID de venta). Se guarda y te permite consultar la orden con estado, pero no evita duplicados. Lo más simple es usar el mismo valor en id_externo e idempotency_key.
ejecutar?Ejecutar una orden ya procesada no la recarga de nuevo (responde "duplicada": true). Pero si una llamada a ejecutar se corta, no la repitas: consulta estado primero. Detalles en Errores y reintentos.
Integra recargas móviles nacionales e internacionales, paquetes de datos, PINs y saldo de telefonía Voznet en tu propia plataforma, con una sola API.
Para empresas que quieren vender recargas desde su propio sistema:
| Producto | Cobertura | Ejemplos |
|---|---|---|
internacional | Más de 180 países (según disponibilidad de cada operador) | Recargas de saldo a celulares prepago en el extranjero |
icargas | Colombia | Recargas, paquetes de datos, PINs |
movilservicios | Colombia | Recargas, paquetes y otros servicios |
voznet | Chile | Saldo para la app de telefonía Voznet |
Qué productos ves depende de lo habilitado en tu contrato. Consúltalos con productos.
crear. Todavía no se envía nada.marcar_pagada.ejecutar envía la recarga al operador y te responde el resultado.Solicítalas a {{SUPPORT_TEXT}}. Te las entregamos junto con los productos habilitados para tu empresa.
La API de Recargas de Callpcs es una API HTTP que responde en JSON. Te permite consultar productos, crear órdenes de recarga, ejecutarlas y seguir su estado desde tu propio servidor.
Cada operación es una acción. La acción se indica en el parámetro accion de la URL:
{{API_URL}}?accion=<accion>Todas las respuestas tienen el mismo formato base: "ok": true cuando la operación funcionó, y "ok": false con un error_code cuando no.
X-API-USER) y una clave (X-API-KEY). Si lo pides, restringimos el acceso a las IPs de tu servidor. Ver credenciales.ping y después productos para ver qué tienes habilitado.servicios obtienes el catálogo: operador, montos y codigo_producto.crear → marcar_pagada → ejecutar.estado. Nunca repitas ejecutar a ciegas.ejecutar puede tardar hasta 2 minutos (ver buenas prácticas).Cada orden tiene dos montos: lo que recibe el destinatario (monto, en la moneda del país de destino) y lo que te cobramos (total_pagar, en CLP).
| Campo | Qué es | Moneda |
|---|---|---|
monto | Lo que se carga al destinatario | moneda del producto (por ejemplo COP) |
total_pagar | Lo que te cobramos por esa recarga | moneda_cobro (CLP) |
| producto | monto que envías | total_pagar |
|---|---|---|
internacional | Exactamente el monto_destino del ítem elegido (moneda de destino) | Lo calcula la API en CLP según tu tarifa |
icargas | Exactamente el valor_cop del ítem (COP). En recargas de monto libre, uno de los montos disponibles | Lo calcula la API según el catálogo |
movilservicios | El valor del subproducto, o un monto entre monto_minimo y monto_maximo (COP) | Según tu contrato |
voznet | Monto en CLP a cargar | Según tu contrato |
Si el monto no coincide con el del ítem, crear lo rechaza (por ejemplo DTONE_MONTO_NO_COINCIDE o ICARGAS_MONTO_NO_COINCIDE). Los montos se tratan como enteros: no envíes decimales.
servicios justo antes de vender y muestra a tu cliente el total_pagar vigente.crear. Lo ves en la respuesta de crear y en estado.Las fechas vienen en hora de Chile continental (America/Santiago), con formato AAAA-MM-DD HH:MM:SS y sin indicador de zona horaria.
El formato del número es la causa más común de errores. Siempre solo dígitos, y con o sin código de país según el producto.
| producto | Formato | Ejemplo correcto | Incorrecto |
|---|---|---|---|
internacional | Código de país + número local | 573001234567 | 3001234567, +57 300… |
icargas | Número local colombiano, 10 dígitos, sin 57 | 3001234567 | 573001234567 |
movilservicios | Número local colombiano, 10 dígitos, sin 57 | 3001234567 | 573001234567 |
voznet | 56 + 9 dígitos (si envías 9 dígitos que empiezan en 9, se agrega el 56) | 56912345678 | +56 9 1234 5678 |
+, espacios, guiones ni paréntesis. La API elimina lo que no sea dígito, pero no agrega ni quita códigos de país (salvo el caso de Voznet indicado arriba).fallida. Valida el largo en tu formulario antes de llamar a la API.paisespaises te da la lista de países con su prefijo, largo esperado, un ejemplo y la URL de la bandera, ordenada por los países con más recargas. Es la referencia para internacional.
{
"iso": "CO",
"nombre": "Colombia",
"prefijo": "57",
"min_local": 10,
"max_local": 10,
"ejemplo_local": "3001234567",
"mascara_local": "### ### ####",
"movil_empieza_con": ["3"],
"ejemplo_completo": "573001234567",
"flag_url": "https://…/co.svg",
"ranking": 1
}Valores ilustrativos: usa los que devuelva la API.
paises es solo una ayuda de interfaz. En internacional, quien confirma el número y detecta el operador es servicios: si el número no corresponde a ningún operador, responde 404 DTONE_OPERATOR_NOT_FOUND.
Tu primera recarga internacional en 5 llamadas. Los valores de ejemplo (número, producto, montos) son ilustrativos: usa los que te devuelva la API.
Hoy no hay un ambiente de pruebas separado: ejecutar envía una recarga real al operador. Para tus primeras pruebas coordina con {{SUPPORT_TEXT}} y usa el monto más bajo del catálogo.
Guárdalas como variables de entorno en tu servidor, nunca en el código:
export API="{{API_URL}}"
export API_USER="api_pv_123" # tu usuario de API
export API_KEY="********************" # tu clave (te la entregamos una sola vez)curl -s "$API?accion=productos" \ -H "X-API-USER: $API_USER" -H "X-API-KEY: $API_KEY"
La respuesta lista los productos que tienes habilitados (por ejemplo internacional).
Envía el número completo con código de país, sin + ni espacios. La API detecta el operador y te devuelve sus productos:
curl -s "$API?accion=servicios&producto=internacional&numero=573001234567" \ -H "X-API-USER: $API_USER" -H "X-API-KEY: $API_KEY"
{
"ok": true,
"operador": "Claro Colombia",
"total": 6,
"servicios": [
{
"codigo_producto": "12345",
"nombre": "Claro Colombia 10.000 COP",
"monto_destino": 10000,
"moneda_destino": "COP",
"total_pagar": 2600,
"moneda_cobro": "CLP"
}
]
}
Elige un producto. Anota su codigo_producto y su monto_destino. total_pagar es lo que te cobramos, en CLP.
Usa un idempotency_key propio (por ejemplo, el ID de la venta en tu sistema) para no duplicar la orden si repites la llamada.
curl -s -X POST "$API?accion=crear" \
-H "X-API-USER: $API_USER" -H "X-API-KEY: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"producto": "internacional",
"numero": "573001234567",
"codigo_producto": "12345",
"monto": 10000,
"id_externo": "venta-000981",
"idempotency_key": "venta-000981"
}'
{
"ok": true,
"recarga_id": 245871,
"estado": "pendiente_pago",
"producto": "internacional",
"numero": "573001234567",
"monto": 10000,
"moneda": "COP",
"total_pagar": 2600,
"moneda_cobro": "CLP",
"id_externo": "venta-000981",
"idempotency_key": "venta-000981"
}
Cuando cobraste a tu cliente, marca la orden como pagada y ejecútala:
curl -s -X POST "$API?accion=marcar_pagada" \
-H "X-API-USER: $API_USER" -H "X-API-KEY: $API_KEY" -H "Content-Type: application/json" \
-d '{"recarga_id": 245871, "referencia_pago": "caja-3-boleta-5521"}'
curl -s -X POST "$API?accion=ejecutar" --max-time 150 \
-H "X-API-USER: $API_USER" -H "X-API-KEY: $API_KEY" -H "Content-Type: application/json" \
-d '{"recarga_id": 245871}'
{
"ok": true,
"recarga_id": 245871,
"estado_anterior": "pagada",
"estado": "procesada",
"numero": "573001234567",
"monto": 10000,
"moneda": "COP",
"provider_ref": "245871",
"message": "…"
}
curl -s "$API?accion=estado&recarga_id=245871" \ -H "X-API-USER: $API_USER" -H "X-API-KEY: $API_KEY"
estado te dice si la orden quedó procesada, fallida o en revision_manual. Detalles en Ciclo de vida.
<?php
function recargas(string $accion, array $body = null, array $query = []): array {
$url = getenv('API') . '?' . http_build_query(['accion' => $accion] + $query);
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 150, // ejecutar puede tardar
CURLOPT_HTTPHEADER => [
'X-API-USER: ' . getenv('API_USER'),
'X-API-KEY: ' . getenv('API_KEY'),
'Content-Type: application/json',
],
]);
if ($body !== null) {
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));
}
$raw = curl_exec($ch);
$http = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return ['http' => $http, 'data' => json_decode((string) $raw, true)];
}
$orden = recargas('crear', [
'producto' => 'internacional', 'numero' => '573001234567',
'codigo_producto' => '12345', 'monto' => 10000,
'idempotency_key' => 'venta-000981',
]);
$id = $orden['data']['recarga_id'];
recargas('marcar_pagada', ['recarga_id' => $id]);
$r = recargas('ejecutar', ['recarga_id' => $id]);
if (!($r['data']['ok'] ?? false)) {
// No reintentes ejecutar: consulta el estado
$r = recargas('estado', null, ['recarga_id' => $id]);
}
echo $r['data']['estado'];
import os, requests
API = os.environ["API"]
H = {"X-API-USER": os.environ["API_USER"], "X-API-KEY": os.environ["API_KEY"]}
def recargas(accion, body=None, **query):
params = {"accion": accion, **query}
if body is None:
r = requests.get(API, params=params, headers=H, timeout=30)
else:
r = requests.post(API, params=params, json=body, headers=H, timeout=150)
return r.status_code, r.json()
_, orden = recargas("crear", {
"producto": "internacional", "numero": "573001234567",
"codigo_producto": "12345", "monto": 10000,
"idempotency_key": "venta-000981",
})
rid = orden["recarga_id"]
recargas("marcar_pagada", {"recarga_id": rid})
try:
_, res = recargas("ejecutar", {"recarga_id": rid})
except requests.Timeout:
_, res = recargas("estado", recarga_id=rid) # nunca repitas ejecutar a ciegas
print(res.get("estado"))
const API = process.env.API;
const H = { "X-API-USER": process.env.API_USER, "X-API-KEY": process.env.API_KEY };
async function recargas(accion, body, query = {}) {
const url = `${API}?${new URLSearchParams({ accion, ...query })}`;
const res = await fetch(url, {
method: body ? "POST" : "GET",
headers: { ...H, "Content-Type": "application/json" },
body: body ? JSON.stringify(body) : undefined,
signal: AbortSignal.timeout(150_000),
});
return res.json();
}
const orden = await recargas("crear", {
producto: "internacional", numero: "573001234567",
codigo_producto: "12345", monto: 10000, idempotency_key: "venta-000981",
});
await recargas("marcar_pagada", { recarga_id: orden.recarga_id });
let r = await recargas("ejecutar", { recarga_id: orden.recarga_id }).catch(() => null);
if (!r || !r.ok) r = await recargas("estado", null, { recarga_id: orden.recarga_id });
console.log(r.estado);
Un producto es una familia de recargas (por ejemplo, internacionales o Colombia). Dentro de cada producto hay ítems de catálogo con su propio codigo_producto y monto.
| producto | Cobertura | Cómo se elige el ítem | Catálogo por API |
|---|---|---|---|
internacional | Recargas móviles en más de 180 países | Automático por número: la API detecta el operador | Sí |
icargas | Colombia: recargas, paquetes de datos, PINs | Eliges operador y paquete del catálogo | Sí |
movilservicios | Colombia: recargas, paquetes y servicios | Eliges producto y, si aplica, subproducto | Sí |
voznet | Chile: saldo de telefonía Voznet | Monto libre, identificando al cliente por su número | No aplica |
Ves solo los productos habilitados en tu contrato: consúltalos con productos. Si llamas un producto no habilitado recibes 403 API_SERVICE_NOT_ALLOWED.
Siempre es el mismo patrón: pides el catálogo con servicios, eliges un ítem, y pasas su codigo_producto y su monto a crear.
| producto | Parámetros para servicios | Qué envías en crear |
|---|---|---|
internacional | numero completo | codigo_producto y monto = monto_destino del ítem |
icargas | opcional: operador, tipo, monto | codigo_producto y monto = valor_cop del ítem |
movilservicios | opcional: categoria, codigo | codigo_producto, codigo_sub_producto si el ítem lo requiere, y el monto |
voznet | (usa cliente) | numero y monto en CLP |
Los operadores agregan, quitan y cambian productos y precios. No guardes el catálogo por días: consúltalo antes de vender (o cachéalo como máximo unos minutos).
Por compatibilidad, la API también acepta algunos alias en producto (por ejemplo dtone para internacional, o colombia para icargas). Usa siempre los nombres de la tabla de arriba.
Mejoras planificadas para la API. Las fechas se confirman en el Changelog.
| Mejora | Para qué te sirve |
|---|---|
Dirección /api/v1/… | URL estable y más simple (por ejemplo …/api/v1/crear). La dirección actual seguirá funcionando. |
| Ambiente de pruebas (sandbox) | Credenciales de prueba para integrar sin mover dinero real. |
| Notificaciones (webhooks) | Te avisamos cuando una orden cambia de estado, sin que tengas que consultar estado. |
| Saldo prepago por cuenta | Consultar tu saldo disponible y que cada recarga se descuente automáticamente. |
| Reportes por API | Listado de tus órdenes por rango de fechas para conciliación. |
| Más productos | Nuevos países y servicios (PINs, pagos de servicios). |
Cuéntaselo a {{SUPPORT_TEXT}}: priorizamos según lo que piden los integradores.
Guarda el nombre de un cliente Voznet que aún no lo tiene registrado.
A diferencia de crear, esta acción recibe un cuerpo de formulario (application/x-www-form-urlencoded), no JSON.
| Campo | Tipo | Descripción | |
|---|---|---|---|
producto | string | opcional | voznet (valor por defecto) |
numero o account | string | obligatorio | Identifica al cliente |
nombre | string | obligatorio | Entre 2 y 100 caracteres |
forzar | 1 | opcional | Reemplaza el nombre aunque ya tenga uno |
curl -s -X POST "{{API_URL}}?accion=cliente_actualizar" \
-H "X-API-USER: $API_USER" -H "X-API-KEY: $API_KEY" \
--data-urlencode "numero=56912345678" \
--data-urlencode "nombre=María Pérez"
{
"ok": true,
"success": true,
"producto": "voznet",
"message": "Nombre de cliente guardado en Voznet"
}
{
"ok": false,
"success": false,
"message": "…",
"error_code": "NOMBRE_YA_EXISTE",
"nombre_actual": "…"
}
| HTTP | error_code | Cuándo |
|---|---|---|
| 400 | IDENTIFICADOR_REQUIRED, NOMBRE_REQUIRED | Faltan datos |
| 404 | CLIENTE_NOT_FOUND | No existe el cliente |
| 409 | NOMBRE_YA_EXISTE | Ya tiene nombre; usa forzar=1 si corresponde |
| 422 | NOMBRE_INVALIDO, NOMBRE_MUY_LARGO, NOMBRE_RESERVADO | Nombre no válido |
Busca un cliente Voznet por su número y devuelve su nombre, cuenta y saldo actual. Úsala antes de recargar saldo Voznet.
| Parámetro | Tipo | Descripción | |
|---|---|---|---|
producto | string | obligatorio | Siempre voznet |
numero | string | obligatorio | Número del cliente, por ejemplo 56912345678 |
curl -s "{{API_URL}}?accion=cliente&producto=voznet&numero=56912345678" \
-H "X-API-USER: $API_USER" -H "X-API-KEY: $API_KEY"
{
"ok": true,
"success": true,
"producto": "voznet",
"numero": "56912345678",
"cliente": {
"ok": true,
"multiple": false,
"cliente": {
"numero": "56912345678",
"nombre": "María Pérez",
"account": "56912345678",
"saldo_actual": 1250,
"estado": "…",
"requiere_nombre": false
}
}
}
{
"ok": true,
"success": true,
"producto": "voznet",
"cliente": {
"ok": true,
"multiple": true,
"clientes": [
{ "numero": "56912345678", "nombre": "María Pérez" },
{ "numero": "56912345678", "nombre": "…" }
]
}
}
Valores ilustrativos.
cliente.cliente.cliente.multiple es true, el número coincide con varias cuentas: muestra cliente.clientes y pide confirmar.requiere_nombre es true, puedes registrar el nombre con cliente_actualizar.| HTTP | error_code | Cuándo |
|---|---|---|
| 400 | PRODUCTO_REQUIRED, NUMERO_REQUIRED | Faltan parámetros |
| 400 | CLIENTE_SOLO_VOZNET | producto distinto de voznet |
| 403 | API_SERVICE_NOT_ALLOWED | Voznet no habilitado |
| 502 | VOZNET_RESPONSE_ERROR | Cliente no encontrado u otro rechazo de Voznet (el detalle viene en voznet_response) |
| 502 | VOZNET_CURL_ERROR | Voznet no respondió: reintenta |
Crea una orden de recarga en estado pendiente_pago. Valida el producto, el número y el monto, y fija el precio. No envía nada al operador ni mueve dinero.
| Campo | Tipo | Descripción | |
|---|---|---|---|
producto | string | obligatorio | internacional, icargas, movilservicios o voznet |
numero | string | obligatorio | Número del destinatario. Formato según producto |
monto | integer | obligatorio | Monto a cargar, en la moneda del destino. Debe coincidir con el catálogo (ver Montos) |
codigo_producto | string | obligatorio* | Del catálogo de servicios. *No aplica a voznet |
codigo_sub_producto | string | opcional | Solo movilservicios, cuando el ítem lo requiere |
idempotency_key | string | recomendado | Clave única de tu venta, máximo 64 caracteres. Evita duplicados (ver Idempotencia) |
id_externo | string | opcional | Tu referencia para conciliar |
operador | string | opcional | Nombre del operador para la descripción de la orden |
curl -s -X POST "{{API_URL}}?accion=crear" \
-H "X-API-USER: $API_USER" -H "X-API-KEY: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"producto": "internacional",
"numero": "573001234567",
"codigo_producto": "12345",
"monto": 10000,
"id_externo": "venta-000981",
"idempotency_key": "venta-000981"
}'
{
"ok": true,
"success": true,
"recarga_id": 245871,
"estado": "pendiente_pago",
"producto": "internacional",
"numero": "573001234567",
"monto": 10000,
"moneda": "COP",
"total_pagar": 2600,
"moneda_cobro": "CLP",
"id_externo": "venta-000981",
"idempotency_key": "venta-000981",
"message": "…"
}
{
"ok": true,
"success": true,
"recarga_id": 245871,
"estado": "pendiente_pago",
"duplicada": true,
"message": "La orden ya existia para esa idempotency_key"
}
{
"ok": false,
"success": false,
"message": "El monto enviado no coincide con el monto fijo del producto DT One",
"error_code": "DTONE_MONTO_NO_COINCIDE"
}
| Campo | Descripción |
|---|---|
recarga_id | Identificador de la orden. Guárdalo. |
estado | pendiente_pago |
monto, moneda | Lo que recibirá el destinatario |
total_pagar, moneda_cobro | Tu costo por esta recarga |
numero | Número normalizado (solo dígitos) |
id_externo, idempotency_key | Los tuyos, o generados si no los enviaste |
duplicada | true si ya existía una orden con ese idempotency_key |
| HTTP | error_code | Cuándo |
|---|---|---|
| 400 | PRODUCTO_REQUIRED, PRODUCTO_NO_SOPORTADO, NUMERO_REQUIRED, MONTO_INVALIDO, INVALID_JSON | Datos faltantes o inválidos |
| 400 | DTONE_PRODUCT_ID_REQUIRED, DTONE_PRODUCT_NOT_AVAILABLE, DTONE_MONTO_NO_COINCIDE | internacional: producto o monto no válidos para ese número |
| 400 / 404 | ICARGAS_PRODUCTO_REQUIRED, ICARGAS_PRODUCTO_NOT_FOUND, ICARGAS_MONTO_NO_COINCIDE, ICARGAS_MONTO_COLOMBIA_NO_DISPONIBLE | icargas |
| 400 | MOVILSERVICIOS_PRODUCTO_REQUIRED, …_NO_ENCONTRADO, …_MONTO_MINIMO, …_MONTO_MAXIMO, …_MONTO_NO_COINCIDE | movilservicios |
| 403 | API_SERVICE_NOT_ALLOWED | Producto no habilitado |
| 405 | METHOD_NOT_ALLOWED | No usaste POST |
En internacional, crear vuelve a consultar al operador para validar el producto, por lo que puede tardar algunos segundos. Usa un timeout de 60 s.
Envía la recarga al operador y responde con el resultado. Es la única acción que entrega saldo real.
ejecutar a ciegasSi la llamada se corta, se agota el tiempo o recibes un 502, consulta primero estado. La recarga pudo haber llegado aunque no recibieras la respuesta.
Identifica la orden igual que en marcar_pagada: recarga_id (recomendado), id_externo o idempotency_key. La orden debe estar pagada.
curl -s -X POST "{{API_URL}}?accion=ejecutar" --max-time 150 \
-H "X-API-USER: $API_USER" -H "X-API-KEY: $API_KEY" \
-H "Content-Type: application/json" \
-d '{"recarga_id": 245871}'
{
"ok": true,
"success": true,
"recarga_id": 245871,
"estado_anterior": "pagada",
"estado": "procesada",
"producto": "internacional",
"numero": "573001234567",
"monto": 10000,
"moneda": "COP",
"provider_ref": "245871",
"message": "…"
}
{
"ok": true,
"success": true,
"recarga_id": 245871,
"estado": "procesada",
"duplicada": true,
"message": "La recarga ya estaba procesada"
}
{
"ok": false,
"success": false,
"message": "…",
"error_code": "DTONE_TRANSACTION_NOT_SUCCESS",
"recarga_id": 245871,
"estado": "fallida"
}
| Respuesta | estado de la orden | Qué hacer |
|---|---|---|
200 | procesada | Entrega el comprobante |
200 + duplicada: true | procesada | Ya se había ejecutado antes; no se recargó de nuevo |
502 con código …_RESPONSE_ERROR / …_RECHAZADA | fallida | El operador la rechazó: no hubo carga. Si quieres reintentar, crea una orden nueva |
502 con código …_CURL_ERROR / …_INVALID_JSON / …_NOT_SUCCESS | fallida o revision_manual | Consulta estado |
409 ESTADO_INVALIDO | la que tenga | La orden no estaba pagada: consulta estado |
| Timeout / conexión cortada | desconocido | Consulta estado |
Además de los campos comunes, la respuesta puede traer el detalle del operador (por ejemplo voznet_response con el saldo nuevo del cliente Voznet, o el código PIN en productos que lo entregan). Ese detalle también queda disponible después en estado → proveedor_respuesta.
La llamada es síncrona: responde cuando el operador contesta. Normalmente son pocos segundos, pero algunos operadores pueden tardar hasta 2 minutos. Configura un timeout de 150 segundos.
| HTTP | error_code | Cuándo |
|---|---|---|
| 400 | IDENTIFICADOR_REQUIRED | No enviaste identificador |
| 403 | API_SERVICE_NOT_ALLOWED | Producto no habilitado |
| 404 | RECARGA_NOT_FOUND | La orden no existe o no es tuya |
| 409 | ESTADO_INVALIDO | La orden no está pagada |
| 502 | Códigos del operador | Ver Códigos de error |
Todos los error_code que puede devolver la API, agrupados por tema. La columna "Reintentar" te dice si tiene sentido repetir la misma llamada.
| error_code | HTTP | Significado | Reintentar |
|---|---|---|---|
API_CREDENTIALS_REQUIRED | 401 | Faltan las cabeceras X-API-USER o X-API-KEY | No |
API_CLIENT_NOT_FOUND | 401 | Usuario de API desconocido | No |
API_KEY_INVALID | 401 | Clave incorrecta | No |
API_CLIENT_INACTIVE | 403 | Cuenta desactivada | No |
API_IP_NOT_ALLOWED | 403 | La IP no está en tu lista autorizada (la respuesta trae ip) | No |
API_SERVICE_NOT_ALLOWED | 403 | Producto no habilitado para tu cuenta | No |
ACCION_NO_PERMITIDA | 403 | Acción no disponible para tu cuenta | No |
| error_code | HTTP | Significado | Reintentar |
|---|---|---|---|
ACCION_NO_SOPORTADA | 404 | El valor de accion no existe | No |
METHOD_NOT_ALLOWED | 405 | La acción requiere POST | No |
INVALID_JSON | 400 | El cuerpo no es un JSON válido | No |
PRODUCTO_REQUIRED | 400 | Falta producto | No |
PRODUCTO_NO_SOPORTADO | 400 | Valor de producto desconocido | No |
NUMERO_REQUIRED | 400 | Falta numero | No |
MONTO_INVALIDO | 400 | monto falta, no es número o es menor o igual a 0 | No |
IDENTIFICADOR_REQUIRED | 400 | Falta recarga_id, id_externo o idempotency_key (o numero/account en cliente_actualizar) | No |
CATALOGO_NO_IMPLEMENTADO | 501 | El producto no tiene catálogo por API (por ejemplo voznet) | No |
| error_code | HTTP | Significado | Reintentar |
|---|---|---|---|
RECARGA_NOT_FOUND | 404 | La orden no existe o no es de tu cuenta | No |
ESTADO_INVALIDO | 409 | La orden no está en el estado necesario (la respuesta trae estado_actual) | Consulta estado |
| error_code | HTTP | Significado | Reintentar |
|---|---|---|---|
DTONE_NUMERO_REQUIRED | 400 | servicios sin número ni país | No |
DTONE_NUMERO_INVALIDO | 400 | Número vacío o inválido | No |
DTONE_OPERATOR_NOT_FOUND | 404 / 400 | No se encontró operador para el número | No: revisa el número |
DTONE_PRODUCTS_EMPTY | 404 | El operador no tiene productos disponibles | Más tarde |
DTONE_PRODUCT_ID_REQUIRED | 400 | Falta codigo_producto | No |
DTONE_PRODUCT_ID_INVALID | 400 | codigo_producto no numérico | No |
DTONE_PRODUCT_NOT_AVAILABLE | 400 | Ese producto no está disponible para ese número | No: vuelve a pedir el catálogo |
DTONE_MONTO_NO_COINCIDE | 400 | monto distinto del monto_destino del producto | No |
DTONE_PAIS_REQUIRED | 400 | Consulta por país sin pais | No |
DTONE_LOOKUP_ERROR, DTONE_PRODUCTS_ERROR, DTONE_OPERATOR_ID_INVALID, DTONE_PRODUCTS_COUNTRY_ERROR | 502 (400 en crear) | El operador no respondió bien al consultar | Sí, en unos segundos |
DTONE_TRANSACTION_NOT_SUCCESS | 502 | La recarga no se confirmó (la orden queda fallida o revision_manual) | No: consulta estado |
icargas, movilservicios)| error_code | HTTP | Significado | Reintentar |
|---|---|---|---|
ICARGAS_PRODUCTO_REQUIRED | 400 | Falta codigo_producto | No |
ICARGAS_PRODUCTO_NOT_FOUND | 404 | Código de producto inexistente o desactivado | No |
ICARGAS_MONTO_NO_COINCIDE | 400 | monto distinto del valor_cop del paquete | No |
ICARGAS_MONTO_COLOMBIA_NO_DISPONIBLE | 400 | Monto no disponible (la respuesta trae montos_disponibles) | No |
ICARGAS_RESPONSE_ERROR | 502 | El operador rechazó la recarga (orden fallida) | No |
ICARGAS_CURL_ERROR | 502 | Sin respuesta del operador (orden revision_manual) | No: consulta estado |
MOVILSERVICIOS_PRODUCTO_REQUIRED | 400 | Falta o no es numérico codigo_producto | No |
MOVILSERVICIOS_PRODUCTO_NO_ENCONTRADO, MOVILSERVICIOS_SUB_PRODUCTO_NO_ENCONTRADO | 400 | Producto o subproducto inexistente | No |
MOVILSERVICIOS_MONTO_NO_COINCIDE, MOVILSERVICIOS_MONTO_MINIMO, MOVILSERVICIOS_MONTO_MAXIMO | 400 | Monto fuera de lo permitido | No |
MOVILSERVICIOS_PRODUCTO_DESCONTINUADO | 502 | El producto se retiró después de crear la orden | No: crea otra orden |
MOVILSERVICIOS_RESPONSE_ERROR | 502 | El operador rechazó la recarga (orden fallida) | No |
MOVILSERVICIOS_CURL_ERROR, MOVILSERVICIOS_INVALID_JSON | 502 | Sin confirmación del operador (orden revision_manual) | No: consulta estado |
MOVILSERVICIOS_CATALOGO_CURL_ERROR, MOVILSERVICIOS_CATALOGO_INVALIDO, MOVILSERVICIOS_AUTH_ERROR | 502 | No se pudo leer el catálogo del operador | Sí, en unos segundos |
| error_code | HTTP | Significado | Reintentar |
|---|---|---|---|
CLIENTE_SOLO_VOZNET | 400 | cliente/cliente_actualizar solo aplican a voznet | No |
NOMBRE_REQUIRED | 400 | Falta nombre | No |
NOMBRE_INVALIDO, NOMBRE_MUY_LARGO, NOMBRE_RESERVADO | 422 | Nombre no válido (2 a 100 caracteres) | No |
NOMBRE_YA_EXISTE | 409 | El cliente ya tiene nombre (usa forzar=1 para reemplazarlo) | No |
CLIENTE_NOT_FOUND | 404 | No existe un cliente Voznet con ese número | No |
VOZNET_RESPONSE_ERROR | 502 | Voznet rechazó la operación (en ejecutar: revisa estado) | Consulta estado |
VOZNET_CURL_ERROR, VOZNET_INVALID_JSON | 502 | Sin confirmación de Voznet (en ejecutar: orden revision_manual) | No: consulta estado |
Códigos con HTTP 500 (por ejemplo DB_CONNECT_ERROR, INSERT_RECARGA_ERROR o los que terminan en _CONFIG_MISSING, _QUERY_ERROR o _UPDATE_LOCAL_ERROR) indican un problema de nuestro lado. Reintenta más tarde. Si ocurrió en ejecutar, consulta estado antes de hacer cualquier otra cosa, y si persiste avisa a {{SUPPORT_TEXT}} con el recarga_id.
Consulta una orden: su estado, montos, referencias del operador y fechas. Úsala siempre que no tengas certeza del resultado de ejecutar.
Uno de:
| Parámetro | Tipo | Descripción |
|---|---|---|
recarga_id | integer | Recomendado |
id_externo | string | Tu referencia (si la repetiste en varias órdenes, el resultado es ambiguo) |
idempotency_key | string | Tu clave de idempotencia |
curl -s "{{API_URL}}?accion=estado&recarga_id=245871" \
-H "X-API-USER: $API_USER" -H "X-API-KEY: $API_KEY"
{
"ok": true,
"success": true,
"recarga_id": 245871,
"producto": "internacional",
"numero": "573001234567",
"monto": 10000,
"moneda": "COP",
"total_pagar": "2600",
"estado": "procesada",
"id_externo": "venta-000981",
"idempotency_key": "venta-000981",
"transactionid": "4452198765",
"recarga_nombre": "…",
"mensaje": "…",
"proveedor_respuesta": { "…": "detalle del operador" },
"fecha_recarga": "2026-09-26 10:00:00",
"fecha_proceso": "2026-09-26 10:00:07",
"fecha_fin": "2026-09-26 10:00:07"
}
| Campo | Descripción |
|---|---|
estado | pendiente_pago, pagada, procesando, procesada, fallida o revision_manual. Ver ciclo de vida |
monto, moneda | Lo que recibe el destinatario |
total_pagar | Tu costo (puede venir como texto) |
transactionid | Referencia de la transacción en el operador. Úsala para reclamos |
proveedor_respuesta | Detalle del operador en la última ejecución (por ejemplo, el código PIN). Puede ser un objeto o texto |
mensaje | Texto descriptivo del resultado |
fecha_recarga, fecha_proceso, fecha_fin | Creación, último cambio y término (hora de Chile) |
Si la orden está en procesando o revision_manual, consulta cada 30 segundos durante unos minutos y luego cada algunos minutos. No consultes más de una vez por segundo.
| HTTP | error_code | Cuándo |
|---|---|---|
| 400 | IDENTIFICADOR_REQUIRED | Falta el identificador |
| 404 | RECARGA_NOT_FOUND | La orden no existe o no es tuya |
Reglas comunes a todas las acciones: URL, métodos, formato de entrada y de respuesta.
{{API_URL}}?accion=<accion>La acción va siempre en el parámetro accion de la URL. Una acción desconocida responde 404 ACCION_NO_SOPORTADA.
| Acción | Método | Para qué |
|---|---|---|
ping | GET | Comprobar que la API está en línea (sin credenciales) |
productos | GET | Productos habilitados para tu cuenta |
paises | GET | Países, prefijos y banderas para tu formulario |
servicios | GET | Catálogo de un producto (operadores, montos, códigos) |
crear | POST | Crear una orden de recarga |
marcar_pagada | POST | Confirmar que cobraste la orden |
ejecutar | POST | Enviar la recarga al operador |
estado | GET | Consultar una orden |
cliente | GET | Buscar un cliente Voznet |
cliente_actualizar | POST | Guardar el nombre de un cliente Voznet |
| Acciones | Formato |
|---|---|
crear, marcar_pagada, ejecutar | POST con cuerpo JSON y Content-Type: application/json. Un cuerpo que no sea JSON responde 400 INVALID_JSON. |
servicios, estado, cliente | GET con los parámetros en la URL (query string). |
cliente_actualizar | POST con cuerpo de formulario (application/x-www-form-urlencoded). |
ping, productos, paises | Sin parámetros. |
Las acciones POST llamadas con otro método responden 405 METHOD_NOT_ALLOWED.
200 con "ok": true y "success": true.4xx/5xx con "ok": false, message y error_code. Ver Códigos de error.{
"ok": true,
"success": true,
"...": "campos de la acción"
}
{
"ok": false,
"success": false,
"message": "Monto invalido",
"error_code": "MONTO_INVALIDO"
}
AAAA-MM-DD HH:MM:SS en hora de Chile (America/Santiago)."2600"): conviértelos al leerlos.Confirma que cobraste la orden a tu cliente. La orden pasa de pendiente_pago a pagada y queda lista para ejecutar.
Esta acción no verifica pagos: registra que tú ya cobraste. Llámala solo cuando el dinero esté efectivamente recibido. Las órdenes que ejecutes quedan a cargo de tu cuenta.
Identifica la orden con uno de estos campos (se usa el primero presente, en este orden):
| Campo | Tipo | Descripción |
|---|---|---|
recarga_id | integer | El que devolvió crear (recomendado) |
id_externo | string | Tu referencia |
idempotency_key | string | Tu clave de idempotencia |
referencia_pago opcional | string | Tu comprobante de cobro (boleta, transacción). Queda registrado en la orden |
curl -s -X POST "{{API_URL}}?accion=marcar_pagada" \
-H "X-API-USER: $API_USER" -H "X-API-KEY: $API_KEY" \
-H "Content-Type: application/json" \
-d '{"recarga_id": 245871, "referencia_pago": "caja-3-boleta-5521"}'
{
"ok": true,
"success": true,
"recarga_id": 245871,
"estado_anterior": "pendiente_pago",
"estado": "pagada",
"producto": "internacional",
"numero": "573001234567",
"monto": 10000,
"moneda": "COP",
"referencia_pago": "caja-3-boleta-5521"
}
{
"ok": false,
"success": false,
"message": "La recarga no esta en estado pendiente_pago",
"error_code": "ESTADO_INVALIDO",
"estado_actual": "pagada"
}
| HTTP | error_code | Cuándo |
|---|---|---|
| 400 | IDENTIFICADOR_REQUIRED | No enviaste ningún identificador |
| 404 | RECARGA_NOT_FOUND | La orden no existe o no es tuya |
| 409 | ESTADO_INVALIDO | La orden no está en pendiente_pago (ya pagada, ejecutada, etc.) |
| 405 | METHOD_NOT_ALLOWED | No usaste POST |
Lista de países con prefijo telefónico, largo esperado del número, máscara y bandera, para construir el selector de país de tu formulario.
No tiene.
curl -s "{{API_URL}}?accion=paises" \
-H "X-API-USER: $API_USER" -H "X-API-KEY: $API_KEY"
{
"ok": true,
"success": true,
"total": 187,
"paises": [
{
"iso": "CO",
"nombre": "Colombia",
"prefijo": "57",
"min_local": 10,
"max_local": 10,
"ejemplo_local": "3001234567",
"mascara_local": "### ### ####",
"movil_empieza_con": ["3"],
"flag_url": "https://…/banderas/co.svg",
"ejemplo_completo": "573001234567",
"ranking": 1
}
]
}
Valores ilustrativos.
| Campo | Tipo | Descripción |
|---|---|---|
iso | string | Código ISO de 2 letras |
nombre | string | Nombre del país |
prefijo | string | Código telefónico del país, solo dígitos |
min_local, max_local | integer | Largo mínimo y máximo del número local |
ejemplo_local | string | Número local de ejemplo |
mascara_local | string | Máscara de presentación (# = dígito) |
movil_empieza_con | string[] | Dígitos con que empiezan los celulares (puede venir vacío) |
flag_url | string | null | Bandera en SVG cuadrado (muéstrala redonda si quieres) |
ejemplo_completo | string | prefijo + ejemplo_local: así se envía a internacional |
ranking | integer | Posición según volumen de recargas (1 = más usado). La lista viene ordenada por este campo |
Que un país esté en la lista no garantiza cobertura para todos sus operadores. La validación real la hace servicios. Esta lista cambia poco: puedes guardarla en caché por un día.
Comprueba que la API está en línea. No requiere credenciales.
curl -s "{{API_URL}}?accion=ping"
{
"ok": true,
"success": true,
"message": "API generica de recargas activa",
"version": "0.1.0",
"acciones_disponibles": ["ping", "paises", "productos", "servicios", "crear", "marcar_pagada", "ejecutar", "estado", "..."]
}
Para monitoreo de disponibilidad. ping no valida tus credenciales: para eso usa productos.
Lista los productos habilitados para tu cuenta. Sirve también para verificar que tus credenciales funcionan.
No tiene.
curl -s "{{API_URL}}?accion=productos" \
-H "X-API-USER: $API_USER" -H "X-API-KEY: $API_KEY"
{
"ok": true,
"success": true,
"api_user": "api_pv_123",
"total": 2,
"productos": [
{
"producto": "internacional",
"nombre": "Recargas Internacionales",
"tipo": "recarga_internacional",
"requiere_cliente": false,
"acciones": ["servicios", "crear", "marcar_pagada", "ejecutar", "estado"],
"activo": true
},
{
"producto": "voznet",
"nombre": "Voznet Chile",
"tipo": "recarga_nacional",
"requiere_cliente": true,
"acciones": ["cliente", "crear", "marcar_pagada", "ejecutar", "estado"],
"activo": true
}
]
}
| Campo | Tipo | Descripción |
|---|---|---|
producto | string | Valor que usas en el parámetro producto de las demás acciones |
nombre | string | Nombre para mostrar |
tipo | string | Clasificación del producto |
requiere_cliente | boolean | true si antes debes identificar al cliente con cliente |
acciones | string[] | Acciones que aplican a este producto |
Solo los de autenticación.
Devuelve el catálogo de un producto: operadores, ítems, montos y el codigo_producto que necesitas para crear.
Todos van en la URL.
| Parámetro | Tipo | Descripción | |
|---|---|---|---|
producto | string | obligatorio | internacional, icargas o movilservicios |
internacionalDetecta el operador a partir del número y devuelve sus recargas de valor fijo, ordenadas de menor a mayor.
| Parámetro | Tipo | Descripción | |
|---|---|---|---|
numero | string | obligatorio | Número completo con código de país, solo dígitos |
curl -s "{{API_URL}}?accion=servicios&producto=internacional&numero=573001234567" \
-H "X-API-USER: $API_USER" -H "X-API-KEY: $API_KEY"
{
"ok": true,
"success": true,
"producto": "internacional",
"numero_sin_plus": "573001234567",
"pais": "CO",
"pais_nombre": "Colombia",
"operador": "Claro Colombia",
"total": 6,
"servicios": [
{
"codigo_producto": "12345",
"nombre": "Claro Colombia 10.000 COP",
"tipo_producto": "saldo",
"operador": "Claro Colombia",
"monto_destino": 10000,
"moneda_destino": "COP",
"total_pagar": 2600,
"moneda_cobro": "CLP",
"logo_url": "https://…/logos/claro.png"
}
]
}
{
"ok": false,
"success": false,
"message": "…",
"error_code": "DTONE_OPERATOR_NOT_FOUND"
}
| Campo | Descripción |
|---|---|
codigo_producto | Lo envías en crear |
nombre | Descripción para mostrar |
tipo_producto | saldo o bolsa (paquete de datos, minutos o SMS) |
monto_destino, moneda_destino | Lo que recibe el destinatario. monto_destino es el monto que envías en crear |
total_pagar, moneda_cobro | Tu costo en CLP. Si no se pudo calcular viene null junto a precio_error: no vendas ese ítem |
logo_url | Logo del operador (puede ser null; en ese caso usa logo_fallback, las iniciales) |
icargas (Colombia)Catálogo por operador. No detecta el operador por número: tu cliente lo elige.
| Parámetro | Tipo | Descripción | |
|---|---|---|---|
operador | string | opcional | Filtra por operador (nombre exacto, sin distinguir mayúsculas) |
tipo | string | opcional | saldo (recargas) o datos (paquetes) |
categoria | string | opcional | Filtra por categoría |
codigo | number | opcional | Un producto específico |
monto | number | opcional | Filtra las recargas de monto libre por monto (COP) |
curl -s "{{API_URL}}?accion=servicios&producto=icargas&operador=CLARO&tipo=saldo" \
-H "X-API-USER: $API_USER" -H "X-API-KEY: $API_KEY"
{
"ok": true,
"producto": "icargas",
"pais": "CO",
"total_operadores": 1,
"operadores": [{ "operador": "CLARO", "permite_monto_libre": true, "logo_url": "https://…" }],
"total": 8,
"servicios": [
{
"codigo_producto": "101",
"operador": "CLARO",
"tipo": "monto_libre",
"tipo_producto": "saldo",
"nombre": "Recarga Claro 10.000",
"valor_cop": 10000,
"total_pagar": 2600,
"moneda_destino": "COP",
"moneda_cobro": "CLP"
}
]
}
En crear envías codigo_producto y monto = valor_cop. Recuerda: número local de 10 dígitos, sin 57.
movilservicios (Colombia)| Parámetro | Tipo | Descripción | |
|---|---|---|---|
categoria | string | opcional | Filtra por categoría |
codigo | number | opcional | Un producto específico |
{
"codigo_producto": 12,
"categoria": "Recargas",
"nombre": "Recarga Tigo",
"monto_minimo": 1000,
"monto_maximo": 200000,
"moneda": "COP",
"requiere_sub_producto": false,
"sub_productos": []
}
Si requiere_sub_producto es true, elige uno de sub_productos y envía su codigo_sub_producto y su valor como monto. Si no, envía un monto entre monto_minimo y monto_maximo.
| HTTP | error_code | Cuándo |
|---|---|---|
| 400 | PRODUCTO_REQUIRED / PRODUCTO_NO_SOPORTADO | Falta o no existe producto |
| 403 | API_SERVICE_NOT_ALLOWED | Producto no habilitado |
| 400 | DTONE_NUMERO_REQUIRED | internacional sin número |
| 404 | DTONE_OPERATOR_NOT_FOUND / DTONE_PRODUCTS_EMPTY | Número sin operador o sin productos |
| 501 | CATALOGO_NO_IMPLEMENTADO | Producto sin catálogo (voznet) |
| 502 | Varios (DTONE_LOOKUP_ERROR, MOVILSERVICIOS_CATALOGO_CURL_ERROR…) | El operador no respondió: reintenta en unos segundos |
Estamos para ayudarte a integrar y operar.
Escribe a {{SUPPORT_TEXT}}.
Para resolver rápido, envía siempre:
X-API-USER). Nunca envíes tu clave.recarga_id (y tu id_externo si lo usaste).error_code recibidos.| Situación | Qué hacemos |
|---|---|
Orden en revision_manual | Verificamos con el operador si la recarga llegó y actualizamos la orden. |
El cliente dice que no recibió una recarga procesada | Con el transactionid abrimos el reclamo con el operador. |
| Cambio de IP de tu servidor | Registramos la nueva IP. Avísanos antes del cambio. |
| Clave comprometida | La revocamos y te entregamos una nueva de inmediato. |