API v1

Documentación

Integra recargas, facturas, remesas y Paso Rápido con una sola API REST. Peticiones y respuestas en JSON, sobre HTTPS.

Introducción

#

La URL base de producción es:

Base URL
https://api.zenterapp.com/v1

Hay dos entornos, determinados por el prefijo de tu API key: zp_live_ para producción y zp_test_ para sandbox. El sandbox simula respuestas sin mover dinero real.

Todos los montos están en pesos dominicanos (DOP) con dos decimales.

Quickstart

#

Haz tu primera llamada en menos de un minuto. Con una key de sandbox, crea una recarga de prueba:

shell
curl https://api.zenterapp.com/v1/recargas \
  -H "Authorization: Bearer zp_test_0c7d..." \
  -d carrier="Claro" -d account="8094128890" -d amount=100

Recibirás una transacción con status: "completed". Cambia tu key por una zp_live_ para procesar en producción.

Autenticación

#

Envía tu API key como Bearer token en el header Authorization de cada petición. Mantén tus keys en secreto y rótalas si se exponen.

curl https://api.zenterapp.com/v1/balance \
  -H "Authorization: Bearer zp_live_4f9a..."

Idempotencia

#

Para evitar transacciones duplicadas ante reintentos de red, envía un header Idempotency-Key único por operación (un UUID). Si repites la misma key, la API devuelve el resultado de la primera petición sin volver a procesar.

shell
curl https://api.zenterapp.com/v1/recargas \
  -H "Authorization: Bearer zp_live_4f9a..." \
  -H "Idempotency-Key: 9f1c2b7a-..." \
  -d carrier="Claro" -d account="8094128890" -d amount=200

Rate limits

#

El límite por defecto es de 100 peticiones por minuto por API key. Cada respuesta incluye los headers X-RateLimit-Remaining y X-RateLimit-Reset. Al excederlo recibirás un 429.

Listar operadores

#
GET/v1/operators

Devuelve los operadores disponibles y su categoría.

200 OK
{
  "data": [
    { "id": "Claro", "category": "recarga", "group": "Telefonía móvil" },
    { "id": "Edenorte", "category": "factura", "group": "Electricidad" },
    { "id": "NATCASH", "category": "remesa", "group": "Remesas" }
  ]
}

Crear una recarga

#
POST/v1/recargas
Parámetros
carrierreqstringID del operador (p. ej. Claro).
accountreqstringNúmero de teléfono destino.
amountreqnumberMonto en DOP.
referencestringReferencia propia para conciliar.
curl https://api.zenterapp.com/v1/recargas \
  -H "Authorization: Bearer zp_live_4f9a..." \
  -d carrier="Claro" \
  -d account="8094128890" \
  -d amount=200 \
  -d reference="REF-1001"

Respuesta:

200 OK
{
  "id": "txn_000174f3z",
  "status": "completed",
  "carrier": "Claro",
  "account": "8094128890",
  "amount": 200,
  "benefit": 8.00,
  "currency": "DOP",
  "created_at": "2026-06-18T15:00:00-04:00"
}

Pagar una factura

#

Primero consulta la cuenta para obtener el titular y el monto pendiente, luego confirma el pago.

GET/v1/facturas/lookup
POST/v1/facturas
Parámetros
carrierreqstringOperador de factura (p. ej. Edenorte).
accountreqstringNIC, contrato o cuenta.
amountreqnumberMonto a pagar en DOP.
shell
# 1. Consultar
curl https://api.zenterapp.com/v1/facturas/lookup \
  -H "Authorization: Bearer zp_live_4f9a..." \
  -d carrier="Edenorte" -d account="7741203"

# 2. Pagar
curl https://api.zenterapp.com/v1/facturas \
  -H "Authorization: Bearer zp_live_4f9a..." \
  -d carrier="Edenorte" -d account="7741203" -d amount=1250

Enviar una remesa

#
POST/v1/remesas
Parámetros
providerreqstringNATCASH o MONCASH.
accountreqstringTeléfono o billetera destino.
amountreqnumberMonto en DOP.
shell
curl https://api.zenterapp.com/v1/remesas \
  -H "Authorization: Bearer zp_live_4f9a..." \
  -d provider="NATCASH" \
  -d account="+50933441290" \
  -d amount=2500

Consultar balance

#
GET/v1/balance

Devuelve el balance disponible de tu wallet.

200 OK
{
  "balance": 184350.75,
  "currency": "DOP"
}

Transacciones

#
GET/v1/transactions
GET/v1/transactions/:id
Query params
categorystringFiltra por recarga, factura, remesa o pasorapido.
statusstringFiltra por estado (completed, failed, …).
limitnumberMáximo de resultados (1–100, por defecto 25).
starting_afterstringCursor de paginación (id de transacción).
shell
curl "https://api.zenterapp.com/v1/transactions?category=recarga&limit=10" \
  -H "Authorization: Bearer zp_live_4f9a..."

Paginación

#

Los endpoints de listado usan paginación basada en cursor. Pasa el último id recibido en starting_after para obtener la siguiente página. La respuesta incluye has_more.

200 OK
{
  "data": [ /* ... */ ],
  "has_more": true
}

Webhooks

#

Registra un endpoint para recibir eventos firmados cuando cambia el estado de una transacción. Verifica la firma con el secreto whsec_... usando el header X-Zenter-Signature.

Evento
{
  "event": "transaction.completed",
  "data": {
    "id": "txn_000174f3z",
    "status": "completed",
    "amount": 200
  }
}

Verificar la firma en Node.js:

import crypto from "crypto";

function verify(payload, signature, secret) {
  const expected = crypto
    .createHmac("sha256", secret)
    .update(payload)
    .digest("hex");
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

Eventos: transaction.completed, transaction.failed, transaction.reversed, balance.low.

Objetos

#

Estos son los recursos principales que devuelve la API. Los mismos modelos se usan en el panel y en los webhooks.

El objeto Transaction

Campos
idstringIdentificador único (txn_…).
referencestringReferencia del comercio.
categoryenumrecarga · factura · remesa · pasorapido.
carrierstringID del operador.
accountstringCuenta destino (teléfono, NIC…).
amountnumberMonto en DOP.
benefitnumberGanancia del comercio (4% en recargas; 0 en facturas).
currencystringSiempre “DOP”.
statusenumpending · processing · completed · failed · reversed.
channelenumapi · dashboard.
created_atstringFecha de creación (ISO 8601).
updated_atstringÚltima actualización (ISO 8601).

El objeto Webhook

Campos
idstringIdentificador único (wh_…).
urlstringEndpoint HTTPS de destino.
eventsarrayEventos suscritos.
statusenumactive · disabled.
secretstringSecreto de firma (whsec_…).
created_atstringFecha de creación (ISO 8601).

Errores

#

Los errores devuelven un código HTTP y un cuerpo JSON con code y message.

422 Unprocessable Entity
{
  "error": {
    "code": "transaction_failed",
    "message": "El operador rechazó la transacción."
  }
}
CódigoHTTPDescripción
invalid_request400Faltan parámetros o son inválidos.
unauthorized401API key ausente o inválida.
insufficient_funds402Balance insuficiente en el wallet.
not_found404El recurso no existe.
transaction_failed422El operador rechazó la transacción.
rate_limited429Demasiadas peticiones.
carrier_unavailable503El operador no está disponible.

SDKs

#

Usa nuestras librerías oficiales para integrar más rápido. También puedes llamar la API directamente con cualquier cliente HTTP.

npm install @zenterpay/node