Health Subscription Management

What it does:
Manages recurring subscription payments for healthcare services such as telemedicine plans, wellness programs, or chronic care packages.

Why it matters:
Ensures uninterrupted access to healthcare services, reduces administrative overhead, and provides transparent, automated billing for patients and providers.

How it works:

  • Healthcare providers create subscription plans

  • Subscription price and billing cycle are defined on-chain

  • Patients subscribe by paying the first billing period

  • Subscription status is tracked automatically

  • Payments are charged at each billing cycle

  • Subscriptions can be paused or canceled

  • All payment history is transparently recorded

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

/**
 * @title HealthSubscriptionManagement
 * @author Nam
 * @notice Manages recurring healthcare service subscriptions
 */
contract HealthSubscriptionManagement {

    // -------------------- ROLES --------------------

    address public admin;

    // -------------------- STRUCTS --------------------

    struct Plan {
        uint256 price;        // wei per cycle
        uint256 billingCycle; // seconds
        bool active;
    }

    struct Subscription {
        bool active;
        uint256 nextPayment;
    }

    // -------------------- STORAGE --------------------

    uint256 public planCount;
    mapping(uint256 => Plan) public plans;

    // user => planId => Subscription
    mapping(address => mapping(uint256 => Subscription)) public subscriptions;

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

    event PlanCreated(uint256 indexed planId, uint256 price, uint256 cycle);
    event Subscribed(address indexed user, uint256 indexed planId);
    event PaymentCharged(address indexed user, uint256 indexed planId);
    event SubscriptionCanceled(address indexed user, uint256 indexed planId);

    // -------------------- MODIFIERS --------------------

    modifier onlyAdmin() {
        require(msg.sender == admin, "Not admin");
        _;
    }

    // -------------------- CONSTRUCTOR --------------------

    constructor() {
        admin = msg.sender;
    }

    // -------------------- PLAN MANAGEMENT --------------------

    /**
     * @notice Create a healthcare subscription plan
     */
    function createPlan(
        uint256 _price,
        uint256 _billingCycle
    )
        external
        onlyAdmin
    {
        require(_price > 0, "Invalid price");
        require(_billingCycle > 0, "Invalid cycle");

        planCount += 1;
        plans[planCount] = Plan({
            price: _price,
            billingCycle: _billingCycle,
            active: true
        });

        emit PlanCreated(planCount, _price, _billingCycle);
    }

    // -------------------- SUBSCRIPTIONS --------------------

    /**
     * @notice Subscribe to a healthcare plan
     */
    function subscribe(uint256 _planId)
        external
        payable
    {
        Plan memory plan = plans[_planId];
        require(plan.active, "Plan inactive");
        require(msg.value == plan.price, "Incorrect payment");

        subscriptions[msg.sender][_planId] = Subscription({
            active: true,
            nextPayment: block.timestamp + plan.billingCycle
        });

        emit Subscribed(msg.sender, _planId);
    }

    /**
     * @notice Charge recurring subscription payment
     */
    function chargeSubscription(
        address _user,
        uint256 _planId
    )
        external
        onlyAdmin
    {
        Subscription storage sub = subscriptions[_user][_planId];
        Plan memory plan = plans[_planId];

        require(sub.active, "Subscription inactive");
        require(block.timestamp >= sub.nextPayment, "Too early");

        sub.nextPayment = block.timestamp + plan.billingCycle;

        emit PaymentCharged(_user, _planId);
    }

    /**
     * @notice Cancel subscription
     */
    function cancelSubscription(uint256 _planId)
        external
    {
        Subscription storage sub = subscriptions[msg.sender][_planId];
        require(sub.active, "Not active");

        sub.active = false;
        emit SubscriptionCanceled(msg.sender, _planId);
    }

    // -------------------- FUNDING --------------------

    receive() external payable {}
}