Decentralized Wholesale Platform

What it does:
Facilitates direct wholesale transactions between suppliers and buyers on-chain, automating listings, negotiations, and payments.

Why it matters:
Eliminates intermediaries, reduces fees, enforces transparent contracts, and provides auditable records of transactions for all parties.

How it works:

  • Suppliers list products with quantity, pricing, and terms on-chain

  • Buyers can browse, place orders, and commit payments via smart contracts

  • Milestone-based or Just-In-Time payments can be triggered automatically upon delivery

  • Ratings and reviews feed into supplier reputation scoring

  • Integrates with Supplier Reputation System, Cross-Border Trade Settlement, and Product Lifecycle Tracking

  • Dashboards provide real-time visibility into available products, orders, and settlement status

      // SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "@openzeppelin/contracts/access/Ownable.sol";

/**
 * @title DecentralizedWholesale
 * @author Nam
 * @notice Enables on-chain wholesale listings, orders, and payments
 */
contract DecentralizedWholesale is Ownable {

    struct Product {
        string name;
        uint256 pricePerUnit;
        uint256 quantityAvailable;
        address payable supplier;
        bool active;
    }

    struct Order {
        uint256 productId;
        uint256 quantity;
        address payable buyer;
        uint256 totalAmount;
        bool fulfilled;
    }

    mapping(uint256 => Product) public products;
    mapping(uint256 => Order) public orders;

    uint256 public productCount;
    uint256 public orderCount;

    mapping(address => bool) public authorizedSuppliers;

    // -------------------- EVENTS --------------------

    event SupplierApproved(address supplier);
    event ProductListed(uint256 productId, string name, uint256 pricePerUnit, uint256 quantity, address supplier);
    event OrderPlaced(uint256 orderId, uint256 productId, address buyer, uint256 quantity, uint256 totalAmount);
    event OrderFulfilled(uint256 orderId);

    // -------------------- SUPPLIER MANAGEMENT --------------------

    function approveSupplier(address _supplier) external onlyOwner {
        authorizedSuppliers[_supplier] = true;
        emit SupplierApproved(_supplier);
    }

    function revokeSupplier(address _supplier) external onlyOwner {
        authorizedSuppliers[_supplier] = false;
    }

    modifier onlySupplier() {
        require(authorizedSuppliers[msg.sender], "Not an authorized supplier");
        _;
    }

    // -------------------- PRODUCT MANAGEMENT --------------------

    function listProduct(string calldata _name, uint256 _pricePerUnit, uint256 _quantity) external onlySupplier {
        require(_quantity > 0, "Quantity must be > 0");
        require(_pricePerUnit > 0, "Price must be > 0");

        productCount += 1;
        products[productCount] = Product({
            name: _name,
            pricePerUnit: _pricePerUnit,
            quantityAvailable: _quantity,
            supplier: payable(msg.sender),
            active: true
        });

        emit ProductListed(productCount, _name, _pricePerUnit, _quantity, msg.sender);
    }

    // -------------------- ORDER MANAGEMENT --------------------

    function placeOrder(uint256 _productId, uint256 _quantity) external payable {
        Product storage p = products[_productId];
        require(p.active, "Product not active");
        require(_quantity > 0 && _quantity <= p.quantityAvailable, "Invalid quantity");

        uint256 total = _quantity * p.pricePerUnit;
        require(msg.value == total, "Incorrect payment amount");

        orderCount += 1;
        orders[orderCount] = Order({
            productId: _productId,
            quantity: _quantity,
            buyer: payable(msg.sender),
            totalAmount: total,
            fulfilled: false
        });

        p.quantityAvailable -= _quantity;

        emit OrderPlaced(orderCount, _productId, msg.sender, _quantity, total);
    }

    function fulfillOrder(uint256 _orderId) external onlySupplier {
        Order storage o = orders[_orderId];
        Product storage p = products[o.productId];
        require(msg.sender == p.supplier, "Not the supplier");
        require(!o.fulfilled, "Order already fulfilled");

        o.fulfilled = true;
        p.supplier.transfer(o.totalAmount);

        emit OrderFulfilled(_orderId);
    }

    // -------------------- VIEW FUNCTIONS --------------------

    function getProduct(uint256 _productId) external view returns (Product memory) {
        return products[_productId];
    }

    function getOrder(uint256 _orderId) external view returns (Order memory) {
        return orders[_orderId];
    }
}