B2B Platform

B2B Marketplace: Toptan Ticaret Platformu

B2B e-ticaret platformu, toplu sipariş, teklif yönetimi (RFQ), özel fiyatlandırma. Alibaba, IndiaMART tarzı wholesale marketplace yazılımı.

🏢B2B vs B2C Farkları

B2B Marketplace, işletmeler arası toptan ticareti dijitalleştirir. Ortalama sipariş değeri B2C'den 15-20x daha yüksektir (50K-500K TL).

ÖzellikB2CB2B
Sipariş Miktarı1-5 adet100-10,000+ adet
Ortalama Sepet500-2,000 TL50K-500K TL
FiyatlandırmaSabit fiyatDinamik, müzakereli
ÖdemeKredi kartı, anındaVade, havale, açık hesap
Satış SüreciSelf-serviceTeklif, onay, sözleşme
KullanıcıBireyselŞirket (çoklu kullanıcı)

RFQ (Request for Quote) Sistemi

// RFQ (Teklif Talebi) Workflow
// 1. Alıcı teklif talebi oluşturur
// 2. Tedarikçiler teklif gönderir
// 3. Alıcı teklifleri karşılaştırır
// 4. Kazanan teklif siparişe dönüşür

// Node.js + MongoDB RFQ API
const express = require('express');
const router = express.Router();

// RFQ Schema
const RFQSchema = {
    rfq_id: String,
    buyer_company_id: String,
    product_name: String,
    quantity: Number,
    unit: String,  // adet, kg, ton
    specifications: {
        material: String,
        dimensions: String,
        quality: String,
        // ... diğer teknik özellikler
    },
    delivery_location: String,
    desired_delivery_date: Date,
    budget_range: {
        min: Number,
        max: Number
    },
    attachment_urls: [String],  // Teknik doküman, çizim
    status: String,  // draft, published, closed, awarded
    quotes: [{
        supplier_id: String,
        unit_price: Number,
        total_price: Number,
        delivery_time: Number,  // gün
        payment_terms: String,  // 30 gün vade, %50 peşin vb.
        validity_days: Number,  // Teklif geçerlilik süresi
        notes: String,
        submitted_at: Date
    }],
    created_at: Date,
    deadline: Date
};

// 1. RFQ oluştur
router.post('/rfq/create', async (req, res) => {
    const rfq = {
        rfq_id: generateRFQId(),
        buyer_company_id: req.user.company_id,
        product_name: req.body.product_name,
        quantity: req.body.quantity,
        specifications: req.body.specifications,
        delivery_location: req.body.delivery_location,
        desired_delivery_date: req.body.delivery_date,
        budget_range: req.body.budget_range,
        status: 'draft',
        quotes: [],
        created_at: new Date(),
        deadline: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000)  // 7 gün
    };

    await db.collection('rfqs').insertOne(rfq);

    // İlgili tedarikçilere bildirim gönder
    const suppliers = await findRelevantSuppliers(rfq);
    await notifySuppliers(suppliers, rfq);

    res.json({ success: true, rfq_id: rfq.rfq_id });
});

// 2. Tedarikçi teklif gönderir
router.post('/rfq/:rfq_id/quote', async (req, res) => {
    const rfq = await db.collection('rfqs').findOne({ rfq_id: req.params.rfq_id });

    if (rfq.status !== 'published') {
        return res.status(400).json({ error: 'RFQ not accepting quotes' });
    }

    const quote = {
        supplier_id: req.user.company_id,
        unit_price: req.body.unit_price,
        total_price: req.body.unit_price * rfq.quantity,
        delivery_time: req.body.delivery_time,
        payment_terms: req.body.payment_terms,
        validity_days: req.body.validity_days || 30,
        notes: req.body.notes,
        submitted_at: new Date()
    };

    await db.collection('rfqs').updateOne(
        { rfq_id: req.params.rfq_id },
        { $push: { quotes: quote } }
    );

    // Alıcıya yeni teklif bildirimi
    await notifyBuyer(rfq.buyer_company_id, quote);

    res.json({ success: true });
});

// 3. Teklif karşılaştırma
router.get('/rfq/:rfq_id/compare', async (req, res) => {
    const rfq = await db.collection('rfqs').findOne({ rfq_id: req.params.rfq_id });

    // Teklifleri sırala (fiyat, teslimat süresi, tedarikçi puanı)
    const rankedQuotes = rfq.quotes.map(quote => {
        const supplier = await getSupplierInfo(quote.supplier_id);

        return {
            ...quote,
            supplier_name: supplier.name,
            supplier_rating: supplier.rating,
            supplier_completed_orders: supplier.completed_orders,
            // Skor hesaplama (örnek)
            score: calculateQuoteScore(quote, supplier)
        };
    }).sort((a, b) => b.score - a.score);

    res.json({ rfq, quotes: rankedQuotes });
});

// Skor hesaplama (ağırlıklı)
function calculateQuoteScore(quote, supplier) {
    const priceScore = 100 - (quote.total_price / budget_max * 100);  // Düşük fiyat = yüksek skor
    const deliveryScore = 100 - (quote.delivery_time / 60 * 100);  // Hızlı = yüksek skor
    const supplierScore = supplier.rating * 20;  // 5 yıldız = 100 puan

    // Ağırlıklar: fiyat %50, teslimat %30, tedarikçi %20
    return (priceScore * 0.5) + (deliveryScore * 0.3) + (supplierScore * 0.2);
}

// 4. Kazanan teklifi seç ve siparişe dönüştür
router.post('/rfq/:rfq_id/award', async (req, res) => {
    const { supplier_id } = req.body;

    const rfq = await db.collection('rfqs').findOne({ rfq_id: req.params.rfq_id });
    const winningQuote = rfq.quotes.find(q => q.supplier_id === supplier_id);

    // RFQ'yu kapat
    await db.collection('rfqs').updateOne(
        { rfq_id: req.params.rfq_id },
        { $set: { status: 'awarded', winner: supplier_id } }
    );

    // Purchase Order (PO) oluştur
    const po = {
        po_number: generatePONumber(),
        rfq_id: rfq.rfq_id,
        buyer_id: rfq.buyer_company_id,
        supplier_id: supplier_id,
        product: rfq.product_name,
        quantity: rfq.quantity,
        unit_price: winningQuote.unit_price,
        total_amount: winningQuote.total_price,
        delivery_date: new Date(Date.now() + winningQuote.delivery_time * 24 * 60 * 60 * 1000),
        payment_terms: winningQuote.payment_terms,
        status: 'pending_approval',
        created_at: new Date()
    };

    await db.collection('purchase_orders').insertOne(po);

    // Kazanana bildirim
    await notifySupplier(supplier_id, { type: 'rfq_won', po });

    // Diğer tedarikçilere bildirim (kaybettiler)
    const otherSuppliers = rfq.quotes.filter(q => q.supplier_id !== supplier_id);
    await notifyLosers(otherSuppliers, rfq);

    res.json({ success: true, po_number: po.po_number });
});

Özel Fiyatlandırma (Custom Pricing)

// Müşteriye özel fiyat listeleri (tiered pricing, volume discounts)
const PriceTierSchema = {
    product_id: String,
    base_price: Number,
    tiers: [
        {
            min_quantity: Number,
            max_quantity: Number,  // null = sınırsız
            unit_price: Number,
            discount_percentage: Number
        }
    ],
    customer_specific_prices: [
        {
            customer_id: String,
            unit_price: Number,
            valid_from: Date,
            valid_until: Date,
            notes: String  // "Yıllık anlaşma - %15 indirim"
        }
    ]
};

// Fiyat hesaplama fonksiyonu
async function calculatePrice(product_id, customer_id, quantity) {
    const pricing = await db.collection('pricing').findOne({ product_id });

    // 1. Müşteriye özel fiyat var mı kontrol et
    const customerPrice = pricing.customer_specific_prices.find(
        cp => cp.customer_id === customer_id &&
              new Date() >= cp.valid_from &&
              new Date() <= cp.valid_until
    );

    if (customerPrice) {
        return {
            unit_price: customerPrice.unit_price,
            total: customerPrice.unit_price * quantity,
            discount_reason: customerPrice.notes
        };
    }

    // 2. Miktar bazlı kademe fiyatlandırma
    const tier = pricing.tiers.find(
        t => quantity >= t.min_quantity &&
             (t.max_quantity === null || quantity <= t.max_quantity)
    );

    if (tier) {
        return {
            unit_price: tier.unit_price,
            total: tier.unit_price * quantity,
            discount_percentage: tier.discount_percentage,
            saved: (pricing.base_price - tier.unit_price) * quantity
        };
    }

    // 3. Standart fiyat
    return {
        unit_price: pricing.base_price,
        total: pricing.base_price * quantity
    };
}

// Örnek fiyat yapısı
const productPricing = {
    product_id: "LAPTOP-001",
    base_price: 5000,  // Tekil alım fiyatı
    tiers: [
        { min_quantity: 1, max_quantity: 9, unit_price: 5000, discount_percentage: 0 },
        { min_quantity: 10, max_quantity: 49, unit_price: 4750, discount_percentage: 5 },
        { min_quantity: 50, max_quantity: 99, unit_price: 4500, discount_percentage: 10 },
        { min_quantity: 100, max_quantity: null, unit_price: 4250, discount_percentage: 15 }
    ],
    customer_specific_prices: [
        {
            customer_id: "COMPANY-A",
            unit_price: 4000,  // %20 özel indirim
            valid_from: new Date('2026-01-01'),
            valid_until: new Date('2026-12-31'),
            notes: "Yıllık anlaşma (min 1000 adet)"
        }
    ]
};

// Test
console.log(await calculatePrice("LAPTOP-001", "COMPANY-A", 500));
// { unit_price: 4000, total: 2000000, discount_reason: "Yıllık anlaşma" }

console.log(await calculatePrice("LAPTOP-001", "COMPANY-B", 150));
// { unit_price: 4250, total: 637500, discount_percentage: 15, saved: 112500 }

Çoklu Kullanıcı Yönetimi

B2B Rol Yapısı:

1. Admin (Şirket Sahibi/Genel Müdür)
  • • Tüm yetkiler
  • • Kullanıcı ekleme/çıkarma
  • • Fatura/ödeme bilgileri
  • • Finansal raporlar
2. Procurement Manager (Satın Alma Müdürü)
  • • RFQ oluşturma
  • • Teklif değerlendirme
  • • Sipariş onaylama (limit dahilinde)
  • • Tedarikçi yönetimi
3. Buyer (Satın Alma Uzmanı)
  • • Ürün arama/görüntüleme
  • • Sepete ekleme
  • • Taslak sipariş oluşturma (onay bekler)
4. Finance (Muhasebe)
  • • Fatura görüntüleme
  • • Ödeme yapma
  • • Finansal raporlar
// Onay workflow (approval chain)
const OrderApprovalSchema = {
    order_id: String,
    created_by: String,  // Sipariş oluşturan kullanıcı
    amount: Number,
    approval_chain: [
        {
            approver_role: 'procurement_manager',
            approver_id: String,
            status: 'pending',  // pending, approved, rejected
            approved_at: Date,
            notes: String
        },
        {
            approver_role: 'finance',  // 100K TL üzeri siparişler için
            approver_id: String,
            status: 'pending'
        },
        {
            approver_role: 'admin',  // 500K TL üzeri için
            approver_id: String,
            status: 'pending'
        }
    ],
    current_step: 0,
    final_status: 'pending'  // pending, approved, rejected
};

// Onay kuralları
function getApprovalChain(order) {
    const chain = [{ approver_role: 'procurement_manager' }];

    if (order.amount > 100000) {
        chain.push({ approver_role: 'finance' });
    }

    if (order.amount > 500000) {
        chain.push({ approver_role: 'admin' });
    }

    return chain;
}

Maliyet ve ROI

ÖzellikGeliştirme SüresiMaliyet
Temel B2B marketplace12 hafta250-400K TL
RFQ/Quote sistemi4 hafta80-120K TL
Custom pricing engine3 hafta60-90K TL
Multi-user + approval workflow3 hafta60-80K TL
Toplam (Full B2B Platform)22 hafta450-690K TL

Örnek ROI: Toptan Elektronik Dağıtıcı

Öncesi: Manuel teklif/sipariş (email, telefon) → 3-5 gün/sipariş
Sonrası: Otomatik RFQ/sipariş → 4-8 saat/sipariş (%90 hızlanma)
Aylık sipariş: 200 → 500 (kapasite artışı)
Ortalama sipariş: 150K TL
Ek ciro: 300 sipariş × 150K = 45M TL/ay (%150 büyüme)
Komisyon (%3): 1.35M TL/ay gelir artışı
Platform maliyeti: 500K TL
ROI: İlk ayda %170

B2B Marketplace Platformunuzu Kuralım

RFQ/Quote yönetimi, özel fiyatlandırma, çoklu kullanıcı, approval workflow ile B2B ticaretinizi dijitalleştirin.

Demo İste