Consulta el catálogo con tus precios de distribuidor, mira tu saldo y compra desde tu propio sistema.
Viene incluida con los planes Mayorista y Distribuidor. Las claves se crean en Mi cuenta → Mis claves de API.
https://recargasdigitales.com/api/v1| Prefijo | Qué hace | |
|---|---|---|
| Pruebas | rd_test_… | Lee el catálogo y tus precios de verdad. Los pedidos son simulados: no se entrega nada, no se te cobra nada. Billetera de mentira de 1.000 $. |
| Producción | rd_live_… | Los pedidos se cobran de tu billetera y se entregan. |
El entorno va en la clave, no en un parámetro. No hay ninguna combinación de
campos que haga que una clave rd_test_ compre de verdad. Empieza con la de
pruebas y cambia sólo la clave cuando todo funcione: no hay que tocar nada más.
La clave va en una cabecera. Las dos formas valen:
-H "Authorization: Bearer rd_live_xxxxxxxx…"
-H "X-API-Key: rd_live_xxxxxxxx…"
⚠️ La clave no se acepta por la URL. Las URL acaban en el registro de
accesos, en el historial del navegador y en el Referer. Una clave que compra
no puede vivir ahí.
⚠️ La clave se enseña una sola vez. No la guardamos en claro, así que no
podemos volver a enseñártela ni nosotros. Si la pierdes, revócala y crea otra.
Tu clave deja de valer el día que caduque tu plan. No hay que revocar nada:
empezarás a recibir 401. Mira dias_restantes en /saldo para verlo venir.
CLAVE=rd_test_pega_aqui_tu_clave
# 1 · ¿Qué puedo hacer con esta clave?
curl -s -H "Authorization: Bearer $CLAVE" \
https://recargasdigitales.com/api/v1/ayuda
# 2 · Mi saldo
curl -s -H "Authorization: Bearer $CLAVE" \
https://recargasdigitales.com/api/v1/saldo
# 3 · Diez productos con mi precio
curl -s -H "Authorization: Bearer $CLAVE" \
"https://recargasdigitales.com/api/v1/catalogo?n=10"
Todo lo que devuelve esta API tiene ok y peticion_id:
{ "ok": true, "peticion_id": "rd-4f2a9c…", "…": "…", "ms": 35 }
{ "ok": false, "peticion_id": "rd-4f2a9c…",
"error": "saldo_insuficiente",
"mensaje": "Tu saldo es $1.20 y este pedido son $5.00…" }
error es un código estable en minúsculas. Es lo que debes comparar en tu código.mensaje es para una persona y puede cambiar mañana. No programes contra él.peticion_id identifica esa llamada exacta. Guárdalo en tu registro: es lo único que necesitamos para encontrar qué pasó cuando nos escribas.Cada clave lleva los permisos que le des al crearla. Da sólo los que necesites: una clave que alimenta un escaparate no tiene por qué poder comprar.
| Permiso | Da acceso a |
|---|---|
catalogo | GET /catalogo |
precio | GET /precio |
saldo | GET /saldo |
pedidos | POST /pedido, GET /pedido, GET /pedidos |
Sin el permiso, la respuesta es 403 sin_permiso.
60 por minuto y por clave en producción, 120 en pruebas. Todas las respuestas lo dicen:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 57
Al pasarte recibes 429 demasiadas_llamadas con Retry-After en segundos y
reintentar_en_s en el cuerpo. Usa ese número: reintentar a ciegas es lo
que dispara el siguiente tope.
GET /ayudaQué hay, en qué entorno estás y qué permisos tiene tu clave. No pide ningún permiso: es la primera llamada que conviene hacer.
GET /catalogoLos productos y variantes activos con tu precio.
| Parámetro | Por omisión | Qué hace |
|---|---|---|
n | 200 | Cuántos, máximo 500 |
desde | 0 | Desde cuál (paginado) |
buscar | — | Filtra por nombre de producto o variante |
proveedor | — | fazercards, reloadly… |
region | — | Código de país del producto |
tipo | — | Tipo de recarga |
modificado_desde | — | 2026-09-01 o 2026-09-01T10:00:00. Sólo lo que cambió |
curl -s -H "Authorization: Bearer $CLAVE" \
"https://recargasdigitales.com/api/v1/catalogo?buscar=netflix&n=20"
{
"ok": true,
"desde": 0, "n": 20, "total": 3022, "siguiente": 20,
"variantes": [
{
"variante_id": "ae1f42de-49f9-401e-a759-be1b9eb55699",
"producto_id": "8e323eb0-68f6-4f0e-82d7-c081128fdf09",
"producto": "8 Ball Pool",
"variante": "Golden Spin",
"region": null,
"entrega": "recarga_directa",
"tipo": null,
"proveedor": "fazercards",
"precio_usd": 0.82,
"publico_usd": 0.89,
"ahorro_usd": 0.07,
"stock": 99
}
]
}
precio_usd es lo que se te cobra a ti. Pon tu margen sobre este número.publico_usd es lo que paga quien entra sin plan. Sirve para enseñar un «antes / ahora», no para calcular.stock: null significa sin límite conocido, no cero.desde hasta que siguiente sea null:
desde=0
while [ "$desde" != "null" ]; do
r=$(curl -s -H "Authorization: Bearer $CLAVE" \
"https://recargasdigitales.com/api/v1/catalogo?n=500&desde=$desde")
echo "$r" | jq -c '.variantes[]'
desde=$(echo "$r" | jq -r '.siguiente')
done
GET /precioEl precio de una variante, con los campos de entrega que hace falta mandar
para comprarla. Es la llamada que se hace justo antes de POST /pedido.
| Parámetro | Por omisión | |
|---|---|---|
variante | *obligatorio* | El variante_id del catálogo |
cantidad | 1 | De 1 a 20 |
curl -s -H "Authorization: Bearer $CLAVE" \
"https://recargasdigitales.com/api/v1/precio?variante=ae1f42de-…&cantidad=3"
{
"ok": true,
"variante": { "…": "…", "precio_usd": 0.82 },
"cantidad": 3,
"total_usd": 2.46,
"campos_requeridos": [
{ "clave": "telefono", "etiqueta": "Número a recargar", "tipo": "telefono", "opciones": null }
],
"comprable": true
}
Usa total_usd tal cual. Si lo multiplicas y redondeas por tu cuenta, tu total
puede no cuadrar con el que te cobre /pedido y lo leerás como un cobro de más.
GET /saldo{ "ok": true, "entorno": "produccion", "saldo_usd": 148.30, "moneda": "USD",
"plan": { "nombre": "Distribuidor", "hasta": "2026-10-13", "dias_restantes": 30 } }
Con una clave de pruebas devuelve la billetera simulada.
POST /pedido · comprarcurl -s -X POST \
-H "Authorization: Bearer $CLAVE" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: mi-pedido-000123" \
-d '{
"variante_id": "ae1f42de-49f9-401e-a759-be1b9eb55699",
"cantidad": 1,
"datos": { "telefono": "04121234567" },
"precio_max_usd": 0.90
}' \
https://recargasdigitales.com/api/v1/pedido
Idempotency-Key es obligatoriaUn identificador único tuyo para ese pedido — el número de pedido de tu
sistema, o un UUID. Entre 8 y 120 caracteres de A-Z a-z 0-9 . _ : -.
Si reintentas con la misma clave, no se compra dos veces: te devolvemos el
pedido que ya existía con "reintento": true y código 200 en vez de 201.
⚠️ Esto no es burocracia. Tu librería HTTP reintenta sola cuando se le agota el
tiempo de espera, tu cola reintenta el trabajo fallido y tu operador pulsa dos
veces. Sin esta cabecera, cada reintento sería otra gift card comprada y
cobrada.
>
Una clave por pedido. Reutilizarla para comprar otra cosa distinta da
409 idempotency_key_reutilizada, no el pedido viejo en silencio.
| Campo | ||
|---|---|---|
variante_id | *obligatorio* | Del catálogo |
cantidad | 1 | De 1 a 20 |
datos | {} | Los campos_requeridos que diga /precio |
precio_max_usd | — | Recomendado. «No compres si el precio unitario subió de aquí» |
simular | false | Hace todas las comprobaciones y no compra. Útil para probar tu integración con una clave de producción |
Usa precio_max_usd. Los precios de esta tienda siguen al coste del
proveedor y se mueven solos. Sin este campo, un cambio de precio entre que
consultas y compras te lo comes tú.
{
"ok": true,
"entorno": "produccion",
"reintento": false,
"pedido": {
"pedido_id": "9f1c…",
"numero": "9F1C2A4B",
"estado": "entregado",
"total_usd": 0.82,
"creado": "2026-09-13 21:04:11",
"lineas": [ { "variante_id": "…", "descripcion": "8 Ball Pool · Golden Spin",
"cantidad": 1, "precio_usd": 0.82, "datos": {"telefono":"04121234567"} } ],
"entregas": [ { "entrega_id": "…", "tipo": "codigo",
"codigo": "XXXX-XXXX-XXXX", "codigo_pin": null } ]
},
"saldo_usd": 147.48
}
Estados posibles: entregado, pendiente, enviado, rechazado,
devuelto.
pendiente no es un error: significa que el mayorista todavía no ha confirmado.
Vuelve a preguntar por GET /pedido?id=… en unos minutos. No repitas el
POST — para eso está la Idempotency-Key.
| HTTP | error | Qué pasó |
|---|---|---|
| 400 | falta_idempotency_key | No mandaste la cabecera |
| 400 | idempotency_key_invalida | Menos de 8 caracteres o caracteres raros |
| 402 | saldo_insuficiente | Recarga tu billetera desde la web |
| 403 | kyc_requerido | Hay que verificar la identidad. Se hace desde la web |
| 404 | no_existe | Esa variante ya no está en el catálogo |
| 409 | precio_cambio | El precio subió por encima de tu precio_max_usd |
| 409 | importe_excesivo | Por encima del tope por pedido (500 $ por omisión) |
| 409 | producto_fisico | Los productos que hay que enviar se compran por la web |
| 409 | no_comprable | Producto «a consultar» o sin precio |
| 422 | datos_invalidos | Faltan campos de entrega. Vienen en detalles |
| 503 | compra_cerrada | Hemos cerrado la compra por API temporalmente |
GET /pedido?id=…Cómo va un pedido y qué se entregó, con los códigos.
curl -s -H "Authorization: Bearer $CLAVE" \
"https://recargasdigitales.com/api/v1/pedido?id=9f1c…"
⚠️ Cada vez que se piden los códigos de un pedido queda registrado, igual que
cuando se destapan desde la web. Si un cliente reclama que su código ya estaba
canjeado, eso es lo que permite saber quién lo vio y cuándo.
GET /pedidosTus últimos pedidos. n (máx. 100) y desde. No trae los códigos: se piden
de uno en uno con la ruta de arriba.
POST /pruebas/reiniciarSólo con clave rd_test_. Borra tus pedidos simulados y vuelve a llenar la
billetera de mentira. Es lo que te permite ejecutar tu batería de pruebas dos
veces seguidas.
curl -s -X POST -H "Authorization: Bearer $CLAVE_TEST" \
https://recargasdigitales.com/api/v1/pruebas/reiniciar
En pruebas puedes forzar el desenlace de un pedido con ?forzar=:
curl -s -X POST "…/api/v1/pedido?forzar=rechazado" … # estado: rechazado
curl -s -X POST "…/api/v1/pedido?forzar=pendiente" … # estado: pendiente
Lo que de verdad hay que probar no es el camino feliz —ése sale solo— sino qué
hace tu sistema cuando un pedido se rechaza o se queda pendiente. En producción
eso depende del mayorista y no se puede provocar.
| HTTP | error | |
|---|---|---|
| 401 | no_autorizado | Falta la clave, no existe, está revocada o tu plan caducó |
| 403 | sin_permiso | Esa clave no lleva el permiso que pide la ruta |
| 404 | ruta_desconocida | Mira GET /ayuda |
| 404 | version_desconocida | Sólo existe v1 |
| 405 | metodo_no_admitido | La cabecera Allow dice cuáles valen |
| 429 | demasiadas_llamadas | Espera lo que diga Retry-After |
| 500 | fallo_interno | Mándanos el peticion_id |
El 401 no distingue entre «no mandaste clave», «esa clave no existe», «está
revocada» y «tu plan caducó». Es a propósito: distinguirlos le diría a quien
prueba claves al azar cuáles ha acertado. Si no sabes cuál es tu caso, mira
tu página de claves.
1. La clave va en el servidor, nunca en el navegador. Esta API no admite
CORS a propósito: si la llamas desde el JavaScript de una página pública,
estás regalando la clave. Llámala desde tu backend.
2. Una clave por integración, con los permisos justos. Así puedes revocar
una sin parar las demás.
3. Guarda el peticion_id de cada llamada en tu registro.
4. Usa siempre precio_max_usd en los pedidos.
5. Cachea el catálogo y refréscalo con modificado_desde en vez de bajarlo
entero cada vez.
6. Trata pendiente como un estado normal y consúltalo por GET /pedido.
Nunca reenviando el POST.