En pocas palabras
La API de iPay permite a los desarrolladores integrar programáticamente el procesamiento de pagos, la facturación y las transacciones financieras. Utiliza autenticación OAuth 2.0 y clave API, puntos finales RESTful para pagos, reembolsos, transacciones y conciliación, con requisitos de 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 implementación en producción.
Introducción
El procesamiento de pagos digitales gestiona más de 8 billones de dólares anuales en todo el mundo. Para los desarrolladores que construyen plataformas de comercio electrónico, aplicaciones SaaS o soluciones de mercado, la integración de la API de pagos no es opcional, es esencial para aceptar pagos de clientes de forma segura y conforme a la normativa.
Aquí está la realidad: las empresas pierden entre el 5% y el 10% de sus ingresos debido a pagos fallidos, conciliación manual y fraude en los pagos. Una sólida integración de la API de pagos automatiza el procesamiento de pagos, reduce los fallos con una lógica de reintento inteligente, permite la conciliación automática e implementa la detección de fraude.
Esta guía le guiará a través de todo el proceso de integración de la API de pagos. Aprenderá sobre la configuración de autenticación, el procesamiento de pagos, la gestión de reembolsos, el manejo de webhooks, el cumplimiento PCI DSS, las mejores prácticas de seguridad y las estrategias de implementación en producción. Al final, tendrá una integración de pagos lista para producción.
Nota: Esta guía cubre patrones generales de integración de API de pagos aplicables a iPay y procesadores de pagos similares. Las URL de los puntos finales específicos y los detalles de autenticación pueden variar; consulte siempre la documentación oficial de iPay para obtener detalles de implementación.
¿Qué es la API de iPay?
Las API de pago como iPay proporcionan interfaces RESTful para procesar transacciones financieras. La API maneja:
- 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
Antes de acceder a la API:
- Visite el registro de comerciante de iPay
- Complete la verificación de la empresa (KYB)
- Envíe los documentos requeridos:
- Registro de empresa
- Detalles de la cuenta bancaria
- Identificación gubernamental
- Espere la aprobación (1-3 días hábiles)
Paso 2: Obtener Credenciales de API
Genere credenciales de API:
- Inicie sesión en el Panel de Comerciantes de iPay
- Navegue a Configuración > Claves API
- Cree una nueva clave API
- Copie las credenciales de forma segura
# Archivo .env (NUNCA lo suba a git)
IPAY_API_KEY="live_xxxxxxxxxxxxxxxxxxxx"
IPAY_API_SECRET="secret_xxxxxxxxxxxxxxxxxxxx"
IPAY_WEBHOOK_SECRET="whsec_xxxxxxxxxxxxxxxxxxxx"
Nota de seguridad: Utilice claves separadas para sandbox y producción.
Paso 3: Entender los Métodos de Autenticación
iPay admite múltiples 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
Cree 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 (codificada en 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)}`;
}
// Uso
const account = await ipayRequest('/account');
console.log(`Comerciante: ${account.business_name}`);
Procesamiento de Pagos
Creación de una Intención de Pago
Inicializar pago:
const createPayment = async (paymentData) => {
const payment = {
amount: paymentData.amount, // En la unidad monetaria más pequeña (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', // 'automatic' o 'manual'
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
Almacenar de forma segura la tarjeta para uso futuro:
const tokenizeCard = async (cardData) => {
// NUNCA envíe datos de tarjeta sin procesar a su servidor
// En su lugar, utilice la tokenización del lado del cliente
// Lado del cliente (navegador/móvil)
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íe token.id a su servidor
};
// Lado del servidor: Use 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
Implementar el cumplimiento de SCA:
const createPaymentWith3DS = async (paymentData) => {
const payment = await createPayment({
...paymentData,
confirmation_token: true // Devolver secreto del cliente 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 del cliente: Manejar el desafío 3DS
// Use iPay.js o el SDK móvil para presentar el desafío de autenticación
Gestión de Reembolsos
Procesar Reembolso Completo
Reembolsar 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
Reembolsar una porción del pago:
const partialRefund = async (paymentId, amount, reason = null) => {
const refund = {
payment: paymentId,
amount: amount, // En la unidad monetaria más pequeña
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
Almacenar cliente 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
Guardar 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
Obtener 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
Configure los puntos finales de webhook:
- Inicie sesión en el Panel de iPay
- Navegue a Desarrolladores > Webhooks
- Haga clic en Agregar Punto Final
- Introduzca su URL HTTPS
- Seleccione los eventos a los que desea suscribirse
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());
// Dirigir al manejador apropiado
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);
}
// Confirmar recepción
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 electrónico 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);
// Lógica de 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
Las integraciones de pagos deben 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. Usar tokenización - NUNCA manejar datos de tarjeta sin procesar
const token = await tokenizeCard(cardData); // Lado del cliente
// 2. Implementar idempotencia para todas las operaciones de pago
const idempotencyKey = `pay_${orderId}_${Date.now()}`;
// 3. Validar montos en el lado del servidor
if (req.body.amount !== calculatedAmount) {
throw new Error('Discrepancia de monto - posible manipulación');
}
// 4. Registrar todas las operaciones de pago (sin datos sensibles)
logger.info('Intento de pago', {
orderId,
amount,
currency,
customerId,
timestamp: new Date().toISOString()
// NUNCA registrar: números de tarjeta, CVV, detalles completos del método de pago
});
// 5. Usar variables de entorno para los secretos
const apiKey = process.env.IPAY_API_KEY; // No codificado
// 6. Implementar limitación de tasa en los puntos finales de pago
const paymentLimiter = rateLimit({
windowMs: 60000,
max: 10 // 10 intentos de pago por minuto
});
Lista de Verificación para la Implementación en Producción
Antes de procesar pagos en vivo:
- [ ] Completar el Cuestionario de Autoevaluación PCI DSS
- [ ] Usar HTTPS para todos los puntos finales
- [ ] Almacenar las claves API en una gestión de secretos segura
- [ ] Implementar la verificación de la firma de webhook
- [ ] Añadir idempotencia para todas las operaciones de pago
- [ ] Configurar un registro completo (sin datos sensibles)
- [ ] Configurar reglas de detección de fraude
- [ ] Probar flujos de reembolso y disputa
- [ ] Crear un manual de operaciones para fallos de pago
- [ ] Configurar monitoreo y alertas
- [ ] Implementar un procesador de pagos de respaldo
Casos de Uso en el Mundo Real
Cierre de Compra en Comercio Electrónico
Un minorista en línea integra pagos:
- Desafío: Procesamiento manual de pagos, alto abandono
- Solución: Cierre de compra en una página con tarjetas tokenizadas
- Resultado: Aumento del 35% en la conversión, pagos instantáneos
Facturación por Suscripción SaaS
Una empresa de software automatiza la facturación:
- Desafío: Generación y cobro manual de facturas
- Solución: Pagos recurrentes con reintento automático
- Resultado: 95% de pagos a tiempo, 80% de ahorro en tiempo administrativo
Depósito en Garantía (Escrow) para Marketplaces
Una plataforma maneja pagos entre múltiples partes:
- Desafío: Pagos divididos complejos entre proveedores
- Solución: Intenciones de pago con programación de transferencias
- Resultado: Pagos automatizados a proveedores, reducción del fraude
Conclusión
La integración de la API de pagos requiere una cuidadosa atención a la seguridad, el cumplimiento y el manejo de errores. Puntos clave:
- Nunca maneje datos de tarjeta sin procesar; use tokenización
- Implemente la idempotencia para todas las operaciones de pago
- Verifique las firmas de webhook para prevenir el fraude
- Cumpla con los requisitos PCI DSS
- Pruebe exhaustivamente en el entorno de pruebas (sandbox) antes de la producción
- Apidog agiliza las pruebas de API y la colaboración en equipo
Sección de Preguntas Frecuentes
¿Cómo me autentico con la API de iPay?
Use autenticación básica con clave API y secreto, o OAuth 2.0 para aplicaciones multi-inquilino.
¿Puedo almacenar los detalles de la tarjeta del cliente?
Sí, pero debe cumplir con PCI DSS. Use la tokenización para almacenar tarjetas de forma segura en la bóveda de iPay.
¿Cómo manejo los pagos fallidos?
Implemente una lógica de reintento con retroceso exponencial, notifique a los clientes y proporcione métodos de pago alternativos.
¿Qué es la idempotencia y por qué es importante?
La idempotencia garantiza que las solicitudes duplicadas con la misma clave produzcan el mismo resultado, evitando cargos duplicados.
¿Cómo pruebo los pagos sin cargar las tarjetas?
Use el modo sandbox con números de tarjeta de prueba proporcionados en la documentación de iPay.
¿Qué son las firmas de webhook?
Firmas criptográficas que verifican que los webhooks provienen de iPay, no de un actor malintencionado.
