Skip to content

Hệ thống Thuế

1. Tổng quan

Hệ thống thuế quản lý tính toán thuế cho biến thể sản phẩm thông qua TaxSets (bộ chứa cho mỗi biến thể), Taxes (các mục thuế riêng lẻ với phần trăm hoặc số tiền cố định), và TaxTypes (danh mục thuế phạm vi hệ thống hoặc merchant như VAT, GST). Thuế được áp dụng theo thứ tự ưu tiên, hỗ trợ cửa sổ thời gian, và cung cấp các tính năng nâng cao bao gồm tính thuế inclusive/exclusive, thuế compound (thuế trên thuế), điều kiện theo số lượng, và thuế cấp đơn hàng cho TaxSet của merchant.

Source: src/services/core/pricing-tax-calculator.service.ts, src/services/management/tax.service.tsControllers: src/controllers/tax.controller.ts, tax-set.controller.ts, tax-type.controller.tsRoutes: /taxes, /tax-sets, /tax-types

2. Mô hình Dữ liệu

2.1. Chế độ Thuế

Chế độpercentageamountCách tính
Phần trămset (vd: 0.1)nulltax = taxableAmount × percentage
Cố địnhnullset (vd: 5000)tax = amount
Kết hợpsetsettax = (taxableAmount × percentage) + amount

2.2. Phạm vi TaxType

Phạm vimerchantIdMô tả
Hệ thốngnullLoại thuế toàn nền tảng (VAT, GST) — từ dữ liệu khởi tạo
MerchantsetLoại thuế tùy chỉnh do merchant cụ thể tạo

2.3. Thuế Inclusive vs Exclusive

LoạiisInclusiveHành vi
Exclusivefalse (mặc định)Thuế cộng thêm vào giá — làm tăng tổng tiền
InclusivetrueThuế đã tích hợp trong giá — tính ngược, không làm tăng tổng tiền

Công thức tính ngược cho thuế inclusive:

Chế độCông thức
Phần trămtaxAmount = price − (price / (1 + rate))
Số tiền cố địnhtaxAmount = fixedAmount (khấu trừ từ giá, không cộng thêm)

Lưu ý: Thuế inclusive chỉ áp dụng ở phạm vi ITEM.

2.4. Phạm vi Thuế (Tax Scope)

Mỗi thuế có trường scope kiểm soát nơi thuế được áp dụng:

ScopeÁp dụng trênCho phép trên
ITEM (mặc định)Subtotal của từng biến thể sản phẩmBất kỳ TaxSet nào
ORDERTổng subtotal đơn hàng sau khi tính xong tất cả itemChỉ TaxSet của Merchant

Ràng buộc: Thuế phạm vi ORDER bắt buộc phải là exclusive (isInclusive = false). Hệ thống sẽ ném lỗi validation nếu vi phạm quy tắc này.

2.5. Các Cờ Hành vi Thuế

TrườngKiểuMặc địnhMô tả
isInclusivebooleanfalseThuế tích hợp trong giá (inclusive) hay cộng thêm vào (exclusive)
isCompoundbooleantrueThuế compound trên tích lũy thuế từ các nhóm ưu tiên trước
shouldApplyOnDiscountedbooleantrueDùng subtotal sau giảm giá làm cơ sở (true) hay subtotal gốc (false)
scopeITEM | ORDERITEMÁp dụng ở cấp item hay cấp đơn hàng
minQuantityinteger?nullBỏ qua thuế nếu số lượng item nhỏ hơn ngưỡng này
maxQuantityinteger?nullBỏ qua thuế nếu số lượng item vượt quá ngưỡng này

2.6. Điều kiện Dựa trên Số lượng

Thuế có thể được bỏ qua có điều kiện dựa trên số lượng đơn hàng:

Điều kiệnKết quả
minQuantity được đặt và quantity < minQuantityThuế bị bỏ qua
maxQuantity được đặt và quantity > maxQuantityThuế bị bỏ qua
Không đặt cả haiThuế luôn được áp dụng

3. Luồng Tính Thuế

3.1. Kết quả Tính toán

typescript
interface TaxCalculationResult {
  taxSetId: string;
  totalTax: string;                // Tổng các thuế exclusive đã áp dụng
  appliedTaxes: AppliedTaxResponse[];
}

interface AppliedTaxResponse {
  taxId: string;
  amount: string;                  // Số tiền thuế riêng lẻ
  taxableBase: string;             // Số tiền cơ sở dùng để tính
  taxTypeId: string;
  isInclusive: boolean;            // Thuế có phải inclusive không
  isVat: boolean;                  // true nếu taxType.type === 'VAT'
  isCompound: boolean;             // Thuế có compound trên các nhóm trước không
}

3.2. Thuế Cấp Đơn hàng (Order-Level Taxes)

Sau khi tính xong tất cả thuế cấp item, hệ thống áp dụng thuế cấp đơn hàng khi merchantId được cung cấp trong context:

Cấu trúc OrderTaxesResponse:

typescript
interface OrderTaxesResponse {
  totalOrderTax: string;
  totalExclusiveOrderTax: string;
  totalInclusiveOrderTax: string;    // Luôn là "0.0000" — thuế ORDER phải exclusive
  appliedOrderTaxes: AppliedTaxResponse[];
}

Lưu ý: totalInclusiveOrderTax luôn là "0.0000" vì thuế phạm vi ORDER bắt buộc phải là exclusive (isInclusive = false).

4. Thiết lập VAT Tự động

Khi một biến thể sản phẩm được tạo, hệ thống thuế tự động tạo TaxSet với VAT mặc định 10%:

5. Thao tác Repository

5.1. TaxRepository

Phương thứcMô tả
findActivated()Tải thuế theo taxSetId, lọc theo effectiveDate, sắp xếp theo priority
findByTaxTypeId()Tìm thuế sử dụng loại thuế cụ thể
findFutureTaxes()Tìm thuế có effectiveFrom trong tương lai
findExpiredTaxes()Tìm thuế có effectiveTo trong quá khứ

5.2. TaxSetRepository

Phương thứcMô tả
findActivated()Tìm TaxSet đang kích hoạt cho biến thể sản phẩm (strict/non-strict)
findActiveTaxSetByPrincipal()Tìm theo principalId + principalType kèm thuế
deactivateAllForPrincipal()Vô hiệu tất cả TaxSet trước khi kích hoạt cái mới

5.3. TaxTypeRepository

Phương thứcMô tả
findSystemTaxTypes()Loại thuế hệ thống (merchantId = null)
findByMerchantId()Loại thuế theo merchant cụ thể
findAvailableTaxTypes()Loại thuế hệ thống + merchant kết hợp

6. API Controller

Phương thứcĐường dẫnMô tả
POST/taxesTạo thuế
GET/taxesDanh sách thuế
GET/taxes/:idLấy thuế theo ID
PUT/taxes/:idCập nhật thuế
DELETE/taxes/:idXóa thuế

Tax Sets (/tax-sets) và Tax Types (/tax-types) có các endpoint CRUD tương tự.


7. Ví dụ Thực tế

7.1. Kịch bản 1: Thuế Phần trăm Đơn giản (VAT)

Quy tắc Kinh doanh: "Áp dụng VAT 10% cho tất cả sản phẩm"

Bước 1: Tạo Tax Set (Tự động khi Tạo Biến thể Sản phẩm)

Khi tạo biến thể sản phẩm, hệ thống tự động tạo:

  • TaxSet với trạng thái ACTIVATED
  • Thuế VAT mặc định với percentage: 0.1 (10%)

Bước 2: Tính Thuế

typescript
// Internal API call from PricingService
const result = await pricingTaxCalculatorService.calculateTax({
  productVariantId: 'pv-001',
  taxableAmount: '100000',  // Giá cơ sở sau giảm giá
  context: {
    traceId: 'trace-001',
    calculatingAt: '2026-02-25T10:00:00Z'
  }
});

Kết quả:

json
{
  "taxSetId": "taxset-001",
  "totalTax": "10000.0000",
  "appliedTaxes": [
    {
      "taxId": "tax-vat-001",
      "amount": "10000.0000"
    }
  ]
}

Tính toán: 100,000 × 0.1 = 10,000


7.2. Kịch bản 2: Thuế Cố định (Phí Dịch vụ)

Quy tắc Kinh doanh: "Thêm phí dịch vụ 5,000đ cho tất cả đơn hàng"

Bước 1: Tạo Thuế Phí Dịch vụ

http
POST /taxes
Content-Type: application/json
Authorization: Bearer <token>

{
  "taxSetId": "taxset-001",
  "taxTypeId": "taxtype-service-fee",
  "amount": "5000",
  "percentage": null,
  "effectiveFrom": "2026-02-01T00:00:00Z",
  "effectiveTo": null,
  "priority": 1,
  "status": "ACTIVATED"
}

Bước 2: Tính Thuế với VAT + Phí Dịch vụ

typescript
const result = await pricingTaxCalculatorService.calculateTax({
  productVariantId: 'pv-001',
  taxableAmount: '100000',
  context: { traceId: 'trace-002' }
});

Kết quả:

json
{
  "taxSetId": "taxset-001",
  "totalTax": "15000.0000",
  "appliedTaxes": [
    {
      "taxId": "tax-vat-001",
      "amount": "10000.0000"
    },
    {
      "taxId": "tax-service-fee-001",
      "amount": "5000.0000"
    }
  ]
}

Tính toán:

  • VAT: 100,000 × 0.1 = 10,000
  • Phí dịch vụ: 5,000 (cố định)
  • Tổng: 10,000 + 5,000 = 15,000

7.3. Kịch bản 3: Thuế Kết hợp (Phần trăm + Cố định)

Quy tắc Kinh doanh: "Áp dụng thuế xa xỉ 8% + phí môi trường 10,000đ trên các sản phẩm cao cấp"

Bước 1: Tạo Thuế Kết hợp

http
POST /taxes
Content-Type: application/json

{
  "taxSetId": "taxset-premium-001",
  "taxTypeId": "taxtype-luxury",
  "percentage": "0.08",
  "amount": "10000",
  "effectiveFrom": "2026-01-01T00:00:00Z",
  "priority": 2,
  "status": "ACTIVATED"
}

Bước 2: Tính Thuế (VAT + Xa xỉ + Môi trường)

typescript
const result = await pricingTaxCalculatorService.calculateTax({
  productVariantId: 'pv-premium-001',
  taxableAmount: '500000',
  context: { traceId: 'trace-003' }
});

Kết quả:

json
{
  "taxSetId": "taxset-premium-001",
  "totalTax": "100000.0000",
  "appliedTaxes": [
    {
      "taxId": "tax-vat-001",
      "amount": "50000.0000"
    },
    {
      "taxId": "tax-luxury-001",
      "amount": "50000.0000"
    }
  ]
}

Tính toán:

  • VAT (priority 0): 500,000 × 0.1 = 50,000
  • Xa xỉ + Môi trường (priority 2): (500,000 × 0.08) + 10,000 = 40,000 + 10,000 = 50,000
  • Tổng: 50,000 + 50,000 = 100,000

7.4. Kịch bản 4: Định giá Tax-Inclusive vs Tax-Exclusive

Quy tắc Kinh doanh: "Hiển thị giá đã bao gồm VAT (tax-inclusive), nhưng tính thuế riêng cho mục đích báo cáo"

Cách tiếp cận Tax-Exclusive (Triển khai hiện tại):

typescript
// 1. Tính giá vé (giá cơ sở)
const fareResult = await pricingFareCalculatorService.selectFare({
  productVariantId: 'pv-001',
  context: { quantity: '1' }
});
// fareResult.selectedFare.amount = '100000'

// 2. Tính thuế trên số tiền giá vé
const taxResult = await pricingTaxCalculatorService.calculateTax({
  productVariantId: 'pv-001',
  taxableAmount: '100000',  // Dùng số tiền giá vé làm cơ sở chịu thuế
  context: { traceId: 'trace-004' }
});
// taxResult.totalTax = '10000'

// 3. Giá cuối cùng
const finalPrice = {
  subtotal: '100000',      // Số tiền trước thuế
  tax: '10000',            // Số tiền thuế
  total: '110000'          // Khách hàng trả số này
};

Cách tiếp cận Tax-Inclusive (Tính ngược):

typescript
// Cho trước: Giá tax-inclusive = 110,000 VND (đã bao gồm VAT 10%)
// Tính: Số tiền thuế và số tiền trước thuế

const taxInclusivePrice = 110000;
const vatRate = 0.1;

// Công thức ngược: preTaxAmount = inclusivePrice / (1 + vatRate)
const preTaxAmount = taxInclusivePrice / (1 + vatRate);
// preTaxAmount = 110,000 / 1.1 = 100,000

const taxAmount = taxInclusivePrice - preTaxAmount;
// taxAmount = 110,000 - 100,000 = 10,000

const breakdown = {
  displayPrice: '110000',   // Giá hiển thị cho khách
  subtotal: '100000',       // Số tiền trước thuế
  tax: '10000',             // Số tiền thuế
  total: '110000'           // Bằng giá hiển thị
};

7.5. Kịch bản 5: Sắp xếp Thuế Theo Ưu tiên

Quy tắc Kinh doanh: "Áp dụng thuế theo thứ tự cụ thể: VAT (priority 0) → Phí dịch vụ (priority 1) → Thuế xa xỉ (priority 2)"

Bước 1: Tạo Thuế với Mức Ưu tiên Khác nhau

http
# VAT (ưu tiên cao nhất)
POST /taxes
{
  "taxSetId": "taxset-001",
  "taxTypeId": "taxtype-vat",
  "percentage": "0.1",
  "priority": 0,
  "status": "ACTIVATED"
}

# Phí dịch vụ (ưu tiên trung bình)
POST /taxes
{
  "taxSetId": "taxset-001",
  "taxTypeId": "taxtype-service",
  "amount": "5000",
  "priority": 1,
  "status": "ACTIVATED"
}

# Thuế xa xỉ (ưu tiên thấp nhất)
POST /taxes
{
  "taxSetId": "taxset-001",
  "taxTypeId": "taxtype-luxury",
  "percentage": "0.05",
  "priority": 2,
  "status": "ACTIVATED"
}

Bước 2: Tính Thuế (Áp dụng Theo Thứ tự Ưu tiên)

typescript
const result = await pricingTaxCalculatorService.calculateTax({
  productVariantId: 'pv-001',
  taxableAmount: '200000',
  context: { traceId: 'trace-005' }
});

Kết quả:

json
{
  "taxSetId": "taxset-001",
  "totalTax": "35000.0000",
  "appliedTaxes": [
    {
      "taxId": "tax-vat-001",
      "amount": "20000.0000"
    },
    {
      "taxId": "tax-service-001",
      "amount": "5000.0000"
    },
    {
      "taxId": "tax-luxury-001",
      "amount": "10000.0000"
    }
  ]
}

Tính toán (theo thứ tự ưu tiên):

  1. VAT (priority 0): 200,000 × 0.1 = 20,000
  2. Phí dịch vụ (priority 1): 5,000 (cố định)
  3. Thuế xa xỉ (priority 2): 200,000 × 0.05 = 10,000
  4. Tổng: 20,000 + 5,000 + 10,000 = 35,000

Lưu ý: Các thuế cùng mức ưu tiên chia sẻ cùng một cơ sở tích lũy. Thuế có isCompound = true sẽ compound trên tổng thuế tích lũy từ tất cả nhóm ưu tiên thấp hơn. Xem Kịch bản 7.10 để có ví dụ đầy đủ.


7.6. Kịch bản 6: Thay đổi Thuế Theo Thời gian (Tăng Thuế VAT)

Quy tắc Kinh doanh: "VAT tăng từ 10% lên 12% bắt đầu từ 1/4/2026"

Bước 1: Cập nhật VAT Hiện tại để Hết hạn

http
PUT /taxes/tax-vat-001
Content-Type: application/json

{
  "effectiveTo": "2026-03-31T23:59:59Z"
}

Bước 2: Tạo VAT Mới với Ngày Hiệu lực Tương lai

http
POST /taxes
Content-Type: application/json

{
  "taxSetId": "taxset-001",
  "taxTypeId": "taxtype-vat",
  "percentage": "0.12",
  "effectiveFrom": "2026-04-01T00:00:00Z",
  "effectiveTo": null,
  "priority": 0,
  "status": "ACTIVATED"
}

Bước 3: Tính Thuế Trước Chuyển đổi (30/3/2026)

typescript
const resultBefore = await pricingTaxCalculatorService.calculateTax({
  productVariantId: 'pv-001',
  taxableAmount: '100000',
  context: {
    traceId: 'trace-006',
    calculatingAt: '2026-03-30T10:00:00Z'
  }
});

Kết quả:

json
{
  "taxSetId": "taxset-001",
  "totalTax": "10000.0000",
  "appliedTaxes": [
    {
      "taxId": "tax-vat-001",
      "amount": "10000.0000"
    }
  ]
}

Tính toán: 100,000 × 0.1 = 10,000 (mức cũ)


Bước 4: Tính Thuế Sau Chuyển đổi (2/4/2026)

typescript
const resultAfter = await pricingTaxCalculatorService.calculateTax({
  productVariantId: 'pv-001',
  taxableAmount: '100000',
  context: {
    traceId: 'trace-007',
    calculatingAt: '2026-04-02T10:00:00Z'
  }
});

Kết quả:

json
{
  "taxSetId": "taxset-001",
  "totalTax": "12000.0000",
  "appliedTaxes": [
    {
      "taxId": "tax-vat-002",
      "amount": "12000.0000"
    }
  ]
}

Tính toán: 100,000 × 0.12 = 12,000 (mức mới)


7.7. Kịch bản 7: Thuế Tùy chỉnh của Merchant

Quy tắc Kinh doanh: "Merchant 'ABC Corp' thêm phí xử lý 2% tùy chỉnh cho sản phẩm của họ"

Bước 1: Tạo Loại Thuế của Merchant

http
POST /tax-types
Content-Type: application/json
Authorization: Bearer <merchant-abc-token>

{
  "type": "HANDLING_FEE",
  "name": "ABC Handling Fee",
  "merchantId": "merchant-abc-001",
  "status": "ACTIVATED"
}

Phản hồi:

json
{
  "id": "taxtype-abc-handling",
  "type": "HANDLING_FEE",
  "merchantId": "merchant-abc-001",
  "status": "ACTIVATED"
}

Bước 2: Thêm Thuế Tùy chỉnh vào Biến thể Sản phẩm

http
POST /taxes
Content-Type: application/json

{
  "taxSetId": "taxset-abc-product-001",
  "taxTypeId": "taxtype-abc-handling",
  "percentage": "0.02",
  "priority": 3,
  "status": "ACTIVATED"
}

Bước 3: Tính Thuế (VAT Hệ thống + Phí Xử lý Merchant)

typescript
const result = await pricingTaxCalculatorService.calculateTax({
  productVariantId: 'pv-abc-001',
  taxableAmount: '150000',
  context: { traceId: 'trace-008' }
});

Kết quả:

json
{
  "taxSetId": "taxset-abc-product-001",
  "totalTax": "18000.0000",
  "appliedTaxes": [
    {
      "taxId": "tax-vat-001",
      "amount": "15000.0000"
    },
    {
      "taxId": "tax-abc-handling-001",
      "amount": "3000.0000"
    }
  ]
}

Tính toán:

  • VAT hệ thống (priority 0): 150,000 × 0.1 = 15,000
  • Phí xử lý Merchant (priority 3): 150,000 × 0.02 = 3,000
  • Tổng: 15,000 + 3,000 = 18,000

7.8. Kịch bản 8: Xử lý Lỗi - Cấu hình Thuế Không hợp lệ

Quy tắc Kinh doanh: "Thuế PHẢI có percentage HOẶC amount (hoặc cả hai)"

Yêu cầu Tạo Thuế Không hợp lệ:

http
POST /taxes
Content-Type: application/json

{
  "taxSetId": "taxset-001",
  "taxTypeId": "taxtype-invalid",
  "percentage": null,
  "amount": null,
  "status": "ACTIVATED"
}

Yêu cầu Tính toán:

typescript
try {
  const result = await pricingTaxCalculatorService.calculateTax({
    productVariantId: 'pv-001',
    taxableAmount: '100000',
    context: { traceId: 'trace-009' }
  });
} catch (error) {
  console.error(error);
}

Phản hồi Lỗi:

json
{
  "statusCode": 500,
  "message": "[PricingTaxCalculatorService][_validateTaxConfiguration] Invalid tax configuration: tax must have either percentage or amount value | Tax ID: tax-invalid-001 | Tax Set ID: taxset-001",
  "details": {
    "taxId": "tax-invalid-001",
    "taxSetId": "taxset-001",
    "percentage": null,
    "amount": null
  }
}

7.9. Kịch bản 9: VAT Inclusive

Quy tắc Kinh doanh: "Sản phẩm có giá 110,000 VND đã bao gồm VAT 10% — trích xuất thuế tích hợp để báo cáo"

Thuế có isInclusive: truepercentage: 0.1. Hệ thống tính ngược thuế tích hợp mà không làm tăng tổng tiền.

Cấu hình thuế:

http
POST /taxes
Content-Type: application/json

{
  "taxSetId": "taxset-inclusive-001",
  "taxTypeId": "taxtype-vat",
  "percentage": "0.1",
  "isInclusive": true,
  "priority": 0,
  "status": "ACTIVATED"
}

Tính thuế trên giá inclusive:

typescript
const result = await pricingTaxCalculatorService.calculateTax({
  productVariantId: 'pv-inclusive-001',
  taxableAmount: '110000',  // Giá hiển thị (đã bao gồm VAT)
  context: { traceId: 'trace-009' }
});

Kết quả:

json
{
  "taxSetId": "taxset-inclusive-001",
  "totalTax": "0.0000",
  "appliedTaxes": [
    {
      "taxId": "tax-vat-inclusive-001",
      "amount": "10000.0000",
      "taxableBase": "110000.0000",
      "isInclusive": true,
      "isVat": true,
      "isCompound": true
    }
  ]
}

Tính toán: 110,000 − (110,000 / (1 + 0.1)) = 110,000 − 100,000 = 10,000

Quan trọng: totalTax0 vì thuế inclusive KHÔNG cộng thêm vào tổng — thuế đã tích hợp trong giá hiển thị. Trường amount trong appliedTaxes chỉ dùng cho mục đích báo cáo/phân tích chi tiết.


7.10. Kịch bản 10: Thuế Compound (Thuế trên Thuế)

Quy tắc Kinh doanh: "Áp dụng VAT 10% (priority 0), sau đó phí dịch vụ 2% trên giá đã gồm VAT (priority 1, compound)"

ThuếPriorityTỷ lệisCompound
VAT010%true
Phí dịch vụ12%true

Cấu hình thuế:

http
# VAT — priority 0
POST /taxes
{
  "taxSetId": "taxset-compound-001",
  "taxTypeId": "taxtype-vat",
  "percentage": "0.1",
  "isCompound": true,
  "priority": 0,
  "status": "ACTIVATED"
}

# Phí dịch vụ — priority 1, compound trên VAT
POST /taxes
{
  "taxSetId": "taxset-compound-001",
  "taxTypeId": "taxtype-service",
  "percentage": "0.02",
  "isCompound": true,
  "priority": 1,
  "status": "ACTIVATED"
}

Tính thuế compound:

typescript
const result = await pricingTaxCalculatorService.calculateTax({
  productVariantId: 'pv-compound-001',
  taxableAmount: '100000',
  context: { traceId: 'trace-010' }
});

Kết quả:

json
{
  "taxSetId": "taxset-compound-001",
  "totalTax": "12200.0000",
  "appliedTaxes": [
    {
      "taxId": "tax-vat-001",
      "amount": "10000.0000",
      "taxableBase": "100000.0000",
      "isInclusive": false,
      "isVat": true,
      "isCompound": true
    },
    {
      "taxId": "tax-service-001",
      "amount": "2200.0000",
      "taxableBase": "110000.0000",
      "isInclusive": false,
      "isVat": false,
      "isCompound": true
    }
  ]
}

Tính toán (thuật toán compound):

  1. Priority 0 — VAT: taxableBase = 100,000 (cơ sở, chưa có tích lũy) → tax = 100,000 × 0.1 = 10,000cumulativeTax = 10,000
  2. Priority 1 — Phí dịch vụ: isCompound = truetaxableBase = 100,000 + 10,000 = 110,000tax = 110,000 × 0.02 = 2,200
  3. Tổng: 10,000 + 2,200 = 12,200

7.11. Kịch bản 11: Thuế Cấp Đơn hàng (Phí Dịch vụ Merchant)

Quy tắc Kinh doanh: "Merchant áp dụng phí dịch vụ nền tảng 1% trên tổng subtotal đơn hàng đầy đủ sau khi tính xong tất cả thuế item"

Merchant có TaxSet với thuế phạm vi ORDER. Sau khi tính xong tất cả item, hệ thống tính khoản phí này trên subtotal đơn hàng.

Cấu hình thuế trong TaxSet của Merchant:

http
POST /taxes
Content-Type: application/json

{
  "taxSetId": "taxset-merchant-order-001",
  "taxTypeId": "taxtype-platform-fee",
  "percentage": "0.01",
  "scope": "ORDER",
  "isInclusive": false,
  "priority": 0,
  "status": "ACTIVATED"
}

Context simulation với merchantId:

typescript
const result = await simulationService.calculate({
  items: [/* ... */],
  context: {
    merchantId: 'merchant-abc-001',   // Kích hoạt tra cứu thuế cấp đơn hàng
    traceId: 'trace-011'
  }
});

Kết quả thuế cấp đơn hàng (SimulationCalculateResponse.orderTaxes):

json
{
  "totalOrderTax": "5000.0000",
  "totalExclusiveOrderTax": "5000.0000",
  "totalInclusiveOrderTax": "0.0000",
  "appliedOrderTaxes": [
    {
      "taxId": "tax-platform-fee-001",
      "amount": "5000.0000",
      "taxableBase": "500000.0000",
      "isInclusive": false,
      "isVat": false,
      "isCompound": true
    }
  ]
}

Tính toán: orderSubtotal (500,000) × 0.01 = 5,000

Lưu ý: totalInclusiveOrderTax luôn là "0.0000" vì thuế phạm vi ORDER bắt buộc phải là exclusive theo thiết kế.


8. Tài liệu Liên quan

Proprietary and Confidential. Unauthorized copying, distribution, or use of this software is strictly prohibited.