RugWard Pay
Referencia de la API REST
Todos los endpoints de comerciante de RugWard Pay con ejemplos de solicitud y respuesta, autenticación con clave de API, errores, límites y código en curl, Node.js, Python y PHP.
En esta página
Conceptos básicos#
| URL base | https://rugward.com |
| Formato | JSON de entrada y de salida. Envía Content-Type: application/json con cada cuerpo (si no, 415). Los cuerpos están limitados a unos pocos KB. |
| Autenticación | una clave de API en Authorization: Bearer rwp_… o x-api-key: rwp_… |
| Importes | USD como cadena con hasta 2 decimales ("25", "25.50"); los importes en moneda son cadenas decimales |
| Tiempos | milisegundos Unix (createdAt, expiresAt, paidAt) |
| Errores | {"error": "human readable message"}, a veces con "retry": true |
Solo de servidor a servidor. Guarda la clave de API en tu servidor. Los navegadores no pueden llamar a la API de comerciante con una clave (no se permiten solicitudes de origen cruzado), y una clave dentro de una página web sería pública.
Claves de API#
Crea claves en el panel, en API keys (requiere iniciar sesión). Una clave tiene el formato rwp_ seguido de 40 letras y dígitos y se muestra una sola vez: cópiala de inmediato al almacén de secretos de tu servidor. RugWard solo guarda un hash SHA-256, así que una clave perdida no puede volver a mostrarse: crea una nueva y revoca la antigua. Hasta 10 claves por comerciante; el panel muestra el prefijo de cada clave y cuándo se usó por última vez.

Qué puede y qué no puede hacer una clave:
| Una clave puede | Una clave no puede |
|---|---|
| crear, listar, leer y cancelar facturas | cambiar la configuración ni las direcciones de cobro |
| crear, listar y desactivar enlaces de pago | crear, listar ni revocar claves de API |
| cambiar ni leer el webhook o su secreto | |
| crear facturas de prueba |
Así, una clave filtrada no puede desviar tu dinero: las direcciones de cobro solo se pueden cambiar iniciando sesión con tu billetera.
Endpoints#
| Método y ruta | Autenticación | Propósito |
|---|---|---|
POST /api/pay/merchant/invoices | clave o sesión | Crear una factura |
GET /api/pay/merchant/invoices | clave o sesión | Listar facturas, las más recientes primero, 50 por página |
GET /api/pay/merchant/invoices/:id | clave o sesión | Leer una factura con cotizaciones y pagos (también vuelve a comprobar la cadena) |
POST /api/pay/merchant/invoices/:id/cancel | clave o sesión | Cancelar una factura abierta sin pagos |
GET /api/pay/merchant/links | clave o sesión | Listar enlaces de pago |
POST /api/pay/merchant/links | clave o sesión | Crear un enlace de pago, o desactivarlo |
GET /api/pay/proof/:id | pública | Prueba de pago (solo facturas paid u overpaid) |
La configuración, las claves de API, el webhook y los pagos sin coincidencia se gestionan en el panel (solo con sesión de billetera).
Crear una factura#
POST /api/pay/merchant/invoices
| Campo | Tipo | Obligatorio | Reglas |
|---|---|---|---|
amountUsd | cadena o número | sí | de 1 a 50000, máx. 2 decimales |
orderId | cadena | no | 1–64 caracteres: letras, dígitos, . _ - : # / |
description | cadena | no | máx. 200 caracteres, se muestra al comprador |
redirectUrl | cadena | no | URL https:// (máx. 500 caracteres), se muestra tras el pago |
expiresMin | entero | no | de 15 a 10080 (7 días); por defecto 60 |
curl -X POST https://rugward.com/api/pay/merchant/invoices \
-H "Authorization: Bearer $RUGWARD_PAY_KEY" \
-H "Content-Type: application/json" \
-d '{
"amountUsd": "25.00",
"orderId": "1234",
"description": "1 x T-shirt, size M",
"redirectUrl": "https://shop.example/thanks?order=1234",
"expiresMin": 60
}'{
"id": "Zx3kQ8pL2mN7vR1tY5wB9c",
"url": "https://rugward.com/pay/i/Zx3kQ8pL2mN7vR1tY5wB9c",
"status": "open",
"expiresAt": 1793326882069,
"assets": ["BTC", "ETH-8453", "USDC-8453", "USDT-56", "SOL", "USDC-SOL"]
}Envía al comprador a url. assets lista los ids de activo entre los que puede elegir el comprador (tus monedas activadas que tienen dirección de cobro).
La misma solicitud en otros lenguajes:
// Never put the API key in a browser page: call RugWard Pay from your server.
const res = await fetch("https://rugward.com/api/pay/merchant/invoices", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.RUGWARD_PAY_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ amountUsd: "25.00", orderId: "1234", expiresMin: 60 }),
});
const body = await res.json();
if (!res.ok) throw new Error(body.error);
// Save body.id with your order, then send the buyer to body.url
console.log(body.id, body.url);import os, requests
r = requests.post(
"https://rugward.com/api/pay/merchant/invoices",
headers={"Authorization": f"Bearer {os.environ['RUGWARD_PAY_KEY']}"},
json={"amountUsd": "25.00", "orderId": "1234", "expiresMin": 60},
timeout=15,
)
data = r.json()
if r.status_code != 201:
raise RuntimeError(data.get("error"))
print(data["id"], data["url"]) # store the id, redirect the buyer to the url<?php
$ch = curl_init("https://rugward.com/api/pay/merchant/invoices");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv("RUGWARD_PAY_KEY"),
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => json_encode(["amountUsd" => "25.00", "orderId" => "1234", "expiresMin" => 60]),
]);
$data = json_decode(curl_exec($ch), true);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($code !== 201) { throw new Exception($data["error"] ?? "RugWard Pay error"); }
header("Location: " . $data["url"]); // send the buyer to the hosted checkoutLeer una factura#
GET /api/pay/merchant/invoices/:id. Leer una factura también comprueba las blockchains en busca de pagos nuevos, así que esta es la llamada adecuada para confirmar un pago antes de enviar el pedido (junto con los webhooks).
curl https://rugward.com/api/pay/merchant/invoices/Zx3kQ8pL2mN7vR1tY5wB9c \
-H "Authorization: Bearer $RUGWARD_PAY_KEY"{
"invoice": {
"id": "Zx3kQ8pL2mN7vR1tY5wB9c",
"status": "paid",
"amountUsd": "25.00",
"orderId": "1234",
"description": "1 x T-shirt, size M",
"redirectUrl": "https://shop.example/thanks?order=1234",
"createdAt": 1793323282069,
"expiresAt": 1793326882069,
"paidAt": 1793324100512,
"assets": ["BTC", "ETH-8453", "USDC-8453", "USDT-56", "SOL", "USDC-SOL"],
"test": false,
"quotes": [
{
"id": 4711,
"asset": "USDC-8453",
"amount": "25.000629",
"rateUsd": "1",
"address": "0xYourMerchantAddress…",
"expiresAt": 1793325082069
}
],
"payments": [
{
"txid": "0x…",
"asset": "USDC-8453",
"amount": "24.875626",
"confirmations": 30,
"required": 30,
"confirmed": true,
"seenAt": 1793324012000,
"explorer": "https://basescan.org/tx/0x…"
}
]
}
}quotes: una entrada por cada moneda que eligió el comprador (importe, tipo de cambio, dirección de cobro, vencimiento del bloqueo del tipo de cambio).payments: cada transacción vista para esta factura, conconfirmations, el númerorequiredyconfirmed.- En pagos con splitter en Base,
amountes lo que te llegó (99,5%).
Listar facturas#
GET /api/pay/merchant/invoices?before=<createdAt>: 50 por página, las más recientes primero. Para obtener la página siguiente, pasa el createdAt de la última factura que recibiste.
curl "https://rugward.com/api/pay/merchant/invoices" \
-H "Authorization: Bearer $RUGWARD_PAY_KEY"
# next page: pass the createdAt of the last invoice you received
curl "https://rugward.com/api/pay/merchant/invoices?before=1793323282069" \
-H "Authorization: Bearer $RUGWARD_PAY_KEY"{
"invoices": [
{
"id": "Zx3kQ8pL2mN7vR1tY5wB9c",
"status": "open",
"amountUsd": "25.00",
"orderId": "1234",
"description": "1 x T-shirt, size M",
"createdAt": 1793323282069,
"expiresAt": 1793326882069,
"paidAt": null
}
]
}Cancelar una factura#
POST /api/pay/merchant/invoices/:id/cancel (sin cuerpo). Solo funciona mientras la factura está open y no se ha visto ningún pago; si no, 409.
curl -X POST https://rugward.com/api/pay/merchant/invoices/Zx3kQ8pL2mN7vR1tY5wB9c/cancel \
-H "Authorization: Bearer $RUGWARD_PAY_KEY"
# 200 {"ok":true}
# 409 {"error":"Only your open invoices without payments can be canceled."}Enlaces de pago#
POST /api/pay/merchant/links con {amountUsd, description?, redirectUrl?} crea un enlace reutilizable; {"deactivate": "<link id>"} lo desactiva. GET lista hasta 100 enlaces con uses, active y createdAt. Primero deben aceptarse los términos para comerciantes. Consulta Enlaces de pago.
curl -X POST https://rugward.com/api/pay/merchant/links \
-H "Authorization: Bearer $RUGWARD_PAY_KEY" \
-H "Content-Type: application/json" \
-d '{"amountUsd": "15", "description": "Monthly membership", "redirectUrl": "https://shop.example/welcome"}'
# 201 {"id":"k33JZ0ij5F2yLDprwrQgjN","url":"https://rugward.com/pay/l/k33JZ0ij5F2yLDprwrQgjN"}
# list your links
curl https://rugward.com/api/pay/merchant/links -H "Authorization: Bearer $RUGWARD_PAY_KEY"
# turn one off
curl -X POST https://rugward.com/api/pay/merchant/links \
-H "Authorization: Bearer $RUGWARD_PAY_KEY" -H "Content-Type: application/json" \
-d '{"deactivate": "k33JZ0ij5F2yLDprwrQgjN"}'Errores#
{ "error": "Amount in USD, e.g. 25 or 25.50." }
// some temporary errors also carry "retry": true| HTTP | Significado | Qué hacer |
|---|---|---|
| 400 | entrada no válida (el mensaje indica qué campo) | corrige la solicitud |
| 401 | clave de API ausente o no válida | revisa la clave; puede haber sido revocada |
| 403 | solicitud entre sitios rechazada, términos de comerciante no aceptados, cuenta suspendida o acción no permitida con claves | lee el mensaje |
| 404 | no encontrado o no es tuyo | revisa el id |
| 409 | conflicto (por ejemplo, cancelar una factura pagada, o ya hay 100 enlaces activos) | lee el mensaje |
| 415 | el cuerpo no es JSON | envía Content-Type: application/json |
| 429 | límite de frecuencia, o 500 facturas en la última hora | espera y reintenta con espera progresiva |
| 451 | no disponible en tu región | — |
503 con "retry": true | una blockchain o fuente de precios no está disponible temporalmente | reintenta tras unos segundos |
Límites#
- Frecuencia de solicitudes: unas 20 solicitudes por minuto por dirección IP entre todos los endpoints
/api/pay/*, más un tope de 30 por minuto por grupo de endpoints. Usa webhooks en lugar de sondeos; si sondeas, una vez por minuto por factura abierta es más que suficiente. - Facturas: 500 por comerciante por hora.
- Enlaces de pago: 100 activos por comerciante; cada enlace crea como máximo 100 facturas por hora.
Lista de comprobación de integración#
- Crea la factura desde tu servidor cuando el cliente finalice la compra; guarda el
idcon tu pedido. - Redirige al cliente a
url. - Con
invoice.paidoinvoice.overpaid(webhook), verifica la firma, luego vuelve a leer la factura conGET /api/pay/merchant/invoices/:idy compruebastatusyamountUsdantes de enviar el pedido. - Gestiona
underpaid,lateyexpired(ver Estados). - Haz que tu manejador sea idempotente: el mismo evento puede llegar más de una vez.
Última actualización: 30 de octubre de 2026