Docs
Host-to-host (H2H): muestra el pago cripto en tu propia interfaz
Muestra un pago de CryptoLike en tu pantalla: dirección, monto exacto, red, QR y plazo de la factura, elección de moneda por API y pedido confirmado por webhook.
Host-to-host (H2H) significa que tu servidor crea el pago con la API de CryptoLike y tu propia interfaz lo muestra: el pagador nunca abre una página de CryptoLike. Cada respuesta con la factura (invoice) trae lo que necesita la pantalla — la dirección, el monto exacto, la red, los datos del QR y el plazo de pago — y un webhook firmado le avisa a tu servidor cuando el pago está confirmado. Aquí verás cuándo elegir H2H, cómo es el flujo, qué debe mostrar la pantalla y qué hacer cuando el pagador envía de menos, de más o tarde.
Cuándo elegir H2H, la página de pago o el widget
Las tres opciones muestran la misma factura, con los mismos estados y webhooks; cambia quién dibuja la pantalla de pago.
| Opción | Quién dibuja la pantalla | Elígela cuando | Qué construyes |
|---|---|---|---|
| Página de pago | CryptoLike, en checkout_url |
Quieres el camino más corto: una redirección y un webhook | Una redirección desde tu backend |
| Widget de pago | CryptoLike, en un marco dentro de tu página | El cliente debe quedarse en tu flujo de compra, y la página de CryptoLike puede aparecer dentro | Tu origen en la lista permitida, un script y una regla de CSP |
| H2H | Tú | Una app para celular, un quiosco, un bot de mensajería o un flujo de compra que debe verse por completo como tu producto | La pantalla de pago con cada elemento de la lista de abajo |
La página de pago y el widget ya muestran la advertencia de red, el plazo, el estado en vivo y los textos para un pago insuficiente o vencido en inglés, ruso y español. Con H2H todo eso queda a tu cargo, así que empieza por la página de pago o el widget, salvo que tu interfaz tenga que ser del todo tuya. El widget se describe en la guía del widget de pago.
Cómo es el flujo
- Tu servidor crea la factura —
POST /v1/invoices, firmada con tu clave API y con el encabezadoIdempotency-Key. Envíacoin_idpara fijar la moneda ahora; omítelo para que el pagador la elija en tu interfaz. - Si la factura no tiene moneda, el pagador la elige. Tu servidor lee
GET /v1/invoices/{id}/coin-options, tu interfaz muestra las monedas y tu servidor fija la elección conPOST /v1/invoices/{id}/coin. - Tu interfaz muestra el pago a partir de la respuesta con la factura: red, dirección,
payer_amount, QR, cuenta regresiva hastattl_expires_aty estado. - Tu servidor sigue el estado con los webhooks
invoice.*y, para el contador de confirmaciones, conGET /v1/invoices/{id}, no más de una vez cada pocos segundos. Tu página le pregunta a tu servidor, nunca a la API de CryptoLike. - Tu servidor confirma el pedido solo con un webhook
invoice.paidverificado; después tu interfaz muestra la confirmación.
El secreto de la API se queda en tu servidor. El navegador o la app reciben solo lo que tu servidor decide mostrar y nunca firman solicitudes. La firma se explica en autenticación.
Crea la factura
La solicitud de abajo fija la moneda desde el inicio (USDT en TRON). Sin coin_id, la respuesta trae los campos de la moneda, address y el bloque de pago en null hasta la elección.
POST /v1/invoices HTTP/1.1
Host: api.cryptolike.net
Content-Type: application/json
Idempotency-Key: order-10042
X-API-Key: <key_id>
X-Timestamp: <unix seconds>
X-Signature: <HMAC-SHA256 of the request>
{"amount": "49.90", "currency": "USD", "coin_id": "6f1c2a3e-8d4b-4c5a-9e7f-0a1b2c3d4e5f", "order_id": "10042", "description": "Order #10042 — annual plan", "ttl_seconds": 1800, "fee_paid_by": "merchant"}La respuesta es la factura (valores de ejemplo de la referencia de la API):
{
"id": "4e2bc88c-cb79-4afc-b864-c1ba8e9d50c9",
"status": "new",
"currency": "USD",
"amount": "49.90",
"coin_id": "6f1c2a3e-8d4b-4c5a-9e7f-0a1b2c3d4e5f",
"ticker": "USDT",
"network": "tron",
"address": "TXYZopYRdj2D9XRtbG411XZZ3kM5VW9t7g",
"amount_crypto": "49.90",
"payer_amount": "49.90",
"paid_amount": "0",
"remaining_amount": "49.90",
"overpaid_amount": "0",
"amount_fiat": "49.90",
"fiat_currency": "USD",
"rate_locked": "1.0004",
"rate_locked_at": "2026-09-16T12:00:00Z",
"late_payment": false,
"fee_paid_by": "merchant",
"order_id": "10042",
"description": "Order #10042 — annual plan",
"return_url": null,
"webhook_url": null,
"metadata": null,
"allowed_coin_ids": null,
"checkout_url": "https://cryptolike.net/pay/4e2bc88c-cb79-4afc-b864-c1ba8e9d50c9",
"ttl_expires_at": "2026-09-16T12:30:00Z",
"expired_at": null,
"created_at": "2026-09-16T12:00:00Z",
"updated_at": "2026-09-16T12:00:00Z",
"payment_uri": "tron:TXYZopYRdj2D9XRtbG411XZZ3kM5VW9t7g?amount=49.9&token=TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
"qr_payload": "TXYZopYRdj2D9XRtbG411XZZ3kM5VW9t7g",
"confirmations": null,
"required_confirmations": 20
}Los campos que usa tu pantalla:
payer_amountyticker— exactamente lo que el pagador debe enviar. Confee_paid_by: payerla comisión de la plataforma ya está incluida, así quepayer_amountes mayor queamount_crypto; muestrapayer_amount, nuncaamountniamount_crypto. Las comisiones están en la página de precios.network—btc,ltc,ethotron. Un mismo ticker puede estar en dos redes (USDT en TRON y en Ethereum), y la red decide a dónde envía el pagador.address— la dirección de depósito de esta factura.payment_uri— un enlace que abre la billetera con la dirección y el monto que falta pagar: BIP-21 en Bitcoin y Litecoin, EIP-681 en Ethereum y un enlacetron:en TRON.qr_payload— lo que va en el código QR: solo la dirección en todas las redes, sin el monto. Muchos pagadores envían desde un exchange, y el formulario de retiro de un exchange acepta solo una dirección. Si quieres un «QR con monto» para billeteras, ofrécelo como interruptor en Bitcoin y Litecoin y codifica ahípayment_uri.ttl_expires_at— el plazo de pago. Lo definettl_seconds, de 60 segundos a 30 días; sin él se aplica la configuración de tu cuenta (30 minutos por defecto). Para un precio en USD u otra moneda fiat, el tipo de cambio derate_lockedqueda fijo hasta ese momento.confirmationsyrequired_confirmations— el contador de confirmaciones;confirmationsesnullmientras no llega nada.
Guarda cada monto como la cadena que devuelve la API: no lo redondees ni lo conviertas a un número de punto flotante.
Deja que el pagador elija la moneda en tu interfaz
Para una factura creada sin coin_id, la lista de monedas y la elección pasan por dos llamadas: la misma lista y la misma operación que en la página de pago.
GET /v1/invoices/4e2bc88c-cb79-4afc-b864-c1ba8e9d50c9/coin-options{
"coin_options": [
{ "coin_id": "6f1c2a3e-8d4b-4c5a-9e7f-0a1b2c3d4e5f", "ticker": "USDT", "name": "Tether USD", "network": "tron", "network_name": "TRON",
"decimals": 6, "confirmations": 20, "estimated_amount": "49.90", "rate_as_of": "2026-09-16T12:00:03Z",
"estimate_reason": null, "estimate_message": null },
{ "coin_id": "a01d6e2b-3c4f-4a5b-8c7d-9e0f1a2b3c4d", "ticker": "BTC", "name": "Bitcoin", "network": "btc", "network_name": "Bitcoin",
"decimals": 8, "confirmations": 2, "estimated_amount": null, "rate_as_of": null,
"estimate_reason": "rate_stale",
"estimate_message": { "key": "checkout.estimate.rate_stale", "default": "The exchange rate is updating. Choose this currency to see the exact amount." } }
]
}- Muestra
network_namejunto a cada ticker yestimated_amountcon el signo≈: es una estimación. Cuando esnull, muestra en su lugar el texto deestimate_message; la moneda se puede elegir igual. - La lista incluye solo las monedas que ofreces para facturas y que corresponden a la moneda de la factura, reducidas a
allowed_coin_idscuando la factura los tiene; las monedas en mantenimiento quedan fuera. - Si la moneda ya está elegida, la llamada responde
409condetails.coin_id, y la factura ya tiene la dirección.
Fija la elección desde tu servidor, con un Idempotency-Key:
POST /v1/invoices/4e2bc88c-cb79-4afc-b864-c1ba8e9d50c9/coin HTTP/1.1
Content-Type: application/json
Idempotency-Key: order-10042-coin
{"coin_id": "6f1c2a3e-8d4b-4c5a-9e7f-0a1b2c3d4e5f"}La respuesta es la factura con address, payer_amount, payment_uri, qr_payload y ttl_expires_at, con la misma forma que arriba. La elección vuelve a calcular el monto y fija el tipo de cambio, así que muestra el payer_amount de esta respuesta y no la estimación. Rechazos: 400 con details.field: coin_id para una moneda fuera de las opciones; 409 cuando ya hay una moneda elegida (aunque sea la misma) o la factura ya no está en new; 503 cuando el tipo de cambio o una dirección nueva no están disponibles en ese momento: espera unos segundos y envía la misma solicitud. Una repetición con el mismo Idempotency-Key devuelve la primera respuesta. La moneda se elige una sola vez; si el pagador también tiene abierta la página de pago, esta cambia al pago de inmediato.
Qué debe mostrar tu pantalla de pago
Estos elementos están en la página de pago de CryptoLike; tu pantalla necesita cada uno.
| Elemento | Campo | Por qué |
|---|---|---|
| La red con su nombre y, para un token, el estándar (TRON, TRC20) | network, ticker |
El mismo ticker y el mismo formato de dirección existen en varias redes |
| Advertencia de red equivocada junto a la dirección | ticker, network |
«Envía a esta dirección solo USDT en la red TRON. Los fondos enviados por otra red no se pueden recuperar.» |
| La dirección, con botón para copiar | address |
El pagador la pega en su billetera; los fondos enviados a una dirección mal escrita no se pueden recuperar |
| El monto exacto, con botón para copiar | payer_amount, ticker |
Una transferencia menor al monto se vuelve un pago insuficiente |
| El código QR, con el monto escrito al lado | qr_payload |
El QR lleva solo la dirección en todas las redes |
| Un enlace «Abrir en la billetera» | payment_uri |
Un toque en un teléfono que tiene billetera instalada |
| El tiempo restante | ttl_expires_at |
Después la factura vence, y una transferencia posterior es un pago tardío |
| El estado, con las confirmaciones mientras espera | status, confirmations, required_confirmations |
«Pago detectado, 3 de 20 confirmaciones» le indica al pagador que no envíe dos veces |
| La pantalla de resultado | status, paid_amount, remaining_amount |
Pagado, pago insuficiente con el monto restante, vencido o cancelado, cada uno con el siguiente paso |
Lleva la cuenta regresiva con el reloj de tu servidor, no con el del dispositivo del pagador. Cuando llegue a cero, oculta la dirección y el QR y ofrece crear un pago nuevo. Los estados son new, pending, paid, underpaid, expired y cancelled; el artículo sobre confirmaciones explica por qué una transferencia espera antes de contar.
Pago insuficiente, pago excedente y pago tardío
- Pago insuficiente. Una transferencia confirmada menor a
payer_amountpasa la factura aunderpaidy envíainvoice.underpaid; una diferencia dentro de la tolerancia de pago insuficiente de tu cuenta igual cuenta comopaid. La factura sigue abierta para completar el pago en la misma dirección hastattl_expires_at: muestraremaining_amounty elpayment_uriactualizado, que ahora pide el resto. Después del plazo el pago insuficiente es definitivo; pídele al pagador que te contacte. Más en pago insuficiente. - Pago excedente. El estado es
paidconoverpaid_amountmayor que cero; lo traeinvoice.paid, que vuelve a llegar cuando otra transferencia lo aumenta. Todo el monto se acredita a tu saldo; arregla la diferencia con el cliente. - Pago tardío. Una transferencia confirmada después de que la factura se cerró (
expired,cancelledo ununderpaiddefinitivo) igual se acredita a tu saldo: la factura recibelate_payment: true, te llegainvoice.late_paymenty el estado no cambia. Pasa también cuando una transferencia ya se detectó pero aún no se confirmó al vencer el plazo: la factura vence y la transferencia llega como pago tardío. Decide si entregas el pedido o devuelves el dinero. Más en pago vencido. - Reverso. Si una reorganización de la red elimina una transferencia confirmada, recibes
invoice.revertedcon los montos recalculados. Detén la entrega hasta que llegue un nuevoinvoice.paid.
Confirma el pedido solo con el webhook
Entrega un pedido cuando tu servidor recibe invoice.paid con una firma de webhook válida, no cuando el pagador presiona «Ya pagué» ni por un estado que vio tu página. La entrega es al menos una vez: guarda event_id, responde 2xx en menos de 10 segundos y omite las repeticiones. Los webhooks son los mismos para H2H, la página de pago y el widget, y no traen payment_uri, qr_payload ni el contador de confirmaciones; cuando los necesites, lee GET /v1/invoices/{id}. Los tipos de evento, los reintentos y un vector de prueba están en la referencia de webhooks.
Antes del lanzamiento, haz en una red de prueba un pago por cada caso: pagado, pago insuficiente y luego completado, vencido y una transferencia tardía. Cómo conseguir una clave de prueba y monedas de prueba: pagos cripto de prueba.
Preguntas frecuentes
¿Necesito el widget para H2H?
No. Con H2H tu interfaz dibuja la pantalla con los campos de la factura, y en el navegador del pagador no se carga nada de CryptoLike. El widget es la otra opción: la página de pago de CryptoLike dentro de un marco en tu flujo de compra.
¿Puedo enviar igual al pagador a la página de pago?
Sí. Cada factura tiene checkout_url, y la página de pago muestra la misma factura. Una moneda elegida por API cambia de inmediato una página abierta al pago, así que puedes ofrecer la página como alternativa, por ejemplo a un pagador que tiene la billetera en otro dispositivo.
¿H2H cambia los webhooks?
No. Los eventos, la firma y los reintentos son los mismos que con la página de pago. El bloque de pago de la factura — payment_uri, qr_payload, confirmations y required_confirmations — no viene en el cuerpo del webhook; lee la factura con GET /v1/invoices/{id}.
¿Qué monto envía el pagador cuando él paga la comisión?
payer_amount. Con fee_paid_by: payer ya incluye la comisión de la plataforma, y amount_crypto es lo que recibes tú. Muestra payer_amount y guárdalo como la cadena que devuelve la API.