# 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** 进行认证: ```http Authorization: Bearer ``` ### 1.3 响应格式 所有响应使用 JSON 格式,统一结构: ```json { "success": true, "data": { ... }, "meta": { "request_id": "req_abc123", "timestamp": "2026-02-03T10:30:00Z" } } ``` 错误响应: ```json { "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 用户注册 ```http POST /auth/register Content-Type: application/json { "email": "user@example.com", "password": "SecurePass123!", "full_name": "John Doe" } ``` **响应:** ```json { "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 用户登录 ```http POST /auth/login Content-Type: application/json { "email": "user@example.com", "password": "SecurePass123!" } ``` **响应:** ```json { "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 ```http POST /auth/refresh Content-Type: application/json { "refresh_token": "eyJhbGciOiJIUzI1NiIs..." } ``` ### 2.4 登出 ```http POST /auth/logout Authorization: Bearer ``` --- ## 3. 会计系统集成 (通用接口) ### 3.1 获取支持的会计系统列表 ```http GET /accounting/providers Authorization: Bearer ``` **响应:** ```json { "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 ```http GET /accounting/{provider}/auth/url Authorization: Bearer ``` **参数:** | 参数 | 类型 | 说明 | |------|------|------| | provider | string | 会计系统标识 (fortnox, visma, hogia) | **响应:** ```json { "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 回调处理 ```http GET /accounting/{provider}/auth/callback?code=xxx&state=xxx ``` **响应:** ```json { "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 获取用户的所有连接 ```http GET /accounting/connections Authorization: Bearer ``` **响应:** ```json { "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 获取特定连接状态 ```http GET /accounting/connections/{provider} Authorization: Bearer ``` **响应:** ```json { "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 更新连接设置 ```http PATCH /accounting/connections/{provider}/settings Authorization: Bearer Content-Type: application/json { "default_voucher_series": "A", "default_account_code": 5460, "auto_attach_pdf": true, "auto_create_supplier": false } ``` ### 3.7 断开连接 ```http DELETE /accounting/connections/{provider} Authorization: Bearer ``` --- ## 4. 发票处理 ### 4.1 上传发票 ```http POST /invoices Authorization: Bearer Content-Type: multipart/form-data file: provider: "fortnox" # 目标会计系统 auto_process: false # 是否自动处理 ``` **响应 (预览模式):** ```json { "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 获取发票列表 ```http GET /invoices?page=1&limit=20&status=imported&provider=fortnox&sort=-created_at Authorization: Bearer ``` **查询参数:** | 参数 | 类型 | 说明 | |------|------|------| | page | int | 页码,默认 1 | | limit | int | 每页数量,默认 20,最大 100 | | status | string | 过滤状态 | | provider | string | 过滤会计系统 | | sort | string | 排序字段,`-` 前缀表示降序 | **响应:** ```json { "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 获取发票详情 ```http GET /invoices/{id} Authorization: Bearer ``` ### 4.4 更新发票数据 (审核时) ```http PATCH /invoices/{id} Authorization: Bearer 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 导入到会计系统 ```http POST /invoices/{id}/import Authorization: Bearer Content-Type: application/json { "provider": "fortnox", "create_supplier": false, "supplier_data": { "name": "New Supplier", "organisation_number": "112233-4455" } } ``` **响应:** ```json { "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 删除发票 ```http DELETE /invoices/{id} Authorization: Bearer ``` 仅允许删除未导入 (`pending`, `preview`, `failed`) 状态的发票。 --- ## 5. 供应商管理 (通用接口) ### 5.1 获取供应商列表 ```http GET /accounting/{provider}/suppliers?search=ABC&page=1&limit=50 Authorization: Bearer ``` **响应:** ```json { "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 创建供应商 ```http POST /accounting/{provider}/suppliers Authorization: Bearer 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 刷新供应商缓存 ```http POST /accounting/{provider}/suppliers/refresh-cache Authorization: Bearer ``` --- ## 6. 会计科目 (通用接口) ### 6.1 获取科目列表 ```http GET /accounting/{provider}/accounts Authorization: Bearer ``` **响应:** ```json { "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 获取科目映射规则 ```http GET /account-mappings?provider=fortnox Authorization: Bearer ``` ### 6.3 创建科目映射规则 ```http POST /account-mappings Authorization: Bearer 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 接收 ```http 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 (内部) ```http POST /webhooks/register Authorization: Bearer Content-Type: application/json { "provider": "fortnox", "url": "https://api.invoice-master.app/webhooks/fortnox", "events": ["voucher.created", "voucher.updated"] } ``` --- ## 8. 健康检查 ### 8.1 基础健康检查 ```http GET /health ``` **响应:** ```json { "status": "healthy", "timestamp": "2026-02-03T10:30:00Z", "version": "2.0.0" } ``` ### 8.2 详细健康检查 ```http GET /health/detailed Authorization: Bearer ``` **响应:** ```json { "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 | 限速响应头: ```http X-RateLimit-Limit: 100 X-RateLimit-Remaining: 95 X-RateLimit-Reset: 1643875200 ``` --- ## 11. OpenAPI 规范 完整的 OpenAPI 3.0 规范可在 `/docs` 端点查看 (Swagger UI)。 ```http 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 | 初始版本 |