En pocas palabras
La API de iPay permite a los desarrolladores integrar de forma programática el procesamiento de pagos, facturación y transacciones financieras. Utiliza autenticación OAuth 2.0 y clave API, puntos finales RESTful para pagos, reembolsos, transacciones y conciliación, con cumplimiento PCI DSS y límites de tasa estándar de la industria. Esta guía cubre la configuración de autenticación, el procesamiento de pagos, la integración de webhooks, el cumplimiento de seguridad y las estrategias de despliegue en producción.
Introducción
El procesamiento de pagos digitales gestiona más de 8 billones de dólares anuales mundialmente. Para desarrolladores de plataformas e-commerce, SaaS o marketplaces, integrar una API de pagos es esencial para aceptar pagos de clientes de forma segura y conforme a la normativa.
Las empresas pierden entre el 5% y el 10% de ingresos por pagos fallidos, conciliación manual y fraude. Una integración robusta automatiza el procesamiento, reduce fallos con lógica de reintento, permite conciliación automática e implementa detección de fraude.
En esta guía verás paso a paso cómo integrar la API de pagos: autenticación, procesamiento, reembolsos, webhooks, cumplimiento PCI DSS, seguridad y despliegue en producción. Al final tendrás una integración lista para producción.
💡Apidog simplifica las pruebas de la API de pagos. Prueba los endpoints en modo sandbox, valida firmas de webhook, inspecciona respuestas y depura problemas de integración en un solo workspace. Importa especificaciones, simula respuestas y comparte escenarios con tu equipo.
Nota: Esta guía cubre patrones generales de integración de API de pagos aplicables a iPay y procesadores similares. Las URLs y autenticación específicas pueden variar; consulta siempre la documentación oficial de iPay.
¿Qué es la API de iPay?
Las APIs de pago como iPay proporcionan interfaces RESTful para procesar transacciones financieras, incluyendo:
- Autorización y captura de pagos
- Reembolsos y contracargos
- Historial de transacciones e informes
- Tokenización de clientes (bóveda)
- Suscripción y facturación recurrente
- Generación y gestión de facturas
- Conciliación y liquidación
- Detección y prevención de fraudes
Características Clave
| Característica | Descripción |
|---|---|
| API RESTful | Puntos finales basados en JSON |
| OAuth 2.0 + Claves API | Autenticación segura |
| Webhooks | Notificaciones de pago en tiempo real |
| Tokenización | Almacenamiento seguro de tarjetas |
| 3D Secure | Cumplimiento de SCA |
| PCI DSS | Se requiere cumplimiento de Nivel 1 |
| Multi-Moneda | Compatible con más de 100 monedas |
| Herramientas Antifraude | Puntuación de riesgo, verificación de velocidad |
Visión General del Flujo de Pagos
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Cliente │───▶│ Comerciante │───▶│ Pasarela │
│ (Navegador) │ │ (Servidor) │ │ de Pagos │
└─────────────┘ └─────────────┘ └─────────────┘
│ │ │
│ 1. Introducir Tarjeta │ │
│───────────────────▶│ │
│ │ │
│ 2. Tokenizar │ │
│───────────────────▶│ 3. Crear Intento │
│ │───────────────────▶│
│ │ │
│ │ 4. Confirmar Pago│
│ │───────────────────▶│
│ │ │
│ │ 5. Resultado │
│ │◀───────────────────│
│ │ │
│ 6. Recibo │ │
│◀───────────────────│ │
Entorno de API
| Entorno | URL | Caso de Uso |
|---|---|---|
| Sandbox | https://sandbox.ipay.com/api |
Desarrollo, pruebas |
| Producción | https://api.ipay.com/api |
Transacciones en vivo |
Primeros Pasos: Configuración de Autenticación
Paso 1: Crear Cuenta iPay
- Regístrate como comerciante en iPay.
- Completa la verificación de empresa (KYB).
- Envía los documentos requeridos:
- Registro de empresa
- Detalles bancarios
- Identificación oficial
- Espera la aprobación (1-3 días hábiles).
Paso 2: Obtener Credenciales de API
- Inicia sesión en el Panel de Comerciantes de iPay.
- Ve a Configuración > Claves API.
- Crea una nueva clave API.
- Copia y almacena las credenciales de forma segura.
# .env (NO lo subas a git)
IPAY_API_KEY="live_xxxxxxxxxxxxxxxxxxxx"
IPAY_API_SECRET="secret_xxxxxxxxxxxxxxxxxxxx"
IPAY_WEBHOOK_SECRET="whsec_xxxxxxxxxxxxxxxxxxxx"
Nota de seguridad: Usa claves separadas para sandbox y producción.
Paso 3: Entender los Métodos de Autenticación
| Método | Mejor para | Nivel de Seguridad |
|---|---|---|
| Autenticación Básica | Servidor a servidor | Alto |
| OAuth 2.0 | Aplicaciones multi-inquilino | Más alto |
| JWT | Microservicios | Alto |
Paso 4: Realizar Llamadas a la API Autenticadas
Implementa un cliente de API reutilizable:
const IPAY_BASE_URL = process.env.IPAY_SANDBOX
? 'https://sandbox.ipay.com/api'
: 'https://api.ipay.com/api';
const ipayRequest = async (endpoint, options = {}) => {
const apiKey = process.env.IPAY_API_KEY;
const apiSecret = process.env.IPAY_API_SECRET;
// Autenticación básica (Base64)
const authHeader = Buffer.from(`${apiKey}:${apiSecret}`).toString('base64');
const response = await fetch(`${IPAY_BASE_URL}${endpoint}`, {
...options,
headers: {
'Authorization': `Basic ${authHeader}`,
'Content-Type': 'application/json',
'Idempotency-Key': options.idempotencyKey || generateIdempotencyKey(),
...options.headers
}
});
if (!response.ok) {
const error = await response.json();
throw new Error(`iPay API Error: ${error.message}`);
}
return response.json();
};
function generateIdempotencyKey() {
return `req_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
}
// Ejemplo de uso
const account = await ipayRequest('/account');
console.log(`Comerciante: ${account.business_name}`);
Procesamiento de Pagos
Creación de una Intención de Pago
Inicializa un pago así:
const createPayment = async (paymentData) => {
const payment = {
amount: paymentData.amount, // En centavos
currency: paymentData.currency || 'USD',
customer: paymentData.customerId,
payment_method: paymentData.paymentMethodId,
confirm: true,
description: paymentData.description,
metadata: {
orderId: paymentData.orderId,
customerId: paymentData.customerId
},
capture_method: paymentData.captureMethod || 'automatic',
statement_descriptor: paymentData.statementDescriptor || 'MYCOMPANY'
};
const response = await ipayRequest('/payments', {
method: 'POST',
body: JSON.stringify(payment),
idempotencyKey: paymentData.idempotencyKey
});
return response;
};
// Uso
const payment = await createPayment({
amount: 2999, // $29.99
currency: 'USD',
customerId: 'cus_12345',
paymentMethodId: 'pm_67890',
description: 'Pedido #ORD-001',
orderId: 'ORD-001',
statementDescriptor: 'MYCOMPANY INC'
});
console.log(`Estado del pago: ${payment.status}`);
console.log(`ID del pago: ${payment.id}`);
Flujo de Estado de Pagos
requires_payment_method → requires_confirmation → requires_action
→ processing → requires_capture → succeeded
→ failed
→ canceled
Métodos de Pago
| Método | Tipo | Caso de Uso |
|---|---|---|
card |
Crédito/Débito | Pagos estándar |
bank_transfer |
ACH, SEPA | Transferencias de baja comisión |
digital_wallet |
Apple Pay, Google Pay | Pago móvil |
buy_now_pay_later |
Klarna, Afterpay | Pagos a plazos |
Tokenización de Detalles de Tarjeta
Almacena tarjetas de forma segura para pagos futuros:
const tokenizeCard = async (cardData) => {
// NUNCA envíes datos de tarjeta sin procesar a tu backend
// Usa tokenización del lado del cliente
// Lado del cliente
const response = await fetch(`${IPAY_BASE_URL}/tokens`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${CLIENT_PUBLISHABLE_KEY}`
},
body: JSON.stringify({
card: {
number: cardData.number,
exp_month: cardData.expMonth,
exp_year: cardData.expYear,
cvc: cardData.cvc
}
})
});
const token = await response.json();
return token; // Envía token.id a tu backend
};
// Lado backend: Usa el token para crear un método de pago
const createPaymentMethod = async (tokenId, customerId) => {
const response = await ipayRequest('/payment_methods', {
method: 'POST',
body: JSON.stringify({
type: 'card',
token: tokenId,
customer: customerId
})
});
return response;
};
Autenticación 3D Secure
Implementa SCA (Strong Customer Authentication):
const createPaymentWith3DS = async (paymentData) => {
const payment = await createPayment({
...paymentData,
confirmation_token: true // Devuelve client_secret para 3DS
});
if (payment.status === 'requires_action') {
// El cliente debe completar el desafío 3DS
return {
requiresAction: true,
clientSecret: payment.client_secret,
nextAction: payment.next_action
};
}
return { success: true, payment };
};
// Lado cliente: Usa iPay.js o el SDK móvil para presentar el desafío 3DS
Gestión de Reembolsos
Procesar Reembolso Completo
Reembolsa el pago completo:
const refundPayment = async (paymentId, reason = null) => {
const refund = {
payment: paymentId,
reason: reason || 'solicitado_por_cliente'
};
const response = await ipayRequest('/refunds', {
method: 'POST',
body: JSON.stringify(refund),
idempotencyKey: `refund_${paymentId}_${Date.now()}`
});
return response;
};
// Uso
const refund = await refundPayment('pay_12345', 'duplicado');
console.log(`Estado del reembolso: ${refund.status}`);
console.log(`ID del reembolso: ${refund.id}`);
Procesar Reembolso Parcial
Reembolsa una parte del pago:
const partialRefund = async (paymentId, amount, reason = null) => {
const refund = {
payment: paymentId,
amount: amount, // En centavos
reason: reason || 'solicitado_por_cliente'
};
const response = await ipayRequest('/refunds', {
method: 'POST',
body: JSON.stringify(refund),
idempotencyKey: `refund_${paymentId}_${amount}_${Date.now()}`
});
return response;
};
// Uso - Reembolsar $15.00 de un pago de $29.99
const refund = await partialRefund('pay_12345', 1500, 'envío_parcial');
console.log(`Reembolsado: $${refund.amount / 100}`);
Razones de Reembolso
| Código de Razón | Descripción |
|---|---|
duplicate |
Cargo duplicado |
fraudulent |
Transacción fraudulenta |
requested_by_customer |
Solicitud del cliente |
order_canceled |
Cancelación de pedido |
product_not_received |
Artículo no entregado |
product_not_as_described |
Artículo diferente a la descripción |
Gestión de Clientes
Crear un Cliente
Almacena datos para pagos recurrentes:
const createCustomer = async (customerData) => {
const customer = {
email: customerData.email,
name: customerData.name,
phone: customerData.phone,
metadata: {
internalId: customerData.internalId,
tier: customerData.tier
}
};
const response = await ipayRequest('/customers', {
method: 'POST',
body: JSON.stringify(customer)
});
return response;
};
// Uso
const customer = await createCustomer({
email: 'customer@example.com',
name: 'John Doe',
phone: '+1-555-0123',
internalId: 'USR-12345',
tier: 'premium'
});
console.log(`Cliente creado: ${customer.id}`);
Asociar un Método de Pago al Cliente
Guarda una tarjeta para uso futuro:
const attachPaymentMethod = async (paymentMethodId, customerId) => {
const response = await ipayRequest(`/payment_methods/${paymentMethodId}/attach`, {
method: 'POST',
body: JSON.stringify({
customer: customerId
})
});
return response;
};
// Uso
await attachPaymentMethod('pm_67890', 'cus_12345');
Listar Métodos de Pago del Cliente
Obtén tarjetas guardadas:
const getCustomerPaymentMethods = async (customerId) => {
const response = await ipayRequest(`/customers/${customerId}/payment_methods`);
return response;
};
// Uso
const methods = await getCustomerPaymentMethods('cus_12345');
methods.data.forEach(method => {
console.log(`${method.card.brand} terminada en ${method.card.last4}`);
console.log(`Expira: ${method.card.exp_month}/${method.card.exp_year}`);
});
Webhooks
Configuración de Webhooks
- Inicia sesión en el panel de iPay.
- Ve a Desarrolladores > Webhooks.
- Haz clic en Agregar Punto Final.
- Ingresa tu URL HTTPS.
- Selecciona eventos a suscribirte.
Eventos de Webhook
| Evento | Activador |
|---|---|
payment.succeeded |
Pago completado |
payment.failed |
Pago rechazado |
payment.refunded |
Reembolso procesado |
payment.disputed |
Contracargo presentado |
customer.created |
Nuevo cliente |
customer.subscription.updated |
Suscripción modificada |
Manejo de Webhooks
const express = require('express');
const crypto = require('crypto');
const app = express();
app.post('/webhooks/ipay', express.raw({ type: 'application/json' }), async (req, res) => {
const signature = req.headers['ipay-signature'];
const payload = req.body;
// Verificar firma del webhook
const isValid = verifyWebhookSignature(payload, signature, process.env.IPAY_WEBHOOK_SECRET);
if (!isValid) {
console.error('Firma de webhook inválida');
return res.status(401).send('No autorizado');
}
const event = JSON.parse(payload.toString());
// Manejar eventos
switch (event.type) {
case 'payment.succeeded':
await handlePaymentSucceeded(event.data);
break;
case 'payment.failed':
await handlePaymentFailed(event.data);
break;
case 'payment.refunded':
await handlePaymentRefunded(event.data);
break;
case 'payment.disputed':
await handlePaymentDisputed(event.data);
break;
default:
console.log('Tipo de evento no manejado:', event.type);
}
res.status(200).send('OK');
});
function verifyWebhookSignature(payload, signature, secret) {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature, 'hex'),
Buffer.from(expectedSignature, 'hex')
);
}
async function handlePaymentSucceeded(data) {
console.log(`Pago exitoso: ${data.id}`);
// Actualizar estado del pedido
await db.orders.update(data.metadata.orderId, {
status: 'pagado',
paymentId: data.id,
paidAt: new Date()
});
// Enviar correo de confirmación
await sendOrderConfirmation(data.metadata.orderId);
}
async function handlePaymentFailed(data) {
console.log(`Pago fallido: ${data.id} - ${data.failure_code}`);
// Notificar al cliente
await sendPaymentFailedEmail(data.customer, data.failure_message);
// Reintento o marcar pedido como fallido
await db.orders.update(data.metadata.orderId, {
status: 'pago_fallido',
failureReason: data.failure_message
});
}
Seguridad y Cumplimiento
Requisitos PCI DSS
Debes cumplir con PCI DSS:
| Requisito | Implementación |
|---|---|
| Red Segura | Usar HTTPS, firewalls, configuraciones seguras |
| Protección de Datos del Titular de la Tarjeta | Nunca almacenar CVV, cifrar PAN |
| Gestión de Vulnerabilidades | Actualizaciones de seguridad regulares, antivirus |
| Control de Acceso | Mínimo privilegio, MFA, IDs únicos |
| Monitoreo | Registro, detección de intrusiones |
| Política de Seguridad | Políticas documentadas, formación regular |
Mejores Prácticas de Seguridad
// 1. Usa tokenización - NUNCA manejes datos de tarjeta sin procesar
const token = await tokenizeCard(cardData); // Lado cliente
// 2. Implementa idempotencia en todos los pagos
const idempotencyKey = `pay_${orderId}_${Date.now()}`;
// 3. Valida montos en backend
if (req.body.amount !== calculatedAmount) {
throw new Error('Discrepancia de monto - posible manipulación');
}
// 4. Registra operaciones de pago (sin datos sensibles)
logger.info('Intento de pago', {
orderId,
amount,
currency,
customerId,
timestamp: new Date().toISOString()
// JAMÁS registres: números de tarjeta, CVV, detalles completos
});
// 5. Usa variables de entorno para los secretos
const apiKey = process.env.IPAY_API_KEY;
// 6. Implementa rate limiting en endpoints de pago
const paymentLimiter = rateLimit({
windowMs: 60000,
max: 10 // 10 intentos por minuto
});
Lista de Verificación para la Implementación en Producción
Antes de procesar pagos en vivo, asegúrate de:
- [ ] Completar el cuestionario PCI DSS
- [ ] Usar HTTPS en todos los endpoints
- [ ] Almacenar claves API de forma segura
- [ ] Implementar verificación de firma de webhook
- [ ] Añadir idempotencia en todos los pagos
- [ ] Configurar logs (sin datos sensibles)
- [ ] Configurar reglas antifraude
- [ ] Probar flujos de reembolso y disputa
- [ ] Crear manual de operaciones para fallos
- [ ] Configurar monitoreo y alertas
- [ ] Implementar procesador de pagos de respaldo
Casos de Uso en el Mundo Real
Checkout en e-commerce
Desafío: Procesamiento manual, alto abandono
Solución: Checkout en una página con tarjetas tokenizadas
Resultado: +35% en conversión, pagos instantáneos
Facturación por Suscripción SaaS
Desafío: Facturación y cobro manual
Solución: Pagos recurrentes con reintentos automáticos
Resultado: 95% de pagos a tiempo, 80% menos tiempo administrativo
Depósito en Garantía (Escrow) para Marketplaces
Desafío: Pagos divididos entre proveedores
Solución: Intenciones de pago y transferencias programadas
Resultado: Pagos automatizados, menos fraude
Conclusión
Integrar una API de pagos exige atención a la seguridad, cumplimiento y manejo de errores. Recuerda:
- Nunca manejes datos de tarjeta sin procesar; usa tokenización
- Implementa idempotencia en operaciones de pago
- Verifica firmas de webhook para prevenir fraude
- Cumple con PCI DSS
- Prueba exhaustivamente en sandbox antes de producción
- Apidog facilita pruebas de API y colaboración de equipo
Sección de Preguntas Frecuentes
¿Cómo me autentico con la API de iPay?
Usa autenticación básica con clave API y secreto, u OAuth 2.0 para aplicaciones multi-inquilino.
¿Puedo almacenar los detalles de la tarjeta del cliente?
Sí, siempre que cumplas PCI DSS. Usa tokenización para almacenar tarjetas en la bóveda de iPay.
¿Cómo manejo los pagos fallidos?
Implementa lógica de reintento con backoff exponencial, notifica al cliente y ofrece métodos alternativos.
¿Qué es la idempotencia y por qué es importante?
La idempotencia asegura que solicitudes duplicadas con la misma clave produzcan el mismo resultado, evitando cargos dobles.
¿Cómo pruebo los pagos sin cargar las tarjetas?
Utiliza el modo sandbox con tarjetas de prueba de la documentación oficial de iPay.
¿Qué son las firmas de webhook?
Firmas criptográficas que validan que los webhooks provienen de iPay y no de actores maliciosos.
Top comments (0)