En esta página
- ¿Qué son los Contactos?
- ¿Por qué Usar Contactos?
- Estructura de Contacto
- Campos Requeridos
- Campos Opcionales
- Crear Contactos
- Creación Básica de Contacto
- Tipos de Documento por País
- Colombia (CO)
- Brasil (BR)
- México (MX)
- Chile (CL)
- Argentina (AR)
- Perú (PE)
- Bolivia (BO)
- Venezuela (VE)
- Estados Unidos (US)
- Cuentas Bancarias
- Vincular Cuentas Bancarias a Contactos
- Campos Opcionales con Valores por Defecto
- Campos Requeridos por País
- Recuperar Contactos
- Listar Todos los Contactos
- Obtener Contacto Específico
- Obtener Cuentas Bancarias del Contacto
- Actualizar Contactos
- Requisitos de Validación
- Persona vs Empresa
- Formatos de Número de Documento
- Mejores Prácticas
- Cuándo Crear Contactos
- Reutilizar Contactos
- Privacidad de Datos
- Escenarios Comunes
- Escenario 1: Pago de Cliente E-Commerce
- Escenario 2: Pago a Proveedor
- Próximos Pasos
Contactos y Cuentas Bancarias
Los Contactos representan a tus clientes o proveedores en el sistema Koywe, almacenando su información y cuentas bancarias vinculadas para operaciones de pago.
¿Qué son los Contactos?
Un Contacto es una persona o entidad comercial con la que interactúas a través de pagos:
- Clientes que te pagan (PAYIN)
- Proveedores a los que tú pagas (PAYOUT)
- Ambos en escenarios de marketplace
¿Por qué Usar Contactos?
Rastrea el historial de pagos por cliente o proveedor
Almacena información KYC/cumplimiento (documentos, IDs fiscales)
Vincula cuentas bancarias para pagos recurrentes fáciles
Genera reportes por contacto o tipo de negocio
Estructura de Contacto
Campos Requeridos
{
"firstName": "Juan", // Nombre
"countrySymbol": "CO", // Código de país
"businessType": "PERSON", // PERSON, COMPANY, etc.
"type": "PERSON" // PERSON, BUSINESS, GOVERNMENT, NGO, FOREIGN
}Campos Opcionales
{
"lastName": "Pérez", // Apellido
"email": "cliente@ejemplo.com", // Correo electrónico
"phone": "+573001234567", // Número de teléfono
"documentType": "CED_CIU", // Tipo de documento de ID (ver Tipos de Documento por País). Para "BR" se exige un CPF o CNPJ: envíalo aquí o en documents[]
"documentNumber": "1234567890", // Número de documento de ID (requerido si se provee documentType)
"taxIdType": "NIT", // Tipo de ID fiscal (deprecado, usar documentType)
"taxIdNumber": "9001234561", // Número de ID fiscal (deprecado, usar documentNumber)
"addressLine1": "Calle 123", // Dirección
"city": "Bogotá", // Ciudad
"state": "Cundinamarca", // Departamento / estado
"postalCode": "110111" // Código postal
}Crear Contactos
Creación Básica de Contacto
async function createContact(token, orgId, merchantId, contactData) {
const response = await axios.post(
`https://api-sandbox.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/contacts`,
{
firstName: contactData.firstName,
lastName: contactData.lastName, // Opcional
email: contactData.email, // Opcional
phone: contactData.phone, // Opcional
countrySymbol: contactData.countrySymbol,
documentType: contactData.documentType, // Opcional
documentNumber: contactData.documentNumber, // Opcional (requerido si se provee documentType)
businessType: 'PERSON', // o 'COMPANY'
type: 'PERSON' // PERSON, BUSINESS, GOVERNMENT, NGO, FOREIGN
},
{
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
}
);
return response.data;
}
// Uso - Crear contacto de cliente
const customer = await createContact(token, orgId, merchantId, {
firstName: 'Juan',
lastName: 'Pérez',
countrySymbol: 'CO',
email: 'cliente@ejemplo.com',
phone: '+573001234567',
documentType: 'CED_CIU',
documentNumber: '1234567890'
});
console.log('Contacto creado:', customer.id);def create_contact(token, org_id, merchant_id, contact_data):
response = requests.post(
f'https://api-sandbox.koywe.com/api/v1/organizations/{org_id}/merchants/{merchant_id}/contacts',
json={
'firstName': contact_data['first_name'],
'lastName': contact_data.get('last_name'), # Opcional
'email': contact_data.get('email'), # Opcional
'phone': contact_data.get('phone'), # Opcional
'countrySymbol': contact_data['country'],
'documentType': contact_data.get('document_type'), # Opcional
'documentNumber': contact_data.get('document_number'),# Opcional (requerido si se provee documentType)
'businessType': 'PERSON',
'type': 'PERSON'
},
headers={
'Authorization': f'Bearer {token}',
'Content-Type': 'application/json'
}
)
return response.json()
# Uso
customer = create_contact(token, org_id, merchant_id, {
'first_name': 'Juan',
'last_name': 'Pérez',
'email': 'cliente@ejemplo.com',
'phone': '+573001234567',
'country': 'CO',
'document_type': 'CED_CIU',
'document_number': '1234567890'
})curl -X POST 'https://api-sandbox.koywe.com/api/v1/organizations/TU_ORG_ID/merchants/TU_MERCHANT_ID/contacts' \
-H 'Authorization: Bearer TU_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"firstName": "Juan",
"lastName": "Pérez",
"email": "cliente@ejemplo.com",
"phone": "+573001234567",
"countrySymbol": "CO",
"documentType": "CED_CIU",
"documentNumber": "1234567890",
"businessType": "PERSON",
"type": "PERSON"
}'Respuesta:
{
"id": "cnt_abc123",
"firstName": "Juan",
"lastName": "Pérez",
"email": "cliente@ejemplo.com",
"phone": "+573001234567",
"countrySymbol": "CO",
"documentType": "CED_CIU",
"documentNumber": "1234567890",
"businessType": "PERSON",
"createdAt": "2025-11-13T10:00:00Z",
"merchantId": "mrc_xyz789"
}Tipos de Documento por País
Colombia (CO)
En documentType se envía el código de la tabla, no la sigla con la que se conoce el documento en Colombia (CC, CE). Si envías CC o CE, la API responde con error 400.
| Tipo de Documento | Sigla común | Código (documentType) | Descripción | Ejemplo |
|---|---|---|---|---|
| Cédula de Ciudadanía | CC | CED_CIU | ID Nacional | 1234567890 |
| Cédula de Extranjería | CE | CED_EXT | ID Extranjero | 1234567 |
| Número de Identificación Tributaria | NIT | NIT | ID Fiscal (empresas) | 9001234561 o 900.123.456-1 |
Formato del NIT: se acepta con 10 dígitos seguidos (9001234561) o con puntos y guión (900.123.456-1). Ambos incluyen el dígito de verificación.
El catálogo de Colombia también incluye RC (Registro civil), NOP (NIT de otro país), PP (Pasaporte) y DIE (Documento de identificación extranjero), pero hoy no se aceptan al crear contactos de Colombia: la API responde Document type not supported for the specified country. Puedes consultar el catálogo completo con GET /api/v1/documents?countrySymbol=CO.
Brasil (BR)
| Tipo de Documento | Código | Descripción | Ejemplo |
|---|---|---|---|
| CPF | CPF | ID Fiscal Individual | 123.456.789-09 |
| CNPJ | CNPJ | ID Fiscal de Empresa (numérico o alfanumérico) | 12.345.678/0001-95 · 12.ABC.345/01DE-35 |
Documento obligatorio
Los contactos con countrySymbol: "BR" tienen que incluir un CPF (persona) o un CNPJ (empresa). Los proveedores de Brasil rechazan el pago si el contacto no tiene documento, así que la API lo valida al crear el contacto.
- Al crear: siempre es obligatorio. Puedes enviarlo en
documentType/documentNumbero como una entrada dedocuments[]. - Al editar: solo se valida si la actualización cambia el país o el documento. Los contactos de Brasil que ya existen sin documento se pueden seguir editando en otros campos.
- La regla usa el país del contacto (
countrySymbol), no su nacionalidad.
Si falta el documento, la API responde 400 con el código CT00048. Consulta el Catálogo de Códigos de Error.
Formato de los documentos
- CPF: 11 dígitos, con o sin formato (
123.456.789-09). - CNPJ: 14 caracteres, con o sin formato (
AA.AAA.AAA/AAAA-DV). Los primeros 12 pueden ser letras o números y los últimos 2 (dígitos verificadores) son siempre numéricos. Desde julio de 2026 la Receita Federal asigna CNPJ alfanuméricos a empresas nuevas, y los CNPJ numéricos siguen siendo válidos. Se aceptan minúsculas, que se guardan en mayúsculas.- Ejemplos válidos:
12.345.678/0001-95,12.ABC.345/01DE-35
- Ejemplos válidos:
- El número se guarda sin formato. Por eso el mismo documento escrito con máscara, sin máscara o en minúsculas cuenta como duplicado (
CT00023).
México (MX)
| Tipo de Documento | Código | Descripción | Ejemplo |
|---|---|---|---|
| RFC | RFC | ID Fiscal | XAXX010101000 |
| CURP | CURP | Registro de Población | ABCD123456HDFXXX09 |
Chile (CL)
| Tipo de Documento | Código | Descripción | Ejemplo |
|---|---|---|---|
| RUT | RUT | ID Fiscal | 11.111.111-1 |
Argentina (AR)
| Tipo de Documento | Código | Descripción | Ejemplo |
|---|---|---|---|
| DNI | DNI | ID Nacional | 12345678 |
| CUIT | CUIT | ID Fiscal | 20-12345678-9 |
Perú (PE)
| Tipo de Documento | Código | Descripción | Ejemplo |
|---|---|---|---|
| Documento Nacional de Identidad | DNI | ID Nacional | 12345678 |
| Registro Único de Contribuyentes | RUC | ID Fiscal (empresas) | 20123456789 |
| Carné de Extranjería | CED_EXT | ID de Residente Extranjero | 001234567 |
Bolivia (BO)
| Tipo de Documento | Código | Descripción | Ejemplo |
|---|---|---|---|
| Cédula de Identidad | CED_CIU | ID Nacional | 1234567 |
| Número de Identificación Tributaria | NIT | ID Fiscal (empresas) | 1234567890 |
Venezuela (VE)
| Tipo de Documento | Código | Descripción | Ejemplo |
|---|---|---|---|
| Cédula de Identidad | CED_CIU | ID Nacional (prefijo V/E) | V12345678 |
| Número de Identificación Tributaria | NIT | ID Fiscal (empresas, prefijo J/G) | J123456789 |
Estados Unidos (US)
| Tipo de Documento | Código | Descripción | Ejemplo |
|---|---|---|---|
| Employer Identification Number | EIN | ID Fiscal de Empleador | 12-3456789 |
Cuentas Bancarias
Vincular Cuentas Bancarias a Contactos
Para operaciones PAYOUT, necesitas vincular una cuenta bancaria al contacto:
Asociación Automática: Las cuentas bancarias se vinculan automáticamente con la información del contacto. El nombre del titular se toma del firstName y lastName (cuando se proporciona) del contacto. Los códigos bancarios pueden deducirse de los números de cuenta para la mayoría de los países.
Campos Opcionales con Valores por Defecto
| Campo | Tipo | Valor por Defecto | Descripción |
|---|---|---|---|
type | string | VIRTUAL | Tipo de cuenta: SAVINGS, CHECKING, o VIRTUAL. Requerido para Colombia, salvo con rail: "BREB". Opcional para la mayoría de países. |
isVirtual | boolean | false | Si es una cuenta virtual. |
isTracked | boolean | false | Si la cuenta tiene seguimiento para monitoreo de saldo. |
rail | string | (ninguno) | Riel de pago por el que se alcanza el destino: BANK o BREB. Solo tiene sentido en Colombia — requerido para almacenar una llave Bre-B. Ver Rieles de Pago. |
Campos Requeridos por País
| País | entity (código banco) | Notas |
|---|---|---|
| Colombia (CO) | Requerido | Debe proporcionar código de banco — salvo en un destino Bre-B (rail: "BREB"), que no tiene banco |
| Chile (CL) | Requerido | Debe proporcionar código de banco |
| Perú (PE) | Opcional | Auto-deducido del número de cuenta (CCI) |
| Argentina (AR) | Opcional | Auto-deducido de CVU/CBU |
| México (MX) | Opcional | Auto-deducido de CLABE |
| Brasil (BR) | Opcional | Auto-deducido |
Perú — tiempos de acreditación (PEN y USD): las transferencias a Banco BCP son instantáneas, 24/7 salvo entre 00:00 y 04:00. Interbank demora ~20 minutos, de lunes a sábado entre 06:05 y 21:00. Hacia otros bancos se acredita según el horario de envío, a más tardar el siguiente día hábil. Ver Pagar Proveedores para el horario completo y los límites.
async function addBankAccountToContact(token, orgId, merchantId, contactId, bankData) {
const response = await axios.post(
`https://api-sandbox.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/contacts/${contactId}/accounts`,
{
name: bankData.name,
kind: 'BANK',
isDefault: bankData.isDefault,
countrySymbol: bankData.country,
currencySymbol: bankData.currency,
entity: bankData.entity, // Requerido para CO, CL. Opcional para otros (auto-deducido)
accountNumber: bankData.accountNumber,
type: bankData.type, // Requerido para Colombia: 'SAVINGS' o 'CHECKING'
rail: bankData.rail // Opcional: 'BANK' o 'BREB'. Requerido para una llave Bre-B colombiana
},
{
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
}
);
return response.data;
}
// Uso - Colombia (entity requerido)
const bankAccountCO = await addBankAccountToContact(token, orgId, merchantId, 'cnt_abc123', {
name: 'Bancolombia COP',
isDefault: true,
country: 'CO',
currency: 'COP',
entity: 'BANCOLOMBIA', // Requerido para Colombia y Chile
accountNumber: '1234567890',
type: 'SAVINGS' // Requerido para Colombia
});
// Uso - Perú (entity auto-deducido del CCI)
const bankAccountPE = await addBankAccountToContact(token, orgId, merchantId, 'cnt_def456', {
name: 'Peru PEN',
isDefault: false,
country: 'PE',
currency: 'PEN',
accountNumber: '00219100012345678901' // CCI de 20 dígitos - código banco auto-deducido
});
console.log('Cuenta bancaria agregada:', bankAccountCO.id);def add_bank_account_to_contact(token, org_id, merchant_id, contact_id, bank_data):
payload = {
'name': bank_data['name'],
'kind': 'BANK',
'isDefault': bank_data['is_default'],
'countrySymbol': bank_data['country'],
'currencySymbol': bank_data['currency'],
'accountNumber': bank_data['account_number']
}
# entity requerido para CO, CL; opcional para otros
if bank_data.get('entity'):
payload['entity'] = bank_data['entity']
# type requerido para Colombia; opcional para otros países (por defecto VIRTUAL)
if bank_data.get('type'):
payload['type'] = bank_data['type']
# rail opcional: 'BANK' o 'BREB'. Requerido para una llave Bre-B colombiana
if bank_data.get('rail'):
payload['rail'] = bank_data['rail']
response = requests.post(
f'https://api-sandbox.koywe.com/api/v1/organizations/{org_id}/merchants/{merchant_id}/contacts/{contact_id}/accounts',
json=payload,
headers={
'Authorization': f'Bearer {token}',
'Content-Type': 'application/json'
}
)
return response.json()
# Uso - Colombia (entity requerido)
bank_account_co = add_bank_account_to_contact(token, org_id, merchant_id, 'cnt_abc123', {
'country': 'CO',
'currency': 'COP',
'entity': 'BANCOLOMBIA', # Requerido para Colombia
'account_number': '1234567890',
'type': 'SAVINGS' # Requerido para Colombia
})
# Uso - Chile (entity requerido)
bank_account_cl = add_bank_account_to_contact(token, org_id, merchant_id, 'cnt_ghi789', {
'country': 'CL',
'currency': 'CLP',
'entity': 'BANCO_ESTADO', # Requerido para Chile
'account_number': '12345678901'
})# Colombia - entity (código banco) requerido
curl -X POST 'https://api-sandbox.koywe.com/api/v1/organizations/TU_ORG_ID/merchants/TU_MERCHANT_ID/contacts/cnt_abc123/accounts' \
-H 'Authorization: Bearer TU_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"name": "Bancolombia COP",
"kind": "BANK",
"isDefault": true,
"countrySymbol": "CO",
"currencySymbol": "COP",
"entity": "BANCOLOMBIA",
"accountNumber": "1234567890",
"type": "SAVINGS"
}'Colombia — llaves Bre-B: rail es opcional, pero envía rail: "BREB" siempre que accountNumber contenga una llave Bre-B (un email, un @alias, un celular o un número de documento). Sin eso el valor se valida y se liquida como número de cuenta bancaria: normalmente se rechaza con BAA00020 / BAA00021, y cuando su longitud coincide con la de una cuenta real queda guardado como cuenta bancaria — y el pago sale por el riel equivocado. Declararlo también te exime de entity y type, que una llave no tiene. Ver Rieles de Pago.
# Colombia — llave Bre-B como destino
curl -X POST 'https://api-sandbox.koywe.com/api/v1/organizations/YOUR_ORG_ID/merchants/YOUR_MERCHANT_ID/contacts/cnt_abc123/accounts' \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"name": "Bre-B Juan Pérez",
"kind": "BANK",
"isDefault": true,
"countrySymbol": "CO",
"currencySymbol": "COP",
"accountNumber": "@juanperez",
"rail": "BREB"
}'Requisitos por País: Consulta Cuentas Externas del Comercio para reglas de validación detalladas por país. Las cuentas bancarias de contactos siguen las mismas validaciones (CLABE para México, CCI para Perú, CVU/CBU para Argentina, etc.).
Recuperar Contactos
Listar Todos los Contactos
async function listContacts(token, orgId, merchantId, options = {}) {
const response = await axios.get(
`https://api-sandbox.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/contacts`,
{
params: {
search: options.search, // Opcional: buscar por nombre o email
limit: options.limit || 50,
page: options.page || 1
},
headers: { 'Authorization': `Bearer ${token}` }
}
);
return response.data;
}
// Uso
const contacts = await listContacts(token, orgId, merchantId, {
search: 'juan',
limit: 20
});
console.log(`Se encontraron ${contacts.length} contactos`);Obtener Contacto Específico
async function getContact(token, orgId, merchantId, contactId) {
const response = await axios.get(
`https://api-sandbox.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/contacts/${contactId}`,
{
headers: { 'Authorization': `Bearer ${token}` }
}
);
return response.data;
}
// Uso
const contact = await getContact(token, orgId, merchantId, 'cnt_abc123');
console.log('Contacto:', contact);Obtener Cuentas Bancarias del Contacto
async function getContactBankAccounts(token, orgId, merchantId, contactId) {
const response = await axios.get(
`https://api-sandbox.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/contacts/${contactId}/accounts`,
{
headers: { 'Authorization': `Bearer ${token}` }
}
);
return response.data;
}
// Uso
const bankAccounts = await getContactBankAccounts(token, orgId, merchantId, 'cnt_abc123');
console.log('Cuentas bancarias:', bankAccounts);Actualizar Contactos
async function updateContact(token, orgId, merchantId, contactId, updates) {
const response = await axios.put(
`https://api-sandbox.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/contacts/${contactId}`,
updates,
{
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
}
);
return response.data;
}
// Uso - Actualizar teléfono o dirección
const updated = await updateContact(token, orgId, merchantId, 'cnt_abc123', {
phone: '+573009876543',
addressLine1: 'Calle 456',
city: 'Medellín'
});Requisitos de Validación
Persona vs Empresa
Para PERSON (individual):
- Usa tipos de documento individual (CED_CIU, DNI, CPF, etc.)
businessType:"PERSON"firstNamedel individuo (y opcionalmentelastName)
Para COMPANY (empresa):
- Usa tipos de documento de empresa (NIT, CNPJ, CUIT, etc.)
businessType:"COMPANY"type:"BUSINESS"- Nombre legal de la empresa como
firstName
Formatos de Número de Documento
Los números de documento deben coincidir con el formato esperado para cada país:
- Colombia CED_CIU / CED_EXT: solo dígitos (hasta 15)
- Colombia NIT: 10 dígitos (
9001234561) o con puntos y guión (900.123.456-1) - Brasil CPF: 11 dígitos (con o sin formato)
- Brasil CNPJ: 14 caracteres, numérico o alfanumérico (con o sin formato)
- México RFC: 12-13 caracteres
- Chile RUT: Formato XX.XXX.XXX-X
Mejores Prácticas
Cuándo Crear Contactos
Crear contactos para:
- Clientes haciendo pagos (PAYIN) - para seguimiento y cumplimiento
- Proveedores recibiendo pagos (PAYOUT) - requerido para vinculación de cuenta bancaria
- Transacciones recurrentes con la misma entidad
Reutilizar Contactos
Reutiliza contactos existentes para el mismo cliente/proveedor para:
- Mantener historial de pagos
- Evitar registros duplicados
- Simplificar reconciliación
// Verificar si el contacto existe antes de crear
async function getOrCreateContact(token, orgId, merchantId, email) {
// Intentar encontrar existente
const contacts = await listContacts(token, orgId, merchantId, { search: email });
if (contacts.length > 0) {
return contacts[0]; // Devolver existente
}
// Crear nuevo si no se encuentra
return await createContact(token, orgId, merchantId, {
email: email,
// ... otros campos
});
}Privacidad de Datos
Consideraciones de Seguridad:
- Almacena solo información necesaria
- Sigue regulaciones GDPR/protección de datos
- No almacenes datos sensibles en campos de metadata
- Implementa controles de acceso apropiados
Escenarios Comunes
Escenario 1: Pago de Cliente E-Commerce
// 1. Crear contacto de cliente
const customer = await createContact(token, orgId, merchantId, {
firstName: 'María',
lastName: 'García',
countrySymbol: 'CO',
businessType: 'PERSON',
type: 'PERSON',
email: 'cliente@ejemplo.com',
documentType: 'CED_CIU',
documentNumber: '1234567890',
phone: '+573001234567'
});
// 2. Crear orden PAYIN vinculada al contacto
const order = await createPayinOrder(token, orgId, merchantId, {
contactId: customer.id,
amount: 50000,
currency: 'COP',
// ... otros campos
});Escenario 2: Pago a Proveedor
// 1. Crear contacto de proveedor
const provider = await createContact(token, orgId, merchantId, {
firstName: 'Servicios ABC SAS',
countrySymbol: 'CO',
businessType: 'COMPANY',
type: 'BUSINESS',
email: 'proveedor@ejemplo.com',
documentType: 'NIT',
documentNumber: '9001234561'
});
// 2. Agregar cuenta bancaria del proveedor
const bankAccount = await addBankAccountToContact(token, orgId, merchantId, provider.id, {
name: 'Bancolombia COP',
kind: 'BANK',
isDefault: true,
countrySymbol: 'CO',
currencySymbol: 'COP',
entity: 'BANCOLOMBIA',
accountNumber: '1234567890',
type: 'CHECKING'
});
// 3. Crear orden PAYOUT
const payout = await createPayoutOrder(token, orgId, merchantId, {
contactId: provider.id,
destinationAccountId: bankAccount.id, // Vincular a cuenta bancaria
amount: 500000,
currency: 'COP'
});