Documentación / Integración

Facturas

Una factura corresponde a una compra: un precio en moneda fiduciaria o stablecoin, un plazo de validez y, una vez que el cliente elige, la moneda de pago y la dirección de depósito.

Creación

POST/v1/invoices

Cabeceras: Authorization (CP-HMAC), Idempotency-Key, Content-Type: application/json.

cuerpo de la solicitud
{
  "order_id": "ORDER-1001",
  "price_amount": "49.99",
  "price_currency": "USD",
  "allowed_assets": ["USDT-TRON", "USDC-BASE", "BTC"],
  "return_url": "https://shop.example/orders/ORDER-1001",
  "expires_in_seconds": 1800,
  "metadata": { "user_id": "42", "plan": "pro" }
}
CampoObligatorioReglas
order_idsí1–128 caracteres, único por comercio (si se repite: 409 duplicate_order)
price_amountsíCadena decimal > 0, con hasta 18 decimales
price_currencysíUSD, EUR, USDT o USDC
allowed_assetsnoHasta 30 ID de activos (GET /v1/assets). Si se deja vacío, todos los disponibles. La factura recibe la intersección con los disponibles; si queda vacía: 422 invalid_allowed_assets
return_urlnohttps://…: el botón «Volver a la tienda»
expires_in_secondsno300–86 400; por defecto, 1800 (30 minutos)
metadatanoHasta 20 claves [A-Za-z0-9_.-]{1,64} con valores de hasta 500 caracteres; se devuelven en la factura

Respuesta 201:

JSON
{
  "id": "inv_x7k2…",
  "order_id": "ORDER-1001",
  "status": "created",
  "price_amount": "49.99",
  "price_currency": "USD",
  "allowed_assets": ["USDT-TRON", "BTC"],
  "checkout_url": "https://pay.coinetic.money/pay/inv_x7k2…#t=…",
  "return_url": "https://shop.example/orders/ORDER-1001",
  "expires_at": "2026-10-12T15:30:00Z",
  "created_at": "2026-10-12T15:00:00Z",
  "quote": null,
  "paid_amount": "0", "outstanding_amount": "0", "overpaid_amount": "0",
  "refunded_amount": "0", "refundable_amount": "0",
  "payments": [],
  "metadata": { "user_id": "42", "plan": "pro" },
  "livemode": true
}
  • price_amount se devuelve en forma canónica, sin ceros finales: si envía "3.00", recibirá "3". Compare los importes como decimales, no como float ni byte a byte.
  • checkout_url contiene el token de la página de pago tras la #. No lo registre en logs ni lo publique.
  • livemode: false indica una factura del sandbox. Su tienda en producción debe rechazarlas.

Qué activos se incluyen en la factura

Un activo está disponible si está habilitado en Coinetic, usted tiene una billetera de cobro activa en esa red y no lo ha excluido en el panel («Configuración» → «Activos de pago»). Cada activo tiene un mínimo (min_amount en GET /v1/assets): si el importe de la factura en ese activo es inferior, el activo no se incluye. Ejemplo: una factura de 3 USD con BTC a 60 000 USD equivale a 5000 sat, frente a un mínimo de 10 000; esa factura solo ofrecerá stablecoins.

El campo selectable_assets recoge los activos de allowed_assets que pueden elegirse en este momento; la página de pago solo ofrece esos.

Idempotencia

  • Idempotency-Key: 8–128 caracteres ASCII imprimibles sin espacios; no puede empezar por d:. Lo más práctico es derivarlo del número de pedido: order-ORDER-1001.
  • Misma clave y mismo cuerpo: la misma respuesta (la misma factura).
  • Misma clave con otro cuerpo: 409 idempotency_conflict.
  • Si la primera solicitud aún se está procesando: 409 idempotency_in_progress; reintente al cabo de un segundo.
  • Los rechazos por reglas de negocio (por ejemplo, 422) también se memorizan.

Consulta

GET/v1/invoices/{id}

Cuando el cliente ha elegido la moneda, la factura incluye quote:

quote
{
  "asset_id": "USDT-TRON", "network": "tron", "token_contract": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
  "address": "TX…", "amount_due": "49990000", "decimals": 6, "display_amount": "49.99",
  "payment_uri": "tron:…", "rate": "1", "rate_valid_until": null,
  "network_warning": "Envíe solo USDT por la red TRON (TRC-20)…"
}

payments: los pagos, con tx_hash, amount (en unidades mínimas), confirmations, required_confirmations y state (mempool, included, confirmed, reorged, replaced, failed, dropped).

unmatched_payments: transferencias a la dirección de la factura que no se han acreditado, ya sea por otra red EVM (wrong_network) o con un token fuera de la lista blanca (token_not_whitelisted). No modifican el estado ni paid_amount.

Listado

GET/v1/invoices?status=paid&from=…&to=…&limit=50&cursor=…

Respuesta: { "items": [...], "next_cursor": "…" | null }, de la más reciente a la más antigua; limit entre 1 y 200.

Estados

EstadoSignificadoQué debe hacer la tienda
createdFactura creada, moneda sin elegiresperar
awaiting_paymentMoneda elegida, dirección asignadaesperar
detectedPago visible en la red (mempool)mostrar «pago detectado», no entregar
confirmingIncluido en un bloque, con menos confirmaciones de las necesariasmostrar el progreso, no entregar
paidPagada por completo y confirmadaentregar el pedido
overpaidSe pagó más de lo necesarioentregar el pedido; el excedente se reembolsa a petición
underpaidConfirmado menos de lo necesario (descontada la tolerancia)pedir al cliente que complete el pago en la misma dirección
expiredVenció el plazo sin pagoofrecer una factura nueva (ver más abajo)
late_paymentEl pago llegó fuera de plazola decisión es suya: entregar o reembolsar
manual_reviewPago en verificación AMLesperar la resolución; no entregar
refunded, cancelledCerradano entregar
Regla principalEntregue el pedido solo con paid u overpaid obtenidos de GET /v1/invoices/{id}.

Pago con stablecoin fuera de plazo

USDT o USDC en una factura en USD no conllevan riesgo cambiario, así que un pago fuera de plazo (hasta 30 días) se acredita automáticamente: una factura que ya recibió invoice.expired pasa a paid y se envía invoice.paid con data.late: true. Por eso, no cierre el pedido de forma definitiva al recibir invoice.expired. En los activos volátiles, ese pago genera late_payment.

Importes y tipo de cambio

  • El precio se fija en la moneda de la factura. Coinetic fija el importe en criptomoneda en el momento en que el cliente elige la moneda.
  • Stablecoin en su propia moneda (USDT para una factura en USD): 1:1, con el importe fijado hasta el final de la factura.
  • Activo volátil (BTC, ETH, etc.): mediana de los tipos de Kraken, Coinbase y Bitstamp, fijada durante 20 minutos.
  • amount_due va en unidades mínimas del activo (USDT en TRON tiene 6 decimales: "49990000" = 49.99). display_amount es lo mismo en notación habitual.
  • La tolerancia de pago insuficiente (por defecto, 0,5 %) cubre los redondeos de las billeteras.

Tipo de cambio de referencia: GET /v1/rates?base=BTC&quote=USD. No lo use para mostrar al cliente un importe «exacto» en criptomoneda: el único importe vinculante es el de la factura.