Retail Loyalty Smart Contract
What it does:
Manages loyalty points, rewards, and tiered benefits for retail customers, automatically issuing points for purchases and redeeming rewards on-chain.
Why it matters:
Enhances customer engagement, prevents fraud, provides transparent reward tracking, and reduces manual loyalty program management.
How it works:
-
Retailers register customers on-chain
-
Purchases are tracked and loyalty points are credited automatically
-
Customers can redeem points for discounts, tokens, or special offers
-
Tiered programs can reward frequent or high-value customers
-
Points and rewards are auditable and transferable (optional)
-
Integrates with POS systems, marketplaces, and token-based reward ecosystems
-
Dashboards display customer points, reward history, and redemption options
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/access/Ownable.sol";
/**
* @title RetailLoyalty
* @author Nam
* @notice Tracks customer loyalty points and manages rewards on-chain
*/
contract RetailLoyalty is Ownable {
struct Customer {
uint256 points;
bool registered;
}
mapping(address => Customer) public customers;
mapping(address => bool) public authorizedRetailers;
// -------------------- EVENTS --------------------
event CustomerRegistered(address customer);
event PointsAccrued(address customer, uint256 points);
event PointsRedeemed(address customer, uint256 points, string reward);
event RetailerApproved(address retailer);
// -------------------- RETAILER MANAGEMENT --------------------
function approveRetailer(address _retailer) external onlyOwner {
authorizedRetailers[_retailer] = true;
emit RetailerApproved(_retailer);
}
function revokeRetailer(address _retailer) external onlyOwner {
authorizedRetailers[_retailer] = false;
}
modifier onlyRetailer() {
require(authorizedRetailers[msg.sender], "Not an authorized retailer");
_;
}
// -------------------- CUSTOMER MANAGEMENT --------------------
function registerCustomer(address _customer) external onlyRetailer {
require(!customers[_customer].registered, "Already registered");
customers[_customer] = Customer({
points: 0,
registered: true
});
emit CustomerRegistered(_customer);
}
// -------------------- POINTS MANAGEMENT --------------------
function accruePoints(address _customer, uint256 _points) external onlyRetailer {
require(customers[_customer].registered, "Customer not registered");
customers[_customer].points += _points;
emit PointsAccrued(_customer, _points);
}
function redeemPoints(address _customer, uint256 _points, string calldata _reward) external onlyRetailer {
Customer storage c = customers[_customer];
require(c.registered, "Customer not registered");
require(c.points >= _points, "Insufficient points");
c.points -= _points;
emit PointsRedeemed(_customer, _points, _reward);
}
// -------------------- VIEW FUNCTIONS --------------------
function getCustomerPoints(address _customer) external view returns (uint256) {
return customers[_customer].points;
}
}