DOCUMENTACIÓN
Desarrolla con SMetaGateway.
Todo lo necesario para crear facturas USDT TRC20 desde tu servidor, enviar a los compradores al checkout y confirmar pagos con webhooks firmados.
Visión general
SMetaGateway es una capa de facturación sin custodia para USDT en TRON. Los comercios registran una dirección pública de cobro y los compradores pagan directamente a ella. La pasarela asigna a cada factura un importe exacto único, sigue su estado, registra los datos contables y notifica a tu servidor.
Todos los endpoints están bajo /api/v1 en el mismo origen que este sitio. Los importes son siempre cadenas decimales con hasta seis decimales, nunca números de coma flotante.
- Tu servidor → SMetaGateway1POST /api/v1/invoices con un Idempotency-Key
- SMetaGateway → Tu servidor2Factura con payable_amount y checkout_url
- Tu servidor → Comprador3Redirige al comprador a checkout_url
- Comprador → SMetaGateway4El comprador abre el checkout y escanea el código QR
- Comprador → Tu billetera TRON5El comprador envía el importe exacto de USDT a tu dirección
- SMetaGateway6La pasarela encuentra el importe exacto en la cadena y confirma la factura
- SMetaGateway → Tu servidor7Webhook firmado invoice.confirmed
- Tu servidor → SMetaGateway8GET /api/v1/invoices/{id} para verificar y luego completar el pedido
Ruta de datosRuta del dinero
Inicio rápido
1. Crea un espacio y añade una dirección de cobro de TRON. Copia su ID de billetera.
2. Abre Desarrolladores → Claves API y crea una clave con vencimiento. El secreto empieza por smg_ y solo se muestra una vez, así que guárdalo de forma segura.
3. Crea una factura desde tu servidor con la solicitud de abajo. Guarda el ID de la factura y el payable_amount exacto.
4. Redirige al comprador a checkout_url. Marca el pedido como pagado solo tras verificar el webhook invoice.confirmed y consultar la factura desde el servidor.
curl -X POST "https://smg.sabco24.com/api/v1/invoices" \
-H "Authorization: Bearer $SMETA_API_KEY" \
-H "Idempotency-Key: order-1001" \
-H "Content-Type: application/json" \
-d '{"merchant_order_id":"1001","amount":"49.95","wallet_id":"WALLET_ID","description":"Example order","expires_in_minutes":20}'Autenticación
Las integraciones de servidor se autentican con una clave API bearer: Authorization: Bearer smg_…. Las claves tienen los permisos invoices:read, invoices:write y ledger:read, y pueden vencer a los 30, 90 o 365 días. Una clave vencida devuelve 401 api_key_expired; rótala en el panel para obtener un nuevo secreto. Guarda las claves en tu servidor; nunca las incluyas en navegadores ni apps móviles.
El panel oficial usa una cookie de sesión HttpOnly. La gestión de cuenta, billeteras, claves API y webhooks requiere esa sesión de propietario y no puede hacerse con una clave API.
curl "https://smg.sabco24.com/api/v1/invoices/INVOICE_ID" \
-H "Authorization: Bearer $SMETA_API_KEY"Importes e identificación
Envía el precio base como cadena decimal, por ejemplo "49.95". La pasarela añade un ajuste de identificación positivo —de 0.000001 a 0.009999 USDT por debajo de 100 USDT, o de 0.000001 a 0.999999 USDT a partir de 100 USDT— y devuelve base_amount, adjustment y payable_amount por separado.
El total exacto se reserva 90 días para la misma red, token y dirección de cobro entre todos los comercios. Se prefieren totales no usados; un total reutilizado deja la factura en review en lugar de confirmarse automáticamente.
Reservado 90 días por red, token y dirección de recepción
{
"base_amount": "49.950000",
"adjustment": "0.003821",
"payable_amount": "49.953821"
}Facturas e idempotencia
POST /api/v1/invoices requiere la cabecera Idempotency-Key. Repetir la misma solicitud con la misma clave devuelve la factura original con idempotent_replay: true; reutilizar la clave con otros datos devuelve 409 idempotency_conflict.
Cada merchant_order_id admite una sola factura. Guarda el ID de factura y el payable_amount con tu pedido y compáralos cuando llegue un webhook.
POST /invoices + Idempotency-Key- Clave nueva201 — factura nueva creada
- Misma clave, mismo cuerpoFactura original, idempotent_replay: true
- Misma clave, cuerpo distinto409 idempotency_conflict
{
"invoice": {
"id": "6f1c…",
"merchant_order_id": "1001",
"base_amount": "49.950000",
"adjustment": "0.003821",
"payable_amount": "49.953821",
"status": "pending",
"mode": "live",
"checkout_url": "https://smg.sabco24.com/checkout/…",
"expires_at": "2026-10-21T12:20:00.000Z",
"reserved_until": "2027-01-19T12:00:00.000Z"
},
"idempotent_replay": false
}Checkout y estado de la factura
checkout_url es un enlace de capacidad: quien lo tenga puede ver los datos seguros para el pagador, así que trátalo como confidencial. El checkout muestra el nombre del comercio, el desglose, la dirección, el código QR y la caducidad, nunca tus metadatos ni IDs internos.
El estado es pending, confirmed, expired o review. El checkout caduca tras expires_in_minutes (20 por defecto, máximo 1440); la reserva del importe dura 90 días de forma independiente.
pending- Importe exacto recibido
confirmed - Se agotó el tiempo de pago
expired - Importe reutilizado o requiere revisión manual
review
Webhooks firmados
Registra un endpoint HTTPS público (puerto 443) en el panel. Su secreto de firma se muestra una vez. Eventos: invoice.created, invoice.confirmed, invoice.expired, invoice.review y webhook.test. Las entregas se reintentan hasta ocho veces y pueden reintentarse manualmente.
Cada solicitud incluye las cabeceras X-SMeta-Event-Id, X-SMeta-Timestamp y X-SMeta-Signature. Calcula HMAC-SHA256 sobre timestamp + "." + cuerpo sin procesar, compara en tiempo constante, rechaza marcas de tiempo de más de cinco minutos y después analiza el JSON. Procesa cada ID de evento una sola vez.
- 1Lee el cuerpo sin procesar y las cabeceras X-SMeta-*
- 2¿Marca de tiempo dentro de 5 minutos?Rechazar (4xx)
- 3HMAC-SHA256(timestamp + "." + body)
- 4Comparación en tiempo constante con X-SMeta-SignatureRechazar (4xx)
- 5¿ID de evento ya procesado?Responder 2xx y omitir
- 6Actualiza el pedido y responde 2xx
import { createHmac, timingSafeEqual } from 'node:crypto';
export function verify(rawBody: Buffer, headers: Record<string, string>, secret: string) {
const timestamp = headers['x-smeta-timestamp'];
const signature = headers['x-smeta-signature'] ?? '';
if (!/^\d+$/.test(timestamp) || Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return null;
const expected = 'sha256=' + createHmac('sha256', secret)
.update(timestamp + '.').update(rawBody).digest('hex');
const a = Buffer.from(expected), b = Buffer.from(signature);
if (a.length !== b.length || !timingSafeEqual(a, b)) return null;
const event = JSON.parse(rawBody.toString('utf8'));
return event.id === headers['x-smeta-event-id'] ? event : null;
}Errores y límites de uso
Los errores devuelven un JSON con error.code y error.message. Estados habituales: 400 validación, 401 autenticación, 403 permiso u origen, 404 no encontrado, 409 conflicto o revisión, 429 límite superado.
La creación de facturas está limitada a 120 solicitudes por minuto por comercio. Reintenta las respuestas 429 y 5xx con espera progresiva y la misma Idempotency-Key.
{
"error": {
"code": "idempotency_conflict",
"message": "This idempotency key was used with different invoice details."
},
"mode": "live"
}Integraciones
El panel incluye 32 recetas listas para copiar para Node.js, NestJS, PHP, Laravel, Python, Django, Go, Java, C#, Ruby, React, Next.js, Vue y plataformas de comercio como WooCommerce, Magento y Shopware. El plugin descargable de WooCommerce es una versión preliminar y aún no acepta claves API de producción.
Las recetas son ejemplos, no SDK publicados. Los ejemplos frontend llaman a tu propio backend, que guarda la clave API.
Confirmación de pagos
La pasarela lee la red principal de TRON mediante TronGrid en busca de transferencias USDT TRC20 confirmadas hacia cada dirección de cobro con una factura abierta, y verifica cada transferencia con un recibo solidificado exitoso. Una transferencia del payable_amount exacto entre la creación y el vencimiento de la factura la confirma, y el hash de la transacción se guarda como tx_hash.
Una transferencia que llega tras el vencimiento, coincide con un importe usado antes o corresponde a una factura ya en revisión cambia el estado a review y nunca se confirma automáticamente. La detección suele tardar unos minutos. La comisión cero y el diseño no custodio no establecen por sí solos una exención fiscal ni una autorización regulatoria.