- Add .NET 8 backend with Clean Architecture - Add React + Vite + TypeScript frontend - Implement authentication with JWT - Implement Azure Blob Storage client - Implement OCR integration - Implement supplier matching service - Implement voucher generation - Implement Fortnox provider - Add unit and integration tests - Add Docker Compose configuration
16 KiB
16 KiB
Invoice Master - API 设计文档
版本: v3.0
Base URL: https://api.invoice-master.app/api/v1
日期: 2026-02-03
技术栈: .NET 8 + ASP.NET Core + MediatR (CQRS)
1. 概述
1.1 多会计系统支持
本 API 支持连接多个会计系统(Fortnox, Visma, Hogia 等),通过统一的抽象层提供一致的接口。
Provider 标识:
fortnox- Fortnox (瑞典)visma- Visma eAccounting (北欧)hogia- Hogia Smart (瑞典)
1.2 认证方式
API 使用 JWT Bearer Token 进行认证:
Authorization: Bearer <jwt_token>
1.3 响应格式
所有响应使用 JSON 格式,统一结构:
{
"success": true,
"data": { ... },
"meta": {
"request_id": "req_abc123",
"timestamp": "2026-02-03T10:30:00Z"
}
}
错误响应:
{
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "Human readable message",
"details": { ... }
},
"meta": {
"request_id": "req_abc123",
"timestamp": "2026-02-03T10:30:00Z"
}
}
1.4 HTTP 状态码
| 状态码 | 含义 |
|---|---|
| 200 | 成功 |
| 201 | 创建成功 |
| 400 | 请求参数错误 |
| 401 | 未认证 |
| 403 | 无权限 |
| 404 | 资源不存在 |
| 409 | 资源冲突 |
| 422 | 业务逻辑错误 |
| 429 | 请求过于频繁 |
| 500 | 服务器错误 |
2. 认证相关
2.1 用户注册
POST /auth/register
Content-Type: application/json
{
"email": "user@example.com",
"password": "SecurePass123!",
"full_name": "John Doe"
}
响应:
{
"success": true,
"data": {
"user": {
"id": "uuid",
"email": "user@example.com",
"full_name": "John Doe",
"created_at": "2026-02-03T10:30:00Z"
},
"tokens": {
"access_token": "eyJhbGciOiJIUzI1NiIs...",
"refresh_token": "eyJhbGciOiJIUzI1NiIs...",
"expires_in": 900
}
}
}
2.2 用户登录
POST /auth/login
Content-Type: application/json
{
"email": "user@example.com",
"password": "SecurePass123!"
}
响应:
{
"success": true,
"data": {
"user": {
"id": "uuid",
"email": "user@example.com",
"full_name": "John Doe",
"connections": [
{
"provider": "fortnox",
"connected": true,
"company_name": "My Company AB"
}
]
},
"tokens": {
"access_token": "eyJhbGciOiJIUzI1NiIs...",
"refresh_token": "eyJhbGciOiJIUzI1NiIs...",
"expires_in": 900
}
}
}
2.3 刷新 Token
POST /auth/refresh
Content-Type: application/json
{
"refresh_token": "eyJhbGciOiJIUzI1NiIs..."
}
2.4 登出
POST /auth/logout
Authorization: Bearer <token>
3. 会计系统集成 (通用接口)
3.1 获取支持的会计系统列表
GET /accounting/providers
Authorization: Bearer <token>
响应:
{
"success": true,
"data": {
"providers": [
{
"id": "fortnox",
"name": "Fortnox",
"description": "Swedish accounting software",
"available": true,
"connected": true
},
{
"id": "visma",
"name": "Visma eAccounting",
"description": "Nordic accounting software",
"available": true,
"connected": false
},
{
"id": "hogia",
"name": "Hogia Smart",
"description": "Swedish accounting software",
"available": false,
"connected": false
}
]
}
}
3.2 获取授权 URL
GET /accounting/{provider}/auth/url
Authorization: Bearer <token>
参数:
| 参数 | 类型 | 说明 |
|---|---|---|
| provider | string | 会计系统标识 (fortnox, visma, hogia) |
响应:
{
"success": true,
"data": {
"provider": "fortnox",
"authorization_url": "https://apps.fortnox.se/oauth-v1/auth?client_id=xxx&redirect_uri=...&scope=...&state=...",
"state": "random_state_string"
}
}
3.3 OAuth 回调处理
GET /accounting/{provider}/auth/callback?code=xxx&state=xxx
响应:
{
"success": true,
"data": {
"provider": "fortnox",
"connected": true,
"company_name": "My Company AB",
"company_org_number": "556677-8899",
"connected_at": "2026-02-03T10:30:00Z"
}
}
3.4 获取用户的所有连接
GET /accounting/connections
Authorization: Bearer <token>
响应:
{
"success": true,
"data": {
"connections": [
{
"provider": "fortnox",
"connected": true,
"company_name": "My Company AB",
"company_org_number": "556677-8899",
"scopes": ["supplier", "voucher", "account"],
"expires_at": "2026-02-03T11:30:00Z",
"settings": {
"default_voucher_series": "A",
"default_account_code": 5460,
"auto_attach_pdf": true,
"auto_create_supplier": false
}
}
]
}
}
3.5 获取特定连接状态
GET /accounting/connections/{provider}
Authorization: Bearer <token>
响应:
{
"success": true,
"data": {
"provider": "fortnox",
"connected": true,
"company_name": "My Company AB",
"company_org_number": "556677-8899",
"scopes": ["supplier", "voucher", "account"],
"expires_at": "2026-02-03T11:30:00Z"
}
}
3.6 更新连接设置
PATCH /accounting/connections/{provider}/settings
Authorization: Bearer <token>
Content-Type: application/json
{
"default_voucher_series": "A",
"default_account_code": 5460,
"auto_attach_pdf": true,
"auto_create_supplier": false
}
3.7 断开连接
DELETE /accounting/connections/{provider}
Authorization: Bearer <token>
4. 发票处理
4.1 上传发票
POST /invoices
Authorization: Bearer <token>
Content-Type: multipart/form-data
file: <binary>
provider: "fortnox" # 目标会计系统
auto_process: false # 是否自动处理
响应 (预览模式):
{
"success": true,
"data": {
"id": "inv_uuid",
"status": "preview",
"provider": "fortnox",
"file": {
"name": "Invoice_2024_001.pdf",
"size": 1024567,
"url": "https://blob.azure/..."
},
"extraction": {
"supplier_name": "ABC Company",
"supplier_org_number": "556677-8899",
"invoice_number": "F2024-001",
"invoice_date": "2024-01-15",
"due_date": "2024-02-15",
"amount_total": 1250.00,
"amount_vat": 250.00,
"vat_rate": 25,
"ocr_number": "7350012345678",
"bankgiro": "123-4567",
"currency": "SEK",
"confidence": 0.95
},
"supplier_match": {
"action": "USE_EXISTING",
"supplier_number": "123",
"supplier_name": "ABC Company",
"confidence": 1.0
},
"voucher_preview": {
"series": "A",
"rows": [
{
"account": 5460,
"account_name": "Kontorsmaterial",
"debit": 1000.00,
"credit": 0,
"description": "ABC Company - F2024-001"
},
{
"account": 2610,
"account_name": "Ingående moms",
"debit": 250.00,
"credit": 0,
"description": "Moms 25%"
},
{
"account": 2440,
"account_name": "Leverantörsskulder",
"debit": 0,
"credit": 1250.00,
"description": "Faktura F2024-001",
"supplier_number": "123"
}
]
},
"created_at": "2026-02-03T10:30:00Z"
}
}
4.2 获取发票列表
GET /invoices?page=1&limit=20&status=imported&provider=fortnox&sort=-created_at
Authorization: Bearer <token>
查询参数:
| 参数 | 类型 | 说明 |
|---|---|---|
| page | int | 页码,默认 1 |
| limit | int | 每页数量,默认 20,最大 100 |
| status | string | 过滤状态 |
| provider | string | 过滤会计系统 |
| sort | string | 排序字段,- 前缀表示降序 |
响应:
{
"success": true,
"data": {
"items": [
{
"id": "inv_uuid",
"status": "imported",
"provider": "fortnox",
"file_name": "Invoice_2024_001.pdf",
"supplier_name": "ABC Company",
"amount_total": 1250.00,
"invoice_date": "2024-01-15",
"voucher": {
"series": "A",
"number": "1234",
"url": "https://api.fortnox.se/3/vouchers/A/1234"
},
"created_at": "2026-02-03T10:30:00Z"
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 156,
"total_pages": 8
}
}
}
4.3 获取发票详情
GET /invoices/{id}
Authorization: Bearer <token>
4.4 更新发票数据 (审核时)
PATCH /invoices/{id}
Authorization: Bearer <token>
Content-Type: application/json
{
"extraction": {
"supplier_name": "Corrected Name",
"supplier_org_number": "556677-8899",
"amount_total": 1300.00,
"vat_rate": 25
},
"voucher_rows": [
{
"account": 6210,
"debit": 1040.00,
"credit": 0
},
{
"account": 2610,
"debit": 260.00,
"credit": 0
},
{
"account": 2440,
"debit": 0,
"credit": 1300.00
}
]
}
4.5 导入到会计系统
POST /invoices/{id}/import
Authorization: Bearer <token>
Content-Type: application/json
{
"provider": "fortnox",
"create_supplier": false,
"supplier_data": {
"name": "New Supplier",
"organisation_number": "112233-4455"
}
}
响应:
{
"success": true,
"data": {
"id": "inv_uuid",
"status": "imported",
"provider": "fortnox",
"voucher": {
"series": "A",
"number": "1234",
"url": "https://api.fortnox.se/3/vouchers/A/1234"
},
"supplier": {
"number": "123",
"name": "ABC Company"
},
"attachment": {
"id": "att_xxx",
"uploaded": true
},
"accounting_url": "https://apps.fortnox.se/...",
"imported_at": "2026-02-03T10:35:00Z"
}
}
4.6 删除发票
DELETE /invoices/{id}
Authorization: Bearer <token>
仅允许删除未导入 (pending, preview, failed) 状态的发票。
5. 供应商管理 (通用接口)
5.1 获取供应商列表
GET /accounting/{provider}/suppliers?search=ABC&page=1&limit=50
Authorization: Bearer <token>
响应:
{
"success": true,
"data": {
"items": [
{
"supplier_number": "123",
"name": "ABC Company",
"organisation_number": "556677-8899",
"address": "Storgatan 1, 123 45 Stockholm",
"phone": "08-123 45 67",
"email": "info@abc.com",
"bankgiro": "123-4567",
"cached_at": "2026-02-03T09:00:00Z"
}
],
"pagination": {
"page": 1,
"limit": 50,
"total": 45
},
"from_cache": true
}
}
5.2 创建供应商
POST /accounting/{provider}/suppliers
Authorization: Bearer <token>
Content-Type: application/json
{
"name": "New Supplier AB",
"organisation_number": "112233-4455",
"address1": "Testgatan 1",
"postcode": "123 45",
"city": "Stockholm",
"phone": "08-123 45 67",
"email": "info@supplier.com",
"bankgiro": "765-4321"
}
5.3 刷新供应商缓存
POST /accounting/{provider}/suppliers/refresh-cache
Authorization: Bearer <token>
6. 会计科目 (通用接口)
6.1 获取科目列表
GET /accounting/{provider}/accounts
Authorization: Bearer <token>
响应:
{
"success": true,
"data": {
"accounts": [
{
"code": 2440,
"name": "Leverantörsskulder",
"type": "liability"
},
{
"code": 2610,
"name": "Ingående moms",
"type": "liability"
},
{
"code": 5460,
"name": "Kontorsmaterial",
"type": "expense"
}
]
}
}
6.2 获取科目映射规则
GET /account-mappings?provider=fortnox
Authorization: Bearer <token>
6.3 创建科目映射规则
POST /account-mappings
Authorization: Bearer <token>
Content-Type: application/json
{
"provider": "fortnox",
"supplier_org_number": "556677-8899",
"keyword": "kontor",
"account_code": 5460,
"vat_rate": 25,
"description_template": "{supplier_name} - Kontorsmaterial",
"priority": 5
}
7. Webhooks
7.1 通用 Webhook 接收
POST /webhooks/{provider}
Headers:
X-Provider-Event: voucher.created
X-Provider-Signature: sha256=...
{
"event": "voucher.created",
"provider": "fortnox",
"timestamp": "2026-02-03T10:30:00Z",
"data": {
"voucher_number": "1234",
"series": "A",
"company_org_number": "556677-8899"
}
}
7.2 注册 Webhook (内部)
POST /webhooks/register
Authorization: Bearer <admin_token>
Content-Type: application/json
{
"provider": "fortnox",
"url": "https://api.invoice-master.app/webhooks/fortnox",
"events": ["voucher.created", "voucher.updated"]
}
8. 健康检查
8.1 基础健康检查
GET /health
响应:
{
"status": "healthy",
"timestamp": "2026-02-03T10:30:00Z",
"version": "2.0.0"
}
8.2 详细健康检查
GET /health/detailed
Authorization: Bearer <admin_token>
响应:
{
"status": "healthy",
"timestamp": "2026-02-03T10:30:00Z",
"checks": {
"database": { "status": "healthy", "latency_ms": 5 },
"redis": { "status": "healthy", "latency_ms": 2 },
"providers": {
"fortnox": { "status": "healthy", "latency_ms": 150 },
"visma": { "status": "not_configured" }
},
"ocr_api": { "status": "healthy", "latency_ms": 50 },
"blob_storage": { "status": "healthy", "latency_ms": 30 }
}
}
9. 错误代码表
| 错误代码 | HTTP 状态 | 说明 |
|---|---|---|
UNAUTHORIZED |
401 | Token 无效或过期 |
FORBIDDEN |
403 | 无权限访问 |
NOT_FOUND |
404 | 资源不存在 |
VALIDATION_ERROR |
400 | 请求参数验证失败 |
PROVIDER_NOT_SUPPORTED |
400 | 不支持的会计系统 |
PROVIDER_NOT_CONNECTED |
422 | 用户未连接该会计系统 |
PROVIDER_TOKEN_EXPIRED |
401 | 会计系统 Token 过期 |
PROVIDER_RATE_LIMITED |
429 | 会计系统 API 限流 |
OCR_FAILED |
422 | OCR 提取失败 |
INVOICE_ALREADY_IMPORTED |
409 | 发票已导入 |
INVALID_FILE_TYPE |
400 | 不支持的文件类型 |
FILE_TOO_LARGE |
400 | 文件超过大小限制 |
SUPPLIER_NOT_FOUND |
404 | 供应商不存在 |
VOUCHER_CREATE_FAILED |
422 | 凭证创建失败 |
10. 速率限制
| 端点 | 限制 |
|---|---|
/auth/* |
10 req/min |
/invoices (POST) |
10 req/min |
/invoices/* |
100 req/min |
/accounting/{provider}/* |
30 req/min |
| 其他 | 100 req/min |
限速响应头:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1643875200
11. OpenAPI 规范
完整的 OpenAPI 3.0 规范可在 /docs 端点查看 (Swagger UI)。
GET /docs # Swagger UI
GET /openapi.json # OpenAPI JSON
12. API 变更日志
v3.0 (2026-02-03)
技术栈变更:
- Python/FastAPI → .NET 8 + ASP.NET Core
- 新增 CQRS 模式 (MediatR)
- 新增领域事件 (审计支持)
- 新增审计 API 端点
新增:
/invoices/{id}/audit-log- 获取发票审计日志/users/me/audit-log- 获取用户操作历史/admin/audit-export- 导出审计报告
v2.0 (2026-02-03)
新增:
- 多会计系统支持
/accounting/providers- 获取支持的会计系统列表/accounting/{provider}/auth/url- 通用授权 URL 接口/accounting/{provider}/auth/callback- 通用 OAuth 回调/accounting/connections- 获取所有连接/accounting/connections/{provider}- 特定连接管理
变更:
/fortnox/*接口迁移到/accounting/{provider}/*/suppliers迁移到/accounting/{provider}/suppliers/accounts迁移到/accounting/{provider}/accounts- 发票上传增加
provider参数 - 发票导入增加
provider参数
废弃:
/fortnox/*(旧接口,将在 v3.0 移除)
文档历史:
| 版本 | 日期 | 作者 | 变更 |
|---|---|---|---|
| 3.0 | 2026-02-03 | Claude Code | 重构为 .NET + CQRS + 审计支持 |
| 2.0 | 2026-02-03 | Claude Code | 添加多会计系统支持 |
| 1.0 | 2026-02-03 | Claude Code | 初始版本 |