Skip to main content

Flujo de trabajo completo de verificación KYB

El flujo de trabajo KYB de gu1 automatiza todo el proceso de verificación de empresas desde la recopilación inicial de datos hasta el monitoreo continuo. Esta guía recorre cada paso con detalles técnicos de implementación.

Descripción general del flujo de trabajo

Paso 1: Recopilación inicial de datos

Qué recopilar

Reúna información básica de la empresa desde su formulario de solicitud:
  • Nombre de la Empresa: Nombre legal y nombre comercial
  • Número de Registro: Registro empresarial emitido por el gobierno
  • ID Fiscal: EIN (EE.UU.), CNPJ (Brasil), RFC (México), etc.
  • Fecha de Constitución: Cuándo se formó la empresa
  • País: Jurisdicción de constitución
  • Dirección de la Empresa: Ubicación de la oficina registrada
  • Industria: Tipo de actividad empresarial
  • Volumen de Transacciones Esperado: Estimaciones mensuales/anuales

Ejemplo de formulario de solicitud

const businessApplication = {
  legalName: "Tech Solutions Sociedade Anônima",
  tradeName: "Tech Solutions",
  registrationNumber: "12.345.678/0001-90",
  taxId: "12.345.678/0001-90",
  incorporationDate: "2020-06-15",
  country: "BR",
  address: {
    street: "Av. Paulista, 1000",
    city: "São Paulo",
    state: "SP",
    postalCode: "01310-100"
  },
  industry: "Software Development",
  website: "https://techsolutions.com.br",
  expectedMonthlyVolume: 250000,
  businessDescription: "B2B SaaS platform for enterprise clients"
};

Paso 2: Crear entidad empresarial

Use la API de Entidades para crear una entidad de empresa en gu1:
curl -X POST http://api.gu1.ai/entities \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "company",
    "externalId": "business_12345",
    "name": "Tech Solutions Sociedade Anônima",
    "taxId": "12.345.678/0001-90",
    "countryCode": "BR",
    "entityData": {
      "company": {
        "legalName": "Tech Solutions Sociedade Anônima",
        "tradeName": "Tech Solutions",
        "incorporationDate": "2020-06-15",
        "industry": "Software Development",
        "employeeCount": 50,
        "revenue": 5000000
      }
    },
    "attributes": {
      "registrationNumber": "12.345.678/0001-90",
      "website": "https://techsolutions.com.br",
      "registeredAddress": "Av. Paulista, 1000, São Paulo",
      "expectedMonthlyVolume": 250000,
      "applicationDate": "2024-10-03T10:00:00Z"
    }
  }'
Respuesta:
{
  "success": true,
  "entity": {
    "id": "660e9511-f39c-52e5-b827-557766551111",
    "externalId": "business_12345",
    "type": "company",
    "name": "Tech Solutions Sociedade Anônima",
    "riskScore": 0,
    "status": "under_review",
    "createdAt": "2024-10-03T10:00:00Z"
  }
}

Paso 3: Carga y verificación de documentos

Cargue los documentos empresariales requeridos para la verificación:

Documentos requeridos

  1. Acta Constitutiva - Documento de fundación
  2. Licencia de Negocio - Permiso de operación emitido por el gobierno
  3. Certificado Fiscal - Comprobante de registro fiscal
  4. Comprobante de Domicilio - Factura de servicios o estado de cuenta bancario
  5. Declaración de Propiedad Beneficiaria - Información de beneficiarios finales

Cargar documentos

async function uploadBusinessDocuments(entityId, documents) {
  const documentUploads = [];

  for (const doc of documents) {
    const formData = new FormData();
    formData.append('file', doc.file);
    formData.append('documentType', doc.type);
    formData.append('entityId', entityId);

    const response = await fetch('http://api.gu1.ai/documents', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${API_KEY}`
      },
      body: formData
    });

    documentUploads.push(await response.json());
  }

  return documentUploads;
}

// Uso
const documents = [
  { file: articlesOfIncorporation, type: 'articles_of_incorporation' },
  { file: businessLicense, type: 'business_license' },
  { file: taxCertificate, type: 'tax_certificate' },
  { file: proofOfAddress, type: 'proof_of_address' }
];

const uploadedDocs = await uploadBusinessDocuments(entityId, documents);

Paso 4: Análisis con IA y evaluación de riesgo

Solicite un análisis impulsado por IA de la entidad empresarial:
async function requestAIAnalysis(entityId) {
  const response = await fetch(
    `http://api.gu1.ai/entities/${entityId}/ai-analysis`,
    {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${API_KEY}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        analysisType: 'kyb_verification',
        includeDocuments: true,
        checkSanctions: true,
        checkAdverseMedia: true
      })
    }
  );

  return await response.json();
}
Respuesta del análisis con IA:
{
  "analysisId": "analysis_abc123",
  "entityId": "660e9511-f39c-52e5-b827-557766551111",
  "riskScore": 35,
  "riskLevel": "medium",
  "findings": {
    "documentVerification": {
      "status": "verified",
      "confidence": 0.95,
      "articlesOfIncorporation": "valid",
      "businessLicense": "valid",
      "taxCertificate": "valid"
    },
    "businessLegitimacy": {
      "status": "verified",
      "registrationVerified": true,
      "taxIdValid": true,
      "addressConfirmed": true
    },
    "sanctionsScreening": {
      "status": "clear",
      "listsChecked": ["OFAC", "UN", "EU", "UK"],
      "matches": []
    },
    "adverseMedia": {
      "status": "minor_flags",
      "findings": [
        {
          "source": "news_article",
          "date": "2023-05-15",
          "summary": "Small tax dispute resolved",
          "severity": "low"
        }
      ]
    },
    "riskFactors": [
      {
        "factor": "new_business",
        "impact": 20,
        "description": "Company incorporated less than 5 years ago"
      },
      {
        "factor": "high_growth_industry",
        "impact": 15,
        "description": "Software industry has elevated fraud risk"
      },
      {
        "factor": "clean_compliance_history",
        "impact": -10,
        "description": "No regulatory violations found"
      }
    ]
  },
  "recommendation": "approve_with_monitoring",
  "nextSteps": [
    "Verify beneficial ownership",
    "Set transaction monitoring thresholds",
    "Schedule 6-month review"
  ]
}

Paso 5: Decisión basada en riesgo

Según la puntuación de riesgo, enrute al flujo de trabajo apropiado:
async function processKYBDecision(analysisResult) {
  const { riskScore, riskLevel, recommendation } = analysisResult;

  if (riskScore < 30) {
    // Riesgo Bajo - Aprobación automática
    return await autoApprove(analysisResult.entityId);

  } else if (riskScore < 70) {
    // Riesgo Medio - Debida Diligencia Reforzada
    return await enhancedDueDiligence(analysisResult.entityId);

  } else {
    // Riesgo Alto - Revisión Manual Requerida
    return await flagForManualReview(analysisResult.entityId, analysisResult.findings);
  }
}

async function autoApprove(entityId) {
  // Actualizar estado de la entidad a aprobado
  await fetch(`http://api.gu1.ai/entities/${entityId}`, {
    method: 'PATCH',
    headers: {
      'Authorization': `Bearer ${API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      attributes: {
        kybStatus: 'approved',
        approvedAt: new Date().toISOString(),
        approvedBy: 'automated_system',
        reviewNotes: 'Low risk - auto-approved'
      }
    })
  });

  // Enviar notificación de aprobación
  await sendApprovalEmail(entityId);

  // Habilitar monitoreo
  await enableOngoingMonitoring(entityId);

  return { status: 'approved', action: 'auto_approved' };
}

async function enhancedDueDiligence(entityId) {
  // Solicitar información adicional
  await requestAdditionalDocs(entityId, [
    'financial_statements',
    'ownership_structure',
    'source_of_funds'
  ]);

  // Actualizar estado
  await updateEntityStatus(entityId, 'enhanced_due_diligence');

  return { status: 'pending', action: 'edd_required' };
}

async function flagForManualReview(entityId, findings) {
  // Crear tarea de revisión
  await createReviewTask({
    entityId,
    priority: 'high',
    assignTo: 'compliance_team',
    findings,
    dueDate: new Date(Date.now() + 24 * 60 * 60 * 1000) // 24 horas
  });

  return { status: 'manual_review', action: 'flagged_for_review' };
}

Paso 6: Verificación de beneficiarios finales

Identifique y verifique los Beneficiarios Finales (UBO):
async function verifyBeneficialOwners(entityId, owners) {
  const verifiedOwners = [];

  for (const owner of owners) {
    // Crear entidad persona para cada UBO
    const uboEntity = await fetch('http://api.gu1.ai/entities', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${API_KEY}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        type: 'person',
        externalId: `ubo_${owner.id}`,
        name: `${owner.firstName} ${owner.lastName}`,
        countryCode: owner.nationality,
        entityData: {
          person: {
            firstName: owner.firstName,
            lastName: owner.lastName,
            dateOfBirth: owner.dateOfBirth,
            nationality: owner.nationality
          }
        },
        attributes: {
          ownershipPercentage: owner.ownership,
          isPEP: owner.isPEP,
          relationshipToCompany: 'beneficial_owner'
        }
      })
    });

    const ubo = await uboEntity.json();

    // Ejecutar verificaciones KYC en el UBO
    const kycResult = await runKYCCheck(ubo.entity.id);

    // Crear relación entre la empresa y el UBO
    await createRelationship({
      fromEntityId: entityId,
      toEntityId: ubo.entity.id,
      relationshipType: 'beneficial_owner',
      ownershipPercentage: owner.ownership
    });

    verifiedOwners.push({
      ...ubo.entity,
      kycStatus: kycResult.status,
      riskScore: kycResult.riskScore
    });
  }

  return verifiedOwners;
}

Paso 7: Configurar monitoreo continuo

Habilite el monitoreo continuo para empresas aprobadas:
async function setupOngoingMonitoring(entityId) {
  // Configurar reglas de monitoreo
  await fetch('http://api.gu1.ai/rules', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      name: `KYB Monitoring - ${entityId}`,
      entityId: entityId,
      rules: [
        {
          type: 'sanctions_screening',
          frequency: 'daily',
          action: 'alert_compliance_team'
        },
        {
          type: 'adverse_media',
          frequency: 'weekly',
          action: 'create_review_task'
        },
        {
          type: 'ownership_changes',
          frequency: 'realtime',
          action: 'trigger_reverification'
        },
        {
          type: 'transaction_anomalies',
          threshold: 'high',
          action: 'flag_for_review'
        }
      ]
    })
  });

  // Configurar notificaciones webhook
  await configureWebhook({
    entityId,
    events: [
      'sanctions_match',
      'adverse_media_found',
      'ownership_change',
      'transaction_anomaly'
    ],
    url: 'https://your-app.com/webhooks/kyb-alerts'
  });
}

Paso 8: Actualizaciones de estado y notificaciones

Mantenga informada a la empresa durante todo el proceso:
async function sendStatusUpdate(entityId, status, details) {
  // Obtener detalles de la entidad
  const entity = await getEntity(entityId);

  // Enviar notificación por correo electrónico
  await sendEmail({
    to: entity.attributes.contactEmail,
    subject: `Actualización de Verificación KYB - ${status}`,
    template: 'kyb_status_update',
    data: {
      companyName: entity.name,
      status: status,
      details: details,
      nextSteps: getNextSteps(status),
      dashboardUrl: `https://app.gu1.ai/onboarding/${entityId}`
    }
  });

  // Enviar webhook a su sistema
  await sendWebhook({
    event: 'kyb_status_changed',
    entityId: entityId,
    status: status,
    timestamp: new Date().toISOString(),
    details: details
  });
}

// Ejemplos de actualización de estado
await sendStatusUpdate(entityId, 'documents_received', {
  message: 'Hemos recibido sus documentos y los estamos procesando.'
});

await sendStatusUpdate(entityId, 'approved', {
  message: '¡Su empresa ha sido verificada y aprobada!',
  approvalDate: new Date().toISOString()
});

await sendStatusUpdate(entityId, 'additional_info_required', {
  message: 'Necesitamos información adicional para completar su verificación.',
  requiredDocuments: ['financial_statements', 'ownership_structure']
});

Implementación completa del flujo de trabajo

Aquí hay una función completa que orquesta todo el flujo de trabajo KYB:
async function executeKYBWorkflow(applicationData) {
  try {
    // Paso 1 y 2: Crear entidad
    console.log('Creando entidad empresarial...');
    const entity = await createBusinessEntity(applicationData);

    // Paso 3: Cargar documentos
    console.log('Cargando documentos de verificación...');
    await uploadBusinessDocuments(entity.id, applicationData.documents);

    // Paso 4: Solicitar análisis con IA
    console.log('Ejecutando análisis con IA...');
    const analysis = await requestAIAnalysis(entity.id);

    // Paso 5: Tomar decisión basada en riesgo
    console.log('Procesando decisión KYB...');
    const decision = await processKYBDecision(analysis);

    if (decision.status === 'approved') {
      // Paso 6: Verificar UBOs (para entidades aprobadas)
      console.log('Verificando beneficiarios finales...');
      await verifyBeneficialOwners(entity.id, applicationData.beneficialOwners);

      // Paso 7: Configurar monitoreo
      console.log('Configurando monitoreo continuo...');
      await setupOngoingMonitoring(entity.id);
    }

    // Paso 8: Enviar actualización de estado
    console.log('Enviando notificación de estado...');
    await sendStatusUpdate(entity.id, decision.status, analysis.findings);

    return {
      success: true,
      entityId: entity.id,
      status: decision.status,
      riskScore: analysis.riskScore,
      decision: decision
    };

  } catch (error) {
    console.error('Error en el flujo de trabajo KYB:', error);
    return {
      success: false,
      error: error.message
    };
  }
}

Estimaciones de tiempo

Nivel de RiesgoProcesamiento AutomatizadoCon Revisión ManualProceso Tradicional
Riesgo Bajo2-5 minutos30 minutos2-3 días
Riesgo Medio15-30 minutos2-4 horas3-5 días
Riesgo Alto30-60 minutos1-2 días5-10 días

Próximos pasos