Files
pos-system/services/wallet-service-net/src/WalletService.API/Application/Validations/CreatePaymentCommandValidator.cs
Ho Ngoc Hai 8af86e9e89 feat: implement Phase 1 payment gateway, real-time SignalR, kitchen-inventory deduction, and order payment flow
- wallet-service: IPaymentGateway abstraction + VN Pay implementation (HMAC-SHA512, sandbox), Payment aggregate root, PaymentsController with create/callback/query endpoints
- order-service: PosHub SignalR hub with Redis backplane + MessagePack, strongly-typed clients, 3 group types (shop/kds/pos), integrated into Create/Pay/Complete/Cancel order handlers
- fnb-engine + inventory-service: Kitchen→Inventory auto-deduction via domain events, HTTP with Polly retry + circuit breaker, idempotency check, graceful degradation on insufficient stock
- order-service: Enhanced PayOrderCommand with 3 flows (cash/card/online), PaymentPending status, WalletServiceClient, CompleteOrderPaymentCommand for gateway callbacks
- POS frontend: Cash/Card/QR payment components wired to real backend, BFF proxy updated
- infra: Traefik routes for fnb-engine, inventory-service, and SignalR WebSocket hub
- ROADMAP.md: Updated with Phase 1 progress tracking

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 13:28:46 +07:00

65 lines
2.4 KiB
C#

namespace WalletService.API.Application.Validations;
using FluentValidation;
using WalletService.API.Application.Commands.Payments;
/// <summary>
/// EN: Validator for CreatePaymentCommand.
/// VI: Validator cho CreatePaymentCommand.
/// </summary>
public class CreatePaymentCommandValidator : AbstractValidator<CreatePaymentCommand>
{
public CreatePaymentCommandValidator()
{
RuleFor(x => x.OrderId)
.NotEmpty()
.WithMessage("Order ID is required / Ma don hang la bat buoc");
RuleFor(x => x.Amount)
.GreaterThan(0)
.WithMessage("Amount must be greater than zero / So tien phai lon hon 0");
RuleFor(x => x.Currency)
.NotEmpty()
.WithMessage("Currency is required / Tien te la bat buoc")
.MaximumLength(10)
.WithMessage("Currency code must not exceed 10 characters / Ma tien te khong vuot qua 10 ky tu");
RuleFor(x => x.GatewayName)
.NotEmpty()
.WithMessage("Gateway name is required / Ten cong thanh toan la bat buoc")
.MaximumLength(50)
.WithMessage("Gateway name must not exceed 50 characters / Ten cong thanh toan khong vuot qua 50 ky tu");
RuleFor(x => x.ReturnUrl)
.NotEmpty()
.WithMessage("Return URL is required / URL tra ve la bat buoc")
.Must(url => Uri.TryCreate(url, UriKind.Absolute, out _))
.WithMessage("Return URL must be a valid URL / URL tra ve phai hop le");
RuleFor(x => x.IpAddress)
.NotEmpty()
.WithMessage("IP address is required / Dia chi IP la bat buoc");
}
}
/// <summary>
/// EN: Validator for ProcessPaymentCallbackCommand.
/// VI: Validator cho ProcessPaymentCallbackCommand.
/// </summary>
public class ProcessPaymentCallbackCommandValidator : AbstractValidator<ProcessPaymentCallbackCommand>
{
public ProcessPaymentCallbackCommandValidator()
{
RuleFor(x => x.GatewayName)
.NotEmpty()
.WithMessage("Gateway name is required / Ten cong thanh toan la bat buoc");
RuleFor(x => x.Parameters)
.NotNull()
.WithMessage("Callback parameters are required / Cac tham so callback la bat buoc")
.Must(p => p.Count > 0)
.WithMessage("Callback parameters cannot be empty / Cac tham so callback khong duoc trong");
}
}