En resumen
La API de 2Checkout (ahora Verifone) permite a los desarrolladores procesar pagos, gestionar suscripciones y manejar transacciones de comercio electrónico de forma programática. Admite puntos finales RESTful para pedidos, clientes, productos y webhooks con autenticación basada en JSON utilizando claves API. Esta guía cubre todo, desde la configuración inicial hasta el manejo avanzado de webhooks.
Introducción
El procesamiento de pagos es crítico para cualquier negocio en línea. Una mala integración puede causar pérdida de ingresos, mientras que una integración sólida abre mercados globales. La API de 2Checkout (ahora Verifone) gestiona pagos para más de 45.000 comerciantes, procesando miles de millones en transacciones cada año.
El 67% de los compradores abandona el carrito por fricción en el pago. Por eso, una integración robusta de la API impacta directamente en tus resultados.
Esta guía te lleva paso a paso en la integración de la API de 2Checkout: autenticación, procesamiento de pagos, gestión de suscripciones, manejo de webhooks y tratamiento de errores. Terminarás con una integración lista para producción.
💡 Apidog simplifica las pruebas de integración de API. Prueba tus endpoints de 2Checkout, valida cargas útiles de webhooks y depura autenticación en un solo workspace. Importa la especificación OpenAPI de 2Checkout, simula respuestas y comparte escenarios de prueba con tu equipo.
¿Qué es la API de 2Checkout?
2Checkout (ahora Verifone Digital Commerce) expone una API RESTful para procesamiento de pagos y gestión de suscripciones. Puedes:
- Procesar pagos únicos y recurrentes
- Gestionar clientes y productos
- Seguir el ciclo de vida de los pedidos
- Gestionar reembolsos y disputas
- Automatizar impuestos y cumplimiento
- Soportar más de 100 monedas
Características clave
| Característica | Descripción |
|---|---|
| Diseño RESTful | Métodos HTTP estándar (GET, POST, PUT, DELETE) con JSON |
| Entorno Sandbox | Prueba pagos sin afectar transacciones reales |
| Soporte de Webhooks | Notificaciones en tiempo real para eventos de pedidos |
| Tokenización | Manejo seguro de datos de pago (sin almacenar tarjetas) |
| Cumplimiento Global | PCI DSS Nivel 1, GDPR, PSD2 y 3D Secure 2.0 |
Descripción general de la arquitectura de la API
La API usa endpoints versionados:
https://api.2checkout.com/1/
https://api.2checkout.com/2/
La versión 2 es la recomendada, con mejor gestión de suscripciones y webhooks.
Primeros pasos: Configuración de la autenticación
Paso 1: Crea tu cuenta de 2Checkout
- Regístrate en el portal de 2Checkout (Verifone).
- Sube documentos comerciales para verificación.
- Espera aprobación (24-48 horas normalmente).
- Accede a tu panel y recupera tus credenciales de API.
Paso 2: Recupera las claves API
En Integraciones > Claves API en el panel:
- Clave privada: para autenticación servidor (mantener en secreto)
- Clave pública: para tokenización cliente (puede exponerse)
- Secreto de Webhook: para validar firmas de webhooks
Práctica recomendada: Nunca subas claves API al control de versiones. Usa variables de entorno:
# .env file
TWOCHECKOUT_PRIVATE_KEY="tu_clave_privada"
TWOCHECKOUT_PUBLIC_KEY="tu_clave_publica"
TWOCHECKOUT_WEBHOOK_SECRET="tu_secreto_webhook"
Paso 3: Sandbox vs Producción
| Entorno | URL base | Uso |
|---|---|---|
| Sandbox | https://sandbox.2checkout.com/api/ |
Desarrollo y pruebas |
| Prod | https://api.2checkout.com/ |
Pagos en vivo |
Usa credenciales de sandbox en desarrollo. Cambia a producción sólo al lanzar pagos reales.
Paso 4: Métodos de autenticación
Método 1: API Key (Recomendado)
Incluye tu clave privada en el header:
const response = await fetch('https://api.2checkout.com/1/orders', {
method: 'GET',
headers: {
'X-Api-Key': process.env.TWOCHECKOUT_PRIVATE_KEY,
'Content-Type': 'application/json',
'Accept': 'application/json'
}
});
Método 2: Firma HMAC
Para máxima seguridad, firma requests con HMAC-SHA256:
const crypto = require('crypto');
function generateSignature(payload, privateKey) {
const hash = crypto
.createHmac('sha256', privateKey)
.update(JSON.stringify(payload))
.digest('hex');
return hash;
}
// Uso
const payload = { order_id: '12345', amount: 99.99 };
const signature = generateSignature(payload, privateKey);
const response = await fetch('https://api.2checkout.com/1/orders', {
method: 'POST',
headers: {
'X-Api-Key': process.env.TWOCHECKOUT_PRIVATE_KEY,
'X-Signature': signature,
'Content-Type': 'application/json'
},
body: JSON.stringify(payload)
});
Procesamiento de pagos: Puntos finales principales
Crear un pedido único
Procesa un pago único con /orders:
const createOrder = async (customerData, productData) => {
const payload = {
currency: 'USD',
customer: {
email: customerData.email,
first_name: customerData.firstName,
last_name: customerData.lastName,
phone: customerData.phone,
billing_address: {
address1: customerData.address,
city: customerData.city,
state: customerData.state,
zip: customerData.zip,
country: customerData.country
}
},
items: [
{
name: productData.name,
quantity: productData.quantity,
price: productData.price,
product_code: productData.sku
}
],
payment_method: {
type: 'card',
card_token: customerData.cardToken // Tokenización desde el frontend
}
};
const response = await fetch('https://api.2checkout.com/1/orders', {
method: 'POST',
headers: {
'X-Api-Key': process.env.TWOCHECKOUT_PRIVATE_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify(payload)
});
return await response.json();
};
Respuesta esperada
{
"order_id": "ORD-2026-001234",
"status": "approved",
"amount": 99.99,
"currency": "USD",
"customer_id": "CUST-789456",
"transaction_id": "TXN-9876543210",
"created_at": "2026-03-20T10:30:00Z"
}
Manejo de errores de pago
Implementa control de errores específico:
try {
const result = await createOrder(customer, product);
if (result.error) {
switch (result.error.code) {
case 'CARD_DECLINED':
// Solicita otra tarjeta
break;
case 'INSUFFICIENT_FUNDS':
// Mensaje de fondos insuficientes
break;
case 'INVALID_CVV':
// Solicita reingresar CVV
break;
default:
console.error('Payment failed:', result.error);
}
}
} catch (error) {
// Error de red o server
console.error('API request failed:', error);
}
Códigos de error comunes
| Código | HTTP | Descripción | Resolución |
|---|---|---|---|
CARD_DECLINED |
402 | Tarjeta rechazada | Solicitar otro método |
INVALID_CARD |
400 | Número no válido | Validar entrada |
EXPIRED_CARD |
400 | Tarjeta vencida | Solicitar fecha actualizada |
INVALID_CVV |
400 | CVV inválido | Pedir CVV de nuevo |
INSUFFICIENT_FUNDS |
402 | Fondos insuficientes | Sugerir pago alternativo |
DUPLICATE_ORDER |
409 | Pedido duplicado | Revisar duplicados |
INVALID_CURRENCY |
400 | Moneda no soportada | Verificar moneda |
API_KEY_INVALID |
401 | Autenticación fallida | Revisar clave API |
Gestión de clientes
La gestión de clientes es esencial para suscripciones y compras recurrentes. 2Checkout provee endpoints completos.
Crear cliente
const createCustomer = async (customerData) => {
const payload = {
email: customerData.email,
first_name: customerData.firstName,
last_name: customerData.lastName,
phone: customerData.phone,
company: customerData.company,
billing_address: {
address1: customerData.address,
address2: customerData.address2 || '',
city: customerData.city,
state: customerData.state,
zip: customerData.zip,
country: customerData.country
},
shipping_address: customerData.shippingAddress || null,
tax_exempt: false,
language: 'en'
};
const response = await fetch('https://api.2checkout.com/1/customers', {
method: 'POST',
headers: {
'X-Api-Key': process.env.TWOCHECKOUT_PRIVATE_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify(payload)
});
return await response.json();
};
Respuesta
{
"customer_id": "CUST-2026-123456",
"email": "john.doe@example.com",
"first_name": "John",
"last_name": "Doe",
"created_at": "2026-03-20T10:00:00Z",
"updated_at": "2026-03-20T10:00:00Z",
"payment_methods": [],
"subscriptions": [],
"order_history": []
}
Recuperar detalles de cliente
const getCustomer = async (customerId) => {
const response = await fetch(
`https://api.2checkout.com/1/customers/${customerId}`,
{
method: 'GET',
headers: {
'X-Api-Key': process.env.TWOCHECKOUT_PRIVATE_KEY,
'Content-Type': 'application/json'
}
}
);
return await response.json();
};
Actualizar información de cliente
const updateCustomer = async (customerId, updates) => {
const response = await fetch(
`https://api.2checkout.com/1/customers/${customerId}`,
{
method: 'PUT',
headers: {
'X-Api-Key': process.env.TWOCHECKOUT_PRIVATE_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify(updates)
}
);
return await response.json();
};
Eliminar cliente
const deleteCustomer = async (customerId) => {
const response = await fetch(
`https://api.2checkout.com/1/customers/${customerId}`,
{
method: 'DELETE',
headers: {
'X-Api-Key': process.env.TWOCHECKOUT_PRIVATE_KEY
}
}
);
return response.status === 204;
};
Nota: No puedes eliminar clientes con suscripciones activas o saldos; cancela primero.
Patrones de integración avanzados
Idempotencia en reintentos
Para evitar cargos duplicados, usa una clave única por orden:
const createIdempotentOrder = async (payload, idempotencyKey) => {
const response = await fetch('https://api.2checkout.com/1/orders', {
method: 'POST',
headers: {
'X-Api-Key': process.env.TWOCHECKOUT_PRIVATE_KEY,
'Content-Type': 'application/json',
'X-Idempotency-Key': idempotencyKey
},
body: JSON.stringify(payload)
});
return await response.json();
};
// Genera una clave única por orden
const idempotencyKey = `order_${userId}_${Date.now()}`;
Si reintentas con la misma clave, recibirás la misma respuesta, no se duplica el cargo.
3D Secure 2.0 (Cumplimiento UE)
Para tarjetas de clientes europeos, activa 3DS:
const createOrderWith3DS = async (payload) => {
const response = await fetch('https://api.2checkout.com/1/orders', {
method: 'POST',
headers: {
'X-Api-Key': process.env.TWOCHECKOUT_PRIVATE_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({
...payload,
three_ds: {
enabled: true,
challenge_required: 'preferred',
notification_url: 'https://tu-sitio.com/3ds-callback'
}
})
});
const result = await response.json();
if (result.three_ds_redirect_url) {
res.redirect(result.three_ds_redirect_url);
}
return result;
};
Precios multidivisa
Calcula precios en moneda local:
const getLocalizedPrice = async (basePrice, targetCurrency) => {
const response = await fetch(
`https://api.2checkout.com/1/rates?from=USD&to=${targetCurrency}`,
{
headers: {
'X-Api-Key': process.env.TWOCHECKOUT_PRIVATE_KEY
}
}
);
const rates = await response.json();
return basePrice * rates.rate;
};
const eurPrice = await getLocalizedPrice(99.99, 'EUR');
console.log(`Price: EUR ${eurPrice.toFixed(2)}`);
Prorrateo en upgrades de suscripción
Calcula cargos prorrateados al cambiar de plan:
const upgradeSubscription = async (subscriptionId, newPlanId) => {
const response = await fetch(
`https://api.2checkout.com/1/subscriptions/${subscriptionId}/upgrade`,
{
method: 'POST',
headers: {
'X-Api-Key': process.env.TWOCHECKOUT_PRIVATE_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({
plan_id: newPlanId,
proration: 'immediate',
invoice_proration: true
})
}
);
return await response.json();
};
Solución de problemas comunes
Webhooks no llegan
Síntomas: Los pedidos se procesan, pero tu sistema no se actualiza.
Diagnóstico:
// Revisar logs de entrega de webhooks en el panel de 2Checkout
Soluciones:
- Tu endpoint debe devolver 200 OK en menos de 5 segundos.
- Certificado SSL válido (solo HTTPS).
- Permitir rangos IP de 2Checkout en tu firewall.
- Revisar lógica de firma del webhook.
- Prueba con simulador antes de ir a producción.
Pagos de prueba fallan en Sandbox
Síntomas: Todas las tarjetas de prueba son rechazadas.
Soluciones:
- Usa claves API de sandbox.
- Verifica la URL base de sandbox.
- Usa tarjetas de prueba correctas.
- Confirma que la cuenta de sandbox esté activa.
Renovaciones de suscripción fallan
Síntomas: Suscripciones activas, pero no se renuevan.
Diagnóstico:
// Consulta historial de pagos de la suscripción
const history = await fetch(
`https://api.2checkout.com/1/subscriptions/${subId}/payments`,
{ headers: { 'X-Api-Key': privateKey } }
);
Soluciones:
- Verifica vencimiento de la tarjeta del cliente.
- Configura correctamente el cobro en el panel.
- Revisa la entrega del webhook
subscription.payment_failed. - Confirma que auto_renew esté activo.
Discrepancias en conversión de moneda
Síntomas: El cobro difiere de la conversión esperada.
Causa: 2Checkout usa tasas diarias, pueden variar.
Solución:
- Muestra conversión “aproximada” con disclaimer.
- Bloquea tasa al crear carrito (expira en 15 min).
- Almacena transacciones en moneda local del cliente.
Fallos en AVS (Verificación de dirección)
Síntomas: Tarjetas válidas rechazadas por dirección.
Soluciones:
- Usa autocompletado de direcciones.
- Haz obligatorio el código postal.
- Implementa AVS suave (advierte, no rechaza).
- Permite actualizar dirección de facturación.
Gestión de suscripciones
2Checkout es ideal para facturación recurrente. Así funciona la gestión de suscripciones:
Crear suscripción
const createSubscription = async (customerId, planId) => {
const payload = {
customer_id: customerId,
plan_id: planId,
start_date: new Date().toISOString(),
billing_cycle: 'monthly',
payment_method: {
type: 'card',
card_token: 'tok_card_tokenized'
},
options: {
trial_days: 14,
auto_renew: true
}
};
const response = await fetch('https://api.2checkout.com/1/subscriptions', {
method: 'POST',
headers: {
'X-Api-Key': process.env.TWOCHECKOUT_PRIVATE_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify(payload)
});
return await response.json();
};
Respuesta
{
"subscription_id": "SUB-2026-567890",
"status": "active",
"plan_id": "PLAN-PREMIUM-MONTHLY",
"customer_id": "CUST-789456",
"current_period_start": "2026-03-20T00:00:00Z",
"current_period_end": "2026-04-20T00:00:00Z",
"trial_end": "2026-04-03T00:00:00Z",
"amount": 29.99,
"currency": "USD"
}
Actualizar suscripción
const updateSubscription = async (subscriptionId, updates) => {
const payload = {
...updates
// Ejemplos:
// plan_id: 'PLAN-ENTERPRISE-MONTHLY',
// quantity: 5,
// payment_method: { card_token: 'new_token' }
};
const response = await fetch(
`https://api.2checkout.com/1/subscriptions/${subscriptionId}`,
{
method: 'PUT',
headers: {
'X-Api-Key': process.env.TWOCHECKOUT_PRIVATE_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify(payload)
}
);
return await response.json();
};
Cancelar suscripción
const cancelSubscription = async (subscriptionId, reason = '') => {
const payload = {
cancel_at_period_end: false,
reason: reason
};
const response = await fetch(
`https://api.2checkout.com/1/subscriptions/${subscriptionId}/cancel`,
{
method: 'POST',
headers: {
'X-Api-Key': process.env.TWOCHECKOUT_PRIVATE_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify(payload)
}
);
return await response.json();
};
Integración de Webhooks: Manejo de eventos en tiempo real
Los webhooks notifican a tu sistema sobre pagos, renovaciones y reembolsos automáticamente.
Paso 1: Configura el endpoint de Webhook
En tu panel de 2Checkout:
- Ve a Integraciones > Webhooks
- Agrega tu URL endpoint (debe ser HTTPS)
- Selecciona eventos deseados
- Guarda y anota tu secreto de webhook
Paso 2: Crea el manejador de Webhooks
const express = require('express');
const crypto = require('crypto');
const app = express();
app.post('/webhooks/2checkout', express.raw({ type: 'application/json' }), async (req, res) => {
const signature = req.headers['x-webhook-signature'];
const payload = req.body;
// Verifica la firma
const isValid = verifyWebhookSignature(payload, signature, process.env.TWOCHECKOUT_WEBHOOK_SECRET);
if (!isValid) {
console.error('Invalid webhook signature');
return res.status(401).send('Unauthorized');
}
const event = JSON.parse(payload.toString());
// Rutea evento
switch (event.type) {
case 'order.created':
await handleOrderCreated(event.data);
break;
case 'order.approved':
await handleOrderApproved(event.data);
break;
case 'order.declined':
await handleOrderDeclined(event.data);
break;
case 'subscription.created':
await handleSubscriptionCreated(event.data);
break;
case 'subscription.renewed':
await handleSubscriptionRenewed(event.data);
break;
case 'subscription.cancelled':
await handleSubscriptionCancelled(event.data);
break;
case 'refund.processed':
await handleRefundProcessed(event.data);
break;
default:
console.log('Unhandled event type:', 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')
);
}
Eventos críticos de Webhook
| Tipo de evento | Disparador | Acción sugerida |
|---|---|---|
order.created |
Nuevo pedido | Enviar email de confirmación |
order.approved |
Pago exitoso | Cumplir pedido, habilitar acceso |
order.declined |
Pago fallido | Notificar cliente, lógica de reintento |
subscription.renewed |
Pago recurrente | Extender acceso |
subscription.payment_failed |
Renovación fallida | Iniciar secuencia de cobro |
subscription.cancelled |
Cancelación cliente | Revocar acceso al final del periodo |
refund.processed |
Reembolso | Actualizar saldo usuario |
chargeback.received |
Disputa presentada | Reunir evidencias |
Buenas prácticas de Webhooks
- Verifica siempre firmas para evitar spoofing.
- Responde 200 OK rápidamente (evita reintentos).
- Procesa en background (pon en cola eventos).
- Haz idempotencia para manejar duplicados.
- Registra todo para depurar disputas.
Probando tu integración
Uso del entorno Sandbox
const BASE_URL = 'https://sandbox.2checkout.com/api/1';
const TEST_CARDS = {
APPROVED: '4111111111111111',
DECLINED: '4000000000000002',
INSUFFICIENT_FUNDS: '4000000000009995',
EXPIRED_CARD: '4000000000000069'
};
const TEST_ADDRESS = {
country: 'US',
zip: '90210'
};
Probar Webhooks localmente
Utiliza ngrok para exponer tu servidor local:
npm install -g ngrok
node server.js
ngrok http 3000
# Usa la URL ngrok en la configuración del webhook de 2Checkout
Apidog para pruebas de API
Apidog agiliza las pruebas de la API de 2Checkout:
- Importa la especificación OpenAPI.
- Crea colecciones de pruebas por endpoint.
- Simula respuestas sin acceder a la API real.
- Valida cargas útiles de webhooks.
- Comparte escenarios de prueba con tu equipo.
Configura variables de entorno para sandbox vs producción y alterna en un clic.
Checklist de lanzamiento a producción
Antes de lanzar:
- [ ] Cambia claves API de sandbox a producción
- [ ] Actualiza la URL base a
https://api.2checkout.com/ - [ ] Habilita verificación de firma HMAC en webhooks
- [ ] Configura monitoreo de pagos fallidos
- [ ] Implementa lógica de reintento para errores transitorios
- [ ] Prueba flujos de reembolso y contracargo
- [ ] Asegura cumplimiento PCI DSS (tokenización)
- [ ] Activa 3D Secure 2.0 para clientes UE
- [ ] Configura logging/auditoría
- [ ] Documenta operación ante incidencias
Monitoreo y alertas
Supervisa estas métricas:
// Ejemplo: tasa de éxito de pagos
const successRate = approvedOrders / totalOrders * 100;
if (successRate < 95) {
sendAlert('Payment success rate bajo 95%');
}
const errorBreakdown = errors.reduce((acc, err) => {
acc[err.code] = (acc[err.code] || 0) + 1;
return acc;
}, {});
if (errorBreakdown['CARD_DECLINED'] > threshold) {
sendAlert('Aumento de rechazos de tarjeta detectado');
}
Casos de uso del mundo real
Tienda de e-commerce
Un retailer de moda integró 2Checkout para pagos globales:
- Soporte de +100 monedas
- Redujo abandono de carrito un 23%
- Manejo automático de IVA UE
- Procesó >$2M el primer año
Implementación: 3 semanas, primero con pago alojado, luego API directa para UX personalizada.
Negocio SaaS de suscripción
Un SaaS de gestión de proyectos usó suscripciones 2Checkout:
- +5,000 suscripciones activas
- Upgrade prorrateado de planes
- Cobranza automatizada en renovaciones fallidas
- Bajó churn 15% con reintentos inteligentes
Clave: acceso controlado por webhook. Al recibir subscription.renewed, extiende acceso; con subscription.cancelled, revoca.
Conclusión
La API de 2Checkout cubre todo lo necesario para pagos y suscripciones. Recuerda:
- Usa sandbox para todo desarrollo/pruebas
- Implementa verificación HMAC en webhooks
- Maneja errores según código
- Prueba a fondo flujos de suscripción
- Monitorea métricas en producción
- Apalanca Apidog para pruebas y colaboración
Sección de Preguntas Frecuentes (FAQ)
¿Qué es la API de 2Checkout?
La API de 2Checkout (ahora Verifone) es una interfaz RESTful para procesar pagos, gestionar suscripciones, manejar reembolsos y automatizar transacciones e-commerce. Soporta JSON, autenticación HMAC y webhooks.
¿Es 2Checkout lo mismo que Verifone?
Sí. 2Checkout fue adquirida por Verifone en 2020 y renombrada como Verifone Digital Commerce. Los endpoints y funciones de API no cambiaron.
¿Cómo obtengo mi clave API de 2Checkout?
Entra a tu panel de 2Checkout, ve a Integraciones > Claves API y crea una nueva. Obtendrás clave privada (backend) y pública (frontend/tokenización).
¿Tiene 2Checkout entorno sandbox?
Sí. Usa https://sandbox.2checkout.com/api/ para pruebas. Crea cuenta sandbox y usa claves separadas para testear sin cobros reales.
¿Qué métodos de pago admite 2Checkout?
Tarjeta de crédito (Visa, Mastercard, Amex, Discover), PayPal, Apple Pay, Google Pay, transferencias bancarias y métodos locales en +100 países.
¿Cómo manejo los webhooks de forma segura?
Verifica el header X-Webhook-Signature usando HMAC-SHA256 y tu secreto. Procesa eventos de forma asíncrona y responde 200 OK enseguida.
¿Qué pasa si falla un pago de suscripción?
2Checkout envía webhook subscription.payment_failed. Implementa reintentos (3 veces en 7 días). Si fallan todos, se envía subscription.cancelled.
¿Es 2Checkout compatible con PCI DSS?
Sí, es PCI DSS Nivel 1. Usa tokenización frontend para evitar manipular datos de tarjeta y reducir tu alcance PCI.
¿Puedo probar suscripciones en sandbox?
Sí, el sandbox permite pruebas completas (trial, renovación, upgrade/downgrade, cancelación). Usa la tarjeta 4111111111111111 para pagos aprobados.
¿Cómo gestiono reembolsos vía API?
Haz POST a /refunds con el ID de pedido e importe. 2Checkout procesa reembolsos parciales o totales y envía webhook refund.processed al completar.

Top comments (0)