Visão Geral
Este guia fornece uma implementação completa e pronta para produção de verificação KYB (Know Your Business) usando a API da gu1. Você pode copiar e adaptar este código para sua aplicação.Pré-requisitos
- Chave de API da gu1 (obtenha uma aqui)
- Node.js 18+ ou Python 3.8+
- Conhecimento básico de APIs RESTful
Implementação Completa
Node.js / TypeScript
Implementação completa de KYB com TypeScript:Copy
Ask AI
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 {
/**
* Step 1: Create Business Entity
*/
async createBusinessEntity(application: BusinessApplication): Promise<any> {
console.log('📋 Creating business entity...');
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(`✅ Entity created: ${response.data.entity.id}`);
return response.data.entity;
}
/**
* Step 2: Upload Verification Documents
*/
async uploadDocuments(entityId: string, documents: DocumentUpload[]): Promise<any[]> {
console.log(`📄 Uploading ${documents.length} documents...`);
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(` ✅ Uploaded: ${doc.type}`);
uploadResults.push(response.data);
}
return uploadResults;
}
/**
* Step 3: Request AI Analysis
*/
async requestAIAnalysis(entityId: string): Promise<any> {
console.log('🤖 Requesting AI analysis...');
const response = await apiClient.post(`/entities/${entityId}/ai-analysis`, {
analysisType: 'kyb_verification',
includeDocuments: true,
checkSanctions: true,
checkAdverseMedia: true,
checkUBOs: true
});
console.log(`✅ Analysis complete. Risk Score: ${response.data.riskScore}`);
return response.data;
}
/**
* Step 4: Verify Beneficial Owners
*/
async verifyBeneficialOwners(entityId: string, owners: BeneficialOwner[]): Promise<any[]> {
console.log(`👥 Verifying ${owners.length} beneficial owners...`);
const verifiedOwners = [];
for (const owner of owners) {
// Create person entity for 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;
// Run KYC check on UBO
const kycResponse = await apiClient.post(`/entities/${ubo.id}/ai-analysis`, {
analysisType: 'kyc_verification',
checkPEP: true,
checkSanctions: true
});
// Create relationship
await apiClient.post('/relationships', {
fromEntityId: entityId,
toEntityId: ubo.id,
relationshipType: 'beneficial_owner',
metadata: {
ownershipPercentage: owner.ownershipPercentage
}
});
console.log(` ✅ Verified: ${owner.firstName} ${owner.lastName}`);
verifiedOwners.push({
...ubo,
kycStatus: kycResponse.data.status,
riskScore: kycResponse.data.riskScore
});
}
return verifiedOwners;
}
/**
* Step 5: Make Decision Based on Risk
*/
async makeDecision(entityId: string, analysis: any): Promise<string> {
console.log('⚖️ Making KYB decision...');
const { riskScore, riskLevel } = analysis;
if (riskScore < 30) {
// Low Risk - Auto Approve
await this.approveEntity(entityId, analysis);
return 'approved';
} else if (riskScore < 70) {
// Medium Risk - Enhanced Due Diligence
await this.requestEnhancedDueDiligence(entityId, analysis);
return 'pending';
} else {
// High Risk - Manual Review
await this.flagForManualReview(entityId, analysis);
return 'manual_review';
}
}
/**
* Approve Low-Risk Entity
*/
private async approveEntity(entityId: string, analysis: any): Promise<void> {
console.log('✅ Auto-approving low-risk entity...');
// Update entity status
await apiClient.patch(`/entities/${entityId}`, {
attributes: {
kybStatus: 'approved',
approvedAt: new Date().toISOString(),
approvedBy: 'automated_system',
riskLevel: 'low',
reviewNotes: 'Low risk - auto-approved based on AI analysis'
}
});
// Setup monitoring
await this.setupMonitoring(entityId);
// Send notification
await this.sendStatusNotification(entityId, 'approved');
}
/**
* Request Enhanced Due Diligence
*/
private async requestEnhancedDueDiligence(entityId: string, analysis: any): Promise<void> {
console.log('🔍 Requesting enhanced due diligence...');
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');
}
/**
* Flag for Manual Review
*/
private async flagForManualReview(entityId: string, analysis: any): Promise<void> {
console.log('⚠️ Flagging for manual review...');
// Create review task
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');
}
/**
* Setup Ongoing Monitoring
*/
private async setupMonitoring(entityId: string): Promise<void> {
console.log('📊 Setting up ongoing monitoring...');
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'
}
]
});
}
/**
* Send Status Notification
*/
private async sendStatusNotification(entityId: string, status: string): Promise<void> {
console.log(`📧 Sending ${status} notification...`);
// Your notification logic here (email, webhook, etc.)
await apiClient.post('/webhooks/send', {
event: 'kyb_status_changed',
entityId: entityId,
status: status,
timestamp: new Date().toISOString()
});
}
/**
* Complete KYB Workflow
*/
async processKYB(application: BusinessApplication): Promise<KYBResult> {
try {
console.log('🚀 Starting KYB verification process...\n');
// Step 1: Create entity
const entity = await this.createBusinessEntity(application);
// Step 2: Upload documents
await this.uploadDocuments(entity.id, application.documents);
// Step 3: AI Analysis
const analysis = await this.requestAIAnalysis(entity.id);
// Step 4: Verify UBOs
const verifiedOwners = await this.verifyBeneficialOwners(
entity.id,
application.beneficialOwners
);
// Step 5: Make decision
const status = await this.makeDecision(entity.id, analysis);
console.log('\n✨ KYB process completed successfully!');
return {
success: true,
entityId: entity.id,
status: status as any,
riskScore: analysis.riskScore,
findings: analysis.findings,
nextSteps: analysis.nextSteps
};
} catch (error: any) {
console.error('❌ KYB process failed:', error.message);
return {
success: false,
entityId: '',
status: 'rejected',
riskScore: 100,
findings: { error: error.message },
nextSteps: ['Contact support']
};
}
}
}
// 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: '[email protected]',
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📊 Final Result:');
console.log(JSON.stringify(result, null, 2));
}
// Run the example
main().catch(console.error);
Implementação em Python
Fluxo de trabalho completo de KYB em Python:Copy
Ask AI
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:
"""Step 1: Create business entity"""
print('📋 Creating business entity...')
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'✅ Entity created: {entity["id"]}')
return entity
def upload_documents(self, entity_id: str, documents: List[Dict]) -> List[Dict]:
"""Step 2: Upload verification documents"""
print(f'📄 Uploading {len(documents)} documents...')
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' ✅ Uploaded: {doc["type"]}')
upload_results.append(response.json())
return upload_results
def request_ai_analysis(self, entity_id: str) -> Dict:
"""Step 3: Request AI analysis"""
print('🤖 Requesting AI analysis...')
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'✅ Analysis complete. Risk Score: {analysis["riskScore"]}')
return analysis
def verify_beneficial_owners(self, entity_id: str, owners: List[Dict]) -> List[Dict]:
"""Step 4: Verify beneficial owners"""
print(f'👥 Verifying {len(owners)} beneficial owners...')
verified_owners = []
for owner in owners:
# Create person entity for 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']
# Run KYC check
kyc_response = requests.post(
f'{GUENO_API_URL}/entities/{ubo["id"]}/ai-analysis',
headers=self.headers,
json={
'analysisType': 'kyc_verification',
'checkPEP': True,
'checkSanctions': True
}
)
# Create relationship
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' ✅ Verified: {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:
"""Step 5: Make decision based on risk"""
print('⚖️ Making KYB decision...')
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):
"""Approve low-risk entity"""
print('✅ Auto-approving low-risk entity...')
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):
"""Request enhanced due diligence"""
print('🔍 Requesting enhanced due diligence...')
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):
"""Flag for manual review"""
print('⚠️ Flagging for manual review...')
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):
"""Setup ongoing monitoring"""
print('📊 Setting up ongoing monitoring...')
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):
"""Send status notification"""
print(f'📧 Sending {status} notification...')
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:
"""Complete KYB workflow"""
try:
print('🚀 Starting KYB verification process...\n')
# Step 1: Create entity
entity = self.create_business_entity(application)
# Step 2: Upload documents
self.upload_documents(entity['id'], application['documents'])
# Step 3: AI Analysis
analysis = self.request_ai_analysis(entity['id'])
# Step 4: Verify UBOs
verified_owners = self.verify_beneficial_owners(
entity['id'],
application['beneficial_owners']
)
# Step 5: Make decision
status = self.make_decision(entity['id'], analysis)
print('\n✨ KYB process completed successfully!')
return {
'success': True,
'entityId': entity['id'],
'status': status,
'riskScore': analysis['riskScore'],
'findings': analysis['findings'],
'nextSteps': analysis['nextSteps']
}
except Exception as e:
print(f'❌ KYB process failed: {str(e)}')
return {
'success': False,
'entityId': '',
'status': 'rejected',
'riskScore': 100,
'findings': {'error': str(e)},
'nextSteps': ['Contact support']
}
# 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': '[email protected]',
'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📊 Final Result:')
print(result)
Saída Esperada
Quando você executar o fluxo de trabalho completo, verá:Copy
Ask AI
🚀 Starting KYB verification process...
📋 Creating business entity...
✅ Entity created: 660e9511-f39c-52e5-b827-557766551111
📄 Uploading 4 documents...
✅ Uploaded: articles_of_incorporation
✅ Uploaded: tax_certificate
✅ Uploaded: business_license
✅ Uploaded: proof_of_address
🤖 Requesting AI analysis...
✅ Analysis complete. Risk Score: 35
👥 Verifying 2 beneficial owners...
✅ Verified: Carlos Silva
✅ Verified: Ana Costa
⚖️ Making KYB decision...
🔍 Requesting enhanced due diligence...
📧 Sending additional_info_required notification...
✨ KYB process completed successfully!
📊 Final Result:
{
"success": true,
"entityId": "660e9511-f39c-52e5-b827-557766551111",
"status": "pending",
"riskScore": 35,
"findings": {
"documentVerification": "verified",
"sanctionsScreening": "clear",
"adverseMedia": "minor_flags"
},
"nextSteps": [
"Provide financial statements",
"Submit ownership structure diagram",
"Document source of funds"
]
}
Testes
Teste o fluxo de trabalho de KYB com dados de exemplo:Copy
Ask AI
# Install dependencies
npm install axios form-data
# or
pip install requests
# Set your API key
export GUENO_API_KEY="your_api_key_here"
# Run the example
node kyb-example.ts
# or
python kyb_example.py
Considerações para Produção
Tratamento de Erros
Copy
Ask AI
try {
const result = await kybProcessor.processKYB(application);
} catch (error) {
if (error.response?.status === 401) {
console.error('Invalid API key');
} else if (error.response?.status === 429) {
console.error('Rate limit exceeded - retry in 60s');
} else {
console.error('KYB process failed:', error.message);
}
}
Integração de Webhooks
Configure webhooks para receber atualizações em tempo real:Copy
Ask AI
app.post('/webhooks/kyb', (req, res) => {
const { event, entityId, status } = req.body;
switch (status) {
case 'approved':
// Enable business features
enableBusinessAccount(entityId);
break;
case 'additional_info_required':
// Request more documents
requestAdditionalDocs(entityId);
break;
case 'manual_review':
// Notify compliance team
alertComplianceTeam(entityId);
break;
}
res.sendStatus(200);
});