Koywe
En esta página

Cuentas Externas del Comercio

Configura las cuentas bancarias externas y billeteras cripto de tu comercio para recibir fondos de liquidaciones de cuenta virtual y compras de criptomonedas.

¿Qué son las Cuentas Externas del Comercio?

Las Cuentas Externas del Comercio son las cuentas bancarias y billeteras cripto propias de tu organización donde recibes fondos de las operaciones de Koywe.

Tipos de Cuentas Externas

Cuentas Bancarias Externas

Tus cuentas bancarias empresariales para recibir liquidaciones fiat y retiros

Billeteras Cripto Externas

Tus direcciones de billetera cripto para recibir criptomonedas de deals ONRAMP


Cuentas Bancarias Externas vs Cuentas Virtuales

Entendiendo la diferencia:

CaracterísticaCuenta VirtualCuenta Bancaria Externa
UbicaciónDentro de KoyweTu propio banco
PropósitoOperaciones y transaccionesDestino de liquidación final
ConfiguraciónAutomáticaConfiguración manual
UsoPAYINs, PAYOUTs, transferenciasRetiros, liquidaciones
MonedasMúltiples soportadasEspecíficas del banco
ComisionesNinguna para ops internasPuede tener comisiones de transferencia
Dibujando diagrama…

Liquidación Automática: Los fondos en cuentas virtuales se liquidan automáticamente a tu cuenta bancaria externa registrada después de un período configurado (típicamente 1-7 días). También puedes solicitar retiros manualmente.


Configuración de Cuentas Bancarias Externas

Cuándo Necesitas una Cuenta Bancaria Externa

✅ Requerido para:

  • Recibir liquidaciones automáticas de cuentas virtuales
  • Retirar fondos de saldos virtuales
  • Recibir pagos del comercio
  • Cumplimiento y verificación

Creando una Cuenta Bancaria Externa

Asociación Automática: Las cuentas bancarias se asocian automáticamente con la información comercial registrada de tu comercio. No es necesario enviar nombre del titular o números de documento - usamos la información ya en el sistema.

Endpoint Unificado: Tanto las cuentas bancarias como las billeteras cripto usan el mismo endpoint /accounts. El campo kind determina el tipo de cuenta: "BANK" para cuentas bancarias fiat, "CRYPTO" para billeteras cripto.

async function addMerchantBankAccount(token, orgId, merchantId) {
  const response = await axios.post(
    `https://api-sandbox.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/accounts`,
    {
      name: 'Cuenta de Liquidación Empresa',
      kind: 'BANK',                    // Indica que es una cuenta bancaria fiat
      countrySymbol: 'CO',
      currencySymbol: 'COP',
      entity: 'BANCOLOMBIA',           // Código del banco
      accountNumber: '1234567890',
      type: 'CHECKING',                // o 'SAVINGS'
      isDefault: true,                 // Establecer como cuenta de liquidación predeterminada
      isVirtual: false                 // Cuenta externa (no administrada por Koywe)
    },
    { headers: { 'Authorization': `Bearer ${token}` } }
  );
  
  console.log('Cuenta bancaria agregada:', response.data.id);
  console.log('Estado:', response.data.status);
  
  return response.data;
}
 
const bankAccount = await addMerchantBankAccount(token, orgId, merchantId);

Campos Requeridos por País

Flexibilidad del Código Bancario: Para la mayoría de los países, el código bancario puede deducirse del número de cuenta. Aún puedes proporcionarlo, pero la API validará contra el valor deducido. Para países donde es requerido, la validación asegura que el banco esté en la lista soportada.

Chile 🇨🇱

JavaScript
{
  name: 'Cuenta Liquidación Chile',
  kind: 'BANK',
  countrySymbol: 'CL',
  currencySymbol: 'CLP',
  entity: 'BANCO_CHILE',          // Requerido: BANCO_CHILE, BCI, SANTANDER_CHILE, etc.
  accountNumber: '12345678',      // Requerido
  isDefault: true,
  isVirtual: false
}

Validaciones: El código bancario (entity) debe estar en la lista de bancos válidos.


Colombia 🇨🇴

JavaScript
{
  name: 'Cuenta Liquidación Colombia',
  kind: 'BANK',
  countrySymbol: 'CO',
  currencySymbol: 'COP',
  entity: 'BANCOLOMBIA',          // Requerido: BANCOLOMBIA, DAVIVIENDA, BOGOTA, etc.
  accountNumber: '1234567890',    // Requerido
  type: 'CHECKING',               // Requerido: 'CHECKING' o 'SAVINGS'
  rail: 'BANK',                   // Opcional: declara que accountNumber es una cuenta bancaria y no una llave Bre-B
  isDefault: true,
  isVirtual: false
}

Validaciones: El tipo de cuenta debe ser soportado por el banco. Longitud del número de cuenta validada (mín/máx).

Bre-B: Colombia opera dos rieles. Para usar una llave Bre-B como destino, pon la llave en accountNumber y envía rail: 'BREB'. Eso omite toda la validación del número contra el catálogo de bancos — banco encontrado (BAA00019), tipo de cuenta soportado por ese banco (BAA00020), longitud del número (BAA00021) —, porque una llave no tiene banco. También te exime de entity y type, que una llave tampoco tiene: si los omites, el destino queda con entity: "UNKNOWN_BANK" y type: "VIRTUAL"; si los envías, se guardan tal cual sin validarse. El campo sigue siendo opcional, pero sin él la llave se valida como número de cuenta — normalmente se rechaza, y cuando su longitud coincide queda guardada como cuenta bancaria, que después se liquida por el riel bancario. Ver Rieles de Pago.


Brasil 🇧🇷

JavaScript
{
  name: 'Cuenta Liquidación Brasil',
  kind: 'BANK',
  countrySymbol: 'BR',
  currencySymbol: 'BRL',
  accountNumber: '12345-6',       // Requerido (O pixKey)
  // entity: '001'                // Opcional (deducido de accountNumber)
  isDefault: true,
  isVirtual: false
}

Validaciones: Código bancario deducido del número de cuenta. PIX key puede usarse en lugar del número de cuenta. Una llave Pix con CNPJ alfanumérico no se reconoce todavía: ver Métodos de pago.


México 🇲🇽

JavaScript
{
  name: 'Cuenta Liquidación México',
  kind: 'BANK',
  countrySymbol: 'MX',
  currencySymbol: 'MXN',
  accountNumber: '012345678901234567',  // Requerido: CLABE (18 dígitos)
  // entity: 'BBVA_MEXICO'              // Opcional (deducido de accountNumber)
  isDefault: true,
  isVirtual: false
}

Validaciones: Validación formato CLABE (18 dígitos). Validación dígito verificador. Banco deducido de CLABE.


Argentina 🇦🇷

JavaScript
{
  name: 'Cuenta Liquidación Argentina',
  kind: 'BANK',
  countrySymbol: 'AR',
  currencySymbol: 'ARS',
  accountNumber: '0123456789012345678901',  // Requerido: CVU o CBU o alias
  // entity: 'BANCO_NACION'                 // Opcional (deducido de accountNumber)
  isDefault: true,
  isVirtual: false
}

Validaciones: Validación formato CVU/CBU. Validación dígito verificador. Banco deducido del número de cuenta. Alias soportado.


Perú 🇵🇪

JavaScript
{
  name: 'Cuenta Liquidación Perú',
  kind: 'BANK',
  countrySymbol: 'PE',
  currencySymbol: 'PEN',
  accountNumber: '01234567890123456789',  // Requerido: formato CCI
  // entity: 'BCP'                        // Opcional (deducido de accountNumber)
  isDefault: true,
  isVirtual: false
}

Validaciones: Validación formato CCI (20 dígitos). Banco deducido del número de cuenta.


Bolivia 🇧🇴

JavaScript
{
  name: 'Cuenta Liquidación Bolivia',
  kind: 'BANK',
  countrySymbol: 'BO',
  currencySymbol: 'BOB',
  accountNumber: '1234567890',  // Requerido
  // entity: 'BNB'              // Opcional (deducido de accountNumber)
  isDefault: true,
  isVirtual: false
}

Validaciones: Banco deducido del número de cuenta.


Estados Unidos 🇺🇸

JavaScript
{
  name: 'Cuenta Liquidación EEUU',
  kind: 'BANK',
  countrySymbol: 'US',
  currencySymbol: 'USD',
  accountNumber: '123456789',      // Requerido
  routingNumber: '021000021',      // Requerido
  // entity: 'CHASE'               // Opcional (deducido de routingNumber)
  isDefault: true,
  isVirtual: false
}

Validaciones: Banco deducido del routing number. Banco genérico guardado si no se encuentra.

Proceso de Verificación

  1. Cuenta Creada

    La cuenta bancaria externa se crea con estado PENDING_VERIFICATION

  2. Microdepósito Enviado (si es requerido)

    Koywe puede enviar un pequeño depósito de prueba para verificar la propiedad de la cuenta

  3. Verificación Completada

    Verificas el monto del depósito o la cuenta se auto-verifica

  4. Cuenta Activada

    El estado cambia a VERIFIED y está lista para liquidaciones

Verificación Automática: La cuenta bancaria se vincula automáticamente con la información comercial registrada de tu comercio. Asegúrate de que tu perfil de comercio tenga el nombre legal correcto y el ID fiscal, ya que se usarán para la verificación de cuenta.

Listando Cuentas Bancarias del Comercio

JavaScript
async function getMerchantBankAccounts(token, orgId, merchantId) {
  const response = await axios.get(
    `https://api-sandbox.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/accounts`,
    {
      params: { kind: 'BANK' },  // Filtrar solo cuentas bancarias
      headers: { 'Authorization': `Bearer ${token}` }
    }
  );
  
  console.log('Cuentas bancarias externas:');
  response.data.forEach(account => {
    console.log(`- ${account.currencySymbol}: ${account.entity} ****${account.accountNumber.slice(-4)}`);
    console.log(`  Predeterminada: ${account.isDefault}, Estado: ${account.status}`);
  });
  
  return response.data;
}
 
const accounts = await getMerchantBankAccounts(token, orgId, merchantId);

Configuración de Billeteras Cripto Externas

Cuándo Necesitas una Billetera Cripto Externa

✅ Requerido para:

  • Recibir criptomoneda de deals ONRAMP
  • Enviar cripto a tus propias soluciones de custodia
  • Tenencias cripto a largo plazo fuera de Koywe

Billeteras Integradas vs Externas: Las billeteras integradas gestionadas por Koywe se provisionan con el flujo de passkeys (/webauthn/wallet/prepare y /webauthn/wallet/complete) — ver Passkeys y Aprobaciones. Las billeteras externas son TUS PROPIAS billeteras en dispositivos hardware, exchanges, u otras soluciones de custodia donde quieres recibir cripto, y las registras tú mismo con las llamadas de abajo.

Agregando una Billetera Cripto Externa

Mismo Endpoint que Cuentas Bancarias: Las billeteras cripto externas usan el mismo endpoint /accounts que las cuentas bancarias. Establece kind: "CRYPTO" para crear una billetera cripto en lugar de una cuenta bancaria.

async function addExternalCryptoWallet(token, orgId, merchantId, walletData) {
  const response = await axios.post(
    `https://api-sandbox.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/accounts`,
    {
      name: walletData.name,                 // ej., "Billetera Ledger Empresa"
      kind: 'CRYPTO',                        // Indica que es una billetera cripto
      currencySymbol: walletData.currency,   // USDC, USDT, BTC, ETH, etc.
      network: walletData.network,           // ETHEREUM, POLYGON, BITCOIN, etc.
      address: walletData.address,           // Tu dirección de billetera
      isDefault: walletData.isDefault || false,
      isVirtual: false                       // Billetera externa (no administrada por Koywe)
    },
    { headers: { 'Authorization': `Bearer ${token}` } }
  );
  
  console.log('Billetera externa agregada:', response.data.id);
  console.log('Dirección:', response.data.address);
  console.log('Red:', response.data.network);
  
  return response.data;
}
 
// Ejemplo: Agregar USDC en Ethereum
const usdcWallet = await addExternalCryptoWallet(token, orgId, merchantId, {
  name: 'Ledger Empresa - USDC',
  currency: 'USDC',
  network: 'ETHEREUM',
  address: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb2',
  isDefault: true
});
 
console.log('Billetera USDC registrada para operaciones ONRAMP');

Redes y Monedas Soportadas

MonedaNombreRedes
USDTTetherETHEREUM · POLYGON · SOLANA · BASE · ALGORAND · TRON · BSC
USDCUSD CoinETHEREUM · POLYGON · SOLANA · BASE · ALGORAND
ETHEtherETHEREUM · BASE
BTCBitcoinBITCOIN
EURCEuro CoinBASE
MATICPolygonPOLYGON
SOLSolanaSOLANA
TRXTronTRON

Solo estos pares son válidos. Cualquier otra combinación de símbolo y red es rechazada por la API.

Coincidencia de Red Crítica: Al crear deals ONRAMP, el parámetro network debe coincidir con una de las redes de billeteras externas registradas. ¡Siempre verifica la red antes de enviar cripto!

Listando Billeteras Cripto Externas

JavaScript
async function getExternalWallets(token, orgId, merchantId) {
  const response = await axios.get(
    `https://api-sandbox.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/accounts`,
    {
      params: { kind: 'CRYPTO' },  // Filtrar solo billeteras cripto
      headers: { 'Authorization': `Bearer ${token}` }
    }
  );
  
  console.log('Billeteras cripto externas:');
  response.data.forEach(wallet => {
    console.log(`- ${wallet.currencySymbol} (${wallet.network})`);
    console.log(`  Dirección: ${wallet.address}`);
    console.log(`  Predeterminada: ${wallet.isDefault}, Estado: ${wallet.status}`);
  });
  
  return response.data;
}
 
const wallets = await getExternalWallets(token, orgId, merchantId);

Usando Cuentas Externas en Operaciones

ONRAMP: Enviar Cripto a Billetera Externa

Al crear deals ONRAMP, especifica tu billetera externa como destino:

JavaScript
// 1. Obtener cotización
const quote = await axios.post(
  `https://api-sandbox.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/quotes`,
  {
    orderType: 'ONRAMP',
    executable: true,
    originCurrencySymbol: 'COP',
    destinationCurrencySymbol: 'USDC',
    amountIn: 1000000,  // 1M COP
    network: 'ETHEREUM'  // Requerido para ONRAMP/OFFRAMP
  },
  { headers: { 'Authorization': `Bearer ${token}` } }
);
 
// 2. Crear deal con billetera externa como destino
const deal = await axios.post(
  `https://api-sandbox.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/deals`,
  {
    destinationAccountId: usdcWallet.id,  // Tu ID de billetera externa
    quoteId: quote.data.id
  },
  { headers: { 'Authorization': `Bearer ${token}` } }
);
 
console.log('Deal ONRAMP creado');
console.log('Cripto se enviará a:', usdcWallet.address);
console.log('Red:', usdcWallet.network);

Usar Integradas vs Externas: Para cripto operacional (trading frecuente, OFFRAMP), usa billeteras integradas. Para tenencias a largo plazo o requisitos específicos de custodia, usa billeteras externas.

Retiros: Mover Fondos a Cuenta Bancaria Externa

Solicita retiro de cuenta virtual a tu cuenta bancaria externa:

JavaScript
async function withdrawToExternalBank(token, orgId, merchantId, withdrawalData) {
  // Verificar saldo de cuenta virtual primero
  const balances = await axios.get(
    `https://api-sandbox.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/accounts/balances`,
    { headers: { 'Authorization': `Bearer ${token}` } }
  );
  
  const copBalance = balances.data.find(b => b.currencySymbol === 'COP');
  
  if (copBalance.availableBalance < withdrawalData.amount) {
    throw new Error('Saldo insuficiente para retiro');
  }
  
  // Crear orden de retiro
  const withdrawal = await axios.post(
    `https://api-sandbox.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/withdrawals`,
    {
      currency: 'COP',
      amount: withdrawalData.amount,
      destinationAccountId: withdrawalData.bankAccountId,  // Tu cuenta bancaria externa
      description: 'Retiro a cuenta empresarial'
    },
    { headers: { 'Authorization': `Bearer ${token}` } }
  );
  
  console.log('Retiro iniciado:', withdrawal.data.id);
  console.log('Monto:', withdrawal.data.amount, 'COP');
  console.log('Estado:', withdrawal.data.status); // "PROCESSING"
  console.log('Tiempo estimado:', withdrawal.data.estimatedSettlement);
  
  return withdrawal.data;
}
 
const withdrawal = await withdrawToExternalBank(token, orgId, merchantId, {
  amount: 5000000,  // 5M COP
  bankAccountId: bankAccount.id
});

Liquidaciones Automáticas: Si tienes liquidaciones automáticas habilitadas, los fondos se transferirán a tu cuenta bancaria externa primaria automáticamente después del período de retención configurado. Los retiros manuales te dan más control sobre el tiempo.


Mejores Prácticas

Seguridad

Verificar Direcciones

Siempre verifica dos veces las direcciones de billetera cripto antes de agregarlas. Los errores son irreversibles.

Usar Montos de Prueba

Envía transacciones de prueba pequeñas a nuevas billeteras externas antes de transferencias grandes.

Monitorear Webhooks

Configura webhooks para rastrear liquidaciones y retiros a cuentas externas.

Mantener Registros

Mantén registros de todas las cuentas externas para cumplimiento y auditoría.

Gestión de Cuentas

✅ Hacer:

  • Mantener cuentas primarias actualizadas
  • Verificar nuevas cuentas inmediatamente
  • Usar billeteras separadas por red
  • Documentar propósitos de cuentas internamente

❌ No hacer:

  • Compartir credenciales de cuenta
  • Usar direcciones de depósito de exchange como billeteras externas (usar direcciones de retiro)
  • Agregar billeteras no verificadas o de prueba en producción
  • Usar cuentas personales para operaciones comerciales

Patrones Comunes

Configuración Multi-Moneda

Para negocios que operan en múltiples países:

JavaScript
// Configurar cuentas bancarias externas para cada moneda
const copAccount = await axios.post(
  `https://api-sandbox.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/accounts`,
  {
    name: 'Bancolombia COP',
    kind: 'BANK',
    isDefault: true,
    countrySymbol: 'CO',
    currencySymbol: 'COP',
    entity: 'BANCOLOMBIA',
    accountNumber: '1234567890',
    type: 'CHECKING'
  },
  { headers: { 'Authorization': `Bearer ${token}` } }
);
 
const brlAccount = await axios.post(
  `https://api-sandbox.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/accounts`,
  {
    name: 'Brazil BRL',
    kind: 'BANK',
    isDefault: false,
    countrySymbol: 'BR',
    currencySymbol: 'BRL',
    accountNumber: '12345-6'  // Banco deducido automáticamente
  },
  { headers: { 'Authorization': `Bearer ${token}` } }
);
 
const mxnAccount = await axios.post(
  `https://api-sandbox.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/accounts`,
  {
    name: 'Mexico MXN',
    kind: 'BANK',
    isDefault: false,
    countrySymbol: 'MX',
    currencySymbol: 'MXN',
    accountNumber: '012345678901234567'  // CLABE - banco deducido
  },
  { headers: { 'Authorization': `Bearer ${token}` } }
);
 
console.log('Cuentas externas multi-moneda configuradas');
console.log('Todas las cuentas auto-vinculadas a la información comercial del comercio');

Configuración Cripto Multi-Red

Para tenencias cripto diversificadas:

JavaScript
// USDC en múltiples redes
const usdcEthereum = await addExternalCryptoWallet(token, orgId, merchantId, {
  name: 'USDC - Ethereum Principal',
  currency: 'USDC',
  network: 'ETHEREUM',
  address: '0x...',
  isDefault: true
});
 
const usdcPolygon = await addExternalCryptoWallet(token, orgId, merchantId, {
  name: 'USDC - Polygon Comisiones Bajas',
  currency: 'USDC',
  network: 'POLYGON',
  address: '0x...',
  isDefault: false
});
 
// Diferentes stablecoins
const usdtTron = await addExternalCryptoWallet(token, orgId, merchantId, {
  name: 'USDT - Tron',
  currency: 'USDT',
  network: 'TRON',
  address: 'T...',
  isDefault: false
});
 
console.log('Billeteras externas multi-red configuradas');

Próximos Pasos