- Inicio
- 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.
https://omniwallet.ewin888.com/api/v1/https://omniwallet-dev.ewin888.com/api/v1/Guía rápida
- 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.
- 02
Crea un pago
Llama a
POST /v1/paymentcon el importe, la moneda del precio y la moneda de pago. En la respuesta,pay_addresses la dirección única de este pago ypay_amount, el importe que se debe pagar.POST /v1/paymentcurlcurl -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" } - 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/invoicepara crear una factura alojada y redirigir al cliente a lainvoice_urlde la respuesta.POST /v1/invoicecurlcurl -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" } - 04
Recibe las IPN
Cada vez que cambia el estado de un pago, enviamos una solicitud POST a tu URL de callback (
Verificar las IPNipn_callback_url). Verifica primero la firma y después actualiza el pedido segúnpayment_status. - 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_idy estado y, si es necesario, llama aGET /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
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);<?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);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{
"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.
| Estado | Significado |
|---|---|
waitingEsperando pago | Esperando el pago del cliente |
confirmingConfirmando | Transacción detectada; esperando las confirmaciones de bloque |
confirmedConfirmado | Confirmado y acreditado |
sendingLiquidando | En proceso de liquidación a tu billetera |
partially_paidPago parcial | Pago insuficiente; el cliente puede completarlo antes del vencimiento |
finishedCompletado | Pago completado |
failedFallido | Pago fallido; por ejemplo, por coincidir con una lista de sanciones |
refundedReembolsado | Reembolsado al pagador |
expiredExpirado | No se pagó a tiempo |
Migrar desde NOWPayments
La API es compatible, así que la mayor parte de tu código no necesita cambios.
- Cambia la URL baseSustituye
https://api.nowpayments.io/v1/por la URL de OmniWallet que aparece abajo. - Usa una clave de API de OmniWalletEl encabezado sigue siendo
x-api-key. - 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 compatibilidadx-nowpayments-sig. - Comprueba las monedas compatiblesLos códigos de moneda son los mismos (por ejemplo,
usdttrc20ousdcsol), pero solo puedes usar las monedas que admitimos. Consúltalas conGET /v1/merchant/coinso en la página de monedas compatibles. - 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.
- 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 enviarx-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
| Red | Red de prueba | Códigos de moneda disponibles |
|---|---|---|
| Ethereum | Ethereum Sepolia | eth usdc |
| BNB Smart Chain | BNB Smart Chain Testnet | bnbbsc usdtbsc |
| Polygon | Polygon Amoy | maticmainnet usdcmatic |
| Avalanche C-Chain | Avalanche Fuji | avax usdcavax |
| Arbitrum | Arbitrum Sepolia | etharb usdcarb |
| Base | Base Sepolia | ethbase usdcbase |
| Optimism | OP Sepolia | ethop usdcop |
| TRON | TRON Nile | trx usdttrc20 |
| Solana | Solana Devnet | sol usdcsol |
| Bitcoin | Bitcoin Testnet4 | btc |
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
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/jsonEmpieza 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.