Documentación de integración
API REST de primepagos para procesar cobros (pay-ins) y envíos (pay-outs) por transferencia bancaria en Argentina (ARS).
Introducción
La integración se hace 100% server-to-server contra nuestra API. Tu backend autentica con una API key, crea pagos y recibe el resultado por webhooks firmados. Toda la operación de dinero ocurre del lado de primepagos; vos sólo consumís la API.
- Pay-in (cobro): generás un link/instrucciones para que un pagador te transfiera. Al acreditarse, recibís
payin.succeeded. - Pay-out (envío): enviás dinero a un CBU/CVU. Al confirmarse, recibís
payout.succeeded.
Entornos y URL base
Todas las rutas cuelgan de la URL base (incluye el prefijo de versión /v1):
https://api.primepagos.com/v1No hay un host separado para sandbox: el modo de prueba se define a nivel de cuenta (tu merchant puede estar en estado sandbox o active). Ver Sandbox.
Autenticación
Cada request a la API se autentica con tu API key en el header x-api-key. La key se entrega una sola vez al crearla; guardala de forma segura y nunca la expongas en el frontend.
x-api-key: pk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxIdempotencia
Los endpoints de creación (payins y payouts) requieren el header Idempotence-Key: un identificador único que vos generás por cada operación. Si reintentás con la misma key y el mismo cuerpo, la API devuelve el pago ya creado en lugar de duplicarlo.
- Obligatorio en
POSTde pagos. - Máximo 255 caracteres, sólo ASCII.
- Si reusás la key con un cuerpo distinto, la API responde
400.
POST/v1/payments/payins
Crea un cobro. Devuelve un payment_url e instrucciones (el CVU destino) para que el pagador transfiera.
Cuerpo
| Campo | Tipo | Detalle |
|---|---|---|
amount | string | Monto con hasta 2 decimales, ej. "15000.00". String para no perder precisión. |
currency | string | "ARS" (3 letras). |
paymentMethod | string | "bank_transfer". |
payer | object | documentNumber (DNI: 7-8 dígitos · CUIT: 11) + documentType (DNI por defecto, o CUIT). |
returnUrl | string? | Opcional. URL https a la que volver tras pagar. |
metadata | object? | Opcional. Objeto plano, hasta 20 claves, valores primitivos, máx. 4 kB. Te lo devolvemos en el webhook. |
Ejemplo
curl -X POST https://api.primepagos.com/v1/payments/payins \
-H "x-api-key: TU_API_KEY" \
-H "Idempotence-Key: order-A-1024" \
-H "Content-Type: application/json" \
-d '{
"amount": "15000.00",
"currency": "ARS",
"paymentMethod": "bank_transfer",
"payer": { "documentNumber": "20123456", "documentType": "DNI" },
"returnUrl": "https://tu-sitio.com/gracias",
"metadata": { "order_id": "A-1024" }
}'Respuesta
{
"payment_url": "https://pay.primepagos.com/pay/pm_x8q6oJ9l0v",
"payment": {
"id": "pm_x8q6oJ9l0v",
"input_amount": "15000",
"fact_amount": null,
"currency": "ARS",
"status": "pending",
"method": "bank_transfer",
"metadata": { "order_id": "A-1024" },
"created_at": "2026-06-15T00:37:41.015Z",
"expires_at": "2026-06-15T01:37:40.993Z"
},
"instructions": { "destination_cvu": "0000151500038783109135" }
}pending y expira en 1 hora si no se acredita. Mostrale al pagador el payment_url o el destination_cvu de instructions.POST/v1/payments/payouts
Envía dinero a un CBU/CVU. Requiere saldo disponible del merchant (en cuentas active).
Cuerpo
| Campo | Tipo | Detalle |
|---|---|---|
amount | string | Monto con hasta 2 decimales. |
currency | string | "ARS". |
paymentMethod | string | "bank_transfer". |
payee | object | cbu (22-23 dígitos), documentNumber (CUIT: 11 dígitos), documentType (CUIT por defecto). |
metadata | object? | Igual que en pay-in. |
Ejemplo
curl -X POST https://api.primepagos.com/v1/payments/payouts \
-H "x-api-key: TU_API_KEY" \
-H "Idempotence-Key: withdrawal-W-77" \
-H "Content-Type: application/json" \
-d '{
"amount": "20000.00",
"currency": "ARS",
"paymentMethod": "bank_transfer",
"payee": {
"cbu": "0000076500000123456789",
"documentNumber": "20123456789",
"documentType": "CUIT"
},
"metadata": { "withdrawal_id": "W-77" }
}'GET/v1/payments/payins/:id · GET/v1/payments/payouts/:id
Consultá el estado de un pago por su id público (el que devuelve la creación, ej. pm_x8q6oJ9l0v).
curl https://api.primepagos.com/v1/payments/payins/pm_x8q6oJ9l0v \
-H "x-api-key: TU_API_KEY"GET para reconciliar o consultar puntualmente.Estados de un pago
| Estado | Significado |
|---|---|
| new | Creado (típico al iniciar un pay-out). |
| pending | A la espera de la acreditación/confirmación. |
| succeeded | Acreditado/confirmado. Estado final exitoso. |
| expired | Pay-in que venció sin acreditarse (1 h). |
| failed | Falló el procesamiento (ej. pay-out rechazado). |
| cancelled | Cancelado. |
| reversed | Revertido por una corrección/ajuste. |
Webhooks
Cuando configurás una URL de webhook y un secret en tu cuenta, primepagos te envía un POST JSON ante cada evento relevante. Los eventos son idempotentes (pueden reintentarse): deduplicá por id.
Eventos
| Evento | Cuándo |
|---|---|
payin.succeeded | Se acreditó un cobro. |
payout.succeeded | Se confirmó un envío. |
payout.failed | El envío falló definitivamente. |
payout.cancelled | El envío fue cancelado. |
webhook.test | Evento de prueba que podés disparar para validar tu endpoint. |
Payload
El cuerpo es un sobre con id, type, created_at y data:
{
"id": "payin_succeeded_8c1e...e0b",
"type": "payin.succeeded",
"created_at": "2026-06-15T00:37:41.071Z",
"data": {
"id": "pm_x8q6oJ9l0v",
"status": "succeeded",
"currency": "ARS",
"input_amount": "15000",
"fact_amount": "15000",
"metadata": { "order_id": "A-1024" },
"created_at": "2026-06-15T00:37:41.015Z"
}
}Verificar la firma
Cada webhook incluye el header x-primepagos-webhook-signature: un HMAC-SHA256 (hex) del cuerpo crudo calculado con tu secret. Validalo siempre antes de procesar.
import { createHmac } from 'crypto';
import express from 'express';
const app = express();
// IMPORTANTE: la firma se calcula sobre el body CRUDO (raw), no sobre el JSON
// re-serializado. Capturá el Buffer original.
app.post(
'/webhooks/primepagos',
express.raw({ type: 'application/json' }),
(req, res) => {
const signature = req.header('x-primepagos-webhook-signature');
const expected = createHmac('sha256', process.env.PRIMEPAGOS_WEBHOOK_SECRET)
.update(req.body) // req.body es un Buffer (raw)
.digest('hex');
if (signature !== expected) {
return res.status(401).send('invalid signature');
}
const event = JSON.parse(req.body.toString('utf8'));
// Procesá de forma idempotente usando event.id (puede reintentarse).
switch (event.type) {
case 'payin.succeeded': /* acreditar la orden */ break;
case 'payout.succeeded': /* marcar retiro enviado */ break;
case 'payout.failed':
case 'payout.cancelled': /* revertir / reintentar */ break;
}
res.sendStatus(200); // respondé 2xx para confirmar la recepción
},
);Sandbox / pruebas
Si tu merchant está en estado sandbox, los pagos se simulan y se resuelven automáticamente sin tocar el banco — ideal para integrar de punta a punta. Usá tu API key normal.
- Pay-in que se aprueba solo →
payer.documentNumber = "11111111". - Pay-out que se aprueba solo →
payee.cbu = "1111111111111111111111"(22 unos). Otros CBU se cancelan, útil para probar el camino de fallo.
# Merchant en modo SANDBOX: los pagos se aprueban solos, sin tocar el banco.
# Pay-in de prueba que se aprueba automáticamente -> usar DNI 11111111
curl -X POST https://api.primepagos.com/v1/payments/payins \
-H "x-api-key: TU_API_KEY_SANDBOX" \
-H "Idempotence-Key: test-1" \
-H "Content-Type: application/json" \
-d '{ "amount":"10000","currency":"ARS","paymentMethod":"bank_transfer",
"payer":{"documentNumber":"11111111","documentType":"DNI"} }'
# Pay-out de prueba que se aprueba automáticamente -> usar CBU de 22 unos
# payee.cbu = "1111111111111111111111"Límites y validaciones
| Regla | Valor (ARS) |
|---|---|
| Monto de pay-in | entre 1.000 y 50.000.000 |
| Monto de pay-out | entre 15.000 y 30.000.000 |
| Decimales del monto | hasta 2 (se envía como string) |
| DNI (payer) | 7 u 8 dígitos |
| CUIT | 11 dígitos |
| CBU (payee) | 22 o 23 dígitos |
| Expiración de pay-in | 1 hora |
metadata | ≤ 20 claves · valores primitivos · ≤ 4 kB |
Errores
La API responde con códigos HTTP estándar y un cuerpo JSON con el detalle:
| Código | Significado |
|---|---|
400 | Datos inválidos (validación) o key de idempotencia reusada con otro cuerpo. |
401 | API key faltante o inválida (x-api-key). |
403 | Merchant sin permiso / estado no habilitado. |
404 | Recurso no encontrado. |
500 | Error interno. Reintentá con la misma Idempotence-Key. |
{
"statusCode": 400,
"error": "Bad Request",
"message": "documentNumber must be string with 7-8 numbers when documentType is DNI",
"path": "/v1/payments/payins"
}Soporte
Para obtener credenciales (API key), configurar tu URL/secret de webhook o pasar tu cuenta a producción, escribinos a soporte@primepagos.com.