diff --git a/services/promotion-service-net/docs/en/ARCHITECTURE.md b/services/promotion-service-net/docs/en/ARCHITECTURE.md
new file mode 100644
index 00000000..2b5f6bcd
--- /dev/null
+++ b/services/promotion-service-net/docs/en/ARCHITECTURE.md
@@ -0,0 +1,383 @@
+# Promotion Service Architecture
+
+## Overview
+
+Promotion Service manages marketing campaigns, Vouchers and Gift Cards for GoodGo Platform.
+
+```
+┌─────────────────────────────────────────────────────────────┐
+│ Promotion Service │
+├─────────────────────────────────────────────────────────────┤
+│ API Layer (Controllers, CQRS) │
+├─────────────────────────────────────────────────────────────┤
+│ Domain Layer (Campaign, Voucher Aggregates) │
+├─────────────────────────────────────────────────────────────┤
+│ Infrastructure Layer (EF Core, Repositories, Events) │
+├─────────────────────────────────────────────────────────────┤
+│ PostgreSQL Database │
+└─────────────────────────────────────────────────────────────┘
+```
+
+## Decoupling Concept
+
+```mermaid
+graph TB
+ subgraph "Voucher Creation"
+ BA["Backing Asset
(What's inside voucher)"] --> V["Voucher"]
+ AM["Acquisition Method
(How user gets it)"] --> V
+ end
+
+ subgraph "Backing Assets"
+ BA1["CURRENCY (VND, USD)"]
+ BA2["POINT (PPoint)"]
+ end
+
+ subgraph "Acquisition Methods"
+ AM1["FREE"]
+ AM2["EXCHANGE_POINTS"]
+ AM3["PURCHASE"]
+ end
+```
+
+## Architecture Patterns
+
+### Domain-Driven Design (DDD)
+
+- **Aggregates**: Campaign, Voucher (nested in Campaign)
+- **Entities**: Voucher, Redemption
+- **Value Objects**: AssetType, AcquisitionType
+- **Domain Events**: CampaignCreated, VoucherClaimed, VoucherRedeemed
+
+### CQRS Pattern
+
+```
+Commands (Write) Queries (Read)
+ │ │
+ ▼ ▼
+CreateCampaignCommand GetCampaignQuery
+ActivateCampaignCommand GetCampaignsQuery
+ClaimVoucherCommand GetVoucherQuery
+ExchangeVoucherCommand GetUserVouchersQuery
+RedeemVoucherCommand ValidateVoucherQuery
+CancelCampaignCommand GetCampaignStatisticsQuery
+```
+
+## Domain Model
+
+### Campaign Aggregate
+
+```mermaid
+classDiagram
+ class Campaign {
+ +Guid Id
+ +Guid MerchantId
+ +string Name
+ +AssetType BackingAssetType
+ +string BackingAssetCode
+ +decimal FaceValue
+ +AcquisitionType AcquisitionType
+ +decimal AcquisitionPrice
+ +Guid EscrowHoldId
+ +int TotalVouchers
+ +int IssuedVouchers
+ +CampaignStatus Status
+ +List~Voucher~ Vouchers
+ +Activate()
+ +Pause()
+ +Cancel()
+ +IssueVoucher(userId)
+ }
+
+ class Voucher {
+ +Guid Id
+ +string Code
+ +Guid? OwnerId
+ +VoucherStatus Status
+ +decimal RemainingValue
+ +DateTime? ClaimedAt
+ +DateTime? RedeemedAt
+ +Claim(userId)
+ +Redeem(amount)
+ +Expire()
+ }
+
+ class Redemption {
+ +Guid Id
+ +Guid VoucherId
+ +Guid? OrderId
+ +decimal AmountUsed
+ +decimal AmountRefunded
+ +DateTime RedeemedAt
+ }
+
+ Campaign "1" --> "*" Voucher
+ Voucher "1" --> "*" Redemption
+```
+
+### Enums
+
+```csharp
+public enum AssetType
+{
+ Currency = 1, // VND, USD
+ Point = 2 // PPoint
+}
+
+public enum AcquisitionType
+{
+ Free = 1, // Free giveaway
+ ExchangePoints = 2, // Exchange points
+ Purchase = 3 // Purchase with money
+}
+
+public enum CampaignStatus
+{
+ Draft = 1,
+ Active = 2,
+ Paused = 3,
+ Completed = 4,
+ Cancelled = 5
+}
+
+public enum VoucherStatus
+{
+ Available = 1,
+ Claimed = 2,
+ PartiallyRedeemed = 3,
+ FullyRedeemed = 4,
+ Expired = 5
+}
+```
+
+## Database Schema
+
+### Tables
+
+| Table | Description |
+|-------|-------------|
+| `campaigns` | Merchant campaigns |
+| `vouchers` | Voucher/gift card codes |
+| `redemptions` | Redemption history |
+
+### Detailed Schema
+
+```sql
+CREATE TABLE campaigns (
+ id UUID PRIMARY KEY,
+ merchant_id UUID NOT NULL,
+ name VARCHAR(255) NOT NULL,
+ backing_asset_type INT NOT NULL,
+ backing_asset_code VARCHAR(10) NOT NULL,
+ face_value DECIMAL(18,2) NOT NULL,
+ acquisition_type INT NOT NULL,
+ acquisition_price DECIMAL(18,2) DEFAULT 0,
+ escrow_hold_id UUID,
+ total_vouchers INT NOT NULL,
+ issued_vouchers INT DEFAULT 0,
+ start_date TIMESTAMP NOT NULL,
+ end_date TIMESTAMP NOT NULL,
+ status INT NOT NULL,
+ created_at TIMESTAMP DEFAULT NOW(),
+ updated_at TIMESTAMP DEFAULT NOW()
+);
+
+CREATE TABLE vouchers (
+ id UUID PRIMARY KEY,
+ campaign_id UUID NOT NULL REFERENCES campaigns(id),
+ code VARCHAR(20) UNIQUE NOT NULL,
+ owner_id UUID,
+ status INT NOT NULL,
+ remaining_value DECIMAL(18,2) NOT NULL,
+ claimed_at TIMESTAMP,
+ redeemed_at TIMESTAMP,
+ expires_at TIMESTAMP,
+ created_at TIMESTAMP DEFAULT NOW()
+);
+
+CREATE TABLE redemptions (
+ id UUID PRIMARY KEY,
+ voucher_id UUID NOT NULL REFERENCES vouchers(id),
+ order_id UUID,
+ amount_used DECIMAL(18,2) NOT NULL,
+ amount_refunded DECIMAL(18,2) DEFAULT 0,
+ redeemed_at TIMESTAMP DEFAULT NOW()
+);
+```
+
+### Key Indexes
+
+- `IX_Campaigns_MerchantId` - Campaigns by merchant
+- `IX_Vouchers_CampaignId` - Vouchers by campaign
+- `IX_Vouchers_Code` - Lookup by code
+- `IX_Vouchers_OwnerId` - Vouchers by user
+
+## Service Integration
+
+### Overall Architecture
+
+```mermaid
+graph TB
+ APP["Mobile/Web App"]
+ PS["Promotion Service"]
+ WS["Wallet Service"]
+ MS["Merchant Service"]
+ MQ["RabbitMQ"]
+
+ APP --> PS
+ PS --> WS
+ PS --> MS
+ PS --> MQ
+ WS --> MQ
+
+ style PS fill:#90EE90
+```
+
+### Wallet Service Integration (Escrow)
+
+```
+Promotion Service ──────► Wallet Service
+ │ │
+ │ Hold/Execute/ │
+ │ Release │
+ ▼ ▼
+ Campaign Escrow Balance
+ Created Locked/Released
+```
+
+**API Calls:**
+
+| Action | Wallet API | Description |
+|--------|------------|-------------|
+| Create Campaign | `POST /holds` | Lock funds in escrow |
+| Redeem Voucher | `POST /holds/{id}/execute` | Deduct from escrow |
+| Refund Surplus | `POST /holds/{id}/release` | Return unused amount |
+| Cancel Campaign | `POST /holds/{id}/release` | Release full escrow |
+
+## Processing Flows
+
+### 1. Create Campaign
+
+```
+1. Merchant → POST /api/v1/campaigns
+2. Validate campaign info
+3. Call Wallet Service: Hold(amount, merchantWallet)
+4. Save Campaign with escrowHoldId
+5. Generate voucher codes
+6. Response → Campaign created
+```
+
+### 2. User Claims Voucher (Free)
+
+```
+1. User → POST /api/v1/vouchers/claim
+2. Validate campaign is active
+3. Check user doesn't have this voucher
+4. Update voucher.ownerId = userId
+5. Response → Voucher code
+```
+
+### 3. User Redeems Voucher
+
+```
+1. Checkout → POST /api/v1/vouchers/redeem
+2. Validate voucher is valid
+3. Calculate: amountUsed = min(faceValue, orderAmount)
+4. Calculate: surplus = faceValue - amountUsed
+5. Call Wallet: Execute(holdId, amountUsed)
+6. If surplus > 0: Call Wallet: Release(holdId, surplus)
+7. Update voucher.status = Redeemed
+8. Save redemption history
+9. Response → Redemption confirmed
+```
+
+## Integration Events
+
+### Outgoing Events
+
+```csharp
+// When campaign is created
+public record CampaignCreatedIntegrationEvent(
+ Guid CampaignId,
+ Guid MerchantId,
+ string AssetCode,
+ decimal TotalEscrow);
+
+// When voucher is redeemed
+public record VoucherRedeemedIntegrationEvent(
+ Guid VoucherId,
+ Guid CampaignId,
+ Guid UserId,
+ Guid? OrderId,
+ decimal AmountUsed,
+ decimal AmountRefunded);
+```
+
+### Incoming Events
+
+```csharp
+// From Wallet Service
+public record EscrowHeldIntegrationEvent(
+ Guid HoldId,
+ Guid WalletId,
+ Guid ReferenceId,
+ decimal Amount);
+
+public record EscrowExecutedIntegrationEvent(
+ Guid HoldId,
+ decimal ExecutedAmount,
+ string ExecutionRef);
+```
+
+## Security
+
+### Authentication
+- JWT Bearer token from IAM Service
+- Merchant context from Merchant Service
+
+### Authorization
+- Merchant can only manage their own campaigns
+- User can only view/use their own vouchers
+- Admin has full access
+
+### Validation
+- FluentValidation for all commands
+- Rate limiting for claim/redeem APIs
+
+## Deployment
+
+### Docker Compose
+
+```yaml
+promotion-service:
+ build:
+ context: ../..
+ dockerfile: services/promotion-service-net/Dockerfile
+ environment:
+ - DATABASE_URL=${PROMOTION_DATABASE_URL}
+ - WALLET_SERVICE_URL=http://wallet-service:5000
+ - RABBITMQ_URL=${RABBITMQ_URL}
+ - JWT_AUTHORITY=${IAM_SERVICE_URL}
+ labels:
+ - traefik.http.routers.promotion.rule=PathPrefix(`/api/v1/campaigns`) || PathPrefix(`/api/v1/vouchers`)
+```
+
+### Health Checks
+
+| Endpoint | Checks |
+|----------|--------|
+| `/health/live` | Service is running |
+| `/health/ready` | Database + RabbitMQ + Wallet Service |
+| `/health` | Full status |
+
+## Monitoring
+
+### Metrics
+- Number of active campaigns
+- Vouchers issued/redeemed per campaign
+- Redemption rate
+- Response times
+
+### Logging
+- Serilog structured logging
+- Correlation IDs for tracing
+- Audit log for financial transactions
diff --git a/services/promotion-service-net/docs/en/README.md b/services/promotion-service-net/docs/en/README.md
new file mode 100644
index 00000000..6ed70baf
--- /dev/null
+++ b/services/promotion-service-net/docs/en/README.md
@@ -0,0 +1,261 @@
+# Promotion Service .NET
+
+> **EN**: Campaign, Voucher and Gift Card management service for GoodGo Platform.
+> **VI**: Dịch vụ quản lý Chiến dịch, Voucher và Gift Card cho GoodGo Platform.
+
+## Overview
+
+Promotion Service manages marketing campaigns with Vouchers and Gift Cards:
+
+- **Campaign Management** - Create and manage campaigns with multiple models
+- **Voucher/Gift Card** - Generate codes, distribute, redeem and expire
+- **Unified Asset Model** - Support both Currency and Point as backing assets
+- **Escrow Integration** - Integrate escrow with Wallet Service
+- **Refund Surplus** - Mechanism to refund unused amount to Merchant
+
+## Tech Stack
+
+| Component | Technology |
+|-----------|------------|
+| Framework | .NET 10 |
+| Database | PostgreSQL (EF Core) |
+| CQRS | MediatR |
+| Validation | FluentValidation |
+| API Docs | Swagger/OpenAPI |
+| Logging | Serilog |
+| Message Bus | RabbitMQ (Events) |
+
+## Requirements
+
+```bash
+# Check .NET version
+dotnet --version # Must be 10.0.x
+```
+
+## Quick Start
+
+### 1. Environment Configuration
+
+```bash
+cp .env.example .env
+# Edit .env with your database connection
+```
+
+### 2. Run with Docker
+
+```bash
+cd deployments/local
+docker-compose up promotion-service -d
+```
+
+### 3. Run Locally
+
+```bash
+cd services/promotion-service-net
+dotnet restore
+dotnet build
+dotnet run --project src/PromotionService.API
+```
+
+## API Endpoints
+
+### Campaign APIs (Merchant)
+
+| Method | Endpoint | Description |
+|--------|----------|-------------|
+| `POST` | `/api/v1/campaigns` | Create new campaign |
+| `GET` | `/api/v1/campaigns` | List merchant's campaigns |
+| `GET` | `/api/v1/campaigns/{id}` | Get campaign details |
+| `PUT` | `/api/v1/campaigns/{id}` | Update campaign |
+| `POST` | `/api/v1/campaigns/{id}/activate` | Activate campaign |
+| `POST` | `/api/v1/campaigns/{id}/pause` | Pause campaign |
+| `POST` | `/api/v1/campaigns/{id}/cancel` | Cancel campaign (refund escrow) |
+
+### Voucher APIs (User)
+
+| Method | Endpoint | Description |
+|--------|----------|-------------|
+| `POST` | `/api/v1/vouchers/claim` | Claim free voucher |
+| `POST` | `/api/v1/vouchers/exchange` | Exchange points for voucher |
+| `POST` | `/api/v1/vouchers/purchase` | Purchase gift card |
+| `GET` | `/api/v1/vouchers/validate/{code}` | Validate voucher code |
+| `POST` | `/api/v1/vouchers/redeem` | Redeem voucher |
+| `GET` | `/api/v1/users/{userId}/vouchers` | Get user's vouchers |
+
+### Admin APIs
+
+| Method | Endpoint | Description |
+|--------|----------|-------------|
+| `GET` | `/api/v1/admin/campaigns` | List all campaigns |
+| `GET` | `/api/v1/admin/campaigns/{id}/statistics` | Campaign statistics |
+| `POST` | `/api/v1/admin/vouchers/{id}/revoke` | Revoke voucher |
+
+### Health Endpoints
+
+| Endpoint | Purpose |
+|----------|---------|
+| `/health` | Full health status |
+| `/health/live` | Liveness probe (K8s) |
+| `/health/ready` | Readiness probe (K8s) |
+
+## Project Structure
+
+```
+promotion-service-net/
+├── src/
+│ ├── PromotionService.API/ # API Layer
+│ │ ├── Controllers/ # REST endpoints
+│ │ └── Application/ # Commands & Queries
+│ │ ├── Commands/ # Write operations
+│ │ ├── Queries/ # Read operations
+│ │ └── IntegrationEvents/ # Event handlers
+│ │
+│ ├── PromotionService.Domain/ # Domain Layer
+│ │ ├── AggregatesModel/
+│ │ │ ├── CampaignAggregate/ # Campaign, Voucher
+│ │ │ └── RedemptionAggregate/ # Redemption history
+│ │ ├── Events/ # Domain events
+│ │ └── Exceptions/ # Domain exceptions
+│ │
+│ └── PromotionService.Infrastructure/ # Infrastructure Layer
+│ ├── EntityConfigurations/ # EF Core mappings
+│ ├── Repositories/ # Data access
+│ └── PromotionContext.cs # DbContext
+│
+├── tests/
+│ ├── PromotionService.UnitTests/ # Domain & Logic tests
+│ └── PromotionService.FunctionalTests/ # API integration tests
+│
+├── docs/
+│ ├── en/ # English documentation
+│ └── vi/ # Vietnamese documentation
+│
+└── Dockerfile
+```
+
+## 4 Marketing Scenarios
+
+### A. Free Cash Voucher
+
+```yaml
+Campaign:
+ backing_asset_type: CURRENCY
+ backing_asset_code: VND
+ face_value: 50000
+ acquisition_type: FREE
+ acquisition_price: 0
+```
+
+### B. Exchange Points for Cash Voucher
+
+```yaml
+Campaign:
+ backing_asset_type: CURRENCY
+ backing_asset_code: VND
+ face_value: 50000
+ acquisition_type: EXCHANGE_POINTS
+ acquisition_price: 500 # 500 points
+```
+
+### C. Purchase Gift Card
+
+```yaml
+Campaign:
+ backing_asset_type: CURRENCY
+ backing_asset_code: VND
+ face_value: 100000
+ acquisition_type: PURCHASE
+ acquisition_price: 100000 # VND
+```
+
+### D. Free Bonus Points Voucher
+
+```yaml
+Campaign:
+ backing_asset_type: POINT
+ backing_asset_code: PPoint
+ face_value: 100 # 100 points
+ acquisition_type: FREE
+ acquisition_price: 0
+```
+
+## Testing
+
+```bash
+# Run all tests
+dotnet test
+
+# Run with coverage
+dotnet test /p:CollectCoverage=true
+
+# Unit tests only
+dotnet test tests/PromotionService.UnitTests
+
+# Functional tests only
+dotnet test tests/PromotionService.FunctionalTests
+```
+
+## Configuration
+
+### Environment Variables
+
+| Variable | Description | Required |
+|----------|-------------|----------|
+| `DATABASE_URL` | PostgreSQL connection | Yes |
+| `WALLET_SERVICE_URL` | Wallet Service URL | Yes |
+| `RABBITMQ_URL` | RabbitMQ connection | Yes |
+| `JWT_AUTHORITY` | JWT issuer URL | Yes |
+
+### appsettings.json
+
+```json
+{
+ "ConnectionStrings": {
+ "DefaultConnection": "Host=localhost;Database=promotion_db;Username=postgres;Password=postgres"
+ },
+ "WalletService": {
+ "BaseUrl": "http://wallet-service:5000"
+ },
+ "RabbitMQ": {
+ "Host": "localhost",
+ "Username": "guest",
+ "Password": "guest"
+ }
+}
+```
+
+## Database Migrations
+
+```bash
+# Create migration
+dotnet ef migrations add InitialCreate \
+ --project src/PromotionService.Infrastructure \
+ --startup-project src/PromotionService.API
+
+# Apply migration
+dotnet ef database update \
+ --project src/PromotionService.Infrastructure \
+ --startup-project src/PromotionService.API
+```
+
+## Deployment
+
+### Docker Build
+
+```bash
+docker build -t goodgo/promotion-service:latest .
+```
+
+### Docker Compose
+
+Service is registered in `deployments/local/docker-compose.yml` with Traefik routing.
+
+## Resources
+
+- [Architecture Documentation](./ARCHITECTURE.md)
+- [Wallet Service](../../../wallet-service-net/docs/en/README.md)
+- [Merchant Service](../../../merchant-service-net/docs/en/README.md)
+
+## License
+
+Proprietary - GoodGo Platform
diff --git a/services/promotion-service-net/docs/vi/ARCHITECTURE.md b/services/promotion-service-net/docs/vi/ARCHITECTURE.md
new file mode 100644
index 00000000..e88f1b84
--- /dev/null
+++ b/services/promotion-service-net/docs/vi/ARCHITECTURE.md
@@ -0,0 +1,384 @@
+# Kiến Trúc Promotion Service
+
+## Tổng Quan
+
+Promotion Service quản lý chiến dịch khuyến mãi, Voucher và Gift Card cho GoodGo Platform.
+
+```
+┌─────────────────────────────────────────────────────────────┐
+│ Promotion Service │
+├─────────────────────────────────────────────────────────────┤
+│ API Layer (Controllers, CQRS) │
+├─────────────────────────────────────────────────────────────┤
+│ Domain Layer (Campaign, Voucher Aggregates) │
+├─────────────────────────────────────────────────────────────┤
+│ Infrastructure Layer (EF Core, Repositories, Events) │
+├─────────────────────────────────────────────────────────────┤
+│ PostgreSQL Database │
+└─────────────────────────────────────────────────────────────┘
+```
+
+## Decoupling Concept
+
+```mermaid
+graph TB
+ subgraph "Voucher Creation"
+ BA["Backing Asset
(Tài sản đảm bảo)"] --> V["Voucher"]
+ AM["Acquisition Method
(Phương thức sở hữu)"] --> V
+ end
+
+ subgraph "Backing Assets"
+ BA1["CURRENCY (VND, USD)"]
+ BA2["POINT (PPoint)"]
+ end
+
+ subgraph "Acquisition Methods"
+ AM1["FREE"]
+ AM2["EXCHANGE_POINTS"]
+ AM3["PURCHASE"]
+ end
+```
+
+## Các Pattern Kiến Trúc
+
+### Domain-Driven Design (DDD)
+
+- **Aggregates**: Campaign, Voucher (nested in Campaign)
+- **Entities**: Voucher, Redemption
+- **Value Objects**: AssetType, AcquisitionType
+- **Domain Events**: CampaignCreated, VoucherClaimed, VoucherRedeemed
+
+### CQRS Pattern
+
+```
+Commands (Ghi) Queries (Đọc)
+ │ │
+ ▼ ▼
+CreateCampaignCommand GetCampaignQuery
+ActivateCampaignCommand GetCampaignsQuery
+ClaimVoucherCommand GetVoucherQuery
+ExchangeVoucherCommand GetUserVouchersQuery
+RedeemVoucherCommand ValidateVoucherQuery
+CancelCampaignCommand GetCampaignStatisticsQuery
+```
+
+## Domain Model
+
+### Campaign Aggregate
+
+```mermaid
+classDiagram
+ class Campaign {
+ +Guid Id
+ +Guid MerchantId
+ +string Name
+ +AssetType BackingAssetType
+ +string BackingAssetCode
+ +decimal FaceValue
+ +AcquisitionType AcquisitionType
+ +decimal AcquisitionPrice
+ +Guid EscrowHoldId
+ +int TotalVouchers
+ +int IssuedVouchers
+ +CampaignStatus Status
+ +List~Voucher~ Vouchers
+ +Activate()
+ +Pause()
+ +Cancel()
+ +IssueVoucher(userId)
+ }
+
+ class Voucher {
+ +Guid Id
+ +string Code
+ +Guid? OwnerId
+ +VoucherStatus Status
+ +decimal RemainingValue
+ +DateTime? ClaimedAt
+ +DateTime? RedeemedAt
+ +Claim(userId)
+ +Redeem(amount)
+ +Expire()
+ }
+
+ class Redemption {
+ +Guid Id
+ +Guid VoucherId
+ +Guid? OrderId
+ +decimal AmountUsed
+ +decimal AmountRefunded
+ +DateTime RedeemedAt
+ }
+
+ Campaign "1" --> "*" Voucher
+ Voucher "1" --> "*" Redemption
+```
+
+### Enums
+
+```csharp
+public enum AssetType
+{
+ Currency = 1, // VND, USD
+ Point = 2 // PPoint
+}
+
+public enum AcquisitionType
+{
+ Free = 1, // Tặng miễn phí
+ ExchangePoints = 2, // Đổi điểm
+ Purchase = 3 // Mua bằng tiền
+}
+
+public enum CampaignStatus
+{
+ Draft = 1,
+ Active = 2,
+ Paused = 3,
+ Completed = 4,
+ Cancelled = 5
+}
+
+public enum VoucherStatus
+{
+ Available = 1,
+ Claimed = 2,
+ PartiallyRedeemed = 3,
+ FullyRedeemed = 4,
+ Expired = 5
+}
+```
+
+## Database Schema
+
+### Các Bảng
+
+| Bảng | Mô Tả |
+|------|-------|
+| `campaigns` | Chiến dịch của Merchant |
+| `vouchers` | Mã voucher/gift card |
+| `redemptions` | Lịch sử sử dụng |
+
+### Schema Chi Tiết
+
+```sql
+CREATE TABLE campaigns (
+ id UUID PRIMARY KEY,
+ merchant_id UUID NOT NULL,
+ name VARCHAR(255) NOT NULL,
+ backing_asset_type INT NOT NULL,
+ backing_asset_code VARCHAR(10) NOT NULL,
+ face_value DECIMAL(18,2) NOT NULL,
+ acquisition_type INT NOT NULL,
+ acquisition_price DECIMAL(18,2) DEFAULT 0,
+ escrow_hold_id UUID,
+ total_vouchers INT NOT NULL,
+ issued_vouchers INT DEFAULT 0,
+ start_date TIMESTAMP NOT NULL,
+ end_date TIMESTAMP NOT NULL,
+ status INT NOT NULL,
+ created_at TIMESTAMP DEFAULT NOW(),
+ updated_at TIMESTAMP DEFAULT NOW()
+);
+
+CREATE TABLE vouchers (
+ id UUID PRIMARY KEY,
+ campaign_id UUID NOT NULL REFERENCES campaigns(id),
+ code VARCHAR(20) UNIQUE NOT NULL,
+ owner_id UUID,
+ status INT NOT NULL,
+ remaining_value DECIMAL(18,2) NOT NULL,
+ claimed_at TIMESTAMP,
+ redeemed_at TIMESTAMP,
+ expires_at TIMESTAMP,
+ created_at TIMESTAMP DEFAULT NOW()
+);
+
+CREATE TABLE redemptions (
+ id UUID PRIMARY KEY,
+ voucher_id UUID NOT NULL REFERENCES vouchers(id),
+ order_id UUID,
+ amount_used DECIMAL(18,2) NOT NULL,
+ amount_refunded DECIMAL(18,2) DEFAULT 0,
+ redeemed_at TIMESTAMP DEFAULT NOW()
+);
+```
+
+### Indexes Chính
+
+- `IX_Campaigns_MerchantId` - Campaigns theo merchant
+- `IX_Vouchers_CampaignId` - Vouchers theo campaign
+- `IX_Vouchers_Code` - Tra cứu theo mã
+- `IX_Vouchers_OwnerId` - Vouchers theo user
+
+## Tích Hợp Giữa Các Service
+
+### Kiến Trúc Tổng Quan
+
+```mermaid
+graph TB
+ APP["Mobile/Web App"]
+ PS["Promotion Service"]
+ WS["Wallet Service"]
+ MS["Merchant Service"]
+ MQ["RabbitMQ"]
+
+ APP --> PS
+ PS --> WS
+ PS --> MS
+ PS --> MQ
+ WS --> MQ
+
+ style PS fill:#90EE90
+```
+
+### Tích Hợp Wallet Service (Escrow)
+
+```
+
+Promotion Service ──────► Wallet Service
+ │ │
+ │ Hold/Execute/ │
+ │ Release │
+ ▼ ▼
+ Campaign Escrow Balance
+ Created Locked/Released
+```
+
+**API Calls:**
+
+| Action | Wallet API | Mô Tả |
+|--------|------------|-------|
+| Tạo Campaign | `POST /holds` | Lock tiền/điểm vào escrow |
+| Sử dụng Voucher | `POST /holds/{id}/execute` | Trừ tiền từ escrow |
+| Hoàn dư | `POST /holds/{id}/release` | Trả lại tiền dư |
+| Hủy Campaign | `POST /holds/{id}/release` | Hoàn toàn bộ escrow |
+
+## Luồng Xử Lý
+
+### 1. Tạo Campaign
+
+```
+1. Merchant → POST /api/v1/campaigns
+2. Validate thông tin campaign
+3. Gọi Wallet Service: Hold(amount, merchantWallet)
+4. Lưu Campaign với escrowHoldId
+5. Sinh voucher codes
+6. Response → Campaign created
+```
+
+### 2. User Lấy Voucher (Free)
+
+```
+1. User → POST /api/v1/vouchers/claim
+2. Validate campaign đang active
+3. Kiểm tra user chưa có voucher này
+4. Cập nhật voucher.ownerId = userId
+5. Response → Voucher code
+```
+
+### 3. User Sử Dụng Voucher
+
+```
+1. Checkout → POST /api/v1/vouchers/redeem
+2. Validate voucher còn hiệu lực
+3. Tính toán: amountUsed = min(faceValue, orderAmount)
+4. Tính toán: surplus = faceValue - amountUsed
+5. Gọi Wallet: Execute(holdId, amountUsed)
+6. Nếu surplus > 0: Gọi Wallet: Release(holdId, surplus)
+7. Cập nhật voucher.status = Redeemed
+8. Lưu redemption history
+9. Response → Redemption confirmed
+```
+
+## Integration Events
+
+### Outgoing Events
+
+```csharp
+// Khi campaign được tạo
+public record CampaignCreatedIntegrationEvent(
+ Guid CampaignId,
+ Guid MerchantId,
+ string AssetCode,
+ decimal TotalEscrow);
+
+// Khi voucher được sử dụng
+public record VoucherRedeemedIntegrationEvent(
+ Guid VoucherId,
+ Guid CampaignId,
+ Guid UserId,
+ Guid? OrderId,
+ decimal AmountUsed,
+ decimal AmountRefunded);
+```
+
+### Incoming Events
+
+```csharp
+// Từ Wallet Service
+public record EscrowHeldIntegrationEvent(
+ Guid HoldId,
+ Guid WalletId,
+ Guid ReferenceId,
+ decimal Amount);
+
+public record EscrowExecutedIntegrationEvent(
+ Guid HoldId,
+ decimal ExecutedAmount,
+ string ExecutionRef);
+```
+
+## Bảo Mật
+
+### Xác Thực
+- JWT Bearer token từ IAM Service
+- Merchant context từ Merchant Service
+
+### Phân Quyền
+- Merchant chỉ quản lý campaigns của mình
+- User chỉ xem/sử dụng vouchers của mình
+- Admin có full access
+
+### Validation
+- FluentValidation cho tất cả commands
+- Rate limiting cho claim/redeem APIs
+
+## Triển Khai
+
+### Docker Compose
+
+```yaml
+promotion-service:
+ build:
+ context: ../..
+ dockerfile: services/promotion-service-net/Dockerfile
+ environment:
+ - DATABASE_URL=${PROMOTION_DATABASE_URL}
+ - WALLET_SERVICE_URL=http://wallet-service:5000
+ - RABBITMQ_URL=${RABBITMQ_URL}
+ - JWT_AUTHORITY=${IAM_SERVICE_URL}
+ labels:
+ - traefik.http.routers.promotion.rule=PathPrefix(`/api/v1/campaigns`) || PathPrefix(`/api/v1/vouchers`)
+```
+
+### Health Checks
+
+| Endpoint | Kiểm Tra |
+|----------|----------|
+| `/health/live` | Service đang chạy |
+| `/health/ready` | Database + RabbitMQ + Wallet Service |
+| `/health` | Trạng thái đầy đủ |
+
+## Giám Sát
+
+### Metrics
+- Số lượng campaigns active
+- Vouchers issued/redeemed per campaign
+- Tỷ lệ redemption
+- Thời gian response
+
+### Logging
+- Serilog structured logging
+- Correlation IDs cho tracing
+- Audit log cho financial transactions
diff --git a/services/promotion-service-net/docs/vi/README.md b/services/promotion-service-net/docs/vi/README.md
new file mode 100644
index 00000000..ff8a090f
--- /dev/null
+++ b/services/promotion-service-net/docs/vi/README.md
@@ -0,0 +1,261 @@
+# Promotion Service .NET
+
+> **EN**: Campaign, Voucher and Gift Card management service for GoodGo Platform.
+> **VI**: Dịch vụ quản lý Chiến dịch, Voucher và Gift Card cho GoodGo Platform.
+
+## Tổng Quan
+
+Promotion Service quản lý chiến dịch khuyến mãi với Voucher và Gift Card:
+
+- **Campaign Management** - Tạo, quản lý chiến dịch theo nhiều mô hình
+- **Voucher/Gift Card** - Sinh mã, phân phối, sử dụng và hết hạn
+- **Unified Asset Model** - Hỗ trợ cả Currency và Point làm tài sản đảm bảo
+- **Escrow Integration** - Tích hợp ký quỹ với Wallet Service
+- **Refund Surplus** - Cơ chế hoàn tiền dư về Merchant
+
+## Tech Stack
+
+| Thành Phần | Công Nghệ |
+|------------|-----------|
+| Framework | .NET 10 |
+| Database | PostgreSQL (EF Core) |
+| CQRS | MediatR |
+| Validation | FluentValidation |
+| API Docs | Swagger/OpenAPI |
+| Logging | Serilog |
+| Message Bus | RabbitMQ (Events) |
+
+## Yêu Cầu Hệ Thống
+
+```bash
+# Kiểm tra phiên bản .NET
+dotnet --version # Phải là 10.0.x
+```
+
+## Bắt Đầu Nhanh
+
+### 1. Cấu Hình Môi Trường
+
+```bash
+cp .env.example .env
+# Chỉnh sửa .env với connection database của bạn
+```
+
+### 2. Chạy với Docker
+
+```bash
+cd deployments/local
+docker-compose up promotion-service -d
+```
+
+### 3. Chạy Local
+
+```bash
+cd services/promotion-service-net
+dotnet restore
+dotnet build
+dotnet run --project src/PromotionService.API
+```
+
+## API Endpoints
+
+### Campaign APIs (Merchant)
+
+| Method | Endpoint | Mô Tả |
+|--------|----------|-------|
+| `POST` | `/api/v1/campaigns` | Tạo chiến dịch mới |
+| `GET` | `/api/v1/campaigns` | Danh sách campaigns của merchant |
+| `GET` | `/api/v1/campaigns/{id}` | Chi tiết campaign |
+| `PUT` | `/api/v1/campaigns/{id}` | Cập nhật campaign |
+| `POST` | `/api/v1/campaigns/{id}/activate` | Kích hoạt campaign |
+| `POST` | `/api/v1/campaigns/{id}/pause` | Tạm dừng campaign |
+| `POST` | `/api/v1/campaigns/{id}/cancel` | Hủy campaign (hoàn escrow) |
+
+### Voucher APIs (User)
+
+| Method | Endpoint | Mô Tả |
+|--------|----------|-------|
+| `POST` | `/api/v1/vouchers/claim` | Nhận voucher miễn phí |
+| `POST` | `/api/v1/vouchers/exchange` | Đổi points lấy voucher |
+| `POST` | `/api/v1/vouchers/purchase` | Mua gift card |
+| `GET` | `/api/v1/vouchers/validate/{code}` | Kiểm tra mã voucher |
+| `POST` | `/api/v1/vouchers/redeem` | Sử dụng voucher |
+| `GET` | `/api/v1/users/{userId}/vouchers` | Vouchers của user |
+
+### Admin APIs
+
+| Method | Endpoint | Mô Tả |
+|--------|----------|-------|
+| `GET` | `/api/v1/admin/campaigns` | Tất cả campaigns |
+| `GET` | `/api/v1/admin/campaigns/{id}/statistics` | Thống kê campaign |
+| `POST` | `/api/v1/admin/vouchers/{id}/revoke` | Thu hồi voucher |
+
+### Health Endpoints
+
+| Endpoint | Mục Đích |
+|----------|----------|
+| `/health` | Trạng thái sức khỏe đầy đủ |
+| `/health/live` | Liveness probe (K8s) |
+| `/health/ready` | Readiness probe (K8s) |
+
+## Cấu Trúc Dự Án
+
+```
+promotion-service-net/
+├── src/
+│ ├── PromotionService.API/ # API Layer
+│ │ ├── Controllers/ # REST endpoints
+│ │ └── Application/ # Commands & Queries
+│ │ ├── Commands/ # Thao tác ghi
+│ │ ├── Queries/ # Thao tác đọc
+│ │ └── IntegrationEvents/ # Event handlers
+│ │
+│ ├── PromotionService.Domain/ # Domain Layer
+│ │ ├── AggregatesModel/
+│ │ │ ├── CampaignAggregate/ # Campaign, Voucher
+│ │ │ └── RedemptionAggregate/ # Redemption history
+│ │ ├── Events/ # Domain events
+│ │ └── Exceptions/ # Domain exceptions
+│ │
+│ └── PromotionService.Infrastructure/ # Infrastructure Layer
+│ ├── EntityConfigurations/ # EF Core mappings
+│ ├── Repositories/ # Data access
+│ └── PromotionContext.cs # DbContext
+│
+├── tests/
+│ ├── PromotionService.UnitTests/ # Domain & Logic tests
+│ └── PromotionService.FunctionalTests/ # API integration tests
+│
+├── docs/
+│ ├── en/ # Tài liệu tiếng Anh
+│ └── vi/ # Tài liệu tiếng Việt
+│
+└── Dockerfile
+```
+
+## 4 Kịch Bản Marketing
+
+### A. Tặng Free Voucher Tiền mặt
+
+```yaml
+Campaign:
+ backing_asset_type: CURRENCY
+ backing_asset_code: VND
+ face_value: 50000
+ acquisition_type: FREE
+ acquisition_price: 0
+```
+
+### B. Đổi Point lấy Voucher Tiền mặt
+
+```yaml
+Campaign:
+ backing_asset_type: CURRENCY
+ backing_asset_code: VND
+ face_value: 50000
+ acquisition_type: EXCHANGE_POINTS
+ acquisition_price: 500 # 500 points
+```
+
+### C. Mua Gift Card bằng Tiền
+
+```yaml
+Campaign:
+ backing_asset_type: CURRENCY
+ backing_asset_code: VND
+ face_value: 100000
+ acquisition_type: PURCHASE
+ acquisition_price: 100000 # VND
+```
+
+### D. Tặng Voucher tích điểm
+
+```yaml
+Campaign:
+ backing_asset_type: POINT
+ backing_asset_code: PPoint
+ face_value: 100 # 100 points
+ acquisition_type: FREE
+ acquisition_price: 0
+```
+
+## Testing
+
+```bash
+# Chạy tất cả tests
+dotnet test
+
+# Chạy với coverage
+dotnet test /p:CollectCoverage=true
+
+# Chỉ unit tests
+dotnet test tests/PromotionService.UnitTests
+
+# Chỉ functional tests
+dotnet test tests/PromotionService.FunctionalTests
+```
+
+## Cấu Hình
+
+### Biến Môi Trường
+
+| Biến | Mô Tả | Bắt Buộc |
+|------|-------|----------|
+| `DATABASE_URL` | Connection PostgreSQL | Có |
+| `WALLET_SERVICE_URL` | URL Wallet Service | Có |
+| `RABBITMQ_URL` | Connection RabbitMQ | Có |
+| `JWT_AUTHORITY` | URL JWT issuer | Có |
+
+### appsettings.json
+
+```json
+{
+ "ConnectionStrings": {
+ "DefaultConnection": "Host=localhost;Database=promotion_db;Username=postgres;Password=postgres"
+ },
+ "WalletService": {
+ "BaseUrl": "http://wallet-service:5000"
+ },
+ "RabbitMQ": {
+ "Host": "localhost",
+ "Username": "guest",
+ "Password": "guest"
+ }
+}
+```
+
+## Database Migrations
+
+```bash
+# Tạo migration
+dotnet ef migrations add InitialCreate \
+ --project src/PromotionService.Infrastructure \
+ --startup-project src/PromotionService.API
+
+# Áp dụng migration
+dotnet ef database update \
+ --project src/PromotionService.Infrastructure \
+ --startup-project src/PromotionService.API
+```
+
+## Triển Khai
+
+### Docker Build
+
+```bash
+docker build -t goodgo/promotion-service:latest .
+```
+
+### Docker Compose
+
+Service được đăng ký trong `deployments/local/docker-compose.yml` với Traefik routing.
+
+## Tài Nguyên
+
+- [Tài liệu Kiến trúc](./ARCHITECTURE.md)
+- [Wallet Service](../../../wallet-service-net/docs/vi/README.md)
+- [Merchant Service](../../../merchant-service-net/docs/vi/README.md)
+
+## Giấy Phép
+
+Proprietary - GoodGo Platform