# @florinszilagyi/anaf-ts-sdk 中文文档

规范地址：https://npmcn.com/package/%40florinszilagyi/anaf-ts-sdk/

版本：2\.0\.6
npm 元数据更新时间：2026-11-13T10:36:55.960Z
中文译文更新时间：2026-11-15T00:01:24.728Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40florinszilagyi/anaf-ts-sdk
原文对照：https://npmcn.com/package/%40florinszilagyi/anaf-ts-sdk/?lang=original
项目主页：https://github.com/florin-szilagyi/ts-anaf#readme
源码仓库：https://github.com/florin-szilagyi/ts-anaf

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：661 kB，119 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- Node.js 要求：\>=20\.0\.0
- 运行依赖：5 个
- 首次发布：2026-04-15T08:25:28.485Z
- 最新版本发布：2026-11-13T10:36:55.627Z
- 近 30 天下载量：6011（2026-10-15 至 2026-11-13，npm 官方下载统计）
- 已发布版本数：16（近 12 个月 16 个）

## 中文简介

Romanian ANAF API - E-Factura, 公司的检查

## 安装

```sh
npm install @florinszilagyi/anaf-ts-sdk
```

也可以使用：`pnpm add @florinszilagyi/anaf-ts-sdk`、`yarn add @florinszilagyi/anaf-ts-sdk`、`bun add @florinszilagyi/anaf-ts-sdk`

## README

# ANAF e- Factura 类型Script SDK

用于与罗马尼亚ANAF e-Factura系统互动的综合性TypeScript SDK. 这个SDK提供OAuth 2.0认证,文档上传/下载,验证,UBL生成,以及公司数据查询能力.

## 特征

-   **OAuth 2. 0 认证**: 使用 USB 符号支持完成 OAuth 流量
-   **文件操作**: 上传、状态检查和下载
-   **信件管理**: 列出并标出发票信息
-   **验证**: XML 验证和数字签名验证
-   **PDF 转换**: 将 XML 发票转换为 PDF 格式
-   **UBL 生成**: 创建符合规定的UBL 2.1 XML发票
-   **收到发票分析**: 将收到的 UBL 2.1 和 CII 文档读入打出的标题外加其行
-   **公司数据查询**:从公开的ANAF API中获取罗马尼亚公司详情
-   **类型脚本**: 完全类型安全和IntelliSense支持

## 安装

```bash
pnpm add @florinszilagyi/anaf-ts-sdk
```

## 快速启动

SDK主要分为四类:

### 1\. 认证 - OAuth 2.0认证

```typescript
import { AnafAuthenticator } from '@florinszilagyi/anaf-ts-sdk';

const auth = new AnafAuthenticator({
  clientId: 'your-oauth-client-id',
  clientSecret: 'your-oauth-client-secret',
  redirectUri: 'https://your-app.com/oauth/callback',
});

// Get authorization URL (user will authenticate with USB token)
const authUrl = auth.getAuthorizationUrl();
console.log('Redirect user to:', authUrl);

// Exchange authorization code for tokens
const tokens = await auth.exchangeCodeForToken(authorizationCode);
console.log('Access token:', tokens.access_token);

// Refresh tokens when needed
const newTokens = await auth.refreshAccessToken(tokens.refresh_token);
```

### 2\. AnafEfacturaClient - API操作系统

客户端用刷新符号构建一次并解决访问符号 自己,所以没有电话 需要象征性的争论.

```typescript
import { AnafEfacturaClient } from '@florinszilagyi/anaf-ts-sdk';

const client = new AnafEfacturaClient(
  {
    vatNumber: 'RO12345678',
    testMode: true, // Use test environment
    refreshToken: tokens.refresh_token,
  },
  auth // the AnafAuthenticator from step 1
);

// Upload a document
const uploadResult = await client.uploadDocument(xmlContent, {
  standard: 'UBL',
  executare: true,
});

// Check upload status
const status = await client.getUploadStatus(uploadResult.indexIncarcare);

// Download processed document (ZIP archive: invoice + detached signature)
if (status.idDescarcare) {
  const result = await client.downloadDocument(status.idDescarcare);

  // Or unwrap the archive and get the invoice XML directly
  const invoiceXml = await client.downloadDocumentXml(status.idDescarcare);

  // …which is what you need to render the invoice as a PDF
  const pdf = await client.convertXmlToPdf(invoiceXml, 'FACT1');
}

// List recent messages
const messages = await client.getMessages({
  zile: 7, // Last 7 days
  filtru: 'E', // Only errors
});

// Validate XML
const validation = await client.validateXml(xmlContent, 'FACT1');

// Convert XML to PDF
const pdfBuffer = await client.convertXmlToPdf(xmlContent, 'FACT1');
```

### 3\. UblBuilder - UBL XML 生成器

```typescript
import { UblBuilder } from '@florinszilagyi/anaf-ts-sdk';

const builder = new UblBuilder();

const xml = builder.generateInvoiceXml({
  invoiceNumber: 'INV-2024-001',
  issueDate: new Date(),
  supplier: {
    registrationName: 'Company SRL',
    companyId: 'RO12345678',
    vatNumber: 'RO12345678',
    address: {
      street: 'Str. Example 1',
      city: 'Bucharest',
      postalZone: '010101',
    },
  },
  customer: {
    registrationName: 'Customer SRL',
    companyId: 'RO87654321',
    address: {
      street: 'Str. Customer 2',
      city: 'Cluj-Napoca',
      postalZone: '400001',
    },
  },
  lines: [
    {
      description: 'Product/Service',
      quantity: 1,
      unitPrice: 100,
      taxPercent: 19,
    },
  ],
  isSupplierVatPayer: true,
});
```

可选政党和联系人:

```typescript
const xml = builder.generateInvoiceXml({
  // ...the fields above
  note: 'Delegat: Ion Exemplu', // BT-22
  supplier: { /* ... */ contactName: 'Ana Exemplu' }, // BT-41
  customer: { /* ... */ contactName: 'Ion Exemplu' }, // BT-56
  // BG-11: only for a seller that has appointed a tax representative.
  taxRepresentative: {
    name: 'Reprezentant Exemplu SRL',
    vatNumber: 'RO11223344', // with country prefix
    address: { street: 'Str. Exemplu 5', city: 'Cluj-Napoca', postalZone: '400002', county: 'RO-CJ' },
  },
});
```

建筑师投出 `AnafValidationError` 当税务代表没有 名称,没有前缀的增值税号码,没有ISO 3166-2:RO县代码(`RO-CJ`用于 罗马尼亚语地址,或者当供应商不是增值税支付人时.

### 4\. AnafDetailsClient - 公司数据查询

```typescript
import { AnafDetailsClient } from '@florinszilagyi/anaf-ts-sdk';

const detailsClient = new AnafDetailsClient({
  timeout: 30000,
  url: 'https://webservicesp.anaf.ro/api/PlatitorTvaRest/v9/tva', // Optional: custom ANAF API URL
});

// Fetch company data by VAT code (single company)
const result = await detailsClient.getCompanyData('RO12345678');
if (result.success) {
  console.log('Company:', result.data[0].name);
  console.log('Address:', result.data[0].address);
  console.log('VAT registered:', result.data[0].scpTva);
  console.log('Registration number:', result.data[0].registrationNumber);
  console.log('Phone:', result.data[0].contactPhone);
} else {
  console.error('Error:', result.error);
}

// Validate VAT code format
const isValid = await detailsClient.isValidVatCode('RO12345678');
console.log('Valid format:', isValid);

// Batch fetch multiple companies (single API call)
const batchResult = await detailsClient.batchGetCompanyData(['RO12345678', 'RO87654321', 'RO11111111']);
if (batchResult.success) {
  batchResult.data.forEach((company, index) => {
    console.log(`Company ${index + 1}:`, company.name);
    console.log(`VAT registered:`, company.scpTva);
  });
} else {
  console.error('Batch error:', batchResult.error);
}

// Bulk lookup: max 100 CUIs, a fixed request date, no e-Factura registry request
const bulk = await detailsClient.batchGetCompanyData(['12345678', '87654321'], {
  date: '2026-01-31',
  includeEfacturaRegistry: false,
});
if (bulk.success) {
  bulk.data.forEach((company) => console.log(company.vatCode, company.caenCode));
  console.log('Not found:', bulk.notFound);
} else if (bulk.retryable) {
  console.log('Retry later', bulk.statusCode, bulk.retryAfter);
} else {
  console.log('Final answer:', bulk.error, bulk.notFound);
}

// Configuration options
const customClient = new AnafDetailsClient({
  timeout: 60000, // 60 second timeout
  url: 'https://custom-anaf-proxy.example.com/api/tva', // Custom endpoint (e.g., proxy server)
});
```

### 5\. 分析 发票 -- -- 收到阅读发票

分析通过SPV收到的文件——UBL 2.1 `Invoice`编号 :`CreditNote` 或 CII 类型 `CrossIndustryInvoice` ——入平头外加其源行. 每个数额 以十进制的形式回来 **字符串** 所发表的文件,从未 JavaScript 编号, 因此在它到达前没有丢失任何浮标 你自己的钱处理.

```typescript
import { parseReceivedInvoice } from '@florinszilagyi/anaf-ts-sdk';

const xml = await client.downloadDocumentXml(status.idDescarcare);
const invoice = parseReceivedInvoice(xml);

invoice.documentStandard; // 'ubl' | 'cii'
invoice.documentKind; // 'invoice' | 'credit_note' | 'corrective' | a raw type code
invoice.pdfStandard; // 'FACT1' | 'FCN' — which converter convertXmlToPdf needs
invoice.invoiceNumber; // 'EXMPL-2026-001'
invoice.issueDate; // '2026-08-01'
invoice.supplierName; // 'Exemplu SRL'
invoice.supplierVatCode; // 'RO12345678'
invoice.totalAmount; // '119.00' — a string, not 119
invoice.notes; // every invoice note (BT-22) in document order; [] when there are none
invoice.supplierContact; // { name, telephone, email } | null
invoice.customerContact; // { name, telephone, email } | null
invoice.taxRepresentative; // { name, vatCode, address } | null (BG-11)
invoice.sourceLines; // one ReceivedInvoiceLine per document line
invoice.sourceLineDiagnostics; // human-readable notes for malformed/absent line facts
```

**每个信头字段均为无效.** `invoiceNumber`, (中文(简体) ), `issueDate`, (中文(简体) ), `totalAmount` 剩下的就回来 `null` 当文档没有时 以不验证的形式出版或出版它们 —— 解析器 从不取代默认。 检查您自己的流量所依赖的字段 使用它们.

剖析者拒绝猜测. 它抛出:

-   `AnafValidationError` ——文件超大(12 MB of UTF-8)或其 根元素不是一个公认的发票根.
-   `AnafXmlParsingError` —— XML 结构不完善, 声明外部 实体在其DTD中(甚至一个未提及的实体),或 将一个元素命名为一个元素 保留 JavaScript 属性名称, 例如 `__proto__`。 。 。 .
-   `AnafAmbiguousTaxTotalError` 文件载有若干增值税总额和 其中没有一个与文档货币相匹配.

字段不能读取为有效的小数、日期或货币返回为 `null` 而不是强迫, 和无法读取的线性事实报告 `sourceLineDiagnostics` 而线本身被保留.

普通和DTD实体扩展仍被禁用(这些文件是: 供应商授权,一个递归实体定义将气球内存). 五个预定义的 XML 实体和小数/hex 字符引用—— 罗马尼亚的二极论者通常到达时 `&#38;amp;` 是文字文本 `&amp;`永远 `&`。 。 。 .

## AnafDetails 客户端配置

这个 `AnafDetailsClient` 支持以下配置选项:

| 选项 | 类型 | 默认 | 说明 |
| --- | --- | --- | --- |
| `timeout` | `number` | `30000` | 请求超时( 毫秒) |
| `url` | `string` | `'https://webservicesp.anaf.ro/api/PlatitorTvaRest/v9/tva'` | ANAF API 端点 URL |

### 配置示例

```typescript
// Default configuration
const client = new AnafDetailsClient();

// Custom timeout
const clientWithTimeout = new AnafDetailsClient({
  timeout: 60000, // 60 seconds
});

// Custom API endpoint (useful for proxy servers or testing)
const clientWithCustomUrl = new AnafDetailsClient({
  url: 'https://your-proxy.example.com/anaf-api',
  timeout: 45000,
});

// Minimal configuration
const minimalClient = new AnafDetailsClient({
  timeout: 15000, // Fast timeout for quick responses
});
```

### 自定义 URL 使用大小写

-   **代理服务器**: 通过您自己的登录/监测代理请求路由
-   **装入平衡器**: 在多个ANAF端点分发请求
-   **测试**: 开发期间指向模拟服务器
-   **区域终点**: 如果可用, 使用不同的 ANAF 区域服务器
-   **公司防火墙**:通过核准的公司网关的路线

## 完整示例

```typescript
import { AnafAuthenticator, AnafClient, AnafDetailsClient, UblBuilder } from '@florinszilagyi/anaf-ts-sdk';

// Setup
const auth = new AnafAuthenticator({
  clientId: process.env.ANAF_CLIENT_ID,
  clientSecret: process.env.ANAF_CLIENT_SECRET,
  redirectUri: 'https://myapp.com/oauth/callback',
});

const client = new AnafClient({
  vatNumber: 'RO12345678',
  testMode: true,
});

const detailsClient = new AnafDetailsClient();
const builder = new UblBuilder();

// 1. Get customer company data
const customerData = await detailsClient.getCompanyData('RO87654321');
if (!customerData.success) {
  throw new Error(`Customer not found: ${customerData.error}`);
}

// 2. Authentication (one-time setup)
const authUrl = auth.getAuthorizationUrl();
// Direct user to authUrl, they authenticate with USB token
const tokens = await auth.exchangeCodeForToken(authCode);

// 3. Generate invoice XML using fetched company data
const xml = builder.generateInvoiceXml({
  invoiceNumber: 'INV-2024-001',
  issueDate: new Date(),
  supplier: {
    registrationName: 'My Company SRL',
    companyId: 'RO12345678',
    vatNumber: 'RO12345678',
    address: {
      street: 'Str. Example 1',
      city: 'Bucharest',
      postalZone: '010101',
    },
  },
  customer: {
    registrationName: customerData.data[0].name,
    companyId: customerData.data[0].vatCode,
    vatNumber: customerData.data[0].vatCode,
    address: {
      street: customerData.data[0].address,
      city: 'Cluj-Napoca', // Parse from address if needed
      postalZone: customerData.data[0].postalCode || '400001',
    },
  },
  lines: [
    {
      description: 'Consulting Services',
      quantity: 1,
      unitPrice: 1000,
      taxPercent: customerData.data[0].scpTva ? 19 : 0, // Apply VAT if customer is VAT registered
    },
  ],
  isSupplierVatPayer: true,
});

// 4. Upload to ANAF
const uploadResult = await client.uploadDocument(tokens.access_token, xml);

// 5. Monitor status
const status = await client.getUploadStatus(tokens.access_token, uploadResult.index_incarcare);

// 6. Download result
if (status.id_descarcare) {
  const result = await client.downloadDocument(tokens.access_token, status.id_descarcare);
}
```

## 开发和测试

### 先决条件

1.  **USB 安全托肯**: ANAF认证要求
    
    -   支持的符号 : 罗马尼亚 CA 的任何合格证书
    -   安装制造商驱动程序( 安全网、 Gemalto等)
    -   证书必须在 ANAF SPV 注册
2.  **ANAF OAuth 应用程序**登记地址: [ANAF 门户](https://anaf.ro/)
    
    -   导航: Servicii Online →nregistrare utilizatori → DEZVOLTATORI APLICAȚII Î 二 (中文(简体) )
    -   用您的回调 URL 注册应用程序

### 环境设置

创建一个 `.env` 在工程根中的文件 :

```env
ANAF_CLIENT_ID=your_oauth_client_id_here
ANAF_CLIENT_SECRET=your_oauth_client_secret_here
```

### 本地开发与 ngrok

要进行本地测试, 您需要 OAuth 调用 URL :

1.  **安装 ngrok**数字 :
    
    ```bash
    # Using npm
    npm install -g ngrok
    
    # Or download from https://ngrok.com/
    ```
    
2.  **曝光本地服务器**数字 :
    
    ```bash
    # Start your local server on port 3000
    npm start
    
    # In another terminal, expose it publicly
    ngrok http 3000
    ```
    
3.  **更新 OAuth 设置**数字 :
    
    -   复制 ngrok HTTPS URL(例如, `https://abc123.ngrok.io`(中文(简体) )
    -   注册回调 URL : `https://abc123.ngrok.io/oauth/callback`
    -   更新您的 Anaf 认证器配置 :
    
    ```typescript
    const auth = new AnafAuthenticator({
      clientId: process.env.ANAF_CLIENT_ID,
      clientSecret: process.env.ANAF_CLIENT_SECRET,
      redirectUri: 'https://abc123.ngrok.io/oauth/callback', // Your ngrok URL
    });
    ```
    

### OAuth 认证流程

OAuth 完整的 USB 令牌认证 :

1.  **生成授权 URL**数字 :
    
    ```typescript
    const authUrl = auth.getAuthorizationUrl();
    console.log('Direct user to:', authUrl);
    ```
    
2.  **用户认证进程**数字 :
    
    -   用户点击/访问授权 URL
    -   ANAF 登录页面打开
    -   **插入 USB 键**:用户插入 USB 安全标志
    -   **输入 PIN**: 用户在提示时输入符号 PIN
    -   **证书选择**: 浏览器显示证书选择对话框
    -   **选择证书**: 用户选择适当的证书
    -   **授权应用程序**: 用户授予您的应用程序权限
    -   **重定向**: 浏览器以授权代码重定向到您的回调 URL
3.  **处理召回**数字 :
    
    ```typescript
    // Your callback endpoint receives: ?code=AUTH_CODE&state=STATE
    app.get('/oauth/callback', async (req, res) => {
      const { code } = req.query;
    
      try {
        const tokens = await auth.exchangeCodeForToken(code);
        // Store tokens securely
        res.send('Authentication successful!');
      } catch (error) {
        res.status(400).send('Authentication failed');
      }
    });
    ```
    
4.  **使用访问托肯**数字 :
    
    ```typescript
    // Token is valid for 1 hour
    const client = new AnafClient({ vatNumber: 'RO12345678' });
    const result = await client.uploadDocument(tokens.access_token, xmlContent);
    ```
    
5.  **刷新鼠标**数字 :
    
    ```typescript
    // Refresh before expiration
    const newTokens = await auth.refreshAccessToken(tokens.refresh_token);
    ```
    

### 自动测试

SDK包括一个综合OAuth流的综合Jest测试:

```bash
# Run all tests
pnpm test

# Run OAuth authentication tests with callback server
pnpm test:auth

# Run tests with coverage
pnpm test:coverage
```

### 手动操作测试

测试套件包括一个有用的OAuth测试流程:

1.  **开始测试**数字 :
    
    ```bash
    pnpm test:auth
    ```
    
2.  **回调服务器**: 自动启动 `http://localhost:4040`
    
3.  **获取 OAuth URL**:测试在控制台显示授权 URL
    
4.  **完成 OAuth 任务**数字 :
    
    -   复制 URL 到浏览器
    -   提示时插入 USB 令牌
    -   输入 PIN 并选择证书
    -   授权应用程序
    -   浏览器重定向到 `localhost:4040/callback`
5.  **自动按键处理**: 测试抓取代码并交换令牌
    

### 测试环境

-   **测试环境**: 所有测试都使用ANAF测试环境
-   **OAuth 终点**数字 : `logincert.anaf.ro`
-   **API 终点**数字 : `api.anaf.ro/test`
-   **回调 URL**数字 : `http://localhost:4040/callback` (用于测试)

### 托肯管理

-   自动保存到 `token.secret` 测试期间
-   1小时后失效
-   刷新符号具有更长的有效性
-   测试自动刷新过期的符号
-   无效的令牌被自动清理

### 解决问题

#### USB 托肯问题

```
❌ Certificate selection failed
```

**解决方案**数字 :

-   确保正确插入 USB 令牌
-   安装制造商驱动程序
-   尝试不同的浏览器( 推荐 Chrome)
-   在浏览器设置中检查证书的有效性

#### OAuth 回召问题

```
❌ Redirect URI mismatch
```

**解决方案**数字 :

-   完全验证已注册的 URL 匹配
-   包含协议( https://) 和路径
-   对 ngrok : 使用 HTTPS URL, 而非 HTTP
-   检查后面的鞭打

#### 网络问题

```
❌ Connection refused or timeout
```

**解决方案**数字 :

-   检查互联网连接
-   校验防火墙设置
-   Ngrok: 确保隧道活动
-   尝试不同的 ngrok 区域 : `ngrok http 3000 --region eu`

#### 托肯过期

```
❌ Access token expired
```

**解决方案**数字 :

-   使用刷新令牌获取新访问令牌
-   在您的app中执行自动刷新令牌
-   存储标志过期时间并主动刷新

## API 覆盖范围

SDK执行来自ANAF e-Factura OpenAPI规格的所有端点:

### 认证

-   OAuth 2.0 授权流量
-   切换和刷新

### 文件操作

-   QQ 上传文档 (`/upload`, (中文(简体) ), `/uploadb2c`(中文(简体) )
-   请检查上传状态 (X)`/stareMesaj`(中文(简体) )
-   下载已处理的文件(`/descarcare`(中文(简体) )

### 信件管理

-   QQ 以页标列出信件( L)`/listaMesajePaginatieFactura`(中文(简体) )
-   列出最近的信件( L)`/listaMesajeFactura`(中文(简体) )

### 验证和转换

-   XML 验证`/validare/{standard}`(中文(简体) )
-   \* 数字签字验证`/api/validate/signature`(中文(简体) )
-   XML 到 PDF 转换 (`/transformare/{standard}`(中文(简体) )
-   XML 到 PDF 不经过验证 (`/transformare/{standard}/DA`(中文(简体) )

### UBL 生成

-   UBL 2.1 符合要求的XML 生成
-   罗马尼亚CIUS-RO规格支持

### 公司数据查询

-   按增值税代码获取公司数据
-   验证增值税代码格式
-   QQ 批量抓取多个公司
-   QQ 快取管理

## 环境配置

SDK支持测试和生产环境:

```typescript
// Test environment (recommended for development)
const client = new AnafClient({
  vatNumber: 'RO12345678',
  testMode: true,
});

// Production environment
const client = new AnafClient({
  vatNumber: 'RO12345678',
  testMode: false,
});
```

## 处理错误

SDK为不同的情景提供了特定的出错类型:

```typescript
import { AnafAuthenticationError, AnafValidationError, AnafApiError } from '@florinszilagyi/anaf-ts-sdk';

try {
  await client.uploadDocument(token, xml);
} catch (error) {
  if (error instanceof AnafAuthenticationError) {
    // Handle authentication issues - refresh token or re-authenticate
    console.log('Authentication failed:', error.message);
  } else if (error instanceof AnafValidationError) {
    // Handle validation errors - fix XML or parameters
    console.log('Validation error:', error.message);
  } else if (error instanceof AnafApiError) {
    // Handle API errors - check status, retry, or contact support
    console.log('API error:', error.message);
  }
}
```

## 类型脚本支持

SDK用TypeScript来写,并提供了全面的类型定义:

```typescript
import type { InvoiceInput, UploadStatus, ListMessagesResponse, ValidationResult, OAuthTokens } from '@florinszilagyi/anaf-ts-sdk';
```

## 安保最佳做法

-   **永远不要交代**页:1 `token.secret` 财务报告和审定财务报表 `.env` 改为 `.gitignore`
-   **使用 HTTPS**: 在生产中总是使用 HTTPS 用于 OAuth 回调
-   **验证证书**: 确保 USB 令牌证书有效且不过期
-   **安全信使存储**: 安全存储令牌(加密、数据库、安全存储)
-   **执行刷新**: 过期前自动刷新符号
-   **测试环境**: 使用测试模式进行开发和中转

## 生产部署

部署到生产时:

1.  **注册生产 OAuth App**数字 :
    
    -   使用您的生产域调回 URL
    -   获取单独的客户证书来制作
2.  **环境配置**数字 :
    
    ```typescript
    const client = new AnafClient({
      vatNumber: 'RO12345678',
      testMode: false, // Production mode
    });
    ```
    
3.  **安全召回处理**数字 :
    
    -   对所有 OAuth 回调使用 HTTPS
    -   验证状态参数
    -   实施CSRF保护
    -   日志认证事件
4.  **托肯管理**数字 :
    
    -   安全存储令牌( 加密数据库)
    -   执行自动刷新
    -   处理刷新标志性过期
    -   监视令牌的使用和过期

## 许可证

麻省理工学院许可证 - 详情见LICENSE文件.

## 捐款

1.  叉子存储器
2.  创建特性分支
3.  做你的改变
4.  添加测试
5.  运行测试和起伏
6.  提交拉动请求

## 支助

关于下列问题:

-   **ANAF e-Factura API**: 检查 [ANAF 正式文件](https://mfinante.gov.ro/web/efactura/informatii-tehnice)
-   **这个SDK**: 在 GitHub 上打开一期
-   **OAuth 设置**: 查阅ANAF SPV文件: [ANAF 正式文件](https://static.anaf.ro/static/10/Anaf/Informatii_R/API/Oauth_procedura_inregistrare_aplicatii_portal_ANAF.pdf)
-   **USB 托肯问题**: 联系您的证书提供者

* * *

**完美无缺**:SaaS应用程序、会计软件、企业资源规划集成、发票系统

**所需资源**:USB安全标志,ANAF OAuth注册,Node.js 16+

## 常见问题

### @florinszilagyi/anaf-ts-sdk 是什么？

Romanian ANAF API - E-Factura, 公司的检查

### 如何安装 @florinszilagyi/anaf-ts-sdk？

在项目目录运行 npm install @florinszilagyi/anaf-ts-sdk，或使用 pnpm add / yarn add / bun add。

### @florinszilagyi/anaf-ts-sdk 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @florinszilagyi/anaf-ts-sdk 支持 ESM 还是 CommonJS？

同时提供 ES Module 与 CommonJS 入口，import 和 require\(\) 都可以使用，打包工具会自动选择合适的版本。

### @florinszilagyi/anaf-ts-sdk 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js \>=20\.0\.0。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### @florinszilagyi/anaf-ts-sdk 可以商用吗？

@florinszilagyi/anaf-ts-sdk 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @florinszilagyi/anaf-ts-sdk 的下载量有多少？

根据 npm 官方下载统计，@florinszilagyi/anaf-ts-sdk 在 2026/10/15 – 2026/11/13 这 30 天内被下载 6,011 次，日均约 200 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @florinszilagyi/anaf-ts-sdk 还在维护吗？

最新版本 2\.0\.6 发布于 2026/11/13（2 天前）；至今共发布 16 个版本，其中过去 12 个月发布了 16 个；首次发布于 2026/04/15。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

