Skip to content

Tích hợp T-VAN

Tích hợp T-VAN (Mạng giá trị gia tăng về thuế) cung cấp kết nối trực tiếp đến Cơ quan Thuế Việt Nam (CQT) để tra cứu thông tin thuế và tuân thủ việc gửi hóa đơn.

Tổng quan

Thuộc tínhGiá trị
Gói@nx/t-van
Trạng tháiProduction
Mục đíchTích hợp CQT trực tiếp để tuân thủ thuế
Tính năngTra cứu thông tin thuế, Xác thực hóa đơn

Tính năng Chính

  • Tra cứu thông tin thuế - Truy vấn chi tiết đăng ký thuế doanh nghiệp
  • Xác thực hóa đơn - Xác minh tính xác thực của hóa đơn với CQT
  • Hỗ trợ đa nhà cung cấp - Kết nối với nhiều nhà cung cấp T-VAN khác nhau
  • Sẵn sàng tuân thủ - Đáp ứng các yêu cầu của Nghị định 123/2020 và 70/2025

Bắt đầu Nhanh

1. Cấu hình ứng dụng của bạn

typescript
// application.ts
import { NxTVanComponent, TVanBindingKeys, ITVanOptions } from '@nx/t-van';

class MyApplication extends BaseApplication {
  preConfigure() {
    // Cấu hình các client T-VAN
    this.bind<ITVanOptions>({ key: TVanBindingKeys.TVAN_CLIENT_OPTIONS })
      .toValue({
        enableControllers: true,
        clients: [
          {
            name: 'default',
            provider: 'VIETTEL',
            apiKey: process.env.TVAN_API_KEY,
            secretKey: process.env.TVAN_SECRET_KEY,
            taxCode: process.env.COMPANY_TAX_CODE,
            isProduction: process.env.NODE_ENV === 'production',
          },
        ],
      });

    // Tải thành phần T-VAN
    this.component(NxTVanComponent);
  }
}

2. Thiết lập biến môi trường

bash
# Cấu hình T-VAN
APP_ENV_TVAN_API_KEY=your-api-key
APP_ENV_TVAN_SECRET_KEY=your-secret-key
APP_ENV_TVAN_TAX_CODE=0123456789
APP_ENV_TVAN_PROVIDER=VIETTEL
APP_ENV_TVAN_IS_PRODUCTION=false

Kiến trúc

Cấu trúc Thành phần

🧩
NxTVanComponent
Thành phần tích hợp Thuế VAN
🔗
Custom Bindings
🏭TVanClientProviderFactory client
📚TVanClientRegistryRegistry đa client
⚙️
Dịch vụ
🏛️TVanServiceCác thao tác T-VAN cốt lõi
🌐
Controllers
📄TVanInvoiceControllerCác điểm cuối liên quan hóa đơn
🔍TVanTaxInfoControllerCác điểm cuối tra cứu thông tin thuế

Luồng Tích hợp

📱
BANA
Ứng dụng
Gọi API
🔌
T-VAN
Nhà cung cấp
Chuyển tiếp
🏛️
CQT
Cơ quan Thuế
1Ứng dụng gửi Yêu cầu Thông tin Thuế đến Nhà cung cấp T-VAN
2T-VAN chuyển tiếp yêu cầu đến CQT (Cơ quan Thuế)
3CQT trả về phản hồi cho Nhà cung cấp T-VAN
4T-VAN trả về kết quả đã xử lý cho Ứng dụng

Tham khảo API

Tra cứu Thông tin Thuế

Truy vấn chi tiết đăng ký kinh doanh từ CQT:

typescript
import { inject } from '@venizia/ignis';
import { TVanService } from '@nx/t-van';

class TaxController {
  constructor(
    @inject({ key: 'services.TVanService' })
    private tvanService: TVanService,
  ) {}

  async lookupTaxInfo(taxCode: string) {
    const result = await this.tvanService.getTaxInfo({
      taxCode: taxCode,
    });

    return {
      taxCode: result.taxCode,
      companyName: result.companyName,
      address: result.address,
      representative: result.representative,
      status: result.status, // ACTIVE, SUSPENDED, CLOSED
      registrationDate: result.registrationDate,
    };
  }
}

Ví dụ Phản hồi:

json
{
  "taxCode": "0123456789",
  "companyName": "CÔNG TY TNHH ABC",
  "address": "123 Nguyễn Huệ, Quận 1, TP.HCM",
  "representative": "Nguyễn Văn A",
  "status": "ACTIVE",
  "registrationDate": "2020-01-15",
  "businessType": "Bán lẻ",
  "phoneNumber": "028-1234-5678"
}

Xác thực Hóa đơn

Xác minh hóa đơn tồn tại và hợp lệ với CQT:

typescript
async validateInvoice(invoiceNumber: string, sellerTaxCode: string) {
  const result = await this.tvanService.validateInvoice({
    invoiceNumber: invoiceNumber,
    sellerTaxCode: sellerTaxCode,
    invoiceDate: new Date('2024-01-15'),
  });

  return {
    isValid: result.isValid,
    invoiceStatus: result.status, // VALID, CANCELLED, REPLACED
    totalAmount: result.totalAmount,
    buyerTaxCode: result.buyerTaxCode,
  };
}

Tra cứu Thông tin Thuế Hàng loạt

Truy vấn nhiều doanh nghiệp cùng lúc:

typescript
async batchLookup(taxCodes: string[]) {
  const results = await this.tvanService.batchGetTaxInfo({
    taxCodes: taxCodes,
  });

  return results.map(r => ({
    taxCode: r.taxCode,
    companyName: r.companyName,
    status: r.status,
    found: r.found,
  }));
}

Các Điểm cuối REST API

Khi enableControllers: true, các điểm cuối sau sẽ khả dụng:

Điểm cuối Thông tin Thuế

http
# Lấy thông tin thuế theo mã số thuế
GET /api/t-van/tax-info/:taxCode

# Tra cứu hàng loạt
POST /api/t-van/tax-info/batch
Content-Type: application/json

{
  "taxCodes": ["0123456789", "9876543210"]
}

Điểm cuối Hóa đơn

http
# Xác thực hóa đơn
POST /api/t-van/invoice/validate
Content-Type: application/json

{
  "invoiceNumber": "AA/24E0001234",
  "sellerTaxCode": "0123456789",
  "invoiceDate": "2024-01-15"
}

Cấu hình Đa Client

Hỗ trợ nhiều nhà cung cấp T-VAN hoặc tài khoản:

typescript
this.bind<ITVanOptions>({ key: TVanBindingKeys.TVAN_CLIENT_OPTIONS })
  .toValue({
    enableControllers: true,
    clients: [
      // Nhà cung cấp chính
      {
        name: 'primary',
        provider: 'VIETTEL',
        apiKey: process.env.VIETTEL_API_KEY,
        isDefault: true,
      },
      // Nhà cung cấp dự phòng
      {
        name: 'backup',
        provider: 'VNPT',
        apiKey: process.env.VNPT_API_KEY,
      },
    ],
  });

Sử dụng Client Cụ thể

typescript
// Sử dụng client mặc định
const info = await this.tvanService.getTaxInfo({ taxCode });

// Sử dụng client cụ thể
const info = await this.tvanService.getTaxInfo({ taxCode }, {
  clientName: 'backup',
});

Tham khảo Trạng thái Thuế

Trạng thái Doanh nghiệp

Trạng tháiMô tảCó thể Xuất Hóa đơn
ACTIVEHoạt động bình thường
SUSPENDEDTạm ngừng hoạt độngKhông
CLOSEDĐã giải thểKhông
PENDINGĐang chờ đăng kýKhông

Trạng thái Hóa đơn

Trạng tháiMô tả
VALIDHóa đơn hợp lệ và được chấp nhận
CANCELLEDHóa đơn đã bị hủy
REPLACEDHóa đơn đã bị thay thế bởi hóa đơn khác
NOT_FOUNDKhông tìm thấy hóa đơn trong CQT

Xử lý Lỗi

Các Lỗi Thường gặp

Mã lỗiMô tảGiải pháp
TVAN_001Định dạng mã số thuế không hợp lệMã số thuế phải có 10 hoặc 13 chữ số
TVAN_002Không tìm thấy mã số thuếXác minh mã số thuế tồn tại
TVAN_003Kết nối quá hạnThử lại hoặc kiểm tra mạng
TVAN_004Lỗi nhà cung cấpKiểm tra trạng thái nhà cung cấp
TVAN_005Vượt quá giới hạn tốc độChờ và thử lại

Ví dụ Xử lý Lỗi

typescript
try {
  const info = await this.tvanService.getTaxInfo({ taxCode });
  return info;
} catch (error) {
  if (error.code === 'TVAN_002') {
    return { found: false, message: 'Mã số thuế chưa đăng ký' };
  }
  throw error;
}

Tuân thủ Thuế Việt Nam

Khi nào Sử dụng T-VAN

Trường hợp Sử dụngTính năng T-VAN
Xác minh mã số thuế khách hàngTra cứu thông tin thuế
Xác thực hóa đơn nhà cung cấpXác thực hóa đơn
Kiểm tra tính hợp pháp của doanh nghiệpTra cứu thông tin thuế
Xác minh trước hóa đơnTra cứu thông tin thuế

Yêu cầu Tuân thủ

Yêu cầuT-VAN Hỗ trợ
Xác minh mã số thuế người mua trước khi xuất hóa đơn B2BTra cứu thông tin thuế
Xác thực hóa đơn nhận đượcXác thực hóa đơn
Kiểm tra trạng thái nhà cung cấpTra cứu thông tin thuế

Các Thực hành Tốt nhất

Caching Thông tin Thuế

typescript
// Thông tin thuế không thay đổi thường xuyên - hãy cache nó
const CACHE_TTL = 24 * 60 * 60 * 1000; // 24 giờ

async getTaxInfoCached(taxCode: string) {
  const cached = await this.cache.get(`tax:${taxCode}`);
  if (cached) return cached;

  const info = await this.tvanService.getTaxInfo({ taxCode });
  await this.cache.set(`tax:${taxCode}`, info, CACHE_TTL);

  return info;
}

Thao tác Hàng loạt

typescript
// Hiệu quả hơn so với tra cứu riêng lẻ
const taxCodes = orders.map(o => o.customerTaxCode).filter(Boolean);
const uniqueTaxCodes = [...new Set(taxCodes)];

const taxInfoMap = await this.tvanService.batchGetTaxInfo({
  taxCodes: uniqueTaxCodes,
});

Liên quan

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