Tajo 사전 이용 신청

이름과 이메일 주소 또는 전화번호를 입력해 주세요. Tajo 이용 방법을 안내해 드립니다.

거래 관리

Brevo CRM 거래 API를 사용하면 Tajo 플랫폼 안에서 영업 파이프라인을 관리하고, 거래 진행 상황을 추적하며, 매출 관련 워크플로를 자동화할 수 있습니다.

개요

거래 관리는 다음과 같은 목적에 필수적입니다:

  • 영업 파이프라인 추적: 단계 기반 진행과 매출 예측
  • 매출 기여도 분석: 거래를 이커머스 고객 활동과 연결
  • 자동 후속 조치: 거래 단계 변경으로 트리거
  • 팀 성과 분석: 수주/실주 추적과 전환율 측정
  • 로열티 프로그램 연동: 거래 성사 시 포인트 지급

빠른 시작

거래 생성

POST https://api.brevo.com/v3/crm/deals
Content-Type: application/json
api-key: YOUR_API_KEY
{
"name": "Acme Corp - Enterprise Loyalty Package",
"attributes": {
"deal_stage": "Qualified",
"amount": 75000,
"close_date": "2026-06-30",
"pipeline": "Enterprise Sales",
"deal_owner": "[email protected]",
"deal_type": "new_business",
"probability": 60,
"company_id": "comp_123456789",
"contact_id": "contact_987654321",
"source": "inbound_lead",
"loyalty_points_bonus": 5000,
"contract_length_months": 12
}
}

응답

{
"id": "deal_abc123def456",
"name": "Acme Corp - Enterprise Loyalty Package",
"created_at": "2026-01-25T14:30:00Z",
"updated_at": "2026-01-25T14:30:00Z"
}

거래 조회

전체 거래 목록

필터링과 페이지네이션으로 거래를 조회합니다:

GET https://api.brevo.com/v3/crm/deals?limit=50&offset=0&sort=desc
Content-Type: application/json
api-key: YOUR_API_KEY

응답

{
"items": [
{
"id": "deal_abc123def456",
"name": "Acme Corp - Enterprise Loyalty Package",
"attributes": {
"deal_stage": "Qualified",
"amount": 75000,
"close_date": "2026-06-30",
"pipeline": "Enterprise Sales",
"deal_owner": "[email protected]"
},
"created_at": "2026-01-25T14:30:00Z",
"updated_at": "2026-01-25T14:30:00Z"
}
],
"total": 1
}

단계별 거래 필터링

GET https://api.brevo.com/v3/crm/deals?filters[attributes.deal_stage]=Negotiation&sort=attributes.amount:desc

단일 거래 조회

GET https://api.brevo.com/v3/crm/deals/{deal_id}
Content-Type: application/json
api-key: YOUR_API_KEY

거래 업데이트

거래 속성 업데이트

PATCH https://api.brevo.com/v3/crm/deals/{deal_id}
Content-Type: application/json
api-key: YOUR_API_KEY
{
"attributes": {
"deal_stage": "Negotiation",
"amount": 82000,
"probability": 75,
"next_activity_date": "2026-02-15"
}
}

응답

{
"id": "deal_abc123def456",
"updated_at": "2026-02-01T10:15:00Z"
}

거래 파이프라인 관리

파이프라인 단계 구성

이커머스 영업에 맞는 체계적인 거래 진행 방식을 구현합니다:

class TajoDealPipeline {
constructor() {
this.dealsApi = new DealsApi();
this.stages = [
{ name: 'Lead', probability: 10, actions: ['qualify_lead'] },
{ name: 'Qualified', probability: 25, actions: ['schedule_demo'] },
{ name: 'Demo', probability: 40, actions: ['send_proposal'] },
{ name: 'Proposal', probability: 60, actions: ['negotiate_terms'] },
{ name: 'Negotiation', probability: 80, actions: ['finalize_contract'] },
{ name: 'Closed Won', probability: 100, actions: ['onboard_customer', 'award_loyalty_points'] },
{ name: 'Closed Lost', probability: 0, actions: ['analyze_loss', 'schedule_followup'] }
];
}
async advanceDealStage(dealId, newStage) {
const deal = await this.dealsApi.getDeal(dealId);
const stageConfig = this.stages.find(s => s.name === newStage);
if (!stageConfig) {
throw new Error(`Invalid stage: ${newStage}`);
}
// Update deal with new stage
await this.dealsApi.updateDeal(dealId, {
attributes: {
deal_stage: newStage,
probability: stageConfig.probability,
stage_changed_at: new Date().toISOString(),
previous_stage: deal.attributes.deal_stage
}
});
// Execute stage-specific actions
for (const action of stageConfig.actions) {
await this.executeStageAction(dealId, action, deal);
}
return { dealId, newStage, probability: stageConfig.probability };
}
async executeStageAction(dealId, action, deal) {
switch (action) {
case 'award_loyalty_points':
if (deal.attributes.loyalty_points_bonus > 0) {
await loyaltyService.awardCorporatePoints(
deal.attributes.company_id,
deal.attributes.loyalty_points_bonus,
{ reason: 'Deal closure bonus', dealId }
);
}
break;
case 'onboard_customer':
await this.triggerOnboardingWorkflow(deal);
break;
case 'analyze_loss':
await this.logDealLoss(dealId, deal);
break;
case 'schedule_followup':
await this.createFollowUpTask(dealId, deal);
break;
}
}
}

거래 예측

파이프라인 데이터를 기반으로 매출 예측을 생성합니다:

class DealForecasting {
async generateForecast(pipeline, timeframe) {
const deals = await this.dealsApi.getDeals({
filters: {
'attributes.pipeline': pipeline,
'attributes.close_date': `<${timeframe.end}`,
'attributes.deal_stage': '!Closed Lost'
}
});
const forecast = {
pipeline,
timeframe,
totalPipeline: 0,
weightedPipeline: 0,
byStage: {},
byOwner: {},
byMonth: {}
};
for (const deal of deals.items) {
const amount = deal.attributes.amount || 0;
const probability = deal.attributes.probability || 0;
const weighted = amount * (probability / 100);
const stage = deal.attributes.deal_stage;
const owner = deal.attributes.deal_owner;
const month = new Date(deal.attributes.close_date).toISOString().slice(0, 7);
forecast.totalPipeline += amount;
forecast.weightedPipeline += weighted;
// Aggregate by stage
if (!forecast.byStage[stage]) {
forecast.byStage[stage] = { count: 0, total: 0, weighted: 0 };
}
forecast.byStage[stage].count++;
forecast.byStage[stage].total += amount;
forecast.byStage[stage].weighted += weighted;
// Aggregate by owner
if (!forecast.byOwner[owner]) {
forecast.byOwner[owner] = { count: 0, total: 0, weighted: 0 };
}
forecast.byOwner[owner].count++;
forecast.byOwner[owner].total += amount;
forecast.byOwner[owner].weighted += weighted;
// Aggregate by month
if (!forecast.byMonth[month]) {
forecast.byMonth[month] = { count: 0, total: 0, weighted: 0 };
}
forecast.byMonth[month].count++;
forecast.byMonth[month].total += amount;
forecast.byMonth[month].weighted += weighted;
}
return forecast;
}
}

이커머스 거래 자동화

주문에서 거래 자동 생성

고액 이커머스 활동에서 거래를 자동으로 생성합니다:

class EcommerceDealAutomation {
async createDealFromOrder(order) {
// Only create deals for high-value or B2B orders
if (order.total < 5000 && !order.isB2B) return null;
const deal = {
name: `${order.customerName} - Order #${order.id}`,
attributes: {
deal_stage: order.isB2B ? 'Qualified' : 'Proposal',
amount: order.total,
close_date: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString(),
pipeline: order.isB2B ? 'Enterprise Sales' : 'E-Commerce Upsell',
deal_type: 'new_business',
source: 'ecommerce_order',
order_id: order.id,
product_categories: order.categories.join(', '),
contact_id: order.contactId,
company_id: order.companyId || null,
loyalty_points_bonus: Math.floor(order.total * 0.1)
}
};
return await this.dealsApi.createDeal(deal);
}
async createRenewalDeal(subscription) {
const renewalDate = new Date(subscription.expiresAt);
const createDate = new Date(renewalDate.getTime() - 90 * 24 * 60 * 60 * 1000);
if (new Date() < createDate) return null;
const deal = {
name: `${subscription.customerName} - Renewal`,
attributes: {
deal_stage: 'Qualified',
amount: subscription.annualValue,
close_date: subscription.expiresAt,
pipeline: 'Renewals',
deal_type: 'renewal',
probability: 70,
source: 'auto_renewal',
subscription_id: subscription.id,
contact_id: subscription.contactId,
company_id: subscription.companyId,
contract_length_months: 12,
loyalty_points_bonus: Math.floor(subscription.annualValue * 0.05)
}
};
return await this.dealsApi.createDeal(deal);
}
}

거래 기반 로열티 워크플로

class DealLoyaltyIntegration {
async onDealStageChange(dealId, oldStage, newStage) {
const deal = await this.dealsApi.getDeal(dealId);
// Award milestone points at key stages
const milestoneStages = {
'Demo': 100,
'Proposal': 250,
'Closed Won': deal.attributes.loyalty_points_bonus || 1000
};
if (milestoneStages[newStage] && deal.attributes.contact_id) {
await loyaltyService.awardPoints(
deal.attributes.contact_id,
milestoneStages[newStage],
{ reason: `Deal milestone: ${newStage}`, dealId }
);
}
// Trigger tier evaluation on deal closure
if (newStage === 'Closed Won' && deal.attributes.company_id) {
const company = await this.companiesApi.getCompany(deal.attributes.company_id);
const newTotal = (company.attributes.annual_spend || 0) + deal.attributes.amount;
await this.companiesApi.updateCompany(deal.attributes.company_id, {
attributes: {
annual_spend: newTotal,
last_deal_closed: new Date().toISOString()
}
});
await this.tierManager.evaluateTierUpgrade(deal.attributes.company_id, newTotal);
}
}
}

거래 분석

파이프라인 성과 지표

class DealAnalytics {
async getPipelineMetrics(pipeline, timeframe) {
const allDeals = await this.dealsApi.getDeals({
filters: { 'attributes.pipeline': pipeline }
});
const closedDeals = allDeals.items.filter(
d => d.attributes.deal_stage === 'Closed Won' || d.attributes.deal_stage === 'Closed Lost'
);
const wonDeals = closedDeals.filter(d => d.attributes.deal_stage === 'Closed Won');
const lostDeals = closedDeals.filter(d => d.attributes.deal_stage === 'Closed Lost');
return {
totalDeals: allDeals.total,
openDeals: allDeals.total - closedDeals.length,
wonDeals: wonDeals.length,
lostDeals: lostDeals.length,
winRate: closedDeals.length > 0
? (wonDeals.length / closedDeals.length * 100).toFixed(1)
: 0,
totalRevenue: wonDeals.reduce((sum, d) => sum + (d.attributes.amount || 0), 0),
averageDealSize: wonDeals.length > 0
? wonDeals.reduce((sum, d) => sum + (d.attributes.amount || 0), 0) / wonDeals.length
: 0,
averageSalesCycle: this.calculateAverageSalesCycle(wonDeals),
loyaltyPointsAwarded: wonDeals.reduce(
(sum, d) => sum + (d.attributes.loyalty_points_bonus || 0), 0
)
};
}
calculateAverageSalesCycle(wonDeals) {
if (wonDeals.length === 0) return 0;
const totalDays = wonDeals.reduce((sum, deal) => {
const created = new Date(deal.created_at);
const closed = new Date(deal.attributes.stage_changed_at || deal.updated_at);
return sum + Math.floor((closed - created) / (1000 * 60 * 60 * 24));
}, 0);
return Math.round(totalDays / wonDeals.length);
}
}

API 메서드 레퍼런스

거래 CRUD 작업

// Create a new deal
const deal = await dealsApi.createDeal({
name: 'New Enterprise Deal',
attributes: {
deal_stage: 'Lead',
amount: 50000,
pipeline: 'Enterprise Sales'
}
});
// Get deal by ID
const deal = await dealsApi.getDeal('deal_abc123def456');
// Update deal attributes
await dealsApi.updateDeal('deal_abc123def456', {
attributes: {
deal_stage: 'Negotiation',
amount: 55000,
probability: 80
}
});
// Delete a deal
await dealsApi.deleteDeal('deal_abc123def456');
// List deals with filtering
const deals = await dealsApi.getDeals({
filters: {
'attributes.deal_stage': 'Qualified',
'attributes.amount': '>10000'
},
sort: 'attributes.amount:desc',
limit: 50
});

고급 쿼리

// Find deals closing this quarter
const quarterEnd = new Date();
quarterEnd.setMonth(quarterEnd.getMonth() + 3);
const closingDeals = await dealsApi.getDeals({
filters: {
'attributes.close_date': `<${quarterEnd.toISOString()}`,
'attributes.deal_stage': '!Closed Won,!Closed Lost'
}
});
// Find high-value stale deals (no update in 14 days)
const staleDate = new Date(Date.now() - 14 * 24 * 60 * 60 * 1000);
const staleDeals = await dealsApi.getDeals({
filters: {
'attributes.amount': '>25000',
'updated_at': `<${staleDate.toISOString()}`,
'attributes.deal_stage': '!Closed Won,!Closed Lost'
}
});
// Get deals by owner for performance review
const ownerDeals = await dealsApi.getDeals({
filters: {
'attributes.deal_owner': '[email protected]',
'attributes.deal_stage': 'Closed Won'
}
});

모범 사례

  1. 일관된 단계: 각 단계에서 기대되는 활동과 함께 파이프라인 단계를 명확히 정의합니다
  2. 성사 확률 관리: 예측 정확도를 높이려면 거래 성사 확률을 항상 최신 상태로 유지합니다
  3. 적시 업데이트: 파이프라인 가시성을 정확하게 유지하려면 거래 속성을 즉시 업데이트합니다
  4. 로열티 연동: 고객 유지를 위해 거래 성사와 로열티 포인트 지급을 연결합니다
  5. 자동화 워크플로: 단계 변경 트리거로 후속 작업을 자동화합니다
  6. 정기 파이프라인 점검: 주간 파이프라인 리뷰를 잡아 정체되거나 위험한 거래를 찾아냅니다

오류 처리

try {
const deal = await dealsApi.createDeal(dealData);
console.log('Deal created:', deal.id);
} catch (error) {
if (error.status === 400) {
console.error('Invalid deal data:', error.message);
} else if (error.status === 404) {
console.error('Associated company or contact not found');
} else if (error.status === 409) {
console.error('Duplicate deal detected');
} else {
console.error('Unexpected error:', error);
}
}

다음 단계

Tajo 사전 이용 신청

이름과 이메일 주소 또는 전화번호를 입력해 주세요. Tajo 이용 방법을 안내해 드립니다.

자동 감지
AI 어시스턴트

안녕하세요! 문서에 대해 무엇이든 물어보세요.