Smart City Micro-Payment Contract

What it does:
Enables automatic micro-payments for urban services such as public transport, parking, utilities, or shared resources, using smart contracts.

Why it matters:
Removes intermediaries, reduces transaction friction, ensures transparent and accurate payments, and supports scalable smart city services.

How it works:

  • Urban services (transport, parking, utilities) register with metadata, pricing, and service rules

  • Citizens make micro-payments per usage, per minute, or per service consumption

  • Smart contracts automatically distribute payments to service providers

  • Supports recurring subscriptions, top-ups, or pay-per-use schemes

  • Integrates with Autonomous Vehicle Payment System, AI Agent Payment Contract, or Tokenized Wallets

  • Dashboards track individual usage, payments, and service consumption history

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

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

/**
 * @title SmartCityMicroPayment
 * @author Nam
 * @notice Manages micro-payments for smart city services on-chain
 */
contract SmartCityMicroPayment is Ownable {

    struct Service {
        string name;
        address payable provider;
        uint256 pricePerUnit; // e.g., per minute, per km, per usage
        bool active;
    }

    mapping(uint256 => Service) public services;
    uint256 public serviceCount;

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

    event ServiceRegistered(uint256 indexed serviceId, string name, address provider, uint256 pricePerUnit);
    event ServiceDeactivated(uint256 indexed serviceId);
    event MicroPaymentMade(uint256 indexed serviceId, address user, uint256 unitsUsed, uint256 amount);

    // -------------------- SERVICE MANAGEMENT --------------------

    function registerService(string calldata _name, uint256 _pricePerUnit) external {
        require(_pricePerUnit > 0, "Price must be >0");

        serviceCount += 1;
        services[serviceCount] = Service({
            name: _name,
            provider: payable(msg.sender),
            pricePerUnit: _pricePerUnit,
            active: true
        });

        emit ServiceRegistered(serviceCount, _name, msg.sender, _pricePerUnit);
    }

    function deactivateService(uint256 _serviceId) external {
        Service storage s = services[_serviceId];
        require(msg.sender == s.provider, "Not provider");
        s.active = false;

        emit ServiceDeactivated(_serviceId);
    }

    // -------------------- PAYMENT MANAGEMENT --------------------

    function payForService(uint256 _serviceId, uint256 _unitsUsed) external payable {
        Service storage s = services[_serviceId];
        require(s.active, "Service inactive");

        uint256 totalAmount = s.pricePerUnit * _unitsUsed;
        require(msg.value == totalAmount, "Incorrect payment");

        s.provider.transfer(msg.value);

        emit MicroPaymentMade(_serviceId, msg.sender, _unitsUsed, msg.value);
    }

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

    function isServiceActive(uint256 _serviceId) external view returns (bool) {
        return services[_serviceId].active;
    }

    function getServicePrice(uint256 _serviceId) external view returns (uint256) {
        return services[_serviceId].pricePerUnit;
    }
}