Refactor payment verification to manual workflow and add comprehensive cleanup tools

Major changes:
• Remove BTCPay Server integration in favor of SilverPAY manual verification
• Add test data cleanup mechanisms (API endpoints and shell scripts)
• Fix compilation errors in TestController (IdentityReference vs CustomerIdentity)
• Add deployment automation scripts for Hostinger VPS
• Enhance integration testing with comprehensive E2E validation
• Add Blazor components and mobile-responsive CSS for admin interface
• Create production environment configuration scripts

Key Features Added:
• Manual payment verification through Admin panel Order Details
• Bulk test data cleanup with proper cascade handling
• Deployment automation with systemd service configuration
• Comprehensive E2E testing suite with SilverPAY integration validation
• Mobile-first admin interface improvements

Security & Production:
• Environment variable configuration for production secrets
• Proper JWT and VAPID key management
• SilverPAY API integration with live credentials
• Database cleanup and maintenance tools

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-09-25 19:29:00 +01:00
parent 1588c79df0
commit 127be759c8
46 changed files with 3470 additions and 971 deletions

View File

@@ -1,94 +0,0 @@
using System.Text.Json.Serialization;
namespace LittleShop.DTOs;
/// <summary>
/// DTO for BTCPay Server webhook events
/// Based on BTCPay Server webhook documentation
/// </summary>
public class BTCPayWebhookDto
{
[JsonPropertyName("deliveryId")]
public string DeliveryId { get; set; } = string.Empty;
[JsonPropertyName("webhookId")]
public string WebhookId { get; set; } = string.Empty;
[JsonPropertyName("originalDeliveryId")]
public string? OriginalDeliveryId { get; set; }
[JsonPropertyName("isRedelivery")]
public bool IsRedelivery { get; set; }
[JsonPropertyName("type")]
public string Type { get; set; } = string.Empty;
[JsonPropertyName("timestamp")]
public long Timestamp { get; set; }
[JsonPropertyName("storeId")]
public string StoreId { get; set; } = string.Empty;
[JsonPropertyName("invoiceId")]
public string InvoiceId { get; set; } = string.Empty;
[JsonPropertyName("afterExpiration")]
public bool? AfterExpiration { get; set; }
[JsonPropertyName("manuallyMarked")]
public bool? ManuallyMarked { get; set; }
[JsonPropertyName("overPaid")]
public bool? OverPaid { get; set; }
[JsonPropertyName("partiallyPaid")]
public bool? PartiallyPaid { get; set; }
[JsonPropertyName("payment")]
public BTCPayWebhookPayment? Payment { get; set; }
}
public class BTCPayWebhookPayment
{
[JsonPropertyName("id")]
public string Id { get; set; } = string.Empty;
[JsonPropertyName("receivedDate")]
public long ReceivedDate { get; set; }
[JsonPropertyName("value")]
public decimal Value { get; set; }
[JsonPropertyName("fee")]
public decimal? Fee { get; set; }
[JsonPropertyName("status")]
public string Status { get; set; } = string.Empty;
[JsonPropertyName("destination")]
public string? Destination { get; set; }
[JsonPropertyName("paymentMethod")]
public string PaymentMethod { get; set; } = string.Empty;
[JsonPropertyName("paymentMethodPaid")]
public decimal PaymentMethodPaid { get; set; }
[JsonPropertyName("transactionData")]
public BTCPayWebhookTransactionData? TransactionData { get; set; }
}
public class BTCPayWebhookTransactionData
{
[JsonPropertyName("transactionHash")]
public string? TransactionHash { get; set; }
[JsonPropertyName("blockHash")]
public string? BlockHash { get; set; }
[JsonPropertyName("blockHeight")]
public int? BlockHeight { get; set; }
[JsonPropertyName("confirmations")]
public int? Confirmations { get; set; }
}

View File

@@ -0,0 +1,32 @@
using System;
namespace LittleShop.DTOs
{
public class ProductVariationDto
{
public Guid Id { get; set; }
public Guid ProductId { get; set; }
public string Name { get; set; } = string.Empty;
public int Quantity { get; set; }
public decimal Price { get; set; }
public decimal PricePerUnit { get; set; }
public bool IsActive { get; set; } = true;
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
}
public class CreateProductVariationDto
{
public string Name { get; set; } = string.Empty;
public int Quantity { get; set; }
public decimal Price { get; set; }
}
public class UpdateProductVariationDto
{
public string Name { get; set; } = string.Empty;
public int Quantity { get; set; }
public decimal Price { get; set; }
public bool IsActive { get; set; } = true;
}
}