Archivo/Para quien vende/Pagar con SERO

SERO Pay, versión 1.0

Pagar con SERO, en cualquier web.

Un archivo abierto y gratuito convierte tu carrito en una orden SERO. Tu cliente la recibe en su teléfono como una notificación, la revisa y la aprueba; el dinero llega completo a tu billetera y tu página se entera sola.

Para el comercio
Recibe el monto completo. Sin cuentas, sin claves, sin contratos.
Para el cliente
Paga desde SERO, con la orden a la vista y su propia confirmación.
Para quien lo integra
Un script, un botón y un evento. Sin dependencias ni servidor obligatorio.

Demostración

Una tienda ficticia, el flujo real.

Arma un pedido y paga con SERO. Nada se cobra: la ventana es la misma que verá tu cliente y el teléfono simulado muestra lo que ocurre del otro lado.

Tostadores del Ávila

Café de especialidad, tostado cada semana.

Tienda de ejemplo

  • Café de altura, 250 gTueste medio, notas de cacao.

    9.50 USDT

    1
  • Café de altura, 1 kgPara la casa o la oficina.

    32.00 USDT

    0
  • Taza esmaltadaBlanca, con borde negro.

    7.00 USDT

    1
  • Filtros de papel, 100 unidadesPara método V60.

    1.25 USDT

    0

Total16.50 USDT

Tienda ficticia. Ningún pago es real.

Club del Café

Una bolsa de 250 g cada mes. 12 USDT al mes, sin permanencia.

Para quién es

Cualquier negocio que venda en una página web.

Si puedes agregar un fragmento de HTML a tu página, puedes aceptar pagos en USDT. El dinero llega completo a tu billetera SERO y tu cliente paga desde la suya, estén donde estén.

Tiendas en línea

Carritos de hasta cien productos, con su detalle en la orden que aprueba el cliente.

Cursos y contenido digital

Entrega el acceso en cuanto el pago queda confirmado en la red, sin revisar capturas de pantalla.

Membresías y suscripciones

Un cobro por mes que el suscriptor aprueba desde su teléfono. Sin retiros automáticos.

Servicios y reservas

Consultas, clases, encargos o donaciones: un monto único con su concepto.

Integración

Tres pasos y estás cobrando.

¿No programas? Copia nuestro mensaje en Gemini, ChatGPT, Claude o un asistente abierto y revisa su trabajo con cinco comprobaciones: SERO Pay desde cero, con un asistente de IA.

  1. Carga el archivo

    Una sola línea en el <head>. El canal v1 recibe correcciones sin cambios que rompan tu integración.

    <script src="https://web.sero.foundation/sdk/v1/sero-pay.js" defer></script>

    ¿Prefieres fijar la versión exacta con integridad verificada? Usa /sdk/1.0.2/sero-pay.js con integrity="sha384-BpDWHZ0QbMF/EsVMLMLcTZZG48sTJUppTz5t5jLZoDgK1W5BKFtxxKEofoqKSrcg" y crossorigin="anonymous".

  2. Coloca el botón

    El componente <sero-pagar> dibuja el botón oficial y abre la ventana de pago. Para un monto único basta con monto; para un carrito, pasa los productos.

    <sero-pagar
      negocio="Tostadores del Ávila"
      direccion="0xTU_DIRECCION_SERO"
      monto="16.50"
      orden="A-1043">
    </sero-pagar>
    // Un carrito: la propiedad productos acepta la lista completa.
    document.querySelector("sero-pagar").productos = [
      { nombre: "Café de altura, 250 g", precio: "9.50", cantidad: 1 },
      { nombre: "Taza esmaltada", precio: "7.00", cantidad: 1 },
    ];
  3. Entrega cuando llegue el pago

    Cuando el pago queda confirmado en la red, el botón emite sero:pagado con el recibo ya verificado.

    document.addEventListener("sero:pagado", (evento) => {
      const recibo = evento.detail;
      // recibo.referencia  número de referencia de la transacción (0x…)
      // recibo.pagador     billetera que pagó
      // recibo.monto       "16.50"
      // recibo.orden       "A-1043"
      fetch("/api/pedidos/A-1043/pagado", { method: "POST", body: JSON.stringify(recibo) });
    });

    Si vendes algo de valor, confirma también en tu servidor antes de entregar. Lo que ocurre en el navegador lo controla quien lo usa; lo que está en la red, no. Verificar en tu servidor.

Sin botón, desde tu propio código

Si ya tienes tu botón o tu flujo de compra, abre la ventana con una llamada. La promesa se resuelve con el recibo o con null si el cliente la cierra sin pagar.

const recibo = await SeroPay.pagar({
  negocio: "Tostadores del Ávila",
  direccion: "0xTU_DIRECCION_SERO",
  orden: "A-1043",
  productos: carrito.map((p) => ({ nombre: p.nombre, precio: p.precio, cantidad: p.cantidad })),
});
if (recibo) confirmarPedido(recibo);

Cómo funciona

El dinero va de billetera a billetera. Nadie en medio.

  1. La orden. El archivo arma en el navegador una orden SERO idéntica a las que crea la app: productos, total y tu dirección. De ella sale una huella única de 24 bytes.
  2. El cobro. Tu cliente elige cómo recibirla: con una notificación en su teléfono, que insiste hasta que la atienda, o con un QR que puede escanear ahora o guardar y escanear después desde su galería.
  3. La aprobación. SERO le muestra la orden completa, a quién le paga y cuánto. Él la confirma en su teléfono con su rostro o su huella. Nada se mueve sin esa confirmación.
  4. El pago. El contrato público de SERO transfiere los USDT de su billetera a la tuya y deja la huella de la orden grabada en la red.
  5. La confirmación. Tu página pregunta por esa huella y comprueba el pago directamente en nodos públicos de BNB Smart Chain: destino, monto exacto y orden. Solo entonces emite sero:pagado.

Sin custodia

SERO no recibe, no retiene y no puede revertir tu dinero. Llega directo a tu billetera.

Sin registro

No hay cuentas de comercio ni claves que proteger. Tu dirección es tu identidad para cobrar.

Sin sorpresas

Recibes el monto completo. La comisión de la red la paga quien envía y la ve antes de confirmar.

Verificar en tu servidor

La última palabra la tiene la red.

El módulo sero-pay.mjs contiene el mismo núcleo sin interfaz. Funciona en Node 18 o superior, Deno, Bun y Cloudflare Workers. Descárgalo y guárdalo junto a tu código: sero-pay.mjs.

import { crearOrden, consultarPago } from "./sero-pay.mjs";

// La misma referencia y los mismos datos producen la misma orden que vio el cliente.
const orden = crearOrden({
  direccion: "0xTU_DIRECCION_SERO",
  orden: "A-1043",
  productos: pedido.productos,
});

const recibo = await consultarPago(orden, { bloques: 900 });
if (recibo) {
  // Pago confirmado en la red: destino, monto exacto y orden coinciden.
  await marcarPagado(pedido.id, recibo.referencia);
}

consultarPago pregunta por la huella y lee el recibo de la transacción en nodos públicos. Con bloques busca además en los bloques recientes, por si el aviso del teléfono del cliente no llegó. Para confirmar un número de referencia que ya tienes, usa verificarReferencia(orden, referencia).

¿Otro lenguaje? La especificación del protocolo describe cada byte: con ella se implementa en PHP, Python, Go o lo que uses.

Suscripciones

Mes a mes, con permiso cada vez.

Una suscripción SERO es una orden por periodo. Cada mes tu servidor envía el cobro y el suscriptor lo aprueba desde su teléfono. Nadie retira dinero sin su confirmación, y dejar de pagar es tan simple como rechazar el cobro.

  1. El alta: el primer pago

    El botón con plan y cliente cobra el mes en curso. El recibo trae la billetera que pagó: guárdala con el suscriptor.

    <sero-pagar
      negocio="Tostadores del Ávila"
      direccion="0xTU_DIRECCION_SERO"
      plan="club-cafe"
      plan-nombre="Club del Café"
      monto="12.00"
      cliente="cliente-881">
    </sero-pagar>
  2. Cada mes: el cobro desde tu servidor

    Una tarea programada recorre a tus suscriptores. La orden de un periodo es siempre la misma, así que repetir la tarea nunca cobra dos veces.

    import { ordenDeSuscripcion, consultarPago, enviarCobro, periodoActual } from "./sero-pay.mjs";
    
    const periodo = periodoActual(); // "2026-10"
    for (const s of suscriptores) {
      const orden = ordenDeSuscripcion({
        negocio: "Tostadores del Ávila",
        direccion: "0xTU_DIRECCION_SERO",
        plan: { id: "club-cafe", nombre: "Club del Café", precio: "12.00" },
        cliente: s.id,
        periodo,
      });
      if (await consultarPago(orden)) continue;        // ya pagó este mes
      const envio = await enviarCobro(orden, s.billetera);
      if (!envio.ok) avisarPorCorreo(s, envio.mensaje); // por ejemplo, sin notificaciones activas
    }
  3. Y si no lo aprueba

    El cobro insiste cuatro veces en diez minutos y vence a los treinta. Puedes volver a enviarlo más tarde o mandarle el QR por correo con qrSvg(await enlaceCorto(orden)). Si el suscriptor rechaza y bloquea, tus cobros dejan de llegarle: esa es su forma de darse de baja.

Referencia

Todo lo que expone el archivo.

También en texto plano, pensado para leerlo de corrido o entregárselo a un asistente de programación.

Atributos de <sero-pagar>

AtributoDescripción
direccionObligatorio. Tu dirección SERO (0x y 40 caracteres hexadecimales). Ahí llega el pago.
negocioNombre visible en la ventana y en la notificación. Hasta 40 caracteres.
monto, conceptoCobro de un monto único, con una descripción opcional.
productosCarrito como JSON en el atributo o, mejor, como lista en la propiedad productos: { nombre, precio, cantidad, id }.
ordenTu referencia única de la venta (hasta 80 caracteres). La misma referencia con los mismos datos produce la misma orden: un reintento nunca cobra dos veces.
numeroNúmero visible, «Orden de compra N.º …». Por omisión, las cifras de orden.
plan, plan-nombre, cliente, periodoConvierten el botón en el de una suscripción mensual. periodo es «AAAA-MM»; por omisión, el mes en curso.
etiqueta, tema, anchoTexto del botón; tema="claro" para fondos oscuros; ancho="completo" para ocupar todo el ancho.
demostracionSimula todo el flujo sin red y sin cobrar. Para probar tu integración.

Eventos

EventoCuándo y qué trae
sero:pagadoEl pago quedó verificado en la red. detail es el recibo: referencia, pagador, destino, monto, bloque, orden, numero, huella y, en suscripciones, suscripcion.
sero:cobro-enviadoEl cliente pidió el cobro a su billetera. detail: orden, destino.
sero:cerradoSe cerró la ventana sin pagar. Un cobro pendiente se cancela.
sero:listoEn window, cuando SeroPay está disponible.

Funciones de SeroPay y de sero-pay.mjs

FunciónQué hace
pagar(opciones)Solo navegador. Abre la ventana de pago. Resuelve con el recibo o null. Acepta alPagar y alCerrar.
suscribir(opciones)Solo navegador. Ventana de pago del periodo de una suscripción.
crearOrden(opciones)Devuelve la orden: token, huella, total, productos y demás. Lanza ErrorSero con codigo si algo no es válido.
ordenDeSuscripcion(opciones)La orden de un periodo: { direccion, negocio, plan: { id, nombre, precio }, cliente, periodo }. Determinista.
enviarCobro(orden, billetera)Envía la notificación insistente. Resuelve { ok: true, id } o { ok: false, codigo, mensaje }.
estadoDelCobro(id), cancelarCobro(id)activo, pagado, cancelado, rechazado o vencido; y su cancelación.
consultarPago(orden, { bloques })Recibo verificado en la red, o null.
esperarPago(orden, { intervalo, senal })Espera el pago consultando cada intervalo milisegundos; se detiene con un AbortSignal.
verificarReferencia(orden, referencia)Confirma que una transacción concreta paga exactamente esa orden.
enlaceCorto(orden), enlaceLargo(orden)Enlace de la orden para el QR, un correo o un mensaje.
qrSvg(texto), qrMatriz(texto, nivel)Código QR como SVG o como matriz de módulos.
periodoActual(), periodoLegible(periodo)«2026-10» y «octubre de 2026».

Límites

  • Total mínimo de una orden: 1.00 USDT. Montos con hasta dos decimales.
  • Hasta 100 líneas por orden; nombres de hasta 40 caracteres.
  • Una misma billetera recibe como máximo 6 cobros por hora. No hay límite por comercio.
  • Un cobro insiste al enviarse y a los minutos 1, 3 y 10, y vence a los 30 minutos.
  • La billetera del cliente necesita las notificaciones activas para recibir cobros; sin ellas, paga escaneando el QR.

Política de seguridad de contenido

Si tu web define una CSP, agrega estos orígenes:

script-src https://web.sero.foundation;
connect-src https://gate-latam.sero.foundation https://bsc-rpc.publicnode.com https://bsc-dataseed.bnbchain.org https://bsc-dataseed1.binance.org https://1rpc.io;

La ventana usa Shadow DOM y hojas de estilo construidas: los estilos de tu web no la alteran y no requiere 'unsafe-inline'.

Especificación del protocolo

Cada byte, por escrito.

Para implementar SERO Pay en otro lenguaje o auditar el archivo. Todo lo que sigue es público y verificable.

1. La orden

JSON con estos campos, en este orden exacto, codificado en UTF-8 y luego en base64url sin relleno:

{"v":1,"id":"A-1043","number":1043,"status":"enProceso","total":"16.50","currency":"USDT",
 "merchantAddress":"0x…(minúsculas)","products":[{"id":"p1","name":"Café de altura, 250 g",
 "price":"9.50","quantity":1,"subtotal":"9.50"}]}

Montos como texto con dos decimales. total es la suma exacta de los subtotal. Luego:

canonico = "SERO-ORDER-V1." + base64url(json)
suma      = primeros 10 caracteres hexadecimales, en mayúsculas, de keccak256(canonico)
token     = canonico + "." + suma
huella    = primeros 48 caracteres hexadecimales de keccak256("SERO-ORDEN-HUELLA-V1|" + token)

keccak256 es el de Ethereum, no SHA3-256.

2. El pago en la red

La app de quien paga usa como clientTxId la huella seguida de 8 bytes al azar. El contrato SERO 0xc872fcbc4Df48187454798Ebc94176A258832F4D en BNB Smart Chain (cadena 56) emite:

PaymentExecuted(bytes32 indexed clientTxId, address indexed user, address indexed recipient,
                uint256 amount, uint256 fee, uint256 nonce, address relayer, address treasury)
topic0 = 0x101bbd0b71609893cf7095fdbebe9b6e9e097866134ccb8d28e9ce3d309b14e4

Un pago corresponde a una orden cuando la transacción tiene estado 0x1, el log viene de ese contrato y ese topic0, los bytes 1 a 24 de topic1 son la huella, topic3 es tu dirección y amount (primeros 32 bytes de data) es exactamente total × 10¹⁸.

3. La pasarela

Base: https://gate-latam.sero.foundation. JSON en ambas direcciones, CORS abierto, sin credenciales.

RutaCuerpo y respuesta
POST /api/orders{ order: token } → { id, url }. Enlace corto /o/{id} que abre la orden en SERO. Vive 30 días.
POST /api/pagos/estado{ huellas: [hasta 40] } → { ok, pagos: { huella: [{ tx, pagador, destino, monto, bloque }] } }. monto en unidades mínimas.
POST /api/cobros{ token, huella, destino, negocio } → { ok, id }. Errores: propia, bloqueado, pagada, demasiados_cobros, sin_notificaciones.
POST /api/cobros/estado{ id } → { ok, estado }.
POST /api/cobros/cancelar{ id } → { ok }.

La pasarela solo guarda lo que la cadena ya muestra en público y, mientras dura un cobro, a qué billetera se envió. Nunca decide si un pago es válido: esa comprobación se hace siempre contra la red.

Más sobre SERO Pay

Guías para cada tipo de negocio.

SERO Pay

Suscripciones

Cobros mensuales en dólares, sin tarjeta, con permiso cada vez.

SERO Pay

WordPress

Un bloque de HTML personalizado y listo para cobrar.

SERO Pay

El protocolo

La especificación byte a byte, con un ejemplo en Python.

SERO Pay

Por qué MIT

Por qué regalamos esto y de qué vive SERO.

Preguntas frecuentes

Antes de integrarlo.

¿Cómo acepto pagos en USDT en mi tienda en línea?

Agrega el archivo sero-pay.js y el botón <sero-pagar> con tu dirección SERO y el monto o los productos. Tu cliente paga desde SERO, con una notificación en su teléfono o escaneando un QR, y tu página recibe el evento sero:pagado con el pago ya verificado en la red.

¿Cuánto cuesta?

Nada. El archivo es gratuito y de licencia MIT, y el comercio recibe el monto completo. La comisión de la red la paga quien envía: 0,15 USDT en pagos menores a 10 USDT, 0,25 USDT entre 10 y 50, y 0,5 % por encima de 50.

¿SERO Pay es una pasarela de pagos?

No en el sentido tradicional: es software. SERO Pay no recibe, no retiene ni procesa dinero. El pago va directo de la billetera del cliente a la tuya a través de un contrato público en BNB Smart Chain; por eso no hay registro de comercios ni comisión para quien cobra.

¿En qué red y con qué moneda funciona?

Con USDT en BNB Smart Chain (BEP20), una moneda estable: 1 USDT equivale aproximadamente a 1 dólar estadounidense.

¿Necesito una cuenta, una clave o un servidor?

No. Solo tu dirección SERO. El servidor es opcional y recomendable para confirmar pagos de valor antes de entregar.

¿Funciona en WordPress y en otras plataformas?

En cualquier página donde puedas agregar HTML y JavaScript: sitios propios, WordPress con un bloque de HTML personalizado o páginas de aterrizaje. Si tu plataforma no permite scripts, tu servidor puede crear la orden con sero-pay.mjs y enviar al cliente el enlace o el QR.

¿Puedo cobrar suscripciones mensuales?

Sí. Cada mes tu servidor envía el cobro de ese periodo y el suscriptor lo aprueba desde su teléfono. Nadie retira dinero sin su confirmación, y repetir el cobro de un mismo mes nunca cobra dos veces.

¿Qué pasa si el cliente cierra la ventana a mitad del pago?

Si ya aprobó, el pago llega igual a tu billetera. Tu servidor lo encuentra con consultarPago y la misma referencia de orden.

¿Funciona en iPhone?

Sí. La notificación abre SERO instalado en la pantalla de inicio, con la orden lista para aprobar. El QR también puede guardarse y escanearse después desde una foto de la galería.

¿Cómo devuelvo un pago?

Enviando el monto desde tu SERO a la billetera que pagó, que viene en el recibo. Los pagos en la red no se revierten solos.

¿Quién está detrás?

Ostermann Laboratories, una empresa de ingeniería de software de Luxemburgo. Escríbenos a info@sero.foundation: te responde una persona.