Documentación
Con la API de VecchioPay cada venta recibe su propio CVU. Tu cliente transfiere, nosotros detectamos el depósito y te avisamos por webhook. Integrarlo lleva una tarde.
Inicio rápido
- Creá tu cuenta: arrancás en modo prueba, sin esperar ninguna aprobación.
- En el panel, Desarrolladores → creá una API key
sk_test_…y un endpoint de webhook. - Creá un pago y mandá a tu cliente al
checkout_url. - Cuando llegue
payment.paida tu webhook, marcá el pedido como pagado. - Probalo todo con el Simulador del panel. Cuando se apruebe tu alta, cambiá a una clave
sk_live_….
curl -X POST https://api.tudominio.com/v1/payments \
-H "Authorization: Bearer sk_test_..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: orden-1234" \
-d '{
"amount": 15999.90,
"external_id": "orden-1234",
"title": "Pedido #1234",
"expires_in": "1h",
"success_url": "https://mitienda.com/gracias",
"cancel_url": "https://mitienda.com/carrito"
}'{
"id": "pay_k3j9x0aa71m2...",
"object": "payment",
"livemode": false,
"status": "NOT_PAID",
"amount": 15999.9,
"amount_paid": 0,
"currency": "ARS",
"external_id": "orden-1234",
"cvu": "0000017012345678901234",
"alias": "vecchio.k3j9x0aa",
"checkout_url": "https://tudominio.com/pagar/pay_k3j9x0aa71m2...",
"expires_at": "2026-10-04T15:30:00.000Z",
"deposits": [],
"refunds": []
}Autenticación y modos
Mandá tu API key en cada request: Authorization: Bearer sk_test_…. Las claves se crean en el panel y se muestran una sola vez.
sk_test_…→ modo prueba: todo simulado, ideal para desarrollar. En el checkout aparece un botón para simular la transferencia.sk_live_…→ modo real: CVUs reales y plata real. Requiere el alta aprobada.
Cada objeto trae livemode para que sepas de qué modo vino. Los webhooks de cada modo se firman con un secreto distinto.
Pagos y checkout
Un pago es un cobro con su propio CVU y alias. Estados: NOT_PAID → PARTIAL (pagaron menos) → PAID; o EXPIRED / CANCELED.
expires_in: de30ma30d(por defecto24h). Al vencer, el CVU deja de recibir.metadata: hasta 50 pares clave/valor (strings) que te devolvemos en cada webhook.webhook_url: además de tus endpoints, mandamos los eventos de ese pago a esa URL.- Si te transfieren de más, el pago queda
PAIDconamount_paidmayor: podés devolver la diferencia.
Endpoints: POST /v1/payments, GET /v1/payments, GET /v1/payments/:id, POST /v1/payments/:id/cancel, POST /v1/payments/:id/refunds, GET /v1/payments/:id/refunds.
# Devolver todo el depósito (o parte, con "amount")
curl -X POST https://api.tudominio.com/v1/payments/pay_.../refunds \
-H "Authorization: Bearer sk_live_..." -H "Content-Type: application/json" \
-d '{ "amount": 5000 }'Webhooks
Configurá tus endpoints en el panel o por API (/v1/webhook_endpoints). Cada notificación es un POST JSON:
{
"id": "6ac1...",
"evento": "payment.paid",
"modo": "live",
"livemode": true,
"creado": "2026-10-03T22:10:41.120Z",
"data": { "id": "pay_...", "object": "payment", "status": "PAID", ... }
}| payment.paid | El pago se completó (lo que entró ≥ el monto). |
| payment.partially_paid | Entró una transferencia por menos del total. |
| payment.expired | Venció sin completarse; el CVU deja de recibir. |
| payment.canceled | Lo cancelaste antes de que entrara plata. |
| payment.refunded | Devolviste (total o parcialmente) una transferencia. |
| customer.deposit_received | Un cliente transfirió a su CVU fijo. |
| customer.created / customer.updated | Alta, cambios, baja o reactivación de un cliente. |
| deposit.received | Entró una transferencia a tu CVU principal. |
| withdrawal.created / withdrawal.confirmed | Retiros a tu cuenta bancaria. |
| account.approved | Se aprobó el alta de tu cuenta. |
Verificá la firma de cada webhook con el secreto de tu modo (panel → Desarrolladores):
import crypto from 'node:crypto';
// headers: x-webhook-timestamp, x-webhook-signature ("v1=<hex>")
// rawBody: el body EXACTO que llegó, sin re-serializar
export function verificar(headers, rawBody, secreto) {
const ts = headers['x-webhook-timestamp'];
const firma = headers['x-webhook-signature'] ?? '';
if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false; // reenvíos viejos
const esperada = 'v1=' + crypto.createHmac('sha256', secreto)
.update(`${ts}.${rawBody}`).digest('hex');
return firma.length === esperada.length &&
crypto.timingSafeEqual(Buffer.from(firma), Buffer.from(esperada));
}$ts = $_SERVER['HTTP_X_WEBHOOK_TIMESTAMP'] ?? '';
$firma = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';
$body = file_get_contents('php://input');
$esperada = 'v1=' . hash_hmac('sha256', $ts . '.' . $body, $secreto);
$valida = abs(time() - (int) $ts) < 300 && hash_equals($esperada, $firma);Respondé 2xx en menos de 10 segundos. Si no, reintentamos a 1 min, 5 min, 30 min, 2 h, 6 h y 12 h. Un mismo evento puede llegar más de una vez: usá el id para no procesarlo dos veces.
Clientes con CVU fijo
Para clientes que te pagan seguido (cuotas, alquileres, abonos, mayoristas) creá un cliente: recibe un CVU propio y fijo. Todo lo que transfiera queda asociado a él, sin crear cobros, y te llega customer.deposit_received.
curl -X POST https://api.tudominio.com/v1/customers \
-H "Authorization: Bearer sk_live_..." -H "Content-Type: application/json" \
-d '{ "name": "Juan Pérez", "tax_id": "20123456789", "external_id": "cli-42" }'Con PATCH /v1/customers/:id cambiás el alias o das de baja el CVU ("active": false); la baja es reversible y el número no cambia.
Idempotencia
Mandá Idempotency-Key en los POST. Si reintentás con la misma clave (por un timeout, por ejemplo) te devolvemos la misma respuesta y no se crea un segundo pago. La clave vale 24 h; usarla con otro body devuelve 422. Las respuestas repetidas traen el header idempotent-replayed: true.
Errores y límites
Los errores responden { "statusCode": 422, "error": "INSUFFICIENT_FUNDS", "message": "No tenés saldo suficiente…" }.
400datos inválidos ·401API key inválida ·403sin permiso o cuenta suspendida ·404no existe409conflicto (ej.external_idrepetido, cuenta sin activar) ·422la operación no se pudo hacer (ej. saldo insuficiente)429superaste el límite de requests por minuto: esperá y reintentá ·502problema con el procesador
WooCommerce
Instalá el plugin, pegá tu API key y listo: al pagar, el cliente va al checkout de VecchioPay y el pedido se marca como pagado solo cuando llega la transferencia. El plugin registra su propio webhook, soporta devoluciones desde el pedido y el checkout por bloques.
- Subí el
.zipen Plugins → Añadir nuevo → Subir plugin. - WooCommerce → Ajustes → Pagos → VecchioPay: pegá la API key de prueba y la real, y el secreto de firma de cada modo.
- Tocá "Registrar webhook" y probá una compra en modo prueba.
Referencia completa
Todos los endpoints, campos y ejemplos están en la referencia interactiva (Swagger).