Telemedicine Payment Escrow
What it does:
Holds patient payments in escrow for telemedicine sessions and automatically releases funds to healthcare providers once the consultation is completed.
Why it matters:
Protects both patients and providers by ensuring fair payment, reducing disputes, and enforcing transparent, milestone-based healthcare service delivery.
How it works:
-
Telemedicine session terms are defined at deployment
-
Patient deposits consultation fee into escrow
-
Provider conducts the remote medical session
-
Provider marks session as completed
-
Patient confirms service completion or timeout triggers release
-
Escrow automatically pays the provider or refunds if conditions fail
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/**
* @title TelemedicinePaymentEscrow
* @author Nam
* @notice Escrow contract for telemedicine consultation payments
*/
contract TelemedicinePaymentEscrow {
// -------------------- ROLES --------------------
address public patient;
address public provider;
// -------------------- PAYMENT TERMS --------------------
uint256 public consultationFee;
uint256 public sessionDeadline; // timestamp
uint256 public confirmationTimeout; // seconds
// -------------------- STATE --------------------
bool public funded;
bool public sessionCompleted;
bool public patientConfirmed;
bool public paid;
// -------------------- EVENTS --------------------
event Funded(address indexed patient, uint256 amount);
event SessionCompleted(address indexed provider);
event PatientConfirmed(address indexed patient);
event ProviderPaid(address indexed provider, uint256 amount);
event Refunded(address indexed patient, uint256 amount);
// -------------------- MODIFIERS --------------------
modifier onlyPatient() {
require(msg.sender == patient, "Not patient");
_;
}
modifier onlyProvider() {
require(msg.sender == provider, "Not provider");
_;
}
// -------------------- CONSTRUCTOR --------------------
constructor(
address _patient,
address _provider,
uint256 _consultationFee,
uint256 _sessionDuration,
uint256 _confirmationTimeout
) {
require(_patient != address(0), "Invalid patient");
require(_provider != address(0), "Invalid provider");
patient = _patient;
provider = _provider;
consultationFee = _consultationFee;
sessionDeadline = block.timestamp + _sessionDuration;
confirmationTimeout = _confirmationTimeout;
}
// -------------------- ESCROW FLOW --------------------
/**
* @notice Patient funds the escrow
*/
function fund() external payable onlyPatient {
require(!funded, "Already funded");
require(msg.value == consultationFee, "Incorrect fee");
funded = true;
emit Funded(msg.sender, msg.value);
}
/**
* @notice Provider marks session as completed
*/
function completeSession() external onlyProvider {
require(funded, "Not funded");
require(!sessionCompleted, "Already completed");
require(block.timestamp = sessionDeadline + confirmationTimeout,
"Confirmation window open"
);
require(!paid, "Already settled");
_releasePayment();
}
// -------------------- INTERNAL --------------------
function _releasePayment() internal {
require(!paid, "Already paid");
paid = true;
payable(provider).transfer(consultationFee);
emit ProviderPaid(provider, consultationFee);
}
// -------------------- REFUND LOGIC --------------------
/**
* @notice Refund patient if session not completed
*/
function refund() external onlyPatient {
require(funded, "Not funded");
require(!sessionCompleted, "Session completed");
require(block.timestamp > sessionDeadline, "Session still valid");
require(!paid, "Already settled");
paid = true;
payable(patient).transfer(consultationFee);
emit Refunded(patient, consultationFee);
}
}