A comprehensive Point of Sale (POS) system built on the Stacks blockchain using Clarity smart contract language. This contract enables decentralized retail operations with inventory management, sales processing, customer loyalty programs, and multi-cashier support.
- Add Products: Create new products with name, price, stock quantity, and category
- Update Pricing: Modify product prices dynamically
- Stock Management: Update stock levels, add inventory, and track quantities
- Product Status: Activate or deactivate products without deletion
- Inventory Tracking: Real-time stock monitoring with automated deduction on sales
- Customer Registration: Register customers with name and email
- Profile Updates: Modify customer information as needed
- Purchase History: Track total purchases per customer
- Loyalty Program: Automatic loyalty points (10% of purchase value)
- Points Redemption: Redeem accumulated loyalty points
- Transaction Recording: Process sales with automatic stock deduction
- Customer Linking: Optionally link sales to registered customers
- Audit Trail: Complete transaction history with timestamps and cashier details
- Revenue Tracking: Cumulative revenue monitoring
- Multi-Product Support: Handle unlimited product catalog
- Owner Privileges: Full administrative control for contract owner
- Multi-Cashier System: Authorize multiple cashiers for sales operations
- Role-Based Access: Different permission levels for different operations
- Cashier Management: Add or revoke cashier authorization
Products Map
{
name: string-ascii 50,
price: uint,
stock: uint,
category: string-ascii 30,
active: bool
}Sales Map
{
product-id: uint,
customer-id: optional uint,
quantity: uint,
total-price: uint,
timestamp: uint,
cashier: principal
}Customers Map
{
name: string-ascii 50,
email: string-ascii 50,
total-purchases: uint,
loyalty-points: uint
}(add-product (name (string-ascii 50)) (price uint) (stock uint) (category (string-ascii 30)))Creates a new product in the inventory.
- Returns: Product ID
- Access: Owner only
(update-product-price (product-id uint) (new-price uint))Updates the price of an existing product.
- Access: Owner only
(update-product-stock (product-id uint) (new-stock uint))Sets the stock level for a product.
- Access: Owner only
(add-stock (product-id uint) (quantity uint))Adds inventory to existing stock.
- Access: Owner only
(activate-product (product-id uint))
(deactivate-product (product-id uint))Enable or disable products from sale.
- Access: Owner only
(authorize-cashier (cashier principal))
(revoke-cashier (cashier principal))Manage cashier permissions.
- Access: Owner only
(register-customer (name (string-ascii 50)) (email (string-ascii 50)))Register a new customer.
- Returns: Customer ID
- Access: Authorized cashiers
(update-customer-info (customer-id uint) (name (string-ascii 50)) (email (string-ascii 50)))Update customer details.
- Access: Authorized cashiers
(process-sale (product-id uint) (quantity uint) (customer-id (optional uint)))Process a product sale.
- Returns: Sale ID and total price
- Automatically:
- Deducts stock
- Records transaction
- Updates customer loyalty points (if linked)
- Increments total revenue
- Access: Authorized cashiers
(redeem-loyalty-points (customer-id uint) (points uint))Redeem customer loyalty points.
- Access: Authorized cashiers
get-product (product-id uint)- Retrieve product detailsget-sale (sale-id uint)- Retrieve sale transactionget-customer (customer-id uint)- Retrieve customer detailsget-total-revenue- Get cumulative revenueget-next-product-id- Get next product IDget-next-sale-id- Get next sale IDget-next-customer-id- Get next customer IDis-cashier-authorized (cashier principal)- Check cashier status
| Code | Constant | Description |
|---|---|---|
| u100 | err-owner-only |
Function requires owner privileges |
| u101 | err-not-found |
Resource not found |
| u102 | err-insufficient-stock |
Not enough inventory |
| u103 | err-invalid-amount |
Invalid price or points amount |
| u104 | err-already-exists |
Resource already exists |
| u105 | err-unauthorized |
User not authorized |
| u106 | err-invalid-quantity |
Invalid quantity value |
| u107 | err-invalid-input |
Invalid input data |
Deploy the contract to Stacks blockchain. The deployer becomes the contract owner and is automatically authorized as a cashier.
(contract-call? .pos-contract add-product "Coffee Beans" u1000 u50 "Beverages")
;; Returns: (ok u1)(contract-call? .pos-contract authorize-cashier 'SP2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKNRV9EJ7)(contract-call? .pos-contract register-customer "John Doe" "john@example.com")
;; Returns: (ok u1)(contract-call? .pos-contract process-sale u1 u2 (some u1))
;; Product ID: 1, Quantity: 2, Customer ID: 1
;; Returns: (ok {sale-id: u1, total-price: u2000})(contract-call? .pos-contract get-total-revenue)
;; Returns: (ok u2000)- β Input validation on all user-provided data
- β Role-based access control
- β Stock availability checks before sales
- β Overflow protection using Clarity's built-in uint handling
- β Comprehensive error handling
- β Immutable transaction history
- β Customer data validation
- Install Clarinet
- Create new project:
clarinet new pos-system - Add contract to
contracts/directory - Test locally:
clarinet test - Deploy to testnet:
clarinet deploy --testnet - Deploy to mainnet:
clarinet deploy --mainnet
- Test with various product quantities
- Verify stock depletion and replenishment
- Test loyalty points calculation
- Verify authorization checks
- Test edge cases (zero quantities, invalid IDs)
- Confirm transaction atomicity
- Product names limited to 50 ASCII characters
- Email addresses limited to 50 ASCII characters
- Categories limited to 30 ASCII characters
- Single currency unit (no decimals in current implementation)
- No bulk operations (must process individually)
- Multi-currency support
- Bulk product operations
- Sales discounts and promotions
- Refund functionality
- Product search and filtering
- Sales analytics and reporting
- Time-based promotions
- Customer tiers based on purchase history