Skip to content

Product Connections

How products talk to each other.


Connection Model

                         ┌─────────────┐
                         │   YeboID    │
                         │  (Identity) │
                         └──────┬──────┘
                                │ Auth tokens
        ┌───────────────────────┼───────────────────────┐
        │                       │                       │
        ▼                       ▼                       ▼
┌─────────────┐         ┌─────────────┐         ┌─────────────┐
│ YeboShops   │◄───────►│  YeboSafe   │◄───────►│  YeboJobs   │
│ (Commerce)  │ escrow  │ (Payments)  │ payroll │  (Jobs)     │
└─────────────┘         └──────┬──────┘         └─────────────┘
        │                      │                       │
        │                      │                       │
        ▼                      ▼                       ▼
┌─────────────┐         ┌─────────────┐         ┌─────────────┐
│   Eneza     │         │  YeboLink   │         │ YeboLearn   │
│   (Ads)     │◄───────►│  (Comms)    │◄───────►│ (Learning)  │
└─────────────┘  notify └─────────────┘  notify └─────────────┘

Connection Types

1. Authentication (via YeboID)

Every product validates JWTs from YeboID.

javascript
// Any product
const payload = jwt.verify(token, YEBOID_JWT_SECRET);
const userId = payload.userId;
const handle = payload.handle;

2. Direct API Calls

Products call each other's APIs:

javascript
// YeboShops calling YeboSafe
const escrow = await fetch('https://api.yebosafe.com/escrows', {
  method: 'POST',
  headers: { 'X-Service-Key': SERVICE_KEY },
  body: JSON.stringify({ buyerId, sellerId, amount })
});

3. Event-Driven (Pub/Sub)

Products publish events, others subscribe:

javascript
// YeboShops publishes
await events.publish('order.completed', {
  orderId: '123',
  buyerId: 'abc',
  sellerId: 'def',
  amount: 5000
});

// Eneza subscribes
events.subscribe('order.completed', async (event) => {
  // Suggest boost for successful seller
  await suggestBoost(event.sellerId);
});

Key Integration Points

Commerce ↔ Payments

YeboShops uses YeboSafe for:

  • Escrow on every transaction
  • Seller payouts
  • Refunds
javascript
// Create order with escrow
async function createOrder(order) {
  const escrow = await yebosafe.createEscrow({
    buyerId: order.buyerId,
    sellerId: order.sellerId,
    amount: order.total,
    reference: order.id
  });
  
  return { ...order, escrowId: escrow.id };
}

Jobs ↔ Learning

YeboJobs reads skills from YeboLearn:

javascript
// Get user's certified skills
async function getSkills(userId) {
  const certificates = await yebolearn.getCertificates(userId);
  return certificates.map(c => c.skills).flat();
}

// Match jobs to skills
async function matchJobs(userId) {
  const skills = await getSkills(userId);
  return await searchJobs({ skills });
}

Commerce ↔ Advertising

YeboShops can boost via Eneza:

javascript
// Boost a listing
async function boostListing(listingId, budget) {
  const listing = await db.listings.get(listingId);
  
  const campaign = await eneza.createCampaign({
    media: listing.photos,
    caption: `${listing.title} - ${listing.price}`,
    link: `https://yeboshops.com/l/${listingId}`,
    budget
  });
  
  return campaign;
}

All Products ↔ Communications

YeboLink sends messages for all:

javascript
// Notification examples
await yebolink.send({
  to: user.phone,
  channel: 'whatsapp',
  content: { text: 'Your order shipped!' }
});

Data Sharing

What's Shared

DataOwnerShared With
User identityYeboIDAll
BalanceYeboSafeAll (read)
SkillsYeboLearnYeboJobs
ReputationYeboShopsYeboJobs
VerificationYeboVerifyAll

How It's Accessed

javascript
// Get full user context
async function getUserContext(userId) {
  const [profile, wallet, skills, reputation] = await Promise.all([
    yeboid.getProfile(userId),
    yebosafe.getWallet(userId),
    yebolearn.getSkills(userId),
    yeboshops.getReputation(userId)
  ]);
  
  return { profile, wallet, skills, reputation };
}

Cross-Product Flows

Sell → Source → Sell Again

1. YeboShops: User sells 20 phone cases

2. Orchestrator: Detects success pattern

3. Orchestrator → YeboNa: "Find more phone cases"

4. YeboNa: Shows suppliers

5. YeboSafe: Holds escrow for order

6. YeboNa: Tracks shipment

7. YeboShops: Auto-lists new inventory

8. Eneza: Distributes to 12K publishers

Learn → Work → Earn

1. YeboLearn: User completes React course

2. YeboLearn → YeboJobs: Add skills

3. YeboJobs: Auto-search matching jobs

4. YeboJobs: Apply to top matches

5. YeboJobs: User gets hired

6. YeboLink: Send contract

7. YeboSafe: Receive payment

Service Discovery

Each service registers its capabilities:

javascript
const serviceRegistry = {
  yeboshops: {
    url: 'https://api.yeboshops.com',
    capabilities: ['listings', 'orders', 'reviews'],
    events: ['listing.created', 'order.completed']
  },
  yebosafe: {
    url: 'https://api.yebosafe.com',
    capabilities: ['wallets', 'escrows', 'transfers'],
    events: ['payment.completed', 'escrow.released']
  },
  // ...
};

Error Handling

Retry Logic

javascript
async function callService(service, endpoint, data) {
  for (let attempt = 1; attempt <= 3; attempt++) {
    try {
      return await fetch(`${service.url}${endpoint}`, {
        method: 'POST',
        body: JSON.stringify(data)
      });
    } catch (error) {
      if (attempt === 3) throw error;
      await sleep(attempt * 1000);
    }
  }
}

Fallback

javascript
async function getBalance(userId) {
  try {
    return await yebosafe.getBalance(userId);
  } catch {
    // Return cached balance on error
    return await cache.get(`balance:${userId}`) || 0;
  }
}

Monitoring

Cross-Service Tracing

javascript
// Add trace ID to all requests
const traceId = crypto.randomUUID();

await yebosafe.createEscrow({
  ...data,
  _traceId: traceId
});

// All logs include traceId
logger.info('Creating escrow', { traceId, data });

One chat. Everything done.