Pruebas en Sandbox
El entorno sandbox de Koywe te permite probar todos los flujos de pago con transacciones simuladas antes de ir en vivo.
Entorno Sandbox
URL Base
Todas las solicitudes API de sandbox usan:
https://api-sandbox.koywe.comObtener Credenciales de Prueba
Contacta a soporte@koywe.com para recibir:
- API Key de Sandbox
- Secret de Sandbox
- ID de Organización
- ID de Comercio
Sandbox vs Producción: Las credenciales de sandbox están completamente separadas de producción. No se involucra dinero real en las pruebas de sandbox.
Diferencias de comportamiento en sandbox
Sandbox replica producción fielmente, pero un puñado de comportamientos difieren y tropiezan a los integradores nuevos. Ten en cuenta estos de entrada:
| Comportamiento | Lo que realmente ocurre en sandbox |
|---|---|
Órdenes PAYOUT | Se crean como PENDING y luego pasan a FAILED. El USD se descuenta y se reembolsa. El servicio de payout no se ejecuta — usa esto para probar la máquina de estados, no el giro externo. |
KHIPU PAYIN | Se auto-completa del lado de Koywe sin necesidad de visitar el link de Khipu. |
Método de pago QRI (CLP) | Roto en sandbox — usa KHIPU en su lugar. |
BALANCE_TRANSFER sin policy | Bloqueado con POL00002. Crea primero una policy y una regla ALLOW (ver abajo). |
BALANCE_TRANSFER con policy | Se completa instantáneamente — no pasa por PROCESSING. |
| Números de documento inválidos | Se validan siempre, incluso en sandbox (DC00010). Las pruebas necesitan documentos válidos por país (lista abajo). |
| Moneda de cuenta destino que no coincide | BAA00008 — la moneda de la cuenta destino debe coincidir exactamente con la moneda destino de la orden. |
organizationId equivocado en config | Los GET devuelven vacío silenciosamente; los POST fallan con MC00015 (“Merchant does not belong to the organization”). Si las lecturas funcionan pero las escrituras fallan en una configuración nueva, revisa esto primero. |
| Operaciones con MFA | Las órdenes pasan a ON_HOLD y esperan (POL00007). Aprueba desde el dashboard, pasa --mfa-token, o usa flow order --wait. |
Documentos de prueba válidos
La validación de documentos (DC00010) está activa en sandbox. Los valores siguientes pasan las verificaciones de formato por país y son seguros para pruebas:
| País | Tipo | Ejemplo |
|---|---|---|
| Chile | RUT | 11111111-1 |
| Brasil (persona) | CPF | 11144477735 |
| Brasil (empresa) | CNPJ | 11222333000181 |
| Colombia | CC | 1020304050 |
| México | RFC | XAXX010101000 |
| Argentina | CUIT | 20123456780 |
| Perú | DNI | 12345678 |
Policy mínima para BALANCE_TRANSFER
Antes de poder crear una orden BALANCE_TRANSFER o cualquier orden con MFA en sandbox, la organización necesita una policy activa con al menos una regla coincidente:
npx @koyweforest/cli policy create --data '{"name":"default"}'
npx @koyweforest/cli policy rules create --data '{
"name": "allow-balance-transfer",
"scope": "ORDER",
"match": { "orderType": ["BALANCE_TRANSFER"] },
"decision": { "action": "ALLOW" }
}'Consulta Passkeys y Aprobaciones para el modelo completo de policy y el Catálogo de Códigos de Error para los códigos POL*.
Métodos de Pago de Prueba por País
Colombia (COP) 🇨🇴
PSE (Pagos Seguros en Línea)
Bancos de Prueba:
BANCOLOMBIADAVIVIENDABOGOTAOCCIDENTE
Uso:
{
"method": "PSE",
"extra": { "bankAccount": { "name": "BANCOLOMBIA" } } // Cualquier banco de prueba
}Comportamiento:
- El enlace de pago es completamente funcional en sandbox
- Sigue el proceso de pago simulado
- Puedes elegir éxito o fallo del pago durante el flujo
- Permite probar la experiencia completa del usuario
Nequi
Uso:
{
"method": "NEQUI"
}Comportamiento:
- Genera un código QR de prueba
- Después de escanear el código QR, recibirás opciones para éxito o fallo del pago
- Simula la experiencia completa de pago Nequi
Brasil (BRL) 🇧🇷
PIX Estático
Uso:
{
"method": "PIX_STATIC"
}Comportamiento:
- Genera un código QR de prueba
- Después de escanear el código QR, recibirás opciones para éxito o fallo del pago
- Simula la experiencia completa de pago PIX
PIX Dinámico
Uso:
{
"method": "PIX_DYNAMIC"
}Comportamiento:
- Genera un código QR de prueba
- Después de escanear el código QR, recibirás opciones para éxito o fallo del pago
- Similar a PIX_STATIC con opciones de prueba interactivas
México (MXN) 🇲🇽
SPEI
Uso:
{
"method": "SPEI"
}Comportamiento:
- Proporciona detalles de cuenta bancaria de prueba
- Se completa automáticamente después de la creación de la orden
- Simula confirmación de transferencia bancaria
Tarjetas
Números de Tarjeta de Prueba:
- Éxito:
4242424242424242 - Rechazada:
4000000000000002 - Fondos Insuficientes:
4000000000009995
Uso:
{
"method": "CARD"
}Chile (CLP) 🇨🇱
Khipu
Uso:
{
"method": "KHIPU"
}Comportamiento:
- El enlace de pago es completamente funcional en sandbox
- Sigue el proceso de pago simulado
- Puedes elegir éxito o fallo del pago durante el flujo
- Permite probar la experiencia completa del usuario
Argentina (ARS) 🇦🇷
Múltiples Métodos Locales
Uso:
{
"method": "KHIPU" // También funciona para Argentina
}Comportamiento:
- El enlace de pago es completamente funcional en sandbox
- Puedes elegir éxito o fallo del pago durante el flujo
Escenarios de Prueba
Pruebas Interactivas: La mayoría de métodos de pago (PSE, Khipu) proporcionan enlaces de pago funcionales donde puedes seguir el proceso de pago simulado y elegir éxito o fallo. Los métodos basados en QR (PIX, Nequi) te dan opciones después de escanear el código.
Flujo de Pago Exitoso
Prueba un pago exitoso de extremo a extremo:
async function testSuccessfulPayment() {
// Cualquier monto tendrá éxito en sandbox
const order = await createPayinOrder(token, orgId, merchantId, {
amount: 50000,
currency: 'COP',
paymentMethod: 'PSE',
bank: 'BANCOLOMBIA'
});
console.log('Orden creada:', order.id);
console.log('Estado:', order.status); // "PENDING"
console.log('URL de Pago:', order.paymentUrl);
// En sandbox, la orden se completa automáticamente
// Espera unos segundos y verifica el estado
await sleep(5000);
const updated = await getOrderStatus(token, orgId, merchantId, order.id);
console.log('Estado actualizado:', updated.status); // "COMPLETED"
}Flujo esperado:
PENDING → PROCESSING → PAID → COMPLETEDEscenario de Pago Fallido
Prueba el manejo de fallo de pago:
Usa el monto especial de prueba 666 para simular un pago fallido:
async function testFailedPayment() {
const order = await createPayinOrder(token, orgId, merchantId, {
amount: 666, // Monto especial de prueba para fallo
currency: 'COP',
paymentMethod: 'PSE',
bank: 'BANCOLOMBIA'
});
console.log('Orden creada:', order.id);
// Espera el procesamiento
await sleep(3000);
const updated = await getOrderStatus(token, orgId, merchantId, order.id);
console.log('Estado:', updated.status); // "FAILED"
console.log('Error:', updated.errorMessage);
}Flujo esperado:
PENDING → PROCESSING → FAILEDPago Expirado
Prueba la expiración de orden:
async function testExpiredPayment() {
// Establecer dueDate en el pasado
const pastDate = new Date();
pastDate.setHours(pastDate.getHours() - 1);
const order = await createPayinOrder(token, orgId, merchantId, {
amount: 50000,
currency: 'COP',
paymentMethod: 'PSE',
bank: 'BANCOLOMBIA',
dueDate: pastDate.toISOString()
});
console.log('Estado:', order.status); // "EXPIRED"
}Flujo de Enlace de Pago (PAYMENT_LINK)
Prueba la experiencia completa de checkout de marca Koywe:
PAYMENT_LINK es perfecto para e-commerce! Sin contacto o método de pago necesario - solo crea un enlace y compártelo. El cliente ingresa sus propios datos y selecciona su método de pago en el checkout de Koywe.
async function testPaymentLink() {
// Crear enlace de pago - ¡sin contacto o método de pago necesario!
const order = await axios.post(
`https://api-sandbox.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/orders`,
{
type: 'PAYMENT_LINK',
originCurrencySymbol: 'COP',
destinationCurrencySymbol: 'COP',
amountIn: 50000,
description: 'Factura de Prueba #123 - Diseño Web',
externalId: `test-invoice-${Date.now()}`
},
{ headers: { 'Authorization': `Bearer ${token}` } }
);
console.log('✓ Enlace de pago creado:', order.data.id);
console.log('📧 Comparte este enlace:', order.data.paymentUrl);
console.log('');
console.log('El cliente:');
console.log(' 1. Abre el enlace');
console.log(' 2. Ve checkout de marca Koywe');
console.log(' 3. Ingresa su información personal');
console.log(' 4. Selecciona método de pago (PSE, PIX, Nequi, etc.)');
console.log(' 5. Completa el pago');
// Simular compartir vía email, WhatsApp o código QR
return order.data;
}
// Uso
const link = await testPaymentLink();
// Abre la URL de pago en un navegador para probar el flujo completo de checkout
console.log('\n🌐 Abre esta URL para probar:', link.paymentUrl);def test_payment_link():
# Crear enlace de pago - ¡campos mínimos!
response = requests.post(
f'https://api-sandbox.koywe.com/api/v1/organizations/{org_id}/merchants/{merchant_id}/orders',
json={
'type': 'PAYMENT_LINK',
'originCurrencySymbol': 'COP',
'destinationCurrencySymbol': 'COP',
'amountIn': 50000,
'description': 'Factura de Prueba #123 - Diseño Web'
},
headers={'Authorization': f'Bearer {token}'}
)
order = response.json()
print(f"✓ Enlace de pago creado: {order['id']}")
print(f"📧 Comparte este enlace: {order['paymentUrl']}")
return order
# Uso
link = test_payment_link()
print(f"\n🌐 Abre esta URL para probar: {link['paymentUrl']}")Probando el flujo de checkout:
- Crea el enlace de pago usando el código anterior
- Copia la
paymentUrl - Ábrela en tu navegador
- Verás la página de checkout de marca Koywe
- Completa información de cliente de prueba
- Selecciona un método de pago
- Completa el pago simulado (elige éxito o fallo)
- Verifica que se reciba la notificación webhook
Caso de Uso: PAYMENT_LINK es ideal para:
- Páginas de checkout e-commerce
- Solicitudes de pago de facturas
- Enlaces de pago vía email/WhatsApp
- Pagos con código QR
- Colecciones de pago rápidas sin almacenar datos del cliente
Probar Webhooks
Configurar Endpoint de Webhook
Usa herramientas de prueba de webhooks:
- webhook.site - URL de webhook instantánea
- ngrok - Túnel a localhost
- RequestBin - Inspector de webhooks
Usar webhook.site
Obtener URL de webhook
Visita webhook.site y copia tu URL única
Crear orden con webhook
const order = await createPayinOrder(token, orgId, merchantId, {
amount: 50000,
webhookUrl: 'https://webhook.site/tu-id-unico'
});Ver webhooks
Regresa a webhook.site para ver eventos de webhook en tiempo real
Eventos de Webhook Esperados
Para un PAYIN exitoso:
order.created- Orden es creadaorder.pending- Esperando pagoorder.processing- Pago siendo procesadoorder.paid- Pago confirmadoorder.completed- Fondos acreditados
Ejemplo de Payload de Webhook
{
"id": "evt_abc123",
"type": "order.completed",
"version": "v1",
"occurred_at": "2025-11-13T15:30:00Z",
"source": "koywe.api",
"environment": "sandbox",
"organization_id": "org_xyz",
"merchant_id": "mrc_abc",
"data": {
"orderId": "ord_123456",
"type": "PAYIN",
"status": "COMPLETED",
"amountIn": 50000,
"currencySymbol": "COP"
}
}Datos de Prueba
Contactos de Prueba
Usa estos números de documento de prueba (todos válidos en sandbox):
Colombia
{
"documentType": "CC",
"documentNumber": "1234567890",
"fullName": "Juan Pérez Prueba"
}Brasil
{
"documentType": "CPF",
"documentNumber": "12345678900",
"fullName": "Maria Silva Prueba"
}México
{
"documentType": "RFC",
"documentNumber": "XAXX010101000",
"fullName": "Pedro García Prueba"
}Chile
{
"documentType": "RUT",
"documentNumber": "11111111-1",
"fullName": "Ana López Prueba"
}Cuentas Bancarias de Prueba
Para pruebas de PAYOUT:
Colombia
{
"bankCode": "BANCOLOMBIA",
"accountNumber": "1234567890",
"accountType": "savings",
"currencySymbol": "COP"
}Brasil
{
"bankCode": "BANCO_DO_BRASIL",
"accountNumber": "12345678",
"accountType": "checking",
"currencySymbol": "BRL"
}México
{
"bankCode": "BBVA_MEXICO",
"accountNumber": "012345678901234567",
"accountType": "checking",
"currencySymbol": "MXN"
}Chile
{
"bankCode": "BANCO_CHILE",
"accountNumber": "12345678",
"accountType": "checking",
"currencySymbol": "CLP"
}Probar Operaciones Cripto
Selección Automática de Red de Prueba
Nombres de Red de Producción en Sandbox: Al usar nombres de red de producción como ETHEREUM, POLYGON o BSC en sandbox, el sistema automáticamente redirige a redes de prueba (Sepolia, Amoy, BSC Testnet respectivamente). No necesitas especificar nombres de testnet explícitamente.
Redes de Prueba
Sandbox usa automáticamente estas testnets:
| Red de Producción | Testnet en Sandbox | Activos Soportados |
|---|---|---|
| ETHEREUM | Sepolia | ETH, USDC, USDT |
| POLYGON | Amoy | MATIC, USDC |
| BSC | BSC Testnet | BNB, USDC |
Ejemplo: Especifica "network": "POLYGON" en tu solicitud, y sandbox usará Amoy automáticamente.
Dirección de Billetera de Prueba
Usa esta dirección para recibir cripto de prueba:
0x0000000000000000000000000000000000000000Nunca uses direcciones de producción en sandbox - Siempre usa direcciones de prueba/quema como la dirección cero arriba.
Prueba ONRAMP
async function testOnramp() {
// Crear billetera cripto (o usar existente)
const wallet = await createCryptoWallet(token, orgId, merchantId, {
address: '0x0000000000000000000000000000000000000000',
network: 'ETHEREUM' // Usa Sepolia automáticamente en sandbox
});
// Comprar USDC con COP
const order = await createOrder(token, orgId, merchantId, {
type: 'ONRAMP',
originCurrencySymbol: 'COP',
destinationCurrencySymbol: 'USDC',
amountIn: 50000,
destinationAccountId: wallet.id
});
console.log('Orden ONRAMP:', order.id);
// En sandbox, cripto es "enviado" a dirección de prueba
}Prueba OFFRAMP
async function testOfframp() {
// Vender USDC por COP
const order = await createOrder(token, orgId, merchantId, {
type: 'OFFRAMP',
originCurrencySymbol: 'USDC',
destinationCurrencySymbol: 'COP',
amountIn: 10 // 10 USDC
});
console.log('Orden OFFRAMP:', order.id);
// En sandbox, orden se completa automáticamente
// Fiat se acredita a cuenta virtual
}Límites de Tasa
El entorno sandbox tiene los siguientes límites:
| Tipo de Límite | Valor |
|---|---|
| Solicitudes por minuto | 100 |
| Solicitudes por hora | 1,000 |
| Órdenes por día | 10,000 |
Encabezados de límite de tasa están incluidos en todas las respuestas:
X-RateLimit-Limit: Total de solicitudes permitidasX-RateLimit-Remaining: Solicitudes restantesX-RateLimit-Reset: Timestamp Unix cuando se reinicia el límite
Mejores Prácticas de Prueba
Prueba Todos los Tipos de Orden
Prueba cada tipo de orden:
- ✅ PAYIN con diferentes métodos de pago
- ✅ PAYOUT a diferentes países
- ✅ BALANCE_TRANSFER entre monedas
- ✅ ONRAMP para compras de cripto
- ✅ OFFRAMP para ventas de cripto
- ✅ PAYMENT_LINK con vencimiento
Prueba Escenarios de Error
Prueba manejo de errores:
- ✅ Credenciales API inválidas
- ✅ Saldo insuficiente para PAYOUT
- ✅ Detalles de cuenta bancaria inválidos
- ✅ Cotizaciones expiradas
- ✅ Pagos fallidos (monto: 666)
- ✅ Verificación de firma de webhook
Prueba Idempotencia
async function testIdempotency() {
const externalId = `test-order-${Date.now()}`;
// Crear orden
const order1 = await createPayinOrder(token, orgId, merchantId, {
amount: 50000,
externalId: externalId
});
// Intentar crear la misma orden nuevamente
const order2 = await createPayinOrder(token, orgId, merchantId, {
amount: 50000,
externalId: externalId // Mismo externalId
});
// Debería devolver la misma orden
console.log(order1.id === order2.id); // true
}Flujos de Trabajo de Prueba Comunes
Flujo de Checkout E-Commerce
async function testCheckoutFlow() {
console.log('1. Cliente agrega items al carrito...');
const cartTotal = 50000; // 50,000 COP
console.log('2. Cliente procede al checkout...');
const contact = await createContact(token, orgId, merchantId, {
email: 'prueba@ejemplo.com',
fullName: 'Cliente Prueba',
country: 'CO',
documentType: 'CC',
documentNumber: '1234567890'
});
console.log('3. Obtener métodos de pago...');
const methods = await getPaymentMethods('CO', 'COP');
console.log('4. Crear orden de pago...');
const order = await createPayinOrder(token, orgId, merchantId, {
amount: cartTotal,
currency: 'COP',
contactId: contact.id,
paymentMethod: 'PSE',
bank: 'BANCOLOMBIA',
externalId: `cart-${Date.now()}`
});
console.log('5. Redirigir cliente al pago...');
console.log('URL de Pago:', order.paymentUrl);
console.log('6. Esperar confirmación por webhook...');
// En producción, el manejador de webhook procesa esto
await sleep(5000);
console.log('7. Verificar orden completada...');
const completed = await getOrderStatus(token, orgId, merchantId, order.id);
console.log('Estado final:', completed.status); // "COMPLETED"
console.log('8. Cumplir orden...');
console.log('✅ Flujo de checkout de prueba completo!');
}Simular Ingresos Bancarios (Solo Sandbox)
Algunos flujos — depósitos SPEI, transferencias bancarias directas, ciertos rieles de ARS/MXN — funcionan recibiendo fondos en una cuenta bancaria virtual provisionada para tu merchant. En sandbox no hay transferencias bancarias reales que disparen estos flujos. Usa el simulador de ingresos bancarios para registrar un depósito entrante falso que atraviesa el mismo procesador de ingresos bancarios, igual que lo haría una transferencia real.
POST /api/v1/organizations/{organizationId}/merchants/{merchantId}/sandbox/bank-income/simulateEste endpoint es solo de sandbox. Devuelve un error en producción.
Solicitud
{
"currency": "ARS",
"amount": 500000,
"documentType": "CUIT",
"documentNumber": "30712345678",
"customerReference": "customer-test-001"
}| Campo | Requerido | Descripción |
|---|---|---|
currency | ✓ | ARS, MXN o USD. Selecciona qué cuenta virtual falsa se usa. |
amount | ✓ | Monto a acreditar. |
documentType | Condicional | Tipo de documento del depositante. Requerido para ARS y MXN salvo que la validación esté deshabilitada por flags del merchant. |
documentNumber | Condicional | Número de documento del depositante. Mismas condiciones que documentType. |
customerReference | — | Referencia libre para facilitar el rastreo del movimiento simulado en reportes. |
Respuesta
{
"referenceId": "bm_1234567890",
"virtualAccount": { /* PayInVirtualBankAccount */ },
"virtualAccountProvisioned": true
}referenceId— ID del ingreso bancario registrado, usable para conciliación.virtualAccount— Cuenta virtual en la que aterrizó el depósito. Si el merchant no tenía una para esta moneda, el simulador la provisiona al momento.virtualAccountProvisioned—truela primera vez que se tuvo que crear una cuenta virtual para esa moneda;falseen llamadas posteriores.
Ejemplo
async function simularDepositoSandbox() {
const response = await axios.post(
`https://api-sandbox.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/sandbox/bank-income/simulate`,
{
currency: 'ARS',
amount: 500000,
documentType: 'CUIT',
documentNumber: '30712345678',
customerReference: `test-${Date.now()}`
},
{ headers: { Authorization: `Bearer ${token}` } }
);
console.log('Depósito simulado:', response.data.referenceId);
console.log('Acreditado en VA:', response.data.virtualAccount.accountNumber);
}Casos de uso:
- Financiar un merchant de sandbox para probar PAYOUT, BALANCE_TRANSFER u OFFRAMP sin pasar antes por todo un flujo de PAYIN.
- Reproducir casos límite de ingresos bancarios (depositante desconocido, documento que no coincide) variando los campos de documento.
- Hacer smoke tests de pipelines de conciliación que consumen eventos de ingresos bancarios.
Pasar a Producción
Cuando estés listo para ir en vivo:
Solicitar Credenciales de Producción
Contacta a soporte@koywe.com para credenciales de producción API key y secret
Actualizar URL Base
Cambiar de sandbox a producción:
// Sandbox
const BASE_URL = 'https://api-sandbox.koywe.com';
// Producción
const BASE_URL = 'https://api.koywe.com';Actualizar Credenciales
Reemplaza credenciales de sandbox con credenciales de producción en tus variables de entorno
Actualizar URLs de Webhook
Cambiar endpoints de webhook de URLs de prueba a URLs de producción
Probar con Montos Pequeños
Comienza con transacciones reales pequeñas para verificar que todo funciona
Monitorear de Cerca
Observa tus primeras transacciones de producción cuidadosamente
Configurar Monitoreo
Implementa logging, alertas y monitoreo para producción
Lista de Verificación de Producción
- Credenciales de producción API obtenidas
- URL base actualizada a producción
- URLs de webhook apuntando a servidores de producción
- Verificación de firma de webhook implementada
- Manejo de errores probado
- Logging y monitoreo configurado
- Transacción de prueba pequeña exitosa
- Equipo capacitado en procesos de producción