Logo
Nuevos usuarios de RPC: 35% de descuento el primer mesVer oferta
OnFinality Learn
Integración y desarrollo12 min de lectura

Integración de pasarela de pago con criptomonedas: arquitectura, lógica de confirmación y conciliación

Guía técnica para integrar una pasarela de pago con criptomonedas: intenciones de pago, derivación de direcciones, política de confirmación, verificación de webhooks, conciliación y manejo de fallos.

TL;DR

Una pasarela de pago con criptomonedas es una capa de servicio que convierte una transferencia en cadena en un evento de pago reconocible para el comercio: crea una intención de pago, vigila la cadena para detectar el monto esperado en la dirección esperada, aplica una política de confirmación e informa la liquidación. Este artículo explica la arquitectura detrás de ese flujo y luego recorre un patrón de integración ejecutable con intenciones de pago, manejo idempotente de webhooks y un trabajo de conciliación. Separa el comportamiento documentado de la pasarela de las decisiones de confirmación y monitoreo que debes tomar y medir por tu cuenta. El objetivo es un flujo de pago correcto ante reintentos, reorganizaciones de cadena, pagos insuficientes y pagos tardíos, no solo uno que funcione en una demostración ideal.

Qué hace realmente una pasarela de pago cripto

Una pasarela de pago con criptomonedas se sitúa entre la billetera del cliente y tu sistema de pedidos. No mueve fondos a través de una red de tarjetas; observa el estado de la cadena de bloques y traduce una transferencia en un evento de pago sobre el que tu backend puede actuar. Las responsabilidades principales son consistentes entre proveedores: crear una intención de pago con un monto y destino fijos, monitorear la cadena relevante para detectar transferencias coincidentes, aplicar un umbral de confirmación y notificar al comercio mediante un webhook o una API de sondeo.

El punto arquitectónico importante es que la pasarela es un oráculo sobre el estado de la cadena, no un banco. Tu sistema de pedidos aún debe decidir qué cuenta como pagado, cómo manejar pagos insuficientes o en exceso, y cómo conciliar los registros de la pasarela con tu propio libro mayor. Trata el webhook de la pasarela como una afirmación que necesita verificación, no como una actualización autoritativa de saldo.

  • Intención de pago: monto, activo, dirección de destino, vencimiento y una referencia del comercio.
  • Detección: coincidencia de transacciones por dirección, activo, monto y ventana de tiempo.
  • Política de confirmación: cuántos bloques o qué regla de finalidad antes de marcar como pagado.
  • Liquidación: conversión a fiat o stablecoin, modelo de custodia y calendario de pagos.
  • Informes: IDs de transacción, comisiones y extractos exportables para conciliación.

Supuestos y requisitos previos

Esta guía asume que tienes un servicio backend que puede recibir webhooks HTTPS, una base de datos con restricciones únicas y una forma de ejecutar trabajos programados. Necesitas credenciales de API de la pasarela y, para configuraciones autoalojadas o no custodiales, acceso a un endpoint RPC confiable para las cadenas que aceptas. Si aún estás eligiendo un proveedor de endpoints, el Asistente RPC cubre recomendaciones concretas de proveedores y redes; este artículo se centra en la metodología de integración.

También debes conocer tu modelo de liquidación antes de escribir código. Las pasarelas custodiales liquidan a un saldo del comercio y pagan según un calendario; las pasarelas no custodiales envían fondos directamente a una billetera que tú controlas. El modelo de liquidación cambia tu fuente de verdad para la conciliación, así que decídelo temprano. Para obtener información sobre la infraestructura de nodos que respalda el monitoreo de cadenas, consulta la guía de alojamiento de nodos blockchain.

El ciclo de vida del pago como máquina de estados

Modela cada pago como una máquina de estados explícita en lugar de una bandera booleana paid. Un conjunto viable de estados es created, awaiting_payment, detected, confirmed, underpaid, overpaid, expired y refunded. Las transiciones deben ser impulsadas por eventos verificados y registradas con marcas de tiempo para que puedas auditarlas después.

Los valores de estado propios de la pasarela diferirán en nomenclatura, así que mapéalos a tus estados en el límite. Mantén el payload crudo de la pasarela junto a tu estado normalizado. Cuando aparezca una disputa o una discrepancia en la conciliación, el payload crudo es la evidencia que necesitarás.

const PAYMENT_STATES = [
  'created',
  'awaiting_payment',
  'detected',
  'confirmed',
  'underpaid',
  'overpaid',
  'expired',
  'refunded'
];

// Allowed transitions; reject anything not listed.
const TRANSITIONS = {
  created: ['awaiting_payment', 'expired'],
  awaiting_payment: ['detected', 'expired'],
  detected: ['confirmed', 'underpaid', 'overpaid', 'expired'],
  confirmed: ['refunded'],
  underpaid: ['refunded', 'confirmed'],
  overpaid: ['refunded'],
  expired: ['detected'],
  refunded: []
};

function canTransition(from, to) {
  return (TRANSITIONS[from] || []).includes(to);
}

Creación de una intención de pago con una llamada del lado del servidor

Crea intenciones de pago solo en tu servidor, nunca en código del lado del cliente, porque la solicitud lleva tu clave de API y el monto no debe ser controlado por el usuario. Envía una referencia de comercio única para que los reintentos sean idempotentes. El ejemplo siguiente utiliza nombres de campo de marcador de posición; adáptalos a la API documentada de tu pasarela.

Siempre persiste el ID de pago de la pasarela y la dirección de destino antes de devolver la respuesta de pago al cliente. Si tu proceso falla después de que la pasarela crea la intención pero antes de que la almacenes, tendrás un pago huérfano que es difícil de conciliar.

curl -X POST "$GATEWAY_API_URL/v1/payments" \
  -H "Authorization: Bearer $GATEWAY_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-1042-attempt-1" \
  -d '{
    "amount": "49.99",
    "currency": "USD",
    "asset": "USDC",
    "network": "ethereum",
    "merchant_reference": "order-1042",
    "callback_url": "https://shop.example.com/webhooks/crypto",
    "expires_in": 900
  }'

Política de confirmación: la decisión que debes medir

El umbral de confirmación es el parámetro más importante en una integración de pasarela cripto. Si es demasiado bajo, una reorganización o una transacción con reemplazo por comisión puede revertir un pago que ya cumpliste; si es demasiado alto, los clientes esperan innecesariamente. No hay un número universal, y cualquier cifra citada sin contexto debe tratarse como una hipótesis inicial, no como un hecho.

Define tu política por cadena y por valor del pedido. Los pedidos de alto valor pueden requerir más confirmaciones o una regla basada en finalidad; los bienes digitales de bajo valor pueden aceptar menos. Documenta la política y luego mídela con datos reales: registra la altura de bloque en la detección, la altura de bloque en la confirmación y cualquier evento de reorganización observado. La siguiente tabla es una plantilla para completar con tus propias mediciones, no un conjunto de valores recomendados.

  • Registra el tiempo desde la difusión hasta la primera detección para cada cadena.
  • Registra el tiempo desde la detección hasta tu umbral de confirmación.
  • Registra cualquier profundidad de reorganización observada y si afectó a un pago.
  • Rastrea la proporción de pagos que expiran antes de la detección.
  • Revisa la política trimestralmente con los datos observados de reorganización y latencia.

Verificación de webhooks antes de confiar en ellos

Los endpoints de webhook son públicos, por lo que cualquiera puede enviarles una solicitud POST. Verifica la firma usando el secreto compartido que proporciona tu pasarela, compara con una función de tiempo constante y rechaza marcas de tiempo obsoletas para limitar la repetición. Luego carga el pago por ID desde tu propia base de datos y confirma que el evento es una transición legal antes de aplicarlo.

Haz que el manejador sea idempotente: las pasarelas reintentan los webhooks y el mismo evento puede llegar varias veces. Una restricción única en el ID de evento de la pasarela es la defensa más simple.

import crypto from 'node:crypto';

function verifySignature(rawBody, signatureHeader, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(rawBody)
    .digest('hex');
  const a = Buffer.from(expected, 'utf8');
  const b = Buffer.from(signatureHeader || '', 'utf8');
  if (a.length !== b.length) return false;
  return crypto.timingSafeEqual(a, b);
}

// Express-style handler (raw body required for HMAC).
app.post('/webhooks/crypto', express.raw({ type: '*/*' }), async (req, res) => {
  const sig = req.get('X-Gateway-Signature');
  if (!verifySignature(req.body, sig, process.env.GATEWAY_WEBHOOK_SECRET)) {
    return res.status(401).send('bad signature');
  }
  const event = JSON.parse(req.body.toString('utf8'));
  await db.query(
    'INSERT INTO gateway_events (event_id, payload) VALUES ($1, $2) ON CONFLICT DO NOTHING',
    [event.id, event]
  );
  await applyPaymentEvent(event); // checks state machine + idempotency
  res.status(200).send('ok');
});

Monitoreo del estado de la cadena directamente con un endpoint RPC

Las pasarelas custodiales suelen encargarse del monitoreo de la cadena por ti, pero las configuraciones no custodiales y los trabajos de conciliación necesitan su propia vista de la cadena. Un monitor mínimo sondea el último bloque y escanea transferencias a tus direcciones. Usa un endpoint RPC dedicado en lugar de uno público para producción, porque los límites de velocidad y las alturas de cabeza inconsistentes causarán detecciones perdidas o duplicadas.

El siguiente script es un diagnóstico, no un indexador de producción: imprime la cabeza actual y una muestra de números de bloque recientes para que puedas confirmar que tu endpoint está avanzando y es consistente. Compara dos endpoints si sospechas de retraso. Para la selección de endpoints, consulta precios y planes de RPC y la guía de endpoints RPC multicadena.

import requests, time

RPC_URL = "RPC_URL"  # e.g. your provider's HTTPS endpoint

def rpc(method, params):
    r = requests.post(RPC_URL, json={
        "jsonrpc": "2.0", "id": 1, "method": method, "params": params
    }, timeout=10)
    r.raise_for_status()
    body = r.json()
    if "error" in body:
        raise RuntimeError(body["error"])
    return body["result"]

head = int(rpc("eth_blockNumber", []), 16)
print("head:", head)
for offset in range(5):
    block = rpc("eth_getBlockByNumber", [hex(head - offset), False])
    print(block["number"], block["hash"][:18], len(block["transactions"]), "txs")
    time.sleep(0.2)

Resultados de verificación esperados

Después de conectar el flujo, ejecuta un pago de prueba en una testnet o en el sandbox de la pasarela. Deberías observar: la intención creada con un ID estable, el webhook entregado y aceptado con una firma válida, el pago transitando por awaiting_payment a detected y luego a confirmed, y tu pedido marcado como cumplido exactamente una vez incluso cuando reproduces el webhook manualmente.

Para el diagnóstico RPC, la cabeza debe aumentar entre ejecuciones y los hashes de bloque deben ser estables para bloques con varias confirmaciones de profundidad. Si la cabeza se estanca o retrocede, tu endpoint no está saludable o estás llegando a un balanceador de carga con estado inconsistente. Registra estas observaciones en un runbook breve para que los ingenieros de guardia puedan repetirlas.

Solución de problemas comunes de integración

La mayoría de los incidentes en producción caen en unas pocas categorías: discrepancias de firma, cumplimiento duplicado, pagos perdidos y discrepancias de monto. Abórdalos en ese orden porque cada uno puede enmascarar al siguiente.

  • Discrepancia de firma: confirma que estás aplicando hash al cuerpo crudo, no al JSON analizado, y que el secreto coincide con el entorno.
  • Cumplimiento duplicado: verifica la restricción única en el ID de evento y que las transiciones de estado rechacen repeticiones.
  • Pago perdido: verifica que la dirección y el activo coincidan con la intención, y que tu monitor no esté retrasado respecto a la cabeza de la cadena.
  • Pago insuficiente: compara el monto recibido con el monto de la intención al tipo de cambio fijado en la creación; decide si aceptar, solicitar la diferencia o reembolsar.
  • Pago tardío después del vencimiento: mantén la intención abierta por un período de gracia y concilia manualmente en lugar de cumplir automáticamente.
  • El webhook nunca llega: sondea el estado del pago de la pasarela como respaldo y alerta cuando el sondeo y los webhooks no coincidan.

Conciliación y limitaciones

La conciliación es donde las pasarelas cripto difieren más de los procesadores de tarjetas. Crea un trabajo diario que extraiga la lista de transacciones de la pasarela para el período, la una con tus pedidos por referencia de comercio y marque cualquier pedido cuyo estado no coincida con la pasarela. Almacena las comisiones y tasas de conversión de la pasarela para que tu libro mayor coincida con la liquidación.

Sé honesto sobre las limitaciones. Los umbrales de confirmación reducen pero no eliminan el riesgo de reorganización. La volatilidad del tipo de cambio entre la creación de la intención y la liquidación puede crear pequeñas discrepancias. Las pasarelas custodiales introducen riesgo de contraparte, mientras que las no custodiales trasladan la gestión de claves y el monitoreo de la cadena a ti. Ninguna de estas es razón para evitar los pagos cripto, pero cada una necesita un responsable explícito y un respaldo documentado.

Próximos pasos para una integración lista para producción

Pasa de una demostración funcional a un sistema de producción agregando tres cosas: una política de confirmación por cadena respaldada por tus propias mediciones, un pipeline de webhooks idempotente con un respaldo de sondeo y un trabajo de conciliación que se ejecute según un calendario. Luego realiza pruebas de carga en el endpoint de webhook y simula reorganizaciones en un entorno de staging.

Si operas tu propia infraestructura de monitoreo o liquidación, revisa las opciones de nodos dedicados y las redes que admitimos para ajustar la capacidad del endpoint a tu volumen de pagos. Para la pregunta concreta de qué endpoint o proveedor usar para una cadena determinada, pregunta al Asistente RPC en lugar de adivinar a partir de una lista. Finalmente, documenta tu proceso de reembolsos y disputas antes del lanzamiento: es la parte que los clientes notan primero cuando algo sale mal.

Nunca te preocupes por la infraestructura nuevamente

OnFinality elimina la carga pesada de DevOps para que puedas construir de forma más inteligente y rápida.

Comenzar