notpanel
ServiciosPreciosPreguntas frecuentesSorteoAPI
notpanel

Seguidores, likes y vistas para cada plataforma.

El catálogo combina servicios operados directamente con capacidad de socios verificados. La disponibilidad, el tiempo, el refill y el drip-feed se muestran por servicio; las rutas y la identidad de los socios son confidenciales.

Producto

  • Servicios
  • Precios
  • Índice de precios
  • Programa de afiliados

Recursos

  • API
  • Blog
  • Preguntas frecuentes
  • Estado

Empresa

  • Sobre nosotros
  • Por qué NotPanel
  • Contáctanos

Legal

  • Términos del Servicio
  • Política de Privacidad
  • Política de Reembolsos

Idiomas

  • English
  • Español
  • Português
  • Русский
  • Türkçe
  • العربية
  • हिन्दी
  • Bahasa Indonesia
  • Français
  • 中文

© 2026 NotPanel. Todos los derechos reservados.

support@notpanel.com
notpanel
Documentación de la API
+
Documentación de la API

Introducción

  • Resumen
  • Primeros pasos
  • Autenticación
  • Límites de tasa
  • Errores

Catálogo

  • Listar servicios
  • Catálogo avanzado
  • Tipos de servicio

Pedidos

  • Realizar pedido
  • Estado del pedido
  • Cotización de reembolso
  • Refill
  • Cancelar

Cuenta

  • Estado de la cuenta
  • Saldo

Webhooks

  • Gestionar webhooks

Referencia

  • Registro de cambios
  • SDK y librerías

¿Necesitas ayuda?

support@notpanel.com →

Registrar webhook

Suscribe una URL pública a eventos compatibles. Cada endpoint recibe su propio secreto HMAC-SHA256, que se muestra una sola vez al crearlo. Si se pierde, elimina el endpoint y añádelo de nuevo.

POSThttps://notpanel.com/api/v3action=webhook.add
Clave de API requeridaCon límite de tasa (cuenta compartida + IP + acción)Cuerpo: application/x-www-form-urlencoded
Máximo 5 webhooks por clave de API. Usa una URL HTTPS accesible públicamente. Se rechazan destinos inseguros, privados, de loopback o que no sean públicos.

Parámetros

NombreTipoDescripción
keyObligatoriostringTu clave de API.
actionObligatoriostringDebe ser la cadena literal "webhook.add".
urlObligatoriostring (URL)Endpoint HTTPS público que recibirá POSTs. Debe ser accesible desde la internet pública.
eventsstring (CSV)Subconjunto separado por comas de los seis eventos compatibles que aparecen abajo. Omítelo para suscribirte a los seis.

Ejemplo de petición

Reemplaza YOUR_API_KEY por la clave generada en la página de API de tu panel.

curl -X POST https://notpanel.com/api/v3 \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "key=YOUR_API_KEY&action=webhook.add&url=https://your-server.example.com/notpanel-webhook&events=order.completed,order.refunded"
const res = await fetch("https://notpanel.com/api/v3", {
  method: "POST",
  headers: { "Content-Type": "application/x-www-form-urlencoded" },
  body: new URLSearchParams({
    key: "YOUR_API_KEY",
    action: "webhook.add",
    url: "https://your-server.example.com/notpanel-webhook",
    events: "order.completed,order.refunded",
  }),
});

const data = await res.json();
console.log(data);
import requests

res = requests.post(
  "https://notpanel.com/api/v3",
  data={
    "key": "YOUR_API_KEY",
    "action": "webhook.add",
    "url": "https://your-server.example.com/notpanel-webhook",
    "events": "order.completed,order.refunded",
},
)
print(res.json())
<?php
$body = http_build_query([
    'key' => 'YOUR_API_KEY',
    'action' => 'webhook.add',
    'url' => 'https://your-server.example.com/notpanel-webhook',
    'events' => 'order.completed,order.refunded',
]);

$response = file_get_contents('https://notpanel.com/api/v3', false, stream_context_create([
    'http' => [
        'method'  => 'POST',
        'header'  => "Content-Type: application/x-www-form-urlencoded\r\n",
        'content' => $body,
        'ignore_errors' => true,
    ],
]));

print_r(json_decode($response, true));

Ejemplo de respuesta

{
  "webhook_id": "3f2504e0-4f89-41d3-9a0c-0305e82c3301",
  "url": "https://your-server.example.com/notpanel-webhook",
  "secret": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
  "events": [
    "order.completed",
    "order.refunded"
  ]
}

Errores comunes

EstadoCuerpoCausa
400{"error":"Maximum 5 webhook endpoints per API key"}Los endpoints existentes agotaron el límite. Elimina primero un endpoint sin usar con action=webhook.remove.
400{"error":"Webhook URL must be a publicly reachable HTTPS URL"}La URL no era HTTPS válida, no se pudo analizar o se resolvió a una IP privada/de loopback.
400{"error":"Webhook event is invalid","error_code":"INVALID_WEBHOOK_EVENT"}El nombre del evento no está en la lista de permitidos. Revisa la ortografía: los nombres usan el formato "order.<status>".

Eventos disponibles

  • order.completed
  • order.partial
  • order.processing
  • order.in_progress
  • order.refunded
  • order.refill_completed

Listar webhooks

action=webhook.list devuelve cada endpoint registrado bajo la clave que llama, incluida su salud de entrega (status, failureCount, lastDeliveredAt).

key=YOUR_API_KEY&action=webhook.list
[
  {
    "id": "3f2504e0-4f89-41d3-9a0c-0305e82c3301",
    "url": "https://your-server.example.com/notpanel-webhook",
    "events": ["order.completed", "order.refunded"],
    "status": "active",
    "failureCount": 0,
    "lastDeliveredAt": "2026-04-30T15:42:11.000Z",
    "createdAt": "2026-04-15T09:01:00.000Z"
  }
]

Eliminar un webhook

action=webhook.remove con el UUID del endpoint elimina el endpoint y revoca su secreto de firma. Una entrega ya en curso todavía puede llegar; no se encolarán eventos nuevos para él.

key=YOUR_API_KEY&action=webhook.remove&id=3f2504e0-4f89-41d3-9a0c-0305e82c3301

{
  "success": true
}

Payload de entrega

Cada entrega es un POST con Content-Type: application/json. El cuerpo contiene events, timestamp y deliveryId. La configuración pública actual agrupa durante un máximo de 5 segundos e incluye hasta 50 objetos, cada uno con id lógico estable, event, timestamp y data. La cola o una interrupción pueden añadir demora, por lo que no se promete entrega en 5 segundos. Las cabeceras incluyen:

  • X-Webhook-Signature — sha256=&lt;hex&gt;, calculada sobre &lt;timestamp&gt;.&lt;bytes exactos del cuerpo JSON&gt;.
  • X-Webhook-Timestamp — marca de tiempo Unix de la entrega, en segundos.
  • X-Webhook-Delivery-Id — UUID del lote de entrega, reutilizado cuando se reintenta ese mismo lote. No hay una cabecera de evento para toda la entrega; lee cada evento del cuerpo.
{
  "events": [
    {
      "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
      "event": "order.completed",
      "timestamp": 1777534931,
      "data": {
        "order": 7001,
        "orderId": 7001,
        "serviceId": 1,
        "status": "Completed",
        "status_key": "completed",
        "charge": "0.50",
        "startCount": 1234,
        "remains": 0
      }
    }
  ],
  "timestamp": 1777534931,
  "deliveryId": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
}

Verificación de firmas

Lee X-Webhook-Timestamp y los bytes exactos del cuerpo JSON recibido. Calcula HMAC-SHA256 sobre &lt;timestamp&gt;.&lt;bytes del cuerpo&gt; con el secreto, dale formato sha256=&lt;hex&gt; y compáralo con X-Webhook-Signature en tiempo constante. Un reintento conserva los ID de evento y deliveryId, pero recibe una nueva marca de tiempo, cuerpo y firma.

Como política propia contra repeticiones, puedes rechazar una entrega correctamente firmada si su marca de tiempo difiere en más de 5 minutos del reloj de tu servidor.

Comportamiento de entrega y reintentos

  • Mejor esfuerzo con reintentos. Una respuesta 2xx completa una entrega. Cada intento vence tras 30 segundos. Los fallos pueden reintentarse desde los 5 segundos con espera exponencial limitada a 5 minutos, pero no existe una garantía durable de entrega al menos una vez.
  • Umbral de pausa. El endpoint se pausa tras 10 intentos fallidos consecutivos. No existe una acción para habilitarlo o actualizarlo: elimínalo, registra un sustituto con action=webhook.add y guarda el nuevo secreto mostrado.
  • El orden no está garantizado. Mantén manejadores idempotentes, procesa todos los eventos, deduplica una transición por id de evento o un lote reintentado por deliveryId y reconcilia el estado importante con action=status.