Back to: ASP.NET Core Web API Tutorials
Real-time Ecommerce Application using ASP.NET Core Web API
We will build a real-time ECommerce Application using ASP.NET Core Web API and Entity Framework Core using SQL Server Database. As part of this project, we will be implementing the following modules or Features:
- Customer Module
- Address Module
- Category Module
- Product Module
- Shopping Cart Module
- Order Module
- Payment Module
- Cancellation Module
- Refund Module
- User Feedback Module
The above modules are illustrated in the image below:
Customer and Address Management Module
The Customer and Address Management Module is foundational to the E-Commerce application, handling all aspects related to customer data and their associated addresses. This module ensures that customer information is securely managed, easily accessible, and efficiently utilized across various functionalities like order processing and profile management. The following are the Key Features of this module, which we will implement in our application:
- Registration: Enables new customers to create accounts by providing validated personal information. Ensures data integrity through robust validation mechanisms.
- Authentication: Implements secure login procedures using hashed passwords via BCrypt. Protects user credentials and maintains session security.
- Profile Management: Allows customers to retrieve, update, and delete their profiles. Facilitates easy management of personal information and preferences.
- Multiple Addresses: Supports the addition of multiple billing and shipping addresses per customer. Enhances flexibility in order deliveries and billing processes.
- Data Integrity and Security: Uses data annotations and validation rules to maintain accurate and secure customer data. Implements indexing (e.g., unique email addresses) to prevent duplicate entries and ensure quick data retrieval.
Product and Category Management Module
The Product and Category Management Module organizes the merchandise available in the E-Commerce platform, ensuring that products are systematically categorized for optimal navigation and management. This module plays a crucial role in inventory management, product visibility, and sales optimization.
Category Management:
The Category Module Organizes products into distinct groups for better navigation and management. The following are the key Features of Category Management:
- CRUD Operations: Create, read, update, and delete product categories. Facilitates the organization of products into logical groups.
- Association with Products: Each category can encompass multiple products. Enhances product discoverability and categorization.
Product Management:
The Product Module Represents items available for purchase, linked to categories, and supports discounts. The following are the key Features of Product Management:
- CRUD Operations: Create, read, update, and delete products. Manages the lifecycle of products within the inventory.
- Discounts: Apply percentage-based discounts to products. Drives sales promotions and marketing strategies.
- Stock Management: Track and manage product stock quantities. Prevents overselling and ensures inventory accuracy.
- Image Handling: Store and validate product image URLs. Enhances the visual appeal and user experience on the platform.
Shopping Cart Module
The Shopping Cart Module serves as the intermediary between product browsing and order placement. It allows customers to add products they intend to purchase, review their selections, adjust quantities, and remove items before finalizing their orders. This module not only enhances user convenience but also plays a crucial role in inventory management and sales optimization. The following are the Key Features of this module, which we will implement in our application:
- Add to Cart: Allows customers to add products to their shopping cart from the product listing or detail pages. Validates product availability and stock levels before addition.
- View Cart: Provides a detailed view of all items currently in the cart, including product details, quantities, individual prices, and total amounts.
- Update Cart Items: Enables customers to modify the quantity of each item in their cart. Reflects real-time stock availability to prevent overselling.
- Remove from Cart: Allows customers to remove individual items or clear the entire cart.
- Persisting Cart Data: Associates carts with authenticated customers to retain cart contents across sessions and devices. Implements session-based carts for guest users, with options to merge upon account creation.
Order Management Module
The Order Management Module oversees the entire lifecycle of customer orders, from placement to delivery. This module ensures that orders are processed efficiently, statuses are accurately tracked, and financial details are properly managed. The following are the Key Features of this module, which we will implement in our application:
- Order Creation: Allows customers to place new orders containing multiple items. Automatically calculates totals, applies discounts, and adds shipping costs.
- Status Tracking: Manages various order statuses such as Pending, Processing, Shipped, Delivered, and Canceled. Controls status transitions to reflect the current state of each order accurately.
- Financial Tracking: Provides detailed calculations of base amounts, discounts, shipping costs, and total amounts. Ensures transparency and accuracy in order billing.
- Order Item Management: Tracks each product’s quantity, unit price, discount, and total price within an order. Automatically update product stock based on order quantities to maintain inventory accuracy.
Payment Management Module:
The Payment Management Module facilitates the secure and efficient processing of customer payments. This module integrates with payment gateways to handle transactions, record payment details, and update order statuses based on payment outcomes. The following are the Key Features of this module, which we will implement in our application:
- Payment Processing: Handles payment transactions through integrated payment gateways (e.g., Stripe, PayPal, etc.) or Cash on Delivery (COD). Ensures secure transmission and storage of payment information.
- Payment Records: Stores detailed payment information associated with each order. Maintains a clear audit trail for financial transactions.
- Integration with Orders: Links payments to specific orders. Updates order statuses based on the success or failure of payment transactions.
- Transaction Management: Manages transaction IDs and statuses to reflect real-time payment states. Facilitates refund processes by maintaining accurate payment references.
Cancellation Module
The Cancellation Module allows customers to request the cancellation of their orders before they are shipped. This module ensures that cancellations are handled efficiently, maintaining data integrity and providing a seamless user experience. The following are the Key Features of this module, which we will implement in our application:
- Cancellation Requests: Customers can request to cancel orders that are in eligible statuses (e.g., Pending, Processing). Validates cancellation eligibility based on order status.
- Status Management: Automatically updates the order status to “Canceled” upon successful cancellation. Maintains accurate tracking of order states.
- Stock Restoration: Restores the stock quantities of products in the canceled order. Prevents stock discrepancies and ensures inventory accuracy.
- Notification: Inform relevant stakeholders (e.g., customers, administrators) about the cancellation. Enhances communication and transparency within the system.
Refund Module
The Refund Module manages the process of returning funds to customers for canceled orders or returned products. It ensures accurate financial tracking and seamless integration with payment gateways to facilitate smooth refund operations. The following are the Key Features of this module, which we will implement in our application:
- Refund Requests: Handles refund requests associated with canceled orders or returned items. Validates refund eligibility based on order and payment statuses.
- Payment Integration: Processes refunds through existing payment gateway integrations (e.g., Stripe, PayPal). Ensures secure and efficient refund transactions.
- Financial Tracking: Accurately records refund amounts and statuses. Maintains a clear audit trail for all refund operations.
- Notification: Notifies customers about the refund status and completion. Provides transparency and updates to enhance customer satisfaction.
User Feedback Module:
The Feedback Module is a crucial component of the E-Commerce application, designed to capture and manage customer reviews and ratings for products they have purchased. This module not only enhances customer engagement but also provides valuable insights into product performance, helping both customers and administrators in making informed decisions. The following are the Key Features of the Feedback Module that we will implement in our application:
- Feedback Submission: Allows authenticated customers to submit ratings and reviews for products they have purchased. Customers can rate products on a scale (e.g., 1 to 5 stars), providing quantitative feedback.
- Feedback Validation: Ensures that only legitimate customers who have purchased a product can leave feedback. Prevents customers from submitting multiple feedback entries for the same product and order item.
- Update and Delete Feedback: Allows customers to modify their existing feedback, enabling corrections or updates based on further product usage. Enables customers to remove their feedback entries if desired.
- Average Rating Calculation: Computes the average rating for each product, providing a quick overview of customer satisfaction.
- Detailed Feedback Listings: Displays individual feedback entries, including customer names, ratings, comments, and submission dates.
Create the ASP.NET Core Web API Project
First, create a new ASP.NET Core Web API project named ECommerceApp. We will use EF Core with SQL Server. Please install the following packages. The BCrypt.Net-Next library is required to store the password in the hash format in the database.
- Install-Package Microsoft.EntityFrameworkCore.SqlServer
- Install-Package Microsoft.EntityFrameworkCore.Tools
- Install-Package BCrypt.Net-Next
Defining the Models
Models represent the core entities of the application, encapsulating the data and business logic. They are essential for defining the structure of the data that the application manages. We will develop the E-Commerce API with the following entities:
- Customer: Represents users who can place orders, including authentication details.
- Address: Stores multiple addresses per customer for billing and shipping purposes.
- Category: Manages product categories.
- Product: Represents items available for purchase, linked to categories and supporting discounts.
- Cart: Represents a shopping cart associated with a customer.
- CartItems: Represents an individual product entry within a shopping cart.
- Order: Represents a customer’s order with detailed financial tracking and status.
- OrderItem: Represents individual items within an order, including discounts.
- Status: Represents the different statuses that can be used with order and payment.
- Payment: Represents the Payment associated with a specific order.
- Cancellation: This entity captures the details of a cancellation request made by a customer.
- Refund: This entity manages the refund details associated with a cancellation or return.
- Feedback: This entity stores the feedback provided by a user on the purchase of a product.
Each entity will have corresponding DTOs to handle data transfer between the client and server. We will apply various Data Annotation Attributes across these DTOs to enforce validation rules, ensuring data integrity and security. Create a folder named Models in the project root directory, where we will add all our entities.
Customer Entity
Create a class file named Customer.cs within the Models folder, and then copy and paste the following code. The Customer entity represents users who interact with the E-Commerce platform by placing orders. It encapsulates personal details, authentication credentials, and navigational properties to associated addresses and orders.
using System.ComponentModel.DataAnnotations; using Microsoft.EntityFrameworkCore; namespace ECommerceApp.Models { // Represents a customer in the e-commerce system [Index(nameof(Email), Name = "IX_Email_Unique", IsUnique = true)] public class Customer { public int Id { get; set; } [Required(ErrorMessage = "First Name is required.")] [StringLength(50, MinimumLength = 2, ErrorMessage = "First Name must be between 2 and 50 characters.")] public string FirstName { get; set; } [Required(ErrorMessage = "Last Name is required.")] [StringLength(50, MinimumLength = 2, ErrorMessage = "Last Name must be between 2 and 50 characters.")] public string LastName { get; set; } [Required(ErrorMessage = "Email is required.")] public string Email { get; set; } [Required(ErrorMessage = "PhoneNumber is required.")] public string PhoneNumber { get; set; } [Required(ErrorMessage = "DateOfBirth is required.")] public DateTime DateOfBirth { get; set; } [Required(ErrorMessage = "Password is required.")] public string Password { get; set; } public bool IsActive { get; set; } public ICollection<Address> Addresses { get; set; } public ICollection<Order> Orders { get; set; } // Navigation property: A user can have many carts but only 1 active cart public ICollection<Cart> Carts { get; set; } public ICollection<Feedback> Feedbacks { get; set; } } }
Customer Entity Role in ECommerce Application:
- User Management: Facilitates customer registration, ensuring that each user has a unique and secure account. Manages authentication processes, allowing customers to securely log in and access their profiles.
- Profile Management: Stores essential personal information such as name, email, phone number, and date of birth. Enables customers to update or delete their profiles as needed.
- Address Association: Links to multiple addresses, supporting both billing and shipping needs. Enhances flexibility in order placements and deliveries.
- Order Association: Connects to multiple orders placed by the customer. Provides a comprehensive view of a customer’s purchasing history.
- Cart Association: Allows customers to have multiple carts but only 1 active cart.
Address Entity
Create a class file named Address.cs within the Models folder and then copy and paste the following code. The Address entity stores multiple addresses for each customer, facilitating billing and shipping requirements. It ensures that customers can manage various delivery and billing locations efficiently.
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace ECommerceApp.Models { // Represents a customer's address public class Address { public int Id { get; set; } [Required] public int CustomerId { get; set; } [ForeignKey("CustomerId")] public Customer Customer { get; set; } [Required(ErrorMessage = "Address Line 1 is required.")] [StringLength(100, ErrorMessage = "Address Line 1 cannot exceed 100 characters.")] public string AddressLine1 { get; set; } [StringLength(100, ErrorMessage = "Address Line 2 cannot exceed 100 characters.")] public string AddressLine2 { get; set; } [Required(ErrorMessage = "City is required.")] [StringLength(50, ErrorMessage = "City cannot exceed 50 characters.")] public string City { get; set; } [Required(ErrorMessage = "State is required.")] [StringLength(50, ErrorMessage = "State cannot exceed 50 characters.")] public string State { get; set; } [Required(ErrorMessage = "Postal Code is required.")] public string PostalCode { get; set; } [Required(ErrorMessage = "Country is required.")] [StringLength(50, ErrorMessage = "Country cannot exceed 50 characters.")] public string Country { get; set; } } }
Address Entity Role in ECommerce Application:
- Billing and Shipping: Supports the specification of different billing and shipping addresses per customer. Allows customers to select or add new addresses during the checkout process.
- Data Integrity: Enforces validation rules to maintain accurate and complete address information. Prevents duplicate or incomplete address entries.
- Association with Orders: Links to orders to determine where products should be shipped and where billing should be processed. Ensures that each order has designated addresses for accurate processing.
Status Entity
Create a class file named Status.cs within the Models folder, and then copy and paste the following code. The Status entity serves as a master reference for various statuses that can be associated with orders, cancellations, and payments. It standardizes status definitions across the application, ensuring consistency and clarity.
using System.ComponentModel.DataAnnotations; namespace ECommerceApp.Models { // Represents the status master public class Status { [Required] public int Id { get; set; } [Required] [StringLength(50)] public string Name { get; set; } } }
Status Entity Role in ECommerce Application:
- Status Standardization: Defines standardized status names (e.g., Pending, Processing, Approved, Completed, Rejected, Refunded, etc.) used throughout the application. Prevents inconsistencies in status representations across different modules.
- Flexible Status Management: Allows for easy addition or modification of statuses as per the business needs. Enhances the application’s adaptability to changing operational requirements.
- Association with Multiple Entities: Links to Order, Cancellation, and Payment entities to manage their respective statuses. Ensures uniform status handling across various business processes.
Category Entity
Create a class file named Category.cs within the Models folder, and then copy and paste the following code. The Category entity organizes products into distinct groups, enhancing navigation and management within the E-Commerce platform. It allows for systematic categorization of merchandise, helping both customers and administrators.
using Microsoft.EntityFrameworkCore; using System.ComponentModel.DataAnnotations; namespace ECommerceApp.Models { [Index(nameof(Name), Name = "IX_Name_Unique", IsUnique = true)] // Represents a product category public class Category { public int Id { get; set; } [Required(ErrorMessage = "Category Name is required.")] [StringLength(100, MinimumLength = 3, ErrorMessage = "Category Name must be between 3 and 100 characters.")] public string Name { get; set; } [StringLength(500, ErrorMessage = "Description cannot exceed 500 characters.")] public string Description { get; set; } public bool IsActive { get; set; } public ICollection<Product> Products { get; set; } } }
Category Entity Role in E-Commerce Application:
- Product Organization: Groups related products under specific categories, making it easier for customers to browse and find items. Enhances the user experience by providing structured product listings.
- Inventory Management: Assists administrators in managing product inventories by categorizing items logically. Facilitates bulk operations on products within the same category.
- Marketing and Promotions: Enables targeted promotions and discounts on specific categories. Helps in analyzing sales trends within different product segments.
Product Entity
Create a class file named Product.cs within the Models folder and then copy and paste the following code. The Product entity represents items available for purchase in the E-Commerce system. Each product is linked to a category and supports features like discounts, stock management, and image handling to enhance its marketability.
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace ECommerceApp.Models { // Represents a product available for purchase public class Product { public int Id { get; set; } [Required(ErrorMessage = "Product Name is required.")] [StringLength(100, MinimumLength = 3, ErrorMessage = "Product Name must be between 3 and 100 characters.")] public string Name { get; set; } [Required(ErrorMessage = "Description is required.")] [MinLength(10, ErrorMessage = "Description must be at least 10 characters.")] public string Description { get; set; } [Range(0.01, 10000.00, ErrorMessage = "Price must be between $0.01 and $10,000.00.")] [Column(TypeName ="decimal(18,2)")] public decimal Price { get; set; } [Range(0, 1000, ErrorMessage = "Stock Quantity must be between 0 and 1000.")] public int StockQuantity { get; set; } public string ImageUrl { get; set; } [Range(0, 100, ErrorMessage = "Discount Percentage must be between 0% and 100%.")] public int DiscountPercentage { get; set; } public bool IsAvailable { get; set; } // Foreign key to Category [Required(ErrorMessage = "Category ID is required.")] public int CategoryId { get; set; } [ForeignKey("CategoryId")] public Category Category { get; set; } public ICollection<OrderItem> OrderItems { get; set; } public ICollection<Feedback> Feedbacks { get; set; } } }
Product Entity Role in E-Commerce Application:
- Catalog Management: Maintains detailed information about each product, including name, description, price, and images. Ensures that product listings are informative to customers.
- Inventory Control: Tracks stock quantities to prevent overselling. Automatically adjusts stock based on order placements and cancellations.
- Discount Management: Applies percentage-based discounts to products, enabling dynamic pricing strategies. Facilitates sales promotions and limited-time offers.
- Visual Representation: Handles product image URLs, ensuring that visual content is correctly displayed on the platform.
Cart Entity
Create a class file named Cart.cs within the Models folder and then copy and paste the following code. The Cart entity represents a shopping cart associated with a customer. It serves as a container for all items that a customer intends to purchase but has not yet ordered. This entity maintains the state of the cart, including the list of items, total cost, and timestamps for creation and updates.
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace ECommerceApp.Models { // Represents a shopping cart public class Cart { public int Id { get; set; } public int CustomerId { get; set; } [ForeignKey("CustomerId")] public Customer Customer { get; set; } public bool IsCheckedOut { get; set; } = false; [Required] public DateTime CreatedAt { get; set; } [Required] public DateTime UpdatedAt { get; set; } public ICollection<CartItem> CartItems { get; set; } } }
CartItem Entity
Create a class file named CartItem.cs within the Models folder, and then copy and paste the following code. The CartItem entity represents an individual product entry within a shopping cart. It captures details such as the product being added, the quantity desired, and any applicable discounts or pricing adjustments.
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace ECommerceApp.Models { // Represents an individual item within a shopping cart public class CartItem { public int Id { get; set; } [Required] public int CartId { get; set; } [ForeignKey("CartId")] public Cart Cart { get; set; } [Required] public int ProductId { get; set; } [ForeignKey("ProductId")] public Product Product { get; set; } [Required] [Range(1, 100, ErrorMessage = "Quantity must be between 1 and 100.")] public int Quantity { get; set; } [Required] [Column(TypeName = "decimal(18,2)")] [Range(0.01, 10000.00, ErrorMessage = "Unit Price must be between $0.01 and $10,000.00.")] public decimal UnitPrice { get; set; } [Column(TypeName = "decimal(18,2)")] [Range(0.00, 1000.00, ErrorMessage = "Discount must be between $0.00 and $1,000.00.")] public decimal Discount { get; set; } [Column(TypeName = "decimal(18,2)")] public decimal TotalPrice { get; set; } [Required] public DateTime CreatedAt { get; set; } [Required] public DateTime UpdatedAt { get; set; } } }
OrderStatus Enum:
Create a class file named OrderStatus.cs within the Models folder, and copy and paste the following code. This Entity enumerates the possible statuses of an order, enhancing readability by serializing enums as string names in JSON responses.
using System.Text.Json.Serialization; namespace ECommerceApp.Models { // Enum to represent the status of an order // The JsonStringEnumConverter ensures that enums are serialized as their string names // instead of integer values, enhancing readability. [JsonConverter(typeof(JsonStringEnumConverter))] public enum OrderStatus { Pending = 1, Processing = 2, Shipped = 3, Delivered = 4, Canceled = 5 } }
Order Entity
Create a class file named Order.cs within the Models folder and then copy and paste the following code. The Order entity captures comprehensive details of customer orders, including financial tracking, status management, and associations with payments, cancellations, and refunds. It serves as the central record of all purchasing activities within the platform.
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace ECommerceApp.Models { // Represents an order placed by a customer public class Order { public int Id { get; set; } [Required] [StringLength(30, ErrorMessage = "Order Number cannot exceed 30 characters.")] public string OrderNumber { get; set; } [Required] public DateTime OrderDate { get; set; } // Foreign key to Customer [Required(ErrorMessage = "Customer ID is required.")] public int CustomerId { get; set; } [ForeignKey("CustomerId")] public Customer Customer { get; set; } // Foreign keys to Addresses [Required(ErrorMessage = "Billing Address ID is required.")] public int BillingAddressId { get; set; } [ForeignKey("BillingAddressId")] public Address BillingAddress { get; set; } [Required(ErrorMessage = "Shipping Address ID is required.")] public int ShippingAddressId { get; set; } [ForeignKey("ShippingAddressId")] public Address ShippingAddress { get; set; } [Required] [Column(TypeName = "decimal(18,2)")] [Range(0.00, 100000.00, ErrorMessage = "Total Base Amount must be between $0.00 and $100,000.00.")] public decimal TotalBaseAmount { get; set; } [Required] [Column(TypeName = "decimal(18,2)")] [Range(0.00, 100000.00, ErrorMessage = "Total Discount Amount must be between $0.00 and $100,000.00.")] public decimal TotalDiscountAmount { get; set; } [Column(TypeName = "decimal(18,2)")] [Range(0.00, 10000.00, ErrorMessage = "Shipping Cost must be between $0.00 and $10,000.00.")] public decimal ShippingCost { get; set; } [Required] [Column(TypeName = "decimal(18,2)")] [Range(0.00, 110000.00, ErrorMessage = "Total Amount must be between $0.00 and $110,000.00.")] public decimal TotalAmount { get; set; } [Required] [EnumDataType(typeof(OrderStatus), ErrorMessage = "Invalid Order Status.")] public OrderStatus OrderStatus { get; set; } [Required] public ICollection<OrderItem> OrderItems { get; set; } public Payment Payment { get; set; } //Linked with Associated Payment public Cancellation Cancellation { get; set; } //Linked with Associated Cancellation } }
Order Entity Role in E-Commerce Application:
- Order Processing: Facilitates the creation and management of customer orders, handling multiple items per order. Automatically calculates totals, applies discounts, and adds shipping costs.
- Status Management: Tracks the lifecycle of an order through various statuses such as Pending, Processing, Shipped, Delivered, and Canceled. Ensures accurate reflection of an order’s current state for both customers and administrators.
- Financial Information: Maintains detailed financial information, including base amounts, discounts, shipping costs, and total amounts. Ensures transparency and accuracy in billing and accounting.
- Associations: Links to OrderItem entities to detail individual products within an order. Connects to Payment, Cancellation, and Refund entities to manage financial transactions and order modifications.
OrderItem Entity
Create a class file named OrderItem.cs within the Models folder, and copy and paste the following code. The OrderItem entity represents individual items within an order, capturing specific details such as quantity, pricing, and discounts. It provides detailed tracking of each product included in a customer’s order.
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace ECommerceApp.Models { // Represents an individual item within an order public class OrderItem { public int Id { get; set; } // Foreign key to Order [Required(ErrorMessage = "Order ID is required.")] public int OrderId { get; set; } [ForeignKey("OrderId")] public Order Order { get; set; } // Foreign key to Product [Required(ErrorMessage = "Product ID is required.")] public int ProductId { get; set; } [ForeignKey("ProductId")] public Product Product { get; set; } [Range(1, 100, ErrorMessage = "Quantity must be between 1 and 100.")] public int Quantity { get; set; } [Range(0.00, 10000.00, ErrorMessage = "Unit Price must be between $0.00 and $10,000.00.")] [Column(TypeName = "decimal(18,2)")] public decimal UnitPrice { get; set; } [Range(0.00, 10000.00, ErrorMessage = "Discount must be between $0.00 and $10,000.00.")] [Column(TypeName = "decimal(18,2)")] public decimal Discount { get; set; } [Range(0.00, 10000.00, ErrorMessage = "Total Price must be between $0.00 and $10,000.00.")] [Column(TypeName = "decimal(18,2)")] public decimal TotalPrice { get; set; } } }
OrderItem Entity Role in E-Commerce Application:
- Item Tracking: Records the quantity of each product ordered, ensuring accurate order fulfillment. It also captures unit prices and applies discounts for correct financial calculations.
- Stock Management: Automatically deducts product stock based on order quantities. Prevents stock discrepancies and maintains inventory accuracy.
- Financial Calculations: Calculate each item’s total price by considering quantity, unit price, and discounts. Contributes to the overall financial tracking of the associated order.
PaymentStatus Enum:
Create a class file named PaymentStatus.cs within the Models folder, and copy and paste the following code. This Entity enumerates the possible statuses of a payment, enhancing readability by serializing enums as string names in JSON responses.
using System.Text.Json.Serialization; namespace ECommerceApp.Models { [JsonConverter(typeof(JsonStringEnumConverter))] public enum PaymentStatus { Pending = 1, Completed = 6, Failed = 7, Refunded = 10 } }
Payment Entity
Create a class file named Payment.cs within the Models folder and then copy and paste the following code. The Payment entity facilitates the secure and efficient processing of customer payments. It records payment details associated with orders and integrates with payment gateways to manage financial transactions.
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace ECommerceApp.Models { // Represents a payment transaction public class Payment { public int Id { get; set; } [Required] public int OrderId { get; set; } [ForeignKey("OrderId")] public Order Order { get; set; } [Required] [StringLength(50)] public string PaymentMethod { get; set; } // e.g., "DebitCard", "CreditCard", "PayPal", "COD" [StringLength(50)] public string? TransactionId { get; set; } // From payment gateway [Required] [Column(TypeName = "decimal(18,2)")] public decimal Amount { get; set; } [Required] public DateTime PaymentDate { get; set; } [Required] [StringLength(20)] public PaymentStatus Status { get; set; } // "Completed", "Pending", "Failed", "Refunded" public Refund Refund { get; set; } // Navigational property to Refund } }
Payment Entity Role in ECommerce Application:
- Payment Processing: Handles payment transactions through integrated payment gateways (e.g., Stripe, PayPal) or COD. Ensures secure transmission and storage of payment information.
- Payment Records: Stores detailed information about each payment, including payment method, transaction ID, amount, and status. Maintains an audit trail for financial accountability and transparency.
- Order Integration: Links payments to specific orders, ensuring accurate financial tracking. Updates order statuses based on payment outcomes, such as marking orders as “Processing” or “Pending” accordingly.
- Refund Management: Associates with the Refund entity to handle refund transactions. Facilitates the reversal of payments when necessary.
CancellationStatus Enum:
Create a class file named CancellationStatus.cs within the Models folder, and copy and paste the following code. The following Enum represents the status of a cancellation request.
using System.Text.Json.Serialization; namespace ECommerceApp.Models { // Enum to represent the status of a cancellation request [JsonConverter(typeof(JsonStringEnumConverter))] public enum CancellationStatus { Pending = 1, Approved = 8, Rejected = 9 } }
Cancellation Entity
Create a class file named Cancellation.cs within the Models folder, and copy and paste the following code. The Cancellation entity captures the details of a cancellation request made by a customer. It manages the lifecycle of cancellation requests, from initiation to approval or rejection, and ensures corresponding updates to orders and inventory.
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace ECommerceApp.Models { // Represents a cancellation request for an order public class Cancellation { public int Id { get; set; } // Foreign key to Order [Required(ErrorMessage = "Order ID is required.")] public int OrderId { get; set; } [ForeignKey("OrderId")] public Order Order { get; set; } // Reason for cancellation [Required(ErrorMessage = "Cancellation reason is required.")] [StringLength(500, ErrorMessage = "Cancellation reason cannot exceed 500 characters.")] public string Reason { get; set; } // Status of the cancellation request [Required] public CancellationStatus Status { get; set; } // Date and time when the cancellation was requested [Required] public DateTime RequestedAt { get; set; } // Date and time when the cancellation was processed public DateTime? ProcessedAt { get; set; } // ID of the admin or system that processed the cancellation public int? ProcessedBy { get; set; } // Could link to an Admin entity if available // The order amount at the time of cancellation request initiation. [Column(TypeName = "decimal(18,2)")] public decimal OrderAmount { get; set; } // The cancellation charges applied (if any). [Column(TypeName = "decimal(18,2)")] public decimal? CancellationCharges { get; set; } = 0.00m; [StringLength(500, ErrorMessage = "Remarks cannot exceed 500 characters.")] public string? Remarks { get; set; } //Reference Navigation Property public Refund Refund { get; set; } } }
Cancellation Entity Role in ECommerce Application:
- Cancellation Requests: Records customer-initiated requests to cancel orders that are eligible (e.g., orders not yet shipped). Stores reasons for cancellation to help in analytics and customer service.
- Status Management: Tracks the status of cancellation requests (Pending, Approved, Rejected). Ensures that only eligible orders are canceled and appropriately reflected in the system.
- Inventory Restoration: Restores stock quantities of products in the canceled order, maintaining inventory accuracy.
- Administrative Processing: Allows administrators to approve or reject cancellation requests. Logs the processing details, including who handled the cancellation and when.
RefundStatus Enum:
Create a class file named RefundStatus.cs within the Models folder, and copy and paste the following code. The following Enum represents the refund status.
using System.Text.Json.Serialization; namespace ECommerceApp.Models { // Enum to represent the status of a refund [JsonConverter(typeof(JsonStringEnumConverter))] public enum RefundStatus { Pending = 1, Completed = 6, Failed = 7 } }
RefundMethod Enum:
Define an enum to manage refund methods properly. So, create a class file named RefundMethod.cs within the Models folder and copy and paste the following code.
using System.Text.Json.Serialization; namespace ECommerceApp.Models { // Enum representing available refund methods. [JsonConverter(typeof(JsonStringEnumConverter))] public enum RefundMethod { Original, // Refund back to the original payment method PayPal, Stripe, BankTransfer, Manual } }
Refund Entity
Create a class file named Refund.cs within the Models folder, and copy and paste the following code. The Refund entity manages the refund details associated with a cancellation or return. It oversees the financial aspect of returning funds to customers, ensuring accurate tracking and integration with payment gateways.
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace ECommerceApp.Models { // Represents a refund transaction public class Refund { public int Id { get; set; } // Foreign key to Cancellation [Required(ErrorMessage = "Cancellation ID is required.")] public int CancellationId { get; set; } [ForeignKey("CancellationId")] public Cancellation Cancellation { get; set; } // Foreign key to Payment [Required(ErrorMessage = "Payment ID is required.")] public int PaymentId { get; set; } [ForeignKey("PaymentId")] public Payment Payment { get; set; } // Amount to be refunded [Range(0.01, 100000.00, ErrorMessage = "Refund amount must be between $0.01 and $100,000.00.")] [Column(TypeName = "decimal(18,2)")] public decimal Amount { get; set; } // Status of the Refund [Required] public RefundStatus Status { get; set; } [Required] public string RefundMethod { get; set; } [StringLength(500, ErrorMessage = "Refund Reason cannot exceed 500 characters.")] public string? RefundReason { get; set; } // Transaction ID from the payment gateway [StringLength(100, ErrorMessage = "Transaction ID cannot exceed 100 characters.")] public string? TransactionId { get; set; } // Date and time when the refund was initiated [Required] public DateTime InitiatedAt { get; set; } // Date and time when the refund was completed public DateTime? CompletedAt { get; set; } //Track who processed (approved) the refund. public int? ProcessedBy { get; set; } } }
Refund Entity Role in ECommerce Application:
- Refund Requests: Handles customer-initiated refund requests linked to canceled orders or returned products. Validates refund eligibility based on order and payment statuses.
- Payment Integration: Processes refunds through existing payment gateway integrations, ensuring secure and efficient transactions.
- Financial Tracking: Accurately records refund amounts, statuses (Pending, Completed, Failed), and associated transaction IDs. Maintains a clear audit trail for all refund operations.
- Customer Communication: Notifying customers about their refunds’ status and completion, enhancing transparency and trust.
Feedback Entity
Create a new class file named Feedback.cs within the Models folder and add the following code. The Feedback model represents customer feedback on purchased products. It establishes relationships with the Customer, Product, and OrderItem models to ensure that only legitimate purchasers can submit feedback.
using System.ComponentModel.DataAnnotations; namespace ECommerceApp.Models { // Represents customer feedback for a product public class Feedback { public int Id { get; set; } // Foreign key to Customer [Required] public int CustomerId { get; set; } public Customer Customer { get; set; } // Foreign key to Product [Required] public int ProductId { get; set; } public Product Product { get; set; } // Rating between 1 and 5 [Required] [Range(1, 5, ErrorMessage = "Rating must be between 1 and 5.")] public int Rating { get; set; } // Optional comment with maximum length [StringLength(1000, ErrorMessage = "Comment cannot exceed 1000 characters.")] public string? Comment { get; set; } // Timestamp of feedback submission public DateTime CreatedAt { get; set; } // Timestamp of feedback updation public DateTime UpdatedAt { get; set; } } }
Setting Up the Database Context
Create a Data folder and add the ApplicationDbContext class with the necessary configurations and relationships. This class serves as the application’s database context, managing entity configurations, relationships, and database operations using Entity Framework Core.
using Microsoft.EntityFrameworkCore; using ECommerceApp.Models; namespace ECommerceApp.Data { // Database context for the application public class ApplicationDbContext : DbContext { // Constructor accepting DbContextOptions public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { } // Configuring model properties and relationships protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); // Order -> BillingAddress modelBuilder.Entity<Order>() .HasOne(o => o.BillingAddress) .WithMany() .HasForeignKey(o => o.BillingAddressId) .OnDelete(DeleteBehavior.Restrict); // Prevent cascading delete // Order -> ShippingAddress modelBuilder.Entity<Order>() .HasOne(o => o.ShippingAddress) .WithMany() .HasForeignKey(o => o.ShippingAddressId) .OnDelete(DeleteBehavior.Restrict); // Prevent cascading delete // Order -> Cancellation modelBuilder.Entity<Order>() .HasOne(o => o.Cancellation) .WithOne(c => c.Order) .HasForeignKey<Cancellation>(c => c.OrderId) .OnDelete(DeleteBehavior.Restrict); // Prevent cascade delete to avoid multiple paths // Payment -> Refund modelBuilder.Entity<Payment>() .HasOne(p => p.Refund) .WithOne(r => r.Payment) .HasForeignKey<Refund>(r => r.PaymentId) .OnDelete(DeleteBehavior.Restrict); // Prevent cascade delete to avoid multiple paths // Feedback -> Customer (Many-to-One) modelBuilder.Entity<Feedback>() .HasOne(f => f.Customer) .WithMany(c => c.Feedbacks) .HasForeignKey(f => f.CustomerId) .OnDelete(DeleteBehavior.Restrict); // Feedback -> Product (Many-to-One) modelBuilder.Entity<Feedback>() .HasOne(f => f.Product) .WithMany(p => p.Feedbacks) .HasForeignKey(f => f.ProductId) .OnDelete(DeleteBehavior.Restrict); // Initial Seed Data // Seed OrderStatusEntity with initial data modelBuilder.Entity<Status>().HasData( //Order Statuses new Status { Id = 1, Name = "Pending" }, //Can be used to with Order, Paymeny, Cancellation, and Refund new Status { Id = 2, Name = "Processing" }, new Status { Id = 3, Name = "Shipped" }, new Status { Id = 4, Name = "Delivered" }, new Status { Id = 5, Name = "Canceled" }, //Refund Status new Status { Id = 6, Name = "Completed" }, new Status { Id = 7, Name = "Failed" }, //Cancellation Statuses new Status { Id = 8, Name = "Approved" }, new Status { Id = 9, Name = "Rejected" }, //Payment Status new Status { Id = 10, Name = "Refunded" } ); // Seed Categories modelBuilder.Entity<Category>().HasData( new Category { Id = 1, Name = "Electronics", Description = "Electronic devices and accessories", IsActive = true }, new Category { Id = 2, Name = "Books", Description = "Books and magazines", IsActive = true } ); // Seed Products modelBuilder.Entity<Product>().HasData( new Product { Id = 1, Name = "Smartphone", Description = "Latest model smartphone with advanced features.", Price = 699.99m, StockQuantity = 50, ImageUrl = "https://example.com/images/smartphone.jpg", DiscountPercentage = 10, CategoryId = 1, IsAvailable = true }, new Product { Id = 2, Name = "Laptop", Description = "High-performance laptop suitable for all your needs.", Price = 999.99m, StockQuantity = 30, ImageUrl = "https://example.com/images/laptop.jpg", DiscountPercentage = 15, CategoryId = 1, IsAvailable = true }, new Product { Id = 3, Name = "Science Fiction Novel", Description = "A thrilling science fiction novel set in the future.", Price = 19.99m, StockQuantity = 100, ImageUrl = "https://example.com/images/scifi-novel.jpg", DiscountPercentage = 5, CategoryId = 2, IsAvailable = true } ); } // DbSets representing tables in the database public DbSet<Customer> Customers { get; set; } public DbSet<Address> Addresses { get; set; } public DbSet<Status> Statuses { get; set; } public DbSet<Category> Categories { get; set; } public DbSet<Product> Products { get; set; } public DbSet<Order> Orders { get; set; } public DbSet<OrderItem> OrderItems { get; set; } public DbSet<Payment> Payments { get; set; } public DbSet<Cancellation> Cancellations { get; set; } public DbSet<Refund> Refunds { get; set; } public DbSet<Cart> Carts { get; set; } public DbSet<CartItem> CartItems { get; set; } public DbSet<Feedback> Feedbacks { get; set; } } }
Creating DTOs (Data Transfer Objects)
The DTOs (Data Transfer Objects) folder contains classes that facilitate controlled data exchange between the client and server, ensuring that only necessary data is exposed or accepted. So, create a folder named DTOs at the project root directory and add the following classes. Once you create the DTOs folder, then please add the following DTOs.
Define a Standardized Response Type (ApiResponse<T>)
Creating a standardized response type ensures that all API responses follow a consistent structure. This makes it easier for clients to parse responses and handle errors uniformly. So, create a new class file named ApiResponse.cs within the DTOs folder and copy and paste the following code.
namespace ECommerceApp.DTOs { // Standardized API response structure. // T represents then Type of the response data public class ApiResponse<T> { // HTTP status code of the response. public int StatusCode { get; set; } // Indicates whether the request was successful. public bool Success { get; set; } // Response data in case successful public T Data { get; set; } // List of error messages, if any. public List<string> Errors { get; set; } public ApiResponse() { Success = true; Errors = new List<string>(); } public ApiResponse(int statusCode, T data) { StatusCode = statusCode; Success = true; Data = data; Errors = new List<string>(); } public ApiResponse(int statusCode, List<string> errors) { StatusCode = statusCode; Success = false; Errors = errors; } public ApiResponse(int statusCode, string error) { StatusCode = statusCode; Success = false; Errors = new List<string> { error }; } } }
Key Features:
This DTO defines a standardized API response structure to ensure consistency across all API responses, facilitating easier client-side parsing and error handling.
- Generic class with properties like StatusCode, Success, Data, and Errors.
- Constructors to handle different response scenarios (success with data, failure with errors).
ConfirmationResponseDTO
Create a class file named ConfirmationResponseDTO.cs within the DTOs folder and then copy and paste the following code. This DTO is a simple confirmation message structure for actions like updates and deletions.
namespace ECommerceApp.DTOs { public class ConfirmationResponseDTO { public string Message { get; set; } } }
Configuring the Database Connection
In appsettings.json, configure the connection string to your SQL Server instance. So, please modify the appsettings.json file as follows:
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "AllowedHosts": "*", "ConnectionStrings": { "EFCoreDBConnection": "Server=LAPTOP-6P5NK25R\\SQLSERVER2022DEV;Database=ECommerceDB;Trusted_Connection=True;TrustServerCertificate=True;" } }
Registering Services in Program.cs
The Program.cs file is the entry point of the ASP.NET Core application. It configures services, middleware, and the HTTP request pipeline. It sets up the application by configuring services, including controllers, Swagger for API documentation, Entity Framework Core with SQL Server, and middleware components like HTTPS redirection and authorization. So, please modify the Program class as follows:
using ECommerceApp.Data; using ECommerceApp.Services; using Microsoft.EntityFrameworkCore; namespace ECommerceApp { public class Program { public static void Main(string[] args) { var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllers() .AddJsonOptions(options => { // This will use the property names as defined in the C# model options.JsonSerializerOptions.PropertyNamingPolicy = null; }); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); // Configure EF Core with SQL Server builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("EFCoreDBConnection"))); var app = builder.Build(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run(); } } }
Apply Migrations and Create the Database
Open the Package Manager Console and then execute the following Add-Migration and Update-Database commands:
This will generate a Migrations folder and create the ECommerceDB in SQL Server with the required tables shown in the image below.
In the next article, I will discuss How to Implement the Customer Module in our ECommerce Application. In this article, we have designed our ECommerce Application database using EF Core Code First Approach and ASP.NET Core Web API. I hope you enjoy this article on how to develop a Real-Time ECommerce Application Development using ASP.NET Core Web API and EF Core. Please give your valuable feedback in the comment section.
thank you very much
Great application, Mr. Pranaya explained every single step in the application/project, not only the technical side, but went over the business logic and how the application should work in real life, the approach was simple separate the objects for each other and have a project structure that separate getting the data and what data to expose. Mr. Pranaya is doing a great job working on details and take the time to answer questions and then quiz the attendance by asking questions.
Thank you for your time and hard work