1. Inicio
  2. Desarrolladores
Desarrolladores

Integra pagos con criptomonedas en pocos minutos

Una API REST compatible con NOWPayments v1: mismas rutas, campos, valores de estado y códigos de moneda. Autentícate con x-api-key y recibe las actualizaciones de estado mediante IPN firmadas.

URL base de la APIhttps://omniwallet.ewin888.com/api/v1/
Entorno de pruebashttps://omniwallet-dev.ewin888.com/api/v1/

Guía rápida

  1. 01

    Obtén una clave de API

    Regístrate, inicia sesión en el panel y crea una clave en «Desarrolladores → Claves de API»; después, configura el secreto IPN en «IPN». Te recomendamos completar primero la integración en el entorno de pruebas.

  2. 02

    Crea un pago

    Llama a POST /v1/payment con el importe, la moneda del precio y la moneda de pago. En la respuesta, pay_address es la dirección única de este pago y pay_amount, el importe que se debe pagar.

    POST /v1/paymentcurl
    curl -X POST "https://omniwallet.ewin888.com/api/v1/payment" \
      -H "x-api-key: YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -H "Idempotency-Key: order-A-1024" \
      -d '{
        "price_amount": 120,
        "price_currency": "usd",
        "pay_currency": "usdttrc20",
        "order_id": "A-1024",
        "order_description": "Pro plan, 12 months",
        "ipn_callback_url": "https://example.com/ipn"
      }'
    RespuestaJSON
    {
      "payment_id": 355446374401130,
      "payment_status": "waiting",
      "pay_address": "TJ8nq3M5yVfQ9C2dWkPz7aH4sLrE6uXbGt",
      "price_amount": 120,
      "price_currency": "usd",
      "pay_amount": 120.02,
      "pay_currency": "usdttrc20",
      "order_id": "A-1024",
      "network": "TRC20",
      "expiration_estimate_date": "2026-10-02T09:15:00.000Z",
      "omni_payment_url": "https://omniwallet.ewin888.com/payment/4fKq9ZtR2mXcL8vBnW1pYs"
    }
  3. 03

    Guía a tu cliente para que pague

    Muestra la dirección y el importe (o un código QR) a tu cliente. También puedes usar POST /v1/invoice para crear una factura alojada y redirigir al cliente a la invoice_url de la respuesta.

    POST /v1/invoicecurl
    curl -X POST "https://omniwallet.ewin888.com/api/v1/invoice" \
      -H "x-api-key: YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "price_amount": 49.9,
        "price_currency": "usd",
        "order_id": "A-1025",
        "order_description": "Starter plan",
        "ipn_callback_url": "https://example.com/ipn",
        "success_url": "https://example.com/thanks",
        "cancel_url": "https://example.com/cart"
      }'
    RespuestaJSON
    {
      "id": "355447603200201",
      "order_id": "A-1025",
      "price_amount": "49.9",
      "price_currency": "usd",
      "pay_currency": null,
      "invoice_url": "https://omniwallet.ewin888.com/invoice/8hTz2QpLm4XwN7cVb1RkYe",
      "success_url": "https://example.com/thanks",
      "cancel_url": "https://example.com/cart",
      "created_at": "2026-10-01T09:20:00.000Z"
    }
  4. 04

    Recibe las IPN

    Cada vez que cambia el estado de un pago, enviamos una solicitud POST a tu URL de callback (ipn_callback_url). Verifica primero la firma y después actualiza el pedido según payment_status.

    Verificar las IPN
  5. 05

    Pasa a producción

    Cuando se apruebe la verificación de tu empresa, crea una nueva clave de API y un nuevo secreto IPN en el entorno de producción, y cambia la URL base por la de producción.

Verificar las firmas IPN

Calculamos un HMAC-SHA512 del JSON con las claves ordenadas alfabéticamente, usando tu secreto IPN, y lo enviamos como cadena hexadecimal en el encabezado x-omni-sig. El cuerpo de la solicitud que enviamos es exactamente ese JSON ordenado, así que puedes verificar directamente el cuerpo sin procesar que recibes.

  • Compara las firmas en tiempo constante
  • Las IPN pueden llegar duplicadas o desordenadas: elimina duplicados por payment_id y estado y, si es necesario, llama a GET /v1/payment/{id} para obtener el estado más reciente
  • Cualquier respuesta 2xx confirma la recepción; ante cualquier otra respuesta o si se agota el tiempo de espera, reintentamos automáticamente
ExpressNode.js
import crypto from 'node:crypto';
import express from 'express';

const app = express();
const IPN_SECRET = process.env.OMNI_IPN_SECRET;

// Keep the raw body: the signature covers the exact bytes we send.
app.post('/ipn', express.raw({ type: 'application/json' }), (req, res) => {
  const received = String(req.get('x-omni-sig') || '');
  const expected = crypto
    .createHmac('sha512', IPN_SECRET)
    .update(req.body)
    .digest('hex');

  const valid = received.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(received), Buffer.from(expected));
  if (!valid) return res.status(401).send('invalid signature');

  const payment = JSON.parse(req.body.toString('utf8'));
  // Idempotent update: the same status can be delivered more than once.
  // await orders.applyStatus(payment.order_id, payment.payment_status);
  res.sendStatus(200);
});

app.listen(3000);
PHPPHP
<?php
$secret   = getenv('OMNI_IPN_SECRET');
$raw      = file_get_contents('php://input');
$received = $_SERVER['HTTP_X_OMNI_SIG'] ?? '';

// The signature covers the exact bytes we send.
$expected = hash_hmac('sha512', $raw, $secret);
if (!hash_equals($expected, $received)) {
    http_response_code(401);
    exit('invalid signature');
}

$payment = json_decode($raw, true);
// Idempotent update: the same status can be delivered more than once.
// apply_status($payment['order_id'], $payment['payment_status']);
http_response_code(200);
FlaskPython
import hashlib
import hmac
import json
import os

from flask import Flask, abort, request

app = Flask(__name__)
IPN_SECRET = os.environ["OMNI_IPN_SECRET"].encode()

@app.post("/ipn")
def ipn():
    raw = request.get_data()  # the exact bytes we signed
    expected = hmac.new(IPN_SECRET, raw, hashlib.sha512).hexdigest()
    received = request.headers.get("x-omni-sig", "")
    if not hmac.compare_digest(expected, received):
        abort(401)

    payment = json.loads(raw)
    # Idempotent update: the same status can be delivered more than once.
    # apply_status(payment["order_id"], payment["payment_status"])
    return "", 200
Ejemplo de cuerpo de una IPNJSON
{
  "actually_paid": 120.02,
  "actually_paid_at_fiat": 120,
  "invoice_id": null,
  "order_description": "Pro plan, 12 months",
  "order_id": "A-1024",
  "outcome_amount": 119.42,
  "outcome_currency": "usdttrc20",
  "parent_payment_id": null,
  "pay_address": "TJ8nq3M5yVfQ9C2dWkPz7aH4sLrE6uXbGt",
  "pay_amount": 120.02,
  "pay_currency": "usdttrc20",
  "payment_id": 355446374401130,
  "payment_status": "finished",
  "price_amount": 120,
  "price_currency": "usd",
  "purchase_id": null,
  "updated_at": "2026-10-01T09:17:42.000Z"
}

Estados de pago

Los valores de estado son idénticos a los de NOWPayments.

EstadoSignificado
waiting
Esperando pago
Esperando el pago del cliente
confirming
Confirmando
Transacción detectada; esperando las confirmaciones de bloque
confirmed
Confirmado
Confirmado y acreditado
sending
Liquidando
En proceso de liquidación a tu billetera
partially_paid
Pago parcial
Pago insuficiente; el cliente puede completarlo antes del vencimiento
finished
Completado
Pago completado
failed
Fallido
Pago fallido; por ejemplo, por coincidir con una lista de sanciones
refunded
Reembolsado
Reembolsado al pagador
expired
Expirado
No se pagó a tiempo

Migrar desde NOWPayments

La API es compatible, así que la mayor parte de tu código no necesita cambios.

  1. Cambia la URL baseSustituye https://api.nowpayments.io/v1/ por la URL de OmniWallet que aparece abajo.
  2. Usa una clave de API de OmniWalletEl encabezado sigue siendo x-api-key.
  3. Actualiza la verificación de IPNUsa tu secreto IPN de OmniWallet y el encabezado x-omni-sig. Si prefieres no modificar en absoluto tu código actual, activa en el panel el encabezado de compatibilidad x-nowpayments-sig.
  4. Comprueba las monedas compatiblesLos códigos de moneda son los mismos (por ejemplo, usdttrc20 o usdcsol), pero solo puedes usar las monedas que admitimos. Consúltalas con GET /v1/merchant/coins o en la página de monedas compatibles.
  5. Revisa la configuración de retirosLos retiros siguen usando un JWT válido durante 5 minutos, que se obtiene con POST /v1/auth. Además, las claves de API con permisos de retiro necesitan una lista blanca de IP, y las direcciones de destino deben estar previamente en la lista blanca.
URL base de la APIdiff
- https://api.nowpayments.io/v1/
+ https://omniwallet.ewin888.com/api/v1/

Lo que no cambia

  • Rutas y métodos HTTP
  • Nombres de los campos de solicitud y respuesta
  • Valores de estado de pagos y retiros
  • Códigos de moneda
  • Algoritmo de firma de IPN

Diferencias que debes tener en cuenta

  • El encabezado de firma de las IPN es x-omni-sig (opcionalmente, también se puede enviar x-nowpayments-sig)
  • Los campos propios de OmniWallet empiezan por omni_
  • No se admiten retiros en moneda fiduciaria (respuesta HTTP 501)
  • Las liquidaciones siempre se envían a la billetera vinculada en el panel
  • El entorno de pruebas usa redes de prueba reales

Entorno de pruebas (sandbox)

El entorno de pruebas es un despliegue independiente conectado a la red de prueba de cada blockchain, con una API idéntica a la de producción.

  • Las cuentas, las claves de API y los datos están separados de producción, así que debes registrarte por separado; la verificación de empresa se aprueba automáticamente
  • Paga con las monedas de prueba de cada red de prueba; las transacciones se pueden consultar en su explorador de bloques
  • Las monedas de prueba no tienen valor real: no envíes activos de la red principal a direcciones del entorno de pruebas
RedRed de pruebaCódigos de moneda disponibles
EthereumEthereum Sepoliaeth usdc
BNB Smart ChainBNB Smart Chain Testnetbnbbsc usdtbsc
PolygonPolygon Amoymaticmainnet usdcmatic
Avalanche C-ChainAvalanche Fujiavax usdcavax
ArbitrumArbitrum Sepoliaetharb usdcarb
BaseBase Sepoliaethbase usdcbase
OptimismOP Sepoliaethop usdcop
TRONTRON Niletrx usdttrc20
SolanaSolana Devnetsol usdcsol
BitcoinBitcoin Testnet4btc

Idempotencia y reintentos

Todas las solicitudes POST que crean recursos admiten el encabezado Idempotency-Key. Si se agota el tiempo de espera de la red, reenvía la solicitud con la misma clave: no se creará ningún pago ni retiro duplicado.

  • Misma clave y mismo contenido: se devuelve el resultado de la primera solicitud
  • Misma clave y contenido distinto: respuesta 422 IDEMPOTENCY_KEY_REUSED
  • La primera solicitud aún se está procesando: respuesta 409 IDEMPOTENCY_IN_FLIGHT; vuelve a intentarlo en unos instantes
HTTPHTTP
POST /api/v1/payout HTTP/1.1
Host: omniwallet.ewin888.com
x-api-key: YOUR_API_KEY
Authorization: Bearer YOUR_JWT
Idempotency-Key: 6c0a8e6e-3f5b-4f7a-9a52-1f0c2d9b7e41
Content-Type: application/json

Empieza a aceptar pagos con criptomonedas

Regístrate gratis, completa la integración en el entorno de pruebas y pasa a producción cuando se apruebe la verificación de tu empresa.