8.6 KiB
8.6 KiB
Wallet Service .NET
Wallet and Point Account management service for GoodGo Platform.
Overview
The Wallet Service provides comprehensive wallet and loyalty points management with:
- Wallet Management - Create, deposit, withdraw, transfer funds
- Escrow Module - Hold, commit, and release funds (for Promotion Service)
- Point Account - Earn, spend, and track loyalty points
- Transaction History - Full audit trail of all transactions
- Multi-Currency Support - VND, USD, PPoint with exchange capabilities
- Currency Exchange - Convert between currencies with configurable rates
- Admin Backoffice - Full admin APIs for wallet/points management
- Domain-Driven Design - Clean Architecture with CQRS pattern
Tech Stack
| Component | Technology |
|---|---|
| Framework | .NET 10 |
| Database | PostgreSQL (EF Core) |
| CQRS | MediatR |
| Validation | FluentValidation |
| API Docs | Swagger/OpenAPI |
| Logging | Serilog |
Prerequisites
# Check .NET version
dotnet --version # Should be 10.0.x
Quick Start
1. Configure Environment
cp .env.example .env
# Edit .env with your database connection
2. Run with Docker
cd deployments/local
docker-compose up wallet-service -d
3. Run Locally
cd services/wallet-service-net
dotnet restore
dotnet build
dotnet run --project src/WalletService.API
API Endpoints
Wallet APIs
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/v1/wallets |
Create new wallet |
GET |
/api/v1/wallets/{userId} |
Get wallet by user ID |
POST |
/api/v1/wallets/{userId}/deposit |
Deposit funds |
POST |
/api/v1/wallets/{userId}/withdraw |
Withdraw funds |
GET |
/api/v1/wallets/{userId}/transactions |
Get transaction history |
Escrow/Hold APIs
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/v1/wallets/{walletId}/holds |
Create escrow hold |
GET |
/api/v1/wallets/{walletId}/holds/{holdId} |
Get hold details |
POST |
/api/v1/wallets/{walletId}/holds/{holdId}/execute |
Execute hold (deduct funds) |
POST |
/api/v1/wallets/{walletId}/holds/{holdId}/release |
Release hold (return funds) |
POST |
/api/v1/wallets/{walletId}/holds/{holdId}/cancel |
Cancel hold |
Points APIs
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/v1/points |
Create point account |
GET |
/api/v1/points/{userId} |
Get point account |
POST |
/api/v1/points/{userId}/earn |
Earn points |
POST |
/api/v1/points/{userId}/spend |
Spend points |
GET |
/api/v1/points/{userId}/transactions |
Get point transactions |
Admin Wallet APIs
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/v1/admin/wallets |
Get all wallets (paginated) |
GET |
/api/v1/admin/wallets/{walletId} |
Get wallet details |
POST |
/api/v1/admin/wallets/{walletId}/freeze |
Freeze wallet |
POST |
/api/v1/admin/wallets/{walletId}/unfreeze |
Unfreeze wallet |
POST |
/api/v1/admin/wallets/{walletId}/adjust |
Adjust balance |
GET |
/api/v1/admin/wallets/statistics |
Get wallet statistics |
GET |
/api/v1/admin/wallets/search |
Search wallets |
Admin Points APIs
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/v1/admin/points |
Get all point accounts |
GET |
/api/v1/admin/points/{accountId} |
Get point account details |
POST |
/api/v1/admin/points/{accountId}/adjust |
Adjust points |
POST |
/api/v1/admin/points/{accountId}/bonus |
Grant bonus points |
GET |
/api/v1/admin/points/statistics |
Get points statistics |
GET |
/api/v1/admin/points/search |
Search point accounts |
Health Endpoints
| Endpoint | Purpose |
|---|---|
/health |
Full health status |
/health/live |
Liveness probe (K8s) |
/health/ready |
Readiness probe (K8s) |
Multi-Currency Support
Wallet supports multiple currency types with exchange capabilities:
| Currency | Code | Base Rate to VND |
|---|---|---|
| Vietnamese Dong | VND |
1 |
| US Dollar | USD |
25,000 |
| Loyalty Points | PPoint |
1,000 |
Currency Exchange
// Exchange USD to VND
wallet.Exchange(
fromAmount: 100m,
fromCurrency: CurrencyType.USD,
toCurrency: CurrencyType.VND
); // Returns 2,500,000 VND
// Exchange PPoints to VND
wallet.Exchange(
fromAmount: 50m,
fromCurrency: CurrencyType.PPoint,
toCurrency: CurrencyType.VND
); // Returns 50,000 VND
Project Structure
wallet-service-net/
├── src/
│ ├── WalletService.API/ # API Layer
│ │ ├── Controllers/ # REST endpoints
│ │ │ └── Admin/ # Admin endpoints
│ │ └── Application/ # Commands & Queries
│ │ ├── Commands/ # Write operations
│ │ └── Queries/ # Read operations
│ │
│ ├── WalletService.Domain/ # Domain Layer
│ │ ├── AggregatesModel/
│ │ │ ├── WalletAggregate/ # Wallet, HoldItem, CurrencyType
│ │ │ └── PointAccountAggregate/ # Points, PointTransaction
│ │ ├── Events/ # Domain events
│ │ └── Exceptions/ # Domain exceptions
│ │
│ └── WalletService.Infrastructure/ # Infrastructure Layer
│ ├── EntityConfigurations/ # EF Core mappings
│ ├── Repositories/ # Data access
│ └── WalletServiceContext.cs # DbContext
│
├── tests/
│ ├── WalletService.UnitTests/ # Domain & Logic tests
│ └── WalletService.FunctionalTests/ # API integration tests
│
├── docs/
│ ├── en/ # English docs
│ └── vi/ # Vietnamese docs
│
└── Dockerfile
Domain Model
Wallet Aggregate
// Create wallet
var wallet = new Wallet(userId, CurrencyType.VND);
// Deposit funds
wallet.Deposit(1000000m, CurrencyType.VND, "Salary", "REF001");
// Withdraw funds
wallet.Withdraw(500000m, CurrencyType.VND, "Shopping", "REF002");
// Freeze/Unfreeze
wallet.Freeze();
wallet.Unfreeze();
// Escrow operations
var hold = wallet.Hold(100000m, CurrencyType.VND, "CAMPAIGN", campaignId, "Hold for campaign");
wallet.ExecuteHold(hold.Id, 50000m, "ORDER123"); // Commit 50k
wallet.ReleaseHold(hold.Id, 50000m); // Return 50k
wallet.CancelHold(hold.Id); // Cancel remaining
// Currency exchange
wallet.Exchange(100m, CurrencyType.USD, CurrencyType.VND);
Point Account Aggregate
// Create account
var account = new PointAccount(userId);
// Earn points
account.EarnPoints(100, "ORDER001", "Purchase reward", expiresAt);
// Spend points
account.SpendPoints(50, "ORDER002", "Redeem discount");
// Adjust points (admin)
account.AdjustPoints(10, "ADMIN", "Bonus adjustment");
Testing
# Run all tests
dotnet test
# Run with coverage
dotnet test /p:CollectCoverage=true
# Unit tests only
dotnet test tests/WalletService.UnitTests
# Functional tests only
dotnet test tests/WalletService.FunctionalTests
Test Results
- 23 tests total
- 20 unit tests (Wallet, PointAccount domain)
- 3 functional tests (Health endpoints)
Configuration
Environment Variables
| Variable | Description | Required |
|---|---|---|
DATABASE_URL |
PostgreSQL connection | Yes |
ASPNETCORE_ENVIRONMENT |
Environment | No (default: Development) |
JWT_AUTHORITY |
JWT issuer URL | Yes (for auth) |
appsettings.json
{
"ConnectionStrings": {
"DefaultConnection": "Host=localhost;Database=wallet_db;Username=postgres;Password=postgres"
},
"Jwt": {
"Authority": "http://localhost:5001",
"Issuer": "http://localhost:5001"
}
}
Database Migrations
# Create migration
dotnet ef migrations add InitialCreate \
--project src/WalletService.Infrastructure \
--startup-project src/WalletService.API
# Apply migration
dotnet ef database update \
--project src/WalletService.Infrastructure \
--startup-project src/WalletService.API
Deployment
Docker Build
docker build -t goodgo/wallet-service:latest .
Docker Compose
Service is registered in deployments/local/docker-compose.yml with Traefik routing.
Resources
License
Proprietary - GoodGo Platform