SERO Pay
Suscripciones
Cobros mensuales en dólares, sin tarjeta, con permiso cada vez.
Archivo/Para quien vende/Pagar con SERO
SERO Pay, versión 1.0
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.
Demostración
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
9.50 USDT
32.00 USDT
7.00 USDT
1.25 USDT
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
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.
Carritos de hasta cien productos, con su detalle en la orden que aprueba el cliente.
Entrega el acceso en cuanto el pago queda confirmado en la red, sin revisar capturas de pantalla.
Un cobro por mes que el suscriptor aprueba desde su teléfono. Sin retiros automáticos.
Consultas, clases, encargos o donaciones: un monto único con su concepto.
Integración
¿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.
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".
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 },
];
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.
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
sero:pagado.SERO no recibe, no retiene y no puede revertir tu dinero. Llega directo a tu billetera.
No hay cuentas de comercio ni claves que proteger. Tu dirección es tu identidad para cobrar.
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
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
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.
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>
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
}
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
También en texto plano, pensado para leerlo de corrido o entregárselo a un asistente de programación.
<sero-pagar>| Atributo | Descripción |
|---|---|
direccion | Obligatorio. Tu dirección SERO (0x y 40 caracteres hexadecimales). Ahí llega el pago. |
negocio | Nombre visible en la ventana y en la notificación. Hasta 40 caracteres. |
monto, concepto | Cobro de un monto único, con una descripción opcional. |
productos | Carrito como JSON en el atributo o, mejor, como lista en la propiedad productos: { nombre, precio, cantidad, id }. |
orden | Tu 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. |
numero | Número visible, «Orden de compra N.º …». Por omisión, las cifras de orden. |
plan, plan-nombre, cliente, periodo | Convierten el botón en el de una suscripción mensual. periodo es «AAAA-MM»; por omisión, el mes en curso. |
etiqueta, tema, ancho | Texto del botón; tema="claro" para fondos oscuros; ancho="completo" para ocupar todo el ancho. |
demostracion | Simula todo el flujo sin red y sin cobrar. Para probar tu integración. |
| Evento | Cuándo y qué trae |
|---|---|
sero:pagado | El pago quedó verificado en la red. detail es el recibo: referencia, pagador, destino, monto, bloque, orden, numero, huella y, en suscripciones, suscripcion. |
sero:cobro-enviado | El cliente pidió el cobro a su billetera. detail: orden, destino. |
sero:cerrado | Se cerró la ventana sin pagar. Un cobro pendiente se cancela. |
sero:listo | En window, cuando SeroPay está disponible. |
SeroPay y de sero-pay.mjs| Función | Qué 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». |
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
Para implementar SERO Pay en otro lenguaje o auditar el archivo. Todo lo que sigue es público y verificable.
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.
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¹⁸.
Base: https://gate-latam.sero.foundation. JSON en ambas direcciones, CORS abierto, sin credenciales.
| Ruta | Cuerpo 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
SERO Pay
Cobros mensuales en dólares, sin tarjeta, con permiso cada vez.
SERO Pay
Un bloque de HTML personalizado y listo para cobrar.
SERO Pay
Cursos, ebooks y mentorías con entrega automática.
SERO Pay
La especificación byte a byte, con un ejemplo en Python.
SERO Pay
Por qué regalamos esto y de qué vive SERO.
Preguntas frecuentes
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.
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.
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.
Con USDT en BNB Smart Chain (BEP20), una moneda estable: 1 USDT equivale aproximadamente a 1 dólar estadounidense.
No. Solo tu dirección SERO. El servidor es opcional y recomendable para confirmar pagos de valor antes de entregar.
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.
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.
Si ya aprobó, el pago llega igual a tu billetera. Tu servidor lo encuentra con consultarPago y la misma referencia de orden.
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.
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.
Ostermann Laboratories, una empresa de ingeniería de software de Luxemburgo. Escríbenos a info@sero.foundation: te responde una persona.
9:41
Toca la notificación
VAS A PAGAR
USDT
No está en tus contactos
Revisa que sea quien te cobra
Teléfono del cliente, simulado