# LittleShop Client SDK A .NET client library for interacting with the LittleShop e-commerce API. This SDK provides a strongly-typed, easy-to-use interface for all LittleShop API endpoints with built-in authentication, retry policies, and error handling. ## Installation Add the LittleShop.Client library to your project: ```bash dotnet add reference ../LittleShop.Client/LittleShop.Client.csproj ``` Or via NuGet (when published): ```bash dotnet add package LittleShop.Client ``` ## Quick Start ### Basic Setup with Dependency Injection ```csharp using LittleShop.Client.Extensions; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; var host = Host.CreateDefaultBuilder(args) .ConfigureServices((context, services) => { // Add LittleShop client with configuration services.AddLittleShopClient(options => { options.BaseUrl = "https://localhost:5001"; options.TimeoutSeconds = 30; options.MaxRetryAttempts = 3; options.EnableLogging = true; }); }) .Build(); // Get the client from DI var client = host.Services.GetRequiredService(); ``` ### Simple Console Application Example ```csharp using LittleShop.Client; using LittleShop.Client.Extensions; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; // Setup DI container var services = new ServiceCollection(); services.AddLogging(builder => builder.AddConsole()); services.AddLittleShopClient("https://localhost:5001"); var serviceProvider = services.BuildServiceProvider(); var client = serviceProvider.GetRequiredService(); // Authenticate var loginResult = await client.Authentication.LoginAsync("admin", "admin"); if (loginResult.IsSuccess) { Console.WriteLine($"Logged in as: {loginResult.Data.Username}"); Console.WriteLine($"Token expires: {loginResult.Data.ExpiresAt}"); } // Get categories var categoriesResult = await client.Catalog.GetCategoriesAsync(); if (categoriesResult.IsSuccess) { foreach (var category in categoriesResult.Data) { Console.WriteLine($"Category: {category.Name} - {category.Description}"); } } // Get products with filtering var productsResult = await client.Catalog.GetProductsAsync( pageNumber: 1, pageSize: 10, searchTerm: "wireless", minPrice: 10, maxPrice: 100 ); if (productsResult.IsSuccess) { Console.WriteLine($"Found {productsResult.Data.TotalCount} products"); foreach (var product in productsResult.Data.Items) { Console.WriteLine($"Product: {product.Name} - £{product.Price}"); } } ``` ## Authentication The SDK handles JWT authentication automatically. Once you log in, the token is stored and automatically included in subsequent requests. ```csharp // Login var loginResult = await client.Authentication.LoginAsync("username", "password"); if (!loginResult.IsSuccess) { Console.WriteLine($"Login failed: {loginResult.ErrorMessage}"); return; } // Check if authenticated if (client.Authentication.IsAuthenticated()) { Console.WriteLine("User is authenticated"); } // Get current token (if needed for external use) var token = client.Authentication.GetToken(); // Logout client.Authentication.Logout(); ``` ## Catalog Operations ### Get All Categories ```csharp var result = await client.Catalog.GetCategoriesAsync(); if (result.IsSuccess) { foreach (var category in result.Data) { Console.WriteLine($"{category.Name}: {category.Description}"); } } ``` ### Get Products with Pagination and Filtering ```csharp var result = await client.Catalog.GetProductsAsync( pageNumber: 1, pageSize: 20, categoryId: categoryGuid, // Optional: Filter by category searchTerm: "headphones", // Optional: Search term minPrice: 50, // Optional: Minimum price maxPrice: 200 // Optional: Maximum price ); if (result.IsSuccess) { Console.WriteLine($"Page {result.Data.PageNumber} of {result.Data.TotalPages}"); Console.WriteLine($"Total products: {result.Data.TotalCount}"); foreach (var product in result.Data.Items) { Console.WriteLine($"{product.Name} - £{product.Price}"); if (product.Photos.Any()) { Console.WriteLine($" Photo: {product.Photos.First().Url}"); } } } ``` ### Get Single Product ```csharp var result = await client.Catalog.GetProductByIdAsync(productId); if (result.IsSuccess) { var product = result.Data; Console.WriteLine($"Name: {product.Name}"); Console.WriteLine($"Price: £{product.Price}"); Console.WriteLine($"Weight: {product.Weight} {product.WeightUnit}"); } ``` ## Order Operations ### Create Order ```csharp var orderRequest = new CreateOrderRequest { IdentityReference = "CUST123", ShippingName = "John Smith", ShippingAddress = "123 Main Street", ShippingCity = "London", ShippingPostCode = "SW1A 1AA", ShippingCountry = "United Kingdom", Notes = "Please deliver to reception", Items = new List { new CreateOrderItem { ProductId = productId1, Quantity = 2 }, new CreateOrderItem { ProductId = productId2, Quantity = 1 } } }; var result = await client.Orders.CreateOrderAsync(orderRequest); if (result.IsSuccess) { Console.WriteLine($"Order created: {result.Data.Id}"); Console.WriteLine($"Total: £{result.Data.TotalAmount}"); } ``` ### Get Orders by Customer Identity ```csharp var result = await client.Orders.GetOrdersByIdentityAsync("CUST123"); if (result.IsSuccess) { foreach (var order in result.Data) { Console.WriteLine($"Order {order.Id}: {order.Status} - £{order.TotalAmount}"); Console.WriteLine($" Created: {order.CreatedAt}"); if (!string.IsNullOrEmpty(order.TrackingNumber)) { Console.WriteLine($" Tracking: {order.TrackingNumber}"); } } } ``` ### Create Cryptocurrency Payment ```csharp var result = await client.Orders.CreatePaymentAsync(orderId, "BTC"); if (result.IsSuccess) { var payment = result.Data; Console.WriteLine($"Payment ID: {payment.Id}"); Console.WriteLine($"Send {payment.RequiredAmount} {payment.Currency} to:"); Console.WriteLine($"Address: {payment.WalletAddress}"); Console.WriteLine($"Expires: {payment.ExpiresAt}"); if (!string.IsNullOrEmpty(payment.BTCPayCheckoutUrl)) { Console.WriteLine($"Or pay via: {payment.BTCPayCheckoutUrl}"); } } ``` ## Error Handling All API methods return an `ApiResponse` wrapper that includes success status, data, and error information: ```csharp var result = await client.Catalog.GetProductByIdAsync(productId); if (result.IsSuccess) { // Success - access data var product = result.Data; Console.WriteLine($"Product: {product.Name}"); } else { // Error - handle appropriately Console.WriteLine($"Error: {result.ErrorMessage}"); Console.WriteLine($"Status Code: {result.StatusCode}"); switch (result.StatusCode) { case HttpStatusCode.NotFound: Console.WriteLine("Product not found"); break; case HttpStatusCode.Unauthorized: Console.WriteLine("Please login first"); break; case HttpStatusCode.BadRequest: Console.WriteLine("Invalid request"); break; default: Console.WriteLine("An error occurred"); break; } } ``` ## Advanced Configuration ### Custom HTTP Client Configuration The SDK uses Polly for retry policies and includes automatic retry for transient failures: ```csharp services.AddLittleShopClient(options => { options.BaseUrl = "https://api.littleshop.com"; options.TimeoutSeconds = 60; // Request timeout options.MaxRetryAttempts = 5; // Number of retries for transient failures options.EnableLogging = true; // Enable detailed logging }); ``` ### Using in ASP.NET Core Web Application ```csharp // In Program.cs or Startup.cs builder.Services.AddLittleShopClient(options => { options.BaseUrl = builder.Configuration["LittleShop:ApiUrl"]; options.TimeoutSeconds = 30; }); // In a controller or service public class ProductController : Controller { private readonly ILittleShopClient _client; public ProductController(ILittleShopClient client) { _client = client; } public async Task Index() { var result = await _client.Catalog.GetProductsAsync(); if (result.IsSuccess) { return View(result.Data.Items); } return View("Error", result.ErrorMessage); } } ``` ## Features - ✅ **Strongly Typed Models** - All API responses are mapped to C# classes - ✅ **Automatic Authentication** - JWT tokens are managed automatically - ✅ **Retry Policies** - Automatic retry for transient failures - ✅ **Error Handling** - Consistent error responses with detailed information - ✅ **Logging Support** - Built-in logging for debugging - ✅ **Dependency Injection** - Full DI support for ASP.NET Core applications - ✅ **Async/Await** - All methods are async for better performance - ✅ **Pagination Support** - Built-in pagination for product listings - ✅ **Filtering & Search** - Advanced filtering options for products ## API Coverage - **Authentication** - Login - Token refresh - Logout - **Catalog** - Get all categories - Get category by ID - Get products (with pagination and filtering) - Get product by ID - **Orders** - Create order - Get orders by customer identity - Get order by ID - Create cryptocurrency payment - Get order payments ## Requirements - .NET 9.0 or later - LittleShop API server running and accessible ## License This SDK is part of the LittleShop e-commerce platform.