Files
accounting-system/API_DESIGN.md
Invoice Master 05ea67144f feat: initial project setup
- 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
2026-02-04 20:14:34 +01:00

16 KiB
Raw Permalink Blame History

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 初始版本