Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.gu1.ai/llms.txt

Use this file to discover all available pages before exploring further.

Descripción General

Esta guía proporciona una implementación completa lista para producción de verificación KYB (Know Your Business) utilizando la API de gu1. Puedes copiar y adaptar este código para tu aplicación.

Requisitos Previos

  • Clave API de gu1 (obtén una aquí)
  • Node.js 18+ o Python 3.8+
  • Conocimiento básico de APIs RESTful

Implementación Completa

Node.js / TypeScript

Implementación completa de KYB con TypeScript:
import axios from 'axios';
import FormData from 'form-data';
import fs from 'fs';

const GUENO_API_KEY = process.env.GUENO_API_KEY;
const GUENO_API_URL = 'http://api.gu1.ai';

// API Client Setup
const apiClient = axios.create({
  baseURL: GUENO_API_URL,
  headers: {
    'Authorization': `Bearer ${GUENO_API_KEY}`,
    'Content-Type': 'application/json'
  }
});

// Types
interface BusinessApplication {
  businessId: string;
  legalName: string;
  tradeName: string;
  taxId: string;
  countryCode: string;
  incorporationDate: string;
  industry: string;
  website?: string;
  employeeCount?: number;
  revenue?: number;
  address: {
    street: string;
    city: string;
    state: string;
    postalCode: string;
    country: string;
  };
  contactEmail: string;
  contactPhone: string;
  expectedMonthlyVolume: number;
  beneficialOwners: BeneficialOwner[];
  documents: DocumentUpload[];
}

interface BeneficialOwner {
  firstName: string;
  lastName: string;
  dateOfBirth: string;
  nationality: string;
  ownershipPercentage: number;
  isPEP: boolean;
  idNumber?: string;
}

interface DocumentUpload {
  type: string;
  filePath: string;
}

interface KYBResult {
  success: boolean;
  entityId: string;
  status: 'approved' | 'pending' | 'rejected' | 'manual_review';
  riskScore: number;
  findings: any;
  nextSteps: string[];
}

// Main KYB Workflow Class
class KYBProcessor {

  /**
   * Paso 1: Crear Entidad Empresarial
   */
  async createBusinessEntity(application: BusinessApplication): Promise<any> {
    console.log('📋 Creando entidad empresarial...');

    const response = await apiClient.post('/entities', {
      type: 'company',
      externalId: application.businessId,
      name: application.legalName,
      taxId: application.taxId,
      countryCode: application.countryCode,
      entityData: {
        company: {
          legalName: application.legalName,
          tradeName: application.tradeName,
          incorporationDate: application.incorporationDate,
          industry: application.industry,
          employeeCount: application.employeeCount,
          revenue: application.revenue
        }
      },
      attributes: {
        website: application.website,
        registeredAddress: application.address,
        contactEmail: application.contactEmail,
        contactPhone: application.contactPhone,
        expectedMonthlyVolume: application.expectedMonthlyVolume,
        applicationDate: new Date().toISOString()
      }
    });

    console.log(`✅ Entidad creada: ${response.data.entity.id}`);
    return response.data.entity;
  }

  /**
   * Paso 2: Cargar Documentos de Verificación
   */
  async uploadDocuments(entityId: string, documents: DocumentUpload[]): Promise<any[]> {
    console.log(`📄 Cargando ${documents.length} documentos...`);

    const uploadResults = [];

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

      const response = await axios.post(
        `${GUENO_API_URL}/documents`,
        formData,
        {
          headers: {
            'Authorization': `Bearer ${GUENO_API_KEY}`,
            ...formData.getHeaders()
          }
        }
      );

      console.log(`  ✅ Cargado: ${doc.type}`);
      uploadResults.push(response.data);
    }

    return uploadResults;
  }

  /**
   * Paso 3: Solicitar Análisis de IA
   */
  async requestAIAnalysis(entityId: string): Promise<any> {
    console.log('🤖 Solicitando análisis de IA...');

    const response = await apiClient.post(`/entities/${entityId}/ai-analysis`, {
      analysisType: 'kyb_verification',
      includeDocuments: true,
      checkSanctions: true,
      checkAdverseMedia: true,
      checkUBOs: true
    });

    console.log(`✅ Análisis completo. Puntuación de Riesgo: ${response.data.riskScore}`);
    return response.data;
  }

  /**
   * Paso 4: Verificar Beneficiarios Finales
   */
  async verifyBeneficialOwners(entityId: string, owners: BeneficialOwner[]): Promise<any[]> {
    console.log(`👥 Verificando ${owners.length} beneficiarios finales...`);

    const verifiedOwners = [];

    for (const owner of owners) {
      // Crear entidad de persona para UBO
      const uboResponse = await apiClient.post('/entities', {
        type: 'person',
        externalId: `ubo_${entityId}_${owner.idNumber}`,
        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.ownershipPercentage,
          isPEP: owner.isPEP,
          relationshipToCompany: 'beneficial_owner'
        }
      });

      const ubo = uboResponse.data.entity;

      // Ejecutar verificación KYC en UBO
      const kycResponse = await apiClient.post(`/entities/${ubo.id}/ai-analysis`, {
        analysisType: 'kyc_verification',
        checkPEP: true,
        checkSanctions: true
      });

      // Crear relación
      await apiClient.post('/relationships', {
        fromEntityId: entityId,
        toEntityId: ubo.id,
        relationshipType: 'beneficial_owner',
        metadata: {
          ownershipPercentage: owner.ownershipPercentage
        }
      });

      console.log(`  ✅ Verificado: ${owner.firstName} ${owner.lastName}`);

      verifiedOwners.push({
        ...ubo,
        kycStatus: kycResponse.data.status,
        riskScore: kycResponse.data.riskScore
      });
    }

    return verifiedOwners;
  }

  /**
   * Paso 5: Tomar Decisión Basada en el Riesgo
   */
  async makeDecision(entityId: string, analysis: any): Promise<string> {
    console.log('⚖️  Tomando decisión KYB...');

    const { riskScore, riskLevel } = analysis;

    if (riskScore < 30) {
      // Riesgo Bajo - Aprobación Automática
      await this.approveEntity(entityId, analysis);
      return 'approved';

    } else if (riskScore < 70) {
      // Riesgo Medio - Debida Diligencia Reforzada
      await this.requestEnhancedDueDiligence(entityId, analysis);
      return 'pending';

    } else {
      // Riesgo Alto - Revisión Manual
      await this.flagForManualReview(entityId, analysis);
      return 'manual_review';
    }
  }

  /**
   * Aprobar Entidad de Bajo Riesgo
   */
  private async approveEntity(entityId: string, analysis: any): Promise<void> {
    console.log('✅ Aprobando automáticamente entidad de bajo riesgo...');

    // Actualizar estado de entidad
    await apiClient.patch(`/entities/${entityId}`, {
      attributes: {
        kybStatus: 'approved',
        approvedAt: new Date().toISOString(),
        approvedBy: 'automated_system',
        riskLevel: 'low',
        reviewNotes: 'Bajo riesgo - aprobado automáticamente basado en análisis de IA'
      }
    });

    // Configurar monitoreo
    await this.setupMonitoring(entityId);

    // Enviar notificación
    await this.sendStatusNotification(entityId, 'approved');
  }

  /**
   * Solicitar Debida Diligencia Reforzada
   */
  private async requestEnhancedDueDiligence(entityId: string, analysis: any): Promise<void> {
    console.log('🔍 Solicitando debida diligencia reforzada...');

    await apiClient.patch(`/entities/${entityId}`, {
      attributes: {
        kybStatus: 'enhanced_due_diligence',
        requestedAt: new Date().toISOString(),
        riskLevel: 'medium',
        additionalDocsRequired: [
          'financial_statements',
          'ownership_structure',
          'source_of_funds'
        ]
      }
    });

    await this.sendStatusNotification(entityId, 'additional_info_required');
  }

  /**
   * Marcar para Revisión Manual
   */
  private async flagForManualReview(entityId: string, analysis: any): Promise<void> {
    console.log('⚠️  Marcando para revisión manual...');

    // Crear tarea de revisión
    await apiClient.post('/tasks', {
      type: 'manual_review',
      entityId: entityId,
      priority: 'high',
      assignTo: 'compliance_team',
      dueDate: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(),
      context: {
        riskScore: analysis.riskScore,
        riskFactors: analysis.riskFactors,
        findings: analysis.findings
      }
    });

    await apiClient.patch(`/entities/${entityId}`, {
      attributes: {
        kybStatus: 'manual_review',
        flaggedAt: new Date().toISOString(),
        riskLevel: 'high'
      }
    });

    await this.sendStatusNotification(entityId, 'under_review');
  }

  /**
   * Configurar Monitoreo Continuo
   */
  private async setupMonitoring(entityId: string): Promise<void> {
    console.log('📊 Configurando monitoreo continuo...');

    await apiClient.post('/rules', {
      name: `KYB Monitoring - ${entityId}`,
      entityId: entityId,
      active: true,
      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'
        }
      ]
    });
  }

  /**
   * Enviar Notificación de Estado
   */
  private async sendStatusNotification(entityId: string, status: string): Promise<void> {
    console.log(`📧 Enviando notificación de ${status}...`);

    // Tu lógica de notificación aquí (email, webhook, etc.)
    await apiClient.post('/webhooks/send', {
      event: 'kyb_status_changed',
      entityId: entityId,
      status: status,
      timestamp: new Date().toISOString()
    });
  }

  /**
   * Flujo de Trabajo KYB Completo
   */
  async processKYB(application: BusinessApplication): Promise<KYBResult> {
    try {
      console.log('🚀 Iniciando proceso de verificación KYB...\n');

      // Paso 1: Crear entidad
      const entity = await this.createBusinessEntity(application);

      // Paso 2: Cargar documentos
      await this.uploadDocuments(entity.id, application.documents);

      // Paso 3: Análisis de IA
      const analysis = await this.requestAIAnalysis(entity.id);

      // Paso 4: Verificar UBOs
      const verifiedOwners = await this.verifyBeneficialOwners(
        entity.id,
        application.beneficialOwners
      );

      // Paso 5: Tomar decisión
      const status = await this.makeDecision(entity.id, analysis);

      console.log('\n✨ ¡Proceso KYB completado exitosamente!');

      return {
        success: true,
        entityId: entity.id,
        status: status as any,
        riskScore: analysis.riskScore,
        findings: analysis.findings,
        nextSteps: analysis.nextSteps
      };

    } catch (error: any) {
      console.error('❌ Proceso KYB falló:', error.message);

      return {
        success: false,
        entityId: '',
        status: 'rejected',
        riskScore: 100,
        findings: { error: error.message },
        nextSteps: ['Contactar soporte']
      };
    }
  }
}

// Example Usage
async function main() {
  const kybProcessor = new KYBProcessor();

  // Sample business application
  const application: BusinessApplication = {
    businessId: 'business_12345',
    legalName: 'Tech Solutions Sociedade Anônima',
    tradeName: 'Tech Solutions',
    taxId: '12.345.678/0001-90',
    countryCode: 'BR',
    incorporationDate: '2020-06-15',
    industry: 'Software Development',
    website: 'https://techsolutions.com.br',
    employeeCount: 50,
    revenue: 5000000,
    address: {
      street: 'Av. Paulista, 1000',
      city: 'São Paulo',
      state: 'SP',
      postalCode: '01310-100',
      country: 'BR'
    },
    contactEmail: 'contact@techsolutions.com.br',
    contactPhone: '+55 11 1234-5678',
    expectedMonthlyVolume: 250000,
    beneficialOwners: [
      {
        firstName: 'Carlos',
        lastName: 'Silva',
        dateOfBirth: '1975-08-22',
        nationality: 'BR',
        ownershipPercentage: 60,
        isPEP: false,
        idNumber: '123.456.789-00'
      },
      {
        firstName: 'Ana',
        lastName: 'Costa',
        dateOfBirth: '1980-03-15',
        nationality: 'BR',
        ownershipPercentage: 40,
        isPEP: false,
        idNumber: '987.654.321-00'
      }
    ],
    documents: [
      { type: 'articles_of_incorporation', filePath: './docs/contrato_social.pdf' },
      { type: 'tax_certificate', filePath: './docs/cnpj_certificate.pdf' },
      { type: 'business_license', filePath: './docs/alvara.pdf' },
      { type: 'proof_of_address', filePath: './docs/comprovante.pdf' }
    ]
  };

  // Execute KYB workflow
  const result = await kybProcessor.processKYB(application);

  console.log('\n📊 Resultado Final:');
  console.log(JSON.stringify(result, null, 2));
}

// Run the example
main().catch(console.error);

Implementación en Python

Flujo de trabajo KYB completo en Python:
import requests
import os
from typing import List, Dict, Optional
from datetime import datetime, timedelta

GUENO_API_KEY = os.getenv('GUENO_API_KEY')
GUENO_API_URL = 'http://api.gu1.ai'

class KYBProcessor:
    def __init__(self, api_key: str):
        self.api_key = api_key
        self.headers = {
            'Authorization': f'Bearer {api_key}',
            'Content-Type': 'application/json'
        }

    def create_business_entity(self, application: Dict) -> Dict:
        """Paso 1: Crear entidad empresarial"""
        print('📋 Creando entidad empresarial...')

        response = requests.post(
            f'{GUENO_API_URL}/entities',
            headers=self.headers,
            json={
                'type': 'company',
                'externalId': application['business_id'],
                'name': application['legal_name'],
                'taxId': application['tax_id'],
                'countryCode': application['country_code'],
                'entityData': {
                    'company': {
                        'legalName': application['legal_name'],
                        'tradeName': application['trade_name'],
                        'incorporationDate': application['incorporation_date'],
                        'industry': application['industry'],
                        'employeeCount': application.get('employee_count'),
                        'revenue': application.get('revenue')
                    }
                },
                'attributes': {
                    'website': application.get('website'),
                    'registeredAddress': application['address'],
                    'contactEmail': application['contact_email'],
                    'contactPhone': application['contact_phone'],
                    'expectedMonthlyVolume': application['expected_monthly_volume'],
                    'applicationDate': datetime.now().isoformat()
                }
            }
        )

        response.raise_for_status()
        entity = response.json()['entity']
        print(f'✅ Entidad creada: {entity["id"]}')
        return entity

    def upload_documents(self, entity_id: str, documents: List[Dict]) -> List[Dict]:
        """Paso 2: Cargar documentos de verificación"""
        print(f'📄 Cargando {len(documents)} documentos...')

        upload_results = []

        for doc in documents:
            with open(doc['file_path'], 'rb') as file:
                files = {'file': file}
                data = {
                    'documentType': doc['type'],
                    'entityId': entity_id
                }

                response = requests.post(
                    f'{GUENO_API_URL}/documents',
                    headers={'Authorization': f'Bearer {self.api_key}'},
                    data=data,
                    files=files
                )

                response.raise_for_status()
                print(f'  ✅ Cargado: {doc["type"]}')
                upload_results.append(response.json())

        return upload_results

    def request_ai_analysis(self, entity_id: str) -> Dict:
        """Paso 3: Solicitar análisis de IA"""
        print('🤖 Solicitando análisis de IA...')

        response = requests.post(
            f'{GUENO_API_URL}/entities/{entity_id}/ai-analysis',
            headers=self.headers,
            json={
                'analysisType': 'kyb_verification',
                'includeDocuments': True,
                'checkSanctions': True,
                'checkAdverseMedia': True,
                'checkUBOs': True
            }
        )

        response.raise_for_status()
        analysis = response.json()
        print(f'✅ Análisis completo. Puntuación de Riesgo: {analysis["riskScore"]}')
        return analysis

    def verify_beneficial_owners(self, entity_id: str, owners: List[Dict]) -> List[Dict]:
        """Paso 4: Verificar beneficiarios finales"""
        print(f'👥 Verificando {len(owners)} beneficiarios finales...')

        verified_owners = []

        for owner in owners:
            # Crear entidad de persona para UBO
            ubo_response = requests.post(
                f'{GUENO_API_URL}/entities',
                headers=self.headers,
                json={
                    'type': 'person',
                    'externalId': f'ubo_{entity_id}_{owner["id_number"]}',
                    'name': f'{owner["first_name"]} {owner["last_name"]}',
                    'countryCode': owner['nationality'],
                    'entityData': {
                        'person': {
                            'firstName': owner['first_name'],
                            'lastName': owner['last_name'],
                            'dateOfBirth': owner['date_of_birth'],
                            'nationality': owner['nationality']
                        }
                    },
                    'attributes': {
                        'ownershipPercentage': owner['ownership_percentage'],
                        'isPEP': owner['is_pep'],
                        'relationshipToCompany': 'beneficial_owner'
                    }
                }
            )

            ubo = ubo_response.json()['entity']

            # Ejecutar verificación KYC
            kyc_response = requests.post(
                f'{GUENO_API_URL}/entities/{ubo["id"]}/ai-analysis',
                headers=self.headers,
                json={
                    'analysisType': 'kyc_verification',
                    'checkPEP': True,
                    'checkSanctions': True
                }
            )

            # Crear relación
            requests.post(
                f'{GUENO_API_URL}/relationships',
                headers=self.headers,
                json={
                    'fromEntityId': entity_id,
                    'toEntityId': ubo['id'],
                    'relationshipType': 'beneficial_owner',
                    'metadata': {
                        'ownershipPercentage': owner['ownership_percentage']
                    }
                }
            )

            print(f'  ✅ Verificado: {owner["first_name"]} {owner["last_name"]}')

            verified_owners.append({
                **ubo,
                'kycStatus': kyc_response.json()['status'],
                'riskScore': kyc_response.json()['riskScore']
            })

        return verified_owners

    def make_decision(self, entity_id: str, analysis: Dict) -> str:
        """Paso 5: Tomar decisión basada en el riesgo"""
        print('⚖️  Tomando decisión KYB...')

        risk_score = analysis['riskScore']

        if risk_score < 30:
            self.approve_entity(entity_id, analysis)
            return 'approved'
        elif risk_score < 70:
            self.request_enhanced_due_diligence(entity_id, analysis)
            return 'pending'
        else:
            self.flag_for_manual_review(entity_id, analysis)
            return 'manual_review'

    def approve_entity(self, entity_id: str, analysis: Dict):
        """Aprobar entidad de bajo riesgo"""
        print('✅ Aprobando automáticamente entidad de bajo riesgo...')

        requests.patch(
            f'{GUENO_API_URL}/entities/{entity_id}',
            headers=self.headers,
            json={
                'attributes': {
                    'kybStatus': 'approved',
                    'approvedAt': datetime.now().isoformat(),
                    'approvedBy': 'automated_system',
                    'riskLevel': 'low'
                }
            }
        )

        self.setup_monitoring(entity_id)
        self.send_status_notification(entity_id, 'approved')

    def request_enhanced_due_diligence(self, entity_id: str, analysis: Dict):
        """Solicitar debida diligencia reforzada"""
        print('🔍 Solicitando debida diligencia reforzada...')

        requests.patch(
            f'{GUENO_API_URL}/entities/{entity_id}',
            headers=self.headers,
            json={
                'attributes': {
                    'kybStatus': 'enhanced_due_diligence',
                    'requestedAt': datetime.now().isoformat(),
                    'riskLevel': 'medium',
                    'additionalDocsRequired': [
                        'financial_statements',
                        'ownership_structure',
                        'source_of_funds'
                    ]
                }
            }
        )

        self.send_status_notification(entity_id, 'additional_info_required')

    def flag_for_manual_review(self, entity_id: str, analysis: Dict):
        """Marcar para revisión manual"""
        print('⚠️  Marcando para revisión manual...')

        requests.post(
            f'{GUENO_API_URL}/tasks',
            headers=self.headers,
            json={
                'type': 'manual_review',
                'entityId': entity_id,
                'priority': 'high',
                'assignTo': 'compliance_team',
                'dueDate': (datetime.now() + timedelta(days=1)).isoformat(),
                'context': {
                    'riskScore': analysis['riskScore'],
                    'riskFactors': analysis['riskFactors'],
                    'findings': analysis['findings']
                }
            }
        )

    def setup_monitoring(self, entity_id: str):
        """Configurar monitoreo continuo"""
        print('📊 Configurando monitoreo continuo...')

        requests.post(
            f'{GUENO_API_URL}/rules',
            headers=self.headers,
            json={
                'name': f'KYB Monitoring - {entity_id}',
                'entityId': entity_id,
                'active': True,
                'rules': [
                    {
                        'type': 'sanctions_screening',
                        'frequency': 'daily',
                        'action': 'alert_compliance_team'
                    },
                    {
                        'type': 'adverse_media',
                        'frequency': 'weekly',
                        'action': 'create_review_task'
                    }
                ]
            }
        )

    def send_status_notification(self, entity_id: str, status: str):
        """Enviar notificación de estado"""
        print(f'📧 Enviando notificación de {status}...')

        requests.post(
            f'{GUENO_API_URL}/webhooks/send',
            headers=self.headers,
            json={
                'event': 'kyb_status_changed',
                'entityId': entity_id,
                'status': status,
                'timestamp': datetime.now().isoformat()
            }
        )

    def process_kyb(self, application: Dict) -> Dict:
        """Flujo de trabajo KYB completo"""
        try:
            print('🚀 Iniciando proceso de verificación KYB...\n')

            # Paso 1: Crear entidad
            entity = self.create_business_entity(application)

            # Paso 2: Cargar documentos
            self.upload_documents(entity['id'], application['documents'])

            # Paso 3: Análisis de IA
            analysis = self.request_ai_analysis(entity['id'])

            # Paso 4: Verificar UBOs
            verified_owners = self.verify_beneficial_owners(
                entity['id'],
                application['beneficial_owners']
            )

            # Paso 5: Tomar decisión
            status = self.make_decision(entity['id'], analysis)

            print('\n✨ ¡Proceso KYB completado exitosamente!')

            return {
                'success': True,
                'entityId': entity['id'],
                'status': status,
                'riskScore': analysis['riskScore'],
                'findings': analysis['findings'],
                'nextSteps': analysis['nextSteps']
            }

        except Exception as e:
            print(f'❌ Proceso KYB falló: {str(e)}')

            return {
                'success': False,
                'entityId': '',
                'status': 'rejected',
                'riskScore': 100,
                'findings': {'error': str(e)},
                'nextSteps': ['Contactar soporte']
            }

# Example usage
if __name__ == '__main__':
    processor = KYBProcessor(GUENO_API_KEY)

    application = {
        'business_id': 'business_12345',
        'legal_name': 'Tech Solutions Sociedade Anônima',
        'trade_name': 'Tech Solutions',
        'tax_id': '12.345.678/0001-90',
        'country_code': 'BR',
        'incorporation_date': '2020-06-15',
        'industry': 'Software Development',
        'website': 'https://techsolutions.com.br',
        'employee_count': 50,
        'revenue': 5000000,
        'address': {
            'street': 'Av. Paulista, 1000',
            'city': 'São Paulo',
            'state': 'SP',
            'postalCode': '01310-100',
            'country': 'BR'
        },
        'contact_email': 'contact@techsolutions.com.br',
        'contact_phone': '+55 11 1234-5678',
        'expected_monthly_volume': 250000,
        'beneficial_owners': [
            {
                'first_name': 'Carlos',
                'last_name': 'Silva',
                'date_of_birth': '1975-08-22',
                'nationality': 'BR',
                'ownership_percentage': 60,
                'is_pep': False,
                'id_number': '123.456.789-00'
            },
            {
                'first_name': 'Ana',
                'last_name': 'Costa',
                'date_of_birth': '1980-03-15',
                'nationality': 'BR',
                'ownership_percentage': 40,
                'is_pep': False,
                'id_number': '987.654.321-00'
            }
        ],
        'documents': [
            {'type': 'articles_of_incorporation', 'file_path': './docs/contrato_social.pdf'},
            {'type': 'tax_certificate', 'file_path': './docs/cnpj_certificate.pdf'},
            {'type': 'business_license', 'file_path': './docs/alvara.pdf'},
            {'type': 'proof_of_address', 'file_path': './docs/comprovante.pdf'}
        ]
    }

    result = processor.process_kyb(application)

    print('\n📊 Resultado Final:')
    print(result)

Salida Esperada

Cuando ejecutes el flujo de trabajo completo, verás:
🚀 Iniciando proceso de verificación KYB...

📋 Creando entidad empresarial...
✅ Entidad creada: 660e9511-f39c-52e5-b827-557766551111

📄 Cargando 4 documentos...
  ✅ Cargado: articles_of_incorporation
  ✅ Cargado: tax_certificate
  ✅ Cargado: business_license
  ✅ Cargado: proof_of_address

🤖 Solicitando análisis de IA...
✅ Análisis completo. Puntuación de Riesgo: 35

👥 Verificando 2 beneficiarios finales...
  ✅ Verificado: Carlos Silva
  ✅ Verificado: Ana Costa

⚖️  Tomando decisión KYB...
🔍 Solicitando debida diligencia reforzada...
📧 Enviando notificación de additional_info_required...

✨ ¡Proceso KYB completado exitosamente!

📊 Resultado Final:
{
  "success": true,
  "entityId": "660e9511-f39c-52e5-b827-557766551111",
  "status": "pending",
  "riskScore": 35,
  "findings": {
    "documentVerification": "verified",
    "sanctionsScreening": "clear",
    "adverseMedia": "minor_flags"
  },
  "nextSteps": [
    "Proporcionar estados financieros",
    "Enviar diagrama de estructura de propiedad",
    "Documentar origen de fondos"
  ]
}

Pruebas

Prueba el flujo de trabajo KYB con datos de ejemplo:
# Instalar dependencias
npm install axios form-data
# o
pip install requests

# Configurar tu clave API
export GUENO_API_KEY="tu_clave_api_aqui"

# Ejecutar el ejemplo
node kyb-example.ts
# o
python kyb_example.py

Consideraciones de Producción

Manejo de Errores

try {
  const result = await kybProcessor.processKYB(application);
} catch (error) {
  if (error.response?.status === 401) {
    console.error('Clave API inválida');
  } else if (error.response?.status === 429) {
    console.error('Límite de tasa excedido - reintentar en 60s');
  } else {
    console.error('Proceso KYB falló:', error.message);
  }
}

Integración de Webhooks

Configura webhooks para recibir actualizaciones en tiempo real:
app.post('/webhooks/kyb', (req, res) => {
  const { event, entityId, status } = req.body;

  switch (status) {
    case 'approved':
      // Habilitar funcionalidades empresariales
      enableBusinessAccount(entityId);
      break;

    case 'additional_info_required':
      // Solicitar más documentos
      requestAdditionalDocs(entityId);
      break;

    case 'manual_review':
      // Notificar al equipo de cumplimiento
      alertComplianceTeam(entityId);
      break;
  }

  res.sendStatus(200);
});

Próximos Pasos

Descripción de KYB

Comprender conceptos y beneficios de KYB

Flujo de Trabajo KYB

Proceso detallado paso a paso

Requisitos de Datos

Campos y documentos requeridos

Referencia de API

Documentación completa de la API