Features: - Complete .NET client SDK for LittleShop API - JWT authentication with automatic token management - Catalog service for products and categories - Order service with payment creation - Retry policies using Polly for resilience - Error handling middleware - Dependency injection support - Comprehensive documentation and examples SDK Components: - Authentication service with token refresh - Strongly-typed models for all API responses - HTTP handlers for retry and error handling - Extension methods for easy DI registration - Example console application demonstrating usage Test Updates: - Fixed test compilation errors - Updated test data builders for new models - Corrected service constructor dependencies - Fixed enum value changes (PaymentStatus, OrderStatus) Documentation: - Complete project README with features and usage - Client SDK README with detailed examples - API endpoint documentation - Security considerations - Deployment guidelines Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
180 lines
6.2 KiB
C#
180 lines
6.2 KiB
C#
using LittleShop.Client;
|
|
using LittleShop.Client.Extensions;
|
|
using LittleShop.Client.Models;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Logging;
|
|
using System.Text.Json;
|
|
|
|
// Setup dependency injection
|
|
var services = new ServiceCollection();
|
|
|
|
// Add logging
|
|
services.AddLogging(builder => builder
|
|
.AddConsole()
|
|
.SetMinimumLevel(LogLevel.Information));
|
|
|
|
// Add LittleShop client
|
|
services.AddLittleShopClient(options =>
|
|
{
|
|
options.BaseUrl = "https://localhost:5001"; // Update this to your API URL
|
|
options.TimeoutSeconds = 30;
|
|
options.MaxRetryAttempts = 3;
|
|
options.EnableLogging = true;
|
|
});
|
|
|
|
// Build service provider
|
|
var serviceProvider = services.BuildServiceProvider();
|
|
|
|
// Get the client
|
|
var client = serviceProvider.GetRequiredService<ILittleShopClient>();
|
|
|
|
Console.WriteLine("=== LittleShop Client Example ===\n");
|
|
|
|
try
|
|
{
|
|
// Step 1: Authenticate
|
|
Console.WriteLine("1. Authenticating...");
|
|
var loginResult = await client.Authentication.LoginAsync("admin", "admin");
|
|
|
|
if (!loginResult.IsSuccess)
|
|
{
|
|
Console.WriteLine($"Login failed: {loginResult.ErrorMessage}");
|
|
return;
|
|
}
|
|
|
|
Console.WriteLine($"✓ Logged in as: {loginResult.Data!.Username}");
|
|
Console.WriteLine($" Token expires: {loginResult.Data.ExpiresAt}\n");
|
|
|
|
// Step 2: Get Categories
|
|
Console.WriteLine("2. Fetching categories...");
|
|
var categoriesResult = await client.Catalog.GetCategoriesAsync();
|
|
|
|
if (categoriesResult.IsSuccess && categoriesResult.Data!.Any())
|
|
{
|
|
Console.WriteLine($"✓ Found {categoriesResult.Data.Count} categories:");
|
|
foreach (var category in categoriesResult.Data)
|
|
{
|
|
Console.WriteLine($" - {category.Name}: {category.Description}");
|
|
}
|
|
Console.WriteLine();
|
|
}
|
|
|
|
// Step 3: Get Products
|
|
Console.WriteLine("3. Fetching products...");
|
|
var productsResult = await client.Catalog.GetProductsAsync(
|
|
pageNumber: 1,
|
|
pageSize: 5
|
|
);
|
|
|
|
if (productsResult.IsSuccess && productsResult.Data!.Items.Any())
|
|
{
|
|
Console.WriteLine($"✓ Found {productsResult.Data.TotalCount} products (showing first {productsResult.Data.Items.Count}):");
|
|
foreach (var product in productsResult.Data.Items)
|
|
{
|
|
Console.WriteLine($" - {product.Name}");
|
|
Console.WriteLine($" Price: £{product.Price:F2}");
|
|
Console.WriteLine($" Weight: {product.Weight} {product.WeightUnit}");
|
|
Console.WriteLine($" Category: {product.CategoryName}");
|
|
}
|
|
Console.WriteLine();
|
|
}
|
|
|
|
// Step 4: Create a sample order
|
|
Console.WriteLine("4. Creating a sample order...");
|
|
|
|
// Get first product for the order
|
|
var firstProduct = productsResult.Data!.Items.FirstOrDefault();
|
|
if (firstProduct != null)
|
|
{
|
|
var orderRequest = new CreateOrderRequest
|
|
{
|
|
IdentityReference = "CLIENT_DEMO_001",
|
|
ShippingName = "Demo Customer",
|
|
ShippingAddress = "123 Test Street",
|
|
ShippingCity = "London",
|
|
ShippingPostCode = "SW1A 1AA",
|
|
ShippingCountry = "United Kingdom",
|
|
Notes = "Test order from client SDK",
|
|
Items = new List<CreateOrderItem>
|
|
{
|
|
new CreateOrderItem
|
|
{
|
|
ProductId = firstProduct.Id,
|
|
Quantity = 1
|
|
}
|
|
}
|
|
};
|
|
|
|
var orderResult = await client.Orders.CreateOrderAsync(orderRequest);
|
|
|
|
if (orderResult.IsSuccess)
|
|
{
|
|
Console.WriteLine($"✓ Order created successfully!");
|
|
Console.WriteLine($" Order ID: {orderResult.Data!.Id}");
|
|
Console.WriteLine($" Total: £{orderResult.Data.TotalAmount:F2}");
|
|
Console.WriteLine($" Status: {orderResult.Data.Status}\n");
|
|
|
|
// Step 5: Create a payment for the order
|
|
Console.WriteLine("5. Creating Bitcoin payment for the order...");
|
|
var paymentResult = await client.Orders.CreatePaymentAsync(orderResult.Data.Id, "BTC");
|
|
|
|
if (paymentResult.IsSuccess)
|
|
{
|
|
Console.WriteLine($"✓ Payment created successfully!");
|
|
Console.WriteLine($" Payment ID: {paymentResult.Data!.Id}");
|
|
Console.WriteLine($" Amount: {paymentResult.Data.RequiredAmount} BTC");
|
|
Console.WriteLine($" Send to: {paymentResult.Data.WalletAddress}");
|
|
Console.WriteLine($" Expires: {paymentResult.Data.ExpiresAt}");
|
|
|
|
if (!string.IsNullOrEmpty(paymentResult.Data.BTCPayCheckoutUrl))
|
|
{
|
|
Console.WriteLine($" Checkout URL: {paymentResult.Data.BTCPayCheckoutUrl}");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine($"✗ Payment creation failed: {paymentResult.ErrorMessage}");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine($"✗ Order creation failed: {orderResult.ErrorMessage}");
|
|
}
|
|
}
|
|
|
|
// Step 6: Get orders for the identity
|
|
Console.WriteLine("\n6. Fetching orders for identity 'CLIENT_DEMO_001'...");
|
|
var ordersResult = await client.Orders.GetOrdersByIdentityAsync("CLIENT_DEMO_001");
|
|
|
|
if (ordersResult.IsSuccess && ordersResult.Data!.Any())
|
|
{
|
|
Console.WriteLine($"✓ Found {ordersResult.Data.Count} orders:");
|
|
foreach (var order in ordersResult.Data)
|
|
{
|
|
Console.WriteLine($" - Order {order.Id}");
|
|
Console.WriteLine($" Status: {order.Status}");
|
|
Console.WriteLine($" Total: £{order.TotalAmount:F2}");
|
|
Console.WriteLine($" Created: {order.CreatedAt}");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine(" No orders found for this identity.");
|
|
}
|
|
|
|
Console.WriteLine("\n=== Example completed successfully! ===");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine($"\n✗ Error: {ex.Message}");
|
|
if (ex.InnerException != null)
|
|
{
|
|
Console.WriteLine($" Inner: {ex.InnerException.Message}");
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
// Cleanup
|
|
client.Authentication.Logout();
|
|
Console.WriteLine("\nLogged out.");
|
|
} |