سیستم مدیریت سبد خرید با C#

تاریخ: 1404/12/4 ساعت: 15:22 بازدید: 9

سیستم مدیریت سبد خرید با C# چیست و چرا اهمیت دارد؟

اگر قرار است یک فروشگاه آنلاین یا اپلیکیشن تجارت الکترونیک بسازید، سیستم مدیریت سبد خرید قلب تپنده‌ی آن است. این سیستم مشخص می‌کند که کاربر چه محصولاتی انتخاب کرده، چه مقداری، چه قیمتی باید بپردازد و در نهایت فرایند خرید چگونه تکمیل می‌شود.

زبان C# به دلیل ساختار قوی، پشتیبانی از برنامه‌نویسی شیءگرا (OOP)، یکپارچگی با ASP.NET Core و اکوسیستم غنی مایکروسافت، یکی از بهترین انتخاب‌ها برای پیاده‌سازی چنین سیستمی است. در این مقاله، از صفر تا صد طراحی و پیاده‌سازی یک سیستم سبد خرید با C# را با هم مرور می‌کنیم.

معماری و اجزای اصلی سبد خرید

قبل از نوشتن حتی یک خط کد، باید معماری سیستم را درک کنیم. یک سبد خرید حرفه‌ای معمولاً از این اجزا تشکیل می‌شود:

  • مدل داده (Data Model): کلاس‌هایی مثل Product، CartItem و ShoppingCart
  • لایه سرویس (Service Layer): منطق اضافه کردن، حذف و به‌روزرسانی آیتم‌ها
  • لایه ذخیره‌سازی (Repository Layer): ارتباط با دیتابیس یا Session
  • لایه کنترلر (Controller Layer): دریافت درخواست‌های کاربر در ASP.NET
  • View یا API Response: نمایش اطلاعات سبد به کاربر

طراحی مدل داده در C#

اولین قدم، طراحی کلاس‌های اصلی است. یک طراحی تمیز و قابل توسعه به این شکل خواهد بود:

کلاس Product


public class Product

{

public int Id { get; set; }

public string Name { get; set; }

public string Description { get; set; }

public decimal Price { get; set; }

public int StockQuantity { get; set; }

public string ImageUrl { get; set; }

public string Category { get; set; }

}

کلاس CartItem


public class CartItem

{

public int Id { get; set; }

public int ProductId { get; set; }

public Product Product { get; set; }

public int Quantity { get; set; }

public decimal UnitPrice { get; set; }

public decimal TotalPrice => UnitPrice * Quantity;

}

کلاس ShoppingCart


public class ShoppingCart

{

public string CartId { get; set; }

public string UserId { get; set; }

public List Items { get; set; } = new List();

public DateTime CreatedAt { get; set; } = DateTime.Now;

public DateTime UpdatedAt { get; set; } = DateTime.Now;

public decimal SubTotal => Items.Sum(i => i.TotalPrice);

public decimal DiscountAmount { get; set; }

public decimal ShippingCost { get; set; }

public decimal TotalAmount => SubTotal - DiscountAmount + ShippingCost;

public int TotalItems => Items.Sum(i => i.Quantity);

}

پیاده‌سازی سرویس مدیریت سبد خرید

حالا باید منطق اصلی برنامه را بنویسیم. اینترفیس ICartService را ابتدا تعریف می‌کنیم تا از اصل Dependency Inversion پیروی کنیم:


public interface ICartService

{

Task GetCartAsync(string cartId);

Task AddItemAsync(string cartId, int productId, int quantity);

Task UpdateItemAsync(string cartId, int cartItemId, int quantity);

Task RemoveItemAsync(string cartId, int cartItemId);

Task ClearCartAsync(string cartId);

Task ApplyDiscountAsync(string cartId, string couponCode);

}

و حالا پیاده‌سازی اصلی این سرویس:


public class CartService : ICartService

{

private readonly ICartRepository _cartRepository;

private readonly IProductRepository _productRepository;

public CartService(

ICartRepository cartRepository,

IProductRepository productRepository)

{

_cartRepository = cartRepository;

_productRepository = productRepository;

}

public async Task AddItemAsync(

string cartId, int productId, int quantity)

{

var cart = await _cartRepository.GetCartAsync(cartId)

?? new ShoppingCart { CartId = cartId };

var product = await _productRepository.GetByIdAsync(productId);

if (product == null)

throw new Exception(“محصول یافت نشد.”);

if (product.StockQuantity < quantity)

throw new Exception(“موجودی کافی نیست.”);

var existingItem = cart.Items

.FirstOrDefault(i => i.ProductId == productId);

if (existingItem != null)

{

existingItem.Quantity += quantity;

}

else

{

cart.Items.Add(new CartItem

{

ProductId = productId,

Product = product,

Quantity = quantity,

UnitPrice = product.Price

});

}

cart.UpdatedAt = DateTime.Now;

await _cartRepository.SaveCartAsync(cart);

return cart;

}

public async Task RemoveItemAsync(

string cartId, int cartItemId)

{

var cart = await _cartRepository.GetCartAsync(cartId);

if (cart == null)

throw new Exception(“سبد خرید یافت نشد.”);

var item = cart.Items.FirstOrDefault(i => i.Id == cartItemId);

if (item != null)

cart.Items.Remove(item);

cart.UpdatedAt = DateTime.Now;

await _cartRepository.SaveCartAsync(cart);

return cart;

}

public async Task ApplyDiscountAsync(

string cartId, string couponCode)

{

var cart = await _cartRepository.GetCartAsync(cartId);

// منطق اعمال کد تخفیف

if (couponCode == “DISCOUNT20”)

cart.DiscountAmount = cart.SubTotal * 0.20m;

await _cartRepository.SaveCartAsync(cart);

return cart;

}

}

ذخیره‌سازی سبد خرید: Session یا دیتابیس؟

یکی از مهم‌ترین تصمیمات معماری در طراحی سبد خرید، محل ذخیره‌سازی داده‌ها است. دو رویکرد اصلی وجود دارد:

۱. ذخیره‌سازی با Session (برای کاربران مهمان)

  • مزیت: پیاده‌سازی سریع و ساده
  • مزیت: نیازی به لاگین کاربر ندارد
  • معایب: با بستن مرورگر از بین می‌رود
  • معایب: در محیط‌های Load Balanced مشکل‌ساز است

// ذخیره سبد در Session با JSON Serialization

public class SessionCartRepository : ICartRepository

{

private readonly IHttpContextAccessor _httpContextAccessor;

private const string CartSessionKey = “ShoppingCart”;

public SessionCartRepository(IHttpContextAccessor httpContextAccessor)

{

_httpContextAccessor = httpContextAccessor;

}

public Task GetCartAsync(string cartId)

{

var session = _httpContextAccessor.HttpContext.Session;

var cartJson = session.GetString(CartSessionKey);

if (string.IsNullOrEmpty(cartJson))

return Task.FromResult(null);

var cart = JsonSerializer.Deserialize(cartJson);

return Task.FromResult(cart);

}

public Task SaveCartAsync(ShoppingCart cart)

{

var session = _httpContextAccessor.HttpContext.Session;

var cartJson = JsonSerializer.Serialize(cart);

session.SetString(CartSessionKey, cartJson);

return Task.CompletedTask;

}

}

۲. ذخیره‌سازی در دیتابیس (برای کاربران لاگین‌شده)

با استفاده از Entity Framework Core، می‌توانیم سبد خرید را در SQL Server یا هر دیتابیس دیگری ذخیره کنیم. این روش برای کاربران ثبت‌نام‌شده ایده‌آل است زیرا سبد خرید بین جلسات مختلف حفظ می‌شود:


public class ApplicationDbContext : DbContext

{

public DbSet ShoppingCarts { get; set; }

public DbSet CartItems { get; set; }

public DbSet Products { get; set; }

protected override void OnModelCreating(ModelBuilder modelBuilder)

{

modelBuilder.Entity()

.HasMany(c => c.Items)

.WithOne()

.OnDelete(DeleteBehavior.Cascade);

modelBuilder.Entity()

.Property(i => i.UnitPrice)

.HasColumnType(“decimal(18,2)”);

}

}

🚀 آیا می‌خواهید سایت شما هم مثل رقبا در صفحه اول گوگل باشد و زنگ‌خورهایتان چند برابر شود؟

سئوی سایت خود را به متخصصان ما بسپارید. همین حالا برای مشاوره رایگان با ما تماس بگیرید:

📞 09190994063 - 09376846692

پیاده‌سازی کنترلر در ASP.NET Core

با داشتن سرویس و ریپازیتوری، حالا می‌توانیم CartController را پیاده‌سازی کنیم:


[ApiController]

[Route(“api/[controller]”)]

public class CartController : ControllerBase

{

private readonly ICartService _cartService;

public CartController(ICartService cartService)

{

_cartService = cartService;

}

[HttpGet(“{cartId}”)]

public async Task GetCart(string cartId)

{

var cart = await _cartService.GetCartAsync(cartId);

if (cart == null)

return NotFound(new { message = “سبد خرید یافت نشد.” });

return Ok(cart);

}

[HttpPost(“{cartId}/items”)]

public async Task AddItem(

string cartId, [FromBody] AddItemRequest request)

{

try

{

var cart = await _cartService.AddItemAsync(

cartId, request.ProductId, request.Quantity);

return Ok(cart);

}

catch (Exception ex)

{

return BadRequest(new { message = ex.Message });

}

}

[HttpDelete(“{cartId}/items/{itemId}”)]

public async Task RemoveItem(

string cartId, int itemId)

{

var cart = await _cartService.RemoveItemAsync(cartId, itemId);

return Ok(cart);

}

[HttpPost(“{cartId}/discount”)]

public async Task ApplyDiscount(

string cartId, [FromBody] DiscountRequest request)

{

var cart = await _cartService.ApplyDiscountAsync(

cartId, request.CouponCode);

return Ok(cart);

}

}

استفاده از Redis برای کش سبد خرید

در پروژه‌های بزرگ با ترافیک بالا، استفاده از Redis برای کش کردن سبد خرید یک بهترین تجربه (Best Practice) محسوب می‌شود. Redis یک پایگاه داده In-Memory است که سرعت بسیار بالایی دارد:


public class RedisCartRepository : ICartRepository

{

private readonly IDistributedCache _cache;

private readonly TimeSpan _expiry = TimeSpan.FromDays(30);

public RedisCartRepository(IDistributedCache cache)

{

_cache = cache;

}

public async Task GetCartAsync(string cartId)

{

var cartJson = await _cache.GetStringAsync(cartId);

if (string.IsNullOrEmpty(cartJson))

return null;

return JsonSerializer.Deserialize(cartJson);

}

public async Task SaveCartAsync(ShoppingCart cart)

{

var cartJson = JsonSerializer.Serialize(cart);

await _cache.SetStringAsync(cart.CartId, cartJson,

new DistributedCacheEntryOptions

{

AbsoluteExpirationRelativeToNow = _expiry

});

}

public async Task DeleteCartAsync(string cartId)

{

await _cache.RemoveAsync(cartId);

}

}

ثبت سرویس‌ها در Program.cs

برای اینکه همه چیز کار کند، باید وابستگی‌ها را در Dependency Injection Container ثبت کنیم:


var builder = WebApplication.CreateBuilder(args);

// ثبت DbContext

builder.Services.AddDbContext(options =>

options.UseSqlServer(

builder.Configuration.GetConnectionString(“DefaultConnection”)));

// ثبت Redis

builder.Services.AddStackExchangeRedisCache(options =>

{

options.Configuration = builder.Configuration[“Redis:ConnectionString”];

});

// ثبت سرویس‌ها

builder.Services.AddScoped();

builder.Services.AddScoped();

builder.Services.AddScoped();

// Session Configuration

builder.Services.AddSession(options =>

{

options.IdleTimeout = TimeSpan.FromMinutes(30);

options.Cookie.HttpOnly = true;

options.Cookie.IsEssential = true;

});

var app = builder.Build();

app.UseSession();

app.MapControllers();

app.Run();

بهترین تجربه‌ها (Best Practices) در طراحی سبد خرید

  • بررسی موجودی قبل از افزودن: همیشه قبل از اضافه کردن محصول به سبد، موجودی آن را چک کنید.
  • ذخیره قیمت در لحظه خرید: قیمت را در CartItem ذخیره کنید تا تغییرات بعدی قیمت محصول روی سبد تاثیر نگذارد.
  • ادغام سبد مهمان با سبد کاربر: وقتی کاربر مهمان لاگین می‌کند، سبد Session را با سبد دیتابیس ادغام کنید.
  • اعتبارسنجی داده‌ها: از FluentValidation برای اعتبارسنجی تعداد و شناسه محصول استفاده کنید.
  • Unit Testing: حتماً برای CartService تست واحد بنویسید تا از صحت منطق مطمئن شوید.
  • مدیریت Concurrency: از Optimistic Concurrency برای جلوگیری از خریدهای همزمان یک محصول محدود استفاده کنید.

تست واحد برای CartService

یک کد بدون تست، کد ناقص است. با استفاده از xUnit و Moq، می‌توانیم سرویس را تست کنیم:


public class CartServiceTests

{

private readonly Mock _cartRepoMock;

private readonly Mock _productRepoMock;

private readonly CartService _cartService;

public CartServiceTests()

{

_cartRepoMock = new Mock();

_productRepoMock = new Mock();

_cartService = new CartService(

_cartRepoMock.Object,

_productRepoMock.Object);

}

[Fact]

public async Task AddItem_WhenProductExists_ShouldAddToCart()

{

// Arrange

var product = new Product

{

Id = 1,

Name = “لپ‌تاپ”,

Price = 25000000m,

StockQuantity = 10

};

_productRepoMock

.Setup(r => r.GetByIdAsync(1))

.ReturnsAsync(product);

_cartRepoMock

.Setup(r => r.GetCartAsync(“cart-001”))

.ReturnsAsync((ShoppingCart)null);

// Act

var cart = await _cartService.AddItemAsync(“cart-001”, 1, 2);

// Assert

Assert.Single(cart.Items);

Assert.Equal(2, cart.Items[0].Quantity);

Assert.Equal(50000000m, cart.TotalAmount);

}

}

💡 یک نکته مهم برای شما:

داشتن کد خوب کافی نیست! اگر سایت یا فروشگاه آنلاین شما در گوگل دیده نشود، هیچ‌کس آن را پیدا نمی‌کند. سئوی حرفه‌ای یعنی تبدیل بازدیدکننده به مشتری واقعی.

آیا می‌خواهید سایت شما هم مثل رقبا در صفحه اول گوگل باشد و زنگ‌خورهایتان چند برابر شود؟ سئوی سایت خود را به متخصصان ما بسپارید.

📞 همین حالا برای مشاوره رایگان تماس بگیرید: 09190994063 - 09376846692

سوالات متداول (FAQ)

۱. تفاوت ذخیره سبد خرید در Session و دیتابیس چیست؟

Session برای کاربران مهمان (Guest) مناسب است و با بستن مرورگر از بین می‌رود. دیتابیس برای کاربران ثبت‌نام‌شده ایده‌آل است چون سبد در جلسات مختلف حفظ می‌شود. بهترین روش، ترکیب هر دو است: کاربر مهمان از Session استفاده می‌کند و پس از لاگین، سبد با دیتابیس ادغام می‌شود.

۲. چطور از خرید بیش از موجودی جلوگیری کنیم؟

در متد AddItemAsync باید قبل از افزودن محصول به سبد، مقدار StockQuantity را با تعداد درخواستی مقایسه کنید. همچنین در زمان نهایی‌سازی خرید (Checkout)، باید مجدداً موجودی را با استفاده از Optimistic Concurrency یا Transaction بررسی کنید تا از Race Condition جلوگیری شود.

۳. آیا Redis برای سبد خرید الزامی است؟

خیر. Redis یک بهینه‌سازی اختیاری است. برای پروژه‌های کوچک و متوسط، Session یا دیتابیس کاملاً کافی است. اما اگر ترافیک بالایی دارید یا از چندین سرور (Load Balancing) استفاده می‌کنید، Redis سرعت و مقیاس‌پذیری را به شدت بهبود می‌دهد.

۴. چطور کد تخفیف را در سیستم سبد خرید پیاده‌سازی کنیم؟

برای این کار یک جدول Coupon در دیتابیس بسازید که شامل کد، نوع تخفیف (درصدی یا مبلغ ثابت)، تاریخ انقضا و حداقل مبلغ خرید باشد. در متد ApplyDiscountAsync، کد وارد شده با جدول Coupon مقایسه می‌شود و در صورت معتبر بودن، مقدار DiscountAmount در سبد خرید به‌روزرسانی می‌شود.

۵. بهترین روش برای نمایش تعداد آیتم‌های سبد در Header سایت چیست؟

در ASP.NET Core MVC، می‌توانید از یک ViewComponent به نام CartSummaryViewComponent استفاده کنید که در هر بار لود صفحه، تعداد آیتم‌های سبد را از Session یا Cache می‌خواند و در Header نمایش می‌دهد. برای بهینگی بیشتر، از AJAX و SignalR می‌توانید سبد را به صورت Real-Time به‌روز کنید.

۶. آیا می‌توان سبد خرید را با Microservices پیاده‌سازی کرد؟

بله! در معماری Microservices، می‌توانید یک سرویس مستقل Cart Service داشته باشید که از طریق gRPC یا REST API با سایر سرویس‌ها (مثل Product Service و Order Service) ارتباط برقرار می‌کند. در این حالت، Redis به عنوان Storage اصلی سبد، انتخاب رایج است و Event Sourcing با RabbitMQ یا Kafka برای هماهنگی بین سرویس‌ها استفاده می‌شود.

نظرات کاربران


کاوه نادری
تاریخ 1404/12/8 ساعت 13:50

کنترلر API به خوبی طراحی شده بود. در سیستم‌های بزرگ‌تر که نیاز به ردیابی سبدهای رها شده (Abandoned Carts) داریم، چه تغییراتی لازم است؟

سایت اینجا:

برای ردیابی سبدهای رها شده، ابتدا باید یک زمان‌بندی (Scheduler) تعریف کنید که به صورت دوره‌ای سبدهای ذخیره شده در دیتابیس را بررسی کند. سپس سبدهایی که برای مدت مشخصی به‌روز نشده‌اند و تبدیل به سفارش نشده‌اند را به عنوان رها شده علامت‌گذاری کنید. می‌توانید با ارسال ایمیل یادآوری یا نوتیفیکیشن، کاربران را تشویق به تکمیل خرید کنید. این قابلیت نیازمند یک سرویس جداگانه (مثلاً Background Service) است. برای مشاوره بیشتر با ما تماس بگیرید: 09190994063 - 09376846692

مریم احمدی
تاریخ 1404/12/8 ساعت 4:45

مقاله فوق‌العاده‌ای بود، به خصوص بخش ذخیره‌سازی با Redis. سوال من در مورد مدیریت موجودی است. اگر همزمان چند کاربر قصد خرید یک محصول محدود را داشته باشند، چطور می‌توان از فروش بیش از موجودی جلوگیری کرد؟

سایت اینجا:

برای جلوگیری از فروش بیش از موجودی در سناریوهای همزمان، باید از تکنیک‌هایی مانند Optimistic Concurrency یا استفاده از Transaction در دیتابیس در زمان نهایی‌سازی خرید (Checkout) بهره ببرید. همچنین می‌توانید از صف‌های پیام (Message Queues) برای پردازش سفارش‌ها استفاده کنید. برای مشاوره و پیاده‌سازی این موارد با ما تماس بگیرید: 09190994063 - 09376846692

محسن یوسفی
تاریخ 1404/12/7 ساعت 16:30

سپاس از توضیحات جامع. بخش تست واحد بسیار مفید بود. آیا برای مدیریت خطاهای پیش‌بینی نشده در سرویس‌ها (مثل نبود محصول)، مکانیزم خاصی برای گزارش‌گیری و نمایش پیام‌های کاربرپسند پیشنهاد می‌کنید؟

سایت اینجا:

بله، برای مدیریت خطاها در سرویس‌ها، توصیه می‌شود از سیستم‌های Logging (مانند Serilog یا NLog) استفاده کنید تا خطاها را ثبت کنید. همچنین می‌توانید از Middleware های سفارشی در ASP.NET Core برای گرفتن استثناها و برگرداندن پاسخ‌های استاندارد و کاربرپسند (مثلاً JSON با کد خطا و پیام مناسب) استفاده کنید. برای اطلاعات بیشتر با ما تماس بگیرید: 09190994063 - 09376846692

زهرا رضایی
تاریخ 1404/12/7 ساعت 7:25

مقاله به قدری کامل بود که واقعا به دیدگاه من در مورد سبد خرید نظم داد. ممنونم. آیا برای سبد خرید قابلیت‌هایی مثل 'لیست علاقه‌مندی‌ها' (Wishlist) هم می‌شود در همین معماری جای داد یا بهتر است یک ماژول جداگانه باشد؟

سایت اینجا:

بسیار عالی، خوشحالیم که مفید بوده! 'لیست علاقه‌مندی‌ها' (Wishlist) هرچند مفهوم مشابهی با سبد خرید دارد، اما معمولاً بهتر است به عنوان یک ماژول یا سرویس جداگانه پیاده‌سازی شود. دلیل آن این است که Wishlist منطق و هدف متفاوتی دارد (ذخیره برای خرید آتی، اشتراک‌گذاری با دیگران) و نیازمندی‌های خاص خود را در دیتابیس و رابط کاربری دارد. با این حال، می‌توان بین آن‌ها ارتباطاتی برقرار کرد. برای مشاوره در طراحی با ما تماس بگیرید: 09190994063 - 09376846692

رضا کریمی
تاریخ 1404/12/6 ساعت 22:20

تفاوت بین ذخیره‌سازی در Session و دیتابیس رو به خوبی توضیح دادید. می‌خواستم بپرسم وقتی کاربر مهمان لاگین می‌کنه، چطور سبد خرید Session با دیتابیس ادغام میشه؟ آیا منطق خاصی برای حل تداخل‌ها وجود داره؟

سایت اینجا:

بله، وقتی کاربر مهمان لاگین می‌کند، باید محتویات سبد خرید ذخیره شده در Session را بخوانید و سپس آن آیتم‌ها را به سبد خرید کاربر در دیتابیس اضافه کنید. در صورت وجود تداخل (مثلاً یک محصول مشترک در هر دو سبد)، معمولاً تعداد موجود در سبد Session را به تعداد موجود در سبد دیتابیس اضافه می‌کنند. پس از ادغام، سبد Session باید پاک شود. برای مشاوره حرفه‌ای با ما تماس بگیرید: 09190994063 - 09376846692

حامد قاسمی
تاریخ 1404/12/6 ساعت 1:0

در مورد استفاده از Redis، آیا برای پیاده‌سازی آن نیاز به تنظیمات پیچیده‌ای در سرور داریم؟ آیا Redis می‌تواند در محیط ابری (مثل Azure یا AWS) هم به همین راحتی استفاده شود؟

سایت اینجا:

Redis در محیط‌های ابری (Azure Cache for Redis یا AWS ElastiCache) به راحتی قابل راه‌اندازی و استفاده است و بسیاری از پیچیدگی‌های مدیریت سرور را پوشش می‌دهند. در سرورهای شخصی هم نصب و کانفیگ آن نسبتاً ساده است. استفاده از IDistributedCache در ASP.NET Core انتزاع خوبی برای کار با Redis فراهم می‌کند. برای جزئیات پیاده‌سازی با ما تماس بگیرید: 09190994063 - 09376846692

علی محمدی
تاریخ 1404/12/5 ساعت 21:30

مقاله بسیار جامع و کاربردی بود. ممنون از توضیحات کامل. یک سوال: آیا امکان پیاده‌سازی به‌روزرسانی لحظه‌ای سبد خرید (مثلاً با SignalR) وجود دارد که بدون رفرش صفحه، تعداد آیتم‌ها در هدر به‌روز شود؟

سایت اینجا:

خواهش می‌کنم، خوشحالیم که مقاله مفید بوده است. بله، قطعاً امکان پیاده‌سازی به‌روزرسانی لحظه‌ای با استفاده از SignalR وجود دارد. این روش تجربه کاربری را به شکل قابل توجهی بهبود می‌بخشد. برای جزئیات بیشتر یا مشاوره می‌توانید تماس بگیرید: 09190994063 - 09376846692

سارا حسینی
تاریخ 1404/12/4 ساعت 23:29

بخش مدل داده و سرویس‌ها عالی بود. در مورد اعمال کد تخفیف، آیا منطق پیچیده‌تری مثل تخفیف برای محصولات خاص یا محدودیت‌های استفاده (یک بار مصرف) هم قابل پیاده‌سازی است؟

سایت اینجا:

بله، منطق تخفیف می‌تواند بسیار پیچیده‌تر باشد. می‌توانید یک جدول Coupon در دیتابیس با فیلدهایی برای نوع تخفیف، محصولات مجاز، تاریخ انقضا، حداقل مبلغ خرید و تعداد دفعات استفاده تعریف کنید. سپس در متد ApplyDiscountAsync تمامی این شرایط را بررسی کنید. برای راهنمایی بیشتر با ما تماس بگیرید: 09190994063 - 09376846692

فاطمه ناصری
تاریخ 1404/12/4 ساعت 18:34

یک سناریو خاص: اگر کاربر یک محصول را به سبد اضافه کند و بعداً قیمت آن محصول در فروشگاه تغییر کند، آیا قیمت در سبد خرید به‌روز می‌شود یا همان قیمت زمان اضافه شدن حفظ می‌شود؟

سایت اینجا:

نکته بسیار مهمی است! در طراحی که ارائه شد، قیمت (UnitPrice) در CartItem ذخیره می‌شود. این بدان معناست که اگر قیمت محصول اصلی تغییر کند، قیمت در سبد خرید همان قیمت زمان اضافه شدن به سبد باقی می‌ماند. این یک Best Practice است تا کاربر تجربه‌ی ثابت‌تری داشته باشد. البته می‌توانید منطق به‌روزرسانی را نیز پیاده‌سازی کنید. برای مشاوره فنی با ما در تماس باشید: 09190994063 - 09376846692