Skip to content

IIAPI Integration

IIAPI (Invoice Integration API) is an electronic invoice integration component that connects your application with T-VAN (Tax Value Added Network) providers for Vietnam tax compliance.

Overview

AttributeValue
Package@nx/iiapi
StatusProduction
PurposeE-Invoice management for Vietnam tax compliance
ProvidersMultiple T-VAN providers supported

Key Features

  • Multi-provider support - Connect to various T-VAN providers
  • Full invoice lifecycle - Create, update, delete, and manage invoices
  • Multiple invoice types - VAT, POS, Sale, Ticket, Receipt invoices
  • Webhook support - Receive invoice status updates
  • Tax authority compliance - Ready for CQT (Vietnam Tax Authority) requirements

Quick Start

1. Configure your application

typescript
// application.ts
import { NxIIAPIComponent, IIAPIBindingKeys, IIIAPIOptions } from '@nx/iiapi';

class MyApplication extends BaseApplication {
  preConfigure() {
    // Configure IIAPI clients
    this.bind<IIIAPIOptions>({ key: IIAPIBindingKeys.IIAPI_CLIENT_OPTIONS })
      .toValue({
        enableControllers: true,
        clients: [
          {
            name: 'default',
            provider: 'VIETTEL',
            apiKey: process.env.IIAPI_API_KEY,
            secretKey: process.env.IIAPI_SECRET_KEY,
            taxCode: process.env.COMPANY_TAX_CODE,
            isProduction: process.env.NODE_ENV === 'production',
          },
        ],
      });

    // Load IIAPI component
    this.component(NxIIAPIComponent);
  }
}

2. Set environment variables

bash
# IIAPI Configuration
APP_ENV_IIAPI_API_KEY=your-api-key
APP_ENV_IIAPI_SECRET_KEY=your-secret-key
APP_ENV_IIAPI_TAX_CODE=0123456789
APP_ENV_IIAPI_PROVIDER=VIETTEL
APP_ENV_IIAPI_IS_PRODUCTION=false

Architecture

Component Structure

🧩
NxIIAPIComponent
E-Invoice integration component
🔗
Custom Bindings
🏭IIAPIClientProviderClient factory
📚IIAPIClientRegistryMulti-client registry
⚙️
Services (15)
📄VATInvoiceServiceVAT invoice operations
🏪POSVATInvoiceServicePOS VAT invoices
🛒POSSaleInvoiceServicePOS sale invoices
🎫TicketVATInvoiceServiceTicket VAT invoices
🧾SaleInvoiceServiceSale invoices
📋ReceiptServiceReceipt management
📦InternalDeliveryServiceInternal delivery notes
🔄InvoiceManagementServiceInvoice lifecycle
✏️InvoiceUpdateServiceInvoice updates
🗑️InvoiceDeleteServiceInvoice deletion
📝InvoiceTypeServiceInvoice type management
🔔WebhookServiceWebhook handling
🔐OtpServiceOTP verification
📜PitCertificateServiceDigital certificate
⚠️NotificationErrorServiceError notifications
🌐
Controllers (15)
REST API endpoints matching each service

Invoice Types

📄VAT Invoice
Full tax invoiceB2B transactionsTax deductible
🧾Sale Invoice
No buyer info requiredB2C retailSimplified format
🎫Ticket Invoice
Transport/Event ticketsSpecial formatRegulated layout
🏪POS VAT Invoice
POS generatedReal-time submissionAuto-submit to T-VAN
🛒POS Sale Invoice
POS retailQuick checkoutSimplified format
📋Receipt
Non-tax receiptInternal useReference only

Invoice Lifecycle

Status Definitions

StatusDescriptionActions Available
DRAFTInvoice created, not submittedEdit, Delete, Submit
PENDINGSubmitted to T-VAN, awaiting signatureCancel
SIGNEDDigitally signed by T-VANSend to CQT
SENTSent to Tax AuthorityWait for response
ACCEPTEDCQT accepted the invoiceAdjust, Replace
REJECTEDCQT rejected the invoiceCorrect, Resubmit
CANCELLEDInvoice cancelled-

API Reference

Create VAT Invoice

typescript
import { inject } from '@venizia/ignis';
import { VATInvoiceService } from '@nx/iiapi';

class InvoiceController {
  constructor(
    @inject({ key: 'services.VATInvoiceService' })
    private vatInvoiceService: VATInvoiceService,
  ) {}

  async createInvoice() {
    const invoice = await this.vatInvoiceService.create({
      // Seller information
      seller: {
        taxCode: '0123456789',
        name: 'Your Company Name',
        address: '123 Street, District, City',
      },

      // Buyer information
      buyer: {
        taxCode: '9876543210',
        name: 'Customer Company',
        address: '456 Avenue, District, City',
      },

      // Invoice details
      invoiceDate: new Date(),
      currencyCode: 'VND',
      exchangeRate: 1,

      // Line items
      items: [
        {
          itemName: 'Product A',
          unitName: 'Piece',
          quantity: 10,
          unitPrice: 100000,
          amount: 1000000,
          vatRate: 10,
          vatAmount: 100000,
        },
      ],

      // Totals
      totalAmount: 1000000,
      totalVatAmount: 100000,
      totalPayment: 1100000,
    });

    return invoice;
  }
}

Create POS Invoice

typescript
// Quick POS invoice creation
const posInvoice = await this.posSaleInvoiceService.create({
  // Minimal required fields
  invoiceDate: new Date(),
  items: [
    {
      itemName: 'Coffee',
      quantity: 2,
      unitPrice: 50000,
      amount: 100000,
    },
  ],
  totalAmount: 100000,
  paymentMethod: 'CASH',
});

Submit Invoice to T-VAN

typescript
// Submit draft invoice
const result = await this.invoiceManagementService.submit({
  invoiceId: 'inv-uuid-123',
  clientName: 'default', // Which T-VAN client to use
});

// Result contains signed invoice with:
// - Invoice number (auto-assigned)
// - Digital signature
// - T-VAN reference

Handle Webhook

typescript
// T-VAN sends status updates via webhook
app.post('/api/iiapi/webhook', async (c) => {
  const webhookData = await c.req.json();

  await this.webhookService.process({
    provider: webhookData.provider,
    event: webhookData.event,
    invoiceId: webhookData.invoiceId,
    status: webhookData.status,
    data: webhookData.data,
  });

  return c.json({ received: true });
});

Multi-Client Configuration

IIAPI supports multiple T-VAN clients for different business scenarios:

typescript
this.bind<IIIAPIOptions>({ key: IIAPIBindingKeys.IIAPI_CLIENT_OPTIONS })
  .toValue({
    enableControllers: true,
    clients: [
      // Primary T-VAN provider
      {
        name: 'primary',
        provider: 'VIETTEL',
        taxCode: '0123456789',
        apiKey: process.env.VIETTEL_API_KEY,
        isDefault: true,
      },
      // Backup T-VAN provider
      {
        name: 'backup',
        provider: 'VNPT',
        taxCode: '0123456789',
        apiKey: process.env.VNPT_API_KEY,
      },
      // Different company
      {
        name: 'subsidiary',
        provider: 'VIETTEL',
        taxCode: '9876543210',
        apiKey: process.env.SUBSIDIARY_API_KEY,
      },
    ],
  });

Using Specific Client

typescript
// Use default client
const invoice = await this.vatInvoiceService.create(data);

// Use specific client
const invoice = await this.vatInvoiceService.create(data, {
  clientName: 'subsidiary',
});

Error Handling

Common Errors

Error CodeDescriptionSolution
IIAPI_001Invalid tax code formatCheck tax code (10 or 13 digits)
IIAPI_002Missing required fieldsReview required fields
IIAPI_003T-VAN connection failedCheck API credentials
IIAPI_004Invoice already submittedCannot edit submitted invoice
IIAPI_005CQT rejectionCheck rejection reason, correct data

Retry Strategy

typescript
// Built-in retry for transient failures
const result = await this.invoiceManagementService.submit({
  invoiceId: 'inv-uuid-123',
  options: {
    maxRetries: 3,
    retryDelay: 1000,
  },
});

Vietnam Tax Compliance

Decree 123/2020 Requirements

RequirementIIAPI Support
Real-time invoice submissionYes, via T-VAN
Digital signatureYes, T-VAN signs
Invoice number formatAuto-generated
10-year data retentionYour responsibility
CQT connectionVia T-VAN providers

Decree 70/2025 Updates (Effective Jan 2026)

New RequirementIIAPI Support
Immediate e-invoice at salePOS invoice types
Tax ID on every transactionRequired field
Real-time CQT connectionVia T-VAN

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