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
Tus cuentas bancarias empresariales para recibir liquidaciones fiat y retiros
Tus direcciones de billetera cripto para recibir criptomonedas de deals ONRAMP
Cuentas Bancarias Externas vs Cuentas Virtuales
Entendiendo la diferencia:
| Característica | Cuenta Virtual | Cuenta Bancaria Externa |
|---|---|---|
| Ubicación | Dentro de Koywe | Tu propio banco |
| Propósito | Operaciones y transacciones | Destino de liquidación final |
| Configuración | Automática | Configuración manual |
| Uso | PAYINs, PAYOUTs, transferencias | Retiros, liquidaciones |
| Monedas | Múltiples soportadas | Específicas del banco |
| Comisiones | Ninguna para ops internas | Puede tener comisiones de transferencia |
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);def add_merchant_bank_account(token, org_id, merchant_id):
response = requests.post(
f'https://api-sandbox.koywe.com/api/v1/organizations/{org_id}/merchants/{merchant_id}/accounts',
headers={'Authorization': f'Bearer {token}'},
json={
'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 predeterminada
'isVirtual': False # Cuenta externa (no administrada por Koywe)
}
)
response.raise_for_status()
bank_account = response.json()
print(f'Cuenta bancaria agregada: {bank_account["id"]}')
print(f'Estado: {bank_account["status"]}')
return bank_account
bank_account = add_merchant_bank_account(token, org_id, merchant_id)curl -X POST https://api-sandbox.koywe.com/api/v1/organizations/{orgId}/merchants/{merchantId}/accounts \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Cuenta de Liquidación Empresa",
"kind": "BANK",
"countrySymbol": "CO",
"currencySymbol": "COP",
"entity": "BANCOLOMBIA",
"accountNumber": "1234567890",
"type": "CHECKING",
"isDefault": true,
"isVirtual": false
}'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 🇨🇱
{
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 🇨🇴
{
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'
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).
Brasil 🇧🇷
{
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.
México 🇲🇽
{
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 🇦🇷
{
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ú 🇵🇪
{
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 🇧🇴
{
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 🇺🇸
{
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
Cuenta Creada
La cuenta bancaria externa se crea con estado PENDING_VERIFICATION
Microdepósito Enviado (si es requerido)
Koywe puede enviar un pequeño depósito de prueba para verificar la propiedad de la cuenta
Verificación Completada
Verificas el monto del depósito o la cuenta se auto-verifica
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
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: Koywe proporciona billeteras integradas automáticamente (vía endpoint /wallet). Las billeteras externas son TUS PROPIAS billeteras en dispositivos hardware, exchanges, u otras soluciones de custodia donde quieres recibir cripto.
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');def add_external_crypto_wallet(token, org_id, merchant_id, wallet_data):
response = requests.post(
f'https://api-sandbox.koywe.com/api/v1/organizations/{org_id}/merchants/{merchant_id}/accounts',
headers={'Authorization': f'Bearer {token}'},
json={
'name': wallet_data['name'],
'kind': 'CRYPTO', # Indica que es una billetera cripto
'currencySymbol': wallet_data['currency'],
'network': wallet_data['network'],
'address': wallet_data['address'],
'isDefault': wallet_data.get('is_default', False),
'isVirtual': False # Billetera externa (no administrada por Koywe)
}
)
response.raise_for_status()
wallet = response.json()
print(f'Billetera externa agregada: {wallet["id"]}')
print(f'Dirección: {wallet["address"]}')
print(f'Red: {wallet["network"]}')
return wallet
# Ejemplo: Agregar USDT en Polygon
usdt_wallet = add_external_crypto_wallet(token, org_id, merchant_id, {
'name': 'Custodia Empresa - USDT',
'currency': 'USDT',
'network': 'POLYGON',
'address': '0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063',
'is_default': True
})
print('Billetera USDT registrada para operaciones ONRAMP')Redes y Monedas Soportadas
| Moneda | Redes Soportadas | Notas |
|---|---|---|
| USDC | Ethereum, Polygon, BSC | Stablecoin más popular |
| USDT | Ethereum, Polygon, BSC, Tron | Soporte multi-cadena |
| ETH | Ethereum | Ethereum nativo |
| BTC | Bitcoin | Solo Bitcoin mainnet |
| MATIC | Polygon | Polygon nativo |
| BNB | BSC | BSC nativo |
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
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:
// 1. Obtener cotización
const quote = await axios.post(
`https://api-sandbox.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/quotes`,
{
type: 'ONRAMP',
originCurrencySymbol: 'COP',
destinationCurrencySymbol: 'USDC',
amountIn: 1000000, // 1M COP
network: 'ETHEREUM'
},
{ 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`,
{
type: 'ONRAMP',
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:
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
Siempre verifica dos veces las direcciones de billetera cripto antes de agregarlas. Los errores son irreversibles.
Envía transacciones de prueba pequeñas a nuevas billeteras externas antes de transferencias grandes.
Configura webhooks para rastrear liquidaciones y retiros a cuentas externas.
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:
// Configurar cuentas bancarias externas para cada moneda
const copAccount = await axios.post(
`https://api-sandbox.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/accounts`,
{
country: 'CO',
currency: 'COP',
bankCode: 'BANCOLOMBIA',
accountNumber: '1234567890',
accountType: 'checking',
isPrimary: true
},
{ headers: { 'Authorization': `Bearer ${token}` } }
);
const brlAccount = await axios.post(
`https://api-sandbox.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/accounts`,
{
country: 'BR',
currency: 'BRL',
accountNumber: '12345-6', // Banco deducido automáticamente
isPrimary: false
},
{ headers: { 'Authorization': `Bearer ${token}` } }
);
const mxnAccount = await axios.post(
`https://api-sandbox.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/accounts`,
{
country: 'MX',
currency: 'MXN',
accountNumber: '012345678901234567', // CLABE - banco deducido
isPrimary: false
},
{ 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:
// USDC en múltiples redes
const usdcEthereum = await addExternalCryptoWallet(token, orgId, merchantId, {
name: 'USDC - Ethereum Principal',
currency: 'USDC',
network: 'ETHEREUM',
address: '0x...',
isPrimary: true
});
const usdcPolygon = await addExternalCryptoWallet(token, orgId, merchantId, {
name: 'USDC - Polygon Comisiones Bajas',
currency: 'USDC',
network: 'POLYGON',
address: '0x...',
isPrimary: false
});
// Diferentes stablecoins
const usdtTron = await addExternalCryptoWallet(token, orgId, merchantId, {
name: 'USDT - Tron',
currency: 'USDT',
network: 'TRON',
address: 'T...',
isPrimary: false
});
console.log('Billeteras externas multi-red configuradas');