Compare commits

...

49 Commits

Author SHA1 Message Date
53df134759 Clarify payment domain ownership under REV003
Constraint: Keep payment documentation in existing formal docs rather than creating a parallel guide.\nRejected: Treating biz_payment_record as verified production tables | Current evidence only supports target/prototype semantics.\nConfidence: high\nScope-risk: narrow\nDirective: Do not move payment fact ownership into REV004; REV004 should reference REV003/SYS009 payment facts only.\nTested: make validate-file on main touched docs; make check-ai-governance; git diff --check.\nNot-tested: Full export/render pipeline.
2026-04-29 17:23:27 +08:00
1b6fda9c4d Record REV004 regression and fallback-reduction evidence
The evidence captures the new regression scripts, formal-first query
narrowing, and the fresh verification trail used to support the next
round of fallback removal.

Constraint: Evidence must match commands and outcomes actually executed in backend worktree
Rejected: Fold this into an older summary doc | would hide the stepwise proof for fallback reduction
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep appending fresh verification evidence here until the remaining legacy fallback is either removed or explicitly retained
Tested: Evidence cross-checked against backend worktree commands, regression logs, and targeted test outputs
Not-tested: No doc export/render pipeline executed
2026-04-20 15:02:24 +08:00
24761c5df3 Merge PR #16: add REV004 release ops checklist\n\nConstraint: Keep release operations guidance aligned with verified mainline state\nConfidence: high\nScope-risk: narrow\nDirective: Update this checklist only when release-critical reality changes, not for routine doc churn\nTested: PR #16 checklist cross-checked against current summary, truth matrix, and evidence set\nNot-tested: No document export/render pipeline executed at merge time 2026-04-17 18:23:08 +08:00
feb0da254f Add REV004 release ops checklist
This adds an operations-oriented checklist for REV004 covering environment
readiness, rollout order, smoke validation, rollback posture, and fast-path
triage hints for on-call and release engineers.

Constraint: Checklist must stay concise and executable for frontline release use
Rejected: Bury release steps across evidence and design docs only | too slow for runtime operations
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Update this checklist only when release-critical reality changes, not for every minor doc change
Tested: Cross-checked against final summary, go-live checklist, and current evidence set
Not-tested: No document export/render pipeline executed for this checklist
2026-04-17 18:19:47 +08:00
9946fa7572 Merge PR #15: add REV004 go-live and joint-debug checklist\n\nConstraint: Keep the checklist aligned with verified mainline state and evidence set\nConfidence: high\nScope-risk: narrow\nDirective: Update this checklist only when mainline reality or release blockers change materially\nTested: PR #15 checklist cross-checked against final summary, truth matrix, and evidence set\nNot-tested: No document export/render pipeline executed at merge time 2026-04-17 18:15:27 +08:00
74c951641f Add REV004 go-live and joint-debug checklist
This adds a concise operator-facing checklist for REV004 covering current
mainline SHAs, environment prerequisites, smoke order, remaining cautions,
and the evidence index used for release and joint-debug work.

Constraint: Checklist must reflect verified mainline reality and remain short enough for frontline use
Rejected: Keep launch guidance scattered across evidence files only | too slow for release/joint-debug coordination
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Update this checklist only when mainline reality materially changes or a new blocker emerges
Tested: Cross-checked against current mainline summary, truth matrix, and evidence set
Not-tested: No document export/render pipeline executed for this checklist
2026-04-17 18:11:46 +08:00
3741fd597d Merge PR #14: stabilize REV004 final summary docs anchor wording\n\nConstraint: Keep the final summary evergreen instead of self-expiring after each merge\nConfidence: high\nScope-risk: narrow\nDirective: Prefer stable branch-relative wording over self-referential merge SHAs in evergreen handoff docs\nTested: PR #14 wording reviewed against current docs mainline semantics\nNot-tested: No document export/render pipeline executed at merge time 2026-04-17 18:07:20 +08:00
700b8db99c Stabilize REV004 final summary docs anchor wording
This replaces the self-expiring docs latest-merge SHA in the final REV004
summary with a stable wording that points readers to current mainline content,
preventing the summary from going stale immediately after each merge.

Constraint: The top-level handoff summary must remain self-consistent after it is merged into main
Rejected: Keep chasing a concrete docs latest-merge SHA in follow-up patches | creates infinite self-expiring metadata churn
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Prefer stable branch-relative wording over self-referential merge SHAs in evergreen handoff docs
Tested: Reviewed rendered markdown diff for semantic equivalence plus improved stability
Not-tested: No document export/render pipeline executed for this wording-only change
2026-04-17 18:05:05 +08:00
0dd08ec623 Merge PR #13: upgrade redink evidence to full execute closure\n\nConstraint: Keep redink evidence and final summary aligned with the now-verified live execute closure\nConfidence: high\nScope-risk: narrow\nDirective: Remove stale blocker wording immediately once the external dependency closure is verified so handoff docs stay trustworthy\nTested: PR #13 content cross-checked against successful live execute smoke, DB readback, and cleanup results\nNot-tested: No document export/render pipeline executed at merge time 2026-04-17 17:57:42 +08:00
cbedf0aec8 Upgrade redink evidence to full execute closure
This updates the REDINK_RECORD evidence with a successful live execute smoke
run after bringing up business-bank-server locally, and refreshes the final
mainline delivery summary to remove the stale blocker wording.

Constraint: Docs must reflect the newly verified live redink execute closure, not the earlier blocked state
Rejected: Leave the old blocker note in place | factually stale after the successful execute rerun
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: If redink live execute is revalidated again later, append a dated subsection instead of rewriting this successful closure note
Tested: Cross-checked against successful live execute smoke, DB readback, and cleanup results on 2026-04-17
Not-tested: No document export/render pipeline executed for this docs-only refresh
2026-04-17 17:54:37 +08:00
c9b7a135c0 Merge PR #12: refresh REV004 final summary docs-main anchor\n\nConstraint: Keep the final summary internally consistent with current docs mainline\nConfidence: high\nScope-risk: narrow\nDirective: Refresh summary metadata immediately after future summary merges so the handoff page never self-stales\nTested: PR #12 content cross-checked against docs main ab4eec0...\nNot-tested: No document export/render pipeline executed at merge time 2026-04-17 17:38:57 +08:00
6cb590aa13 Refresh REV004 final summary docs-main anchor
This updates the docs-main latest merge anchor inside the REV004 final mainline
summary so the document remains self-consistent after its own merge.

Constraint: The final summary must reference the current docs mainline state, not the pre-summary merge anchor
Rejected: Leave the older docs merge SHA in place | would make the summary internally stale immediately after merge
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Refresh top-level summary anchors whenever the summary itself is merged into main
Tested: Cross-checked against origin/main latest merge ab4eec0...
Not-tested: No document export/render pipeline executed for this one-line metadata refresh
2026-04-17 17:37:42 +08:00
ab4eec0ea8 Merge PR #11: add REV004 final mainline delivery summary\n\nConstraint: Keep the final summary aligned with verified mainline state only\nConfidence: high\nScope-risk: narrow\nDirective: Refresh this summary only when meaningful mainline state changes occur so it remains a stable handoff artifact\nTested: PR #11 summary cross-checked against latest backend/docs mainline commits and evidence set\nNot-tested: No document export/render pipeline executed at merge time 2026-04-17 17:35:36 +08:00
9ac2e9f68e Add REV004 final mainline delivery summary
This adds a one-page summary of the current REV004 mainline delivery state,
including merged backend/docs commits, object truth status, evidence anchors,
and remaining external blockers.

Constraint: Summary must reflect verified mainline truth only, not feature-branch intent
Rejected: Scatter this information across multiple historical evidence files | too costly for frontline consumers to reconstruct delivery status
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep this summary as the top-level operator handoff page and refresh only after meaningful mainline state changes
Tested: Cross-checked against origin/develop and origin/main latest merge commits plus existing evidence set
Not-tested: No document export/render pipeline executed for this summary
2026-04-17 17:33:40 +08:00
415b4cee13 Merge PR #10: land prestorage strict formal-first evidence\n\nConstraint: Preserve reviewed prestorage process/attachments evidence without mixing unrelated docs\nConfidence: high\nScope-risk: narrow\nDirective: Append any future prestorage query verification as follow-up evidence rather than rewriting this closure proof\nTested: PR #10 evidence reviewed against backend PR #80 compile/test/smoke outputs\nNot-tested: No doc export/render pipeline executed at merge time 2026-04-17 17:24:24 +08:00
21aed1f7d7 Capture prestorage strict formal-first evidence for REV004
This records compile/test outputs plus fresh jar smoke proving that
prestorage-process and prestorage-attachments now read formal data first while
retaining fallback behavior.

Constraint: Evidence must stay aligned with the prestorage query-only strict formal-first batch and its application-dev smoke run
Rejected: Fold this note into older prestorage evidence files | reduces traceability for the specific process/attachments closure batch
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Append future prestorage query verification as follow-up evidence rather than overwriting this closure proof
Tested: Cross-checked against backend compile/test output and fresh smoke results on 2026-04-17
Not-tested: No document export/render pipeline executed for this evidence-only commit
2026-04-17 17:20:49 +08:00
89737608b3 Merge PR #9: refresh REV004 current truth matrix with redink\n\nConstraint: Keep the matrix aligned with verified mainline merges only\nConfidence: high\nScope-risk: narrow\nDirective: Refresh this matrix again only after future mainline merges so it stays trustworthy\nTested: PR #9 content cross-checked against backend develop d8596af... and docs main 57763c6...\nNot-tested: No document export/render pipeline executed at merge time 2026-04-17 17:05:58 +08:00
9ca67674a3 Refresh REV004 current truth matrix after redink merge
This updates the current-truth matrix to reflect that REDINK_RECORD is now
an independent formal-table object on the mainline, and refreshes the merge
anchors plus blocker note accordingly.

Constraint: Matrix must match verified mainline truth after PR #79 and docs redink evidence merge
Rejected: Leave REDINK_RECORD as not independent in the matrix | now factually incorrect after mainline merge
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Refresh this matrix only after verified mainline merges so it remains an operator-grade truth artifact
Tested: Cross-checked against origin/develop merge d8596af... and origin/main merge 57763c6...
Not-tested: No document export/render pipeline executed for this matrix refresh
2026-04-17 17:04:02 +08:00
57763c634e Merge PR #8: land REV004 redink evidence\n\nConstraint: Preserve reviewed REDINK_RECORD evidence without mixing unrelated doc drafts\nConfidence: high\nScope-risk: narrow\nDirective: Append a follow-up section when live execute smoke can be rerun with business-bank-server available\nTested: PR #8 evidence reviewed against backend PR #79 verification outputs and blocker trace\nNot-tested: No doc export/render pipeline executed at merge time 2026-04-17 16:56:55 +08:00
f1211d328c Capture redink formal-table dev-db evidence for REV004
This records the application-dev DDL apply/replay, compile and targeted
test evidence, fresh jar query smoke, cleanup proof, and the precise external
blocker observed when attempting live REDINK_RECORD execute smoke.

Constraint: Evidence must reflect the actually verified REDINK_RECORD formal-table scope and explicitly separate completed verification from blocked live-execute proof
Rejected: Present live execute smoke as fully complete | inaccurate because business-bank-server was unavailable
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: When business-bank-server becomes available, append a dated live-execute follow-up section instead of overwriting this baseline evidence
Tested: Cross-checked against backend compile/test outputs, psql results, query smoke, and application log exception trace on 2026-04-17
Not-tested: No document export/render pipeline executed for this evidence-only commit
2026-04-17 16:52:50 +08:00
692ac419f6 Merge PR #7: refresh REV004 current truth matrix\n\nConstraint: Keep the matrix aligned with verified mainline merges only\nConfidence: high\nScope-risk: narrow\nDirective: Refresh this matrix again after future mainline formal-table merges so it remains a reliable operator artifact\nTested: PR #7 content cross-checked against backend develop 1964c782... and docs main c741164...\nNot-tested: No document export/render pipeline executed at merge time 2026-04-17 15:45:14 +08:00
ba58013139 Refresh REV004 current truth matrix after price-diff merge
This updates the REV004 current-truth matrix to reflect that PRICE_DIFF_ADJUST
is now an independent formal-table object on the mainline, and refreshes the
merge/evidence anchors accordingly.

Constraint: Matrix must match current backend develop and docs main truth after PR #78 / docs evidence merge
Rejected: Keep the earlier matrix unchanged | it now incorrectly reports PRICE_DIFF_ADJUST as not independent
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Continue refreshing this matrix only after verified mainline merges, not from feature-branch intent alone
Tested: Cross-checked against origin/develop merge commit 1964c782... and origin/main merge commit c741164...
Not-tested: No document export/render pipeline executed for this matrix refresh
2026-04-17 15:43:50 +08:00
c741164fa4 Merge PR #6: land REV004 price-diff evidence\n\nConstraint: Preserve reviewed PRICE_DIFF_ADJUST evidence without mixing unrelated doc drafts\nConfidence: high\nScope-risk: narrow\nDirective: Keep future price-diff verification updates in follow-up evidence docs or dated append sections\nTested: PR #6 evidence reviewed against backend PR #78 verification outputs\nNot-tested: No doc export/render pipeline executed at merge time 2026-04-17 15:41:02 +08:00
f348481aeb Capture price-diff formal-table dev-db evidence for REV004
This records the application-dev DDL apply/replay, compile and targeted
test evidence, fresh-jar HTTP smoke, DB writeback checks, and cleanup proof
for the PRICE_DIFF_ADJUST formal-table batch.

Constraint: Evidence must stay aligned with the backend price-diff formal-table implementation and application-dev verification run on 2026-04-17
Rejected: Fold this evidence into unrelated doc drafts in the main docs worktree | would mix scopes and weaken traceability
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Append future price-diff reruns as dated subsections or follow-up evidence files instead of overwriting this baseline
Tested: Verified against backend compile/test output and direct psql + fresh-jar smoke results on 2026-04-17
Not-tested: No doc export/render pipeline executed for this evidence-only commit
2026-04-17 15:37:46 +08:00
b5efa3b248 Merge PR #5: land REV004 docs evidence and dict alignment\n\nConstraint: Preserve reviewed REV004 doc evidence and dict-alignment batch without mixing local draft docs\nConfidence: high\nScope-risk: moderate\nDirective: Keep subsequent REV004 evidence/doc updates in separate small PRs for traceability\nTested: PR #5 reviewed content plus latest writtenoff evidence refresh already pushed on branch\nNot-tested: No doc export/render pipeline executed at merge time 2026-04-17 15:01:25 +08:00
29e2ae36a2 Refresh writtenoff formal-table smoke evidence after reliability patch
This updates the REV004 writtenoff evidence with a fresh post-patch smoke run
covering submit, detail/page query, approve/reject, DB writeback, cleanup,
and runtime shutdown on port 48094.

Constraint: Evidence must reflect the final backend patch set actually pushed for PR #77
Rejected: Leave the earlier pre-patch smoke as the last evidence point | weaker proof for the final transaction/fail-fast tightening
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: If writtenoff smoke is rerun again, append a new dated subsection instead of overwriting this verification trail
Tested: Fresh jar smoke on 48094 plus direct psql cleanup/readback verification on 2026-04-17
Not-tested: No separate document export/render pipeline run for this evidence refresh
2026-04-17 14:58:44 +08:00
fccb3a7cf8 Capture writtenoff formal-table dev-db evidence for REV004
This evidence snapshot records the application-dev target database, DDL apply
and replay status, targeted verification commands, fresh-jar smoke outcomes,
and cleanup proof for the writtenoff formal-table batch.

Constraint: Evidence must remain aligned with the backend writtenoff formal-table batch and the actual application-dev database
Rejected: Fold evidence into unrelated doc updates already present in this branch | would mix scopes and obscure traceability
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Update this evidence if later writtenoff smoke is rerun on a different port or with different seeded IDs
Tested: Reviewed against backend compile/test results and direct psql cleanup verification on 2026-04-17
Not-tested: No additional doc rendering/export pipeline run for this evidence-only change
2026-04-17 14:50:06 +08:00
cbecb60aed Record bad-debt formal-table rollout evidence for REV004
This adds the rollout evidence for REV004 bad-debt formal-table work,
covering DDL application, targeted verification, fresh-jar HTTP smoke,
and cleanup proof on the application-dev database.

Constraint: Evidence scope stays limited to bad-debt formal-table rollout and should not absorb unrelated REV004 docs backlog
Rejected: Wait to document until writtenoff/price-diff formalization lands | delays a completed bad-debt evidence slice
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: If later bad-debt semantics expand beyond payState write-back, append a new evidence note instead of rewriting this rollout record
Tested: Evidence content cross-checked against compile/test/DDL/HTTP smoke outputs captured in this session
Not-tested: No doc export/render verification performed
2026-04-17 12:33:27 +08:00
ee78477e8f Record prestorage formal-table rollout evidence for REV004
This documents the prestorage formal-table rollout status, including test DB
DDL application, HTTP smoke evidence, cleanup proof, and the updated
formal-table status matrix for REV004.

Constraint: Documentation must stay scoped to prestorage formal-table evidence and status updates only
Rejected: Fold unrelated REV004 evidence backlog into this commit | would dilute the deliverable and review scope
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: When process/attachments become strict formal-first, update the status matrix and evidence instead of replacing this rollout record
Tested: Evidence file cross-checked against backend compile/test/DB/HTTP smoke outputs
Not-tested: No independent docs rendering/export verification performed
2026-04-17 10:52:11 +08:00
35f2f9b76c Record REV004 late-fee formal-table deployment and canary evidence
This documents that the formal-table deploy SQL has been applied to the
application-dev database, that the previous real-db blocker is resolved,
and that the date-mode late-fee reduce canary now passes against the
test database.

Constraint: Evidence must match the verified dev database and latest canary output
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep evidence updates aligned with the exact environment and command outputs used for verification
Tested: Evidence cross-checked against psql deployment output and fresh canary pass
Not-tested: No additional business flow beyond the documented late-fee date-mode canary
2026-04-15 16:14:03 +08:00
d0ee1cbc17 Align REV004 dictionaries with current interface semantics
Document the minimal dictionary additions and field-binding rules needed to
let REV004 front-end queries and dropdowns use system-managed object and
status semantics while continuing to reuse the existing legacy reason/type
dictionaries.

Constraint: Existing dictionary taxonomy must remain stable for historical pages
Constraint: REV004 needs explicit object/status dictionaries plus a redink reason set for FE binding
Rejected: Rename legacy dictionaries into a new unified taxonomy | too broad for this delivery and risks breaking existing pages
Rejected: Keep object/status values as code-only enums | insufficient for frontend dictionary binding
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: `payment_reason` is only a transitional binding for `WRITTENOFF_ADJUST`; introduce a dedicated writtenoff reason dictionary only when that object stabilizes long-term
Tested: Applied `sql/rev004_account_adjust_dict_seed.sql` to sw_system test DB and verified inserted dict types/data
Not-tested: Frontend page consumption against the new dictionary bindings
2026-04-07 17:53:47 +08:00
9d2ecf1cf6 docs: align planb deployment design with reviewed topology 2026-04-02 17:30:06 +08:00
2a1b9a69b0 merge: planb deployment and pg16 docs 2026-04-02 11:29:03 +08:00
5a1abd4c03 docs: update planb integrated deployment assets 2026-04-01 15:51:07 +08:00
f8b75f7771 docs: import bank api archive and openapi tooling 2026-03-27 10:12:47 +08:00
dc4d2b8655 docs: split plan b deployment guidance from pg16 dr application 2026-03-27 10:12:40 +08:00
5f20c5794c docs: add rev-004 legacy finance migration planning artifacts 2026-03-27 10:12:34 +08:00
327c74c27b docs: align sys-009 design with implementation evidence 2026-03-27 10:12:29 +08:00
eadd91170b docs: refine agent coordination guidance 2026-03-27 10:12:24 +08:00
6538379f1e docs: add speckit workflow and capability map guides 2026-03-27 10:12:14 +08:00
c85550ffde docs: add integrated deployment planb doc and docx 2026-03-26 18:42:53 +08:00
09b8a8e3d9 docs: record Nuoshuitong progress update
Add the Nuoshuitong documentation outputs to the project progress ledger so the documentation lane has a traceable handoff point for review and follow-on implementation work.

Constraint: Keep this update limited to governance tracking for the newly added Nuoshuitong design pack
Confidence: high
Scope-risk: narrow

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 17:51:29 +08:00
3fee9a2c18 docs: add Nuoshuitong integration design pack
Add a Nuoshuitong documentation set covering the implementation checklist, split interface spec notes, normalized enums, and database/DDL guidance so follow-on integration can start from a consistent source of truth.

Constraint: Current phase is documentation-first and must not require backend/frontend code changes
Rejected: Merge the material directly into formal master design docs now | would broaden scope before the integration model and dialect strategy are reviewed
Directive: Treat these guides as integration-layer inputs until they are reconciled with formal technical design masters
Confidence: high
Scope-risk: moderate

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 17:50:46 +08:00
fd8cb6725c Merge pull request 'docs: add pg16 dr resource application doc' (#4) from 011-frontend-speckit-alignment into main
Reviewed-on: #4
2026-03-24 15:57:02 +08:00
ef8834dfb9 docs: add pg16 dr resource application doc 2026-03-24 15:50:36 +08:00
ccc014f15b Merge pull request 'docs: add frontend speckit alignment artifacts' (#3) from 011-frontend-speckit-alignment into main
Reviewed-on: #3
2026-03-24 14:13:31 +08:00
63abce712e docs: add frontend speckit alignment artifacts 2026-03-24 14:01:49 +08:00
8baf5bc3d6 Merge pull request 'docs: finalize 010 bank transfer config' (#2) from docs-010-bank-transfer-config into main
Reviewed-on: #2
2026-03-24 12:12:55 +08:00
09b955d0ac docs: finalize 010 bank transfer config 2026-03-24 12:04:39 +08:00
210 changed files with 41550 additions and 61 deletions

View File

@ -1,6 +1,42 @@
# CLAUDE.md
本文件用于指导 Claude Code 在本仓库中的工作方式。
本文件用于指导 Claude Code 及通用代码代理(包括 Codex 类代理)在本仓库中的工作方式。
## Workspace Coordination
本仓库现在是 `water-workspace` 下的文档总控仓,默认作为正式规格、计划、任务、验收与治理台账的单一入口。
### 邻接仓库
- `../water-backend/`:后端实现仓,默认主开发分支为 `develop`
- `../water-frontend/`:前端实现仓,默认主开发分支为 `develop`
### 启动规则
- 需要运行 `/speckit.specify``/speckit.plan``/speckit.tasks`、正式文档修订、治理台账更新、验收结论汇总时,必须从 `water-docs` 根目录启动代理。
- 需要检查正式规格、计划、任务、基线、evidence 时,以 `water-docs/specs/``water-docs/docs/` 为准。
- 未经用户明确要求,不在本仓库直接修改 `../water-backend/``../water-frontend/` 中的业务代码。
### 多仓协作规则
- 本仓库中的 `.specify/` 是唯一正式流程入口backend/frontend 不复制第二套 `.specify/`
- backend/frontend 仓内实现结论,必须回写到本仓库的正式文档或 `specs/` 工件,不能仅停留在代码仓口头说明。
- 重要 feature 默认记录代码基线:
- backend commit SHA
- frontend commit SHA
- 验证日期
### Worktree 约定
- 推荐在 `../worktrees/` 下按 feature 建立平铺 worktree
- `docs-<feature>`
- `backend-<feature>`
- `frontend-<feature>`
- `verify-<feature>`
- 文档 lane 只改 `water-docs`
- backend lane 只改 `water-backend`
- frontend lane 只改 `water-frontend`
- verify lane 负责样本、日志、验收结论和基线固定
## 项目定位
@ -20,14 +56,17 @@
```text
/
├── docs/design/00_Management/ # 项目管理、进度跟踪、交付规范、编写指南
├── docs/design/01_Overview/ # 总体设计:系统概述、系统架构、概要设计、系统图谱
├── docs/design/02_Detailed_Design/ # 详细设计主详设、模块设计、CA 安装设计
├── docs/design/03_Technical_Design/ # 技术专项:数据库、表结构、接口、安全、部署、加密
├── docs/design/04_Appendix/ # 附录与归档资料
├── assets/ # 图片、模板等静态资源
├── docs/ # 研究资料、映射文档、使用指南
├── scripts/ # 文档处理与导出脚本
└── infra/ # 辅助基础设施
├── docs/design/01_Overview/ # 总体设计:系统概述、系统架构、概要设计、系统图谱
├── docs/design/02_Detailed_Design/ # 详细设计主详设、模块设计、CA 安装设计
├── docs/design/03_Technical_Design/ # 技术专项:数据库、表结构、接口、安全、部署、加密
├── docs/design/04_Appendix/ # 附录与归档资料
├── .claude/ # Claude Code 相关配置
├── .omc/ # 项目记忆与代理状态
├── .zed/ # Zed 项目配置
├── assets/ # 图片、模板等静态资源
├── docs/ # 研究资料、映射文档、使用指南
├── scripts/ # 文档处理与导出脚本
└── infra/ # 辅助基础设施
```
## 当前文档组织原则
@ -193,6 +232,9 @@ make export-word
make export-pdf
make export-html
make unified-export
npm run check:marksman
npm run marksman:help
npm run marksman:server
```
如仅改动单篇文档,优先使用较小范围校验,而不是每次都跑全量导出。
@ -256,11 +298,13 @@ make unified-export
- 归档整理与信息整编助手
- 基于现有资料进行保守补完的编辑者
不是:
不是:
- 擅自扩展需求的产品经理
- 无依据发明实现细节的方案生成器
- 动辄新建文件的“版本制造机”
- 动辄新建文件的”版本制造机”
本文件用于指导通用代码代理(包括 Codex 类代理)在本仓库中的工作方式。
## 最终目标

View File

@ -1,7 +1,7 @@
# 福建水务营收系统概要设计文档 Makefile
# Version: 1.0
.PHONY: help init create validate export clean install-deps check-links check-mermaid validate-mermaid count-mermaid check-mermaid-file merge-docs check-ai-governance archive-tag-index ai-audit-diff
.PHONY: help init create validate export clean install-deps check-links check-mermaid validate-mermaid count-mermaid check-mermaid-file merge-docs check-ai-governance archive-tag-index ai-audit-diff smoke-sftp smoke-ftp
# 默认目标
help:
@ -23,6 +23,8 @@ help:
@echo " check-ai-governance 检查AI文档治理基线"
@echo " archive-tag-index 生成 Archive 标签索引"
@echo " ai-audit-diff 生成 AI 抽检差异清单"
@echo " smoke-sftp 调用 Java smoke CLI 连接 Docker SFTP 容器"
@echo " smoke-ftp 调用 Java smoke CLI 连接 Docker FTP 容器"
@echo " count-mermaid 统计mermaid图表数量"
@echo " check-mermaid-file 检测指定文件中的mermaid图表 (使用 FILE=文件名)"
@echo " merge-docs 合并所有文档"
@ -48,6 +50,8 @@ help:
@echo " make check-ai-governance # 检查AI文档治理基线"
@echo " make archive-tag-index # 生成 Archive 标签索引"
@echo " make ai-audit-diff # 生成 AI 抽检差异清单"
@echo " make smoke-sftp # 运行 Docker SFTP smoke"
@echo " make smoke-ftp # 运行 Docker FTP smoke"
@echo " make check-mermaid-file FILE=新-概要设计说明书.md"
@echo " make export-word # 导出Word文档"
@echo " make export-pdf # 导出PDF文档"
@ -136,6 +140,14 @@ ai-audit-diff:
@echo "生成 AI 抽检差异清单..."
@./scripts/ai-weekly-audit-diff.sh
smoke-sftp:
@echo "运行 Docker SFTP smoke..."
@./scripts/run-bank-transfer-smoke.sh sftp
smoke-ftp:
@echo "运行 Docker FTP smoke..."
@./scripts/run-bank-transfer-smoke.sh ftp
# 检测所有markdown文件中的mermaid图表
check-mermaid:
@echo "检测所有markdown文件中的mermaid图表..."

View File

@ -18,9 +18,11 @@
## 推荐阅读顺序
1. `guides/BACKEND_CURRENT_STATUS.md`
2. `guides/BACKEND_TABLE_MAPPING.md`
3. 其他辅助资料
1. `guides/SPECKIT_WORKFLOW_HUMAN_GUIDE.md`
2. `guides/SYSTEM_CAPABILITY_CLOSURE_MAP.md`
3. `guides/BACKEND_CURRENT_STATUS.md`
4. `guides/BACKEND_TABLE_MAPPING.md`
5. 其他辅助资料
## 维护原则

View File

@ -0,0 +1,96 @@
# 营收系统银行缴费接口文档
本目录包含营收系统与银行/第三方支付机构之间的接口 OpenAPI 规范文档。
## 目录结构
```
docs/api/openapi/
├── main/
│ ├── openapi.yaml # OpenAPI 3.0.3 主文档入口
│ ├── components/ # 可复用组件定义
│ │ ├── schemas.yaml # 数据模型定义
│ │ ├── responses.yaml # 响应定义
│ │ ├── parameters.yaml # 参数定义
│ │ ├── headers.yaml # 头部定义
│ │ ├── security.yaml # 安全定义
│ │ └── index.yaml # 组件索引
│ └── paths/ # API 路径定义
│ ├── bill-query.yaml # 账单查询
│ ├── bill-pay.yaml # 账单缴费
│ ├── pay-invalid.yaml # 账单红冲
│ ├── withholding-signing.yaml # 代扣签约
│ ├── withholding-termination.yaml # 代扣解约
│ ├── withholding-send-disc.yaml # 代扣送盘
│ └── withholding-back-disc.yaml # 代扣回盘
├── generated/ # 生成的代码(保留参考)
├── validate.js # 文档验证脚本
└── serve.js # 本地预览服务器
scripts/api-tools/
└── validate-all.js # 批量验证工具
```
## 接口清单
| 接口名称 | 路径 | 交易码 | 描述 |
|---------|------|--------|------|
| 账单查询 | `/api/app/payCeb/getChargeSearch` | Query/QueryRes | 查询客户账单信息 |
| 账单缴费 | `/api/app/payCeb/getChargeOffs` | Pay/PayRes | 处理账单缴费 |
| 账单红冲 | `/api/app/payInvalid/payInvalid` | PayInvalid/PayInvalidRes | 红冲缴费记录 |
| 代扣签约 | `/api/app/bankWithholding/signing` | Signing/SigningRes | 银行代扣签约 |
| 代扣解约 | `/api/app/bankWithholding/termination` | Termination/TerminationRes | 银行代扣解约 |
| 代扣送盘 | `/api/app/bankWithholding/sendDisc` | SendDisc/SendDiscRes | 批量代扣送盘 |
| 代扣回盘 | `/api/app/bankWithholding/backDisc` | BackDisc/BackDiscRes | 接收银行回盘 |
## 核心特性
### 数据格式支持
- **XML格式**GBK编码符合传统银行系统规范
- **JSON格式**UTF-8编码适合现代化系统集成
- **双格式支持**同时支持XML和JSON请求响应
### 安全加密
- **3DES加密**ECB模式PKCS7填充默认
- **SM2加密**支持C1C3C2和C1C2C3模式
- **SM4加密**支持ECB和CBC模式
- **Base64编码**加密后数据进行Base64编码传输
## 使用指南
### 1. 验证文档
```bash
cd docs/api/openapi
node validate.js
```
### 2. 启动本地预览服务
```bash
cd docs/api/openapi
node serve.js
```
访问 http://localhost:3000 查看 API 文档
### 3. 导入到开发工具
#### Swagger Editor
1. 打开 [Swagger Editor](https://editor.swagger.io/)
2. 导入 `docs/api/openapi/main/openapi.yaml` 文件
#### Postman
1. 打开 Postman
2. 点击 Import
3. 选择 `docs/api/openapi/main/openapi.yaml` 文件导入
## 相关文档
- [接口规范设计文档](../../design/04_Appendix/Archive/银行缴费接口规范设计文档.md)
- [接口说明文档](../../design/04_Appendix/Archive/银行缴费接口说明.md)
- [主接口设计文档](../../design/03_Technical_Design/03_Interface_Design.md)
## 来源
本文档从 `water-bank-api-doc` 仓库迁移而来,原始文档基于营收系统缴费接口规范 v1.5。

View File

@ -0,0 +1,32 @@
components:
headers:
# 响应内容类型
ContentType:
description: 响应内容类型
schema:
type: string
enum:
- "application/xml; charset=GBK"
- "application/json; charset=UTF-8"
# 响应时间戳
ResponseTime:
description: 服务端响应时间戳
schema:
type: string
format: date-time
example: "2024-01-01T12:00:00.000Z"
# 请求追踪ID
RequestId:
description: 请求追踪标识
schema:
type: string
example: "req_123456789012"
# 服务版本
ServiceVersion:
description: 服务端版本号
schema:
type: string
example: "1.0.1"

View File

@ -0,0 +1,288 @@
components:
# 数据模型
schemas:
# 基础请求模型
BaseRequest:
type: object
required:
- Version
- InstId
- TranCode
- TranDate
- TranSeq
properties:
Version:
type: string
description: 版本号
example: "1.0.1"
InstId:
type: string
description: 机构编码
example: "00001"
maxLength: 30
TranCode:
type: string
description: 交易码
example: "Query"
maxLength: 20
TranDate:
type: string
description: 交易日期
pattern: '^\d{8}$'
example: "20240101"
TranSeq:
type: string
description: 交易流水号(银行生成的唯一标识)
example: "123456789012"
maxLength: 40
# 基础响应模型
BaseResponse:
type: object
required:
- Version
- InstId
- TranCode
- TranDate
- TranSeq
- RespCode
- RespMessage
properties:
Version:
type: string
description: 版本号
example: "1.0.1"
InstId:
type: string
description: 机构编码
example: "00001"
TranCode:
type: string
description: 交易码
example: "QueryRes"
TranDate:
type: string
description: 交易日期
pattern: '^\d{8}$'
example: "20240101"
TranSeq:
type: string
description: 交易流水号
example: "123456789012"
RespCode:
type: string
description: 返回码
enum:
- "AAAAAAA" # 成功
- "DEF0001" # 无相应记录
- "DEF0002" # 缴费金额不匹配
- "SYS1001" # 系统异常
- "SEC2001" # 加密错误
example: "AAAAAAA"
RespMessage:
type: string
description: 返回消息
example: "成功"
maxLength: 60
# 错误详情
ErrorDetail:
type: object
properties:
ErrorCode:
type: string
description: 错误码
example: "DEF0001"
ErrorMsg:
type: string
description: 错误消息
example: "用户编号123456不存在"
ErrorTime:
type: string
format: date-time
description: 错误时间
example: "2024-01-01T12:00:00.000Z"
# 其他数据模型引用原有文件
BillQueryRequest:
$ref: './schemas.yaml#/components/schemas/BillQueryRequest'
BillQueryResponse:
$ref: './schemas.yaml#/components/schemas/BillQueryResponse'
BillPayRequest:
$ref: './schemas.yaml#/components/schemas/BillPayRequest'
BillPayResponse:
$ref: './schemas.yaml#/components/schemas/BillPayResponse'
# 响应组件
responses:
# 业务错误响应
BusinessError:
description: 业务处理错误
content:
application/xml:
schema:
allOf:
- $ref: '#/components/schemas/BaseResponse'
- type: object
properties:
ErrorDetail:
$ref: '#/components/schemas/ErrorDetail'
application/json:
schema:
allOf:
- $ref: '#/components/schemas/BaseResponse'
- type: object
properties:
ErrorDetail:
$ref: '#/components/schemas/ErrorDetail'
# 系统错误响应
SystemError:
description: 系统异常错误
content:
application/xml:
schema:
allOf:
- $ref: '#/components/schemas/BaseResponse'
- type: object
properties:
ErrorDetail:
$ref: '#/components/schemas/ErrorDetail'
application/json:
schema:
allOf:
- $ref: '#/components/schemas/BaseResponse'
- type: object
properties:
ErrorDetail:
$ref: '#/components/schemas/ErrorDetail'
# 安全错误响应
SecurityError:
description: 安全验证错误
content:
application/xml:
schema:
allOf:
- $ref: '#/components/schemas/BaseResponse'
- type: object
properties:
ErrorDetail:
$ref: '#/components/schemas/ErrorDetail'
application/json:
schema:
allOf:
- $ref: '#/components/schemas/BaseResponse'
- type: object
properties:
ErrorDetail:
$ref: '#/components/schemas/ErrorDetail'
# 网络错误响应
NetworkError:
description: 网络通信错误
content:
application/xml:
schema:
allOf:
- $ref: '#/components/schemas/BaseResponse'
- type: object
properties:
ErrorDetail:
$ref: '#/components/schemas/ErrorDetail'
application/json:
schema:
allOf:
- $ref: '#/components/schemas/BaseResponse'
- type: object
properties:
ErrorDetail:
$ref: '#/components/schemas/ErrorDetail'
# 参数组件
parameters:
ContentTypeHeader:
name: Content-Type
in: header
required: true
description: 请求内容类型
schema:
type: string
enum:
- application/xml
- application/json
example: "application/xml"
EncryptTypeHeader:
name: X-Encrypt-Type
in: header
required: false
description: 加密算法类型
schema:
type: string
enum:
- "3DES"
- "SM2"
- "SM4"
example: "3DES"
EncryptModeHeader:
name: X-Encrypt-Mode
in: header
required: false
description: 加密模式
schema:
type: string
enum:
- "ECB"
- "CBC"
example: "ECB"
DataTypeHeader:
name: X-Data-Type
in: header
required: false
description: 数据格式类型
schema:
type: string
enum:
- "XML"
- "JSON"
example: "XML"
# 响应头组件
headers:
ContentType:
description: 响应内容类型
schema:
type: string
example: "application/xml; charset=GBK"
ResponseTime:
description: 响应时间(毫秒)
schema:
type: integer
example: 150
RequestId:
description: 请求唯一标识
schema:
type: string
example: "req-123456789012"
# 安全认证组件
securitySchemes:
ApiKeyAuth:
type: apiKey
in: header
name: X-API-Key
description: API密钥认证
EncryptedData:
type: http
scheme: bearer
bearerFormat: encrypted
description: 加密数据传输认证

View File

@ -0,0 +1,67 @@
components:
parameters:
# 内容类型参数
ContentTypeHeader:
name: Content-Type
in: header
required: true
description: 内容类型
schema:
type: string
enum:
- "application/xml; charset=GBK"
- "application/json; charset=UTF-8"
default: "application/xml; charset=GBK"
# 加密类型参数
EncryptTypeHeader:
name: EncryptType
in: header
required: false
description: 加密类型
schema:
type: string
enum:
- "3DES"
- "SM2"
- "SM4"
example: "3DES"
# 加密模式参数
EncryptModeHeader:
name: EncryptMode
in: header
required: false
description: 加密模式
schema:
type: string
enum:
- "ECB"
- "CBC"
- "C1C3C2"
- "C1C2C3"
example: "ECB"
# 数据类型参数
DataTypeHeader:
name: DataType
in: header
required: false
description: 数据类型
schema:
type: string
enum:
- "XML"
- "JSON"
example: "XML"
# 版本号参数
VersionParam:
name: version
in: query
required: false
description: API版本号
schema:
type: string
default: "1.0.1"
example: "1.0.1"

View File

@ -0,0 +1,227 @@
components:
responses:
# 成功响应
Success:
description: 操作成功
content:
application/xml:
schema:
$ref: './schemas.yaml#/components/schemas/BaseResponse'
example: |
<?xml version="1.0" encoding="GBK"?>
<out>
<Version>1.0.1</Version>
<InstId>00001</InstId>
<TranCode>QueryRes</TranCode>
<TranDate>20240101</TranDate>
<TranSeq>123456789012</TranSeq>
<RespCode>AAAAAAA</RespCode>
<RespMessage>成功</RespMessage>
</out>
application/json:
schema:
$ref: './schemas.yaml#/components/schemas/BaseResponse'
example:
Version: "1.0.1"
InstId: "00001"
TranCode: "QueryRes"
TranDate: "20240101"
TranSeq: "123456789012"
RespCode: "AAAAAAA"
RespMessage: "成功"
# 业务错误响应
BusinessError:
description: 业务处理错误
content:
application/xml:
schema:
allOf:
- $ref: './schemas.yaml#/components/schemas/BaseResponse'
- type: object
properties:
ErrorDetail:
$ref: './schemas.yaml#/components/schemas/ErrorDetail'
example: |
<?xml version="1.0" encoding="GBK"?>
<out>
<Version>1.0.1</Version>
<InstId>00001</InstId>
<TranCode>QueryRes</TranCode>
<TranDate>20240101</TranDate>
<TranSeq>123456789012</TranSeq>
<RespCode>DEF0001</RespCode>
<RespMessage>无相应记录</RespMessage>
<ErrorDetail>
<ErrorCode>DEF0001</ErrorCode>
<ErrorMsg>用户编号123456不存在</ErrorMsg>
<ErrorTime>2024-01-01 12:00:00</ErrorTime>
</ErrorDetail>
</out>
application/json:
schema:
allOf:
- $ref: './schemas.yaml#/components/schemas/BaseResponse'
- type: object
properties:
ErrorDetail:
$ref: './schemas.yaml#/components/schemas/ErrorDetail'
example:
Version: "1.0.1"
InstId: "00001"
TranCode: "QueryRes"
TranDate: "20240101"
TranSeq: "123456789012"
RespCode: "DEF0001"
RespMessage: "无相应记录"
ErrorDetail:
ErrorCode: "DEF0001"
ErrorMsg: "用户编号123456不存在"
ErrorTime: "2024-01-01T12:00:00.000Z"
# 系统错误响应
SystemError:
description: 系统异常错误
content:
application/xml:
schema:
allOf:
- $ref: './schemas.yaml#/components/schemas/BaseResponse'
- type: object
properties:
ErrorDetail:
$ref: './schemas.yaml#/components/schemas/ErrorDetail'
example: |
<?xml version="1.0" encoding="GBK"?>
<out>
<Version>1.0.1</Version>
<InstId>00001</InstId>
<TranCode>QueryRes</TranCode>
<TranDate>20240101</TranDate>
<TranSeq>123456789012</TranSeq>
<RespCode>SYS1001</RespCode>
<RespMessage>系统异常</RespMessage>
<ErrorDetail>
<ErrorCode>SYS1001</ErrorCode>
<ErrorMsg>数据库连接失败</ErrorMsg>
<ErrorTime>2024-01-01 12:00:00</ErrorTime>
</ErrorDetail>
</out>
application/json:
schema:
allOf:
- $ref: './schemas.yaml#/components/schemas/BaseResponse'
- type: object
properties:
ErrorDetail:
$ref: './schemas.yaml#/components/schemas/ErrorDetail'
example:
Version: "1.0.1"
InstId: "00001"
TranCode: "QueryRes"
TranDate: "20240101"
TranSeq: "123456789012"
RespCode: "SYS1001"
RespMessage: "系统异常"
ErrorDetail:
ErrorCode: "SYS1001"
ErrorMsg: "数据库连接失败"
ErrorTime: "2024-01-01T12:00:00.000Z"
# 安全错误响应
SecurityError:
description: 安全验证错误
content:
application/xml:
schema:
allOf:
- $ref: './schemas.yaml#/components/schemas/BaseResponse'
- type: object
properties:
ErrorDetail:
$ref: './schemas.yaml#/components/schemas/ErrorDetail'
example: |
<?xml version="1.0" encoding="GBK"?>
<out>
<Version>1.0.1</Version>
<InstId>00001</InstId>
<TranCode>QueryRes</TranCode>
<TranDate>20240101</TranDate>
<TranSeq>123456789012</TranSeq>
<RespCode>SEC2001</RespCode>
<RespMessage>加密验证失败</RespMessage>
<ErrorDetail>
<ErrorCode>SEC2001</ErrorCode>
<ErrorMsg>数据解密失败</ErrorMsg>
<ErrorTime>2024-01-01 12:00:00</ErrorTime>
</ErrorDetail>
</out>
application/json:
schema:
allOf:
- $ref: './schemas.yaml#/components/schemas/BaseResponse'
- type: object
properties:
ErrorDetail:
$ref: './schemas.yaml#/components/schemas/ErrorDetail'
example:
Version: "1.0.1"
InstId: "00001"
TranCode: "QueryRes"
TranDate: "20240101"
TranSeq: "123456789012"
RespCode: "SEC2001"
RespMessage: "加密验证失败"
ErrorDetail:
ErrorCode: "SEC2001"
ErrorMsg: "数据解密失败"
ErrorTime: "2024-01-01T12:00:00.000Z"
# 网络错误响应
NetworkError:
description: 网络通信错误
content:
application/xml:
schema:
allOf:
- $ref: './schemas.yaml#/components/schemas/BaseResponse'
- type: object
properties:
ErrorDetail:
$ref: './schemas.yaml#/components/schemas/ErrorDetail'
example: |
<?xml version="1.0" encoding="GBK"?>
<out>
<Version>1.0.1</Version>
<InstId>00001</InstId>
<TranCode>QueryRes</TranCode>
<TranDate>20240101</TranDate>
<TranSeq>123456789012</TranSeq>
<RespCode>NET3001</RespCode>
<RespMessage>网络超时</RespMessage>
<ErrorDetail>
<ErrorCode>NET3001</ErrorCode>
<ErrorMsg>请求超时,请稍后重试</ErrorMsg>
<ErrorTime>2024-01-01 12:00:00</ErrorTime>
</ErrorDetail>
</out>
application/json:
schema:
allOf:
- $ref: './schemas.yaml#/components/schemas/BaseResponse'
- type: object
properties:
ErrorDetail:
$ref: './schemas.yaml#/components/schemas/ErrorDetail'
example:
Version: "1.0.1"
InstId: "00001"
TranCode: "QueryRes"
TranDate: "20240101"
TranSeq: "123456789012"
RespCode: "NET3001"
RespMessage: "网络超时"
ErrorDetail:
ErrorCode: "NET3001"
ErrorMsg: "请求超时,请稍后重试"
ErrorTime: "2024-01-01T12:00:00.000Z"

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,42 @@
components:
securitySchemes:
# API密钥认证
ApiKeyAuth:
type: apiKey
in: header
name: X-API-Key
description: API密钥认证
# 加密数据认证
EncryptedData:
type: apiKey
in: header
name: X-Encrypted-Data
description: |
加密数据认证方式,支持以下加密算法:
- 3DES: 使用3DES ECB模式PKCS7填充
- SM2: 使用SM2非对称加密支持C1C3C2和C1C2C3模式
- SM4: 使用SM4对称加密支持ECB和CBC模式
加密后的数据需要进行Base64编码传输。
# 机构认证
InstAuth:
type: http
scheme: basic
description: 机构编码认证基于HTTP Basic Auth
# 数字签名认证
DigitalSign:
type: apiKey
in: header
name: X-Digital-Sign
description: |
数字签名认证,使用以下方式:
1. 将请求数据按指定规则排序
2. 使用指定密钥进行签名
3. 将签名结果Base64编码后放入请求头
支持的签名算法:
- SHA256withRSA
- SM3withSM2

View File

@ -0,0 +1,381 @@
openapi: 3.0.3
info:
title: 营收系统接口API
description: |
营收系统与银行/第三方支付机构之间的接口交互API文档
## 特性
- 支持账单查询、缴费、红冲等核心功能
- 支持银行代扣签约、解约、送盘、回盘
- 支持XML和JSON两种数据格式
- 支持多种加密算法3DES、SM2、SM4
- 统一错误码和响应格式
## 安全认证
本API使用多种加密方式保证数据安全传输
- 数据加密后Base64编码传输
- 支持3DES、SM2、SM4等加密算法
- 通过请求头指定加密类型和模式
version: 1.0.0
contact:
name: 营收系统API支持
email: support@billing-system.com
license:
name: 专有许可证
servers:
- url: https://api.billing-system.com
description: 生产环境
- url: https://test-api.billing-system.com
description: 测试环境
- url: https://dev-api.billing-system.com
description: 开发环境
tags:
- name: 账单管理
description: 账单查询、缴费、红冲相关接口
- name: 代扣管理
description: 银行代扣签约、解约、送盘、回盘相关接口
paths:
# 账单查询
/api/app/payCeb/getChargeSearch:
$ref: './paths/bill-query.yaml#/BillQuery'
# 账单缴费
/api/app/payCeb/getChargeOffs:
$ref: './paths/bill-pay.yaml#/BillPay'
# 账单红冲
/api/app/payInvalid/payInvalid:
$ref: './paths/pay-invalid.yaml#/PayInvalid'
# 代扣签约
/api/app/bankWithholding/signing:
$ref: './paths/withholding-signing.yaml#/WithholdingSigning'
# 代扣解约
/api/app/bankWithholding/termination:
$ref: './paths/withholding-termination.yaml#/WithholdingTermination'
# 代扣送盘
/api/app/bankWithholding/sendDisc:
$ref: './paths/withholding-send-disc.yaml#/WithholdingSendDisc'
# 代扣回盘
/api/app/bankWithholding/backDisc:
$ref: './paths/withholding-back-disc.yaml#/WithholdingBackDisc'
# 对账接口
/api/app/payCeb/paymentCheck:
$ref: './paths/payment-check.yaml#/PaymentCheck'
# 取消代扣交易
/api/app/bankWithholding/cancelDisc:
$ref: './paths/withholding-cancel-disc.yaml#/WithholdingCancelDisc'
# 代扣送盘状态查询
/api/app/bankWithholding/sendDiscCheck:
$ref: './paths/withholding-send-disc-check.yaml#/WithholdingSendDiscCheck'
# 代扣回盘状态查询
/api/app/bankWithholding/backDiscCheck:
$ref: './paths/withholding-back-disc-check.yaml#/WithholdingBackDiscCheck'
# 客户基本信息查询
/api/app/customer/check:
$ref: './paths/customer-check.yaml#/CustomerCheck'
components:
# 数据模型
schemas:
# 基础请求模型
BaseRequest:
type: object
required:
- Version
- InstId
- TranCode
- TranDate
- TranSeq
properties:
Version:
type: string
description: 版本号
example: "1.0.1"
InstId:
type: string
description: 机构编码
example: "00001"
maxLength: 30
TranCode:
type: string
description: 交易码
example: "Query"
maxLength: 20
TranDate:
type: string
description: 交易日期
pattern: '^\d{8}$'
example: "20240101"
TranSeq:
type: string
description: 交易流水号(银行生成的唯一标识)
example: "123456789012"
maxLength: 40
# 基础响应模型
BaseResponse:
type: object
required:
- Version
- InstId
- TranCode
- TranDate
- TranSeq
- RespCode
- RespMessage
properties:
Version:
type: string
description: 版本号
example: "1.0.1"
InstId:
type: string
description: 机构编码
example: "00001"
TranCode:
type: string
description: 交易码
example: "QueryRes"
TranDate:
type: string
description: 交易日期
pattern: '^\d{8}$'
example: "20240101"
TranSeq:
type: string
description: 交易流水号
example: "123456789012"
RespCode:
type: string
description: 返回码
enum:
- "AAAAAAA" # 成功
- "DEF0001" # 无相应记录
- "DEF0002" # 缴费金额不匹配
- "SYS1001" # 系统异常
- "SEC2001" # 加密错误
example: "AAAAAAA"
RespMessage:
type: string
description: 返回消息
example: "成功"
maxLength: 60
# 错误详情
ErrorDetail:
type: object
properties:
ErrorCode:
type: string
description: 错误码
example: "DEF0001"
ErrorMsg:
type: string
description: 错误消息
example: "用户编号123456不存在"
ErrorTime:
type: string
format: date-time
description: 错误时间
example: "2024-01-01T12:00:00.000Z"
# 其他数据模型引用原有文件
BillQueryRequest:
$ref: './components/schemas.yaml#/components/schemas/BillQueryRequest'
BillQueryResponse:
$ref: './components/schemas.yaml#/components/schemas/BillQueryResponse'
BillPayRequest:
$ref: './components/schemas.yaml#/components/schemas/BillPayRequest'
BillPayResponse:
$ref: './components/schemas.yaml#/components/schemas/BillPayResponse'
# 响应组件
responses:
# 业务错误响应
BusinessError:
description: 业务处理错误
content:
application/xml:
schema:
allOf:
- $ref: '#/components/schemas/BaseResponse'
- type: object
properties:
ErrorDetail:
$ref: '#/components/schemas/ErrorDetail'
application/json:
schema:
allOf:
- $ref: '#/components/schemas/BaseResponse'
- type: object
properties:
ErrorDetail:
$ref: '#/components/schemas/ErrorDetail'
# 系统错误响应
SystemError:
description: 系统异常错误
content:
application/xml:
schema:
allOf:
- $ref: '#/components/schemas/BaseResponse'
- type: object
properties:
ErrorDetail:
$ref: '#/components/schemas/ErrorDetail'
application/json:
schema:
allOf:
- $ref: '#/components/schemas/BaseResponse'
- type: object
properties:
ErrorDetail:
$ref: '#/components/schemas/ErrorDetail'
# 安全错误响应
SecurityError:
description: 安全验证错误
content:
application/xml:
schema:
allOf:
- $ref: '#/components/schemas/BaseResponse'
- type: object
properties:
ErrorDetail:
$ref: '#/components/schemas/ErrorDetail'
application/json:
schema:
allOf:
- $ref: '#/components/schemas/BaseResponse'
- type: object
properties:
ErrorDetail:
$ref: '#/components/schemas/ErrorDetail'
# 网络错误响应
NetworkError:
description: 网络通信错误
content:
application/xml:
schema:
allOf:
- $ref: '#/components/schemas/BaseResponse'
- type: object
properties:
ErrorDetail:
$ref: '#/components/schemas/ErrorDetail'
application/json:
schema:
allOf:
- $ref: '#/components/schemas/BaseResponse'
- type: object
properties:
ErrorDetail:
$ref: '#/components/schemas/ErrorDetail'
# 参数组件
parameters:
ContentTypeHeader:
name: Content-Type
in: header
required: true
description: 请求内容类型
schema:
type: string
enum:
- application/xml
- application/json
example: "application/xml"
EncryptTypeHeader:
name: X-Encrypt-Type
in: header
required: false
description: 加密算法类型
schema:
type: string
enum:
- "3DES"
- "SM2"
- "SM4"
example: "3DES"
EncryptModeHeader:
name: X-Encrypt-Mode
in: header
required: false
description: 加密模式
schema:
type: string
enum:
- "ECB"
- "CBC"
example: "ECB"
DataTypeHeader:
name: X-Data-Type
in: header
required: false
description: 数据格式类型
schema:
type: string
enum:
- "XML"
- "JSON"
example: "XML"
# 响应头组件
headers:
ContentType:
description: 响应内容类型
schema:
type: string
example: "application/xml; charset=GBK"
ResponseTime:
description: 响应时间(毫秒)
schema:
type: integer
example: 150
RequestId:
description: 请求唯一标识
schema:
type: string
example: "req-123456789012"
# 安全认证组件
securitySchemes:
ApiKeyAuth:
type: apiKey
in: header
name: X-API-Key
description: API密钥认证
EncryptedData:
type: http
scheme: bearer
bearerFormat: encrypted
description: 加密数据传输认证
security:
- ApiKeyAuth: []
- EncryptedData: []

View File

@ -0,0 +1,140 @@
BillPay:
post:
tags:
- 账单管理
summary: 账单缴费
description: |
执行账单缴费操作,支持多种支付渠道。
## 业务说明
- 支持指定客户编号和缴费金额进行缴费
- 支持多种二级支付渠道(支付宝、微信等)
- 实时更新账单状态和生成交易记录
- 支持XML和JSON两种数据格式
- 缴费金额必须与账单金额完全匹配
## 业务规则
- 缴费金额必须大于0.01元
- 账单状态必须为未缴费状态
- 同一笔账单不能重复缴费
- 缴费成功后账单状态自动更新为已缴费
## 调用频率限制
- 单个客户编号每分钟最多缴费5次
- 单个机构每分钟最多缴费500次
operationId: payBill
parameters:
- $ref: '../components/parameters.yaml#/components/parameters/ContentTypeHeader'
- $ref: '../components/parameters.yaml#/components/parameters/EncryptTypeHeader'
- $ref: '../components/parameters.yaml#/components/parameters/EncryptModeHeader'
- $ref: '../components/parameters.yaml#/components/parameters/DataTypeHeader'
requestBody:
required: true
description: 账单缴费请求数据
content:
application/xml:
schema:
$ref: '../components/schemas.yaml#/components/schemas/BillPayRequest'
example: |
<?xml version="1.0" encoding="GBK"?>
<in>
<Version>1.0.1</Version>
<InstId>00001</InstId>
<TranCode>Pay</TranCode>
<TranDate>20240101</TranDate>
<TranSeq>123456789012</TranSeq>
<BillKey>123456</BillKey>
<CompanyId>654321</CompanyId>
<PayAmount>150.00</PayAmount>
<SubChannel>1</SubChannel>
</in>
application/json:
schema:
$ref: '../components/schemas.yaml#/components/schemas/BillPayRequest'
example:
Version: "1.0.1"
InstId: "00001"
TranCode: "Pay"
TranDate: "20240101"
TranSeq: "123456789012"
BillKey: "123456"
CompanyId: "654321"
PayAmount: 150.00
SubChannel: 1
responses:
'200':
description: 缴费成功
headers:
Content-Type:
$ref: '../components/headers.yaml#/components/headers/ContentType'
X-Response-Time:
$ref: '../components/headers.yaml#/components/headers/ResponseTime'
X-Request-Id:
$ref: '../components/headers.yaml#/components/headers/RequestId'
content:
application/xml:
schema:
$ref: '../components/schemas.yaml#/components/schemas/BillPayResponse'
example: |
<?xml version="1.0" encoding="GBK"?>
<out>
<Version>1.0.1</Version>
<InstId>00001</InstId>
<TranCode>PayRes</TranCode>
<TranDate>20240101</TranDate>
<TranSeq>123456789012</TranSeq>
<RespCode>AAAAAAA</RespCode>
<RespMessage>缴费成功</RespMessage>
<Data>
<Transaction>
<TranSeq>TXN123456789012</TranSeq>
<BillKey>123456</BillKey>
<CompanyId>654321</CompanyId>
<TranCode>Pay</TranCode>
<PayAmount>150.00</PayAmount>
<PayDate>2024-01-01T12:00:00.000Z</PayDate>
<SubChannel>1</SubChannel>
<TranStatus>1</TranStatus>
<RespCode>AAAAAAA</RespCode>
<RespMessage>成功</RespMessage>
</Transaction>
</Data>
</out>
application/json:
schema:
$ref: '../components/schemas.yaml#/components/schemas/BillPayResponse'
example:
Version: "1.0.1"
InstId: "00001"
TranCode: "PayRes"
TranDate: "20240101"
TranSeq: "123456789012"
RespCode: "AAAAAAA"
RespMessage: "缴费成功"
Data:
Transaction:
TranSeq: "TXN123456789012"
BillKey: "123456"
CompanyId: "654321"
TranCode: "Pay"
PayAmount: 150.00
PayDate: "2024-01-01T12:00:00.000Z"
SubChannel: 1
TranStatus: 1
RespCode: "AAAAAAA"
RespMessage: "成功"
'400':
$ref: '../components/responses.yaml#/components/responses/BusinessError'
'500':
$ref: '../components/responses.yaml#/components/responses/SystemError'
'401':
$ref: '../components/responses.yaml#/components/responses/SecurityError'
'408':
$ref: '../components/responses.yaml#/components/responses/NetworkError'
security:
- ApiKeyAuth: []
- EncryptedData: []

View File

@ -0,0 +1,136 @@
BillQuery:
post:
tags:
- 账单管理
summary: 账单查询
description: |
根据客户编号查询账单信息,包括客户基本信息和账单详情。
## 业务说明
- 支持根据客户编号(缴费号)查询账单
- 返回客户基本信息和未缴费账单列表
- 支持XML和JSON两种数据格式
- 数据传输支持多种加密方式
## 调用频率限制
- 单个客户编号每分钟最多查询10次
- 单个机构每分钟最多查询1000次
operationId: queryBill
parameters:
- $ref: '../components/parameters.yaml#/components/parameters/ContentTypeHeader'
- $ref: '../components/parameters.yaml#/components/parameters/EncryptTypeHeader'
- $ref: '../components/parameters.yaml#/components/parameters/EncryptModeHeader'
- $ref: '../components/parameters.yaml#/components/parameters/DataTypeHeader'
requestBody:
required: true
description: 账单查询请求数据
content:
application/xml:
schema:
$ref: '../components/schemas.yaml#/components/schemas/BillQueryRequest'
example: |
<?xml version="1.0" encoding="GBK"?>
<in>
<Version>1.0.1</Version>
<InstId>00001</InstId>
<TranCode>Query</TranCode>
<TranDate>20240101</TranDate>
<TranSeq>123456789012</TranSeq>
<BillKey>123456</BillKey>
<CompanyId>654321</CompanyId>
</in>
application/json:
schema:
$ref: '../components/schemas.yaml#/components/schemas/BillQueryRequest'
example:
Version: "1.0.1"
InstId: "00001"
TranCode: "Query"
TranDate: "20240101"
TranSeq: "123456789012"
BillKey: "123456"
CompanyId: "654321"
responses:
'200':
description: 查询成功
headers:
Content-Type:
$ref: '../components/headers.yaml#/components/headers/ContentType'
X-Response-Time:
$ref: '../components/headers.yaml#/components/headers/ResponseTime'
X-Request-Id:
$ref: '../components/headers.yaml#/components/headers/RequestId'
content:
application/xml:
schema:
$ref: '../components/schemas.yaml#/components/schemas/BillQueryResponse'
example: |
<?xml version="1.0" encoding="GBK"?>
<out>
<Version>1.0.1</Version>
<InstId>00001</InstId>
<TranCode>QueryRes</TranCode>
<TranDate>20240101</TranDate>
<TranSeq>123456789012</TranSeq>
<RespCode>AAAAAAA</RespCode>
<RespMessage>成功</RespMessage>
<Data>
<Customer>
<BillKey>123456</BillKey>
<CustomerName>张三</CustomerName>
<ContractNo>CONTRACT001</ContractNo>
<CompanyId>654321</CompanyId>
</Customer>
<Bills>
<Bill>
<BillKey>123456</BillKey>
<CompanyId>654321</CompanyId>
<PayAmount>150.00</PayAmount>
<Balance>0.00</Balance>
<BeginDate>2024-01-01</BeginDate>
<EndDate>2024-01-31</EndDate>
<BillStatus>0</BillStatus>
</Bill>
</Bills>
</Data>
</out>
application/json:
schema:
$ref: '../components/schemas.yaml#/components/schemas/BillQueryResponse'
example:
Version: "1.0.1"
InstId: "00001"
TranCode: "QueryRes"
TranDate: "20240101"
TranSeq: "123456789012"
RespCode: "AAAAAAA"
RespMessage: "成功"
Data:
Customer:
BillKey: "123456"
CustomerName: "张三"
ContractNo: "CONTRACT001"
CompanyId: "654321"
Bills:
- BillKey: "123456"
CompanyId: "654321"
PayAmount: 150.00
Balance: 0.00
BeginDate: "2024-01-01"
EndDate: "2024-01-31"
BillStatus: 0
'400':
$ref: '../components/responses.yaml#/components/responses/BusinessError'
'500':
$ref: '../components/responses.yaml#/components/responses/SystemError'
'401':
$ref: '../components/responses.yaml#/components/responses/SecurityError'
'408':
$ref: '../components/responses.yaml#/components/responses/NetworkError'
security:
- ApiKeyAuth: []
- EncryptedData: []

View File

@ -0,0 +1,107 @@
CustomerCheck:
post:
tags:
- 账单管理
summary: 客户基本信息查询
description: |
银行向公用事业单位发起的客户基本信息查询请求接口。
用于查询客户的基本信息,包括客户姓名、联系方式、地址等详细信息。
## 交易码说明
- 请求交易码CustomerCheck
- 应答交易码CustomerCheckRes
## 查询信息包括
- 客户基本信息:姓名、身份证号等
- 客户联系信息:电话、地址等
- 客户状态信息:账户状态、服务状态等
- 历史缴费记录摘要
## 使用场景
- 客户信息核验
- 代扣协议签约前的客户信息确认
- 客户服务和支持
- 风险评估和反欺诈检查
operationId: customerCheck
parameters:
- $ref: '../components/parameters.yaml#/components/parameters/ContentTypeHeader'
- $ref: '../components/parameters.yaml#/components/parameters/EncryptTypeHeader'
- $ref: '../components/parameters.yaml#/components/parameters/EncryptModeHeader'
- $ref: '../components/parameters.yaml#/components/parameters/DataTypeHeader'
requestBody:
required: true
content:
application/xml:
schema:
$ref: '../components/schemas.yaml#/components/schemas/CustomerCheckRequest'
example: |
<?xml version="1.0" encoding="GBK"?>
<in>
<Version>1.0.1</Version>
<InstId>00001</InstId>
<TranCode>CustomerCheck</TranCode>
<TranDate>20240101</TranDate>
<TranSeq>123456789012</TranSeq>
<billKey>123456</billKey>
<companyId>654321</companyId>
<queryType>0</queryType>
<contractNo>CONTRACT001</contractNo>
<filed1></filed1>
<filed2></filed2>
</in>
application/json:
schema:
$ref: '../components/schemas.yaml#/components/schemas/CustomerCheckRequest'
responses:
'200':
description: 客户基本信息查询成功
headers:
Content-Type:
$ref: '../components/headers.yaml#/components/headers/ContentType'
X-Response-Time:
$ref: '../components/headers.yaml#/components/headers/ResponseTime'
X-Request-Id:
$ref: '../components/headers.yaml#/components/headers/RequestId'
content:
application/xml:
schema:
$ref: '../components/schemas.yaml#/components/schemas/CustomerCheckResponse'
example: |
<?xml version="1.0" encoding="GBK"?>
<out>
<Version>1.0.1</Version>
<InstId>00001</InstId>
<TranCode>CustomerCheckRes</TranCode>
<TranDate>20240101</TranDate>
<TranSeq>123456789012</TranSeq>
<RespCode>AAAAAAA</RespCode>
<RespMessage>查询成功</RespMessage>
<billKey>123456</billKey>
<companyId>654321</companyId>
<contractNo>CONTRACT001</contractNo>
<customerName>张三</customerName>
<customerPhone>13812345678</customerPhone>
<customerAddress>北京市朝阳区xxx街道xxx号</customerAddress>
<customerStatus>1</customerStatus>
<serviceStatus>1</serviceStatus>
<registerDate>20200101</registerDate>
<lastPayDate>20231215</lastPayDate>
<totalPayCount>36</totalPayCount>
<totalPayAmount>540000</totalPayAmount>
<filed1></filed1>
<filed2></filed2>
<filed3></filed3>
</out>
application/json:
schema:
$ref: '../components/schemas.yaml#/components/schemas/CustomerCheckResponse'
'400':
$ref: '../components/responses.yaml#/components/responses/BusinessError'
'500':
$ref: '../components/responses.yaml#/components/responses/SystemError'
'403':
$ref: '../components/responses.yaml#/components/responses/SecurityError'
security:
- ApiKeyAuth: []
- EncryptedData: []

View File

@ -0,0 +1,192 @@
PayInvalid:
post:
tags:
- 账单管理
summary: 账单红冲
description: |
对已缴费的账单进行红冲(撤销)操作。
## 业务说明
- 支持对已缴费账单进行红冲操作
- 红冲后账单状态恢复为未缴费
- 生成红冲交易记录
- 支持XML和JSON两种数据格式
## 业务规则
- 只能对已缴费的账单进行红冲
- 红冲金额必须与原缴费金额一致
- 同一笔缴费记录只能红冲一次
- 红冲成功后生成负数交易记录
## 调用频率限制
- 单个交易流水号每分钟最多红冲1次
- 单个机构每分钟最多红冲100次
operationId: invalidPayment
parameters:
- $ref: '../components/parameters.yaml#/components/parameters/ContentTypeHeader'
- $ref: '../components/parameters.yaml#/components/parameters/EncryptTypeHeader'
- $ref: '../components/parameters.yaml#/components/parameters/EncryptModeHeader'
- $ref: '../components/parameters.yaml#/components/parameters/DataTypeHeader'
requestBody:
required: true
description: 账单红冲请求数据
content:
application/xml:
schema:
allOf:
- $ref: '../components/schemas.yaml#/components/schemas/BaseRequest'
- type: object
required:
- OriginalTranSeq
- BillKey
- CompanyId
properties:
OriginalTranSeq:
type: string
description: 原交易流水号
example: "TXN123456789012"
maxLength: 40
BillKey:
type: string
description: 客户编号
example: "123456"
maxLength: 35
CompanyId:
type: string
description: 机构编码
example: "654321"
maxLength: 30
example: |
<?xml version="1.0" encoding="GBK"?>
<in>
<Version>1.0.1</Version>
<InstId>00001</InstId>
<TranCode>PayInvalid</TranCode>
<TranDate>20240101</TranDate>
<TranSeq>123456789013</TranSeq>
<OriginalTranSeq>TXN123456789012</OriginalTranSeq>
<BillKey>123456</BillKey>
<CompanyId>654321</CompanyId>
</in>
application/json:
schema:
allOf:
- $ref: '../components/schemas.yaml#/components/schemas/BaseRequest'
- type: object
required:
- OriginalTranSeq
- BillKey
- CompanyId
properties:
OriginalTranSeq:
type: string
description: 原交易流水号
example: "TXN123456789012"
BillKey:
type: string
description: 客户编号
example: "123456"
CompanyId:
type: string
description: 机构编码
example: "654321"
example:
Version: "1.0.1"
InstId: "00001"
TranCode: "PayInvalid"
TranDate: "20240101"
TranSeq: "123456789013"
OriginalTranSeq: "TXN123456789012"
BillKey: "123456"
CompanyId: "654321"
responses:
'200':
description: 红冲成功
headers:
Content-Type:
$ref: '../components/headers.yaml#/components/headers/ContentType'
X-Response-Time:
$ref: '../components/headers.yaml#/components/headers/ResponseTime'
X-Request-Id:
$ref: '../components/headers.yaml#/components/headers/RequestId'
content:
application/xml:
schema:
allOf:
- $ref: '../components/schemas.yaml#/components/schemas/BaseResponse'
- type: object
properties:
Data:
type: object
properties:
Transaction:
$ref: '../components/schemas.yaml#/components/schemas/Transaction'
example: |
<?xml version="1.0" encoding="GBK"?>
<out>
<Version>1.0.1</Version>
<InstId>00001</InstId>
<TranCode>PayInvalidRes</TranCode>
<TranDate>20240101</TranDate>
<TranSeq>123456789013</TranSeq>
<RespCode>AAAAAAA</RespCode>
<RespMessage>红冲成功</RespMessage>
<Data>
<Transaction>
<TranSeq>REV123456789013</TranSeq>
<BillKey>123456</BillKey>
<CompanyId>654321</CompanyId>
<TranCode>PayInvalid</TranCode>
<PayAmount>-150.00</PayAmount>
<PayDate>2024-01-01T12:00:00.000Z</PayDate>
<TranStatus>1</TranStatus>
<RespCode>AAAAAAA</RespCode>
<RespMessage>成功</RespMessage>
</Transaction>
</Data>
</out>
application/json:
schema:
allOf:
- $ref: '../components/schemas.yaml#/components/schemas/BaseResponse'
- type: object
properties:
Data:
type: object
properties:
Transaction:
$ref: '../components/schemas.yaml#/components/schemas/Transaction'
example:
Version: "1.0.1"
InstId: "00001"
TranCode: "PayInvalidRes"
TranDate: "20240101"
TranSeq: "123456789013"
RespCode: "AAAAAAA"
RespMessage: "红冲成功"
Data:
Transaction:
TranSeq: "REV123456789013"
BillKey: "123456"
CompanyId: "654321"
TranCode: "PayInvalid"
PayAmount: -150.00
PayDate: "2024-01-01T12:00:00.000Z"
TranStatus: 1
RespCode: "AAAAAAA"
RespMessage: "成功"
'400':
$ref: '../components/responses.yaml#/components/responses/BusinessError'
'500':
$ref: '../components/responses.yaml#/components/responses/SystemError'
'401':
$ref: '../components/responses.yaml#/components/responses/SecurityError'
'408':
$ref: '../components/responses.yaml#/components/responses/NetworkError'
security:
- ApiKeyAuth: []
- EncryptedData: []

View File

@ -0,0 +1,92 @@
PaymentCheck:
post:
tags:
- 账单管理
summary: 缴费单对账
description: |
代理收费向公用事业单位发起的缴费单对账请求接口。
由代理收费公司每天日切后,进行批处理,自动生成和传送对账文件给公用事业单位。
## 交易码说明
- 请求交易码PayCheck
- 应答交易码PayCheckRes
## 对账文件格式
对账文件为文本文件txt格式编码格式为UTF-8包括明细行和汇总行。
行内每个分项之间以"|"为分隔符。
### 汇总行格式
`交易笔数|总金额`
### 明细行格式
`交易日期|交易流水号|客户编号|缴费金额|二级渠道|交易类型`
operationId: paymentCheck
parameters:
- $ref: '../components/parameters.yaml#/components/parameters/ContentTypeHeader'
- $ref: '../components/parameters.yaml#/components/parameters/EncryptTypeHeader'
- $ref: '../components/parameters.yaml#/components/parameters/EncryptModeHeader'
- $ref: '../components/parameters.yaml#/components/parameters/DataTypeHeader'
requestBody:
required: true
content:
application/xml:
schema:
$ref: '../components/schemas.yaml#/components/schemas/PaymentCheckRequest'
example: |
<?xml version="1.0" encoding="GBK"?>
<in>
<Version>1.0.1</Version>
<InstId>00001</InstId>
<TranCode>PayCheck</TranCode>
<TranDate>20240101</TranDate>
<TranSeq>123456789012</TranSeq>
<companyId>654321</companyId>
<payDate>20240101</payDate>
<payCount>10</payCount>
<payMoney>150000</payMoney>
<fileName>654321_20240101.txt</fileName>
</in>
application/json:
schema:
$ref: '../components/schemas.yaml#/components/schemas/PaymentCheckRequest'
responses:
'200':
description: 对账成功
headers:
Content-Type:
$ref: '../components/headers.yaml#/components/headers/ContentType'
X-Response-Time:
$ref: '../components/headers.yaml#/components/headers/ResponseTime'
X-Request-Id:
$ref: '../components/headers.yaml#/components/headers/RequestId'
content:
application/xml:
schema:
$ref: '../components/schemas.yaml#/components/schemas/PaymentCheckResponse'
example: |
<?xml version="1.0" encoding="GBK"?>
<out>
<Version>1.0.1</Version>
<InstId>00001</InstId>
<TranCode>PayCheckRes</TranCode>
<TranDate>20240101</TranDate>
<TranSeq>123456789012</TranSeq>
<RespCode>AAAAAAA</RespCode>
<RespMessage>对账成功</RespMessage>
<companyId>654321</companyId>
<payDate>20240101</payDate>
<payAmount>150000</payAmount>
</out>
application/json:
schema:
$ref: '../components/schemas.yaml#/components/schemas/PaymentCheckResponse'
'400':
$ref: '../components/responses.yaml#/components/responses/BusinessError'
'500':
$ref: '../components/responses.yaml#/components/responses/SystemError'
'403':
$ref: '../components/responses.yaml#/components/responses/SecurityError'
security:
- ApiKeyAuth: []
- EncryptedData: []

View File

@ -0,0 +1,104 @@
WithholdingBackDiscCheck:
post:
tags:
- 代扣管理
summary: 代扣回盘状态查询
description: |
银行向公用事业单位发起的代扣回盘状态查询请求接口。
用于查询已发起的代扣回盘交易的当前处理状态。
## 交易码说明
- 请求交易码BackDiscCheck
- 应答交易码BackDiscCheckRes
## 查询状态说明
- 0: 待处理
- 1: 处理中
- 2: 处理成功
- 3: 处理失败
- 4: 已取消
## 使用场景
- 银行系统需要确认回盘交易状态
- 处理异常情况的状态核查
- 定时批量状态查询
- 对账和清算流程中的状态确认
operationId: withholdingBackDiscCheck
parameters:
- $ref: '../components/parameters.yaml#/components/parameters/ContentTypeHeader'
- $ref: '../components/parameters.yaml#/components/parameters/EncryptTypeHeader'
- $ref: '../components/parameters.yaml#/components/parameters/EncryptModeHeader'
- $ref: '../components/parameters.yaml#/components/parameters/DataTypeHeader'
requestBody:
required: true
content:
application/xml:
schema:
$ref: '../components/schemas.yaml#/components/schemas/WithholdingBackDiscCheckRequest'
example: |
<?xml version="1.0" encoding="GBK"?>
<in>
<Version>1.0.1</Version>
<InstId>00001</InstId>
<TranCode>BackDiscCheck</TranCode>
<TranDate>20240101</TranDate>
<TranSeq>123456789012</TranSeq>
<billKey>123456</billKey>
<companyId>654321</companyId>
<originalTranSeq>ORIG123456789012</originalTranSeq>
<originalTranDate>20240101</originalTranDate>
<contractNo>CONTRACT001</contractNo>
<batchNo>BATCH20240101001</batchNo>
</in>
application/json:
schema:
$ref: '../components/schemas.yaml#/components/schemas/WithholdingBackDiscCheckRequest'
responses:
'200':
description: 代扣回盘状态查询成功
headers:
Content-Type:
$ref: '../components/headers.yaml#/components/headers/ContentType'
X-Response-Time:
$ref: '../components/headers.yaml#/components/headers/ResponseTime'
X-Request-Id:
$ref: '../components/headers.yaml#/components/headers/RequestId'
content:
application/xml:
schema:
$ref: '../components/schemas.yaml#/components/schemas/WithholdingBackDiscCheckResponse'
example: |
<?xml version="1.0" encoding="GBK"?>
<out>
<Version>1.0.1</Version>
<InstId>00001</InstId>
<TranCode>BackDiscCheckRes</TranCode>
<TranDate>20240101</TranDate>
<TranSeq>123456789012</TranSeq>
<RespCode>AAAAAAA</RespCode>
<RespMessage>查询成功</RespMessage>
<billKey>123456</billKey>
<companyId>654321</companyId>
<originalTranSeq>ORIG123456789012</originalTranSeq>
<discStatus>2</discStatus>
<discStatusDesc>处理成功</discStatusDesc>
<discTime>20240101120000</discTime>
<payAmount>15000</payAmount>
<actualPayAmount>15000</actualPayAmount>
<batchNo>BATCH20240101001</batchNo>
<clearingDate>20240102</clearingDate>
<failReason></failReason>
</out>
application/json:
schema:
$ref: '../components/schemas.yaml#/components/schemas/WithholdingBackDiscCheckResponse'
'400':
$ref: '../components/responses.yaml#/components/responses/BusinessError'
'500':
$ref: '../components/responses.yaml#/components/responses/SystemError'
'403':
$ref: '../components/responses.yaml#/components/responses/SecurityError'
security:
- ApiKeyAuth: []
- EncryptedData: []

View File

@ -0,0 +1,334 @@
WithholdingBackDisc:
post:
tags:
- 代扣管理
summary: 代扣回盘
description: |
银行代扣回盘接口,接收银行返回的代扣结果。
## 业务说明
- 接收银行处理代扣送盘后的结果反馈
- 包含每笔代扣的成功或失败信息
- 根据回盘结果更新账单和交易状态
- 支持XML和JSON两种数据格式
- 自动处理代扣成功和失败的业务逻辑
## 业务规则
- 回盘数据必须与送盘数据对应
- 成功的代扣自动更新账单状态为已缴费
- 失败的代扣保持原账单状态
- 生成相应的交易记录和状态
## 调用频率限制
- 单个批次只能回盘一次
- 支持银行异步回盘处理
operationId: withholdingBackDisc
parameters:
- $ref: '../components/parameters.yaml#/components/parameters/ContentTypeHeader'
- $ref: '../components/parameters.yaml#/components/parameters/EncryptTypeHeader'
- $ref: '../components/parameters.yaml#/components/parameters/EncryptModeHeader'
- $ref: '../components/parameters.yaml#/components/parameters/DataTypeHeader'
requestBody:
required: true
description: 代扣回盘请求数据
content:
application/xml:
schema:
allOf:
- $ref: '../components/schemas.yaml#/components/schemas/BaseRequest'
- type: object
required:
- BatchNo
- TotalCount
- SuccessCount
- FailCount
- ResultList
properties:
BatchNo:
type: string
description: 原送盘批次号
example: "BATCH20240101001"
maxLength: 50
TotalCount:
type: integer
description: 总笔数
example: 2
minimum: 1
SuccessCount:
type: integer
description: 成功笔数
example: 1
minimum: 0
FailCount:
type: integer
description: 失败笔数
example: 1
minimum: 0
ResultList:
type: array
description: 代扣结果列表
items:
type: object
required:
- BillKey
- CompanyId
- AgreementNo
- PayAmount
- ResultCode
- ResultMessage
properties:
BillKey:
type: string
description: 客户编号
example: "123456"
CompanyId:
type: string
description: 机构编码
example: "654321"
AgreementNo:
type: string
description: 协议号
example: "AGR001"
PayAmount:
type: number
format: decimal
description: 代扣金额
example: 150.00
ResultCode:
type: string
description: 代扣结果码
enum: ["SUCCESS", "FAIL"]
example: "SUCCESS"
ResultMessage:
type: string
description: 代扣结果信息
example: "代扣成功"
FailReason:
type: string
description: 失败原因结果为FAIL时必填
example: "余额不足"
example: |
<?xml version="1.0" encoding="GBK"?>
<in>
<Version>1.0.1</Version>
<InstId>00001</InstId>
<TranCode>BackDisc</TranCode>
<TranDate>20240101</TranDate>
<TranSeq>123456789017</TranSeq>
<BatchNo>BATCH20240101001</BatchNo>
<TotalCount>2</TotalCount>
<SuccessCount>1</SuccessCount>
<FailCount>1</FailCount>
<ResultList>
<Result>
<BillKey>123456</BillKey>
<CompanyId>654321</CompanyId>
<AgreementNo>AGR001</AgreementNo>
<PayAmount>150.00</PayAmount>
<ResultCode>SUCCESS</ResultCode>
<ResultMessage>代扣成功</ResultMessage>
</Result>
<Result>
<BillKey>123457</BillKey>
<CompanyId>654321</CompanyId>
<AgreementNo>AGR002</AgreementNo>
<PayAmount>150.00</PayAmount>
<ResultCode>FAIL</ResultCode>
<ResultMessage>代扣失败</ResultMessage>
<FailReason>余额不足</FailReason>
</Result>
</ResultList>
</in>
application/json:
schema:
allOf:
- $ref: '../components/schemas.yaml#/components/schemas/BaseRequest'
- type: object
required:
- BatchNo
- TotalCount
- SuccessCount
- FailCount
- ResultList
properties:
BatchNo:
type: string
description: 原送盘批次号
example: "BATCH20240101001"
TotalCount:
type: integer
description: 总笔数
example: 2
SuccessCount:
type: integer
description: 成功笔数
example: 1
FailCount:
type: integer
description: 失败笔数
example: 1
ResultList:
type: array
description: 代扣结果列表
items:
type: object
properties:
BillKey:
type: string
description: 客户编号
example: "123456"
CompanyId:
type: string
description: 机构编码
example: "654321"
AgreementNo:
type: string
description: 协议号
example: "AGR001"
PayAmount:
type: number
format: decimal
description: 代扣金额
example: 150.00
ResultCode:
type: string
description: 代扣结果码
example: "SUCCESS"
ResultMessage:
type: string
description: 代扣结果信息
example: "代扣成功"
FailReason:
type: string
description: 失败原因
example: "余额不足"
example:
Version: "1.0.1"
InstId: "00001"
TranCode: "BackDisc"
TranDate: "20240101"
TranSeq: "123456789017"
BatchNo: "BATCH20240101001"
TotalCount: 2
SuccessCount: 1
FailCount: 1
ResultList:
- BillKey: "123456"
CompanyId: "654321"
AgreementNo: "AGR001"
PayAmount: 150.00
ResultCode: "SUCCESS"
ResultMessage: "代扣成功"
- BillKey: "123457"
CompanyId: "654321"
AgreementNo: "AGR002"
PayAmount: 150.00
ResultCode: "FAIL"
ResultMessage: "代扣失败"
FailReason: "余额不足"
responses:
'200':
description: 回盘处理成功
headers:
Content-Type:
$ref: '../components/headers.yaml#/components/headers/ContentType'
X-Response-Time:
$ref: '../components/headers.yaml#/components/headers/ResponseTime'
X-Request-Id:
$ref: '../components/headers.yaml#/components/headers/RequestId'
content:
application/xml:
schema:
allOf:
- $ref: '../components/schemas.yaml#/components/schemas/BaseResponse'
- type: object
properties:
Data:
type: object
properties:
BatchNo:
type: string
description: 批次号
example: "BATCH20240101001"
ProcessedCount:
type: integer
description: 已处理笔数
example: 2
UpdatedBills:
type: integer
description: 更新账单数
example: 1
CreatedTransactions:
type: integer
description: 创建交易数
example: 2
example: |
<?xml version="1.0" encoding="GBK"?>
<out>
<Version>1.0.1</Version>
<InstId>00001</InstId>
<TranCode>BackDiscRes</TranCode>
<TranDate>20240101</TranDate>
<TranSeq>123456789017</TranSeq>
<RespCode>AAAAAAA</RespCode>
<RespMessage>回盘处理成功</RespMessage>
<Data>
<BatchNo>BATCH20240101001</BatchNo>
<ProcessedCount>2</ProcessedCount>
<UpdatedBills>1</UpdatedBills>
<CreatedTransactions>2</CreatedTransactions>
</Data>
</out>
application/json:
schema:
allOf:
- $ref: '../components/schemas.yaml#/components/schemas/BaseResponse'
- type: object
properties:
Data:
type: object
properties:
BatchNo:
type: string
description: 批次号
example: "BATCH20240101001"
ProcessedCount:
type: integer
description: 已处理笔数
example: 2
UpdatedBills:
type: integer
description: 更新账单数
example: 1
CreatedTransactions:
type: integer
description: 创建交易数
example: 2
example:
Version: "1.0.1"
InstId: "00001"
TranCode: "BackDiscRes"
TranDate: "20240101"
TranSeq: "123456789017"
RespCode: "AAAAAAA"
RespMessage: "回盘处理成功"
Data:
BatchNo: "BATCH20240101001"
ProcessedCount: 2
UpdatedBills: 1
CreatedTransactions: 2
'400':
$ref: '../components/responses.yaml#/components/responses/BusinessError'
'500':
$ref: '../components/responses.yaml#/components/responses/SystemError'
'401':
$ref: '../components/responses.yaml#/components/responses/SecurityError'
'408':
$ref: '../components/responses.yaml#/components/responses/NetworkError'
security:
- ApiKeyAuth: []
- EncryptedData: []

View File

@ -0,0 +1,96 @@
WithholdingCancelDisc:
post:
tags:
- 代扣管理
summary: 取消代扣交易
description: |
银行向公用事业单位发起的取消代扣交易请求接口。
用于取消已经发起但尚未完成的代扣交易。
## 交易码说明
- 请求交易码CancelDisc
- 应答交易码CancelDiscRes
## 使用场景
- 代扣交易发起后,用户要求取消
- 代扣交易异常需要撤销
- 银行系统故障需要回滚交易
## 注意事项
- 只能取消当天发起的代扣交易
- 已经成功扣款的交易不能取消,需要通过退款流程处理
- 取消成功后,相关的代扣协议仍然有效
operationId: withholdingCancelDisc
parameters:
- $ref: '../components/parameters.yaml#/components/parameters/ContentTypeHeader'
- $ref: '../components/parameters.yaml#/components/parameters/EncryptTypeHeader'
- $ref: '../components/parameters.yaml#/components/parameters/EncryptModeHeader'
- $ref: '../components/parameters.yaml#/components/parameters/DataTypeHeader'
requestBody:
required: true
content:
application/xml:
schema:
$ref: '../components/schemas.yaml#/components/schemas/WithholdingCancelDiscRequest'
example: |
<?xml version="1.0" encoding="GBK"?>
<in>
<Version>1.0.1</Version>
<InstId>00001</InstId>
<TranCode>CancelDisc</TranCode>
<TranDate>20240101</TranDate>
<TranSeq>123456789012</TranSeq>
<billKey>123456</billKey>
<companyId>654321</companyId>
<originalTranSeq>ORIG123456789012</originalTranSeq>
<originalTranDate>20240101</originalTranDate>
<cancelReason>用户申请取消</cancelReason>
<contractNo>CONTRACT001</contractNo>
<payAmount>15000</payAmount>
</in>
application/json:
schema:
$ref: '../components/schemas.yaml#/components/schemas/WithholdingCancelDiscRequest'
responses:
'200':
description: 取消代扣交易成功
headers:
Content-Type:
$ref: '../components/headers.yaml#/components/headers/ContentType'
X-Response-Time:
$ref: '../components/headers.yaml#/components/headers/ResponseTime'
X-Request-Id:
$ref: '../components/headers.yaml#/components/headers/RequestId'
content:
application/xml:
schema:
$ref: '../components/schemas.yaml#/components/schemas/WithholdingCancelDiscResponse'
example: |
<?xml version="1.0" encoding="GBK"?>
<out>
<Version>1.0.1</Version>
<InstId>00001</InstId>
<TranCode>CancelDiscRes</TranCode>
<TranDate>20240101</TranDate>
<TranSeq>123456789012</TranSeq>
<RespCode>AAAAAAA</RespCode>
<RespMessage>取消代扣交易成功</RespMessage>
<billKey>123456</billKey>
<companyId>654321</companyId>
<originalTranSeq>ORIG123456789012</originalTranSeq>
<cancelStatus>1</cancelStatus>
<cancelTime>20240101120000</cancelTime>
</out>
application/json:
schema:
$ref: '../components/schemas.yaml#/components/schemas/WithholdingCancelDiscResponse'
'400':
$ref: '../components/responses.yaml#/components/responses/BusinessError'
'500':
$ref: '../components/responses.yaml#/components/responses/SystemError'
'403':
$ref: '../components/responses.yaml#/components/responses/SecurityError'
security:
- ApiKeyAuth: []
- EncryptedData: []

View File

@ -0,0 +1,99 @@
WithholdingSendDiscCheck:
post:
tags:
- 代扣管理
summary: 代扣送盘状态查询
description: |
银行向公用事业单位发起的代扣送盘状态查询请求接口。
用于查询已发起的代扣送盘交易的当前处理状态。
## 交易码说明
- 请求交易码SendDiscCheck
- 应答交易码SendDiscCheckRes
## 查询状态说明
- 0: 待处理
- 1: 处理中
- 2: 处理成功
- 3: 处理失败
- 4: 已取消
## 使用场景
- 银行系统需要确认送盘交易状态
- 处理异常情况的状态核查
- 定时批量状态查询
operationId: withholdingSendDiscCheck
parameters:
- $ref: '../components/parameters.yaml#/components/parameters/ContentTypeHeader'
- $ref: '../components/parameters.yaml#/components/parameters/EncryptTypeHeader'
- $ref: '../components/parameters.yaml#/components/parameters/EncryptModeHeader'
- $ref: '../components/parameters.yaml#/components/parameters/DataTypeHeader'
requestBody:
required: true
content:
application/xml:
schema:
$ref: '../components/schemas.yaml#/components/schemas/WithholdingSendDiscCheckRequest'
example: |
<?xml version="1.0" encoding="GBK"?>
<in>
<Version>1.0.1</Version>
<InstId>00001</InstId>
<TranCode>SendDiscCheck</TranCode>
<TranDate>20240101</TranDate>
<TranSeq>123456789012</TranSeq>
<billKey>123456</billKey>
<companyId>654321</companyId>
<originalTranSeq>ORIG123456789012</originalTranSeq>
<originalTranDate>20240101</originalTranDate>
<contractNo>CONTRACT001</contractNo>
</in>
application/json:
schema:
$ref: '../components/schemas.yaml#/components/schemas/WithholdingSendDiscCheckRequest'
responses:
'200':
description: 代扣送盘状态查询成功
headers:
Content-Type:
$ref: '../components/headers.yaml#/components/headers/ContentType'
X-Response-Time:
$ref: '../components/headers.yaml#/components/headers/ResponseTime'
X-Request-Id:
$ref: '../components/headers.yaml#/components/headers/RequestId'
content:
application/xml:
schema:
$ref: '../components/schemas.yaml#/components/schemas/WithholdingSendDiscCheckResponse'
example: |
<?xml version="1.0" encoding="GBK"?>
<out>
<Version>1.0.1</Version>
<InstId>00001</InstId>
<TranCode>SendDiscCheckRes</TranCode>
<TranDate>20240101</TranDate>
<TranSeq>123456789012</TranSeq>
<RespCode>AAAAAAA</RespCode>
<RespMessage>查询成功</RespMessage>
<billKey>123456</billKey>
<companyId>654321</companyId>
<originalTranSeq>ORIG123456789012</originalTranSeq>
<discStatus>2</discStatus>
<discStatusDesc>处理成功</discStatusDesc>
<discTime>20240101120000</discTime>
<payAmount>15000</payAmount>
<failReason></failReason>
</out>
application/json:
schema:
$ref: '../components/schemas.yaml#/components/schemas/WithholdingSendDiscCheckResponse'
'400':
$ref: '../components/responses.yaml#/components/responses/BusinessError'
'500':
$ref: '../components/responses.yaml#/components/responses/SystemError'
'403':
$ref: '../components/responses.yaml#/components/responses/SecurityError'
security:
- ApiKeyAuth: []
- EncryptedData: []

View File

@ -0,0 +1,287 @@
WithholdingSendDisc:
post:
tags:
- 代扣管理
summary: 代扣送盘
description: |
银行代扣送盘接口,向银行发送批量代扣请求。
## 业务说明
- 支持批量向银行发送代扣请求
- 包含待代扣的账单信息和客户信息
- 支持本行和他行账户代扣
- 送盘成功后等待银行回盘确认
- 支持XML和JSON两种数据格式
## 业务规则
- 只能对已签约且有效的协议进行代扣
- 代扣金额必需与账单金额一致
- 客户账户余额必须充足
- 送盘成功后生成代扣交易记录
## 调用频率限制
- 单个批次最多包含1000笔代扣
- 单个机构每小时最多送盘10次
operationId: withholdingSendDisc
parameters:
- $ref: '../components/parameters.yaml#/components/parameters/ContentTypeHeader'
- $ref: '../components/parameters.yaml#/components/parameters/EncryptTypeHeader'
- $ref: '../components/parameters.yaml#/components/parameters/EncryptModeHeader'
- $ref: '../components/parameters.yaml#/components/parameters/DataTypeHeader'
requestBody:
required: true
description: 代扣送盘请求数据
content:
application/xml:
schema:
allOf:
- $ref: '../components/schemas.yaml#/components/schemas/BaseRequest'
- type: object
required:
- BatchNo
- TotalCount
- TotalAmount
- WithholdingList
properties:
BatchNo:
type: string
description: 批次号
example: "BATCH20240101001"
maxLength: 50
TotalCount:
type: integer
description: 总笔数
example: 10
minimum: 1
maximum: 1000
TotalAmount:
type: number
format: decimal
description: 总金额
example: 1500.00
minimum: 0.01
WithholdingList:
type: array
description: 代扣明细列表
items:
type: object
required:
- BillKey
- CompanyId
- AgreementNo
- PayAmount
properties:
BillKey:
type: string
description: 客户编号
example: "123456"
CompanyId:
type: string
description: 机构编码
example: "654321"
AgreementNo:
type: string
description: 协议号
example: "AGR001"
PayAmount:
type: number
format: decimal
description: 代扣金额
example: 150.00
example: |
<?xml version="1.0" encoding="GBK"?>
<in>
<Version>1.0.1</Version>
<InstId>00001</InstId>
<TranCode>SendDisc</TranCode>
<TranDate>20240101</TranDate>
<TranSeq>123456789016</TranSeq>
<BatchNo>BATCH20240101001</BatchNo>
<TotalCount>2</TotalCount>
<TotalAmount>300.00</TotalAmount>
<WithholdingList>
<Withholding>
<BillKey>123456</BillKey>
<CompanyId>654321</CompanyId>
<AgreementNo>AGR001</AgreementNo>
<PayAmount>150.00</PayAmount>
</Withholding>
<Withholding>
<BillKey>123457</BillKey>
<CompanyId>654321</CompanyId>
<AgreementNo>AGR002</AgreementNo>
<PayAmount>150.00</PayAmount>
</Withholding>
</WithholdingList>
</in>
application/json:
schema:
allOf:
- $ref: '../components/schemas.yaml#/components/schemas/BaseRequest'
- type: object
required:
- BatchNo
- TotalCount
- TotalAmount
- WithholdingList
properties:
BatchNo:
type: string
description: 批次号
example: "BATCH20240101001"
TotalCount:
type: integer
description: 总笔数
example: 2
TotalAmount:
type: number
format: decimal
description: 总金额
example: 300.00
WithholdingList:
type: array
description: 代扣明细列表
items:
type: object
properties:
BillKey:
type: string
description: 客户编号
example: "123456"
CompanyId:
type: string
description: 机构编码
example: "654321"
AgreementNo:
type: string
description: 协议号
example: "AGR001"
PayAmount:
type: number
format: decimal
description: 代扣金额
example: 150.00
example:
Version: "1.0.1"
InstId: "00001"
TranCode: "SendDisc"
TranDate: "20240101"
TranSeq: "123456789016"
BatchNo: "BATCH20240101001"
TotalCount: 2
TotalAmount: 300.00
WithholdingList:
- BillKey: "123456"
CompanyId: "654321"
AgreementNo: "AGR001"
PayAmount: 150.00
- BillKey: "123457"
CompanyId: "654321"
AgreementNo: "AGR002"
PayAmount: 150.00
responses:
'200':
description: 送盘成功
headers:
Content-Type:
$ref: '../components/headers.yaml#/components/headers/ContentType'
X-Response-Time:
$ref: '../components/headers.yaml#/components/headers/ResponseTime'
X-Request-Id:
$ref: '../components/headers.yaml#/components/headers/RequestId'
content:
application/xml:
schema:
allOf:
- $ref: '../components/schemas.yaml#/components/schemas/BaseResponse'
- type: object
properties:
Data:
type: object
properties:
BatchNo:
type: string
description: 批次号
example: "BATCH20240101001"
ProcessedCount:
type: integer
description: 已处理笔数
example: 2
SuccessCount:
type: integer
description: 成功笔数
example: 2
FailCount:
type: integer
description: 失败笔数
example: 0
example: |
<?xml version="1.0" encoding="GBK"?>
<out>
<Version>1.0.1</Version>
<InstId>00001</InstId>
<TranCode>SendDiscRes</TranCode>
<TranDate>20240101</TranDate>
<TranSeq>123456789016</TranSeq>
<RespCode>AAAAAAA</RespCode>
<RespMessage>送盘成功</RespMessage>
<Data>
<BatchNo>BATCH20240101001</BatchNo>
<ProcessedCount>2</ProcessedCount>
<SuccessCount>2</SuccessCount>
<FailCount>0</FailCount>
</Data>
</out>
application/json:
schema:
allOf:
- $ref: '../components/schemas.yaml#/components/schemas/BaseResponse'
- type: object
properties:
Data:
type: object
properties:
BatchNo:
type: string
description: 批次号
example: "BATCH20240101001"
ProcessedCount:
type: integer
description: 已处理笔数
example: 2
SuccessCount:
type: integer
description: 成功笔数
example: 2
FailCount:
type: integer
description: 失败笔数
example: 0
example:
Version: "1.0.1"
InstId: "00001"
TranCode: "SendDiscRes"
TranDate: "20240101"
TranSeq: "123456789016"
RespCode: "AAAAAAA"
RespMessage: "送盘成功"
Data:
BatchNo: "BATCH20240101001"
ProcessedCount: 2
SuccessCount: 2
FailCount: 0
'400':
$ref: '../components/responses.yaml#/components/responses/BusinessError'
'500':
$ref: '../components/responses.yaml#/components/responses/SystemError'
'401':
$ref: '../components/responses.yaml#/components/responses/SecurityError'
'408':
$ref: '../components/responses.yaml#/components/responses/NetworkError'
security:
- ApiKeyAuth: []
- EncryptedData: []

View File

@ -0,0 +1,243 @@
WithholdingSigning:
post:
tags:
- 代扣管理
summary: 代扣签约
description: |
银行代扣业务签约接口,建立客户与银行的代扣协议。
## 业务说明
- 支持客户与银行签署代扣协议
- 包含客户基本信息和银行账户信息
- 支持本行和他行账户签约
- 签约成功后可进行自动代扣
- 支持XML和JSON两种数据格式
## 业务规则
- 客户编号必须在系统中存在
- 银行账户信息必须真实有效
- 同一客户同一银行账户只能签约一次
- 签约成功后协议状态为已签约
## 调用频率限制
- 单个客户编号每天最多签约5次
- 单个机构每分钟最多签约50次
operationId: withholdingSigning
parameters:
- $ref: '../components/parameters.yaml#/components/parameters/ContentTypeHeader'
- $ref: '../components/parameters.yaml#/components/parameters/EncryptTypeHeader'
- $ref: '../components/parameters.yaml#/components/parameters/EncryptModeHeader'
- $ref: '../components/parameters.yaml#/components/parameters/DataTypeHeader'
requestBody:
required: true
description: 代扣签约请求数据
content:
application/xml:
schema:
allOf:
- $ref: '../components/schemas.yaml#/components/schemas/BaseRequest'
- type: object
required:
- BillKey
- CompanyId
- AccountName
- AccountNo
- BankName
properties:
BillKey:
type: string
description: 客户编号
example: "123456"
maxLength: 35
CompanyId:
type: string
description: 机构编码
example: "654321"
maxLength: 30
AccountName:
type: string
description: 开户名
example: "张三"
maxLength: 150
AccountNo:
type: string
description: 开户账号
example: "6222001234567890"
maxLength: 30
BankName:
type: string
description: 银行名称
example: "中国工商银行"
maxLength: 150
ContractNo:
type: string
description: 合同号
example: "CONTRACT001"
maxLength: 150
BankType:
type: integer
description: 银行类型
enum: [0, 1] # 0:本行 1:他行
example: 0
example: |
<?xml version="1.0" encoding="GBK"?>
<in>
<Version>1.0.1</Version>
<InstId>00001</InstId>
<TranCode>Signing</TranCode>
<TranDate>20240101</TranDate>
<TranSeq>123456789014</TranSeq>
<BillKey>123456</BillKey>
<CompanyId>654321</CompanyId>
<AccountName>张三</AccountName>
<AccountNo>6222001234567890</AccountNo>
<BankName>中国工商银行</BankName>
<ContractNo>CONTRACT001</ContractNo>
<BankType>0</BankType>
</in>
application/json:
schema:
allOf:
- $ref: '../components/schemas.yaml#/components/schemas/BaseRequest'
- type: object
required:
- BillKey
- CompanyId
- AccountName
- AccountNo
- BankName
properties:
BillKey:
type: string
description: 客户编号
example: "123456"
CompanyId:
type: string
description: 机构编码
example: "654321"
AccountName:
type: string
description: 开户名
example: "张三"
AccountNo:
type: string
description: 开户账号
example: "6222001234567890"
BankName:
type: string
description: 银行名称
example: "中国工商银行"
ContractNo:
type: string
description: 合同号
example: "CONTRACT001"
BankType:
type: integer
description: 银行类型
example: 0
example:
Version: "1.0.1"
InstId: "00001"
TranCode: "Signing"
TranDate: "20240101"
TranSeq: "123456789014"
BillKey: "123456"
CompanyId: "654321"
AccountName: "张三"
AccountNo: "6222001234567890"
BankName: "中国工商银行"
ContractNo: "CONTRACT001"
BankType: 0
responses:
'200':
description: 签约成功
headers:
Content-Type:
$ref: '../components/headers.yaml#/components/headers/ContentType'
X-Response-Time:
$ref: '../components/headers.yaml#/components/headers/ResponseTime'
X-Request-Id:
$ref: '../components/headers.yaml#/components/headers/RequestId'
content:
application/xml:
schema:
allOf:
- $ref: '../components/schemas.yaml#/components/schemas/BaseResponse'
- type: object
properties:
Data:
type: object
properties:
Agreement:
$ref: '../components/schemas.yaml#/components/schemas/WithholdingAgreement'
example: |
<?xml version="1.0" encoding="GBK"?>
<out>
<Version>1.0.1</Version>
<InstId>00001</InstId>
<TranCode>SigningRes</TranCode>
<TranDate>20240101</TranDate>
<TranSeq>123456789014</TranSeq>
<RespCode>AAAAAAA</RespCode>
<RespMessage>签约成功</RespMessage>
<Data>
<Agreement>
<BillKey>123456</BillKey>
<CompanyId>654321</CompanyId>
<AccountName>张三</AccountName>
<AccountNo>6222001234567890</AccountNo>
<BankName>中国工商银行</BankName>
<ContractNo>CONTRACT001</ContractNo>
<AgreementNo>AGR001</AgreementNo>
<BankType>0</BankType>
<AgreementStatus>1</AgreementStatus>
<SigningDate>2024-01-01</SigningDate>
</Agreement>
</Data>
</out>
application/json:
schema:
allOf:
- $ref: '../components/schemas.yaml#/components/schemas/BaseResponse'
- type: object
properties:
Data:
type: object
properties:
Agreement:
$ref: '../components/schemas.yaml#/components/schemas/WithholdingAgreement'
example:
Version: "1.0.1"
InstId: "00001"
TranCode: "SigningRes"
TranDate: "20240101"
TranSeq: "123456789014"
RespCode: "AAAAAAA"
RespMessage: "签约成功"
Data:
Agreement:
BillKey: "123456"
CompanyId: "654321"
AccountName: "张三"
AccountNo: "6222001234567890"
BankName: "中国工商银行"
ContractNo: "CONTRACT001"
AgreementNo: "AGR001"
BankType: 0
AgreementStatus: 1
SigningDate: "2024-01-01"
'400':
$ref: '../components/responses.yaml#/components/responses/BusinessError'
'500':
$ref: '../components/responses.yaml#/components/responses/SystemError'
'401':
$ref: '../components/responses.yaml#/components/responses/SecurityError'
'408':
$ref: '../components/responses.yaml#/components/responses/NetworkError'
security:
- ApiKeyAuth: []
- EncryptedData: []

View File

@ -0,0 +1,184 @@
WithholdingTermination:
post:
tags:
- 代扣管理
summary: 代扣解约
description: |
银行代扣业务解约接口,终止客户与银行的代扣协议。
## 业务说明
- 支持客户解除与银行的代扣协议
- 解约后不能再进行自动代扣
- 支持XML和JSON两种数据格式
- 解约后协议状态变更为已解约
## 业务规则
- 只能解约已签约状态的协议
- 解约成功后协议状态更新为已解约
- 同一协议只能解约一次
- 解约不影响已产生的交易记录
## 调用频率限制
- 单个协议号每天最多解约1次
- 单个机构每分钟最多解约20次
operationId: withholdingTermination
parameters:
- $ref: '../components/parameters.yaml#/components/parameters/ContentTypeHeader'
- $ref: '../components/parameters.yaml#/components/parameters/EncryptTypeHeader'
- $ref: '../components/parameters.yaml#/components/parameters/EncryptModeHeader'
- $ref: '../components/parameters.yaml#/components/parameters/DataTypeHeader'
requestBody:
required: true
description: 代扣解约请求数据
content:
application/xml:
schema:
allOf:
- $ref: '../components/schemas.yaml#/components/schemas/BaseRequest'
- type: object
required:
- BillKey
- CompanyId
- AgreementNo
properties:
BillKey:
type: string
description: 客户编号
example: "123456"
maxLength: 35
CompanyId:
type: string
description: 机构编码
example: "654321"
maxLength: 30
AgreementNo:
type: string
description: 协议号
example: "AGR001"
maxLength: 150
example: |
<?xml version="1.0" encoding="GBK"?>
<in>
<Version>1.0.1</Version>
<InstId>00001</InstId>
<TranCode>Termination</TranCode>
<TranDate>20240101</TranDate>
<TranSeq>123456789015</TranSeq>
<BillKey>123456</BillKey>
<CompanyId>654321</CompanyId>
<AgreementNo>AGR001</AgreementNo>
</in>
application/json:
schema:
allOf:
- $ref: '../components/schemas.yaml#/components/schemas/BaseRequest'
- type: object
required:
- BillKey
- CompanyId
- AgreementNo
properties:
BillKey:
type: string
description: 客户编号
example: "123456"
CompanyId:
type: string
description: 机构编码
example: "654321"
AgreementNo:
type: string
description: 协议号
example: "AGR001"
example:
Version: "1.0.1"
InstId: "00001"
TranCode: "Termination"
TranDate: "20240101"
TranSeq: "123456789015"
BillKey: "123456"
CompanyId: "654321"
AgreementNo: "AGR001"
responses:
'200':
description: 解约成功
headers:
Content-Type:
$ref: '../components/headers.yaml#/components/headers/ContentType'
X-Response-Time:
$ref: '../components/headers.yaml#/components/headers/ResponseTime'
X-Request-Id:
$ref: '../components/headers.yaml#/components/headers/RequestId'
content:
application/xml:
schema:
allOf:
- $ref: '../components/schemas.yaml#/components/schemas/BaseResponse'
- type: object
properties:
Data:
type: object
properties:
Agreement:
$ref: '../components/schemas.yaml#/components/schemas/WithholdingAgreement'
example: |
<?xml version="1.0" encoding="GBK"?>
<out>
<Version>1.0.1</Version>
<InstId>00001</InstId>
<TranCode>TerminationRes</TranCode>
<TranDate>20240101</TranDate>
<TranSeq>123456789015</TranSeq>
<RespCode>AAAAAAA</RespCode>
<RespMessage>解约成功</RespMessage>
<Data>
<Agreement>
<BillKey>123456</BillKey>
<CompanyId>654321</CompanyId>
<AgreementNo>AGR001</AgreementNo>
<AgreementStatus>2</AgreementStatus>
<TerminationDate>2024-01-01</TerminationDate>
</Agreement>
</Data>
</out>
application/json:
schema:
allOf:
- $ref: '../components/schemas.yaml#/components/schemas/BaseResponse'
- type: object
properties:
Data:
type: object
properties:
Agreement:
$ref: '../components/schemas.yaml#/components/schemas/WithholdingAgreement'
example:
Version: "1.0.1"
InstId: "00001"
TranCode: "TerminationRes"
TranDate: "20240101"
TranSeq: "123456789015"
RespCode: "AAAAAAA"
RespMessage: "解约成功"
Data:
Agreement:
BillKey: "123456"
CompanyId: "654321"
AgreementNo: "AGR001"
AgreementStatus: 2
TerminationDate: "2024-01-01"
'400':
$ref: '../components/responses.yaml#/components/responses/BusinessError'
'500':
$ref: '../components/responses.yaml#/components/responses/SystemError'
'401':
$ref: '../components/responses.yaml#/components/responses/SecurityError'
'408':
$ref: '../components/responses.yaml#/components/responses/NetworkError'
security:
- ApiKeyAuth: []
- EncryptedData: []

119
docs/api/openapi/serve.js Normal file
View File

@ -0,0 +1,119 @@
#!/usr/bin/env node
const express = require('express');
const path = require('path');
const fs = require('fs');
const app = express();
const PORT = 3001;
// 静态文件服务
app.use('/docs', express.static(path.join(__dirname)));
// 主页路由
app.get('/', (req, res) => {
res.send(`
<!DOCTYPE html>
<html>
<head>
<title>营收系统接口文档</title>
<meta charset="utf-8">
<style>
body { font-family: Arial, sans-serif; margin: 40px; line-height: 1.6; }
.header { background: #2c3e50; color: white; padding: 20px; border-radius: 8px; margin-bottom: 30px; }
.card { background: #f8f9fa; padding: 20px; border-radius: 8px; margin: 20px 0; border-left: 4px solid #007bff; }
.btn { display: inline-block; padding: 10px 20px; background: #007bff; color: white; text-decoration: none; border-radius: 5px; margin: 10px 5px; }
.btn:hover { background: #0056b3; }
pre { background: #f4f4f4; padding: 15px; border-radius: 5px; overflow-x: auto; }
.feature { margin: 10px 0; }
.feature strong { color: #2c3e50; }
</style>
</head>
<body>
<div class="header">
<h1>🏦 营收系统接口OpenAPI文档</h1>
<p>银行/第三方支付机构接口交互API文档 - 基于OpenAPI 3.0.3规范</p>
</div>
<div class="card">
<h2>📖 文档访问</h2>
<a href="https://editor.swagger.io/?url=${req.protocol}://${req.get('host')}/docs/main/openapi.yaml" class="btn" target="_blank">
在Swagger Editor中打开
</a>
<a href="/docs/main/openapi.yaml" class="btn" target="_blank">
查看原始YAML
</a>
<a href="/docs/README.md" class="btn" target="_blank">
使用说明
</a>
</div>
<div class="card">
<h2>🚀 主要功能</h2>
<div class="feature"><strong>账单管理:</strong> </div>
<div class="feature"><strong>代扣管理:</strong> </div>
<div class="feature"><strong>多格式支持:</strong> XML (GBK) JSON (UTF-8)</div>
<div class="feature"><strong>安全认证:</strong> 3DESSM2SM4</div>
<div class="feature"><strong>错误处理:</strong> </div>
</div>
<div class="card">
<h2>📋 API概览</h2>
<ul>
<li><strong>POST</strong> /api/app/billQuery/query - </li>
<li><strong>POST</strong> /api/app/billPay/pay - </li>
<li><strong>POST</strong> /api/app/payInvalid/payInvalid - </li>
<li><strong>POST</strong> /api/app/bankWithholding/signing - </li>
<li><strong>POST</strong> /api/app/bankWithholding/termination - </li>
<li><strong>POST</strong> /api/app/bankWithholding/sendDisc - </li>
<li><strong>POST</strong> /api/app/bankWithholding/backDisc - </li>
</ul>
</div>
<div class="card">
<h2>🔧 快速测试</h2>
<p>账单查询示例JSON格式:</p>
<pre>{
"Version": "1.0.1",
"InstId": "00001",
"TranCode": "Query",
"TranDate": "20240101",
"TranSeq": "123456789012",
"BillKey": "123456",
"CompanyId": "654321"
}</pre>
</div>
<div class="card">
<h2>🛠 开发工具</h2>
<p>推荐使用以下工具进行API开发和测试</p>
<ul>
<li><a href="https://www.postman.com/" target="_blank">Postman</a> - API</li>
<li><a href="https://insomnia.rest/" target="_blank">Insomnia</a> - REST</li>
<li><a href="https://editor.swagger.io/" target="_blank">Swagger Editor</a> - 线</li>
</ul>
</div>
<footer style="text-align: center; margin-top: 50px; color: #666;">
<p>营收系统接口API v1.0.0 | OpenAPI 3.0.3</p>
</footer>
</body>
</html>
`);
});
// 启动服务器
app.listen(PORT, () => {
console.log('🚀 营收系统接口文档服务已启动!');
console.log(`📖 访问地址: http://localhost:${PORT}`);
console.log(`📋 Swagger Editor: https://editor.swagger.io/?url=http://localhost:${PORT}/docs/main/openapi.yaml`);
console.log('');
console.log('📁 文档结构:');
console.log('├── docs/main/openapi.yaml # 主入口文档');
console.log('├── docs/main/components/ # 通用组件');
console.log('└── docs/main/paths/ # API路径定义');
console.log('');
console.log('按 Ctrl+C 停止服务');
});
module.exports = app;

View File

@ -0,0 +1,119 @@
#!/usr/bin/env node
const YAML = require('yaml');
const fs = require('fs');
const path = require('path');
/**
* 验证OpenAPI文档的基本语法和结构
*/
function validateOpenAPIDoc() {
try {
console.log('🔍 开始验证营收系统OpenAPI文档...\n');
// 读取主文档
const mainDocPath = path.join(__dirname, 'main', 'openapi.yaml');
const mainContent = fs.readFileSync(mainDocPath, 'utf8');
const mainDoc = YAML.parse(mainContent);
// 验证基本结构
console.log('✅ 主文档语法正确');
console.log(`📋 API标题: ${mainDoc.info.title}`);
console.log(`📋 API版本: ${mainDoc.info.version}`);
console.log(`📋 OpenAPI版本: ${mainDoc.openapi}`);
// 验证服务器配置
if (mainDoc.servers && mainDoc.servers.length > 0) {
console.log(`🌐 配置了 ${mainDoc.servers.length} 个服务器环境:`);
mainDoc.servers.forEach((server, index) => {
console.log(` ${index + 1}. ${server.description}: ${server.url}`);
});
}
// 验证标签
if (mainDoc.tags && mainDoc.tags.length > 0) {
console.log(`🏷️ 定义了 ${mainDoc.tags.length} 个标签:`);
mainDoc.tags.forEach((tag, index) => {
console.log(` ${index + 1}. ${tag.name}: ${tag.description}`);
});
}
// 验证路径
if (mainDoc.paths) {
const pathCount = Object.keys(mainDoc.paths).length;
console.log(`🛣️ 定义了 ${pathCount} 个API路径:`);
Object.keys(mainDoc.paths).forEach((path, index) => {
console.log(` ${index + 1}. ${path}`);
});
}
// 验证组件文件
console.log('\n🔧 验证组件文件:');
const componentFiles = [
'components/schemas.yaml',
'components/responses.yaml',
'components/parameters.yaml',
'components/headers.yaml',
'components/security.yaml'
];
componentFiles.forEach(file => {
const filePath = path.join(__dirname, 'main', file);
if (fs.existsSync(filePath)) {
try {
const content = fs.readFileSync(filePath, 'utf8');
YAML.parse(content);
console.log(`${file}`);
} catch (error) {
console.log(`${file}: ${error.message}`);
}
} else {
console.log(` ⚠️ ${file}: 文件不存在`);
}
});
// 验证路径文件
console.log('\n🛤 验证路径文件:');
const pathFiles = [
'paths/bill-query.yaml',
'paths/bill-pay.yaml',
'paths/pay-invalid.yaml',
'paths/withholding-signing.yaml',
'paths/withholding-termination.yaml',
'paths/withholding-send-disc.yaml',
'paths/withholding-back-disc.yaml'
];
pathFiles.forEach(file => {
const filePath = path.join(__dirname, 'main', file);
if (fs.existsSync(filePath)) {
try {
const content = fs.readFileSync(filePath, 'utf8');
YAML.parse(content);
console.log(`${file}`);
} catch (error) {
console.log(`${file}: ${error.message}`);
}
} else {
console.log(` ⚠️ ${file}: 文件不存在`);
}
});
console.log('\n🎉 OpenAPI文档验证完成!');
console.log('\n📖 使用方法:');
console.log('1. 在Swagger Editor中打开 docs/main/openapi.yaml');
console.log('2. 或使用命令: npx swagger-ui-serve docs/main/openapi.yaml');
console.log('3. 或导入到Postman等API测试工具中');
} catch (error) {
console.error('❌ 验证失败:', error.message);
process.exit(1);
}
}
// 如果直接运行此脚本
if (require.main === module) {
validateOpenAPIDoc();
}
module.exports = { validateOpenAPIDoc };

View File

@ -69,6 +69,12 @@
| 业务审查结论回写 | ✅ 已完成 | 2026-03-12 | 审查三项已在周检记录中形成结论 |
| 非关键治理补漏转入维护 | ✅ 已完成 | 2026-03-12 | 后续按周检机制持续跟踪,不再阻塞本阶段收口 |
### 持续维护记录
| 日期 | 事项 | 修订内容 | 影响 |
| ---- | ---- | -------- | ---- |
| 2026-04-29 | REV-003 支付域归属正式回写 | 将业务支付事实目标层(`biz_payment_record` / `biz_payment_record_detail`)正式归入 `REV-003` 营业收费;明确 `SYS-009` 仅承接 `bk_transaction*` 渠道事实;`REV-004` 仅在退款、冲正、账务调整中引用原支付/渠道事实。 | 统一概要、详细、接口、数据库、追溯矩阵和旧表迁移矩阵口径,避免把支付主域误归到 REV-004。 |
## 质量控制检查点
### 技术质量标准
@ -116,6 +122,9 @@
> 说明:本表中的历史记录按当时原始表述保留;当前正式数据库口径统一以“达梦数据库 8.0+”为准。
| 2026-03-26 | 方案二整体部署方案独立成文 | 1新增 `docs/design/03_Technical_Design/08_Integrated_Deployment_Design_PlanB.md`,将已采纳 PostgreSQL 16 方案二后的整体部署方案独立成文2结合当前前后端分层部署形态补齐应用、数据库、中间件、静态存储的一体化部署结构3新增软件拓扑图、网络拓扑图、主机角色划分、资源配置建议、网络需求和端口访问建议4`07_PostgreSQL16_DR_Resource_Application.md` 增加独立文档引用说明,在技术专项目录增加入口。 | 用户明确要求不要仅在 `07` 文档内保留方案二内容,而是需要形成独立文件,并作为已采纳数据库方案后的整体部署方案提交评审。 | 正面影响,数据库资源申请专题与整体部署方案实现职责分离;后续甲方可分别评审“数据库容灾资源申请”和“系统整体部署方案”,减少口径混杂并提升部署审批的可读性。 |
| 2026-04-02 | 方案二整体部署文档按网络图口径对齐 | 1`docs/design/03_Technical_Design/08_Integrated_Deployment_Design_PlanB.md` 的网络分区口径统一为“办公区 / 公网区域 / 互联网区DMZ / 内网区”2`Nginx` 入口、业务应用节点、`SFTP/FTP` 文件交换服务器的部署区域说明统一调整为与评审图一致3同步修正网络拓扑图、访问链路、带宽/端口、资源角色及结论段落中的命名与边界表述。 | 用户提供最新部署图,要求正式文档向图片口径靠拢,消除 `内网 Nginx`、应用区/DMZ、办公区等描述不一致问题。 | 正面影响,整体部署方案的图文一致性显著提升,便于甲方按统一网络边界和主机分区口径开展安全评审与资源审批。 |
| 2026-03-18 | REV-005 统计模板补齐 | 1`specs/002-rev005-invoice-flow/verification.md``T055``T060``T061``T062``T063` 新增可直接填写的样本记录模板2将 SC-001 ~ SC-004 的建议统计口径细化为表格字段与待补说明避免后续只剩抽象待办3保持“模板已补齐但实际统计结果仍待联调/测试环境补录”的真实状态,不虚构样本结果。 | 用户继续推进 REV-005希望把剩余统计类待办进一步收敛成可执行模板便于后续直接补录真实样本而不是重新设计统计格式。 | 正面影响REV-005 当前已具备统一的统计与日志抽样记录模板;后续补 `T055``T060 ~ T063` 时可直接按模板填充真实环境数据,减少再次整理验证文档结构的成本。 |
| 2026-03-18 | REV-005 verify 执行入口补齐 | 1`specs/002-rev005-invoice-flow/verification.md` 补齐 `/business/invoice/apply``/query``/query/compensate``/write-back``/customer/query``/customer/download``/customer/push``/invalidate``/red-ink` 的最小请求模板2继续补齐 `T055``T060 ~ T063` 的执行命令草稿与样本采集顺序,明确仅作为测试/联调环境占位模板真实地址、鉴权信息、业务主键与统计结果均待后续替换和回填3同步 `03_Task_Checklist.md`,将 verify 阶段推进到“替换真实环境参数即可执行”的状态。 | 用户继续推进 REV-005希望不要停留在抽象验证建议而是把剩余 verify 工作推进到可直接执行、可直接补样本的程度。 | 正面影响REV-005 当前已具备统一的验证入口、请求模板、命令草稿与采样顺序;后续在测试或联调环境中可直接替换参数发起请求并回填 `T055``T060 ~ T063` 的真实结果,减少重复梳理接口和命令的成本。 |
| 2026-03-18 | REV-005 联调补录清单补齐 | 1`specs/002-rev005-invoice-flow/verification.md` 新增 `T055``T060 ~ T063` 的联调补录清单,按“申请 → 查询 → 回写 → 补偿查询 → 客户查询/下载/推送 → 作废/红冲 → 日志抽样”顺序拆解步骤2为每一步明确主要输入、预期产出与回填位置确保联调执行时不再重复梳理样本归档方式3同步 `03_Task_Checklist.md`,将 verify 阶段推进到“可按顺序执行并即时补录”的状态。 | 用户继续推进 REV-005希望把剩余运行态补证工作从“有命令草稿”进一步推进到“有顺序、有产出、有回填位置”的联调操作清单。 | 正面影响REV-005 当前已具备联调补录步骤清单,后续在测试或联调环境中可按固定顺序执行并即时回填样本、统计与日志证据,降低遗漏申请单号、受理号与日志检索条件的风险。 |
@ -128,6 +137,8 @@
| 2026-03-18 | REV-005 SC-005 日志追溯矩阵补齐 | 1基于 `InvoiceServiceImpl.java` 梳理发票申请、查询/补偿、结果回写、客户侧查询/下载/推送、作废、红冲等关键动作的统一日志写入点2确认上述动作均通过 `recordInvoiceOperatLog` 归一写入,并由 `OperatLogService.createOperatLog` 承接操作人、客户与日志内容上下文3`specs/002-rev005-invoice-flow/verification.md` 回写“关键动作 ↔ 日志写入点”矩阵,将 SC-005 收敛为“实现态证据已补齐、运行态样本待抽查”。 | 用户继续推进 REV-005一期验收优先补齐 SC-005 的可引用验证证据,避免日志完整率仍停留在笼统结论。 | 正面影响REV-005 已具备可直接引用的实现态日志追溯矩阵,申请、查询补偿、回写、客户侧查询/下载/推送、作废、红冲等关键动作均可定位到统一日志写入点;后续主要补充测试环境样本抽查即可收口运行态证据。 |
| 2026-03-18 | REV-005 `biz_invoice` DDL 来源核实 | 1`backend/sql``docs/design/04_Appendix/Archive/03_Design_Docs/数据库设计.md``sql/lhc_数据库设计.md``docs/guides/BACKEND_TABLE_MAPPING.md` 范围内交叉检索 `biz_invoice`、作废/红冲新增字段与迁移脚本2确认仓库内未找到与当前 `InvoiceDO.java` 对应的 `biz_invoice` 物理 DDL / migration3确认 Archive 与 `sql/lhc_数据库设计.md` 中同名 `biz_invoice` 更偏“开票配置表”,不能直接作为 REV-005 发票主记录表的落库依据4将该结论回写到 REV-005 验证与管理台账。 | 用户继续要求沿 REV-005 把 US4 剩余风险查清,不停留在“表结构待补”泛化表述。 | 正面影响REV-005 当前已明确“接口/DO/文档承接口径已完成,但物理落库证据仍未在仓库内闭环”;后续若推进提测或联调,可直接把 DDL 缺口作为明确风险跟踪,避免误判作废/红冲字段已正式落库。 |
| 2026-03-18 | REV-005 验证文档补强实现态证据 | 1`specs/002-rev005-invoice-flow/verification.md``SC-001 ~ SC-004` 补充基于 `InvoiceController.java``InvoiceServiceImpl.java` 与各请求 VO 的实现态证据,明确申请入口、必填字段、同步处理边界、回写联动、客户侧消费约束与幂等/拦截规则2`SC-005``T055` 模板补记 `biz_invoice` 物理 DDL / migration 持续跟踪结论避免日志抽样与物理落库风险脱节3保持 `T055``T060 ~ T063` 仍为“待真实联调样本回填”,不虚构量化结果。 | 用户要求直接继续 REV-005并在未取得真实联调样本前先把可防御的实现态证据落入正式验证文档。 | 正面影响REV-005 当前验证记录已从“只有模板和待补口径”提升为“模板 + 代码证据 + 明确缺口”并存;后续联调回填时可直接引用实现态依据解释统计口径、拦截分类与日志追溯边界。 |
| 2026-03-23 | SYS-009 银行代扣六条银行入口实现态闭环回写 | 1复核 `water-backend/sw-business-bank``BankWithholdingController.java``BankWithholdingServiceImpl.java``TransactionMapper.java` 与相关 DTO/DO/Mapper确认 `customerCheck``sendDisc``sendDiscCheck``cancelDisc``backDisc``backDiscCheck` 六条银行入口均已补齐 controller/service 实现2同步更新 `specs/007-sys009-design-align/final-verdict.md``contracts/sys009-status-verdicts.md`,将 `BankWithholding` 从“签约/解约已实现、其余部分实现”修正为“六条银行入口已形成最小实现态闭环”3保留运行态风险说明明确真实银行回盘文件解析、SFTP/文件通道联调与样本补证仍待后续验证。 | 用户要求继续完成 `BankWithholding` 六条银行入口,不留 TODO/null并在实现后回写正式 verdict。 | 正面影响,`SYS-009` 正式结论与 backend 当前代码证据重新对齐,后续评审可区分“实现态已闭环”与“运行态联调证据待补”,避免继续将已完成入口误判为仅部分实现。 |
| 2026-03-20 | SYS-009 设计整合与实现边界收敛 | 1基于 `specs/007-sys009-design-align/` 的规格、计划、研究与契约,将 `/Users/tangweijie/github/water-bank-api-doc``SYS-009` 银行侧设计回写到 `12_REV_Detailed.md``03_Interface_Design.md``01_Database_Design.md``03_Summary_Design.md`2`PayCeb``BankWithholding``BankCollection``bk_*` 表族的当前成熟度统一收敛为“已实现 / 部分实现 / 文档先行”三类口径避免继续把送盘、回盘、对账、结算写成已闭环能力3完成四份主文档单文件校验并通过。 | 用户要求把外部 `SYS-009` 设计整合进正式文档,并与当前 backend 实现现状对齐,形成可评审口径。 | 正面影响,仓内正式主文档已成为 `SYS-009` 的单一评审入口;银行实时收费、签解约、批次/回盘/对账/结算的设计边界与实现成熟度不再混写,后续开发与验收可直接引用统一口径。 |
| 2026-03-17 | REV-005 作废与红冲二期最小入口落地US4 | 1更新 `spec.md``plan.md``tasks.md`,将 US4 从“边界预留”升级为当前二期实现范围2更新 `12_REV_Detailed.md``03_Interface_Design.md`,明确后台作废/红冲入口、状态边界与客户侧消费约束3`InvoiceController.java``InvoiceService.java``InvoiceServiceImpl.java` 中将作废/红冲入口升级为专门请求 VO并补齐原因/备注、原发票代码/号码校验与日志留痕4扩展 `InvoiceDO.java` 承接作废原因/备注、红冲原因/备注、原发票代码/号码与触发来源字段,并在 service 中回写最小上下文5更新 `01_Database_Design.md` 中 REV-005 发票承接口径,补充作废/红冲原因、备注、原票关联与查询补偿上下文6执行 `make validate-file FILE=docs/design/03_Technical_Design/01_Database_Design.md``mvn -f backend/sw-business/sw-business-server/pom.xml -DskipTests compile` 并通过。 | 用户持续要求“继续推进 REV-005”在一期闭环收口后继续落地 US4 二期最小能力入口,避免作废/红冲长期停留在文档预留状态。 | 正面影响REV-005 已从“一期正常开票闭环”进一步扩展到“二期作废/红冲最小入口可评审、可编译验证”的状态;当前已补齐专门 VO 接线、原票引用校验、DO 字段承接与数据库承接口径,后续主要剩余 Mapper/表结构层面的正式持久化落地。 || 2026-03-17 | REV-005 结果回写与客户侧电子发票消费闭环US3 | 1更新 `12_REV_Detailed.md``01_Database_Design.md``03_Interface_Design.md`,补齐结果回写、账单关联、客户侧查询/下载/推送电子发票规则2扩展 `InvoiceController.java``InvoiceServiceImpl.java``InvoiceMapper.java` 与相关 VO/DO落地客户归属校验、`SUCCESS + fileUrl` 消费前置校验、账单开票状态联动、推送状态回写3执行 `make validate-file FILE=docs/design/03_Technical_Design/01_Database_Design.md``make validate-file FILE=docs/design/03_Technical_Design/03_Interface_Design.md``mvn -f backend/sw-business/sw-business-server/pom.xml -DskipTests compile` 验证通过。 | 用户要求沿 `/speckit.implement` 持续推进 REV-005 US3不中断实现链路直接完成结果回写、账单关联与客户侧电子票消费闭环。 | 正面影响REV-005 已形成“回写落账 + 账单状态联动 + 客户侧查询/下载/推送 + 最小编译验证”闭环,后续可继续衔接作废、红冲与更多电子发票渠道扩展。 |
| 2026-03-16 | REV-005 后台发票申请与校验闭环US1 | 1`backend/sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/controller/admin/invoice/InvoiceController.java` 增加后台发票申请入口2`service/invoice/InvoiceServiceImpl.java` 实现客户、客户开票信息、账单与税率校验确保仅已收费未开票账单允许申请3补齐 `applicationNo``custId + chargeIds` 幂等控制、申请单号生成与申请记录落库4执行 `mvn -f backend/sw-business/pom.xml -pl sw-business-server -am -DskipTests compile` 最小编译验证并通过。 | 用户要求继续推进 REV-005 implement优先完成后台发票申请、开票校验与 US1 收尾,不中断当前实现链路。 | 正面影响REV-005 已形成“后台申请入口 + 关键校验 + 幂等受理 + 最小编译验证”闭环,后续可在此基础上继续推进 SYS-008 调用、开票结果回写、账单状态联动与电子发票推送下载能力。 |
| 2026-03-12 | OMX 任务路由样例落地 | 1新增 `docs/design/00_Management/17_OMX_Task_Routing_Examples.md`,给出 `REV-004``REV-003` 与正式文档修订三类任务的 leader / explorer / executor / verifier 分工模板2补充各 lane 的提示词模板、推荐执行顺序与不建议的并行方式3更新 `00_Management/README.md` 收录该文档入口。 | 用户希望在治理层之外,再拿到针对当前项目可以直接复用的多 Agent 分工模板,而不是只看抽象原则。 | 正面影响OMX 从“有规则”变成“可直接照着分工执行”;后续在 `REV-004``REV-003` 等闭环中可直接套用 lane 拆分,减少 leader 临时编排成本。 |
@ -341,3 +352,14 @@
- 完成 `REV-006` 当前轮次治理文档二次对齐:在 `15_SYS002_Requirement_Breakdown.md` 明确 `SYS002-REQ-011` 继续维持“未见实现”判断,并补记 `specs/006-reminder-event-design/` 工件基线与后续研发切入建议。
- 同步回写 `03_Task_Checklist.md` 与本进度文档,补充本轮 implement 阶段的治理动作、验证动作与台账一致性说明,避免将文档收口误写为 backend 已实现。
### 2026-03-24 更新
- 完成 `010-bank-transfer-config` implement 阶段收口,统一 `12_REV_Detailed.md``03_Interface_Design.md``04_Security_Design.md``05_Deployment_Design.md``specs/010-bank-transfer-config/` 工件口径。
- `sw-business-bank` 已新增 `FILE_TRANSFER_CONFIG` 配置类型、统一文件传输解析器、`SFTP/FTP` 双协议解析能力,以及 `send/back/reconcile` 审计字段承接;已落库批次回盘目录继续沿用批次固化结果。
- 已完成 backend 最小验证:`mvn -f ../water-backend/sw-business-bank/pom.xml -pl sw-business-bank-server -am -DskipTests compile` 通过;`mvn ... -Dtest=BankTransferPathResolverTest,BankWithholdingTransferConfigTest -Dsurefire.failIfNoSpecifiedTests=false test` 通过,共 9 个定向测试全部通过。
- 当前剩余 deferred 继续限定为真实银行 `SFTP/FTP` 联调、生产凭据与白名单开通、`BankCollection` 托收链路对等改造,以及运行态样本补证,不将其误写为已闭环能力。
- 新增 `docs/guides/NUOSHUITONG_SAAS_INTEGRATION_CHECKLIST.md`,形成诺税通 saas 首期对接实施清单,统一接口优先级、请求/响应字段映射、业务流程图、错误码处理策略与沙箱测试清单口径,作为外部发票平台首批实施与联调验收的正式参考。
- 新增 `docs/guides/NUOSHUITONG_DATABASE_DESIGN.md`,形成诺税通对接数据库设计草案,明确发票、红字单据、设备、库存、企业配置与平台日志等落表建议,作为后续正式 DDL 与专项数据库设计对齐的输入。
- 新增 `docs/guides/NUOSHUITONG_DDL_DRAFT.md`,形成诺税通对接 DDL 草案,覆盖核心表 `CREATE TABLE`、唯一约束与索引建议,作为后续数据库实现与 PostgreSQL/openGauss 方言适配的基础版本。
- 新增 `docs/guides/NUOSHUITONG_PG_OPENGAUSS_DDL_GUIDE.md`,形成 PostgreSQL 16 / openGauss 适配建议,明确类型替换、主键策略、索引兼容性和迁移实施注意事项,作为双数据库口径下的实现参考。

View File

@ -1,5 +1,15 @@
# 福建水务营收系统文档编写任务清单
## 📌 持续维护任务
### 📋 REV-003 支付域归属正式回写
- [x] **完成 REV-003 业务支付事实层正式文档回写** ✅ (2026-04-29)
- [x] 已在概要、详细、接口、数据库主文档中明确 `biz_payment_record` / `biz_payment_record_detail` 归属 `REV-003` 的目标/原型语义 ✅
- [x] 已明确 `SYS-009` 保持 `bk_transaction*` 渠道事实主责,`REV-004` 仅作为退款、冲正、账务调整引用方 ✅
- [x] 已更新旧表到新对象、字段级映射、试迁校验和 REV-004 追溯矩阵,区分业务支付事实、渠道事实与历史只读投影 ✅
- [x] 已保留“目标/原型、待实现验真”风险说明,避免把未验真实表写成生产事实 ✅
## 🎯 当前冲刺任务 (第一阶段:紧急问题修复)
### 📋 系统架构设计文档 (`water_biz_system_architecture.md`)
@ -138,6 +148,44 @@
## ✅ 最新完成任务 (持续更新)
### 📋 PostgreSQL 16 容灾资源申请专题
- [x] **完成 PostgreSQL 16 容灾与资源申请专题文档** ✅ (2026-03-24)
- [x] 新增独立专题文档,支撑甲方资源申请 ✅
- [x] 已补齐多种容灾形态及部署说明 ✅
- [x] 已补齐主备资源比例与申请清单 ✅
- [x] 已补齐网络、存储、切换与恢复要求 ✅
- [x] 已补齐 PostgreSQL 代理架构、`HAProxy` / `PgBouncer` 配置样例与应用接入建议 ✅
- [x] 已补齐计划切换、故障切换、回切、检查表与验证表 ✅
- [x] 已将原方案二抽出为整体部署方案,补齐前端、后端、中间件、数据库、静态存储和网络需求 ✅
- [x] 已新增独立文档 `08_Integrated_Deployment_Design_PlanB.md`,沉淀已采纳方案二后的整体部署方案 ✅
### 📋 010-bank-transfer-config 银行文件传输配置能力
- [x] **完成 `010-bank-transfer-config` 文档与 backend 闭环实现** ✅ (2026-03-24)
- [x] 已更新 `12_REV_Detailed.md``03_Interface_Design.md``04_Security_Design.md``05_Deployment_Design.md`,明确 `REV-008` 文件传输配置边界、解析优先级、安全约束与部署职责 ✅
- [x] 已补齐 `specs/010-bank-transfer-config/``data-model.md`、合同、quickstart、baseline、validation、final-verdict` 等工件,形成单一规格闭环 ✅
- [x] `sw-business-bank` 已新增 `FILE_TRANSFER_CONFIG`、统一路径解析器、send/back/reconcile 审计字段承接与 2 组定向测试类 ✅
- [x] 已完成 `mvn -f ../water-backend/sw-business-bank/pom.xml -pl sw-business-bank-server -am -DskipTests compile``mvn ... -Dtest=BankTransferPathResolverTest,BankWithholdingTransferConfigTest -Dsurefire.failIfNoSpecifiedTests=false test` 最小验证 ✅
### 📋 SYS-009 银行代扣闭环实现态回写
- [x] **完成 SYS-009 `BankWithholding` 六条银行入口实现态闭环回写** ✅ (2026-03-23)
- [x] 已复核 `BankWithholdingController.java``BankWithholdingServiceImpl.java`,确认 `customerCheck``sendDisc``sendDiscCheck``cancelDisc``backDisc``backDiscCheck` 不再保留 TODO/null 路径 ✅
- [x] 已复核 `TransactionMapper.java`,确认代扣交易审计语义统一使用 `WITHHOLDING`
- [x] 已更新 `specs/007-sys009-design-align/final-verdict.md``contracts/sys009-status-verdicts.md`,同步六条银行入口 verdict 为“已实现” ✅
- [x] 已记录最小验证结论:`mvn ... -DskipTests compile``mvn ... test` 均通过(当前模块输出 `No tests to run`)✅
- [x] 已保留剩余风险说明真实银行回盘文件解析、SFTP/文件通道联调与运行态样本仍待后续补证 ✅
### 📋 SYS-009 设计整合与实现对齐
- [x] **完成 SYS-009 正式设计整合与实现边界收敛** ✅ (2026-03-20)
- [x] 已更新 `12_REV_Detailed.md`,补充 `REV-003``REV-008` 的实现边界与成熟度说明 ✅
- [x] 已更新 `03_Interface_Design.md`,补充签约、解约、状态查询、取消送盘、回盘状态与当前状态约束 ✅
- [x] 已更新 `01_Database_Design.md`,明确 `bk_*` 表族对象齐备但业务编排未闭环的边界 ✅
- [x] 已更新 `03_Summary_Design.md`,将 `SYS-009` 收敛为“已落地能力 + 后续完善项”口径 ✅
- [x] 已完成四份主文档 `make validate-file` 单文件校验并通过 ✅
### 📋 OMX 任务路由样例
- [x] **完成 OMX 任务路由样例落地** ✅ (2026-03-12)

View File

@ -27,9 +27,9 @@
| SYS002-REQ-002 | REV-001 | 开票/托收/代扣关系维护 | 维护客户开票资料、托收关系、代扣关系、渠道绑定关系 | SYS-008 / SYS-009 | IF-REV-002 | biz_cust_invoice、biz_cust_collection_rel、biz_cust_withholding_rel、biz_cust_app_binds | Story |
| SYS002-REQ-003 | REV-002 | 抄表任务与数据采集 | 生成抄表任务并提交人工/远传抄表数据 | IoT / SYS-006 | IF-REV-004 / IF-EXT-009 | biz_meter_read、biz_reading_data、biz_last_reading、biz_reading_logs | Story |
| SYS002-REQ-004 | REV-002 | 开账计费与账单生成 | 基于价格模板、阶梯规则、费用组成生成营业账 | - | IF-REV-005 | biz_charge、biz_charge_detail、biz_price_*、biz_cost_component | Story |
| SYS002-REQ-005 | REV-003 | 收费核销处理 | 柜台收费、余额抵扣、多账单组合核销 | SYS-009 | IF-REV-006 | biz_charge、biz_charge_detail、biz_collection | Story |
| SYS002-REQ-006 | REV-003 | 支付下单与结果回写 | 发起支付订单并处理异步回调结果 | SYS-009 | IF-EXT-004 / IF-EXT-005 | bk_transaction、bk_transaction_callback、bk_transaction_exception | Story |
| SYS002-REQ-007 | REV-004 | 账务调整处理 | 支持金额调整、水量调整、退款、冲正、坏账 | - | IF-REV-007 | biz_charge、biz_charge_detail、biz_operat_log、bk_transaction* | Story |
| SYS002-REQ-005 | REV-003 | 收费核销处理 | 柜台收费、余额抵扣、多账单组合核销,并沉淀业务支付事实/分配明细目标语义 | SYS-009 | IF-REV-006 | biz_charge、biz_charge_detail、biz_collection、目标/原型 biz_payment_record、biz_payment_record_detail | Story |
| SYS002-REQ-006 | REV-003 | 支付下单与结果回写 | 发起支付订单并处理异步回调结果;业务结果回写到账单与业务支付事实目标层 | SYS-009 | IF-EXT-004 / IF-EXT-005 | 渠道事实:bk_transaction、bk_transaction_callback、bk_transaction_exception业务事实目标层biz_payment_record、biz_payment_record_detail | Story |
| SYS002-REQ-007 | REV-004 | 账务调整处理 | 支持金额调整、水量调整、退款、冲正、坏账;引用原支付/渠道事实进行校验追溯 | - | IF-REV-007 | biz_charge、biz_charge_detail、biz_operat_log;引用 bk_transaction* 与目标/原型 biz_payment_record* | Story |
| SYS002-REQ-008 | REV-005 | 发票申请受理 | 对已收费未开票账单发起单笔/批量开票申请 | SYS-008 | IF-REV-008 / IF-EXT-006 | biz_invoice、biz_invoice_taxrate、biz_cust_invoice | Story |
| SYS002-REQ-009 | REV-005 | 发票结果查询与补偿 | 按申请单号/受理号查询开票结果并补偿 | SYS-008 | IF-REV-009 | biz_invoice、biz_operat_log | Story |
| SYS002-REQ-010 | REV-005 | 发票结果回写 | 回写开票状态、票号、下载地址、作废/红冲结果 | SYS-008 | IF-EXT-007 | biz_invoice、biz_process_invoice_modifys | Story |

View File

@ -147,7 +147,7 @@ retrieval_priority: P0
- 业务服务层SYS-001 统一平台、SYS-002 营收业务系统、SYS-003 手机抄表APP、SYS-004 微网厅系统、SYS-005 工单管理系统、SYS-006 表务管理系统、SYS-007 报装业务系统
- 基础服务层SYS-008 发票服务子系统统一开票、SYS-009 支付与银行结算子系统(统一聚合支付/退款/渠道适配/第三方支付平台/银行代扣/夜间批量代扣/对账/加解密/支付回调、SYS-010 消息服务子系统(统一短信/邮件/站内信/模板消息/微信通知/数科系统对接)、注册/配置中心、任务调度等基础服务
- 基础服务层SYS-008 发票服务子系统统一开票、SYS-009 支付与银行结算子系统(统一聚合支付/退款/渠道适配/第三方支付平台/银行实时收费、代扣/托收签解约、批次与对账契约、加解密与支付回调,夜间批量代扣/完整对账结算按后续完善项管理、SYS-010 消息服务子系统(统一短信/邮件/站内信/模板消息/微信通知/数科系统对接)、注册/配置中心、任务调度等基础服务
&emsp;&emsp;通过系统的建设,实现福建省水投数字科技有限公司客户服务管理领域的业务流程梳理再造、组织架构的优化、管理制度的建设、绩效考核标准的建设。构建以客户为中心的一体化服务体系,将客户的所有信息进行有机的关联,方便企业对营收信息进行综合分析和管理,为客户提供更多、更便捷、更主动的个性化服务,提高客户服务的质量和客户满意度。
@ -161,7 +161,7 @@ retrieval_priority: P0
- **表务管理系统**:设备档案、表务全生命周期管理
- **报装业务系统**:覆盖报装申请、踏勘、施工、验收、通水与档案归档的端到端流程,支持调用泛微进行合同签订,电子签章,支持各租户自定义报装流程和表单定义
- **发票服务子系统**(基础服务):统一开票网关与供应商适配(现优先对接航天,预留博思),回执与存证
- **支付与银行对接子系统**(基础服务):统一支付/退款、银行代扣送盘/回盘、对账处理、加解密签名,第三方支付平台(微信、支付宝),支持夜间进行批量代扣
- **支付与银行对接子系统**(基础服务):统一支付/退款、银行实时收费、代扣/托收签解约、送盘/回盘/对账契约、加解密签名与第三方支付平台(微信、支付宝);夜间批量代扣和完整结算闭环按后续完善项管理
- **消息服务子系统**(基础服务):统一短信/邮件/站内信/模板消息下行推送与到达回执供各业务子系统调用如营收业务系统催缴微信信息通知对接数科已建系统通知OA、智水擎水投数科 app
### 功能范围
@ -206,6 +206,7 @@ retrieval_priority: P0
#### SYS-009 支付与银行结算子系统(基础服务)
- 聚合支付/退款、渠道适配(微信/支付宝/银联聚合等)、第三方支付平台(微信、支付宝)、支付结果通知、银行代扣(送盘/回盘)、支持夜间进行批量代扣、对账文件处理、加解密/签名
- 当前实现侧已确认聚合支付基础能力、银行欠费查询/缴费、`BankWithholding` 六条银行入口(客户状态查询、送盘、送盘状态查询、取消送盘、回盘、回盘状态查询)、代扣/托收签约解约和后台资源管理具备证据;其中 `BankCollection` 平行链路、夜间批量代扣、完整对账与结算仍按部分实现或后续完善项管理
#### SYS-010 消息服务子系统(基础服务)
@ -747,7 +748,7 @@ graph TB
| SYS-006 | 表务管理系统 | 设备档案、表务全生命周期管理 | 自行开发 |
| SYS-007 | 报装业务系统 | 报装流程管理、合同签订与电子签章、工程管理、档案管理 | 自行开发 |
| SYS-008 | 发票服务子系统 | 统一开票网关、供应商适配器(优先对接航天)、回执处理与存证 | 自行开发 |
| SYS-009 | 支付与银行结算子系统 | 聚合支付/退款、渠道适配(微信/支付宝/银联)、支付通知、银行代扣送盘/回盘、夜间批量代扣、对账处理、加解密签名 | 自行开发 |
| SYS-009 | 支付与银行结算子系统 | 聚合支付/退款、渠道适配(微信/支付宝/银联)、支付通知、银行实时收费、代扣/托收签解约、送盘/回盘/对账契约、加解密签名;夜间批量代扣与完整结算闭环按后续完善项管理 | 自行开发 |
| SYS-010 | 消息服务子系统 | 短信/邮件/站内信模板与发送、回执查询、批量推送 | 自行开发 |
### 子系统间关系
@ -876,7 +877,7 @@ graph TB
| IF-REV-001 | 客户信息查询接口 | 查询客户档案、账户状态、联系人与水表绑定关系 | 柜台/客户渠道/工单 | HTTPS REST | 客户ID、客户编号、手机号、查询类型 | 客户档案、账户信息、联系人列表、水表绑定关系 |
| IF-REV-004 | 抄表数据提交接口 | 提交人工或远传抄表数据并触发校验 | 手机抄表APP/集抄系统 | HTTPS REST | 抄表任务ID、水表ID、读数、图片证据、GPS位置 | 上传结果、校验状态、异常标记 |
| IF-REV-005 | 账单生成接口 | 根据抄表结果、水价模板和费用组成生成账单 | 开账任务/批量任务 | HTTPS REST | 抄表批次、账期、客户范围、应收日期 | 账单结果、失败清单、生成汇总 |
| IF-REV-006 | 缴费处理接口 | 创建收费记录并核销账单 | 柜台/线上渠道 | HTTPS REST | 客户ID、账单ID列表、支付方式、实收金额 | 收费结果、核销状态、交易流水 |
| IF-REV-006 | 缴费处理接口 | 创建收费记录并核销账单,形成业务支付事实与分配明细的目标语义 | 柜台/线上渠道 | HTTPS REST | 客户ID、账单ID列表、支付方式、实收金额 | 收费结果、核销状态、交易流水、业务支付记录 |
| IF-REV-008 | 发票申请接口 | 发起电子发票申请并接收票据状态回写 | 柜台/客户渠道 | HTTPS REST | 客户ID、账单ID列表、开票抬头、税号、邮箱 | 发票申请结果、票据状态、下载地址 |
| IF-REV-011 | 银行代收协同接口 | 发起代扣、回盘、对账、结算协同 | 银行代收模块/SYS-009 | HTTPS REST / 文件交换 | 批次号、渠道编码、账期、账单明细 | 批次状态、回盘结果、对账差异、结算结果 |
| IF-REV-012 | 业务参数配置接口 | 查询和维护价格模板、优惠方案、业务参数配置 | 管理后台/参数管理端 | HTTPS REST | 参数分类、模板编码、站点范围 | 参数明细、模板信息、更新结果 |
@ -1747,8 +1748,8 @@ graph TD
- **客户资料管理**:客户档案建立、信息维护、分组管理
- **抄表开账**:抄表数据录入、复核确认、自动开账
- **营业收费**:柜台收费、移动收费、在线缴费
- **账务处理**:一期先聚焦水量调整、金额调整、退款、冲正、坏账申请,统一经 `IF-REV-007` 承接,并按共性能力先统一、场景能力再分批推进
- **营业收费**:柜台收费、移动收费、在线缴费,并作为业务支付事实层(目标语义:`biz_payment_record` / `biz_payment_record_detail`)的归属模块
- **账务处理**:一期先聚焦水量调整、金额调整、退款、冲正、坏账申请,统一经 `IF-REV-007` 承接;退款、冲正等场景引用 `REV-003` 业务支付事实与 `SYS-009` 渠道交易事实,不再作为支付主域
- **发票管理**:发票开具、查询、重开、作废
- **催缴管理**:欠费统计、催缴通知、停水管理
- **统计分析**:多维度数据统计和报表分析
@ -1803,7 +1804,7 @@ graph TD
| IF-REV-001 | 客户信息查询接口 | 查询客户档案、账户状态、联系人与水表绑定关系 | 柜台/客户渠道/工单 | HTTPS REST | 客户ID、客户编号、手机号、查询类型 | 客户档案、账户信息、联系人列表、水表绑定关系 |
| IF-REV-004 | 抄表数据提交接口 | 提交人工或远传抄表数据并触发校验 | 手机抄表APP/集抄系统 | HTTPS REST | 抄表任务ID、水表ID、读数、图片证据、GPS位置 | 上传结果、校验状态、异常标记 |
| IF-REV-005 | 账单生成接口 | 根据抄表结果、水价模板和费用组成生成账单 | 开账任务/批量任务 | HTTPS REST | 抄表批次、账期、客户范围、应收日期 | 账单结果、失败清单、生成汇总 |
| IF-REV-006 | 缴费处理接口 | 创建收费记录并核销账单 | 柜台/线上渠道 | HTTPS REST | 客户ID、账单ID列表、支付方式、实收金额 | 收费结果、核销状态、交易流水 |
| IF-REV-006 | 缴费处理接口 | 创建收费记录并核销账单,形成业务支付事实与分配明细的目标语义 | 柜台/线上渠道 | HTTPS REST | 客户ID、账单ID列表、支付方式、实收金额 | 收费结果、核销状态、交易流水、业务支付记录 |
| IF-REV-008 | 发票申请接口 | 发起电子发票申请并接收票据状态回写 | 柜台/客户渠道 | HTTPS REST | 客户ID、账单ID列表、开票抬头、税号、邮箱 | 发票申请结果、票据状态、下载地址 |
| IF-REV-011 | 银行代收协同接口 | 发起代扣、回盘、对账、结算协同 | 银行代收模块/SYS-009 | HTTPS REST / 文件交换 | 批次号、渠道编码、账期、账单明细 | 批次状态、回盘结果、对账差异、结算结果 |
| IF-REV-012 | 业务参数配置接口 | 查询和维护价格模板、优惠方案、业务参数配置 | 管理后台/参数管理端 | HTTPS REST | 参数分类、模板编码、站点范围 | 参数明细、模板信息、更新结果 |
@ -1973,8 +1974,8 @@ graph TB
|---|---|---|---|
| REV-001 | 客户资料管理 | 客户档案管理、客户分组、信息变更 | 自行开发 |
| REV-002 | 抄表开账 | 抄表录入、复核开账、异常处理 | 自行开发 |
| REV-003 | 营业收费 | 柜台收费、移动收费、在线缴费 | 自行开发 |
| REV-004 | 账务处理 | 账务调整、退款处理、坏账管理 | 自行开发 |
| REV-003 | 营业收费 | 柜台收费、移动收费、在线缴费、业务支付事实与分配明细(目标语义) | 自行开发 |
| REV-004 | 账务处理 | 账务调整、退款处理、坏账管理;引用收费/支付事实,不拥有支付主域 | 自行开发 |
| REV-005 | 发票管理 | 发票开具、查询管理、电子发票 | 自行开发 |
| REV-006 | 催缴管理 | 欠费催缴、短信通知、停水管理 | 自行开发 |
| REV-007 | 统计分析 | 多维度数据统计和报表分析功能 | 自行开发 |
@ -2253,7 +2254,7 @@ flowchart TD
**功能概述:**
&emsp;&emsp;营业收费模块提供完整的收费业务流程管理,支持多种收费方式和支付渠道。
&emsp;&emsp;营业收费模块提供完整的收费业务流程管理,支持多种收费方式和支付渠道。业务归属上,`REV-003` 承接“账单核销后的业务支付事实”与“支付分配明细”的目标语义;`SYS-009` 继续承接银行、聚合支付、回调、对账、结算等渠道事实。当前文档中的 `biz_payment_record` / `biz_payment_record_detail` 仅表达目标/原型层,不等同于已验真的生产表。
**核心功能:**
@ -2333,7 +2334,7 @@ flowchart TD
**功能概述:**
&emsp;&emsp;负责处理各类复杂的账务调整、退款、坏账等业务,确保账务的准确性和合规性。
&emsp;&emsp;负责处理各类复杂的账务调整、退款、坏账等业务,确保账务的准确性和合规性。`REV-004` 需要引用原收费记录、业务支付事实与渠道交易事实进行校验和追溯,但不重新定义支付主单或渠道流水主模型。
**核心功能:**
@ -3675,14 +3676,14 @@ graph TD
## 任务概述
&emsp;&emsp;支付与银行结算子系统SYS-009统一承载聚合支付/退款、渠道适配(微信/支付宝/银联聚合)、支付回调验签入账,以及银行代扣(送盘/回盘)、支持夜间进行批量代扣、对账文件处理与安全加解密/签名,向上对营收/微网厅等系统提供标准化支付与结算能力。
&emsp;&emsp;支付与银行结算子系统SYS-009统一承载聚合支付/退款、渠道适配(微信/支付宝/银联聚合)、支付回调验签入账,以及银行实时收费、代扣/托收签约解约、送盘/回盘/对账契约与安全加解密/签名,向上对营收/微网厅等系统提供标准化支付与结算能力。夜间批量代扣、完整回盘状态补偿、对账差异处理与结算确认当前仍按后续完善项管理。
## 设计概述
### 总体约束
- 多渠道聚合:统一接入微信/支付宝/银联聚合
- 统一结算:批量代扣送回盘、批量对账文件处理、差异对齐
- 统一结算:统一维护批次、回盘、对账和差异语义,完整结算闭环按后续完善项推进
- 安全合规:签名/验签、加解密、回调防重放、幂等
- 高可用:基础重试补偿机制
@ -3692,7 +3693,7 @@ graph TD
### 子系统外部接口SYS-009
&emsp;&emsp;支付与银行结算子系统作为统一的支付能力中心,为上游业务系统提供聚合支付、银行代扣、退款处理、对账管理等全方位的支付结算服务。系统与微信支付、支付宝、银联聚合及各大银行系统对接,提供安全可靠的支付解决方案
&emsp;&emsp;支付与银行结算子系统作为统一的支付能力中心,为上游业务系统提供聚合支付、银行实时收费、代扣/托收签解约、退款处理、对账管理等支付结算服务。以下接口表表达的是正式设计目标边界,其中聚合支付、实时收费查询/缴费、代扣/托收签解约已具备较明确实现证据;`BankWithholding` 六条银行入口已形成最小实现态闭环,托收平行链路、对账和完整结算闭环仍按部分实现或后续完善项管理
| 接口编号 | 接口名称 | 功能描述 | 调用方 | 接口协议 | 输入参数 | 输出结果 |
|---|---|---|---|---|---|---|
@ -3700,9 +3701,9 @@ graph TD
| IF-PAY-002 | 统一关单接口 | 订单关闭和撤销处理 | 营收系统/微网厅 | HTTP/REST | 订单号、关闭原因、操作类型 | 关单状态、退款信息、处理结果 |
| IF-PAY-003 | 统一退款接口 | 原路退款和部分退款处理 | 营收系统/微网厅 | HTTP/REST | 原订单号、退款金额、退款原因 | 退款单号、退款状态、预计到账时间 |
| IF-PAY-004 | 支付回调接口 | 接收渠道支付结果回调 | 微信/支付宝/银联 | HTTP/REST | 回调数据、签名、时间戳 | 处理确认、业务更新状态 |
| IF-PAY-005 | 批量代扣送盘接口 | 银行批量代扣文件发送 | 营收业务系统 | HTTP/REST/SFTP | 代扣清单、客户签约信息、扣款金额 | 送盘状态、批次号、预计处理时间 |
| IF-PAY-006 | 批量代扣回盘接口 | 银行代扣结果回盘处理 | 银行系统 | HTTP/REST/SFTP | 回盘文件、处理结果、失败原因 | 解析结果、状态更新、异常处理 |
| IF-PAY-007 | 批量对账文件接口 | 银行对账文件处理分析 | 银行系统/营收系统 | HTTP/REST/SFTP | 对账文件、对账日期、差异规则 | 对账结果、差异明细、调整建议 |
| IF-PAY-005 | 批量代扣送盘接口 | 银行批量代扣文件发送 | 营收业务系统 | HTTP/REST/SFTP | 代扣清单、客户签约信息、扣款金额 | 送盘状态、批次号、预计处理时间`BankWithholding` 已具备最小实现态闭环;真实文件通道联调仍待补证) |
| IF-PAY-006 | 批量代扣回盘接口 | 银行代扣结果回盘处理 | 银行系统 | HTTP/REST/SFTP | 回盘文件、处理结果、失败原因 | 解析结果、状态更新、异常处理`BankWithholding` 已具备最小实现态闭环;真实文件解析与异常补偿仍待补证) |
| IF-PAY-007 | 批量对账文件接口 | 银行对账文件处理分析 | 银行系统/营收系统 | HTTP/REST/SFTP | 对账文件、对账日期、差异规则 | 对账结果、差异明细、调整建议(当前仍按部分实现或后续完善项管理) |
| IF-PAY-008 | 加解密签名接口 | 支付数据安全处理 | 内部模块调用 | HTTP/REST | 待处理数据、加密类型、签名算法 | 处理结果、安全凭证、验证状态 |
## 子系统架构设计
@ -3831,6 +3832,7 @@ graph TD
- 差异识别与异常记录
- 冲正/补记建议生成
- 对账报告与追踪链路告警
- 当前阶段按目标能力保留正式设计口径,不直接表述为已形成完整闭环
#### PAY-006: 加解密/签名

View File

@ -84,8 +84,8 @@ retrieval_priority: P1
| `UP-004` | 审计监控与运维支撑 | [章节](./11_UP_Detailed.md#mod-up-004) | 操作日志、接口日志、任务日志 | `IF-UP-003`(审计关联) | 运维平台、消息服务 |
| `REV-001` | 客户资料管理 | [章节](./12_REV_Detailed.md#mod-rev-001) | 客户、账户、联系人、绑定关系 | `IF-REV-001` | 客户服务、表务、报装 |
| `REV-002` | 抄表开账 | [章节](./12_REV_Detailed.md#mod-rev-002) | 抄表任务、读数、账单主明细 | `IF-REV-004``IF-REV-005` | 抄表APP、IoT、表务 |
| `REV-003` | 营业收费 | [章节](./12_REV_Detailed.md#mod-rev-003) | 营业账、交易流水、回调记录 | `IF-REV-006` | `SYS-009` 支付结算 |
| `REV-004` | 账务处理 | [章节](./12_REV_Detailed.md#mod-rev-004) | 账单调整、日志、审批留痕 | `IF-REV-007` | 财务、营收后台 |
| `REV-003` | 营业收费 | [章节](./12_REV_Detailed.md#mod-rev-003) | 营业账、业务支付事实/分配明细目标层、渠道交易流水、回调记录 | `IF-REV-006` | `SYS-009` 支付结算`bk_transaction*` 归渠道事实 |
| `REV-004` | 账务处理 | [章节](./12_REV_Detailed.md#mod-rev-004) | 账单调整、日志、审批留痕;引用原支付/渠道事实 | `IF-REV-007` | 财务、营收后台;不拥有支付主域 |
| `REV-005` | 发票与税务处理 | [章节](./12_REV_Detailed.md#mod-rev-005) | 发票主记录、税率、开票信息 | `IF-REV-008` | `SYS-008` 发票服务 |
| `REV-006` | 催缴与通知 | [章节](./12_REV_Detailed.md#mod-rev-006) | 欠费账单、催缴结果 | `IF-REV-009` | `SYS-010` 消息服务 |
| `REV-007` | 统计分析 | [章节](./12_REV_Detailed.md#mod-rev-007) | 客户、抄表、收费、渠道聚合 | `IF-REV-010` | 报表与管理端 |

View File

@ -56,8 +56,8 @@ retrieval_priority: P1
|---|---|---|---|
| REV-001 客户资料管理 | `IF-REV-001` | `biz_cust``biz_account``biz_cust_*` | 客户服务模块、报装模块 |
| REV-002 抄表开账 | `IF-REV-004``IF-REV-005` | `biz_meter_book``biz_meter_read``biz_reading_*``biz_charge*` | 抄表APP、物联网集抄 |
| REV-003 营业收费 | `IF-REV-006` | `biz_charge*``biz_collection``bk_transaction*` | `SYS-009` |
| REV-004 账务处理 | `IF-REV-007` | `biz_charge*``biz_operat_log*` | 财务与营业人员 |
| REV-003 营业收费 | `IF-REV-006` | `biz_charge*``biz_collection`目标/原型 `biz_payment_record*``bk_transaction*` | `SYS-009` |
| REV-004 账务处理 | `IF-REV-007` | `biz_charge*``biz_operat_log*`;引用 `REV-003` 支付事实与 `SYS-009` 渠道事实 | 财务与营业人员 |
| REV-005 发票与税务处理 | `IF-REV-008` | `biz_invoice*``biz_cust_invoice` | `SYS-008` |
| REV-006 催缴与通知 | `IF-REV-013` | `biz_charge*`、催缴结果留痕 | `SYS-010` |
| REV-007 统计分析 | `IF-REV-010` | 客户、抄表、收费、渠道聚合对象 | 统计分析端 |
@ -220,7 +220,7 @@ flowchart TD
### 功能说明
支持柜台收费、预存款/余额抵扣、线上缴费回写、柜面扫码、营业网点收费及收费凭证管理,统一承接营收账单的核销处理。
支持柜台收费、预存款/余额抵扣、线上缴费回写、柜面扫码、营业网点收费及收费凭证管理,统一承接营收账单的核销处理。领域边界上,`REV-003` 是业务支付事实与支付分配明细的归属模块;`SYS-009` 只承接渠道交易、回调、对账和结算事实。
### 业务流程
@ -245,13 +245,15 @@ flowchart TD
1. 一次缴费可对应多个账单或账单明细的组合核销。
2. 收费记录必须保留渠道、流水号、网点、操作员、终端信息。
3. 线上支付必须以回调或查询确认结果为准,不得以发起状态直接记账。
4. 支付能力由 `SYS-009` 提供SYS-002 负责账单核销与业务状态回写。
4. 支付能力由 `SYS-009` 提供SYS-002 负责账单核销、业务支付事实沉淀与业务状态回写;渠道交易事实不替代业务支付分配明细。
5. 当前实现侧已确认 `PayCeb` 的欠费查询、缴费处理基础闭环可用,但代理收费对账仍为预留能力;正式文档不得将实时收费对账写成已闭环能力。
### 核心数据
- `biz_charge``biz_charge_detail`:待缴与已缴账单主明细。
- `biz_collection`:托收/代收主表。
- `biz_withholding`:代扣/托收主表。
- `biz_payment_record``biz_payment_record_detail`:业务支付主单与分配明细的目标/原型对象,承接旧 `PM_PAY_DETAILS` 的实收、实销、滞纳金、红冲关联等核心语义;未完成实现验真前不得表述为已落地生产表。
- `bk_transaction`:渠道交易流水。
- `bk_transaction_callback`:支付回调记录。
- `bk_transaction_exception`:支付异常记录。
@ -276,6 +278,12 @@ flowchart TD
- 当前设计可将红冲视为收费核销后的修正场景,不强制要求独立实体表,但必须提供历史只读查询口径。
- 红冲迁移最小保留信息应包括原收费记录、红冲时间、红冲金额、原因、经办人、关联账单和后续账务状态。
#### 旧支付明细与汇总台账
- 旧 `PM_PAY_DETAILS` 的实收金额、实销金额、滞纳金、收费员、红冲关联等字段应优先映射到 `REV-003` 业务支付事实目标层,而不是直接等同于 `SYS-009` 的渠道交易流水。
- 旧 `PM_PAY_SUBTOTALS``PM_PAY_COLLECTS` 更接近班结/汇总/报表口径,可由 `biz_payment_record*``biz_collection``bk_transaction*` 和历史只读归档共同支撑,不建议为旧汇总表机械复制一套在线主表。
- 旧 `PM_REALTIMES*` 如仅用于实时收费过程日志和历史查询,迁移时按历史只读与操作留痕保留;真正发生业务核销时仍回归 `IF-REV-006` 与业务支付事实目标层。
### 接口映射
- `IF-REV-006`:创建收费记录、执行账单核销并回写状态。
@ -314,7 +322,7 @@ flowchart TD
1. 一期场景严格限定为水量调整、金额调整、退款、冲正、坏账申请,不扩展到其他接口族或独立账务台账重构。
2. 所有场景均以 `biz_charge` / `biz_charge_detail` 为主承接对象,并通过 `biz_operat_log` / `biz_operat_log_detail` 记录处理依据、前后变化和责任归属。
3. 退款、冲正必须联动 `bk_transaction`、`bk_transaction_callback``bk_transaction_exception`原支付流水及渠道状态校验,不允许仅依据账单状态直接处理。
3. 退款、冲正必须联动 `REV-003` 业务支付事实目标层与 `bk_transaction`、`bk_transaction_callback``bk_transaction_exception` 等渠道状态校验,不允许仅依据账单状态直接处理。
4. 接口结果统一返回 `resultStatus``writeBackStatus`,其中 `resultStatus` 表示处理结论,`writeBackStatus` 表示账单状态回写结论,两者不得混用。
5. 审批相关内容一期仅保留 `approvalRequired``PENDING_APPROVAL` 与审批边界说明,不展开完整 BPM 流程、节点、流转规则或审批回写实现细节。
6. 对于当前未见明确独立实体表的特账、跨周期水量、退款账等对象,文档以“业务处理场景”表述,不强行落为已实现表。
@ -322,7 +330,8 @@ flowchart TD
### 核心数据
- `biz_charge``biz_charge_detail`:账务调整的核心对象,承接调整前后账单主明细状态。
- `bk_transaction``bk_transaction_callback``bk_transaction_exception`:退款、冲正场景的原交易校验与异常追溯对象。
- `biz_payment_record``biz_payment_record_detail`:退款、冲正、预存转退等场景引用的业务支付事实目标层,用于追溯原收款与核销分配关系。
- `bk_transaction``bk_transaction_callback``bk_transaction_exception`:退款、冲正场景的渠道交易校验与异常追溯对象。
- 价格调整/优惠相关表:用于重算账单或差额追溯。
- `biz_operat_log``biz_operat_log_detail`:操作与变更留痕,记录字段差异、处理说明、附件依据与责任归属。
@ -623,6 +632,11 @@ flowchart TD
2. 实时收费场景由渠道交易流水驱动账单核销,批量代扣场景由签约关系与批次处理驱动。
3. 对账结果区分一致、长款、短款、失败待处理等状态,支持差异追踪与人工补偿。
4. 国密报文、批量文件、标准 API 等技术细节由 `SYS-009` 承载SYS-002 保留业务规则与状态协同。
5. 当前 backend 已确认 `BankWithholding` 六条银行入口(客户状态查询、送盘、送盘状态查询、取消送盘、回盘、回盘状态查询)已形成最小实现态闭环;`BankCollection` 平行链路、对账与结算协同仍以“部分实现或文档先行”表述,不得统一写成已闭环能力。
6. 银行代扣文件传输配置按“默认规则 + 银行通道覆盖 + 租户覆盖 + 租户-银行通道覆盖”建模,命中优先级固定为 `TENANT_CHANNEL > TENANT > CHANNEL > DEFAULT`
7. 目录字段至少区分 `send/back/reconcile/archive/localTemp` 五类阶段;上层覆盖未完整定义时按字段级回退,不允许生成空路径。
8. 路径模板仅允许 `{tenantId}``{companyId}``{channelCode}``{yyyyMMdd}``{yyyyMM}``{batchNo}``{fileName}` 七个固定变量;命中未声明变量或缺少变量取值时立即阻断文件动作。
9. `BankWithholding` 在送盘创建时固化 `sendProtocol/sendDir/sendFilePath``backProtocol/backDir`,配置切换仅影响新发起文件动作,已落库批次继续沿用原解析结果。
### 核心数据
@ -636,6 +650,12 @@ flowchart TD
- `bk_transaction``bk_transaction_callback``bk_transaction_exception`:交易、回调、异常。
- `biz_collection``biz_withholding`:代收/代扣业务主对象。
#### 文件传输配置与审计补充
- 环境默认规则通过 Spring profile + Nacos 承接,不在仓库样例中写入真实密码、私钥或证书。
- `bk_channel_api_config` 使用专用 `apiType=FILE_TRANSFER_CONFIG` 承接文件传输覆盖配置,`extParams` 记录作用域、业务类型、协议、连接引用和五类目录字段。
- `bk_withholding_batch` 固化送盘/回盘目录与协议,`bk_reconcile_batch` 固化对账阶段最终 `protocol/dir/filePath/fileName`,用于审计与问题回放。
### 迁移补充(旧系统承接)
#### 银行托收
@ -650,16 +670,24 @@ flowchart TD
- 当前建议以 `bk_transaction*` 作为主承接对象,并补充按结算日期、银行/渠道、收费结果、差异状态查询和导出能力说明。
- 对旧“实时收费汇总/日志/明细”对象P0 阶段先按历史只读查询口径保留,不误写为当前已落地的独立主模型。
#### 当前实现对齐说明
- `PayCeb` 路径已具备欠费查询、缴费处理、流水唯一性校验和交易日志留痕,可作为实时收费基础闭环的实现证据。
- `BankWithholding` 路径已具备签约、解约、客户状态查询、送盘、送盘状态查询、取消送盘、回盘、回盘状态查询及对应交易留痕的实现证据,可作为代扣最小实现态闭环依据。
- `BankCollection` 路径当前仍仅能确认签约、解约与协议/交易日志处理具备实现证据。
- 对账、结算、真实银行文件解析、SFTP/文件通道联调和运行态样本补证当前仍未闭环,正式文档应继续保留为后续完善项。
### 接口映射
- `IF-REV-011`:代扣批次、对账与结算协同入口。
- `IF-EXT-001`:银行代扣批次下发与回盘协同。
- `IF-EXT-003`:银行实时收费查询、缴费与结果确认协同。
### 落地边界
- **已落地**:渠道、路由、交易、回调、异常、签约、批次、对账、结算等主链路对象
- **部分落地**部分统计类、汇总类对象可能在渠道报表或外部结算文件层体现
- **文档先行**不将未明确扫描到的扩展银行台账写成已实现独立表
- **已落地**:渠道、路由、交易、回调、异常、代扣/托收签约、解约,以及 `BankWithholding` 的客户状态查询、送盘、送盘状态查询、取消送盘、回盘、回盘状态查询和对应日志留痕等主对象已具备明确实现证据
- **部分落地**`BankCollection` 批次、明细、送盘、回盘、状态查询、差异台账和后台资源管理入口已具备对象或骨架,但不等同于银行协同闭环全部完成;`BankWithholding` 的真实文件解析、异常补偿和运行态联调证据仍待补齐
- **文档先行**夜间批量代扣调度、完整对账处理、结算确认、扩展银行台账等内容不得在当前阶段写成已完成能力
<a id="mod-rev-009"></a>

View File

@ -75,7 +75,7 @@ retrieval_priority: P0
| SYS-002 基础配置与价格体系 | `biz_community`, `biz_company_*`, `biz_meter_*`, `biz_price_*`, `biz_template_*` | 小区、水司账户、水表参数、价格体系、调价快照、优惠方案、模板关系等 | 已按真实表对齐 |
| SYS-002 客户主数据与账户关系 | `biz_cust*`, `biz_account` | 客户主档、联系人、客户组、水表绑定、开票信息、托收/代扣关系、编号规则等 | 已按真实表对齐 |
| SYS-002 抄表开账与账单 | `biz_meter`, `biz_meter_book`, `biz_meter_read`, `biz_reading_*`, `biz_charge*` | 抄表册本、抄表状态、读数留痕、开账主单与明细 | 已按真实表对齐 |
| SYS-002 收费票据与操作留痕 | `biz_collection`, `biz_withholding`, `biz_invoice*`, `biz_operat_log*` | 收费、托收/代扣、发票、操作留痕与审计支撑 | 已按真实表对齐 |
| SYS-002 收费票据与操作留痕 | `biz_collection`, `biz_withholding`, `biz_invoice*`, `biz_operat_log*`;目标/原型:`biz_payment_record*` | 收费、托收/代扣、业务支付事实目标层、发票、操作留痕与审计支撑 | 真实表已按现状对齐`biz_payment_record*` 需实现验真后升级为已落地 |
| SYS-002 业务办理与资料 | `biz_process*`, `biz_business_*`, `biz_content*` | 业务办理流程、流转、装表资料、附件与扩展数据 | 已按真实表对齐 |
| SYS-002 银行代收与结算 | `bk_*` | 渠道路由、交易回调、代扣签约、批次、对账、结算 | 已按真实表对齐 |
| SYS-003 手机抄表 APP | `mobile_*` | 移动作业缓存、登录日志、离线任务与现场上报 | 保持现稿 |
@ -1072,7 +1072,7 @@ retrieval_priority: P0
| `biz_water_use_scheme_tier` | `scheme_code`, `tier_level`, `start_volume`, `end_volume` | 用水阶梯 |
| `biz_exceed_water_use_scheme` | `scheme_code`, `exceed_type`, `price_rule` | 超计划规则 |
## SYS-002 开账、收费与票据表 (`biz_charge*` / `biz_collection` / `biz_withholding` / `biz_invoice*`)
## SYS-002 开账、收费与票据表 (`biz_charge*` / `biz_collection` / `biz_withholding` / 目标 `biz_payment_record*` / `biz_invoice*`)
### biz_charge (营业账主表)
| 字段名 | 说明 |
@ -1121,6 +1121,23 @@ retrieval_priority: P0
| `biz_collection` | `code`, `cust_id`, `charge_id`, `collection_status` | 托收主表 |
| `biz_withholding` | `code`, `cust_id`, `charge_id`, `withholding_status` | 代扣主表 |
### biz_payment_record / biz_payment_record_detail (业务支付事实目标层)
> 当前口径:`biz_payment_record``biz_payment_record_detail` 用于表达 `REV-003` 下业务支付主单与账单/费用分配明细的目标/原型语义。除非后续 DDL、Mapper、Service 与测试库实表均完成验真,数据库主文档不得将其表述为已确认生产表。
| 表名 | 目标关键字段 | 说明 |
| :--- | :--- | :--- |
| `biz_payment_record` | `payment_no`, `cust_id`, `payment_amount`, `payment_channel`, `payment_time`, `source_transaction_no`, `payment_status` | 业务支付事实主单,表达一次业务收款/核销结果,与 `bk_transaction*` 的渠道交易事实通过交易号或渠道单号关联 |
| `biz_payment_record_detail` | `payment_id`, `charge_id`, `charge_detail_id`, `detail_type`, `allocated_amount`, `late_fee_amount` | 支付分配明细,表达一笔收款对账单、费用组成、本金/违约金等核销对象的分配关系 |
#### REV-003 支付事实分层口径
| 层次 | 主对象 | 归属 | 说明 |
| :--- | :--- | :--- | :--- |
| 账单结果投影 | `biz_charge``biz_charge_detail` | `REV-002` / `REV-003` 联动 | 表达应收、欠费、已缴、核销状态等账单结果,不承载完整支付主单语义 |
| 业务支付事实目标层 | `biz_payment_record``biz_payment_record_detail` | `REV-003` | 表达业务收款事实与分配明细,承接旧 `PM_PAY_DETAILS` 的实收、实销、滞纳金、红冲关联等核心语义 |
| 渠道交易事实 | `bk_transaction*` | `SYS-009` | 表达银行/聚合支付/回调/对账/结算渠道事实,不直接替代业务支付分配明细 |
### biz_invoice / biz_invoice_taxrate (发票主表与税率表)
| 表名 | 关键字段 | 说明 |
| :--- | :--- | :--- |
@ -1153,7 +1170,7 @@ retrieval_priority: P0
| 旧对象/旧菜单 | 当前主口径 | 承接方式 | 数据策略 |
| :--- | :--- | :--- | :--- |
| 开账记录、特殊开账 | `biz_charge``biz_charge_detail``biz_operat_log*` | 统一纳入营业账主表与明细表,特殊开账按来源类型、业务类型、依据说明留痕,不单设平行“特殊开账表” | 在线保留 |
| 柜台收费、实时收费、代收代扣 | `biz_collection``biz_withholding``bk_transaction*``bk_withholding_*` | 统一纳入收费主模型与渠道交易模型,柜台班结/实时收费日志按交易结果和操作留痕归并 | 在线保留 |
| 柜台收费、实时收费、代收代扣 | `biz_collection``biz_withholding`目标/原型 `biz_payment_record*``bk_transaction*``bk_withholding_*` | 统一纳入收费主模型、业务支付事实目标层与渠道交易模型,柜台班结/实时收费日志按交易结果、支付分配和操作留痕归并 | 在线保留 / 目标层待验真 |
| 发票申请、开票结果、票据税率 | `biz_invoice``biz_invoice_taxrate``biz_cust_invoice` | 统一纳入发票主表、税率表和客户开票信息,不为旧“营业账开票表”机械复制新在线表 | 在线保留 |
| 微网厅业务字段、页面配置、微信参数 | `biz_business_types``biz_business_datas``biz_page_settings*``biz_parameter_settings``sys_wechat_app_settings` | 统一归并为业务类型、页面配置和渠道参数模型 | 在线保留 |
| 办理附件、电子档案 | `biz_content``biz_content_attach` | 当前新增与迁移后新增资料统一按资料主表与附件表承接 | 在线保留 |
@ -1174,7 +1191,7 @@ retrieval_priority: P0
| 对账主题 | 最低核对维度 | 主口径来源 | 验收要求 |
| :--- | :--- | :--- | :--- |
| 开账记录 | 客户数、账单数、账期、应收金额 | `biz_charge``biz_charge_detail` + 历史账单来源 | 支持按账期、营业所、客户类型汇总比对 |
| 缴费记录 | 收费笔数、实收金额、渠道、核销状态 | `biz_collection``bk_transaction*` | 支持按渠道、日期、营业所汇总比对 |
| 缴费记录 | 收费笔数、实收金额、渠道、核销状态、分配金额 | `biz_collection`目标/原型 `biz_payment_record*``bk_transaction*` | 支持按渠道、日期、营业所汇总比对,并区分业务支付事实与渠道交易事实 |
| 发票记录 | 开票笔数、金额、状态、票据类型 | `biz_invoice*` + 历史开票关系 | 支持按发票状态、开票日期比对 |
| 红冲与账务调整 | 调整笔数、调整金额、处理结果 | 账务处理结果 + 历史台账 | 支持汇总与单据级差异定位 |
| 催缴与停复水 | 通知笔数、执行结果、停复水状态 | `IF-REV-013` 任务结果 + 历史记录 | 支持按账期、客户、执行状态、处置引用比对 |
@ -1223,6 +1240,8 @@ retrieval_priority: P0
| `bk_reconcile_diff` | `batch_id`, `trade_no`, `diff_type`, `diff_amount` | 对账差异 |
| `bk_settlement_batch` | `batch_no`, `channel_code`, `settlement_date`, `settlement_status` | 结算批次 |
> 当前实现边界说明:`bk_*` 表族已形成较完整的对象承接口径,且签约、解约、交易流水与后台资源管理具备明确实现证据;但送盘、回盘、对账、结算等业务编排仍缺少完整闭环与统一迁移证据,数据库专项不得据此倒推出“银行协同已全部落地”。
</details>
<a id="sec-meter-inst-topic"></a>

View File

@ -95,8 +95,8 @@ retrieval_priority: P0
|---------|----------|-------------|
| REV-001 | 客户资料管理 | 客户、账户、联系人、水表绑定等主数据查询与维护 |
| REV-002 | 抄表开账 | 抄表任务、抄表数据、校验、开账触发 |
| REV-003 | 营业收费 | 收费受理、账单核销、柜台与渠道收款状态回写 |
| REV-004 | 账务处理 | 调整、退款、冲正、坏账等账务处理申请与结果回写 |
| REV-003 | 营业收费 | 收费受理、账单核销、柜台与渠道收款状态回写,并承接业务支付事实与分配明细的目标语义 |
| REV-004 | 账务处理 | 调整、退款、冲正、坏账等账务处理申请与结果回写;仅引用原支付/渠道事实,不拥有支付主域 |
| REV-005 | 发票管理 | 发票申请、开票结果回写、票据状态查询 |
| REV-006 | 催缴管理 | 催缴名单生成、催缴任务下发、通知结果回写 |
| REV-007 | 统计分析 | 营收、抄表、收费、客户、渠道统计查询 |
@ -150,6 +150,13 @@ retrieval_priority: P0
关键报文信息包括:客户号、签约号、扣款金额、账期、渠道编码、批次号等。
边界约束:
- 当前正式设计包含代扣送盘、回盘与对账的目标边界;其中 `BankWithholding` 已具备送盘、送盘状态查询、取消送盘等六条银行入口的最小实现态闭环证据。
- 正式文档可将 `BankWithholding` 六条银行入口写为“已实现”但需同时注明真实银行文件解析、SFTP/文件通道联调与运行态样本仍待补证。
- 涉及批量文件交互时,正式口径保留 `HTTP/REST/SFTP` 与文件命名、批次号约束,不下沉到特定银行私有报文字段。
- 运行时文件传输配置统一由解析器输出 `protocol/resolvedDir/resolvedPath/fileName/sourceScope`;优先级固定为 `TENANT_CHANNEL > TENANT > CHANNEL > DEFAULT`,高优先级仅覆盖部分字段时按字段级回退。
- 命中协议缺少 `host/port/username/credentialRef`、阶段目录为空或模板变量非法时,接口必须立即返回配置错误,不得回退到错误租户或错误通道。
### IF-EXT-002 银行代扣回盘接收接口
| 项目 | 说明 |
@ -162,6 +169,10 @@ retrieval_priority: P0
| 业务说明 | 接收代扣成功、失败、退票等结果并回写业务状态 |
| 核心数据支撑 | `bk_withholding_batch``bk_withholding_item``bk_transaction``bk_transaction_exception` |
边界约束:
- 回盘处理、回盘状态查询、差异核对和结算确认属于同一能力簇;其中 `BankWithholding` 的回盘与回盘状态查询已具备最小实现态闭环证据,但完整差异核对、异常补偿和结算确认仍属后续完善项。
- 当前正式文档允许保留回盘文件名、批次号、回盘日期、结果状态等正式字段约束,但不得把未落地的真实文件解析、异常补偿和结算闭环写成既成事实。
### IF-EXT-003 银行实时收费接口
| 项目 | 说明 |
@ -174,6 +185,25 @@ retrieval_priority: P0
| 业务说明 | 支撑柜台、网银、手机银行实时查询应收并完成缴费 |
| 核心数据支撑 | `biz_charge``biz_charge_detail``bk_transaction``bk_transaction_callback` |
边界约束:
- 当前 backend 已确认欠费查询与缴费处理具备实现证据,可作为正式文档中的已落地基础能力。
- 代理收费对账、汇总对账和当日未对账红冲等扩展能力当前仍未形成完整实现闭环,正式文档须标注为后续完善项。
### 银行签约、状态查询与批次控制扩展接口
| 接口动作 | 推荐归属 | 当前代码路径 | 当前状态 | 正式口径 |
|---------|----------|-------------|----------|----------|
| 代扣签约 | REV-008 / SYS-009 | `BankWithholdingController#signing` | 已实现 | 可作为正式接口能力写入 |
| 代扣解约 | REV-008 / SYS-009 | `BankWithholdingController#termination` | 已实现 | 可作为正式接口能力写入 |
| 托收签约 | REV-008 / SYS-009 | `BankCollectionController#signing` | 已实现 | 可作为正式接口能力写入 |
| 托收解约 | REV-008 / SYS-009 | `BankCollectionController#termination` | 已实现 | 可作为正式接口能力写入 |
| 客户状态查询 | REV-008 / SYS-009 | `BankWithholdingController#customerCheck` / `BankCollectionController#customerCheck` | 代扣已实现;托收部分实现 | 代扣可作为正式接口能力写入;托收仅保留正式契约边界与结果状态 |
| 送盘 | REV-008 / SYS-009 | `BankWithholdingController#sendDisc` / `BankCollectionController#sendDisc` | 代扣已实现;托收部分实现 | 代扣可作为正式接口能力写入;托收仅保留正式契约边界与批次发送语义 |
| 送盘状态查询 | REV-008 / SYS-009 | `BankWithholdingController#sendDiscCheck` / `BankCollectionController#sendDiscCheck` | 代扣已实现;托收部分实现 | 代扣可作为正式接口能力写入;托收仅保留正式契约边界与批次状态语义 |
| 取消送盘 | REV-008 / SYS-009 | `BankWithholdingController#cancelDisc` / `BankCollectionController#cancelDisc` | 代扣已实现;托收部分实现 | 代扣可作为正式接口能力写入;托收仅保留正式契约边界与可取消条件 |
| 回盘 | REV-008 / SYS-009 | `BankWithholdingController#backDisc` / `BankCollectionController#backDisc` | 代扣已实现;托收部分实现 | 代扣可作为正式接口能力写入;托收仅保留正式契约边界与回盘处理语义 |
| 回盘状态查询 | REV-008 / SYS-009 | `BankWithholdingController#backDiscCheck` / `BankCollectionController#backDiscCheck` | 代扣已实现;托收部分实现 | 代扣可作为正式接口能力写入;托收仅保留正式契约边界与回盘状态语义 |
### IF-EXT-004 聚合支付下单接口
| 项目 | 说明 |
@ -266,8 +296,8 @@ retrieval_priority: P0
| IF-REV-003 | 抄表任务下发接口 | REV-002 | 按册本、片区、抄表周期生成抄表任务 | `biz_meter_book``biz_meter_read` |
| IF-REV-004 | 抄表数据提交接口 | REV-002 | 提交抄表数据、图片、异常标记并触发校验 | `biz_reading_data``biz_reading_logs``biz_last_reading` |
| IF-REV-005 | 账单生成接口 | REV-002 | 根据抄表结果、价格模板和费用组成生成账单 | `biz_charge``biz_charge_detail``biz_price_template``biz_cost_component` |
| IF-REV-006 | 缴费处理接口 | REV-003 | 创建收费记录、核销账单、回写收款结果 | `biz_collection``biz_charge``bk_transaction` |
| IF-REV-007 | 账务调整接口 | REV-004 | 发起金额调整、退款、冲正、坏账等业务处理 | `biz_charge``biz_charge_detail``biz_operat_log` |
| IF-REV-006 | 缴费处理接口 | REV-003 | 创建收费记录、核销账单、回写收款结果,并形成业务支付事实/分配明细目标语义 | `biz_collection``biz_charge``bk_transaction`;目标/原型:`biz_payment_record``biz_payment_record_detail` |
| IF-REV-007 | 账务调整接口 | REV-004 | 发起金额调整、退款、冲正、坏账等业务处理,按引用关系校验原业务支付事实与渠道流水 | `biz_charge``biz_charge_detail``biz_operat_log`;引用:`bk_transaction*`、目标/原型 `biz_payment_record*` |
| IF-REV-008 | 发票申请接口 | REV-005 | 后台发起单笔/批量开票申请并生成受理主键 | `biz_invoice``biz_invoice_taxrate``biz_cust_invoice` |
| IF-REV-009 | 发票结果查询接口 | REV-005 | 按申请单号/受理号查询开票结果并执行补偿查询 | `biz_invoice``biz_operat_log` |
| IF-REV-013 | 催缴任务生成与结果承接接口 | REV-006 | 生成催缴任务、查询任务结果并承接四态状态回写 | `biz_charge``biz_operat_log`、历史催缴查询口径 |
@ -401,8 +431,8 @@ retrieval_priority: P0
| 归属模块 | REV-003 |
| 请求方式 | POST |
| 请求路径 | `/admin-api/revenue/collection/create` |
| 功能描述 | 处理柜台收费、预存抵扣、渠道收款确认与账单核销 |
| 核心表 | `biz_collection``biz_charge``bk_transaction` |
| 功能描述 | 处理柜台收费、预存抵扣、渠道收款确认与账单核销,并在目标口径下沉淀业务支付主单与账单/费用分配明细 |
| 核心表 | 现状:`biz_collection``biz_charge``bk_transaction`;目标/原型:`biz_payment_record``biz_payment_record_detail` |
### IF-REV-007 账务调整接口
@ -413,11 +443,11 @@ retrieval_priority: P0
| 请求方式 | POST |
| 请求路径 | `/admin-api/revenue/accounting/adjust` |
| 功能描述 | 发起水量调整、金额调整、退款、冲正、坏账申请五类账务处理,并统一返回处理结果、审批边界与账单回写状态 |
| 核心表 | `biz_charge``biz_charge_detail``biz_operat_log``bk_transaction*` |
| 核心表 | `biz_charge``biz_charge_detail``biz_operat_log`;退款/冲正引用 `bk_transaction*` 与目标/原型 `biz_payment_record*` 进行原支付事实追溯 |
边界约束:
- 一期仅覆盖 `USAGE``AMOUNT``REFUND``REVERSE``BAD_DEBT` 五类 `adjustType`
- 退款、冲正必须提供 `sourceTradeNo` 并完成原交易校验;其他场景不得误用支付流水替代业务依据。
- 退款、冲正必须提供 `sourceTradeNo` 并完成原交易校验;涉及业务支付事实时按 `REV-003` 目标口径引用 `biz_payment_record*`其他场景不得误用支付流水替代业务依据。
- 审批相关内容仅保留 `approvalRequired``PENDING_APPROVAL` 与边界说明,不展开 BPM 节点与审批回写实现细节。
- `resultStatus``writeBackStatus` 必须分离表达,前者表示处理结论,后者表示账单状态回写结论。
@ -494,6 +524,10 @@ retrieval_priority: P0
| 功能描述 | 创建代扣批次、发起对账、接收结算回写 |
| 核心表 | `biz_withholding``bk_withholding_batch``bk_reconcile_batch``bk_settlement_batch` |
边界约束:
- `IF-REV-011` 在当前阶段主要承接正式业务协同边界,不等同于送盘、回盘、对账、结算全部已闭环。
- 已确认的后台管理入口可证明批次、差异、结算台账对象存在,但不能替代银行 app 协同接口的完成度判断。
### IF-REV-012 业务参数配置接口
| 项目 | 说明 |
@ -1466,6 +1500,7 @@ sequenceDiagram
BatchJob->>SYS002: 发起代扣批次处理(IF-REV-011)
SYS002->>SYS002: 汇总代扣客户、账单与协议关系
SYS002->>SYS002: 生成bk_withholding_batch/bk_withholding_item
SYS002->>SYS002: 解析 send/back/reconcile 目录并固化协议、目录、文件路径
SYS002->>SYS009: 下发银行代扣批次(IF-EXT-001)
SYS009->>Bank: 发送代扣文件或报文
Bank-->>SYS009: 返回受理结果
@ -1509,7 +1544,7 @@ sequenceDiagram
| 客户扩展关系 | `biz_cust_meter``biz_cust_invoice``biz_cust_app_binds``biz_cust_collection_rel``biz_cust_withholding_rel` | 用于客户关联对象查询与服务协同 |
| 抄表与开账 | `biz_meter_book``biz_meter_read``biz_reading_data``biz_last_reading``biz_charge``biz_charge_detail` | 用于抄表任务、账单生成、费用明细查询 |
| 价格与参数 | `biz_price_*``biz_cost_component``biz_parameter_settings``biz_page_settings*` | 用于价格模板、业务参数、页面配置 |
| 收费与票据 | `biz_collection``biz_withholding``biz_invoice``biz_invoice_taxrate` | 用于收费、代扣、发票申请与回写 |
| 收费、业务支付事实与票据 | `biz_collection``biz_withholding`目标/原型 `biz_payment_record``biz_payment_record_detail``biz_invoice``biz_invoice_taxrate` | 用于收费、代扣、业务支付主单/分配明细目标语义、发票申请与回写`biz_payment_record*` 需以实现/DDL 验真后再升级为已落地生产表 |
| 办理与资料 | `biz_process*``biz_business_datas``biz_content*` | 用于业务办理与进度跟踪 |
| 银行代收与结算 | `bk_transaction*``bk_withholding_*``bk_reconcile_*``bk_settlement_batch` | 用于支付流水、批次、回调、对账和结算 |
@ -1564,12 +1599,16 @@ sequenceDiagram
| 批次下发 | `batchNo` | `batchNo` | 代扣批次号 | `bk_withholding_batch.batch_no` |
| 批次下发 | `businessType` | `businessType` | 代扣/对账/结算类型 | 协同参数 |
| 批次下发 | `channelCode` | `channelCode` | 渠道编码 | `bk_payment_channel.channel_code` |
| 批次下发 | `protocol` | `protocol` | `SFTP/FTP` 传输协议 | 统一解析结果 |
| 批次下发 | `sendDir` / `sendFilePath` | `sendDir` / `sendFilePath` | 送盘目录与文件路径 | `bk_withholding_batch` |
| 批次下发 | `billPeriod` | `billPeriod` | 账期 | 批处理参数 |
| 批次明细 | `itemList[].custId` | `itemList[].customerId` | 客户标识 | `bk_withholding_item.cust_id` |
| 批次明细 | `itemList[].chargeId` | `itemList[].sourceBillId` | 账单标识 | `bk_withholding_item.charge_id` |
| 批次明细 | `itemList[].amount` | `itemList[].withholdingAmount` | 代扣金额 | 业务金额 |
| 回盘回写 | `batchStatus` | `batchStatus` | 批次状态:已发送、已回盘等 | `bk_withholding_batch.status` |
| 回盘回写 | `backProtocol` / `backDir` / `backFilePath` | `backProtocol` / `backDir` / `backFilePath` | 回盘阶段最终解析结果 | `bk_withholding_batch` |
| 回盘回写 | `successCount` / `failCount` | `successCount` / `failCount` | 成功失败数量汇总 | 汇总结果 |
| 对账回写 | `protocol` / `dir` / `filePath` | `protocol` / `dir` / `filePath` | 对账文件最终解析结果 | `bk_reconcile_batch` |
| 对账回写 | `reconcileStatus` | `reconcileStatus` | 对账状态 | `bk_reconcile_batch.status` |
| 对账回写 | `diffList[]` | `diffList[]` | 差异明细摘要 | `bk_reconcile_diff` |
| 结算回写 | `settlementStatus` | `settlementStatus` | 结算状态 | `bk_settlement_batch.status` |
@ -1700,7 +1739,7 @@ sequenceDiagram
| 查询主题 | 挂靠接口族 | 主要数据来源 | 最低返回要求 | 说明 |
|---------|------------|--------------|--------------|------|
| 历史账单、特殊开账 | `IF-CS-002``IF-REV-005` | `biz_charge*` + 历史账单来源 | 原账单号、新账单号、客户号、账期、金额、状态、来源类型 | 支撑账单迁移核查与客户侧历史查询 |
| 缴费记录、柜台结账、实时收费 | `IF-CS-002``IF-REV-006``IF-REV-011` | `biz_collection``bk_transaction*` + 历史收费记录 | 原流水号、渠道、实收金额、收费时间、柜员/营业所、核销状态 | 支撑渠道对账、柜面核查和历史收据核对 |
| 缴费记录、柜台结账、实时收费 | `IF-CS-002``IF-REV-006``IF-REV-011` | `biz_collection`目标/原型 `biz_payment_record*``bk_transaction*` + 历史收费记录 | 原流水号、渠道、业务支付金额、分配/核销金额、收费时间、柜员/营业所、核销状态 | 支撑渠道对账、柜面核查和历史收据核对;业务支付事实归 `REV-003`,渠道事实归 `SYS-009` |
| 红冲与账务调整 | `IF-REV-007` | 操作留痕、流程结果 + 历史调整台账 | 调整类型、关联原单号、调整金额、原因、审批状态、处理时间 | 支撑预存退款、已销调整、价差调整、分账调整、呆坏账查询 |
| 发票与开票关系 | `IF-REV-008``IF-CS-004` | `biz_invoice*` + 历史开票关系快照 | 发票号、申请单号、关联账单、票据状态、票据类型、文件地址 | 支撑发票结果核查与历史补打定位 |
| 催缴、停复水、预存短信 | `IF-REV-013``IF-METER-002` | 通知结果、流程工单 + 历史催缴记录 | 客户号、账期、催缴方式、消息状态、停复水状态、执行人、执行时间、处置引用 | 支撑催缴处置闭环核查 |

View File

@ -228,6 +228,13 @@ graph TB
- 使用PKCS12格式的数字证书
- 支持TLSv1.2和TLSv1.3协议版本
#### 银行文件传输安全约束
- 银行文件交换默认优先使用 `SFTP``FTP` 仅作为兼容能力保留,需在风险评估通过后启用。
- 文件传输凭据以 `credentialRef` 引用形式由环境配置或配置中心承接,不在正式文档、默认仓库配置样例或测试样本中写入明文密码、私钥、证书。
- 命中协议缺少 `host/port/username/credentialRef` 时必须立即阻断当前文件动作,避免以残缺配置尝试连接银行通道。
- 路径模板仅允许固定变量白名单,禁止自由表达式、脚本化拼装和未声明变量,防止目录逃逸与错误路由。
- 批次审计只保存最终实际使用的协议、目录、文件路径与文件名,不额外保存完整凭据快照,避免敏感配置在业务表中扩散。
#### 敏感数据加密
- 采用国密SM4对称加密算法
- 实现统一的数据加密和解密服务

View File

@ -48,6 +48,11 @@ retrieval_priority: P0
- **安全防护**:多层次安全防护体系,确保系统和数据安全
- **弹性扩展**:支持系统横向和纵向扩展,适应业务增长需求
### 银行文件传输配置部署约束
- `sw-business-bank` 继续沿用 `application-{profile}.yaml + Nacos` 加载环境默认文件传输规则,不在代码中硬编码送盘、回盘、对账目录。
- 环境默认规则承接 `protocol/host/port/username/credentialRef/sendDir/backDir/reconcileDir/archiveDir/localTempDir`;银行通道、租户、租户-通道覆盖通过 `bk_channel_api_config``FILE_TRANSFER_CONFIG` 记录补充。
- 配置切换只影响新发起文件动作;已落库批次继续沿用已固化的协议、目录和文件路径审计结果,不要求重算旧批次。
<a id="sec-architecture"></a>
## 部署架构
@ -163,6 +168,7 @@ graph
- **任务调度**Quartz集群模式
- **工作流引擎**Flowable 6.8.0
- **文件存储**MinIO 分布式存储
- **配置中心**Nacos承接 profile 对应的银行文件传输默认规则
<a id="sec-solution"></a>
## 部署方案
@ -202,6 +208,7 @@ graph
- **数据库容器**:达梦数据库,数据持久化存储
- **缓存容器**Redis缓存服务提升系统性能
- **文件存储容器**MinIO对象存储管理系统文件
- **银行文件交换目录**:应用节点需具备本地临时目录与归档目录访问权限;外部银行 `SFTP/FTP` 白名单、账户与凭据由环境运维统一开通
### 部署流程

View File

@ -0,0 +1,824 @@
---
doc_id: TC-07-PGSQL-DR
doc_role: supplemental_document
authority: secondary
scope: PostgreSQL 16 容灾资源申请
source_of_truth: false
last_reviewed: 2026-03-24
retrieval_priority: P1
---
# 福建水务营收系统 PostgreSQL 16 容灾与资源申请说明
## 文档信息
| 项目信息 | 详情 |
|---------|------|
| **项目名称** | 福建水务营收系统 |
| **文档类型** | 技术专题说明 |
| **专题用途** | 向甲方申请 PostgreSQL 16 容灾部署资源 |
| **文档版本** | v1.0 |
| **编写日期** | 2026-03-24 |
| **文档状态** | ✅ 正式建议稿 |
## 目录
1. 编制目的
2. 适用范围与说明
3. 容灾建设目标
4. 容灾形态说明
5. 资源配比原则
6. 推荐部署方案
7. 方案二独立整体部署方案
8. 甲方审批汇总表
9. 详细资源申请清单
10. 网络与存储要求
11. 数据库代理与连接接入方案
12. 部署实施说明
13. 切换与恢复说明
14. 切换实施细则
15. 申请结论
## 编制目的
本文档用于说明福建水务营收系统采用 PostgreSQL 16 建设数据库高可用与灾难恢复能力时,所需的资源规模、部署形态、主备配比及实施要求,作为甲方进行服务器、存储、网络及运行环境审批的依据。
## 适用范围与说明
1. 本文档面向 PostgreSQL 16 数据库部署专题,重点说明容灾与资源申请口径。
2. 本文档用于资源论证与部署申请,不替代数据库主文档和总体部署主文档。
3. 文中关于备库资源比例、网络带宽、存储冗余和部署组合的建议,属于结合 PostgreSQL 16 流复制、热备与时间点恢复机制形成的工程实施建议。
## 容灾建设目标
PostgreSQL 16 容灾建设目标如下:
1. 在主库节点故障时,保障数据库能够快速切换并恢复服务。
2. 在误操作、逻辑损坏、批量异常更新等场景下,保障系统具备时间点恢复能力。
3. 在核心收费、账务、对账等业务场景中,尽量降低故障切换时的数据丢失风险。
4. 在资源投入可控的前提下,为甲方提供可分阶段实施的多种建设形态。
## 容灾形态说明
结合 PostgreSQL 16 能力及甲方常见基础设施条件,建议按以下四种形态进行资源申请与部署评估。
### 形态一:单中心主备容灾
适用于预算有限、优先满足基础高可用能力的场景。
部署关系图:
```mermaid
flowchart TD
APP[应用集群] --> PG1[(主库 Primary)]
PG1 -->|流复制| PG2[(备库 Standby)]
PG1 --> BK[备份归档存储]
PG2 --> BK
```
1. 主库与备库部署在同一机房或同一可用区。
2. 备库可采用 `Warm Standby``Hot Standby`
3. 推荐采用异步复制;如网络稳定且事务一致性要求较高,也可采用同步复制。
4. 该形态可解决单机故障问题,但不能覆盖机房级灾难。
### 形态二:同城双可用区主备容灾
适用于生产系统正式上线场景,兼顾高可用与较高的数据安全要求。
部署关系图:
```mermaid
flowchart LR
subgraph AZ1[生产可用区 A]
APP1[应用节点]
PG1[(主库 Primary)]
end
subgraph AZ2[同城可用区 B]
PG2[(同步备库 Standby)]
end
APP1 --> PG1
PG1 -->|同步复制| PG2
PG1 --> BK[备份归档存储]
PG2 --> BK
```
说明:
1. 主库与备库部署在同城不同机房或不同可用区。
2. 推荐备库采用 `Hot Standby`,可承担只读查询与切换接管职责。
3. 对收费、账务、实收确认等核心业务,宜优先评估同步复制。
4. 该形态可覆盖单节点故障和单可用区故障,是生产环境优先推荐的基础方案。
### 形态三:同城双中心 + 异地灾备
适用于对连续运行能力要求较高,且需要同时覆盖机房级与区域级风险的场景。
部署关系图:
```mermaid
flowchart LR
subgraph IDC1[生产中心]
PG1[(主库 Primary)]
end
subgraph IDC2[同城灾备中心]
PG2[(同步备库 Standby)]
end
subgraph IDC3[异地灾备中心]
PG3[(异步灾备库 DR)]
end
PG1 -->|同步复制| PG2
PG1 -->|异步复制| PG3
PG1 --> BK[备份归档存储]
PG2 --> BK
PG3 --> BK
```
说明:
1. 同城备库承担高可用切换职责。
2. 异地灾备库承担区域级灾难恢复职责。
3. 异地灾备一般采用异步复制,避免远距离链路对主业务写入性能造成明显影响。
4. 该形态可满足高可用与灾备双重要求,适合作为甲方正式建设目标方案。
### 形态四:主备高可用 + 备份恢复型灾备
适用于暂不具备异地第三节点条件,但需要形成完整灾难恢复能力的场景。
部署关系图:
```mermaid
flowchart TD
APP[应用集群] --> PG1[(主库 Primary)]
PG1 -->|同步/异步复制| PG2[(同城备库 Standby)]
PG1 -->|基础备份 + WAL 归档| OBJ[异地对象存储/异地备份库]
PG2 -->|基础备份 + WAL 归档| OBJ
```
说明:
1. 在线层保持主备双节点高可用。
2. 异地侧不部署实时在线数据库实例,主要承载基础备份和 WAL 归档。
3. 该形态投入低于三节点实时灾备,但恢复时间长于在线异地灾备库方案。
4. 适用于二期或预算受限情况下的过渡方案。
## 资源配比原则
### 主备资源总体原则
1. 主库负责生产写入CPU、内存、I/O、网络压力最大。
2. 备库必须保存完整数据副本,因此备库存储容量原则上不得低于主库。
3. 如备库承担实时切换接管职责,其 CPU 与内存不宜明显低于主库。
4. 如备库仅承担异步灾备且不承载查询压力,可适当降低 CPU 与内存,但不应压缩存储容量和网络链路质量。
### 主备资源比例建议
| 备库角色 | 复制方式 | 是否承担读请求 | CPU 建议 | 内存建议 | 存储建议 | 适用说明 |
|---|---|---|---|---|---|---|
| 同步热备库 | 同步复制 | 是 | 不低于主库 100% | 不低于主库 100% | 不低于主库 100%,建议 120% | 生产正式切换节点,要求切换后立即承载全部业务 |
| 同步温备库 | 同步复制 | 否 | 主库的 70% 至 100% | 主库的 70% 至 100% | 不低于主库 100%,建议 120% | 不承载查询,但需要较快接管生产流量 |
| 异步热备库 | 异步复制 | 是 | 主库的 70% 至 100% | 主库的 70% 至 100% | 不低于主库 100%,建议 120% | 可承担报表查询或只读分析 |
| 异步温备库 | 异步复制 | 否 | 主库的 50% 至 70% | 主库的 50% 至 70% | 不低于主库 100%,建议 120% | 仅承担容灾接管,不参与日常查询 |
| 异地灾备库 | 异步复制 | 否 | 主库的 50% 左右 | 主库的 50% 至 70% | 不低于主库 100%,建议 120% | 主要用于区域级容灾恢复 |
| 备份恢复节点 | PITR | 否 | 可不单独配置在线节点 | 可不单独配置在线节点 | 备份空间建议为主库有效数据量的 2 至 3 倍 | 用于误操作恢复和灾难后重建 |
### 资源配比说明
1. 备库存储不能按 CPU、内存比例缩减原因是 PostgreSQL 备库需要保存完整数据文件、索引文件及 WAL 回放空间。
2. 当备库承担 `Hot Standby` 查询或要求快速晋升为主库时,推荐按主库同规格申请。
3. 当备库仅作为冷备或异步灾备节点时,可降低计算资源,但仍需预留恢复、回放和切换后的运行余量。
## 推荐部署方案
结合福建水务营收系统收费、账务、对账等核心业务连续性要求,建议分为三档申请方案。
### 方案 A基础上线方案
1. 架构形态:单中心主备容灾。
2. 节点组成1 主库 + 1 备库 + 1 套备份归档存储。
3. 复制方式:异步复制。
4. 适用场景:预算受限、优先满足基本高可用要求。
### 方案 B正式生产推荐方案
1. 架构形态:同城双可用区主备容灾。
2. 节点组成1 主库 + 1 同城热备库 + 1 套备份归档存储。
3. 复制方式:核心业务优先评估同步复制。
4. 适用场景:正式生产环境,要求故障切换后快速恢复业务。
### 方案 C正式生产增强方案
1. 架构形态:同城双中心 + 异地灾备。
2. 节点组成1 主库 + 1 同城同步热备库 + 1 异地异步灾备库 + 1 套集中备份归档存储。
3. 复制方式:同城同步复制,异地异步复制。
4. 适用场景:甲方对连续运行、审计留痕、灾难恢复要求较高的正式建设项目。
本项目建议优先向甲方申请方案 B如甲方同时要求区域级灾难恢复能力建议直接申请方案 C。
## 方案二独立整体部署方案
> 本节内容已独立沉淀为 `docs/design/03_Technical_Design/08_Integrated_Deployment_Design_PlanB.md`。如需评审“已采纳方案二后的整体部署方案”,以独立文档为准。
### 方案定位
本方案基于原“方案 B正式生产推荐方案”进一步展开作为适配当前福建水务营收系统前后端分层部署形态的独立整体部署方案。
本方案的核心约束如下:
1. 前端服务与后端服务保持分层部署。
2. 中间件集中部署在 1 台主机上。
3. 数据库控制组件与中间件部署在同一台主机上。
4. 数据库采用同城双可用区主备架构。
5. 静态存储采用 MinIO并与中间件一并集中部署。
### 适用场景
本方案适用于以下场景:
1. 当前项目已具备前端 Nginx + Vue3、后端 Spring Boot 的分层部署模式。
2. 甲方希望在控制主机数量的前提下,完成应用层、数据库层、中间件层与静态存储层的整体建设。
3. 甲方接受“中间件集中部署、数据库双节点容灾、前后端分层部署”的资源结构。
### 整体部署拓扑
```mermaid
flowchart LR
subgraph CLIENT[访问入口]
U1[PC端用户]
U2[移动端用户]
U3[第三方系统]
end
subgraph LB[负载均衡层]
LB1[负载均衡/VIP]
end
subgraph FE[前端服务层]
FE1[前端服务器 1<br/>Nginx + Vue3]
FE2[前端服务器 2<br/>Nginx + Vue3]
end
subgraph BE[后端服务层]
BE1[后端服务器 1<br/>Spring Boot]
BE2[后端服务器 2<br/>Spring Boot]
BE3[后端服务器 3<br/>Spring Boot]
BE4[后端服务器 4<br/>Spring Boot]
end
subgraph MW[中间件与数据库控制层]
MW1[中间件服务器<br/>Redis + Nacos + MinIO<br/>HAProxy + PgBouncer + Patroni]
end
subgraph DBA[数据库可用区 A]
PG1[(PostgreSQL 16 主库)]
end
subgraph DBB[数据库可用区 B]
PG2[(PostgreSQL 16 同城热备库)]
end
CLIENT --> LB
LB --> FE
FE --> BE
BE --> MW1
MW1 --> PG1
MW1 --> PG2
PG1 -->|同步复制| PG2
PG1 --> BK[备份归档存储]
PG2 --> BK
```
### 主机角色划分
| 层级 | 主机角色 | 数量 | 主要部署内容 | 说明 |
|---|---|---:|---|---|
| 负载均衡层 | 负载均衡/VIP | 1 组 | 统一访问入口、SSL 卸载、转发控制 | 对外统一入口 |
| 前端服务层 | 前端服务器 | 2 台 | Nginx、Vue3 静态页面 | 承担 PC/H5 前端访问 |
| 后端服务层 | 后端服务器 | 4 台 | Spring Boot 业务服务 | 承担营收、账务、表务、发票、银行等业务 |
| 中间件层 | 中间件服务器 | 1 台 | Redis、Nacos、MinIO | 中间件集中部署 |
| 数据库控制层 | 数据库控制服务器 | 与中间件同机 | HAProxy、PgBouncer、Patroni | 不单独新增主机,部署在中间件服务器上 |
| 数据库层 | 主库服务器 | 1 台 | PostgreSQL 16 Primary | 部署在可用区 A |
| 数据库层 | 热备服务器 | 1 台 | PostgreSQL 16 Standby | 部署在可用区 B |
| 备份层 | 备份归档存储 | 1 套 | 基础备份、WAL 归档、恢复副本 | 独立存储空间 |
### 部署说明
#### 1. 前端部署
1. 前端采用 2 台服务器部署 `Nginx + Vue3` 静态资源。
2. 前端服务器不直接访问数据库,仅通过 HTTP/HTTPS 调用后端服务。
3. 负载均衡层对前端节点做健康检查和请求分发。
#### 2. 后端部署
1. 后端采用 4 台 Spring Boot 应用服务器集群部署。
2. 所有后端节点统一连接中间件与数据库控制主机暴露的数据库代理地址。
3. 后端节点统一访问 Redis、Nacos 和 MinIO不直接连接数据库主机 IP。
#### 3. 中间件与静态存储部署
1. 中间件统一部署在 1 台主机上。
2. 中间件主机承载以下组件:
- Redis缓存、会话、轻量级消息能力
- Nacos配置中心、注册治理能力
- MinIO静态文件与附件存储
3. MinIO 作为本项目静态存储与对象存储统一入口,承接附件、票据文件、导出文件及其他静态资源。
#### 4. 数据库控制组件部署
1. 数据库控制组件不单独新增主机。
2. `HAProxy``PgBouncer``Patroni` 与中间件部署在同一台主机。
3. 后端应用通过该主机上的统一数据库代理地址访问 PostgreSQL 主备集群。
4. 数据库切换时,由 Patroni 负责主备角色管理,由 HAProxy 完成入口切换,由 PgBouncer 完成连接池接管。
#### 5. 数据库部署
1. PostgreSQL 16 采用 1 主 1 热备模式。
2. 主库与热备库分别部署在同城不同可用区或不同故障域。
3. 主备之间采用同步复制,保障核心收费、账务、对账数据的一致性要求。
4. 主库和热备库同时将基础备份与 WAL 归档写入备份归档存储。
### 资源建议
| 主机角色 | 数量 | 建议配置 | 备注 |
|---|---:|---|---|
| 前端服务器 | 2 台 | 8 核 CPU / 16 GB 内存 / 200 GB SSD | 支撑 Nginx 与静态页面发布 |
| 后端服务器 | 4 台 | 16 核 CPU / 32 GB 内存 / 300 GB SSD | 对齐当前主文档后端服务集群口径 |
| 中间件与数据库控制服务器 | 1 台 | 16 核 CPU / 64 GB 内存 / 2 TB SSD | 同机承载 Redis、Nacos、MinIO、HAProxy、PgBouncer、Patroni |
| PostgreSQL 主库服务器 | 1 台 | 16 核 CPU / 64 GB 内存 / 2 TB NVMe SSD | 生产写入节点 |
| PostgreSQL 热备服务器 | 1 台 | 16 核 CPU / 64 GB 内存 / 2 TB NVMe SSD | 正式切换接管节点 |
| 备份归档存储 | 1 套 | 可用空间 4 TB 至 6 TB | 存放全量备份与 WAL 归档 |
### 网络需求
#### 1. 网络分区建议
| 网络分区 | 部署对象 | 访问要求 |
|---|---|---|
| 接入区 | 负载均衡、前端服务器 | 对外提供 HTTPS 访问 |
| 应用区 | 后端服务器 | 仅允许接入区与运维区访问 |
| 中间件区 | Redis、Nacos、MinIO、数据库控制组件 | 仅允许后端服务器与运维区访问 |
| 数据区 | PostgreSQL 主库、热备库、备份存储 | 严格限制,仅允许中间件控制主机和运维区访问 |
#### 2. 带宽与时延要求
| 网络链路 | 建议要求 | 说明 |
|---|---|---|
| 前端到后端 | 千兆网络 | 满足业务访问与接口调用 |
| 后端到中间件 | 千兆网络 | 满足缓存、配置、文件访问 |
| 中间件控制主机到数据库 | 千兆网络以上 | 满足数据库代理与健康检查 |
| 主备复制链路 | 不低于 10 Gbps | 支撑同步复制 |
| 同城主备时延 | 建议低于 2 ms | 支撑稳定同步复制 |
| 数据库到备份存储 | 千兆网络以上 | 满足基础备份与 WAL 归档传输 |
#### 3. 端口与访问控制建议
| 服务 | 典型端口 | 访问范围 |
|---|---|---|
| Nginx/HTTPS | 443 | 对外开放 |
| 后端 HTTP/HTTPS | 项目自定义端口 | 仅前端与内网调用 |
| Redis | 6379 | 仅后端与运维可访问 |
| Nacos | 8848 | 仅后端与运维可访问 |
| MinIO | 9000/9001 | 仅后端与运维可访问 |
| PgBouncer | 6432 | 仅后端可访问 |
| HAProxy | 5000 或项目定义端口 | 仅 PgBouncer 与运维可访问 |
| PostgreSQL | 5432 | 仅数据库控制主机与运维可访问 |
### 正式方案结论
结合当前项目前后端部署形态,建议以本方案作为 PostgreSQL 16 正式生产推荐部署方案。其总体特点为:
1. 前端与后端保持现有分层集群部署模式。
2. 中间件与数据库控制组件集中部署在 1 台主机,控制主机数量。
3. PostgreSQL 16 采用同城双可用区 1 主 1 热备部署,满足高可用要求。
4. MinIO 作为静态存储统一入口,与中间件同机部署,便于统一运维。
5. 网络上采用应用区、中间件区、数据区分层隔离,保障安全性与可维护性。
## 甲方审批汇总表
以下汇总表用于甲方进行资源审批、预算评估和实施范围确认。建议优先按“方案 B正式生产推荐方案”审批如甲方同时要求区域级灾难恢复能力可按“方案 C正式生产增强方案”审批。
### 方案 A基础上线方案审批汇总表
| 类别 | 资源项 | 数量 | 单项建议规格 | 审批说明 |
|---|---|---:|---|---|
| 服务器 | 主库服务器 | 1 台 | 16 核 CPU / 64 GB 内存 / 2 TB NVMe SSD | 承担全部生产写入 |
| 服务器 | 备库服务器 | 1 台 | 12 至 16 核 CPU / 48 至 64 GB 内存 / 2 TB NVMe SSD | 承担主库故障接管 |
| 服务器 | 管理与监控节点 | 1 台 | 8 核 CPU / 16 GB 内存 / 500 GB SSD | 部署监控、备份调度、巡检工具 |
| 存储 | 备份归档存储 | 1 套 | 可用空间 4 TB 起 | 存放全量备份与 WAL 归档 |
| 网络 | 主备复制链路 | 1 组 | 不低于 10 Gbps | 建议与业务访问链路隔离 |
| 网络 | 业务接入地址 | 1 组 | 统一数据库代理地址 | 应用统一接入,不直连数据库 IP |
| 软件 | PostgreSQL 16 | 2 套实例 | 主库 1 套,备库 1 套 | 构建基础主备容灾 |
| 软件 | PgBouncer | 1 套 | 连接池代理 | 统一控制连接数 |
| 软件 | HAProxy | 1 套 | 数据库入口代理 | 提供统一切换入口 |
| 软件 | Patroni | 1 套 | 高可用管理组件 | 管理主备选举与切换 |
### 方案 B正式生产推荐方案审批汇总表
| 类别 | 资源项 | 数量 | 单项建议规格 | 审批说明 |
|---|---|---:|---|---|
| 服务器 | 主库服务器 | 1 台 | 16 核 CPU / 64 GB 内存 / 2 TB NVMe SSD | 部署在生产可用区 |
| 服务器 | 同城热备服务器 | 1 台 | 16 核 CPU / 64 GB 内存 / 2 TB NVMe SSD | 与主库同规格,承担正式接管 |
| 服务器 | 管理与监控节点 | 1 台 | 8 核 CPU / 16 GB 内存 / 500 GB SSD | 部署监控、备份、巡检、告警 |
| 存储 | 备份归档存储 | 1 套 | 可用空间 4 TB 至 6 TB | 存放备份、WAL、恢复校验副本 |
| 网络 | 主备复制链路 | 1 组 | 不低于 10 Gbps | 同城低时延链路,适合同步复制 |
| 网络 | 主备时延要求 | 1 项 | 建议低于 2 ms | 支撑主备同步与快速切换 |
| 网络 | 业务接入地址 | 1 组 | 统一数据库代理地址 | 应用系统通过代理地址访问 |
| 软件 | PostgreSQL 16 | 2 套实例 | 主库 1 套,热备库 1 套 | 构建正式生产主备体系 |
| 软件 | PgBouncer | 1 套 | 连接池代理 | 控制连接数并稳定应用连接 |
| 软件 | HAProxy | 1 套 | 数据库入口代理 | 承担统一读写入口切换 |
| 软件 | Patroni | 1 套 | 高可用管理组件 | 管理主备状态、提升与故障切换 |
### 方案 C正式生产增强方案审批汇总表
| 类别 | 资源项 | 数量 | 单项建议规格 | 审批说明 |
|---|---|---:|---|---|
| 服务器 | 主库服务器 | 1 台 | 16 核 CPU / 64 GB 内存 / 2 TB NVMe SSD | 部署在生产中心 |
| 服务器 | 同城同步热备服务器 | 1 台 | 16 核 CPU / 64 GB 内存 / 2 TB NVMe SSD | 承担正式主备切换 |
| 服务器 | 异地灾备服务器 | 1 台 | 8 至 12 核 CPU / 32 至 48 GB 内存 / 2 TB NVMe SSD | 承担区域级灾难恢复 |
| 服务器 | 管理与监控节点 | 1 台 | 8 核 CPU / 16 GB 内存 / 500 GB SSD | 部署监控、备份、审计工具 |
| 存储 | 集中备份归档存储 | 1 套 | 可用空间 6 TB 起 | 保存全量备份、WAL、演练副本 |
| 网络 | 同城复制链路 | 1 组 | 不低于 10 Gbps | 保障同步复制稳定性 |
| 网络 | 异地复制链路 | 1 组 | 专线或稳定 VPN | 保障异步复制与备份回传 |
| 网络 | 业务接入地址 | 1 组 | 统一数据库代理地址 | 应用不直接访问数据库节点 |
| 软件 | PostgreSQL 16 | 3 套实例 | 主库 1 套,同城热备 1 套,异地灾备 1 套 | 构建高可用与灾备双层体系 |
| 软件 | PgBouncer | 1 套 | 连接池代理 | 稳定应用接入层 |
| 软件 | HAProxy | 1 套 | 数据库入口代理 | 承担统一流量入口与切换 |
| 软件 | Patroni | 1 套 | 高可用管理组件 | 管理主备状态与故障切换 |
### 审批建议结论
| 审批项 | 建议结论 | 说明 |
|---|---|---|
| 首选审批方案 | 方案 B | 兼顾资源投入、主备切换能力和正式生产可用性 |
| 最低建设标准 | 不低于方案 A | 至少满足双节点主备与独立备份归档 |
| 增强建设目标 | 方案 C | 适用于要求区域级灾难恢复的正式项目 |
| 备库资源口径 | 存储不低于主库,热备计算资源宜等同主库 | 避免切换后承载不足 |
| 接入方式 | 统一数据库代理地址 | 禁止应用直连数据库物理 IP |
## 详细资源申请清单
以下清单以单套生产系统为口径,作为资源申请参考基线。实际规模可根据并发量、数据量和保留周期进一步调整。
### 方案 A 资源申请清单
| 资源类型 | 数量 | 单节点建议配置 | 说明 |
|---|---:|---|---|
| 主库服务器 | 1 台 | 16 核 CPU / 64 GB 内存 / 2 TB NVMe SSD | 承担生产写入 |
| 备库服务器 | 1 台 | 12 至 16 核 CPU / 48 至 64 GB 内存 / 2 TB NVMe SSD | 温备或热备均可 |
| 备份存储 | 1 套 | 可用空间 4 TB 起 | 存放基础备份与 WAL 归档 |
| 管理与监控节点 | 1 台 | 8 核 CPU / 16 GB 内存 / 500 GB SSD | 部署监控、备份调度、巡检工具 |
### 方案 B 资源申请清单
| 资源类型 | 数量 | 单节点建议配置 | 说明 |
|---|---:|---|---|
| 主库服务器 | 1 台 | 16 核 CPU / 64 GB 内存 / 2 TB NVMe SSD | 部署在生产可用区 |
| 同城热备服务器 | 1 台 | 16 核 CPU / 64 GB 内存 / 2 TB NVMe SSD | 与主库同规格,承担热备与切换 |
| 备份归档存储 | 1 套 | 可用空间 4 TB 至 6 TB | 存放基础备份、WAL、恢复校验副本 |
| 管理与监控节点 | 1 台 | 8 核 CPU / 16 GB 内存 / 500 GB SSD | 部署监控、备份、连接代理等工具 |
### 方案 C 资源申请清单
| 资源类型 | 数量 | 单节点建议配置 | 说明 |
|---|---:|---|---|
| 主库服务器 | 1 台 | 16 核 CPU / 64 GB 内存 / 2 TB NVMe SSD | 部署在生产中心 |
| 同城同步热备服务器 | 1 台 | 16 核 CPU / 64 GB 内存 / 2 TB NVMe SSD | 作为正式切换节点 |
| 异地灾备服务器 | 1 台 | 8 至 12 核 CPU / 32 至 48 GB 内存 / 2 TB NVMe SSD | 用于区域级灾备恢复 |
| 集中备份归档存储 | 1 套 | 可用空间 6 TB 起 | 统一保存全量备份与 WAL 归档 |
| 管理与监控节点 | 1 台 | 8 核 CPU / 16 GB 内存 / 500 GB SSD | 部署监控、备份、审计工具 |
### 资源申请补充说明
1. 如甲方要求备库长期承担报表、统计或只读查询负载,备库应按主库同规格申请。
2. 如数据库数据量预估超过 1 TB建议主库与备库磁盘统一提升至 4 TB 起步。
3. 如需要保留 30 日以上 WAL 归档或多周期全量备份,备份存储应按“在线数据量的 2 至 3 倍”进行规划。
## 网络与存储要求
### 网络要求
| 项目 | 建议要求 | 说明 |
|---|---|---|
| 主备网络带宽 | 不低于 10 Gbps | 保障流复制稳定性与切换效率 |
| 同城主备时延 | 建议低于 2 ms | 适合同步复制 |
| 异地主备链路 | 建议专线或稳定 VPN | 适合异步复制与备份回传 |
| 复制链路隔离 | 建议与业务访问链路分离 | 降低复制抖动风险 |
### 存储要求
| 项目 | 建议要求 | 说明 |
|---|---|---|
| 主库存储 | NVMe SSD 或企业级 SSD | 保障 WAL 与随机 I/O 性能 |
| 备库存储 | 不低于主库存储规格 | 保障回放与切换性能 |
| 磁盘阵列 | RAID 10 优先 | 平衡可靠性与性能 |
| 备份存储 | 独立于数据库数据盘 | 避免单点故障导致备份不可用 |
## 数据库代理与连接接入方案
### 建设目标
为避免应用系统直接连接数据库物理节点并降低主备切换时应用侧配置变更成本PostgreSQL 16 容灾体系宜配套建设数据库代理与连接接入层。
数据库代理层建设目标如下:
1. 为应用系统提供统一数据库访问地址。
2. 在主备切换时避免逐台修改应用节点连接配置。
3. 控制应用连接数,降低数据库连接管理压力。
4. 为后续读写分离和只读查询扩展预留接入能力。
### 推荐组件组合
结合当前项目应用规模与运维复杂度控制要求,推荐采用以下组件组合:
1. `Patroni`:负责 PostgreSQL 主备状态管理、主库选举与故障切换。
2. `HAProxy`:负责数据库访问入口转发,将写请求路由到当前主库。
3. `PgBouncer`:负责连接池管理,降低应用对 PostgreSQL 后端连接数的直接冲击。
本项目不建议以 `pgpool-II` 作为首选统一方案。原因在于 `pgpool-II` 功能较重、配置复杂、运维成本较高,不利于当前项目在甲方环境中的快速落地与稳定运维。
### 推荐接入拓扑
#### 模式一:统一读写入口
适用于一期先满足高可用与连接池要求,暂不启用读写分离的场景。
接入关系图:
```mermaid
flowchart TD
APP[应用集群] --> PGB[PgBouncer]
PGB --> HAP[HAProxy RW 入口]
HAP --> PG1[(当前主库 Primary)]
PAT[Patroni] -.主备状态.-> HAP
```
说明:
1. 应用系统统一连接 `PgBouncer` 暴露的数据库接入地址。
2. `PgBouncer` 后端连接到 `HAProxy` 的读写入口。
3. `HAProxy` 根据 `Patroni` 暴露的主备状态,将流量转发到当前主库。
4. 主备切换时,应用端数据库 URL 不变。
#### 模式二:读写分离入口
适用于二期或存在报表、统计、查询分流需求的场景。
接入关系图:
```mermaid
flowchart LR
APP[应用集群] --> PGBRW[PgBouncer RW]
APP --> PGBRO[PgBouncer RO]
PGBRW --> HAPRW[HAProxy RW]
PGBRO --> HAPRO[HAProxy RO]
HAPRW --> PG1[(当前主库 Primary)]
HAPRO --> PG2[(热备库 Standby)]
PAT[Patroni] -.主备状态.-> HAPRW
PAT -.主备状态.-> HAPRO
```
说明:
1. 写请求通过 `RW` 入口访问当前主库。
2. 只读查询通过 `RO` 入口访问热备库。
3. 如备库不可用,`RO` 入口可根据策略降级转发到主库或暂时关闭。
4. 应用需在代码或配置层明确区分读写连接场景。
### 推荐选型结论
对于福建水务营收系统当前阶段,建议优先采用“`Patroni + HAProxy + PgBouncer`”组合,并采用“统一读写入口”模式上线。待系统稳定运行后,再根据报表与统计查询压力评估是否扩展为“读写分离入口”模式。
### HAProxy 示例配置
以下配置仅用于说明读写入口代理思路,实际参数应由项目环境统一配置并纳入变更管理。
```haproxy
global
log 127.0.0.1 local0
maxconn 20000
defaults
log global
mode tcp
timeout connect 5s
timeout client 1m
timeout server 1m
frontend pg_rw
bind *:5000
default_backend pg_primary
backend pg_primary
option tcp-check
default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions
server pg01 10.0.0.11:5432 check
server pg02 10.0.0.12:5432 check backup
```
配置说明:
1. 应用不直接连接 PostgreSQL 5432而是连接 `HAProxy` 暴露的 5000 端口。
2. `pg01` 为当前主库,`pg02` 为备库。
3. 主库不可用时,代理层将连接切换至备用节点。
4. 正式环境建议结合 `Patroni` REST 状态接口配置更准确的主备健康检查,而非仅做普通 TCP 存活检查。
### PgBouncer 示例配置
以下配置仅用于说明连接池配置思路,实际参数应由项目环境统一配置并纳入变更管理。
```ini
[databases]
waterdb = host=10.0.0.20 port=5000 dbname=waterdb
[pgbouncer]
listen_addr = 0.0.0.0
listen_port = 6432
auth_type = md5
auth_file = /etc/pgbouncer/userlist.txt
pool_mode = transaction
max_client_conn = 5000
default_pool_size = 100
reserve_pool_size = 20
server_reset_query = DISCARD ALL
ignore_startup_parameters = extra_float_digits
```
配置说明:
1. 应用系统统一连接 `PgBouncer` 的 6432 端口。
2. `PgBouncer` 后端目标不是数据库主机,而是 `HAProxy` 的读写入口地址。
3. 推荐优先采用 `transaction` 池化模式,以提升连接复用效率。
4. 如存在依赖会话级状态的特殊业务,应专项评估是否改用 `session` 模式。
### 应用接入建议
对于当前项目的 4 台应用服务器集群,不建议在每台应用服务器上分别配置数据库主机地址切换逻辑。推荐做法如下:
1. 应用配置文件统一写入数据库代理地址,不写数据库物理主机 IP。
2. 生产环境统一维护一个数据库接入地址,例如 `db-rw.xxx.local:6432`
3. 所有应用节点使用同一连接地址接入,由代理层完成后端数据库节点切换。
4. 如后续启用读写分离,再增加只读接入地址,例如 `db-ro.xxx.local:6432`
### 切换时的接入逻辑
当主库发生故障或进行计划切换时,推荐接入逻辑如下:
1. `Patroni` 判定新的主库节点。
2. `HAProxy` 将读写入口转发目标切换至新主库。
3. `PgBouncer` 清理失效后端连接并重建到新主库的连接。
4. 应用系统通过连接池重试机制继续访问统一代理地址。
在该机制下,应用系统通常无需修改数据库配置,仅在切换瞬间可能出现极短暂连接重试或少量请求失败,恢复后可继续正常提供服务。
### 正式文档建议表述
为保障福建水务营收系统数据库主备切换时应用系统的连续接入能力数据库访问层宜采用“Patroni 负责主备选举、HAProxy 负责访问转发、PgBouncer 负责连接池管理”的组合架构。应用系统统一通过数据库代理地址访问数据库,不直接连接数据库物理节点;当主库故障或发生计划切换时,由代理层自动将访问流量切换至新的主库节点,从而实现应用侧最小感知切换。
## 部署实施说明
### 部署原则
1. 主库与同城备库不得部署在同一物理主机。
2. 同城备库宜部署在独立机柜、独立电源域或独立可用区。
3. 异地灾备节点宜部署在独立数据中心,避免与生产中心共用故障域。
4. 备份归档存储应与数据库节点分离部署。
### 组件部署说明
1. 主库节点:部署 PostgreSQL 16 主实例,承担生产写入。
2. 备库节点:部署 PostgreSQL 16 备用实例,通过流复制接收主库 WAL。
3. 备份节点或备份存储保存基础备份、WAL 归档和恢复校验文件。
4. 管理与监控节点:部署 PostgreSQL 监控、备份调度、告警和巡检组件。
### 软件部署建议
1. 操作系统宜采用稳定版 Linux 发行版。
2. 数据目录、WAL 目录、备份目录建议分盘或分卷部署。
3. 主备切换宜配套连接路由、VIP 或代理层能力,避免应用侧频繁修改连接地址。
4. 生产环境应启用备份校验、归档校验和恢复演练机制。
## 切换与恢复说明
### 故障切换
1. 主库故障时,由同城备库提升为新主库。
2. 应用连接通过统一连接地址或代理切换到新主库。
3. 原主库恢复后,应重新以备库身份加入复制体系。
### 数据恢复
1. 误删除、误更新或逻辑损坏场景,通过基础备份与 WAL 归档执行 `PITR` 时间点恢复。
2. 区域级灾难场景下,可优先启用异地灾备库;如未建设异地在线库,则从异地备份存储重建数据库。
### 运维要求
1. 每季度至少开展 1 次主备切换演练。
2. 每季度至少开展 1 次 `PITR` 恢复演练。
3. 每日检查复制延迟、归档状态、备份成功率和磁盘余量。
## 切换实施细则
### 总体原则
福建水务营收系统数据库切换应遵循“统一入口切换、先判定后切换、先验证后恢复流量、禁止双主”的实施原则。
1. 应用系统统一通过数据库代理地址访问数据库,不直接连接数据库物理节点。
2. 切换分为计划切换、故障切换和回切三类场景。
3. 任一切换过程中,必须避免原主库与新主库同时对外提供写服务。
4. 切换完成后,必须执行收费、开账、账务、发票、银行代扣等关键业务链路验证。
### 计划切换流程
计划切换适用于数据库补丁升级、主机维护、操作系统维护、机房迁移演练等场景。
执行顺序:
发起计划切换申请 → 确认切换窗口与影响范围 → 检查主备复制状态 → 暂停高风险写入操作 → 确认备库追平主库 → 提升备库为新主库 → 切换代理入口到新主库 → 验证关键业务链路 → 恢复应用写入流量 → 原主库修复并重建为备库。
实施要点如下:
1. 切换前至少确认主备复制无明显延迟。
2. 切换窗口内应暂停批量开账、批量代扣、批量票据处理等高风险写入任务。
3. 备库提升后,应优先切换代理层入口,不建议逐台修改应用配置。
4. 切换成功后,原主库应以备库身份重新加入复制体系,不得直接恢复为独立写节点。
### 故障切换流程
故障切换适用于主库主机宕机、数据库实例不可用、主库存储异常、主库不可恢复等场景。
执行顺序:
监控发现主库异常 → 确认主库不可服务 → 隔离原主库写入能力 → 确认备库状态可提升 → 提升备库为新主库 → 代理入口切换到新主库 → 应用重连并恢复服务 → 验证关键业务 → 故障主机修复 → 重建为新备库。
实施要点如下:
1. 故障切换的前提不是“主库变慢”,而是“主库已无法稳定提供写服务”。
2. 在故障未完全确认前,不得贸然提升多个备库。
3. 如主库网络隔离但实例未真正关闭,应先执行隔离措施,避免形成双主风险。
4. 故障切换后应优先恢复核心业务可用性,再执行历史备库链路重建。
### 回切流程
回切是指原主库修复完成后,在合适窗口下恢复为生产主库或重新调整主备角色。
执行顺序:
原主库修复完成 → 作为备库追平现主库 → 评估是否需要回切。
如不需要回切,则保持现状运行。
如需要回切,则执行以下步骤:发起计划回切窗口 → 暂停高风险写入 → 确认复制追平 → 切换代理入口 → 恢复原主库为主库 → 验证关键业务 → 现主库调整为备库。
实施要点如下:
1. 故障切换后并不要求立即回切,应以稳定运行为优先。
2. 仅当原主机重新具备稳定承载能力,且运维窗口允许时,才建议执行回切。
3. 回切本质上属于一次计划切换,应按计划切换流程执行。
### 切换前检查表
| 检查项 | 检查要求 | 说明 |
|---|---|---|
| 主备复制状态 | 无严重延迟或异常中断 | 确认备库具备接管条件 |
| WAL 归档状态 | 最近归档成功 | 避免切换与恢复证据缺口 |
| 备库只读可用性 | 可正常连接与查询 | 确认备库实例健康 |
| 代理状态 | `HAProxy``PgBouncer` 正常 | 确保切换入口可用 |
| 应用连接配置 | 使用统一代理地址 | 禁止应用直连数据库 IP |
| 定时任务状态 | 高风险写任务可暂停 | 包括批量收费、批量代扣等 |
| 业务通知 | 已通知相关业务与运维人员 | 降低切换窗口影响 |
### 切换后验证表
| 验证项 | 验证要求 | 适用说明 |
|---|---|---|
| 数据库连接 | 应用可正常连接新主库 | 基础可用性验证 |
| 登录与鉴权 | 后台登录、令牌校验正常 | 确认统一平台链路正常 |
| 收费业务 | 单笔收费、销账可执行 | 核心写业务验证 |
| 开账业务 | 账单查询、开账写入正常 | 核心账务链路验证 |
| 发票业务 | 发票申请、查询可用 | 核心票据链路验证 |
| 银行代扣 | 查询和批次处理链路正常 | 涉及外联时至少完成内部链路检查 |
| 日志与监控 | 新主库监控、慢日志、告警恢复正常 | 运维可观测性验证 |
| 备份与归档 | 新主库 WAL 归档恢复正常 | 确认恢复能力未中断 |
### 当前项目建议切换策略
结合当前项目部署口径,建议采用以下策略:
1. 数据库切换统一由数据库代理层完成,不在 4 台应用服务器上分别切换配置。
2. 一期建议采用统一读写入口模式,减少应用改造复杂度。
3. 切换窗口内应重点管控收费、账务、发票、银行代扣等核心写入场景。
4. 生产切换完成后,应同步检查 `Quartz` 定时任务、银行文件处理任务及发票异步任务是否恢复正常。
### 正式文档建议表述
福建水务营收系统数据库切换采用“主备切换 + 代理入口切换”的实施模式。计划切换和故障切换均由数据库高可用组件完成主备角色调整,由数据库代理层完成统一接入地址切换,应用系统不直接感知数据库物理节点变化。切换实施前应完成复制状态、归档状态、代理状态和高风险任务状态检查,切换实施后应完成收费、开账、账务、发票、银行代扣等关键业务链路验证,并将原主库按备库角色重新纳入复制体系。
## 申请结论
为满足福建水务营收系统生产环境对数据库连续运行和灾难恢复的要求,建议甲方按以下原则审批 PostgreSQL 16 容灾资源:
1. 至少配置 1 台主库服务器、1 台备库服务器和 1 套独立备份归档存储。
2. 如备库承担正式接管职责CPU 与内存宜按主库 100% 配置,存储不得低于主库。
3. 如需形成正式生产级容灾体系,建议采用“同城双可用区主备 + 备份归档”方案。
4. 如需形成区域级灾难恢复体系,建议进一步增配 1 台异地灾备服务器。
综上PostgreSQL 16 容灾资源申请可分阶段实施,但正式生产环境不宜低于“双节点主备 + 独立备份归档”的最低建设标准。

View File

@ -0,0 +1,674 @@
---
doc_id: TC-08-INTEGRATED-DEPLOYMENT
doc_role: supplemental_document
authority: secondary
scope: 方案二整体部署
source_of_truth: false
last_reviewed: 2026-03-26
retrieval_priority: P1
---
# 福建水务营收系统整体部署方案说明书
## 文档信息
| 项目信息 | 详情 |
|---------|------|
| **项目名称** | 福建水务营收系统 |
| **文档类型** | 技术专题说明 |
| **方案定位** | 已采纳 PostgreSQL 16 方案二作为数据库部署方案后的整体部署方案 |
| **文档版本** | v1.0 |
| **编写日期** | 2026-03-26 |
| **文档状态** | ✅ 正式建议稿 |
## 目录
1. 编制目的
2. 方案前提
3. 整体部署原则
4. 软件拓扑图
5. 主机部署图
6. 数据库访问链路图
7. 备份恢复链路图
8. 网络拓扑图
9. 主机角色与部署内容
10. 资源配置建议
11. 资源审批汇总表
12. 基础软件与版本清单
13. 部署方式说明
14. 网络需求
15. 网络开通清单
16. 访问控制与端口建议
17. 实施步骤
18. 验收标准
19. 部署结论
## 编制目的
本文档用于在已采纳 PostgreSQL 16 方案二作为数据库部署方案的前提下,形成覆盖前端、后端、中间件、静态存储及数据库的一体化整体部署方案,作为甲方进行主机、网络、存储与基础软件资源审批的依据。
## 方案前提
本方案以以下前提为基础:
1. 数据库部署方案已采纳 `docs/design/03_Technical_Design/07_PostgreSQL16_DR_Resource_Application.md` 中的方案二,即“同城双可用区主备容灾方案”。
2. 前端继续采用 `Nginx + Vue3` 的静态部署模式。
3. 对外访问经甲方或第三方管理的公网入口进行薄转发,不纳入本方案主机资源范围。
4. `Nginx` 入口单独部署在互联网区 `DMZ`,负责承接办公网、公网入口和外部授权链路转发,并将开放 API 端点负载到两台业务应用节点。
5. 两台业务应用节点部署在互联网区 `DMZ`,节点内均部署 `Spring Boot Gateway`,作为微服务集群统一接入入口,并同时承载业务服务。
6. 中间件集中部署在 1 台主机上。
7. 数据库控制组件与中间件部署在同一台主机上。
8. `RustFS` 作为静态存储与对象存储统一入口,与中间件同机部署。
9. 一期口径下,原“数据与中间件节点”和“文件存储节点”合并为 1 台综合节点。
10. 银行文件交换采用独立 `SFTP/FTP` 文件交换服务器,并部署在互联网区 `DMZ`,作为银行送盘、回盘、对账文件交换专用前置机。
11. 当前已知可用于本方案的业务与基础设施主机资源如下:
- DMZ Nginx 入口节点8 核 CPU / 16 GB 内存 / 300 GB 存储,共 1 台
- 业务应用节点32 核 CPU / 64 GB 内存 / 300 GB 存储,共 2 台
- 数据、中间件与文件存储综合节点16 核 CPU / 32 GB 内存 / 2300 GB 存储,共 1 台
- 银行文件交换服务器2 核 CPU / 8 GB 内存 / 200 GB 存储,共 1 台
- 另行配置 PostgreSQL 主库与热备库各 1 台
## 整体部署原则
整体部署遵循以下原则:
1. 前后端逻辑分层部署,避免数据库节点与业务节点混部。
2. 中间件集中部署,降低主机数量和运维复杂度。
3. 数据库主备分离部署,避免与中间件、应用节点混部。
4. 数据库控制组件集中部署,通过统一代理地址屏蔽主备切换细节。
5. 网络按办公区、公网区域、互联网区 `DMZ`、内网区分层隔离;其中数据库、中间件控制与备份归档均落在内网区。
6. 在现有主机数量约束下优先复用现有业务应用节点、DMZ Nginx 入口节点及综合节点资源。
## 软件拓扑图
**图 4-1 访问与应用软件拓扑图**
```mermaid
flowchart LR
classDef source fill:#ecfeff,stroke:#0891b2,stroke-width:1.2px,color:#083344;
classDef access fill:#fff7ed,stroke:#ea580c,stroke-width:1.4px,color:#7c2d12;
classDef app fill:#eff6ff,stroke:#2563eb,stroke-width:1.4px,color:#1e3a8a;
classDef zone fill:#f8fafc,stroke:#94a3b8,stroke-width:1.2px,color:#0f172a;
subgraph OFFICE[办公区]
direction TB
U1[PC 端用户<br/>办公网段]:::source
end
subgraph PUBLIC[公网区域]
direction TB
U2[移动端用户]:::source
U3[第三方系统]:::source
G1[公网授权入口]:::access
end
subgraph DMZ[互联网区 / DMZ]
direction TB
G2[Nginx 入口]:::access
A1[业务应用节点 1<br/>Spring Boot Gateway + 业务服务]:::app
A2[业务应用节点 2<br/>Spring Boot Gateway + 业务服务]:::app
end
class OFFICE,PUBLIC,DMZ zone;
U1 -->|办公网访问,内网 IP| G2
U2 -->|HTTPS 443| G1
U3 -->|HTTPS / API| G1
G1 -->|授权转发| G2
G2 -->|API 转发| A1
G2 -->|API 转发| A2
```
图说明:
1. 图中已明确区分办公区、公网区域和互联网区 `DMZ`
2. PC 端用户位于办公区,经办公网使用内网 IP 直接访问 `DMZ` 内的 `Nginx` 入口。
3. 移动端用户和第三方系统位于公网区域,先经公网授权入口,再跨边界进入 `DMZ` 内的 `Nginx` 入口。
4. `Nginx` 入口位于互联网区 `DMZ`,负责将开放 API 端点负载到两台业务应用节点。
5. 两台业务应用节点位于互联网区 `DMZ`,节点内均部署 `Spring Boot Gateway`,作为微服务集群统一接入入口。
6. 公网入口后侧涉及的边界路由与 `NAT` 转换属于甲方网络侧能力,本图不展开网络设备细节。
**图 4-2 综合服务软件拓扑图**
```mermaid
flowchart TB
classDef zone fill:#f8fafc,stroke:#94a3b8,stroke-width:1.2px,color:#0f172a;
classDef app fill:#eff6ff,stroke:#2563eb,stroke-width:1.4px,color:#1e3a8a;
classDef service fill:#f5f3ff,stroke:#7c3aed,stroke-width:1.4px,color:#4c1d95;
subgraph DMZ[互联网区 / DMZ]
direction LR
A1[业务应用节点 1<br/>Gateway + Biz]:::app
A2[业务应用节点 2<br/>Gateway + Biz]:::app
end
subgraph INTRA[内网区]
direction TB
subgraph M[综合节点]
direction TB
M2[Redis / Nacos / RustFS]:::service
M3[HAProxy / PgBouncer / Patroni]:::service
end
end
class DMZ,INTRA zone;
A1 -->|缓存 配置 文件访问| M2
A2 -->|缓存 配置 文件访问| M2
A1 -->|数据库代理访问| M3
A2 -->|数据库代理访问| M3
```
图说明:
1. 综合节点位于内网区,承接缓存、配置、对象存储及数据库控制组件。
2. 两台 `DMZ` 业务应用节点统一访问内网区综合节点,不直接连接数据库。
**图 4-3 数据与备份软件拓扑图**
```mermaid
flowchart LR
classDef zone fill:#f8fafc,stroke:#94a3b8,stroke-width:1.2px,color:#0f172a;
classDef service fill:#f5f3ff,stroke:#7c3aed,stroke-width:1.4px,color:#4c1d95;
classDef data fill:#ecfdf5,stroke:#059669,stroke-width:1.4px,color:#064e3b;
classDef backup fill:#fffbeb,stroke:#d97706,stroke-width:1.4px,color:#78350f;
classDef bank fill:#fef2f2,stroke:#dc2626,stroke-width:1.4px,color:#7f1d1d;
subgraph DMZ[互联网区 / DMZ]
F1[SFTP / FTP 文件交换服务器]:::bank
end
subgraph INTRA[内网区]
direction LR
subgraph M[综合节点]
direction TB
M1[数据库管理控件 / 中间件]:::service
M2[对象存储 / RustFS]:::service
end
D1[(PostgreSQL 主库)]:::data
D2[(PostgreSQL 热备)]:::data
B1[备份归档存储]:::backup
end
class DMZ,INTRA zone;
M1 -->|5432 数据库访问| D1
M1 -.->|5432 状态探测| D2
D1 -->|主备同步| D2
D1 -->|备份 / WAL 归档| B1
D2 -->|备份副本| B1
M2 -->|文件归档| B1
F1 -->|银行文件归档| B1
```
图说明:
1. 数据库控制组件经由主库提供数据库访问能力。
2. 主库与热备之间通过同步复制保持一致性。
3. 银行文件交换服务器位于互联网区 `DMZ`,承接送盘、回盘、对账文件交换能力。
4. RustFS 与银行文件交换服务器分别将各自数据归档到备份归档存储。
## 主机部署图
**图 4-4 主机部署总览图**
```mermaid
flowchart LR
classDef gateway fill:#fff7ed,stroke:#ea580c,stroke-width:1.2px,color:#7c2d12;
classDef app fill:#eff6ff,stroke:#2563eb,stroke-width:1.2px,color:#1e3a8a;
classDef middle fill:#f5f3ff,stroke:#7c3aed,stroke-width:1.2px,color:#4c1d95;
classDef data fill:#ecfdf5,stroke:#059669,stroke-width:1.2px,color:#064e3b;
classDef backup fill:#fffbeb,stroke:#d97706,stroke-width:1.2px,color:#78350f;
GW[DMZ Nginx 入口节点]:::gateway
APP1[业务应用节点 1<br/>内含 Gateway]:::app
APP2[业务应用节点 2<br/>内含 Gateway]:::app
FTP[SFTP / FTP 文件交换服务器]:::middle
MID[综合节点]:::middle
DB1[(数据库主库服务器)]:::data
DB2[(数据库热备服务器)]:::data
BK[备份归档存储]:::backup
GW --> APP1
GW --> APP2
APP1 --> MID
APP2 --> MID
APP1 --> FTP
APP2 --> FTP
MID --> DB1
MID --> DB2
DB1 --> DB2
DB1 --> BK
DB2 --> BK
MID --> BK
```
图说明:
1. 本图仅表达主机与主机之间的部署关系,不重复展开办公区、公网区域和跨边界访问链路。
2. `Nginx` 入口节点、业务应用节点和 `SFTP/FTP` 文件交换服务器部署在互联网区 `DMZ`
3. 综合节点、数据库主库服务器、数据库热备服务器和备份归档存储部署在内网区。
4. 业务应用节点经 `DMZ Nginx` 接入,并访问综合节点与 `SFTP/FTP` 文件交换服务器。
5. 综合节点统一访问 PostgreSQL 主库与热备;主库、热备和综合节点均向备份归档存储输出数据。
主机部署细化说明:
1. 互联网区 `DMZ``Nginx` 入口节点部署 `Nginx`,负责开放 API 转发和内部负载均衡。
2. 两台互联网区 `DMZ` 业务应用节点分别部署 `Spring Boot Gateway` 与业务服务实例。
3. 内网区综合节点部署 `Redis``Nacos``RustFS``HAProxy``PgBouncer``Patroni`,并负责访问数据库主库与热备服务器。
4. 互联网区 `DMZ``SFTP/FTP` 文件交换服务器部署银行文件交换服务及送盘、回盘、对账目录,由业务应用节点直接访问。
5. 内网区数据库主库服务器部署 PostgreSQL 主库实例,数据库热备服务器部署 PostgreSQL 热备实例。
## 数据库访问链路图
**图 4-5 数据库访问链路图**
```mermaid
flowchart LR
A1[业务应用节点 1]
A2[业务应用节点 2]
P[PgBouncer]
H[HAProxy]
M[(主库)]
S[(热备)]
T[Patroni]
A1 -->|统一代理地址| P
A2 -->|统一代理地址| P
P -->|连接池复用| H
H -->|写流量| M
H -.热备探测 / 状态访问.-> S
M -->|同步复制| S
T -.主备状态管理.-> H
```
图说明:
1. 业务应用不直接连接数据库主机。
2. PgBouncer 负责连接池。
3. HAProxy 负责数据库入口代理。
4. Patroni 负责主备状态管理与切换控制。
5. 综合节点侧的数据库控制组件会同时访问主库和热备,用于探测、控制和切换。
## 备份恢复链路图
**图 4-6 备份恢复链路图**
```mermaid
flowchart LR
DB1[(PostgreSQL 主库)] --> BK[备份归档存储]
DB2[(PostgreSQL 热备)] --> BK
MID[综合节点 / RustFS] --> BK
BK --> REC[恢复与演练入口]
```
图说明:
1. 主库和热备均向备份归档存储输出备份数据。
2. 综合节点中的 RustFS 文件数据也纳入备份范围。
3. 备份归档存储作为数据库恢复与文件恢复的统一入口。
## 网络拓扑图
> 说明:如需生成正式网络分区图,统一以 `scripts/generate_planb_diagrams.py` 生成的产物为准;其他脚本仅用于布局试验,不作为正式交付依据。
**图 4-7 网络分区图**
```mermaid
flowchart LR
classDef user fill:#ecfeff,stroke:#0891b2,stroke-width:1.2px,color:#083344;
classDef edge fill:#fff7ed,stroke:#ea580c,stroke-width:1.2px,color:#7c2d12;
classDef zone fill:#f8fafc,stroke:#94a3b8,stroke-width:1.2px,color:#0f172a;
classDef svc fill:#f5f3ff,stroke:#7c3aed,stroke-width:1.2px,color:#4c1d95;
classDef data fill:#ecfdf5,stroke:#059669,stroke-width:1.2px,color:#064e3b;
classDef bank fill:#fef2f2,stroke:#dc2626,stroke-width:1.2px,color:#7f1d1d;
classDef backup fill:#fffbeb,stroke:#d97706,stroke-width:1.2px,color:#78350f;
subgraph Z1[办公区]
PC[PC 端用户]
end
subgraph Z2[公网区域]
PUB[移动端用户 / 第三方系统]
EDGE[公网入口 / 边界路由 / NAT]
BANK[银行系统]
end
subgraph Z3[互联网区 / DMZ]
IGW[Nginx 入口]
APP[业务应用集群]
FX[SFTP / FTP 文件交换服务器]
end
subgraph Z4[内网区]
MID[综合节点]
DBM[(PostgreSQL 主库)]
DBS[(PostgreSQL 热备)]
BK[备份归档存储]
end
class Z1,Z2,Z3,Z4 zone;
class PC,PUB user;
class EDGE,IGW edge;
class APP,MID svc;
class DBM,DBS data;
class FX bank;
class BK backup;
PC --> IGW
PUB --> EDGE
BANK --> IGW
BANK --> FX
EDGE --> IGW
IGW --> APP
APP --> FX
APP --> MID
MID --> DBM
MID -.-> DBS
DBM --> BK
DBS --> BK
MID --> BK
```
图说明:
1. 公网入口、边界路由和 `NAT` 转发不纳入我方主机资源,但作为公网访问进入 `DMZ` 的前置接入层予以保留。
2. 网络分区图按办公区、公网区域、互联网区 `DMZ`、内网区四区模型表达,不展开单机内部软件组件。
3. PC 端用户可直接通过办公网访问 `DMZ` 中的 `Nginx` 入口;移动端和第三方系统经公网入口、边界路由或 `NAT` 转发后进入 `DMZ`
4. `DMZ` 中的 `Nginx` 入口、业务应用集群、银行文件交换服务器与内网区综合节点、数据库、备份归档存储通过授权链路互通。
5. 银行系统除通过 `SFTP/FTP` 目录交换文件外,还可按授权专线或外联链路访问 `DMZ Nginx` 暴露的 API 入口,网络分区图已同步表达这两类授权链路。
## 主机角色与部署内容
| 层级 | 主机角色 | 数量 | 主要部署内容 | 说明 |
|---|---|---:|---|---|
| 接入层 | DMZ Nginx 入口节点 | 1 台 | Nginx、API 转发、内部负载均衡 | 作为我方统一 DMZ 接入入口,承接办公网访问、公网转发与开放 API 转发 |
| 应用层 | 业务应用节点(主) | 2 台 | Spring Boot Gateway、Spring Boot 业务服务 | 承载微服务集群接入与表务、抄表、收费、账务、发票、报表等核心应用服务 |
| 综合支撑层 | 数据、中间件与文件存储综合节点 | 1 台 | Redis、Nacos、RustFS、HAProxy、PgBouncer、Patroni | 中间件、数据库控制与文件存储同机部署 |
| 银行交换层 | SFTP/FTP 文件交换服务器 | 1 台 | SFTP/FTP 服务、送盘目录、回盘目录、对账目录、归档目录 | 作为银行文件交换专用前置机 |
| 数据库层 | PostgreSQL 主库服务器 | 1 台 | PostgreSQL 16 Primary | 部署在可用区 A |
| 数据库层 | PostgreSQL 热备服务器 | 1 台 | PostgreSQL 16 Standby | 部署在可用区 B |
| 备份层 | 备份归档存储 | 1 套 | 基础备份、WAL 归档、恢复副本 | 独立备份空间 |
## 资源配置建议
| 主机角色 | 数量 | 建议配置 | 备注 |
|---|---:|---|---|
| DMZ Nginx 入口节点 | 1 台 | 8 核 CPU / 16 GB 内存 / 300 GB 存储 | 承载 DMZ Nginx、API 转发和内部负载均衡 |
| 业务应用节点(主) | 2 台 | 32 核 CPU / 64 GB 内存 / 300 GB 存储 | 承载 Spring Boot Gateway 及表务、抄表、收费、账务、发票、报表等核心应用服务 |
| 数据、中间件与文件存储综合节点 | 1 台 | 16 核 CPU / 32 GB 内存 / 2300 GB 存储 | 承载缓存、配置治理、数据库控制、图片、附件等非结构化数据 |
| SFTP/FTP 文件交换服务器 | 1 台 | 2 核 CPU / 8 GB 内存 / 200 GB 存储 | 承载银行送盘、回盘、对账、归档文件交换,建议独立部署 |
| PostgreSQL 主库服务器 | 1 台 | 24 核 CPU / 48 GB 内存 / 1 TB NVMe SSD | 生产写入节点,不计入上述已知 4 类业务主机 |
| PostgreSQL 热备服务器 | 1 台 | 24 核 CPU / 48 GB 内存 / 1 TB NVMe SSD | 正式切换接管节点,不计入上述已知 4 类业务主机 |
| 备份归档存储 | 1 套 | 可用空间 4 TB 至 6 TB | 存放全量备份与 WAL 归档 |
### 银行文件交换服务器容量估算
按 20 万用户、5 年保留期估算,银行文件交换服务器主要承载代扣、托收、对账等批次文件,不承载全量业务明细数据库。
估算依据如下:
1. 银行代扣、托收、对账文件以批次文件为主,不是每位用户每天形成独立文件。
2. 按“仅覆盖银行代扣/托收用户,且按月批次送盘/回盘一次”的业务节奏估算,单个批次文件大小通常在 `10 MB ~ 40 MB` 量级。
3. 按每月送盘、回盘、对账共 `3` 类核心文件估算,月文件量约为:
- `30 MB ~ 120 MB / 月`
4. 按 1 年估算,原始批次文件总量约为:
- `0.36 GB ~ 1.44 GB / 年`
5. 考虑归档副本、异常重传、中间文件和运行日志,按 `10 ~ 15` 倍放大后5 年总量通常约为:
- `20 GB ~ 110 GB`
因此,按最节约的一期规划,银行文件交换服务器可按 `2 核 CPU / 8 GB 内存 / 200 GB 存储` 配置满足送盘、回盘、对账文件交换与 5 年留存需要;如后续银行通道数量增加、并发文件交换增加或保留策略扩大,再扩容至 `4 核 / 8 GB / 500 GB` 即可。建议设置 `70%` 容量预警,并预留扩容机制。
## 资源审批汇总表
以下汇总表用于甲方进行主机、存储、网络及基础软件部署范围审批。
| 序号 | 资源名称 | 数量 | 规格 | 部署内容 | 用途说明 | 建议口径 |
|---|---:|---:|---|---|---|---|
| 1 | DMZ Nginx 入口节点 | 1 台 | 8 核 CPU / 16 GB 内存 / 300 GB 存储 | Nginx、API 转发、内部负载均衡 | 我方统一 DMZ 接入入口 | 可利旧优先 |
| 2 | 业务应用节点(主) | 2 台 | 32 核 CPU / 64 GB 内存 / 300 GB 存储 | Spring Boot Gateway、Spring Boot 核心业务服务 | 承载微服务接入与核心业务服务 | 现有资源纳入正式方案 |
| 3 | 数据、中间件与文件存储综合节点 | 1 台 | 16 核 CPU / 32 GB 内存 / 2300 GB 存储 | Redis、Nacos、RustFS、HAProxy、PgBouncer、Patroni | 承载缓存、配置治理、数据库控制、图片、附件、导出文件等能力 | 现有资源纳入正式方案 |
| 4 | SFTP/FTP 文件交换服务器 | 1 台 | 2 核 CPU / 8 GB 内存 / 200 GB 存储 | SFTP/FTP 服务、送盘/回盘/对账目录、归档目录 | 承载银行文件交换与目录隔离 | 按最节约一期规划建议新增或单独利旧 |
| 5 | PostgreSQL 主库服务器 | 1 台 | 24 核 CPU / 48 GB 内存 / 1 TB NVMe SSD | PostgreSQL 16 Primary | 承载生产写入 | 建议单独配置 |
| 6 | PostgreSQL 热备服务器 | 1 台 | 24 核 CPU / 48 GB 内存 / 1 TB NVMe SSD | PostgreSQL 16 Standby | 承载正式切换接管 | 建议单独配置 |
| 7 | 备份归档存储 | 1 套 | 可用空间 4 TB 至 6 TB | 基础备份、WAL 归档、恢复副本 | 保障恢复与审计追溯 | 可利旧或新增存储空间 |
### 审批建议
1. 业务应用节点、综合节点、DMZ Nginx 入口节点可优先按现有资源纳入实施范围。
2. SFTP/FTP 文件交换服务器建议单独审批,以满足银行文件交换隔离和安全要求。
3. PostgreSQL 主库与热备库建议作为单独审批项,避免与现有业务节点混部。
4. 备份归档存储建议作为单独资源项审批,避免后期因备份空间不足影响正式上线。
## 基础软件与版本清单
| 类别 | 软件名称 | 建议版本 | 部署位置 | 说明 |
|---|---|---|---|---|
| 操作系统 | Linux 发行版 | 银河麒麟Kylin V10X86 | 全部服务器 | 按甲方当前基础环境标准选定 |
| 运行环境 | JDK | 17 | 业务应用节点 | Spring Boot 运行环境 |
| 接入层 | Nginx | 1.20+ | DMZ Nginx 入口节点 | 办公网、公网入口转发与内部负载均衡 |
| 网关服务 | Spring Boot Gateway | 3.x | 业务应用节点 | 微服务集群统一接入 |
| 业务服务 | Spring Boot | 3.x | 业务应用节点 | 核心业务服务框架 |
| 银行文件交换 | SFTP/FTP 服务 | 稳定版 | SFTP/FTP 文件交换服务器 | 银行送盘、回盘、对账文件交换 |
| 数据库 | PostgreSQL | 16 | 主库、热备库 | 主备数据库部署 |
| 缓存 | Redis | 6.2+ | 综合节点 | 缓存、会话、轻量级消息能力 |
| 配置中心 | Nacos | 2.x | 综合节点 | 配置治理与注册管理 |
| 对象存储 | RustFS | 以项目实际版本为准 | 综合节点 | 图片、附件、导出文件存储 |
| 数据库代理 | HAProxy | 2.x | 综合节点 | 数据库读写入口代理 |
| 连接池 | PgBouncer | 1.2x+ | 综合节点 | 统一数据库连接池 |
| 高可用控制 | Patroni | 稳定版 | 综合节点 | 主备状态管理与切换 |
## 部署方式说明
### 总体部署原则
本方案的部署方式遵循以下原则:
1. 入口代理类组件优先采用 `Docker` 部署,并可优先评估 `host` 网络模式。
2. 业务应用优先采用 `Docker` 部署,但不建议使用 `host` 网络模式。
3. 数据库主备优先采用物理机或虚拟机直接部署,不建议容器化承载 PostgreSQL 主备本体。
4. 数据库控制组件如需容器化,应优先选择轻量代理组件容器化,高可用控制组件仍以直接部署为优先。
### 组件部署方式建议
| 组件 | 部署节点 | 建议部署方式 | 是否建议 `host` 模式 | 说明 |
|---|---|---|---|---|
| DMZ Nginx | DMZ Nginx 入口节点 | Docker 部署 | 是,优先建议 | 作为我方统一 DMZ 接入入口,便于端口管理与转发 |
| Spring Boot Gateway | 业务应用节点(主) | Docker 部署 | 否 | 作为微服务统一接入入口,建议与业务服务同节点部署 |
| Spring Boot 应用 | 业务应用节点(主) | Docker 部署 | 否 | 便于发布、回滚、扩容,保留容器网络隔离 |
| SFTP/FTP 服务 | SFTP/FTP 文件交换服务器 | 物理机/虚拟机直接部署 | 否 | 作为银行文件交换专用服务,建议独立部署并做目录隔离 |
| Redis | 综合节点 | Docker 部署 | 可选 | 可采用普通容器网络,必要时可评估 `host` |
| Nacos | 综合节点 | Docker 部署 | 可选 | 默认容器网络即可,便于配置治理 |
| HAProxy | 综合节点 | Docker 部署 | 是,优先建议 | 作为数据库代理入口,适合 `host` 模式 |
| PgBouncer | 综合节点 | Docker 部署 | 是,优先建议 | 作为数据库连接池入口,适合 `host` 模式 |
| Patroni | 综合节点 | 物理机/虚拟机直接部署 | 否 | 建议与系统服务集成,便于运维与切换控制 |
| RustFS | 综合节点 | Docker 部署 | 否 | 更关注数据盘挂载与对象存储目录管理 |
| PostgreSQL 主库 | 主库服务器 | 物理机/虚拟机直接部署 | 否 | 核心数据库本体不建议容器化 |
| PostgreSQL 热备 | 热备服务器 | 物理机/虚拟机直接部署 | 否 | 高可用数据库本体不建议容器化 |
### 优先采用 Docker 且可使用 `host` 模式的组件
结合当前资源结构,建议优先采用 `Docker + host` 模式的组件如下:
1. `DMZ Nginx`
2. `HAProxy`
3. `PgBouncer`
采用 `host` 模式的主要原因如下:
1. 直接监听固定服务端口,减少端口映射复杂度。
2. 更便于与主机防火墙、域名、VIP、健康检查配合。
3. 对于入口类与代理类组件,运维体验更接近直接部署。
### 不建议采用 `host` 模式的组件
以下组件不建议采用 `Docker + host` 模式:
1. `Spring Boot` 业务应用:应保留容器网络隔离,便于扩容和端口治理。
2. `RustFS`:应以存储挂载与数据目录管理为重点,不依赖 `host` 模式。
3. `PostgreSQL 主库 / 热备`:数据库本体优先直接部署,不建议容器化。
4. `Patroni`:建议直接部署,便于与数据库高可用控制链路协同。
## 网络需求
### 1. 网络分区要求
| 网络分区 | 部署对象 | 访问要求 |
|---|---|---|
| 办公区 | PC 端用户办公网段 | 仅允许通过办公网访问 `DMZ Nginx` 入口 |
| 公网区域 | 移动端用户、第三方系统、公网入口薄转发、边界路由 / NAT | 对外提供 HTTPS 访问,不纳入我方主机资源 |
| 互联网区 DMZ | `DMZ Nginx`、业务应用节点、`SFTP/FTP` 文件交换服务器 | 作为对外与跨边界服务区,仅允许按授权链路访问内网区 |
| 内网区 | Redis、Nacos、RustFS、数据库控制组件、PostgreSQL 主库/热备、备份归档存储 | 严格限制,仅允许 `DMZ` 业务应用节点、综合节点控制链路和运维区访问 |
### 2. 带宽与时延要求
| 网络链路 | 建议要求 | 说明 |
|---|---|---|
| 公网入口薄转发到 DMZ Nginx | 千兆网络 | 满足公网入口转发 |
| 办公网到 DMZ Nginx | 千兆网络 | 满足办公网通过内网 IP 访问 |
| DMZ Nginx 到业务应用 | 千兆网络 | 满足开放 API 转发与网关接入 |
| 业务应用到综合节点 | 千兆网络 | 满足缓存、配置治理、文件访问与数据库代理访问 |
| 业务应用到 SFTP/FTP 服务器 | 千兆网络 | 满足送盘、回盘、对账文件交换 |
| 银行链路到 SFTP/FTP 服务器 | 千兆网络或专线 | 满足银行文件交换与目录投递 |
| 综合节点到数据库 | 千兆网络以上 | 满足数据库代理与健康检查 |
| 主备复制链路 | 不低于 10 Gbps | 支撑同步复制 |
| 同城主备时延 | 建议低于 2 ms | 支撑稳定同步复制 |
| 数据库到备份存储 | 千兆网络以上 | 满足基础备份与 WAL 归档传输 |
| 综合节点到备份存储 | 千兆网络以上 | 满足文件数据备份与归档传输 |
### 3. 网络开通要求
| 类别 | 开通要求 | 说明 |
|---|---|---|
| 对外访问 | 开通 443 端口 | 提供统一 HTTPS 入口 |
| 公网入口薄转发访问 DMZ Nginx | 开通公网入口到 DMZ Nginx 的转发端口 | 仅授权链路访问 |
| 办公网访问 DMZ Nginx | 开通办公网到 DMZ Nginx 的内网访问端口 | 仅办公网访问 |
| 银行专线或授权外联链路访问 DMZ Nginx | 开通银行链路到 DMZ Nginx 的 HTTPS/API 端口 | 仅银行授权链路访问 |
| DMZ Nginx 访问应用 | 开通 DMZ Nginx 到业务应用的 API / 网关端口 | 仅 DMZ 内部访问 |
| 应用访问综合节点 | 开通 Redis、Nacos、RustFS9000/9001、PgBouncer 相关端口 | 仅 DMZ 业务应用节点访问 |
| 业务应用访问 SFTP/FTP 服务器 | 开通 SFTP/FTP 相关端口 | 用于银行文件送盘、回盘、对账交换 |
| 银行链路访问 SFTP/FTP 服务器 | 开通 FTP/SFTP 服务端口 | 仅银行授权链路访问 |
| 综合节点访问数据库 | 开通 PostgreSQL 5432 及健康检查相关端口 | 仅综合节点访问 |
| 运维访问 | 开通运维区到各层必要管理端口 | 用于巡检、发布、恢复、切换 |
## 网络开通清单
| 源区域/源主机 | 目标区域/目标主机 | 协议/端口 | 用途 | 开通要求 |
|---|---|---|---|---|
| 外部用户 | 公网入口薄转发 | HTTPS/443 | 页面访问、接口入口 | 对外开放 |
| 公网入口薄转发 | DMZ Nginx 入口节点 | HTTP/HTTPS/转发端口 | 公网访问转入 DMZ 入口 | 授权链路放通 |
| 办公网段 | DMZ Nginx 入口节点 | HTTP/HTTPS/内网访问端口 | 办公网用户访问系统入口 | 仅办公网放通 |
| 银行专线或授权外联链路 | DMZ Nginx 入口节点 | HTTPS/API 端口 | 银行系统访问 DMZ API 入口 | 仅授权链路放通 |
| DMZ Nginx 入口节点 | 业务应用节点(主) | HTTP/HTTPS/网关端口 | DMZ API 转发与微服务接入 | DMZ 内部放通 |
| 业务应用节点(主) | 综合节点 | TCP/6379 | Redis 访问 | 内网放通 |
| 业务应用节点(主) | 综合节点 | TCP/8848 | Nacos 访问 | 内网放通 |
| 业务应用节点(主) | 综合节点 | TCP/6432 | PgBouncer 访问 | 内网放通 |
| 业务应用节点(主) | 综合节点 | TCP/9000、9001 | RustFS 文件访问与控制台访问 | 内网放通 |
| 业务应用节点(主) | SFTP/FTP 文件交换服务器 | TCP/21 或 22 | 银行送盘、回盘、对账文件交换 | 内网放通 |
| 银行专线或授权外联链路 | SFTP/FTP 文件交换服务器 | TCP/21 或 22 | 银行文件目录投递与回收 | 仅授权链路放通 |
| 综合节点 | PostgreSQL 主库服务器 | TCP/5432 | 数据库代理与控制访问 | 内网放通 |
| 综合节点 | PostgreSQL 热备服务器 | TCP/5432 | 数据库代理、状态探测与控制访问 | 内网放通 |
| PostgreSQL 主库服务器 | PostgreSQL 热备服务器 | TCP/5432 | 主备同步复制 | 高带宽、低时延专用链路 |
| PostgreSQL 主库/热备库 | 备份归档存储 | TCP/存储协议端口 | 基础备份与 WAL 归档 | 内网放通 |
| 综合节点 | 备份归档存储 | TCP/存储协议端口 | 文件归档与备份 | 内网放通 |
| 运维管理终端 | 各节点 | SSH/22 及必要管理端口 | 运维、巡检、发布、恢复 | 仅运维区放通 |
## 访问控制与端口建议
| 服务 | 典型端口 | 访问范围 |
|---|---|---|
| Nginx/HTTPS | 443 | 对外开放、办公网授权访问及银行授权链路访问 |
| Spring Boot Gateway / 业务应用端口 | 项目自定义端口 | 仅 DMZ Nginx 与 DMZ/内网授权调用 |
| Redis | 6379 | 仅业务应用与运维可访问 |
| Nacos | 8848 | 仅业务应用与运维可访问 |
| RustFS | 9000S3 API、9001Console | 仅业务应用与运维可访问 |
| SFTP/FTP 服务 | 21 或 22 | 仅业务应用节点、运维和银行授权链路可访问 |
| PgBouncer | 6432 | 仅业务应用可访问 |
| HAProxy | 5000 或项目定义端口 | 仅 PgBouncer 与运维可访问 |
| PostgreSQL | 5432 | 仅数据库控制主机与运维可访问 |
## 实施步骤
### 1. 基础资源准备
1. 确认 `DMZ Nginx` 入口节点、业务应用节点、综合节点是否为利旧资源。
2. 完成 SFTP/FTP 文件交换服务器、PostgreSQL 主库服务器、热备服务器及备份归档存储审批。
3. 完成各网络分区、IP、域名、SSL 证书、路由及防火墙策略准备。
### 2. 基础软件安装
1. 安装操作系统并完成安全基线加固。
2. 在业务应用节点安装 JDK、部署业务运行环境。
3. 在 `DMZ Nginx` 入口节点安装 Nginx。
4. 在综合节点安装 Redis、Nacos、RustFS、HAProxy、PgBouncer、Patroni。
5. 在 SFTP/FTP 文件交换服务器安装 SFTP/FTP 服务并配置目录结构。
6. 在数据库主备节点安装 PostgreSQL 16。
### 3. 数据库主备部署
1. 初始化 PostgreSQL 主库。
2. 初始化 PostgreSQL 热备库并建立同步复制。
3. 配置 Patroni、HAProxy、PgBouncer 联动。
4. 配置基础备份与 WAL 归档。
5. 配置业务应用节点到 SFTP/FTP 文件交换服务器的文件交换目录映射。
### 4. 应用与存储部署
1. 在业务应用节点部署 Spring Boot Gateway 和业务应用服务。
2. 在 `DMZ Nginx` 入口节点配置 API 转发和内部负载均衡规则。
3. 在综合节点初始化 RustFS 存储桶和访问策略。
4. 在 SFTP/FTP 文件交换服务器配置送盘、回盘、对账、归档目录。
5. 配置业务应用到 Redis、Nacos、RustFS、PgBouncer 的连接参数。
### 5. 联调与演练
1. 完成前后端联调。
2. 完成中间件访问验证。
3. 完成数据库主备同步验证。
4. 完成文件上传、下载、归档验证。
5. 完成主备切换演练与回切演练。
### 6. 上线准备与正式投产
1. 完成上线前巡检与问题清零。
2. 确认监控、日志、备份、告警正常。
3. 完成上线窗口审批。
4. 按上线顺序切换生产流量。
## 验收标准
| 验收项 | 验收标准 | 说明 |
|---|---|---|
| 对外访问 | 用户可通过统一域名正常访问系统 | 公网入口薄转发与 DMZ Nginx 链路正常 |
| 业务应用可用性 | 表务、抄表、收费、账务、发票、报表等核心服务正常 | 业务主流程可执行 |
| Redis 可用性 | 缓存读写正常 | 中间件能力正常 |
| Nacos 可用性 | 配置下发正常 | 配置治理能力正常 |
| RustFS 可用性 | 图片、附件上传下载正常 | 文件存储能力正常 |
| SFTP/FTP 文件交换 | 送盘、回盘、对账目录读写正常 | 银行文件交换能力正常 |
| 数据库连接能力 | 业务应用可通过 PgBouncer 正常连接数据库 | 代理接入正常 |
| PostgreSQL 主备同步 | 主备复制正常,无严重延迟 | 高可用基础正常 |
| 数据库切换演练 | 主备切换成功,业务恢复正常 | 高可用能力可验证 |
| 备份归档 | 基础备份与 WAL 归档正常 | 恢复能力可验证 |
| 运维监控 | 关键节点监控、日志、告警正常 | 运维可观测性正常 |
## 部署结论
在已采纳 PostgreSQL 16 方案二作为数据库部署方案的前提下,建议福建水务营收系统采用“前后端分层部署 + 中间件集中部署 + 数据库主备分离部署”的整体部署模式。
本方案的最终结论如下:
1. 公网入口薄转发、边界路由和 `NAT` 不纳入我方主机资源;我方实际部署的统一接入入口为互联网区 `DMZ``Nginx` 入口节点。
2. 2 台业务应用节点部署在互联网区 `DMZ`,节点内同时部署 `Spring Boot Gateway` 和业务服务,承接微服务统一接入与核心业务处理。
3. 综合节点集中承载 `Redis``Nacos``RustFS` 及数据库控制组件,并部署在内网区,进一步压缩一期主机数量并降低部署复杂度。
## RustFS 产品介绍与选型说明
RustFS 是一款支持私有化部署的 S3 兼容对象存储方案可用于承接图片、附件、导出文件和归档文件等非结构化数据场景。结合本项目当前整体部署方案RustFS 作为综合节点上的对象存储组件,可替代 MinIO 承接对象存储能力。
本项目采用 RustFS 的原因如下:
1. RustFS 具备对象存储能力,适合图片、附件、导出文件和归档文件统一存储。
2. RustFS 支持私有化部署,适合甲方对自主可控和本地化部署的要求。
3. RustFS 可作为独立对象存储组件部署在综合节点中,与缓存、配置治理和数据库控制能力协同运行。
4. 当前方案中,银行文件交换仍由独立的 SFTP/FTP 文件交换服务器承接RustFS 不承担银行送盘、回盘和对账文件交换职责。
5. 新增 1 台 SFTP/FTP 文件交换服务器,作为银行送盘、回盘、对账文件交换专用前置机。
6. PostgreSQL 16 采用同城双可用区 1 主 1 热备部署,满足高可用要求。
7. 网络采用办公区、公网区域、互联网区 `DMZ`、内网区分层隔离模式,以满足安全性、可维护性和资源审批要求。

View File

@ -15,6 +15,8 @@
- `02_Table_Specs.md`:单表规格补充(历史映射,非主口径)
- `06_Sensitive_Data_Encryption.md`:敏感数据加密方案
- `07_PostgreSQL16_DR_Resource_Application.md`PostgreSQL 16 容灾与资源申请专题说明
- `08_Integrated_Deployment_Design_PlanB.md`:采纳 PostgreSQL 16 方案二后的整体部署方案
## 维护原则

View File

@ -0,0 +1,573 @@
# 营收系统接口规范设计文档
## 1. 文档概述
### 1.1 文档信息
- **文档名称**:营收系统接口规范设计文档
- **版本**1.0
- **编写日期**2024年12月
- **基于原始文档**:营收系统缴费接口 v1.5
### 1.2 设计目标
本文档旨在为营收系统与银行/第三方支付机构之间的接口交互提供标准化、规范化的设计指导,确保系统的高可用性、安全性和可扩展性。
### 1.3 适用范围
- 公用事业单位(水司、电力等)
- 银行机构
- 第三方支付平台
- 系统集成商
## 2. 系统架构设计
### 2.1 整体架构
```
┌─────────────────┐ HTTP/HTTPS ┌─────────────────┐
│ │<──────────────────>│ │
│ 银行/支付平台 │ │ 营收系统 │
│ │ │ │
└─────────────────┘ └─────────────────┘
│ │
│ │
v v
┌─────────────────┐ ┌─────────────────┐
│ 对账文件处理 │ │ 业务数据库 │
└─────────────────┘ └─────────────────┘
```
### 2.2 接口分层设计
```
┌─────────────────────────────────────────────────────────┐
│ 表示层 (Presentation Layer) │
│ HTTP/HTTPS + XML/JSON │
├─────────────────────────────────────────────────────────┤
│ 业务层 (Business Layer) │
│ 查询服务 | 缴费服务 | 代扣服务 | 对账服务 │
├─────────────────────────────────────────────────────────┤
│ 数据层 (Data Layer) │
│ 用户数据 | 账单数据 | 交易数据 │
└─────────────────────────────────────────────────────────┘
```
## 3. 接口设计规范
### 3.1 RESTful设计原则
虽然原系统使用XML格式但建议遵循RESTful设计原则
| 功能模块 | HTTP方法 | 资源路径 | 描述 |
|----------|----------|----------|------|
| 账单查询 | POST | `/api/app/billQuery/query` | 查询用户账单 |
| 账单缴费 | POST | `/api/app/billPay/pay` | 执行缴费操作 |
| 账单红冲 | POST | `/api/app/payInvalid/payInvalid` | 红冲已缴费账单 |
| 代扣签约 | POST | `/api/app/bankWithholding/signing` | 代扣签约 |
| 代扣解约 | POST | `/api/app/bankWithholding/termination` | 代扣解约 |
| 代扣送盘 | POST | `/api/app/bankWithholding/sendDisc` | 代扣送盘 |
| 代扣回盘 | POST | `/api/app/bankWithholding/backDisc` | 代扣回盘 |
### 3.2 数据格式规范
#### 3.2.1 请求格式
- **内容类型**`application/xml``application/json`
- **字符编码**GBKXML或 UTF-8JSON
- **请求方法**POST
#### 3.2.2 响应格式
- **状态码**200 OK业务成功/失败通过返回码区分)
- **内容类型**:与请求格式保持一致
- **响应结构**:统一的响应格式
### 3.3 安全设计规范
#### 3.3.1 加密策略
```
┌─────────────────┐ 加密传输 ┌─────────────────┐
│ 客户端 │ ──────────────> │ 服务端 │
│ │ │ │
│ 1. 数据加密 │ │ 1. 数据解密 │
│ 2. Base64编码 │ │ 2. Base64解码 │
│ 3. HTTP传输 │ │ 3. 业务处理 │
└─────────────────┘ └─────────────────┘
```
#### 3.3.2 支持的加密算法
| 加密类型 | 加密模式 | 填充方式 | 安全等级 |
|----------|----------|----------|----------|
| 3DES | ECB | PKCS7 | 中等 |
| SM2 | C1C3C2/C1C2C3 | - | 高 |
| SM4 | ECB/CBC | PKCS7 | 高 |
#### 3.3.3 请求头设计
```http
Content-Type: application/xml; charset=GBK
EncryptType: 3DES
EncryptMode: ECB
DataType: XML
```
### 3.4 错误处理规范
#### 3.4.1 统一错误码设计
```
AAAAAAA: 成功
DEF0xxx: 业务错误 (0001-0999)
SYS1xxx: 系统错误 (1000-1999)
SEC2xxx: 安全错误 (2000-2999)
NET3xxx: 网络错误 (3000-3999)
```
#### 3.4.2 错误响应格式
```xml
<out>
<Version>1.0.1</Version>
<InstId>00001</InstId>
<TranCode>QueryRes</TranCode>
<TranDate>20240101</TranDate>
<TranSeq>123456789012</TranSeq>
<RespCode>DEF0001</RespCode>
<RespMessage>无相应记录</RespMessage>
<ErrorDetail>
<ErrorCode>DEF0001</ErrorCode>
<ErrorMsg>用户编号123456不存在</ErrorMsg>
<ErrorTime>2024-01-01 12:00:00</ErrorTime>
</ErrorDetail>
</out>
```
## 4. 数据模型设计
### 4.1 核心实体模型
#### 4.1.1 用户实体 (Customer)
```sql
CREATE TABLE customer (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
bill_key VARCHAR(35) NOT NULL UNIQUE COMMENT '客户编号',
customer_name VARCHAR(150) NOT NULL COMMENT '客户姓名',
contract_no VARCHAR(30) COMMENT '合同号',
company_id VARCHAR(30) NOT NULL COMMENT '机构编码',
created_time DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_bill_key (bill_key),
INDEX idx_company_id (company_id)
);
```
#### 4.1.2 账单实体 (Bill)
```sql
CREATE TABLE bill (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
bill_key VARCHAR(35) NOT NULL COMMENT '客户编号',
company_id VARCHAR(30) NOT NULL COMMENT '机构编码',
pay_amount DECIMAL(16,2) NOT NULL COMMENT '缴费金额',
balance DECIMAL(16,2) DEFAULT 0.00 COMMENT '余额',
begin_date DATE COMMENT '账单开始日期',
end_date DATE COMMENT '账单结束日期',
bill_status TINYINT DEFAULT 0 COMMENT '账单状态 0:未缴费 1:已缴费',
created_time DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_bill_key (bill_key),
INDEX idx_company_id (company_id),
INDEX idx_status (bill_status)
);
```
#### 4.1.3 交易记录 (Transaction)
```sql
CREATE TABLE transaction (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
tran_seq VARCHAR(40) NOT NULL UNIQUE COMMENT '交易流水号',
bill_key VARCHAR(35) NOT NULL COMMENT '客户编号',
company_id VARCHAR(30) NOT NULL COMMENT '机构编码',
tran_code VARCHAR(20) NOT NULL COMMENT '交易码',
pay_amount DECIMAL(16,2) NOT NULL COMMENT '交易金额',
pay_date DATETIME NOT NULL COMMENT '交易时间',
sub_channel TINYINT COMMENT '二级渠道 1:支付宝 2:微信 6:其它',
tran_status TINYINT DEFAULT 0 COMMENT '交易状态 0:处理中 1:成功 2:失败',
resp_code VARCHAR(7) COMMENT '返回码',
resp_message VARCHAR(60) COMMENT '返回消息',
created_time DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_tran_seq (tran_seq),
INDEX idx_bill_key (bill_key),
INDEX idx_pay_date (pay_date),
INDEX idx_status (tran_status)
);
```
### 4.2 代扣相关实体
#### 4.2.1 代扣协议 (WithholdingAgreement)
```sql
CREATE TABLE withholding_agreement (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
bill_key VARCHAR(35) NOT NULL COMMENT '客户编号',
company_id VARCHAR(30) NOT NULL COMMENT '机构编码',
account_name VARCHAR(150) NOT NULL COMMENT '开户名',
account_no VARCHAR(30) NOT NULL COMMENT '开户账号',
bank_name VARCHAR(150) COMMENT '银行名称',
contract_no VARCHAR(150) COMMENT '合同号',
agreement_no VARCHAR(150) COMMENT '协议号',
bank_type TINYINT COMMENT '银行类型 0:本行 1:他行',
agreement_status TINYINT DEFAULT 0 COMMENT '协议状态 0:未签约 1:已签约 2:已解约',
signing_date DATE COMMENT '签约日期',
termination_date DATE COMMENT '解约日期',
created_time DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_bill_key (bill_key),
INDEX idx_account_no (account_no),
INDEX idx_status (agreement_status)
);
```
## 5. 接口实现规范
### 5.1 查询接口实现
#### 5.1.1 业务流程
```
Client Request → Parameter Validation → Business Logic → Data Query → Response Format → Client Response
```
#### 5.1.2 核心逻辑
```java
@Service
public class BillQueryService {
public QueryResponse queryBill(QueryRequest request) {
// 1. 参数校验
validateRequest(request);
// 2. 业务逻辑处理
List<Bill> bills = billRepository.findByBillKeyAndCompanyId(
request.getBillKey(),
request.getCompanyId()
);
// 3. 构造响应
return buildQueryResponse(bills);
}
private void validateRequest(QueryRequest request) {
if (StringUtils.isEmpty(request.getBillKey())) {
throw new BusinessException("DEF0001", "客户编号不能为空");
}
// 其他校验逻辑...
}
}
```
### 5.2 缴费接口实现
#### 5.2.1 业务流程
```
Client Request → Parameter Validation → Balance Check → Payment Processing → Transaction Record → Response
```
#### 5.2.2 事务处理
```java
@Service
@Transactional
public class BillPayService {
public PayResponse payBill(PayRequest request) {
// 1. 参数校验
validatePayRequest(request);
// 2. 账单查询
Bill bill = billRepository.findByBillKeyAndCompanyId(
request.getBillKey(),
request.getCompanyId()
);
// 3. 金额校验
if (bill.getPayAmount().compareTo(request.getPayAmount()) != 0) {
throw new BusinessException("DEF0002", "缴费金额不匹配");
}
// 4. 更新账单状态
bill.setBillStatus(1);
billRepository.save(bill);
// 5. 记录交易
Transaction transaction = createTransaction(request);
transactionRepository.save(transaction);
// 6. 构造响应
return buildPayResponse(request);
}
}
```
## 6. 性能设计规范
### 6.1 性能指标
| 指标类型 | 要求 | 说明 |
|----------|------|------|
| 响应时间 | < 3秒 | 95%的请求在3秒内响应 |
| 并发量 | 1000 TPS | 支持1000笔/秒的交易处理 |
| 可用性 | 99.9% | 年度可用性不低于99.9% |
| 错误率 | < 0.1% | 系统错误率控制在0.1%以内 |
### 6.2 缓存策略
```java
@Service
public class BillQueryService {
@Cacheable(value = "billCache", key = "#billKey + '_' + #companyId")
public List<Bill> queryBillWithCache(String billKey, String companyId) {
return billRepository.findByBillKeyAndCompanyId(billKey, companyId);
}
}
```
### 6.3 数据库优化
#### 6.3.1 索引设计
- 主要查询字段建立索引
- 复合索引优化多条件查询
- 定期分析索引使用情况
#### 6.3.2 分表策略
- 按时间分表:每月一张交易表
- 按机构分库:不同机构使用不同数据库
## 7. 监控与日志规范
### 7.1 日志规范
#### 7.1.1 日志级别
- ERROR: 系统错误,需要立即处理
- WARN: 业务警告,需要关注
- INFO: 关键业务流程记录
- DEBUG: 调试信息
#### 7.1.2 日志格式
```
[时间戳] [日志级别] [线程名] [类名] [方法名] - [交易流水号] [业务描述] [详细信息]
```
示例:
```
2024-01-01 12:00:00.123 [INFO] [http-thread-1] [BillQueryService] [queryBill] - [TXN123456789012] 查询账单开始 {"billKey":"123456","companyId":"654321"}
```
### 7.2 监控指标
#### 7.2.1 业务监控
- 交易成功率
- 平均响应时间
- 接口调用量
- 错误码分布
#### 7.2.2 系统监控
- CPU使用率
- 内存使用率
- 数据库连接数
- 网络IO
## 8. 部署架构规范
### 8.1 生产环境架构
```
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ 负载均衡器 │────>│ Web服务器1 │ │ 数据库主库 │
│ (Nginx/F5) │ │ (Tomcat) │────>│ (MySQL) │
│ │ └─────────────────┘ │ │
│ │ ┌─────────────────┐ └─────────────────┘
│ │────>│ Web服务器2 │ ┌─────────────────┐
└─────────────────┘ │ (Tomcat) │────>│ 数据库从库 │
└─────────────────┘ │ (MySQL) │
└─────────────────┘
```
### 8.2 容器化部署
#### 8.2.1 Docker配置
```dockerfile
FROM openjdk:8-jre-alpine
VOLUME /tmp
ADD app.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
```
#### 8.2.2 Kubernetes配置
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: billing-api
spec:
replicas: 3
selector:
matchLabels:
app: billing-api
template:
metadata:
labels:
app: billing-api
spec:
containers:
- name: billing-api
image: billing-api:latest
ports:
- containerPort: 8080
resources:
requests:
memory: "512Mi"
cpu: "500m"
limits:
memory: "1Gi"
cpu: "1"
```
## 9. 测试规范
### 9.1 测试策略
#### 9.1.1 单元测试
- 覆盖率 >= 80%
- 核心业务逻辑 100% 覆盖
- Mock 外部依赖
#### 9.1.2 集成测试
- 接口层面的集成测试
- 数据库集成测试
- 第三方服务集成测试
#### 9.1.3 性能测试
- 压力测试:测试系统极限
- 负载测试:测试正常负载下的性能
- 稳定性测试:长时间运行测试
### 9.2 测试用例设计
#### 9.2.1 查询接口测试用例
```java
@Test
public void testQueryBill_Success() {
// Given
QueryRequest request = new QueryRequest();
request.setBillKey("123456");
request.setCompanyId("654321");
// When
QueryResponse response = billQueryService.queryBill(request);
// Then
assertEquals("AAAAAAA", response.getRespCode());
assertNotNull(response.getData());
}
@Test
public void testQueryBill_NotFound() {
// Given
QueryRequest request = new QueryRequest();
request.setBillKey("999999");
request.setCompanyId("654321");
// When & Then
BusinessException exception = assertThrows(
BusinessException.class,
() -> billQueryService.queryBill(request)
);
assertEquals("DEF0001", exception.getCode());
}
```
## 10. 安全审计规范
### 10.1 安全审计要求
#### 10.1.1 审计内容
- 所有接口调用记录
- 敏感操作日志
- 异常访问记录
- 系统配置变更
#### 10.1.2 审计日志格式
```json
{
"timestamp": "2024-01-01T12:00:00.123Z",
"event_type": "API_CALL",
"user_id": "bank_001",
"ip_address": "192.168.1.100",
"endpoint": "/api/app/billQuery/query",
"request_id": "TXN123456789012",
"response_code": "AAAAAAA",
"execution_time": 1500,
"data_accessed": {
"bill_key": "123456",
"company_id": "654321"
}
}
```
### 10.2 安全控制措施
#### 10.2.1 访问控制
- IP白名单机制
- API密钥认证
- 请求频率限制
#### 10.2.2 数据保护
- 敏感数据加密存储
- 传输过程加密
- 数据脱敏处理
## 11. 运维规范
### 11.1 发布流程
```
开发环境 → 测试环境 → 预生产环境 → 生产环境
↓ ↓ ↓ ↓
单元测试 集成测试 性能测试 灰度发布
```
### 11.2 回滚策略
#### 11.2.1 快速回滚
- 保留前一版本的部署包
- 数据库版本管理
- 配置文件版本控制
#### 11.2.2 回滚触发条件
- 系统错误率超过阈值
- 响应时间超过预期
- 业务功能异常
## 12. 总结
本规范设计文档为营收系统接口的设计、开发、测试、部署和运维提供了全面的指导。通过遵循这些规范,可以确保系统的:
1. **可靠性**:通过完善的错误处理和事务管理
2. **安全性**:通过多层次的安全控制措施
3. **性能**:通过合理的架构设计和优化策略
4. **可维护性**:通过标准化的代码和文档规范
5. **可扩展性**:通过模块化和微服务架构设计
建议在实际项目中根据具体需求对本规范进行适当调整和完善。

View File

@ -0,0 +1,385 @@
# 营收系统缴费接口文档
**版本:** 1.5
**作者:** 曹红强
**最后更新:** 2023/03/10
## 修订记录
| 版本号 | 修改日期 | 修改人 | 修改内容 |
|--------|----------|--------|----------|
| v1.0 | 2021/03/24 | 曹红强 | 初始版本 |
| v1.1 | 2021/04/04 | 曹红强 | 新增代扣相关接口 |
| v1.2 | 2021/12/21 | 曹红强 | 完善文档结构及说明 |
| v1.3 | 2022/01/25 | 晋腾飞 | 完善文档结构及说明 |
| v1.4 | 2022/05/02 | 晋腾飞 | 添加托收相关接口 |
| v1.5 | 2023/03/10 | 晋腾飞 | 添加加密方式说明 |
## 概述
本文档主要是针对营收系统和银行(或代收机构)间的实时收费、银行代扣、银行托收(小额支付)协议。
## 术语
1. **商户/第三方支付平台/支付平台/第三方/支付公司**:指第三方支付公司(比如支付宝、微信等)或者银行(比如招商银行、平安银行等)。
2. **公用事业单位**:指接入的缴费事业单位,例如自来水公司、电力公司等。第三方支付发起的实时交易经总行和分行转发最终到公用事业单位进行处理。
## 通讯模式
- **通讯协议**HTTP
- **提交方式**POST
- **加密方式**在请求头Header中填写
- **参数格式**HTTP包体中采用XML或JSON格式默认XML格式
- **服务端口和地址**:由公用事业单位提供
- **超时时间**银行方接收接口返回超时时间建议设置为30秒
## 报文说明
### 报文格式
#### XML格式示例
```xml
<?xml version="1.0" encoding="GBK"?>
<in>
<Version>1.0.1</Version>
<InstId>缴费渠道</InstId>
<TranCode>交易码</TranCode>
<TranDate>交易日期</TranDate>
<TranSeq>交易流水号</TranSeq>
<TAG1>VALUE1</TAG1>
<TAG2>VALUE2</TAG2>
</in>
```
#### 报文说明
1. **编码方式**:报文中固定写"GBK"实际编码采用GBK
2. **in**:根节点
3. **Version**:固定写"1.0.1"
4. **InstId**缴费渠道最大长度5个字节区别不同缴费渠道
5. **TranCode**:交易码
- 账单查询Query/QueryRes
- 账单缴费Pay/PayRes
6. **TranDate**交易日期格式YYYYMMDD
7. **TranSeq**交易流水号由银行系统产生最大长度40个字节同一天内不可重复
### 报文加密
#### 加密方式说明
加密方式填写在HTTP请求头Header里面支持的加密方式3DES、SM2、SM4
| 字段 | Header字段名 | 长度 | 约束条件 | 说明 |
|------|-------------|------|----------|------|
| 加密类型 | EncryptType | char(20) | 必填 | 3DES,SM2,SM4 (默认3DES) |
| 加密模式 | EncryptMode | char(20) | 必填 | 3DES(ECB), SM2(C1C2C3,C1C3C2), SM4(ECB,CBC) |
| 数据格式 | DataType | char(20) | 必填 | XML或JSON默认XML |
#### 默认加密方式
如果HTTP请求头HeaderEncryptType不填写加密方式默认为XML报文整体采用3DES函数加密ECB模式PKCS7填充。加密后的报文用base64编码。
#### SM2加密方式
HTTP请求头Header字段EncryptType填写SM2默认加密模式为C1C3C2默认报文body数据格式为XML。
#### SM4加密方式
HTTP请求头Header字段EncryptType填写SM4默认加密模式为ECB默认报文body数据格式为XML。
## 报文头
所有接口报文开始都有以下5个固定域
| 中文域名 | 标签名 | 长度 | 约束条件 | 说明 |
|----------|--------|------|----------|------|
| 版本号 | Version | char(20) | 必填 | 固定为1.0.1 |
| 缴费渠道 | InstId | char(5) | 必填 | 由水司软件方提供 |
| 交易码 | TranCode | char(20) | 必填 | 见交易码说明 |
| 交易日期 | TranDate | char(8) | 必填 | YYYYMMDD |
| 流水号 | TranSeq | char(40) | 必填 | 银行系统产生的唯一流水号 |
### 交易码说明
- 账单查询Query/QueryRes
- 账单缴费Pay/PayRes
- 代扣签约Signing/SigningRes
- 代扣解约Termination/TerminationRes
- 代扣送盘SendDisc/SendDiscRes
- 代扣回盘BackDisc/BackDiscRes
- 取消代扣CancelDisc/CancelDiscRes
## 接口规范
### 1. 账单查询接口
#### 请求接口
- **接口地址**`/api/app/billQuery/query`
- **请求方法**POST
- **交易码**Query
#### 请求参数
| 中文域名 | 标签名 | 长度 | 约束条件 | 说明 |
|----------|--------|------|----------|------|
| 客户编号 | billKey | char(35) | 必填 | 用水户的唯一标识 |
| 机构编码 | companyId | char(30) | 必填 | 由水司软件方提供 |
| 开始条数 | beginNum | Num(5) | 可选 | 默认1 |
| 查询条数 | queryNum | Num(5) | 可选 | 默认1最大100 |
| 扩展字段1 | filed1 | char(100) | 可选 | 扩展字段 |
| 扩展字段2 | filed2 | char(100) | 可选 | 扩展字段 |
| 扩展字段3 | filed3 | char(100) | 可选 | 扩展字段 |
| 扩展字段4 | filed4 | char(100) | 可选 | 扩展字段 |
#### 请求示例
```xml
<?xml version="1.0" encoding="GBK"?>
<in>
<Version>1.0.1</Version>
<InstId>00001</InstId>
<TranCode>Query</TranCode>
<TranDate>20180101</TranDate>
<TranSeq>123456789012</TranSeq>
<billKey>123456</billKey>
<companyId>654321</companyId>
<beginNum>1</beginNum>
<queryNum>1</queryNum>
<filed1></filed1>
<filed2></filed2>
<filed3></filed3>
<filed4></filed4>
</in>
```
#### 应答参数
| 中文域名 | 标签名 | 长度 | 说明 |
|----------|--------|------|------|
| 返回代码 | RespCode | char(7) | 查询返回代码 |
| 返回说明 | RespMessage | char(60) | 查询返回说明 |
| 客户编号 | billKey | char(35) | 原样返回 |
| 机构编码 | companyId | char(30) | 原样返回 |
| 总条数 | totalNum | Num(5) | 查询结果总条数 |
#### Data数据结构
| 中文域名 | 标签名 | 长度 | 说明 |
|----------|--------|------|------|
| 合同号 | contractNo | char(30) | 合同号码 |
| 客户姓名 | customerName | char(150) | 客户姓名 |
| 余额 | balance | Number(16,2) | 账户余额 |
| 缴费金额 | payAmount | Number(16,2) | 应缴费金额 |
| 开始日期 | beginDate | char(8) | 账单开始日期 |
| 结束日期 | endDate | char(8) | 账单结束日期 |
#### 应答示例
```xml
<?xml version="1.0" encoding="GBK"?>
<out>
<Version>1.0.1</Version>
<InstId>00001</InstId>
<TranCode>QueryRes</TranCode>
<TranDate>20180101</TranDate>
<TranSeq>123456789012</TranSeq>
<RespCode>AAAAAAA</RespCode>
<RespMessage>查询成功</RespMessage>
<billKey>123456</billKey>
<companyId>654321</companyId>
<totalNum>1</totalNum>
<Data>
<contractNo>123456</contractNo>
<customerName>张三</customerName>
<balance></balance>
<payAmount>2314</payAmount>
<beginDate></beginDate>
<endDate></endDate>
</Data>
</out>
```
### 2. 缴费接口
#### 请求接口
- **接口地址**`/api/app/billPay/pay`
- **请求方法**POST
- **交易码**Pay
#### 请求参数
| 中文域名 | 标签名 | 长度 | 约束条件 | 说明 |
|----------|--------|------|----------|------|
| 客户编号 | billKey | char(35) | 必填 | 用水户的唯一标识 |
| 机构编码 | companyId | char(30) | 必填 | 由水司软件方提供 |
| 缴费日期 | payDate | char(14) | 必填 | YYYYMMDDHHMMSS |
| 客户姓名 | customerName | char(150) | 必填 | 客户姓名 |
| 缴费金额 | payAmount | Number(16,2) | 必填 | 缴费金额 |
| 合同号 | contractNo | char(30) | 必填 | 合同号码 |
| 查询类型 | queryType | char(1) | 可选 | 默认0客户编号查询1条形码查询 |
| 二级渠道 | subChannel | char(1) | 可选 | 1:支付宝 2:微信 6:其它 |
#### 请求示例
```xml
<?xml version="1.0" encoding="GBK"?>
<in>
<Version>1.0.1</Version>
<InstId>00001</InstId>
<TranCode>Pay</TranCode>
<TranDate>20180101</TranDate>
<TranSeq>123456789012</TranSeq>
<billKey>123456</billKey>
<companyId>654321</companyId>
<payDate>20110513081540</payDate>
<customerName>张三</customerName>
<payAmount>5555</payAmount>
<contractNo>123456</contractNo>
</in>
```
#### 应答参数
| 中文域名 | 标签名 | 长度 | 说明 |
|----------|--------|------|------|
| 返回代码 | RespCode | char(7) | 缴费返回代码 |
| 返回说明 | RespMessage | char(60) | 缴费返回说明 |
| 客户编号 | billKey | char(35) | 原样返回 |
| 机构编码 | companyId | char(30) | 原样返回 |
| 交易日期 | payDate | char(14) | 原样返回 |
| 缴费金额 | payAmount | Number(16,2) | 原样返回 |
#### 应答示例
```xml
<?xml version="1.0" encoding="GBK"?>
<out>
<Version>1.0.1</Version>
<InstId>00001</InstId>
<TranCode>PayRes</TranCode>
<TranDate>20180101</TranDate>
<TranSeq>123456789012</TranSeq>
<RespCode>AAAAAAA</RespCode>
<RespMessage>缴费成功</RespMessage>
<billKey>123456</billKey>
<companyId>654321</companyId>
<payDate>20110513081540</payDate>
<payAmount>5555</payAmount>
</out>
```
### 3. 账单红冲接口
#### 请求接口
- **接口地址**`/api/app/payInvalid/payInvalid`
- **请求方法**POST
- **交易码**PayInvalid
#### 请求参数
| 中文域名 | 标签名 | 长度 | 约束条件 | 说明 |
|----------|--------|------|----------|------|
| 机构编码 | companyId | char(30) | 必填 | 由水司软件方提供 |
| 交易日期 | payDate | char(14) | 必填 | YYYYMMDDHHMMSS |
| 红冲流水号 | agencyBillNo | char(30) | 必填 | 缴费时的账单流水号 |
| 缴费金额 | payMoney | char(30) | 必填 | 缴费金额 |
**说明**:只可红冲当天收费且未对账交易,红冲成功后银行需发起自动退款。
### 4. 代扣签约接口
#### 请求接口
- **接口地址**`/api/app/bankWithholding/signing`
- **请求方法**POST
- **交易码**Signing
#### 请求参数
| 中文域名 | 标签名 | 长度 | 约束条件 | 说明 |
|----------|--------|------|----------|------|
| 客户编号 | billKey | char(35) | 必填 | 用水户的唯一标识 |
| 机构编码 | companyId | char(30) | 必填 | 由水司软件方提供 |
| 签约日期 | signingDate | char(8) | 必填 | YYYYMMDD |
| 开户名 | accountName | char(150) | 必填 | 开户名 |
| 开户账号 | accountNo | char(30) | 必填 | 用户的账号 |
| 银行名称 | bankName | char(150) | 可选 | 总行名称 |
| 合同号 | contractNo | char(150) | 可选 | 合同号 |
| 协议号 | agreementNo | char(150) | 可选 | 协议号 |
| 银行类型 | bankType | char(1) | 可选 | 0本行 1他行 |
### 5. 代扣解约接口
#### 请求接口
- **接口地址**`/api/app/bankWithholding/termination`
- **请求方法**POST
- **交易码**Termination
### 6. 代扣送盘接口
#### 请求接口
- **接口地址**`/api/app/bankWithholding/sendDisc`
- **请求方法**POST
- **交易码**SendDisc
### 7. 代扣回盘接口
#### 请求接口
- **接口地址**`/api/app/bankWithholding/backDisc`
- **请求方法**POST
- **交易码**BackDisc
## 对账文件
### 对账文件格式
对账文件为文本文件txt格式编码格式为UTF-8包括明细行和汇总行。行内每个分项之间以"|"为分隔符。
#### 汇总行格式
```
交易笔数|总金额
```
#### 明细行格式
```
交易日期|交易流水号|客户编号|缴费金额|二级渠道|交易类型
```
#### 文件命名规则
```
机构编码(companyId)_对账日期.txt
```
其中对账日期为交易当天日期非当前时间。
## 返回代码说明
| 序号 | 错误码 | 错误说明 |
|------|--------|----------|
| 0 | AAAAAAA | 成功 |
| 1 | DEF0001 | 无相应记录 |
| 2 | DEF0002 | 用户未欠费 |
| 3 | DEF0003 | 与第三方通讯失败 |
| 4 | DEF0004 | 超过受理期,银行不予受理,请至缴费单位缴费 |
## 附录
### 扣款结果标志说明
- **0**:扣款成功,其余状态按失败处理
- **1**:扣款失败,余额不足
- **2**:账号、户名错误
- **3**:账号不存在
- **4**:重复扣款
- **99**:其他原因
### 二级渠道说明
- **1**:支付宝
- **2**:微信
- **6**:其它
### 银行类型说明
- **0**:本行
- **1**:他行

View File

@ -0,0 +1,606 @@
# 营收系统缴费接口
**版本:** 1.5
**作者:** 曹红强
## 修订记录
| 版本号 | 修改日期 | 修改人 | 修改内容 |
|---|---|---|---|
| v1.0 | 2021/03/24 | 曹红强 | 初始版本 |
| v1.1 | 2021/04/04 | 曹红强 | 新增代扣相关接口 |
| v1.2 | 2021/12/21 | 曹红强 | 完善文档结构及说明 |
| v1.3 | 2022/01/25 | 晋腾飞 | 完善文档结构及说明 |
| v1.4 | 2022/05/02 | 晋腾飞 | 添加托收相关接口 |
| v1.5 | 2023/03/10 | 晋腾飞 | 添加加密方式说明 |
## 概述
本文档主要是针对营收系统和银行(或代收机构)间的实时收费、银行代扣、银行托收(小额支付)协议。
## 术语
1. 文档中提到的商户、第三方支付平台、支付平台、第三方、支付公司指的就是第三方支付公司(比如支付宝,微信等)或者银行(比如招商银行,平安银行等)。
2. 公用事业单位:是指从接入的缴费事业单位,例如:自来水公司,电力公司等,第三方支付发的实时交易经总行和分行转发最终到公用事业单位进行处理。
## 通讯模式
公用事业单位和银行系统之间采用 Http 进行通讯,提交方式为 POST加密方式在请求头 Header 填写,接口参数在 Http 包体中采用 XML 或 JSON 格式,默认 XML 格式。服务端口和服务地址,由公用事业单位提供。银行方接收接口返回超时时间建议设置为 30 秒。
## 报文说明
### 报文格式
#### XML
```xml
<?xml version="1.0" encoding="GBK"?>
<in>
<Version>1.0.1</Version>
<InstId>缴费渠道</InstId>
<TranCode>交易码</TranCode>
<TranDate>交易日期</TranDate>
<TranSeq>交易流水号</TranSeq>
<TAG1>VALUE1</TAG1>
<TAG2>VALUE2</TAG2>
</in>
```
如上所示为 XML 报文示例:
1. 编码方式在报文中固定写“GBK”但是实际的编码采用 GBK
2. `in`:根节点;
3. `Version`固定写“1.0.1”。
4. `InstId`:缴费渠道,长度最大长度 5 个字节,区别不同缴费渠道
5. `TranCode`:交易码,账单查询时交易码为 Query,查询应答给银行为 QueryRes账单缴费时交易码为 Pay缴费应答给银行时为 PayRes。
6. `TranDate`交易日期YYYYMMDD如 20210101当前交易时间。
7. `TranSeq`:交易流水号,由银行系统产生,用作标识每笔交易的请求,最大长度 40 个字节,并且同一天内该值不可重复。
8. `TAG1`:节点标签名;
9. `VALUE1`:节点值。
### 报文模版
#### 请求
```xml
<?xml version="1.0" encoding="GBK"?>
<in>
<Version>1.0.1</Version>
<InstId>00001</InstId>
<TranCode>Query</TranCode>
<TranDate>20180101</TranDate>
<TranSeq>123456789012</TranSeq>
<billKey>客户编号</billKey>
……
</in>
```
#### 应答
```xml
<?xml version="1.0" encoding="GBK"?>
<out>
<Version>1.0.1</Version>
<InstId>00001</InstId>
<TranCode>QueryRes</TranCode>
<TranDate>请求的日期原样返回</TranDate>
<TranSeq>请求的日期原样返回</TranSeq>
<RespCode>AAAAAAA</RespCode>
<RespMessage>成功</RespMessage >
<billKey>客户编号</billKey>
……
<totalNum>1</totalNum>
<Data>
<contractNo>合同号</contractNo>
</Data>
</out>
```
### 报文样例
#### 查询请求
```xml
<?xml version="1.0" encoding="GBK"?>
<in>
<Version>1.0.1</Version>
<InstId>00001</InstId>
<TranCode>Query</TranCode>
<TranDate>20180101</TranDate>
<TranSeq>123456789012</TranSeq>
<billKey>123456</billKey>
<companyId>654321</companyId>
<beginNum>1</beginNum>
<queryNum>1</queryNum>
<filed1></filed1>
<filed2></filed2>
<filed3></filed3>
<filed4></filed4>
</in>
```
#### 查询应答
```xml
<?xml version="1.0" encoding="GBK"?>
<out>
<Version>1.0.1</Version>
<InstId>00001</InstId>
<TranCode>QueryRes</TranCode>
<TranDate>20180101</TranDate>
<TranSeq>123456789012</TranSeq>
<RespCode>AAAAAAA</RespCode>
<RespMessage>查询成功
</ RespMessage >
<billKey>123456</billKey>
<companyId>654321</companyId>
<item1></item1>
<item2></item2>
<item3></item3>
<item4></item4>
<item5></item5>
<item6></item6>
<item7></item7>
<totalNum>1</totalNum>
<Data>
<contractNo>123456</contractNo>
<customerName>张三</customerName>
<balance></balance>
<payAmount>2314</payAmount>
<beginDate></beginDate>
<endDate></endDate>
<filed1></filed1>
<filed2></filed2>
<filed3></filed3>
<filed4></filed4>
<filed5></filed5>
</Data>
</out>
```
### 销账请求
```xml
<?xml version="1.0" encoding="GBK"?>
<in>
<Version>1.0.1</Version>
<InstId>00001</InstId>
<TranCode>Pay</TranCode>
<TranDate>20180101</TranDate>
<TranSeq>123456789012</TranSeq>
<billKey>123456</billKey>
<companyId>654321</companyId>
<payDate>20110513081540</payDate>
<filed1> </filed1>
<filed2> </filed2>
<filed3> </filed3>
<filed4> </filed4>
<customerName>张三</customerName>
<payAmount>5555</payAmount>
<contractNo>123456</contractNo>
</in>
```
### 销账应答
```xml
<?xml version="1.0" encoding="GBK"?>
<in>
<Version>1.0.1</Version>
<InstId>00001</InstId>
<TranCode>PayRes</TranCode>
<TranDate>20180101</TranDate>
<TranSeq>123456789012</TranSeq>
<RespCode>AAAAAA</RespCode>
<RespMessage>缴费成功</RespMessage>
<billKey>123456</billKey>
<companyId>654321</companyId>
<payDate>20110513081540</payDate>
<payAmount>5555</payAmount>
</in>
```
## 报文编码
报文中可能有汉字,需要对报文进行 GBK 编码才能正常显示。
1. 编码方式在报文中固定写“GBK”
## 报文加密
### 加密方式说明
加密方式填写在 http 请求头 Header 里面加密方式有3DES,SM2,SM4加密方式对 body 数据整体进行加密
| 中文域名 | 字段 | 长度 | 约束条件 | 说明 |
|---|---|---|---|---|
| 加密类型 | EncryptType | char(20) | 必填 | 3DES,SM2,SM4 (默认 3DES) |
| 加密模式 | EncryptMode | char(20) | 必填 | 3DES(ECB), SM2(C1C2C3,C1C3C2), SM4(ECB,CBC) |
| 数据格式 | DataType | char(20) | 必填 | XML 或 JOSN (默认 XML) |
### 默认加密方式
如果 http 请求头 HeaderEncryptType不填写加密方式默认为 XML 报文整体采用 3DES 函数加密ECB 模式 PKCS7P 填充。
加密之后的报文,用 base64 编码。
### SM2 加密方式
http 请求头 Header 字段 EncryptType 填写 SM2默认加密模式为 C1C3C2,默认报文 body 数据格式为 XML
### SM4 加密方式
http 请求头 Header 字段 EncryptType 填写 SM4默认加密模式为 ECB,默认报文 body 数据格式为 XML
### 加密请求示例
加密方式请求头填写示例:
```
[Image Placeholder for Encrypt Header Example]
```
加密 body 请求示例:
```
[Image Placeholder for Encrypt Body Example]
```
## 报文头
### 报文头固定域
所有接口报文开始,都有这 5 个域,这里统一说明。查询和缴费的章节,不再说明报文头这 5 个域。
| 中文域名 | 标签名 | 长度 | 对应字段 | 约束条件 | 说明 |
|---|---|---|---|---|---|
| 版本号 | Version | char(20) | | 必填 | 固定为 1.0.1 |
| 缴费渠道 | InstId | char(5) | | 必填 | 由水司软件方提供 |
| 交易码 | TranCode | char(20) | | 必填 | 见说明 |
| 交易日期 | TranDate | char(8) | | 必填 | YYYYMMDD |
| 流水号 | TranSeq | char(40) | Input2 | 必填 | 见说明 |
说明:
* **交易码:**
* 账单查询时交易码为 Query,查询应答给予银行为 QueryRes
* 账单缴费时交易码为 Pay,缴费应答时为 PayRes
* 代扣签约请求时交易码为 Signing,签约应答时为 SigningRes
* 代扣解约请求时交易码为 Termination,解约应答时为 TerminationRes
* 代扣送盘请求时交易码为 SendDisc,送盘应答时交易码为 SendDiscRes
* 代扣回盘请求时交易码为 BackDisc,回盘应答时交易码为 BackDiscRes
* 取消代扣交易请求时交易码为 CancelDisc,应答码为 CancelDiscRes
* 代扣送盘状态查询交易码为 SendDiscCheck,应答交易码为 SendDiscCheckRes
* 代扣回盘状态查询交易码为 BackDiscCheck,应答交易码为 BackDiscCheckRes
* 客户基本信息查询交易码为 CustomerCheck, 应答交易码为 CustomerCheckRes;
* 实时收费红冲查询交易码为 PayInvalid,应答交易码为 PayInvalidRes;
* 代理收费向公用事业单位发起缴费单对账请求交易码为 PayCheck应答交易码为 PayCheckRes。
* **交易流水号:** 由银行系统产生,用作标识每笔交易的请求,最大长度 40 个字节,并且值不可重复。
## 请求图例
### PostMan
```
[Image Placeholder for PostMan Example]
```
### Swagger
```
[Image Placeholder for Swagger Example]
```
说明:
* 请求返回 415 或 400 Body 加密内容请前后添加双引号
* 请求返回 500 请联系运维人员参与对接
## 1.1 实时收费
### 欠费查询
Query 是从银行向公用事业单位发起的查询缴费单信息的请求报文。
**请求地址:** `/api/app/payCeb/getChargeSearch`
| 中文域名 | 标签名 | 长度 | 对应字段 | 约束条件 | 说明 |
|---|---|---|---|---|---|
| 客户编号 | billKey | char(35) | Input1 | 必填 | 客户编号 |
| 机构编码 | companyId | char(30) | | 必填 | 由水司软件方提供 |
| 查询类型 | billType | char(10) | | 必填 | 见说明 |
| 起始笔数 | beginNum | Num(3) | | | 查询起始笔数,从 1 开始 |
| 查询笔数 | queryNum | Num(3) | | | 查询笔数 |
| 备用字段 | filed1 | char(100) | Input2 | | 二级渠道,默认 6见说明 |
| 备用字段 | filed2 | char(100) | Input3 | | 预留字段 |
| 备用字段 | filed3 | char(100) | Input4 | | 预留字段 |
| 备用字段 | filed4 | char(100) | Input5 | | 预留字段 |
说明:
* **查询类型:** 默认 0客户编号查询1 条形码查询,客户编号为条形码;
* **二级渠道:**
* 1:支付宝;
* 2微信
* 6实时收费
### 应答报文
QueryRes 是公用事业单位返回给银行的查询应答报文。
| 中文域名 | 标签名 | 长度 | 对应字段 | 说明 |
|---|---|---|---|---|
| 返回代码 | RespCode | 7 | | 查询返回代码 |
| 返回说明 | RespMessage | 60 | | 查询返回说明 |
| 客户编号 | billKey | char(35) | Output1 | 原样返回 |
| 机构编码 | companyId | Num(30) | | 原样返回 |
| 备用字段 | item1 | Num(100) | Output2 | 预留数据域 |
| 备用字段 | item2 | char(100) | Output3 | 预留数据域 |
| 备用字段 | item3 | char(100) | Item1 | 预留数据域 |
| 备用字段 | item4 | char(100) | Item2 | 预留数据域 |
| 备用字段 | item5 | char(100) | Item3 | 预留数据域 |
| 备用字段 | item6 | char(100) | Item4 | 预留数据域 |
| 备用字段 | item7 | char(100) | Item5 | 预留数据域 |
| 总笔数 | totalNum | char(3) | TotalNum | 返回总查询笔数 |
| 合同号 | contractNo | char(30) | ContractNo | 账单唯一标识 |
| 客户姓名 | customerName | char(100) | CustomerName | 循环域 |
| 余额 | balance | Number | Balance | 循环域(单位:分) |
| 应缴金额 | payAmount | Number | Amount | 循环域(单位:分) |
| 起始日期 | beginDate | char(10) | BeginDate | 循环域,停用字段 |
| 截至日期 | endDate | char(10) | EndDate | 循环域,停用字段 |
| 备用字段 | filed1 | char(100) | FormItem1 | 循环域 账期 |
| 备用字段 | filed2 | char(100) | FormItem2 | 循环域 滞纳金 |
| 备用字段 | filed3 | char(100) | FormItem3 | 循环域 |
| 备用字段 | filed4 | char(100) | FormItem4 | 循环域 |
| 备用字段 | filed5 | char(100) | FormItem5 | 循环域 客户地址 |
### 欠费缴纳
Pay 是银行向公用事业单位发起的欠费缴纳的请求报文。
**请求地址:** `/api/app/payCeb/getChargeOffs`
| 中文域名 | 标签名 | 长度 | 对应字段 | 约束条件 | 说明 |
|---|---|---|---|---|---|
| 客户编号 | billKey | char(35) | Input1 | 必填 | 客户编号 |
| 机构编码 | companyId | char(30) | | 必填 | 由水司软件方提供 |
| 查询类型 | billType | char(10) | | 必填 | 见说明 |
| 交易日期 | payDate | Num(3) | | 必填 | 见说明 |
| 备用字段 | filed1 | char(100) | Input2 | | 帐期 |
| 备用字段 | filed2 | char(100) | Input3 | | 滞纳金(单位:分) |
| 备用字段 | filed3 | char(100) | Item1 | 必填 | 二级渠道,见说明 |
| 备用字段 | filed4 | char(100) | Item2 | | 预留数据域 |
| 客户姓名 | customerName | char(100) | CustomerName | | 查询应答报文取 |
| 缴费金额 | payAmount | Number | Amount | 必填 | (单位:分) |
| 合同号 | contractNo | char(30) | ContractNo | 必填 | 查询接口应答报文取 |
说明:
* **查询类型:** 默认 0客户编号查询1 条形码查询,客户编号为条形码;
* **交易日期:** YYYYMMDDHHMMSS(支付缴费单时系统当前时间)
* **二级渠道:**
* 1支付宝
* 2微信
* 6其它
### 应答报文
PayRes 公用事业单位返回银行的缴费应答报文。
| 中文域名 | 标签名 | 长度 | 对应字段 | 说明 |
|---|---|---|---|---|
| 返回代码 | RespCode | 7 | | 缴费返回代码 |
| 返回说明 | RespMessage | 60 | | 缴费返回说明 |
| 客户编号 | billKey | char(35) | | 原样返回 |
| 机构编码 | companyId | Num(30) | | 原样返回 |
| 交易日期 | payDate | Num(14) | | 原样返回 |
| 缴费金额 | payAmount | Number(16,2) | | 原样返回 |
## 账单红冲
### 请求报文
PayInvalid 是从银行向公用事业单位发起的红冲缴费单信息的请求报文,只可红冲当天收费且未对账交易,红冲成功后银行需发起自动退款。
**请求接口:** `/api/app/payInvalid/payInvalid`
| 中文域名 | 标签名 | 长度 | 约束条件 | 说明 |
|---|---|---|---|---|
| 机构编码 | companyId | char(30) | 必填 | 由水司软件方提供 |
| 交易日期 | payDate | char(30) | | 交易日期 |
| 红冲流水号 | agencyBillNo | char(30) | | 缴费时的账单流水号 |
| 缴费金额 | payMoney | char(30) | | 缴费金额 |
说明:
* **交易日期:** YYYYMMDDHHMMSS(支付缴费单时系统时间)
### 应答报文
PayInvalidRes 是公用事业单位返回给银行的红冲缴费单信息的应答报文。
| 中文域名 | 标签名 | 长度 | 对应字段 | 约束条件 | 说明 |
|---|---|---|---|---|---|
| 返回代码 | RespCode | char(30) | | 必填 | 返回代码 |
| 返回说明 | RespMessage | char(30) | | 必填 | 返回说明 |
| 机构编码 | companyId | char(30) | | 必填 | 由水司软件方提供 |
| 交易日期 | payDate | char(30) | | | 交易日期 |
| 红冲流水号 | agencyBillNo | char(30) | | | 缴费时的账单流水号 |
| 缴费金额 | payMoney | char(30) | | | 缴费金额 |
## 对账文件上传
### 账单说明
银行每天日结后,进行批处理,自动生成和传送(通过 FTP 或 SFTP对账文件给公用事业单位。
### 对账文件格式
对账文件为文本文件 txt 格式,编码格式为 UTF-8包括明细行和汇总行。行内每个分项之间以“|”为分隔符。无交易数据时,对账文件有且只有一条汇总行。汇总行放在文件前面,定义如下:
`交易笔数|总金额`
明细行的定义如下:
`交易日期|交易流水号|客户编号|缴费金额|二级渠道|交易类型`
注释:对账文件内的交易流水号要与缴费时的流水号保持一致。
说明:
1. **关于文件命名:**
T 日所有交易按收费单位生成 n 个对账文件,文件名:机构编码(companyId)_对账日期.txt其中对账日期为交易当天日期非当前时间。
例如某水司机构编码companyId为 yhcs_yh则 2021 年 1 月 1 日对账文件yhcs_yh_20210101.txt
2. 文件中只含缴费成功的交易;
3. 缴费金额单位是分;
4. 交易类型:默认 0客户编号查询1 条形码查询;
5. 文件编码格式采用 UTF-8。
### 对账接口
#### 对账说明
由代理收费公司每天日切后,进行批处理,自动生成和传送对账文件给公用事业单位。
#### 请求报文
PayCheck 代理收费向公用事业单位发起的缴费单对账的请求报文。
**请求接口:** `/api/app/payCeb/paymentCheck`
| 中文域名 | 标签名 | 长度 | 约束条件 | 说明 |
|---|---|---|---|---|
| 机构编码 | companyId | char(30) | 必填 | 由水司软件方提供 |
| 对账日期 | payDate | char(8) | 必填 | 需要对账的日期,非实时日期 |
| 交易笔数 | payCount | char(8) | 必填 | 交易总笔数 |
| 交易总金额 | payMoney | char(10) | 必填 | 交易总金额到分 |
| 对账文件名 | fileName | Char(100) | 必填 | 见说明 |
说明:
* **对账文件名:** 机构编码(companyId)_对账日期.txt其中对账日期为交易当天日期非当前时间。
* **交易日期:** YYYYMMDDHHMMSS(支付缴费单时系统时间)
#### 应答报文
PayCheckRes 公用事业单位返回的缴费对账应答报文。
| 中文域名 | 标签名 | 长度 | 约束条件 |
|---|---|---|---|
| 返回代码 | RespCode | 7 | 缴费返回代码 |
| 返回说明 | RespMessage | 60 | 缴费返回说明 |
| 机构编码 | companyId | char(30) | 原样返回 |
| 交易日期 | payDate | char(14) | 原样返回 |
| 缴费金额 | payAmount | Number(16,2) | 原样返回 |
## 1.2 银行代扣
### 代扣签约
Signing 是从银行向公用事业单位发起的代扣签约信息的请求报文。
**请求接口:** `/api/app/bankWithholding/signing`
| 中文域名 | 标签名 | 长度 | 对应字段 | 约束条件 | 说明 |
|---|---|---|---|---|---|
| 客户编号 | billKey | char(35) | Input1 | 必填 | 客户编号 |
| 机构编码 | companyId | char(30) | | 必填 | 由水司软件方提供 |
| 开户名称 | accountName | char(100) | | 必输 | 开户名称 |
| 开户账号 | accountNo | char(30) | | 必填 | 开户账号 |
| 开户行 | branchName | char(150) | | 必填 | 开户行 |
| 合同号 | contractNo | char(50) | | | 合同号 |
| 备用字段 | filed1 | char(100) | | | 预留字段 |
| 备用字段 | filed2 | char(100) | | | 预留字段 |
| 备用字段 | filed3 | char(100) | | | 预留字段 |
### 应答报文
SigningRes 是公用事业单位返回给银行的查询应答报文。
| 中文域名 | 标签名 | 长度 | 对应字段 | 说明 |
|---|---|---|---|---|
| 返回代码 | RespCode | 7 | | 查询返回代码 |
| 返回说明 | RespMessage | 60 | | 查询返回说明 |
| 客户编号 | billKey | char(35) | | 原样返回 |
| 备用字段 | filed1 | char(100) | | 循环域 |
| 备用字段 | filed2 | char(100) | | 循环域 |
| 备用字段 | filed3 | char(100) | | 循环域 |
### 代扣解约
Termination 是从银行向公用事业单位发起的代扣解约信息的请求报文。
**请求地址:** `/api/app/bankWithholding/termination`
| 中文域名 | 标签名 | 长度 | 对应字段 | 约束条件 | 说明 |
|---|---|---|---|---|---|
| 客户编号 | billKey | char(35) | Input1 | 必填 | 客户编号 |
| 机构编码 | companyId | char(30) | | 必填 | 由水司软件方提供 |
| 开户名称 | accountName | char(100) | | 必输 | 开户名称 |
| 开户账号 | accountNo | char(30) | | 必填 | 开户账号 |
| 开户行 | branchName | char(150) | | 必填 | 开户行 |
| 合同号 | contractNo | char(50) | | | |
| 备用字段 | filed1 | char(100) | | | 预留字段 |
| 备用字段 | filed2 | char(100) | | | 预留字段 |

View File

@ -0,0 +1,162 @@
# REV004 账务调整统一标准层 — 第一批代码启动证据2026-04-15
## 本轮新增代码
### 标准层 helper
- `sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/service/accountingadjust/standard/AccountingAdjustSemanticMapper.java`
- `sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/service/accountingadjust/standard/AccountingAdjustDictResolver.java`
- `sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/service/accountingadjust/standard/AccountingAdjustStatusResolver.java`
### late-fee reduce formal-table 申请态/审批态基础
- `sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/dal/dataobject/latefeereduce/LateFeeReduceDO.java`
- `sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/dal/dataobject/latefeereducedetail/LateFeeReduceDetailDO.java`
- `sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/dal/mysql/latefeereduce/LateFeeReduceMapper.java`
- `sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/dal/mysql/latefeereducedetail/LateFeeReduceDetailMapper.java`
- `sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/service/accountingadjust/latefeereduce/LateFeeReduceFormalizationService.java`
### 已接入主链 / 读模型
- `AccountingAdjustProcessServiceImpl`
- `AccountingAdjustActionServiceImpl`
- `AccountingAdjustQueryServiceImpl`
- `AccountingAdjustLogProcessServiceImpl`
- `AccountingAdjustProcessRespVO`
- `AccountingAdjustDetailRespVO`
- `AccountingAdjustLogDetailRespVO`
- `AccountingAdjustPageRespVO`
- `AccountingAdjustLogPageRespVO`
### 对应测试
- `AccountingAdjustSemanticMapperTest`
- `AccountingAdjustDictResolverTest`
- `AccountingAdjustStatusResolverTest`
- `LateFeeReduceFormalizationServiceTest`
- `AccountingAdjustQueryServiceImplTest`
- `AccountingAdjustLogProcessServiceImplTest`
- `AccountingAdjustProcessServiceImplTest`(定向方法)
- `AccountingAdjustActionServiceImplTest`late-fee approval 定向方法)
## 本轮目标
1. 完成 Task-01 标准层 helper 最小实现
2. 将字典/状态 helper 接入 late-fee 相关读模型
3. 接入 late-fee reduce formal-table 申请态写入
4. 接入审批通过后 formal-table 最小更新闭环
5. 补 page / log-page 摘要字段试点
## 新鲜验证证据
### 1. 编译
执行:
```bash
rm -rf sw-business/sw-business-server/target/generated-sources \
sw-business/sw-business-server/target/generated-test-sources
mkdir -p sw-business/sw-business-server/target/generated-sources/annotations
mvn -pl sw-business/sw-business-server -DskipTests compile
```
结果:**PASS**
### 2. 定向测试
执行:
```bash
mvn -pl sw-business/sw-business-server \
-Dtest=AccountingAdjustQueryServiceImplTest,AccountingAdjustLogProcessServiceImplTest,AccountingAdjustProcessServiceImplTest#createUnsoldLateFeeReduce_shouldPassDateModeFieldsToUnifiedChargeService+createUnsoldLateFeeReduce_shouldRejectMixedAmountAndDateMode+batchCreateUnsoldLateFeeReduce_shouldMergeBatchOuterFieldsIntoItems+getProcess_shouldExposeLateFeeDisplayFieldsFromUnifiedSnapshot,AccountingAdjustActionServiceImplTest#approve_lateFeeReduceShouldOnlyUpdateLateFee,LateFeeReduceFormalizationServiceTest,AccountingAdjustSemanticMapperTest,AccountingAdjustDictResolverTest,AccountingAdjustStatusResolverTest \
test
```
结果:**PASS24 tests, 0 fail, 0 error**
## 当前结论
本轮已把第一批试点推进到:
- helper 已落地
- helper 已接入 late-fee 相关读模型
- late-fee formal-table 申请态写入已接入提交主链
- 审批通过后 formal-table 最小更新闭环已接入
- page / log-page 摘要字段试点已补
- compile 通过
- 定向测试通过
## 下一步
1. 继续推进 `lateFeeType=2` 按日期模式真正计算闭环
2. 补 formal-table 中 `before/reduce/after` 的更精确计算与状态更新
## 追加说明date-mode 精确计算规则)
### 当前实现口径
- 使用 `LateFeeDateModeCalculator`
- 所有未缴费用项参与计算
- 逐项通过 `ChargeDetailDO.costComponentCode -> CostComponentDO.penaltyCoefficient` 取系数
- `penaltyCoefficient = 0` 的费用项自然贡献 0
- 每项先四舍五入到分,最后汇总
- `lateFeeBefore` / `lateFeeAfter` 使用区间口径,而不是整账单总值口径
### 已覆盖边界测试
- 多费用项逐项计算并汇总
- 起算日晚于用户选择开始日时自动裁剪有效区间
- 0 系数费用项混合场景
- 计算结果大于当前 `lateFee` 时,`reduceAmount` 按当前 `lateFee` 封顶
- 截止日早于有效起算日时返回 0
## 2026-04-15 补充进展:真实库 canary 拉绿
### 本轮补充代码
- `sw-business/sw-business-server/src/test/resources/sql/rev004/accountprocess/00_reset.sql`
- `sw-business/sw-business-server/src/test/resources/sql/rev004/accountprocess/02_latefee_formal_tables.sql`
- `sw-business/sw-business-server/src/test/resources/sql/rev004/accountprocess/03_latefee_formal_reset.sql`
- `sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/service/accountingadjust/latefeereduce/LateFeeReduceFormalizationService.java`
- `sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/service/accountingadjust/AccountingAdjustQueryServiceImpl.java`
- `sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/service/charge/ChargeServiceImpl.java`
- `sw-business/sw-business-server/src/test/java/cn/com/emsoft/sw/business/integration/rev004/accountprocess/Rev004AccountProcessCanaryQueryIntegrationTest.java`
### 修复点
1. **真实库 SQL fixture 兼容性**
- 去掉 `00_reset.sql` 中会被 Spring `ScriptUtils` 误切分的 `DO $$ ... $$`
- 新增 `03_latefee_formal_reset.sql`,把 late-fee formal table 的清理独立出来
- `02_latefee_formal_tables.sql` 改为无 `DO $$` 的约束重建方式
2. **formal-table 查询兜底**
- 当 `AccountingAdjustQueryServiceImpl` 无法仅从 `biz_operat_log(_detail)` 聚合出 `LATE_FEE_REDUCE` 详情时,
改为继续从:
- `biz_latefee_reduce`
- `biz_latefee_reduce_detail`
回退构造详情对象
3. **request log 的 adjustmentNo 明细一致性**
- `ChargeServiceImpl#recordAccountingAdjustOperatLog(...)` 中,
`adjustmentNo` 改为以 `oldValue = null, newValue = adjustmentNo` 记入日志明细,
避免被“旧值=新值则跳过”逻辑误过滤
### 新鲜验证
#### 定向编译
```bash
mvn -pl sw-business/sw-business-server -DskipTests compile
```
结果:**PASS**
#### 定向单测
```bash
mvn -pl sw-business/sw-business-server \
-Dtest=AccountingAdjustQueryServiceImplTest,LateFeeReduceFormalizationServiceTest,AccountingAdjustActionServiceImplTest#approve_lateFeeReduceDateModeShouldReduceCurrentLateFeeAndUpdateFormalTable \
test
```
结果:**PASS8 tests, 0 fail, 0 error**
#### 真实数据库 canary
```bash
REV004_IT_DB_URL=jdbc:postgresql://192.168.10.130:5436/sw_system \
REV004_IT_DB_USERNAME=sw_system \
REV004_IT_DB_PASSWORD='Em@123456' \
mvn -pl sw-business/sw-business-server clean \
-Dtest=Rev004AccountProcessCanaryQueryIntegrationTest#unsoldLateFeeReduceDateModeApprove_shouldPersistFormalTableSummary \
test
```
结果:**PASS**
### canary 覆盖到的链路
- 未销违约金减免(按日期)提交
- request log 写入 `adjustmentNo`
- `biz_latefee_reduce` / `biz_latefee_reduce_detail` 申请态落单
- 审批通过
- formal table 主表 / 明细表更新为成功态
### 当前结论更新
REV004 late-fee date-mode 这条最小闭环已从:
- **代码与单测通过**
推进到:
- **真实库 canary 通过**
当前剩余风险已不再是“缺表阻塞”,而是后续是否要把更多对象(坏账 / 核销 / 价差)也迁移到 formal-table 路线。

View File

@ -0,0 +1,171 @@
# REV004 自动化回归脚本 + legacy fallback 缩减2026-04-17
## 本轮目标
1. 为 REV004 建立可重复执行的自动化回归脚本入口。
2. 继续缩小 accountProcess 对 legacy fallback 的直接依赖面。
## 后端代码变更
### 1. 新增回归脚本目录
后端新增:`script/rev004-regression/`
- `env.sh`
- `01_prepare_env.sh`
- `02_unit_regression.sh`
- `03_live_db_smoke.sh`
- `04_summary.sh`
- `run_all.sh`
说明:
- unit 回归默认覆盖:`AccountingAdjustQueryServiceImplTest``AccountingAdjustProcessServiceImplTest``AccountingAdjustActionServiceImplTest``ChargeServiceAccountingAdjustTest``PrestorageFormalizationServiceTest`
- live DB smoke 默认覆盖:
- `Rev004AccountProcessLiveDbReadinessTest`
- `Rev004AccountProcessCanaryQueryIntegrationTest`
- `prestoragePage_shouldReturnSuccessEnvelope`
- `prestorageSubmit_shouldChangeBalanceAndWriteOperatLog`
- `prestorageRevoke_shouldRestoreBalanceAndWriteRevokeLog`
- `prestorageSubmit_thenProcessAndAttachmentsShouldExposeReturnedAdjustmentNo`
### 2. 缩减 legacy fallback 使用面
#### `AccountingAdjustProcessServiceImpl`
- `getProcess(...)`:调整为
- prestorage formal 优先
- unified snapshot 次优先
- synthetic snapshot 仅在 unified 缺失时兜底
- `getAttachments(...)`:调整为
- prestorage formal 优先
- unified snapshot 次优先
- synthetic snapshot 仅在 unified 缺失时兜底
#### `AccountingAdjustQueryServiceImpl`
- page 聚合时,先汇总 formal adjustmentNo 集合
- legacy request log 转换出的 request record 若 adjustmentNo 已被 formal 记录覆盖,则不再进入 merged 集合
- 保留 legacy log 的审计/兜底职责,但不再重复参与 formal 已覆盖对象的主结果聚合
## 新增/更新测试
### 单测补强
- `AccountingAdjustProcessServiceImplTest`
- `getProcess_shouldPreferUnifiedSnapshotOverSyntheticFallback`
- `getAttachments_shouldPreferUnifiedSnapshotOverSyntheticFallback`
- `AccountingAdjustQueryServiceImplTest`
- `getAccountingAdjustPage_shouldSkipLegacyRequestRecordWhenFormalRecordExists`
## 验证结果
### 1. unit 回归
执行:
```bash
script/rev004-regression/02_unit_regression.sh
```
结果:
- `Tests run: 68, Failures: 0, Errors: 0, Skipped: 0`
- `BUILD SUCCESS`
### 2. live DB smoke
执行:
```bash
script/rev004-regression/03_live_db_smoke.sh
```
结果:
- `Tests run: 5, Failures: 0, Errors: 0, Skipped: 0`
- `BUILD SUCCESS`
### 3. 一键入口
执行:
```bash
script/rev004-regression/run_all.sh
```
结果:
- unit + live DB smoke 均通过
- 日志目录:
- `.omx/logs/rev004-regression/20260417T110151Z`
## 当前边界
- 当前 live DB smoke 默认仍以 prestorage 稳定链路为主,用来验证真实数据库 + Spring + MockMvc + formal/legacy 协同路径。
- writtenoff / price diff / redink / bad debt 在本轮主要由 targeted unit regression 覆盖;后续可继续补到 live DB fixture。
- `Rev004AccountProcessCanaryQueryIntegrationTest` 中仍有其它更大范围场景未纳入默认 smoke 入口,本轮没有把它们全部收进默认脚本,以避免把未收敛场景误当作回归主入口。
## 结论
本轮已完成:
- REV004 自动化回归脚本首版落地
- 一键执行入口可用
- process / attachments 的 legacy fallback 优先级继续收口
- page 聚合中的 duplicate legacy request 参与面继续缩小
## 追加收口(继续删 fallback
### Query 层进一步收口
- `AccountingAdjustQueryServiceImpl#getAccountingAdjustPage(...)`
- `loadLatestActionMap(...)` 改为只对 legacy request records 构建 action overlay
- formal 记录即使 chargeId 下存在 legacy approval log也不再被 legacy 审批轨迹回填覆盖主状态
### 新增回归测试
- `getAccountingAdjustPage_shouldNotLetLegacyApprovalOverrideFormalRecord`
- 验证formal 已存在时legacy approval log 不再覆盖 formal 的 `approvalStatus/resultStatus/writeBackStatus/message/actionAmount`
### 本次追加验证
执行:
```bash
mvn -pl sw-business/sw-business-server -Dtest=AccountingAdjustQueryServiceImplTest,AccountingAdjustProcessServiceImplTest test
```
结果:
- `Tests run: 32, Failures: 0, Errors: 0, Skipped: 0`
- `BUILD SUCCESS`
### 统计口径锁定
新增测试:
- `getAccountingAdjustStat_shouldIgnoreLegacyApprovalForFormalRecord`
验证:
- formal record 已存在时legacy approval/action 不再把统计口径从 `PENDING_APPROVAL` 误改成 `APPROVED`
- `totalActionAmount` 仍取 formal 金额
执行:
```bash
mvn -pl sw-business/sw-business-server -Dtest=AccountingAdjustQueryServiceImplTest test
```
结果:
- `Tests run: 13, Failures: 0, Errors: 0, Skipped: 0`
- `BUILD SUCCESS`
再次执行:
```bash
script/rev004-regression/run_all.sh
```
结果:
- unit`Tests run: 69, Failures: 0, Errors: 0, Skipped: 0`
- live smoke`Tests run: 5, Failures: 0, Errors: 0, Skipped: 0`
- `BUILD SUCCESS`
### 日志查询口径锁定
新增测试:
- `getAccountingAdjustLogs_shouldReturnSyntheticFormalLogWhenLegacyLogsMissing`
验证:
- formal 对象即使没有 legacy operat_log也能通过 `getAccountingAdjustLogs` 返回一条 synthetic formal log
- 前端日志页不再被 legacy log 是否存在所卡死
执行:
```bash
mvn -pl sw-business/sw-business-server -Dtest=AccountingAdjustQueryServiceImplTest test
```
结果:
- `Tests run: 14, Failures: 0, Errors: 0, Skipped: 0`
- `BUILD SUCCESS`
### action-only 日志补齐
新增测试:
- `getAccountingAdjustLogs_shouldPrependSyntheticFormalLogWhenOnlyActionLogExists`
验证:
- formal 对象若只有 legacy action log、没有 legacy request log
- 日志列表会自动在前面补一条 synthetic formal log再保留 legacy action log
- 前端日志时间线可同时看到 formal 主记录和 legacy 审批动作
执行:
```bash
mvn -pl sw-business/sw-business-server -Dtest=AccountingAdjustQueryServiceImplTest test
```
结果:
- `Tests run: 15, Failures: 0, Errors: 0, Skipped: 0`
- `BUILD SUCCESS`

View File

@ -0,0 +1,109 @@
# REV004 bad-debt formal-table 已应用到 application-dev 测试库2026-04-17
## 目标库
依据:
- `sw-business/sw-business-server/src/main/resources/application-dev.yaml`
解析结果:
- Host`192.168.10.130`
- Port`5436`
- DB`sw_system`
- User`sw_system`
## 已执行脚本
- `sql/rev004/REV004_bad_debt_formal_tables_deploy.sql`
## DDL 执行结果
结果:**PASS**
已确认存在:
- `biz_bad_debt_adjust`
- `biz_bad_debt_adjust_detail`
- `biz_bad_debt_adjust_seq`
- `biz_bad_debt_adjust_detail_seq`
已确认幂等重放通过:
- second apply 输出 `already exists, skipping`
- 无重复约束/重复索引异常
## 代码验证
### compile
```bash
mvn -pl sw-business/sw-business-server -DskipTests compile
```
结果:**PASS**
### targeted tests
```bash
mvn -pl sw-business/sw-business-server \
-Dtest=ChargeServiceAccountingAdjustTest,AccountingAdjustActionServiceImplTest,AccountingAdjustProcessServiceImplTest,AccountingAdjustQueryServiceImplTest,BadDebtFormalizationServiceTest test
```
结果:**PASS**
- Tests run: 55
- Failures: 0
- Errors: 0
## HTTP smokefresh jar, port 48092
### submit
- `unsold-bad-debt-submit` on charge `991005``REV004-991005-20260417121621`
- `unsold-bad-debt-submit` on charge `991006``REV004-991006-20260417121622`
- 返回统一为:
- `objectType = BAD_DEBT_RECORD`
- `approvalStatus = PENDING_APPROVAL`
- `resultStatus = PENDING_APPROVAL`
- `writeBackStatus = PENDING`
### DB 回读
`biz_bad_debt_adjust`
- approve 样例:`APPROVED|UPDATED|SUCCESS|approve smoke`
- reject 样例:`REJECTED|SKIPPED|FAIL|reject smoke`
`biz_bad_debt_adjust_detail`
- submit 后 detail 进入 `PENDING_APPROVAL`
- 审批通过后 detail 进入 `SUCCESS`
- 审批驳回后 detail 进入 `REJECTED`
### query
- `GET /admin-api/business/accounting-adjust/get?adjustmentNo=...` 对 bad debt 已返回 formal detail
- `GET /admin-api/business/accounting-adjust/page?...objectType=BAD_DEBT_RECORD` 已返回 formal-first 列表
- `GET /admin-api/business/accounting-adjust/logs?adjustmentNo=...` 仍通过 legacy operat_log 返回完整轨迹
### approve / reject
- approve`/admin-api/business/accounting-adjust/approve`
- 返回 `APPROVED/SUCCESS/UPDATED`
- 账单 `pay_state` 被回写为 `UNCOLLECTIBLE(-2)`
- reject`/admin-api/business/accounting-adjust/reject`
- 返回 `REJECTED/FAIL/SKIPPED`
- 账单状态保持原值,不执行坏账回写
## 当前结论
本轮坏账 formal-table 已达到:
1. DDL 可落库且可幂等重放;
2. submit pending formal record 可落表;
3. approve/reject 会同步 formal main/detail 状态;
4. detail/page 对 `BAD_DEBT_RECORD` 已能返回 formal-first 结果;
5. 日志链路继续保留兼容查询。
## 当前未完成
- `AccountingAdjustQueryServiceImpl` 目前对坏账 formal-first 仅覆盖 detail/page 主路径,后续仍可继续补 stats/更细颗粒 read-model 一致性;
- 本轮 smoke 数据尚未清理,需要在最终收口时删除临时 `991005/991006` 相关客户、账单、formal 记录与日志。
## 测试数据清理
HTTP smoke 完成后,已删除临时 bad-debt smoke 数据:
- `biz_operat_log / detail`identify_value = `991005`, `991006`
- `biz_bad_debt_adjust / detail`
- `biz_charge``991005`, `991006`
- `biz_cust``REV004_BD_SMOKE_A`, `REV004_BD_SMOKE_B`
回读结果:
- `baddebt_main_left=0`
- `operat_log_left=0`
- `charge_left=0`
- `cust_left=0`
## 运行态清理
用于 fresh-jar HTTP smoke 的临时实例:
- port `48092`
已停止,当前无残留 LISTEN 进程。

View File

@ -0,0 +1,87 @@
# REV004 late-fee formal-table 真实库阻塞说明2026-04-15
> 状态更新:**该阻塞已于 2026-04-15 当天解除,本文保留为阻塞发生记录。**
## 结论
当前 late-fee reduce 代码侧与定向单测已通过,但真实数据库集成验证被环境缺表阻塞,阻塞点不是代码逻辑,而是目标库未部署 formal-table。
## 已通过的验证
### 编译
```bash
rm -rf sw-business/sw-business-server/target/generated-sources \
sw-business/sw-business-server/target/generated-test-sources
mkdir -p sw-business/sw-business-server/target/generated-sources/annotations
mvn -pl sw-business/sw-business-server -DskipTests compile
```
结果:**PASS**
### 定向测试
```bash
mvn -pl sw-business/sw-business-server \
-Dtest=AccountingAdjustActionServiceImplTest#approve_lateFeeReduceShouldOnlyUpdateLateFee+approve_lateFeeReduceDateModeShouldReduceCurrentLateFeeAndUpdateFormalTable,LateFeeReduceFormalizationServiceTest,AccountingAdjustQueryServiceImplTest,AccountingAdjustLogProcessServiceImplTest,AccountingAdjustProcessServiceImplTest#createUnsoldLateFeeReduce_shouldPassDateModeFieldsToUnifiedChargeService+createUnsoldLateFeeReduce_shouldRejectMixedAmountAndDateMode+batchCreateUnsoldLateFeeReduce_shouldMergeBatchOuterFieldsIntoItems+getProcess_shouldExposeLateFeeDisplayFieldsFromUnifiedChargeService,AccountingAdjustSemanticMapperTest,AccountingAdjustDictResolverTest,AccountingAdjustStatusResolverTest \
test
```
结果:**PASS24 tests, 0 fail, 0 error**
## 真实 DB 阻塞验证
### 执行命令
```bash
REV004_IT_DB_URL=jdbc:postgresql://192.168.10.130:5436/sw_system \
REV004_IT_DB_USERNAME=sw_system \
REV004_IT_DB_PASSWORD='Em@123456' \
mvn -pl sw-business/sw-business-server \
-Dtest=Rev004AccountProcessCanaryQueryIntegrationTest#unsoldLateFeeReduceDateModeApprove_shouldPersistFormalTableSummary \
test
```
### 失败原因
报错核心:
- `relation "biz_latefee_reduce_detail" does not exist`
在测试前置 / 后置 SQL `sql/rev004/accountprocess/00_reset.sql` 中,已经尝试执行:
- `DELETE FROM biz_latefee_reduce_detail ...`
- `DELETE FROM biz_latefee_reduce ...`
这说明:
- 代码侧已经按 formal-table 路径推进
- 测试脚本也已经按 formal-table 假设编写
- 但真实库中尚未存在这些表
## 当前判断
1. 代码逻辑不是当前 blocker。
2. 真实 DB 环境未部署 `biz_latefee_reduce` / `biz_latefee_reduce_detail` 是当前 canary 唯一主要阻塞。
3. 在部署 formal-table 之前,真实库层面的 late-fee canary 无法拉绿。
## 建议下一步
1. 先确认真实库是否允许部署:
- `biz_latefee_reduce`
- `biz_latefee_reduce_detail`
2. 若允许部署,再重跑 canary。
3. 若暂不允许部署,则当前阶段只能以 compile + unit/integration mock/local 证据为主,明确标注“真实库阻塞未消除”。
---
## 后续结果回写(阻塞已解除)
### 已完成动作
1. 补充并执行 `sql/rev004/REV004_latefee_formal_tables_deploy.sql`
2. 修复测试 SQL fixture
- `00_reset.sql`
- `02_latefee_formal_tables.sql`
- `03_latefee_formal_reset.sql`
3. 补充 late-fee formal-table 查询兜底与 request log `adjustmentNo` 明细一致性
### 解除阻塞后的真实库验证
```bash
REV004_IT_DB_URL=jdbc:postgresql://192.168.10.130:5436/sw_system \
REV004_IT_DB_USERNAME=sw_system \
REV004_IT_DB_PASSWORD='Em@123456' \
mvn -pl sw-business/sw-business-server clean \
-Dtest=Rev004AccountProcessCanaryQueryIntegrationTest#unsoldLateFeeReduceDateModeApprove_shouldPersistFormalTableSummary \
test
```
结果:**PASS**
### 更新后的结论
- `biz_latefee_reduce` / `biz_latefee_reduce_detail` 缺表阻塞已消除
- REV004 late-fee date-mode 最小真实库闭环已验证通过
- 本文档现仅作为“阻塞曾发生过”的历史记录,不再代表当前状态

View File

@ -0,0 +1,73 @@
# REV004 late-fee formal table 已应用到 application-dev 测试库2026-04-15
## 目标库
依据:
- `sw-business/sw-business-server/src/main/resources/application-dev.yaml`
解析结果:
- Host`192.168.10.130`
- Port`5436`
- DB`sw_system`
- User`sw_system`
即当前 `application-dev` 指向的测试数据库为:
`jdbc:postgresql://192.168.10.130:5436/sw_system`
## 已执行脚本
- `sql/rev004/REV004_latefee_formal_tables_deploy.sql`
执行命令:
```bash
PGPASSWORD='Em@123456' \
psql -h 192.168.10.130 -p 5436 -U sw_system -d sw_system \
-v ON_ERROR_STOP=1 \
-f sql/rev004/REV004_latefee_formal_tables_deploy.sql
```
## 执行结果
结果:**PASS**
执行输出显示:
- sequence 已存在时跳过
- table 已存在时跳过
- 索引继续补齐/确认
- 外键创建逻辑执行成功
说明该脚本已成功应用到测试库,且具备幂等重放能力。
## 回读校验
### 表
已确认存在:
- `biz_latefee_reduce`
- `biz_latefee_reduce_detail`
### 序列
已确认存在:
- `biz_latefee_reduce_seq`
- `biz_latefee_reduce_detail_seq`
### 索引
已确认存在:
- `uk_biz_latefee_reduce_no`
- `idx_biz_latefee_reduce_case`
- `idx_biz_latefee_reduce_status`
- `idx_biz_latefee_reduce_type`
- `idx_biz_latefee_reduce_detail_main`
- `idx_biz_latefee_reduce_detail_charge`
- `idx_biz_latefee_reduce_detail_cust`
- `idx_biz_latefee_reduce_detail_bill_month`
### 外键
已确认存在:
- `fk_biz_latefee_reduce_detail_main`
- `biz_latefee_reduce_detail(latefee_reduce_id) -> biz_latefee_reduce(id)`
## 当前结论
`application-dev` 指向的测试数据库现在已经具备 REV004 late-fee formal-table 结构,可直接用于:
1. 未销违约金减免申请态落单
2. 审批态 formal-table 更新
3. accountProcess 真实库 canary / 联调验证
## 建议后续
1. 继续保留 `REV004_latefee_formal_tables_deploy.sql` 作为测试库 / 联调库初始化脚本
2. 若后续坏账 / 核销 / 价差也迁移 formal-table应沿用相同“独立 deploy SQL + 回读校验”的方式推进

View File

@ -0,0 +1,237 @@
# REV004 prestorage formal-table 已应用到 application-dev 测试库2026-04-16
## 目标库
依据:
- `sw-business/sw-business-server/src/main/resources/application-dev.yaml`
解析结果:
- Host`192.168.10.130`
- Port`5436`
- DB`sw_system`
- User`sw_system`
即当前 `application-dev` 指向的测试数据库为:
`jdbc:postgresql://192.168.10.130:5436/sw_system`
## 已执行脚本
- `sql/rev004/REV004_prestorage_formal_tables_deploy.sql`
执行命令:
```bash
PGPASSWORD='Em@123456' \
psql -h 192.168.10.130 -p 5436 -U sw_system -d sw_system \
-v ON_ERROR_STOP=1 \
-f sql/rev004/REV004_prestorage_formal_tables_deploy.sql
```
## 执行结果
结果:**PASS**
执行输出显示:
- `biz_prestorage_adjust_seq` 创建成功
- `biz_prestorage_adjust_detail_seq` 创建成功
- `biz_prestorage_adjust` 创建成功
- `biz_prestorage_adjust_detail` 创建成功
- 主表索引、明细表索引创建成功
- 外键 `fk_biz_prestorage_adjust_detail_main` 创建成功
## 回读校验
### 表
已确认存在:
- `biz_prestorage_adjust`
- `biz_prestorage_adjust_detail`
### 序列
已确认存在:
- `biz_prestorage_adjust_seq`
- `biz_prestorage_adjust_detail_seq`
### 关键索引
已确认存在:
- `uk_biz_prestorage_adjust_no`
- `idx_biz_prestorage_adjust_source`
- `idx_biz_prestorage_adjust_target`
- `idx_biz_prestorage_adjust_type`
- `idx_biz_prestorage_adjust_status`
- `idx_biz_prestorage_adjust_executed_at`
- `idx_biz_prestorage_adjust_detail_main`
- `idx_biz_prestorage_adjust_detail_type`
- `idx_biz_prestorage_adjust_detail_charge`
- `idx_biz_prestorage_adjust_detail_bill_month`
### 外键
已确认存在:
- `fk_biz_prestorage_adjust_detail_main`
- `biz_prestorage_adjust_detail(prestorage_adjust_id) -> biz_prestorage_adjust(id)`
## Smoke 验证
### 1. 代码层最小验证
执行:
```bash
mvn -pl sw-business/sw-business-server -DskipTests compile
mvn -pl sw-business/sw-business-server -Dtest=AccountingAdjustProcessServiceImplTest,AccountingAdjustPrestorageProcessServiceImplTest test
```
结果:**PASS**
说明:
- prestorage submit / revoke 接线后的 Java 编译通过
- `AccountingAdjustProcessServiceImplTest` 通过13/13
- `AccountingAdjustPrestorageProcessServiceImplTest` 通过4/4
- 合计目标测试:`17/17` 通过
### 2. 数据库 transactional smoke
执行:在测试库开启事务后,插入一笔 `biz_prestorage_adjust` 主表记录 + 一笔 `biz_prestorage_adjust_detail` 明细记录,随后回读计数,再 `ROLLBACK`
验证点:
- 主表可写
- 明细表可写
- 外键约束正常
- 回读可见
- 回滚后不污染测试库
实际结果:
- `main_count=1`
- `detail_count=1`
- 回滚后再次检查 `adjustment_no='SMOKE-REV004-PRE-001'` 计数为 `0`
结果:**PASS**
## 当前结论
`application-dev` 指向的测试数据库现在已经具备 REV004 prestorage formal-table 结构,可直接用于:
1. 预存退款 / 预存转账 formal-table 双写
2. prestorage page/detail/stat formal-table 优先投影联调
3. 后续真实接口 smoke / canary 验证
## 真实 HTTP smoke补充于 2026-04-16 18:00 +08:00
为了避免命中本地旧 jar 进程,额外完成了以下动作:
1. 使用最新代码重新执行 `mvn -pl sw-business/sw-business-server -DskipTests package`
2. 以 `java -jar ... --server.port=48091` 启动一份隔离的新实例
3. 通过 `login-user` 头模拟管理员上下文,直连 `/admin-api/business/accounting-adjust/*` 接口做 smoke
### smoke 前置数据
向测试库临时插入:
- 源客户:`REV004_PRE_SMOKE_SRC`
- 目标客户:`REV004_PRE_SMOKE_TGT`
- 源账户余额:`100.00`
- 目标账户余额:`5.00`
### 1. prestorage-submitrefund
请求成功,返回:
- `adjustmentNo = REV004-PRF-990001-20260416180029`
- `resultStatus = SUCCESS`
DB 回读确认:
- `biz_prestorage_adjust` 新增 1 条 `REFUND`
- `biz_prestorage_adjust_detail` 新增 1 条 `REFUND_RESULT`
- 源账户余额由 `100.00 -> 90.00`
### 2. prestorage-submittransfer
请求成功,返回:
- `adjustmentNo = REV004-PTR-990001-20260416180029`
- `resultStatus = SUCCESS`
DB 回读确认:
- `biz_prestorage_adjust` 新增 1 条 `TRANSFER`
- `biz_prestorage_adjust_detail` 新增 2 条:
- `SOURCE_ACCOUNT`
- `TARGET_ACCOUNT`
- 源账户余额由 `90.00 -> 70.00`
- 目标账户余额由 `5.00 -> 25.00`
### 3. prestorage-page / prestorage-detail
在 48091 新实例上验证:
- `prestorage-page` 返回 2 条 smoke 数据
- `prestorage-detail?id=3` 可正常返回 transfer formal 详情
- transfer 记录状态为:
- `workOrderStatus = 2`
- `resultStatus = SUCCESS`
- `writeBackStatus = UPDATED`
### 4. prestorage-process / prestorage-attachments
在 48091 新实例上验证:
- `prestorage-process?adjustmentNo=REV004-PTR-990001-20260416180029` 返回成功
- `prestorage-attachments?...` 返回空数组 `[]`
说明:
- 当前 `process/attachments` 仍主要经 unified/legacy 查询口径返回,但因为 submit 继续写 `operat_log`,链路可正常工作
- 这两条在本轮已不构成阻塞性故障
### 5. prestorage-revoke
调用:
- `prestorage-revoke adjustmentNo=REV004-PTR-990001-20260416180029`
返回:
- `message = 预存转账撤销成功`
- `resultStatus = SUCCESS`
DB 回读确认:
- `biz_prestorage_adjust` 中该 transfer 主记录状态变为:
- `result_status = REVOKED`
- `execute_status = REVOKED`
- 对应 detail 状态均变为:
- `detail_status = REVOKED`
- `proc_type = REVOKE`
- 账户余额恢复为:
- 源账户 `90.00`
- 目标账户 `5.00`
- `prestorage-page` 再查可见该 transfer 记录:
- `workOrderStatus = 3`
- `canRevoke = false`
## 测试数据清理
为避免污染测试库smoke 完成后已执行清理:
- 删除临时 `biz_operat_log / detail`
- 删除临时 `biz_prestorage_adjust / detail`
- 删除临时 `biz_account`
- 删除临时 `biz_cust`
回读结果:
- `formal_main_left = 0`
- `operat_log_left = 0`
- `cust_left = 0`
## 当前仍未完全覆盖的点
1. 本轮已经证明 HTTP submit/query/revoke 主链路可工作;
2. 但 `prestorage-process / prestorage-attachments` 目前仍不是 strict formal-first而是依赖 unified/legacy 口径兜底;
3. 如果后续目标是“彻底以 formal-table 为唯一真值”,还需要继续收口这两条查询路径。
## 建议后续
1. backend PR 可以先按 prestorage formal-table 独立批次提交;
2. PR 描述中明确:
- `process/attachments` 当前可用,但仍保留 legacy/unified 查询兜底;
- 后续可再开一批做 strict formal-first 收口;
3. 保留 `REV004_prestorage_formal_tables_deploy.sql` 作为测试库 / 联调库初始化脚本。
## 补充复核2026-04-16 17:36 +08:00
### 1. 部署脚本幂等重放
再次执行:
```bash
PGPASSWORD='Em@123456' psql -h 192.168.10.130 -p 5436 -U sw_system -d sw_system -v ON_ERROR_STOP=1 -f sql/rev004/REV004_prestorage_formal_tables_deploy.sql
```
结果:**PASS**
关键输出:
- existing sequence/table/index 均以 `already exists, skipping` 形式跳过
- 没有出现失败或约束重复异常
说明:
- `REV004_prestorage_formal_tables_deploy.sql` 具备测试库重放幂等性
- 适合作为联调库/测试库初始化脚本继续使用
### 2. 本地服务存活验证
执行:
```bash
curl -sS http://127.0.0.1:48090/actuator/health
```
返回:
```json
{"status":"UP"}
```
说明:
- 当前本地 `sw-business-server` 进程存活
- 后续若补真实 HTTP 接口 smoke可直接基于该运行实例继续

View File

@ -0,0 +1,94 @@
# REV004 prestorage process/attachments strict formal-first2026-04-17
## 目标
收口:
- `GET /admin-api/business/accounting-adjust/prestorage-process`
- `GET /admin-api/business/accounting-adjust/prestorage-attachments`
使其优先读取 prestorage formal-table而不是继续主要依赖 legacy/unified fallback。
## 代码变更
核心变更位于:
- `AccountingAdjustProcessServiceImpl`
- `AccountingAdjustProcessServiceImplTest`
策略:
1. `getProcess(adjustmentNo)` 先尝试 `PrestorageFormalizationService.getView(adjustmentNo)`
2. 命中 formal view 时,直接组装 `AccountingAdjustProcessRespVO`
3. `getAttachments(adjustmentNo)` 先尝试读取 formal `attachmentRefs`
4. 仅在 formal 不存在时才回退到 synthetic / unified 口径
## 验证
### compile
```bash
mvn -pl sw-business/sw-business-server -DskipTests compile
```
结果:**PASS**
### targeted tests
```bash
mvn -pl sw-business/sw-business-server -Dtest=AccountingAdjustProcessServiceImplTest,AccountingAdjustPrestorageProcessServiceImplTest test
```
结果:**PASS**
- Tests run: 23
- Failures: 0
- Errors: 0
## fresh jar smokeport 48098
### health
- `GET /actuator/health` -> `{"status":"UP"}`
### smoke 数据
手工 seed
- `adjustmentNo = REV004-PTR-993001-SEED`
- formal main`biz_prestorage_adjust`
- formal detail`biz_prestorage_adjust_detail`
- attachment refs`101,proof-raw`
### process
调用:
- `GET /admin-api/business/accounting-adjust/prestorage-process?adjustmentNo=REV004-PTR-993001-SEED`
结果:**PASS**
返回关键字段:
- `objectType = LEGACY_PRESTORAGE_TRANSFER`
- `adjustType = TRANSFER`
- `actionAmount = 20.0`
- `resultStatus = SUCCESS`
- `approvalStatus = NOT_REQUIRED`
- `writeBackStatus = UPDATED`
- `attachmentRefs = ["101", "proof-raw"]`
- `applicant = 王五`
- `contactMobile = 13700000000`
- `latestMessage = 预存转账成功,目标户号=C-993002`
说明process 已命中 formal main而不是再走 unified detail 兜底。
### attachments
调用:
- `GET /admin-api/business/accounting-adjust/prestorage-attachments?adjustmentNo=REV004-PTR-993001-SEED`
结果:**PASS**
返回:
- ref=`101` -> 数值 ID 解析,当前附件实体不存在,返回 `resolved=false, message=附件不存在`
- ref=`proof-raw` -> 非数值引用,返回 `resolved=false, message=附件引用不是数值ID保留原始引用`
说明attachments 已优先读取 formal `attachmentRefs`,并保留现有解析策略。
## 清理
已删除:
- `biz_prestorage_adjust / detail` seed 数据
回读结果:
- `prestorage_main_left=0`
- `prestorage_detail_left=0`
运行态:
- `48098` 已停止
## 当前结论
本轮 prestorage 剩余查询缺口已完成 strict formal-first 收口:
1. `prestorage-process` 优先命中 formal
2. `prestorage-attachments` 优先命中 formal attachment refs
3. formal 缺失时仍可继续 fallback
4. 主链路 schema / 写路径无变更

View File

@ -0,0 +1,135 @@
# REV004 price-diff formal-table 已应用到 application-dev 测试库2026-04-17
## 目标库
依据:
- `sw-business/sw-business-server/src/main/resources/application-dev.yaml`
解析结果:
- Host`192.168.10.130`
- Port`5436`
- DB`sw_system`
- User`sw_system`
## 已执行脚本
- `sql/rev004/REV004_price_diff_formal_tables_deploy.sql`
## DDL 执行结果
结果:**PASS**
已确认存在:
- `biz_price_diff_adjust`
- `biz_price_diff_adjust_detail`
- `biz_price_diff_adjust_seq`
- `biz_price_diff_adjust_detail_seq`
已确认幂等重放通过:
- second apply 输出 `already exists, skipping`
- 无重复约束/重复索引异常
## 代码验证
### compile
```bash
mvn -pl sw-business/sw-business-server -DskipTests compile
```
结果:**PASS**
说明:
- 先顺手修复 develop 基线 compile blocker
- `CustApiImpl.java` 去掉 `updateCustPriceTemplateCode` 上多余 `@Override`
- `CustServiceImpl.java` 去掉 `dept.getCode()` 调用
- 之后串行重跑 compile 成功
- 曾出现一次 `NoSuchFileException ... target/generated-sources/...`,确认为 compile 与 test 并行访问同一 `target/` 目录导致的竞态,不属于业务代码错误
### targeted tests
```bash
mvn -pl sw-business/sw-business-server -Dtest=AccountingAdjustActionServiceImplTest,AccountingAdjustProcessServiceImplTest,AccountingAdjustQueryServiceImplTest,PriceDiffFormalizationServiceTest test
```
结果:**PASS**
- Tests run: 43
- Failures: 0
- Errors: 0
## HTTP smokefresh jar, port 48095
### health
- `GET /actuator/health` -> `{"status":"UP"}`
### submit
- `unsold-price-diff-submit` on charge `992205` -> `REV004-992205-20260417153413`
- `unsold-price-diff-submit` on charge `992206` -> `REV004-992206-20260417153414`
- 返回统一为:
- `objectType = PRICE_DIFF_ADJUST`
- `approvalStatus = PENDING_APPROVAL`
- `resultStatus = PENDING_APPROVAL`
- `writeBackStatus = PENDING`
### get / page
- `GET /admin-api/business/accounting-adjust/get?adjustmentNo=REV004-992205-20260417153413`
- 可返回 formal detail
- `priceDiffAmount=15.50`
- `billAmountBefore=100.00`
- `billAmountAfter=115.50`
- `extendedAmountBefore=100.00`
- `extendedAmountAfter=115.50`
- `GET /admin-api/business/accounting-adjust/page?...objectType=PRICE_DIFF_ADJUST`
- 可返回 2 条 fresh smoke formal-first 记录
- `reasonCodeLabel` 已能解析为字典文本(如 `用户协商` / `定价错误`
### approve / reject
- approve`/admin-api/business/accounting-adjust/approve`
- 返回 `APPROVED / SUCCESS / UPDATED`
- reject`/admin-api/business/accounting-adjust/reject`
- 返回 `REJECTED / FAIL / SKIPPED`
## DB 回读
`biz_price_diff_adjust`
- `REV004-992205-20260417153413 -> APPROVED | UPDATED | SUCCESS`
- `REV004-992206-20260417153414 -> REJECTED | SKIPPED | FAIL`
`biz_price_diff_adjust_detail`
- approve 明细:`SUCCESS | APPROVE_EXECUTE | approve price diff smoke`
- reject 明细:`REJECTED | REJECT | reject price diff smoke`
- approve 样例金额前后值:
- `bill_amount_before=100.00 -> bill_amount_after=115.50`
- `extended_amount_before=100.00 -> extended_amount_after=115.50`
`biz_charge`
- `992205 -> bill_amount=115.5000, extended_amount=115.5000, original_money=115.5000`
- `992206 -> bill_amount=80.0000, extended_amount=80.0000, original_money=80.0000`
## 测试数据清理
smoke 完成后已删除:
- `biz_operat_log / detail`identify_value = `992205`, `992206`
- `biz_price_diff_adjust / detail`
- `biz_charge``992205`, `992206`
- `biz_cust``REV004_PD_SMOKE_A`, `REV004_PD_SMOKE_B`
回读结果:
- `pricediff_main_left=0`
- `pricediff_detail_left=0`
- `operat_log_left=0`
- `charge_left=0`
- `cust_left=0`
## 运行态清理
用于 fresh-jar HTTP smoke 的临时实例:
- port `48095`
已停止,当前无残留 LISTEN 进程。
## 当前结论
本轮 price-diff formal-table 已达到:
1. DDL 可落库且可幂等重放;
2. unsold price-diff submit 能落 pending formal main/detail
3. approve/reject 会同步 formal 状态;
4. detail/page 对 `PRICE_DIFF_ADJUST` 已能返回 formal-first 结果;
5. 账单回写与当前 `applyPriceDiffWriteBack(...)` 口径一致;
6. fresh smoke / cleanup 证据完整。
## 当前仍需收口
- 这批尚未提交 commit / PR
- 如果后续要更贴近原系统 `PM_PRICE_RECORDS / DETAILS` 语义,可继续补:
- `PriceListId`
- `PriceCode`
- `IsLadder`
- `NewFeeId`
- 更细颗粒的 old/new late fee 与账单差额字段来源收口。

View File

@ -0,0 +1,212 @@
# REV004 redink formal-table 已应用到 application-dev 测试库2026-04-17
## 目标库
依据:
- `sw-business/sw-business-server/src/main/resources/application-dev.yaml`
解析结果:
- Host`192.168.10.130`
- Port`5436`
- DB`sw_system`
- User`sw_system`
## 已执行脚本
- `sql/rev004/REV004_redink_formal_tables_deploy.sql`
## DDL 执行结果
结果:**PASS**
已确认存在:
- `biz_redink_record`
- `biz_redink_record_detail`
- `biz_redink_record_seq`
- `biz_redink_record_detail_seq`
已确认幂等重放通过:
- second apply 输出 existing/skip 结果
- 本轮顺手把 sequence 创建方式从 `CREATE SEQUENCE IF NOT EXISTS` 收口为显式 `pg_class` 检查,规避 replay 时 sequence 级重复键异常
## 代码验证
### compile
```bash
mvn -pl sw-business/sw-business-server -DskipTests compile
```
结果:**PASS**
### targeted tests
```bash
mvn -pl sw-business/sw-business-server -Dtest=ChargeServiceAccountingAdjustTest,AccountingAdjustQueryServiceImplTest,RedinkFormalizationServiceTest test
```
结果:**PASS**
- Tests run: 34
- Failures: 0
- Errors: 0
## fresh query smokefresh jar, port 48096
### health
- `GET /actuator/health` -> `{"status":"UP"}`
### smoke 方式说明
REDINK_RECORD 当前依赖原交易定位 / bank follow-up 逻辑;本轮先采用:
1. application-dev 手工 seed 一条 redink formal 主表/明细表记录;
2. fresh jar 验证 `get/page` 是否已 formal-first 命中;
3. 不在本轮直接伪造 live bank follow-up 交易。
### seed 记录
- `adjustmentNo = REV004-RI-992305-SEED`
- `chargeId = 992305`
- formal 主表状态:
- `approvalStatus = NOT_REQUIRED`
- `executeStatus = UPDATED`
- `resultStatus = SUCCESS`
- bank follow-up 样例:`BK-992305`
### get / page
- `GET /admin-api/business/accounting-adjust/get?adjustmentNo=REV004-RI-992305-SEED`
- 返回:
- `objectType = REDINK_RECORD`
- `resultStatus = SUCCESS`
- `approvalStatus = NOT_REQUIRED`
- `writeBackStatus = UPDATED`
- `originalTranSeq = T-992305`
- `originalSysTranSeq = SYS-992305`
- detail 中包含:
- `bankTranSeq`
- `redinkAmount`
- `payStateBefore`
- `payStateAfter`
- `GET /admin-api/business/accounting-adjust/page?...objectType=REDINK_RECORD`
- 返回 1 条 formal-first 记录
- `reasonCodeLabel` 已能解析为字典文本(如 `收费错误`
## 当前结论
本轮 redink formal-table 已达到:
1. DDL 可落库且可幂等重放;
2. 结果型 formal-table 主从表已建模;
3. query detail/page 对 `REDINK_RECORD` 已能返回 formal-first
4. compile / targeted tests 通过;
5. fresh jar query smoke 已验证 formal-first 查询链路可用。
## 当前仍未完全覆盖
- 尚未完成“真实 redink 执行成功后自动落 formal 结果”的 live HTTP smoke
- 原因是当前红冲依赖原交易与 bank follow-up 外部链路,需要在下一轮补真实可复现数据后再做完整 execute smoke。
## 测试数据清理
已删除:
- `biz_redink_record / detail`
- `biz_charge`
- `biz_cust`
回读结果:
- `redink_main_left=0`
- `redink_detail_left=0`
- `charge_left=0`
- `cust_left=0`
## 运行态清理
用于 fresh-jar query smoke 的临时实例:
- port `48096`
已停止,当前无残留 LISTEN 进程。
## live execute smoke 阻塞证据2026-04-17 16:50 +08:00
本轮额外尝试了真实 redink 执行链路:
- fresh jar`48097`
- 请求:`POST /admin-api/business/charge/accounting-adjust`
- `objectType = REDINK_RECORD`
- `chargeId = 992306`
- `originalTranSeq = T-REDINK-NOPE`
接口响应:
```json
{"code":500,"data":null,"msg":"系统异常"}
```
从应用日志定位到的精确异常:
- `FeignException$ServiceUnavailable: [503]`
- `Load balancer does not contain an instance for the service business-bank-server`
- 失败位置:`TransactionApi#getTransactionByTranSeq(...)`
结论:
- 当前 live execute smoke 未能完成的直接原因是 **外部依赖 `business-bank-server` 在当前环境无可用实例**
- 这不是 redink formal-table 本身的 DDL / 查询接线问题。
因此本批已完成:
- compile
- targeted tests
- DDL apply / replay
- fresh query smoke
但“真实 redink 执行成功后自动落 formal”的端到端 smoke 仍需在 `business-bank-server` 可用时补跑。
## live execute smoke 成功补证2026-04-17 17:51 +08:00
在本轮额外启动本地 `business-bank-server`dev profile, port `48092`)并向测试库预置原交易后,重新完成了 REDINK_RECORD 的真实端到端执行 smoke。
### 前置
- 本地启动 `business-bank-server`,并成功注册到 Nacos dev`business-bank-server 192.168.9.109:48092 register finished`
- 向 `bk_transaction` seed 原交易:
- `tran_seq = T-REDINK-NOPE`
- `sys_tran_seq = SYS-REDINK-NOPE`
- `tran_type = PAY`
- `status = SUCCESS`
- `contract_no = 992306`
- `amount = 12000`
- 准备已收费营业账:`chargeId = 992306`
### execute 请求
`POST /admin-api/business/charge/accounting-adjust`
```json
{
"chargeId": 992306,
"objectType": "REDINK_RECORD",
"reasonCode": "1",
"reason": "redink execute smoke",
"originalTranSeq": "T-REDINK-NOPE"
}
```
### execute 响应
结果:**PASS**
返回:
- `adjustmentNo = REV004-992306-20260417175109`
- `objectType = REDINK_RECORD`
- `resultStatus = SUCCESS`
- `approvalStatus = NOT_REQUIRED`
- `writeBackStatus = UPDATED`
- `message = 冲正处理成功bank流水号=RV9923062026041717511073C805`
### DB 回读
`biz_redink_record`
- `adjustment_no = REV004-992306-20260417175109`
- `approval_status = NOT_REQUIRED`
- `execute_status = UPDATED`
- `result_status = SUCCESS`
- `bank_tran_seq = RV9923062026041717511073C805`
- `original_tran_seq = T-REDINK-NOPE`
`biz_redink_record_detail`
- `detail_status = SUCCESS`
- `proc_type = EXECUTE`
- `pay_state_before = 1`
- `pay_state_after = 0`
- `redink_amount = 120.00`
`biz_charge`
- `pay_state = 0`
- 支付信息已清空为红冲后的未收费态
`bk_transaction`
- 原交易 `T-REDINK-NOPE` 状态变为 `REVERSED`
- 新增 follow-up
- `tran_seq = RV9923062026041717511073C805`
- `tran_type = PAY_INVALID`
- `status = SUCCESS`
- `original_tran_seq = T-REDINK-NOPE`
### 查询回读
- `GET /admin-api/business/accounting-adjust/get?adjustmentNo=REV004-992306-20260417175109` -> formal-first 返回成功
- `GET /admin-api/business/accounting-adjust/page?...objectType=REDINK_RECORD` -> formal-first 返回成功
说明至此REDINK_RECORD 已补齐“真实执行 -> 自动落 formal -> formal-first 查询”的完整闭环证据。

View File

@ -0,0 +1,142 @@
# REV004 writtenoff formal-table 已应用到 application-dev 测试库2026-04-17
## 目标库
依据:
- `sw-business/sw-business-server/src/main/resources/application-dev.yaml`
解析结果:
- Host`192.168.10.130`
- Port`5436`
- DB`sw_system`
- User`sw_system`
## 已执行脚本
- `sql/rev004/REV004_writtenoff_formal_tables_deploy.sql`
## DDL 执行结果
结果:**PASS**
已确认存在:
- `biz_writtenoff_adjust`
- `biz_writtenoff_adjust_detail`
- `biz_writtenoff_adjust_seq`
- `biz_writtenoff_adjust_detail_seq`
已确认幂等重放通过:
- second apply 输出 `already exists, skipping`
- 无重复约束/重复索引异常
## 代码验证
### compile
```bash
mvn -pl sw-business/sw-business-server -DskipTests compile
```
结果:**PASS**
### targeted tests
```bash
mvn -pl sw-business/sw-business-server \
-Dtest=AccountingAdjustSoldProcessServiceImplTest,AccountingAdjustActionServiceImplTest,AccountingAdjustProcessServiceImplTest,AccountingAdjustQueryServiceImplTest,WrittenoffFormalizationServiceTest test
```
结果:**PASS**
- Tests run: 41
- Failures: 0
- Errors: 0
## HTTP smokefresh jar, port 48093
### submit
- `sold-submit` on charge `992005``REV004-SLD-992005-20260417143622`
- `sold-submit` on charge `992006``REV004-SLD-992006-20260417143623`
- 返回统一为:
- `objectType = WRITTENOFF_ADJUST`
- `approvalStatus = PENDING_APPROVAL`
- `resultStatus = PENDING_APPROVAL`
- `writeBackStatus = PENDING`
### DB 回读
`biz_writtenoff_adjust_detail`
- submit 后 detail 进入 `PENDING_APPROVAL / SUBMIT`
### query
- `GET /admin-api/business/accounting-adjust/get?adjustmentNo=...` 对 writtenoff 已返回 formal detail
- `GET /admin-api/business/accounting-adjust/page?...objectType=WRITTENOFF_ADJUST` 已返回 formal-first 列表
### approve / reject
- approve`/admin-api/business/accounting-adjust/approve`
- 返回 `APPROVED/SUCCESS/UPDATED`
- 账单 `extended_amount` 归零、`discount_money` 累加、`pay_state=SETTLED(2)`
- reject`/admin-api/business/accounting-adjust/reject`
- 返回 `REJECTED/FAIL/SKIPPED`
- 账单保持原值,不执行核销回写
## 测试数据清理
smoke 完成后已删除:
- `biz_operat_log / detail`identify_value = `992005`, `992006`
- `biz_writtenoff_adjust / detail`
- `biz_charge``992005`, `992006`
- `biz_cust``REV004_WO_SMOKE_A`, `REV004_WO_SMOKE_B`
回读结果:
- `writtenoff_main_left=0`
- `operat_log_left=0`
- `charge_left=0`
- `cust_left=0`
## 运行态清理
用于 fresh-jar HTTP smoke 的临时实例:
- port `48093`
已停止,当前无残留 LISTEN 进程。
## 当前结论
本轮 writtenoff formal-table 已达到:
1. DDL 可落库且可幂等重放;
2. sold submit 能落 pending formal main/detail
3. approve/reject 会同步 formal 状态;
4. detail/page 对 `WRITTENOFF_ADJUST` 已能返回 formal-first 结果;
5. sold submit 已补事务边界,避免 operat_log 与 formal-table 半成功;
6. 审批/驳回缺失 formal 主记录时将显式报错,避免静默漏更新。
## 当前未完成
- writtenoff formal-first 目前仍是最小实现,后续仍可优化 page 查询性能(避免 listAll + getView N+1
- 若需要更细的 charge_detail 差异映射到 formal 明细,可在后续补强。
## 最终补丁后复核2026-04-17 14:57 +08:00
针对本轮补加的两个可靠性修正再次执行 fresh-jar smoke
1. `createSoldAction(...)``@Transactional`,确保 synthetic `operat_log` 与 formal pending 记录同事务提交;
2. writtenoff approve/reject 缺失 formal 主记录时改为显式报错,避免静默跳过 formal 状态更新。
### fresh jar
- 端口:`48094`
- 启动方式:`/usr/bin/java -jar sw-business/sw-business-server/target/sw-business-server.jar --spring.profiles.active=dev --server.port=48094`
- `GET /actuator/health` 返回:`{"status":"UP"}`
### smoke 数据
- charge `992105`approve
- charge `992106`reject
- submit 返回调整单:
- `REV004-SLD-992105-20260417145725`
- `REV004-SLD-992106-20260417145726`
### HTTP 结果
- `sold-submit`:两笔均返回 `PENDING_APPROVAL / PENDING`
- `get?adjustmentNo=REV004-SLD-992105-20260417145725`:可返回 formal detail核销金额、账务年月等
- `page?objectType=WRITTENOFF_ADJUST`:可返回两笔 fresh smoke formal 记录
- `approve`:返回 `APPROVED / SUCCESS / UPDATED`
- `reject`:返回 `REJECTED / FAIL / SKIPPED`
### DB 回读
`biz_writtenoff_adjust`
- `REV004-SLD-992105-20260417145725 -> APPROVED | UPDATED | SUCCESS`
- `REV004-SLD-992106-20260417145726 -> REJECTED | SKIPPED | FAIL`
`biz_writtenoff_adjust_detail`
- approve 明细:`SUCCESS | APPROVE_EXECUTE | approve final smoke`
- reject 明细:`REJECTED | REJECT | reject final smoke`
`biz_charge`
- `992105 -> pay_state=2, extended_amount=0, discount_money=120, original_money=120`
- `992106 -> pay_state=1, extended_amount=88, discount_money=0, original_money=88`
说明最终补丁后writtenoff submit / get / page / approve / reject 主链路再次通过,且回写结果与预期一致。

View File

@ -0,0 +1,543 @@
# 诺税通对接数据库设计草案
## 文档信息
| 项目 | 内容 |
| --- | --- |
| 项目名称 | 福建水务营收系统 |
| 文档类型 | 外部平台对接数据库设计草案 |
| 对接平台 | 诺税通 saas |
| 适用范围 | 销项开票、发票查询、文件获取、交付、作废、红字单据、设备与库存、企业开票配置 |
| 版本 | v1.0 |
| 日期 | 2026-03-24 |
| 状态 | 草案 |
## 适用说明
本文档用于支撑福建水务营收系统对接诺税通 saas 时的数据库落库设计。内容聚焦对接层数据承接,不直接替代正式业务数据库设计主文档,而是作为外部平台集成方案、领域建模和后续 DDL 细化的基础输入。
当前口径基于以下资料统一整理:
- `docs/guides/NUOSHUITONG_SAAS_INTEGRATION_CHECKLIST.md`
- `docs/guides/NUOSHUITONG_INTERFACE_SPEC/`
## 设计目标
本设计用于支撑以下闭环:
- 开票申请与状态同步
- 发票票面文件获取
- 发票交付与补发
- 发票作废、重开、冲红
- 红字信息表与红字确认单管理
- 开票设备与票源库存管理
- 企业开票配置与规则缓存
- 平台回调与请求日志追踪
## 表清单总览
| 表名 | 说明 |
| --- | --- |
| `ns_invoice` | 发票主表 |
| `ns_invoice_item` | 发票明细表 |
| `ns_invoice_delivery` | 发票交付记录表 |
| `ns_invoice_reversal` | 发票逆向处理表 |
| `ns_red_document` | 红字单据主表 |
| `ns_red_document_item` | 红字单据明细表 |
| `ns_billing_device` | 开票设备表 |
| `ns_invoice_stock_snapshot` | 发票库存快照表 |
| `ns_enterprise_billing_config` | 企业开票配置表 |
| `ns_platform_event_log` | 平台回调事件表 |
| `ns_platform_request_log` | 平台请求响应日志表 |
| `ns_config_dictionary_cache` | 配置字典缓存表(可选) |
## 命名与通用约定
### 表命名
- 对接域表统一采用 `ns_` 前缀,表示 Nuoshuitong 集成域。
- 字段命名统一使用下划线命名法。
### 通用审计字段
除快照类或纯日志类表外,建议统一具备:
- `created_at`
- `updated_at`
- `created_by`
- `updated_by`
### 状态字段约定
建议状态类字段统一采用“编码 + 文本”双承接:
- `*_status`
- `*_status_text`
### JSON 字段约定
当平台返回结构复杂、且短期内不适合完全拆表时,可保留 JSON/TEXT 字段承接,例如:
- `specific_factor_json`
- `request_body`
- `response_body`
- `payload_json`
## 详细表结构草案
## `ns_invoice` 发票主表
### 用途
承接发票从申请、查询、回调、文件获取到交付的主生命周期。
### 字段建议
| 字段名 | 类型建议 | 非空 | 说明 |
| --- | --- | --- | --- |
| `id` | bigint | 是 | 主键 |
| `sys_request_no` | varchar(64) | 是 | 系统侧请求号,建议唯一 |
| `order_no` | varchar(64) | 否 | 业务订单号 |
| `source_business_type` | varchar(32) | 否 | 来源业务类型 |
| `source_business_id` | varchar(64) | 否 | 来源业务主键 |
| `platform_invoice_serial_num` | varchar(64) | 否 | 平台发票流水号 |
| `invoice_id` | varchar(64) | 否 | 平台发票 ID |
| `invoice_code` | varchar(32) | 否 | 发票代码 |
| `invoice_no` | varchar(32) | 否 | 发票号码 |
| `all_electronic_invoice_no` | varchar(64) | 否 | 数电票号码 |
| `seller_tax_no` | varchar(32) | 是 | 销方税号 |
| `buyer_name` | varchar(200) | 否 | 购方名称 |
| `buyer_tax_no` | varchar(64) | 否 | 购方税号 |
| `buyer_address` | varchar(255) | 否 | 购方地址 |
| `buyer_tel` | varchar(64) | 否 | 购方电话 |
| `buyer_account` | varchar(255) | 否 | 购方开户行及账号 |
| `invoice_type` | varchar(16) | 否 | 蓝票/红票 |
| `invoice_line` | varchar(16) | 否 | 发票票种 |
| `list_flag` | smallint | 否 | 清单标志 |
| `with_tax_flag` | smallint | 否 | 含税标志 |
| `notify_phone` | varchar(64) | 否 | 交付手机号 |
| `notify_email` | varchar(128) | 否 | 交付邮箱 |
| `cc_phone` | varchar(256) | 否 | 抄送手机号 |
| `cc_email` | varchar(256) | 否 | 抄送邮箱 |
| `total_amount` | decimal(18,2) | 否 | 含税总金额 |
| `amount_without_tax` | decimal(18,2) | 否 | 不含税总金额 |
| `tax_amount` | decimal(18,2) | 否 | 税额 |
| `request_status` | varchar(32) | 是 | 请求状态 |
| `invoice_status` | varchar(32) | 否 | 开票状态 |
| `invoice_status_text` | varchar(255) | 否 | 状态说明 |
| `invalid_state` | varchar(32) | 否 | 作废状态 |
| `delivery_status` | varchar(32) | 否 | 交付状态 |
| `sync_status` | varchar(32) | 否 | 平台同步状态 |
| `pdf_url` | varchar(1024) | 否 | PDF 地址 |
| `ofd_url` | varchar(1024) | 否 | OFD 地址 |
| `image_url` | varchar(1024) | 否 | 图片地址 |
| `paper_pdf_url` | varchar(1024) | 否 | 纸票 PDF 地址 |
| `invoice_time` | datetime | 否 | 开票时间 |
| `request_time` | datetime | 否 | 请求时间 |
| `invalid_time` | datetime | 否 | 作废时间 |
| `last_sync_time` | datetime | 否 | 最近同步时间 |
| `ori_invoice_code` | varchar(32) | 否 | 原发票代码 |
| `ori_invoice_no` | varchar(32) | 否 | 原发票号码 |
| `old_electronic_invoice_no` | varchar(64) | 否 | 原数电票号码 |
| `remark` | varchar(1000) | 否 | 备注 |
| `specific_factor_json` | text | 否 | 特殊因子 JSON |
| `latest_result` | varchar(1000) | 否 | 最近一次平台结果摘要 |
| `latest_error` | varchar(1000) | 否 | 最近一次错误摘要 |
| `try_count` | int | 否 | 同步/补偿次数 |
| `last_try_time` | datetime | 否 | 最近重试时间 |
| `next_try_time` | datetime | 否 | 下次重试时间 |
| `created_at` | datetime | 是 | 创建时间 |
| `updated_at` | datetime | 是 | 更新时间 |
| `created_by` | varchar(64) | 否 | 创建人 |
| `updated_by` | varchar(64) | 否 | 更新人 |
### 主键与唯一约束建议
- 主键:`id`
- 唯一约束:`sys_request_no`
- 可选唯一约束:`platform_invoice_serial_num`
- 可选业务唯一约束:`seller_tax_no + invoice_code + invoice_no`
### 索引建议
- `idx_ns_invoice_order_no`
- `idx_ns_invoice_status`
- `idx_ns_invoice_seller_tax_no`
- `idx_ns_invoice_invoice_time`
- `idx_ns_invoice_next_try_time`
### 状态字段建议
#### `request_status`
- `DRAFT`
- `PRECHECK_FAILED`
- `REQUESTED`
- `PROCESSING`
- `SUCCESS`
- `FAILED`
#### `invoice_status`
- `ISSUING`
- `ISSUED`
- `ISSUE_FAILED`
- `CANCELLED`
- `CANCEL_FAILED`
- `RED_PROCESSED`
#### `delivery_status`
- `NOT_DELIVERED`
- `DELIVERING`
- `DELIVERED`
- `DELIVERY_FAILED`
## `ns_invoice_item` 发票明细表
### 用途
保存开票请求与平台返回的发票明细。
### 字段建议
| 字段名 | 类型建议 | 非空 | 说明 |
| --- | --- | --- | --- |
| `id` | bigint | 是 | 主键 |
| `invoice_id` | bigint | 是 | 发票主表 ID |
| `line_no` | int | 是 | 行号 |
| `goods_name` | varchar(255) | 是 | 商品名称 |
| `goods_code` | varchar(64) | 否 | 税收分类编码 |
| `spec` | varchar(128) | 否 | 规格型号 |
| `unit` | varchar(64) | 否 | 单位 |
| `quantity` | decimal(18,6) | 否 | 数量 |
| `unit_price` | decimal(18,6) | 否 | 单价 |
| `amount_with_tax` | decimal(18,2) | 否 | 含税金额 |
| `amount_without_tax` | decimal(18,2) | 否 | 不含税金额 |
| `tax_rate` | decimal(8,4) | 否 | 税率 |
| `tax_amount` | decimal(18,2) | 否 | 税额 |
| `detail_type` | smallint | 否 | 行类型 |
| `favoured_policy_flag` | smallint | 否 | 优惠政策标志 |
| `zero_rate_flag` | smallint | 否 | 零税率标志 |
| `favoured_policy_name` | varchar(128) | 否 | 优惠政策名称 |
| `created_at` | datetime | 是 | 创建时间 |
| `updated_at` | datetime | 是 | 更新时间 |
### 约束建议
- 外键:`invoice_id -> ns_invoice.id`
- 唯一约束:`invoice_id + line_no`
## `ns_invoice_delivery` 发票交付记录表
### 用途
记录首次交付、补发和交付失败结果。
### 字段建议
| 字段名 | 类型建议 | 非空 | 说明 |
| --- | --- | --- | --- |
| `id` | bigint | 是 | 主键 |
| `invoice_id` | bigint | 是 | 发票 ID |
| `delivery_type` | varchar(16) | 是 | `SMS` / `EMAIL` |
| `delivery_target` | varchar(256) | 是 | 发送目标 |
| `cc_target` | varchar(512) | 否 | 抄送目标 |
| `delivery_status` | varchar(32) | 是 | 交付状态 |
| `delivery_message` | varchar(1000) | 否 | 平台返回信息 |
| `delivery_attempt_no` | int | 是 | 第几次交付 |
| `is_retry` | smallint | 是 | 是否补发 |
| `response_code` | varchar(32) | 否 | 平台响应码 |
| `response_body` | text | 否 | 平台响应体 |
| `delivery_time` | datetime | 否 | 交付时间 |
| `created_at` | datetime | 是 | 创建时间 |
### 索引建议
- `idx_ns_invoice_delivery_invoice_id`
- `idx_ns_invoice_delivery_status`
## `ns_invoice_reversal` 发票逆向处理表
### 用途
记录作废、冲红、重开、空白票作废等逆向业务动作。
### 字段建议
| 字段名 | 类型建议 | 非空 | 说明 |
| --- | --- | --- | --- |
| `id` | bigint | 是 | 主键 |
| `invoice_id` | bigint | 是 | 原发票 ID |
| `reversal_type` | varchar(32) | 是 | `CANCEL` / `FAST_RED` / `REOPEN` / `BLANK_CANCEL` |
| `source_invoice_code` | varchar(32) | 否 | 原票代码 |
| `source_invoice_no` | varchar(32) | 否 | 原票号码 |
| `invalid_reason` | varchar(32) | 否 | 作废原因编码 |
| `specific_reason` | varchar(500) | 否 | 具体原因 |
| `request_status` | varchar(32) | 是 | 请求状态 |
| `reversal_status` | varchar(32) | 否 | 逆向状态 |
| `platform_result_code` | varchar(32) | 否 | 平台响应码 |
| `platform_result_msg` | varchar(1000) | 否 | 平台响应信息 |
| `target_invoice_id` | bigint | 否 | 新票 ID |
| `created_at` | datetime | 是 | 创建时间 |
| `updated_at` | datetime | 是 | 更新时间 |
### 状态建议
- `INIT`
- `CHECKING`
- `REQUESTED`
- `SUCCESS`
- `FAILED`
- `REJECTED`
## `ns_red_document` 红字单据主表
### 用途
统一承接红字信息表与红字确认单。
### 字段建议
| 字段名 | 类型建议 | 非空 | 说明 |
| --- | --- | --- | --- |
| `id` | bigint | 是 | 主键 |
| `invoice_id` | bigint | 否 | 关联蓝票 ID |
| `document_type` | varchar(16) | 是 | `RED_INFO` / `RED_CONFIRM` |
| `bill_no` | varchar(64) | 否 | 单据编号 |
| `bill_id` | varchar(64) | 否 | 平台单据 ID |
| `bill_info_no` | varchar(64) | 否 | 信息表编号 |
| `bill_confirm_no` | varchar(64) | 否 | 确认单编号 |
| `bill_uuid` | varchar(64) | 否 | 平台 UUID |
| `blue_invoice_code` | varchar(32) | 否 | 蓝票代码 |
| `blue_invoice_no` | varchar(32) | 否 | 蓝票号码 |
| `blue_invoice_number` | varchar(64) | 否 | 蓝票数电号 |
| `blue_invoice_line` | varchar(16) | 否 | 蓝票票种 |
| `bill_type` | varchar(32) | 否 | 红字业务类型 |
| `bill_status` | varchar(32) | 否 | 单据状态 |
| `bill_status_text` | varchar(255) | 否 | 状态说明 |
| `open_status` | varchar(32) | 否 | 开具状态 |
| `back_type` | varchar(16) | 否 | 回传类型 |
| `apply_source` | varchar(32) | 否 | 申请来源 |
| `red_reason` | varchar(255) | 否 | 红字原因 |
| `apply_remark` | varchar(1000) | 否 | 申请备注 |
| `pdf_url` | varchar(1024) | 否 | PDF 地址 |
| `callback_status` | varchar(32) | 否 | 回调处理状态 |
| `last_sync_time` | datetime | 否 | 最近同步时间 |
| `created_at` | datetime | 是 | 创建时间 |
| `updated_at` | datetime | 是 | 更新时间 |
### 唯一约束建议
- `bill_no`
- 可选:`bill_id`
## `ns_red_document_item` 红字单据明细表
### 用途
承接红字申请与确认单明细。
### 字段建议
| 字段名 | 类型建议 | 非空 | 说明 |
| --- | --- | --- | --- |
| `id` | bigint | 是 | 主键 |
| `red_document_id` | bigint | 是 | 红字单据主表 ID |
| `line_no` | int | 是 | 行号 |
| `goods_name` | varchar(255) | 否 | 商品名称 |
| `model` | varchar(128) | 否 | 型号 |
| `unit` | varchar(64) | 否 | 单位 |
| `quantity` | decimal(18,6) | 否 | 数量 |
| `unit_price` | decimal(18,6) | 否 | 单价 |
| `amount` | decimal(18,2) | 否 | 金额 |
| `tax_rate` | decimal(8,4) | 否 | 税率 |
| `tax_amount` | decimal(18,2) | 否 | 税额 |
| `with_tax_flag` | smallint | 否 | 含税标志 |
| `created_at` | datetime | 是 | 创建时间 |
| `updated_at` | datetime | 是 | 更新时间 |
## `ns_billing_device` 开票设备表
### 用途
承接设备主数据、运行态状态和设备能力。
### 字段建议
| 字段名 | 类型建议 | 非空 | 说明 |
| --- | --- | --- | --- |
| `id` | bigint | 是 | 主键 |
| `tax_num` | varchar(32) | 是 | 企业税号 |
| `company_id` | varchar(64) | 否 | 平台企业 ID |
| `extension_num` | varchar(32) | 否 | 分机号 |
| `machine_num` | varchar(64) | 否 | 机器编号 |
| `terminal_num` | varchar(64) | 否 | 终端号 |
| `server_type` | varchar(32) | 否 | 设备类型 |
| `invoice_type_list` | varchar(512) | 否 | 支持票种列表 |
| `login_account` | varchar(128) | 否 | 登录账号 |
| `equipment_cabinet_id` | varchar(64) | 否 | 机柜 ID |
| `device_status` | varchar(32) | 是 | 在线状态 |
| `report_tax_status` | varchar(32) | 否 | 抄报状态 |
| `clear_card_status` | varchar(32) | 否 | 清卡状态 |
| `lock_date` | varchar(32) | 否 | 锁死日期 |
| `single_billing_limit` | decimal(18,2) | 否 | 单笔限额 |
| `offline_amount` | decimal(18,2) | 否 | 离线金额 |
| `offline_time` | varchar(64) | 否 | 离线时间 |
| `last_status_sync_time` | datetime | 否 | 最近状态同步时间 |
| `created_at` | datetime | 是 | 创建时间 |
| `updated_at` | datetime | 是 | 更新时间 |
### 唯一约束建议
- 保守建议:`tax_num + extension_num + machine_num`
## `ns_invoice_stock_snapshot` 发票库存快照表
### 用途
记录库存查询、刷新、下载、申领后的快照结果。
### 字段建议
| 字段名 | 类型建议 | 非空 | 说明 |
| --- | --- | --- | --- |
| `id` | bigint | 是 | 主键 |
| `device_id` | bigint | 否 | 设备 ID |
| `seller_tax_no` | varchar(32) | 是 | 销方税号 |
| `extension_num` | varchar(32) | 否 | 分机号 |
| `machine_num` | varchar(64) | 否 | 机器编号 |
| `terminal_num` | varchar(64) | 否 | 终端号 |
| `invoice_line` | varchar(16) | 否 | 票种 |
| `invoice_code` | varchar(32) | 否 | 发票代码 |
| `invoice_num_start` | varchar(32) | 否 | 起始号 |
| `invoice_num_end` | varchar(32) | 否 | 结束号 |
| `remain_num` | int | 否 | 剩余数量 |
| `is_default` | smallint | 否 | 是否默认 |
| `source_type` | varchar(16) | 是 | `QUERY` / `REFRESH` / `DOWNLOAD` / `APPLY` |
| `snapshot_time` | datetime | 是 | 快照时间 |
| `created_at` | datetime | 是 | 创建时间 |
## `ns_enterprise_billing_config` 企业开票配置表
### 用途
承接企业开票默认信息与认证状态。
### 字段建议
| 字段名 | 类型建议 | 非空 | 说明 |
| --- | --- | --- | --- |
| `id` | bigint | 是 | 主键 |
| `tax_num` | varchar(32) | 是 | 企业税号 |
| `company_id` | varchar(64) | 否 | 平台企业 ID |
| `use_scope` | varchar(32) | 否 | 使用范围 |
| `clerker` | varchar(128) | 否 | 开票员 |
| `seller_address` | varchar(255) | 否 | 销方地址 |
| `seller_tel` | varchar(64) | 否 | 销方电话 |
| `seller_bank` | varchar(255) | 否 | 销方开户行 |
| `seller_account` | varchar(255) | 否 | 销方账号 |
| `payee` | varchar(64) | 否 | 收款人 |
| `checker` | varchar(64) | 否 | 复核人 |
| `project_code` | varchar(64) | 否 | 项目编码 |
| `department_name` | varchar(128) | 否 | 部门名称 |
| `auth_status` | varchar(32) | 否 | 认证状态 |
| `last_auth_time` | datetime | 否 | 最近认证时间 |
| `created_at` | datetime | 是 | 创建时间 |
| `updated_at` | datetime | 是 | 更新时间 |
### 唯一约束建议
- `tax_num`
## `ns_platform_event_log` 平台回调事件表
### 用途
保留平台回调原文和处理结果,实现幂等与可追踪。
### 字段建议
| 字段名 | 类型建议 | 非空 | 说明 |
| --- | --- | --- | --- |
| `id` | bigint | 是 | 主键 |
| `event_type` | varchar(32) | 是 | `INVOICE_CALLBACK` / `RED_CALLBACK` |
| `event_key` | varchar(128) | 是 | 幂等键 |
| `seller_tax_no` | varchar(32) | 否 | 销方税号 |
| `business_key` | varchar(128) | 否 | 业务主键 |
| `payload_json` | longtext | 是 | 回调原文 |
| `process_status` | varchar(32) | 是 | `INIT` / `SUCCESS` / `FAILED` / `IGNORED` |
| `process_message` | varchar(1000) | 否 | 处理说明 |
| `processed_at` | datetime | 否 | 处理时间 |
| `created_at` | datetime | 是 | 创建时间 |
### 唯一约束建议
- `event_key`
## `ns_platform_request_log` 平台请求响应日志表
### 用途
记录所有对诺税通平台的请求与响应,便于联调排障。
### 字段建议
| 字段名 | 类型建议 | 非空 | 说明 |
| --- | --- | --- | --- |
| `id` | bigint | 是 | 主键 |
| `request_id` | varchar(64) | 是 | 请求 ID |
| `business_type` | varchar(32) | 否 | 业务类型 |
| `business_id` | varchar(64) | 否 | 业务 ID |
| `method_name` | varchar(128) | 否 | 平台方法名 |
| `request_headers_masked` | text | 否 | 脱敏请求头 |
| `request_body` | longtext | 否 | 请求体 |
| `response_body` | longtext | 否 | 响应体 |
| `response_code` | varchar(32) | 否 | 响应码 |
| `success_flag` | smallint | 否 | 成功标识 |
| `error_message` | varchar(1000) | 否 | 错误信息 |
| `created_at` | datetime | 是 | 创建时间 |
## `ns_config_dictionary_cache` 配置字典缓存表(可选)
### 用途
缓存平台字典项,如:
- `requestSrc`
- `invoiceLine`
- `organize`
- `dept`
- `clerk`
- `invalidSrc`
### 字段建议
| 字段名 | 类型建议 | 非空 | 说明 |
| --- | --- | --- | --- |
| `id` | bigint | 是 | 主键 |
| `dict_type` | varchar(64) | 是 | 字典类型 |
| `dict_key` | varchar(128) | 是 | 字典键 |
| `dict_name` | varchar(255) | 否 | 字典名称 |
| `company_id` | varchar(64) | 否 | 企业 ID |
| `company_name` | varchar(255) | 否 | 企业名称 |
| `extra_json` | text | 否 | 扩展 JSON |
| `last_sync_time` | datetime | 否 | 最近同步时间 |
| `created_at` | datetime | 是 | 创建时间 |
| `updated_at` | datetime | 是 | 更新时间 |
## 表关系建议
```mermaid
erDiagram
ns_invoice ||--o{ ns_invoice_item : contains
ns_invoice ||--o{ ns_invoice_delivery : delivers
ns_invoice ||--o{ ns_invoice_reversal : reverses
ns_invoice ||--o{ ns_red_document : relates
ns_red_document ||--o{ ns_red_document_item : contains
ns_billing_device ||--o{ ns_invoice_stock_snapshot : has
ns_enterprise_billing_config ||--o{ ns_billing_device : configures
```
## 幂等与审计建议
### 回调幂等
必须依赖:
- `ns_platform_event_log.event_key`
建议 `event_key` 构成为:
- 发票回调:`sellerTaxNo + invoiceId + invoiceStatus`
- 红字回调:`backType + billNo + billStatus`
### 请求幂等
建议:
- `sys_request_no` 全局唯一
- 开票请求入库前先校验是否已存在同请求号记录
## 首期最小落表建议
若先追求最小可用,建议优先落以下 7 张表:
- `ns_invoice`
- `ns_invoice_item`
- `ns_invoice_delivery`
- `ns_invoice_reversal`
- `ns_billing_device`
- `ns_invoice_stock_snapshot`
- `ns_platform_request_log`
第二批补充:
- `ns_red_document`
- `ns_red_document_item`
- `ns_platform_event_log`
- `ns_enterprise_billing_config`
## 后续建议
本文档完成后,建议继续补充两项内容:
- 按表输出正式 DDL 草案
- 与 `docs/design/03_Technical_Design/01_Database_Design.md` 对齐,纳入正式专项设计口径

View File

@ -0,0 +1,529 @@
# 诺税通对接 DDL 草案
## 文档信息
| 项目 | 内容 |
| --- | --- |
| 项目名称 | 福建水务营收系统 |
| 文档类型 | 外部平台对接 DDL 草案 |
| 对接平台 | 诺税通 saas |
| 适用范围 | 发票、红字单据、设备、库存、企业配置、平台日志 |
| 版本 | v1.0 |
| 日期 | 2026-03-24 |
| 状态 | 草案 |
## 适用说明
本文档在 `docs/guides/NUOSHUITONG_DATABASE_DESIGN.md` 的基础上,进一步给出面向实现的 DDL 草案。当前以 PostgreSQL/MySQL 均可平滑迁移的通用 SQL 风格表达为主,重点用于:
- 明确核心表字段结构
- 明确主键、唯一约束与索引建议
- 为后续纳入正式数据库设计主文档提供输入
## 使用约定
- 主键统一使用 `bigint`
- 金额统一使用 `decimal(18,2)`
- 数量/单价类字段视场景使用 `decimal(18,6)`
- 状态类字段统一使用 `varchar(32)`
- URL 字段统一预留 `varchar(1024)`
- 长报文、原始回调、请求响应体统一使用 `text` / `longtext`
## DDL 草案
## `ns_invoice` 发票主表
```sql
CREATE TABLE ns_invoice (
id BIGINT PRIMARY KEY,
sys_request_no VARCHAR(64) NOT NULL,
order_no VARCHAR(64),
source_business_type VARCHAR(32),
source_business_id VARCHAR(64),
platform_invoice_serial_num VARCHAR(64),
invoice_id VARCHAR(64),
invoice_code VARCHAR(32),
invoice_no VARCHAR(32),
all_electronic_invoice_no VARCHAR(64),
seller_tax_no VARCHAR(32) NOT NULL,
buyer_name VARCHAR(200),
buyer_tax_no VARCHAR(64),
buyer_address VARCHAR(255),
buyer_tel VARCHAR(64),
buyer_account VARCHAR(255),
invoice_type VARCHAR(16),
invoice_line VARCHAR(16),
list_flag SMALLINT,
with_tax_flag SMALLINT,
notify_phone VARCHAR(64),
notify_email VARCHAR(128),
cc_phone VARCHAR(256),
cc_email VARCHAR(256),
total_amount DECIMAL(18,2),
amount_without_tax DECIMAL(18,2),
tax_amount DECIMAL(18,2),
request_status VARCHAR(32) NOT NULL,
invoice_status VARCHAR(32),
invoice_status_text VARCHAR(255),
invalid_state VARCHAR(32),
delivery_status VARCHAR(32),
sync_status VARCHAR(32),
pdf_url VARCHAR(1024),
ofd_url VARCHAR(1024),
image_url VARCHAR(1024),
paper_pdf_url VARCHAR(1024),
invoice_time DATETIME,
request_time DATETIME,
invalid_time DATETIME,
last_sync_time DATETIME,
ori_invoice_code VARCHAR(32),
ori_invoice_no VARCHAR(32),
old_electronic_invoice_no VARCHAR(64),
remark VARCHAR(1000),
specific_factor_json TEXT,
latest_result VARCHAR(1000),
latest_error VARCHAR(1000),
try_count INT,
last_try_time DATETIME,
next_try_time DATETIME,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
created_by VARCHAR(64),
updated_by VARCHAR(64)
);
```
### 约束与索引建议
```sql
ALTER TABLE ns_invoice
ADD CONSTRAINT uk_ns_invoice_sys_request_no UNIQUE (sys_request_no);
CREATE UNIQUE INDEX uk_ns_invoice_platform_serial_num
ON ns_invoice (platform_invoice_serial_num);
CREATE INDEX idx_ns_invoice_order_no
ON ns_invoice (order_no);
CREATE INDEX idx_ns_invoice_status
ON ns_invoice (request_status, invoice_status, delivery_status);
CREATE INDEX idx_ns_invoice_seller_tax_no
ON ns_invoice (seller_tax_no);
CREATE INDEX idx_ns_invoice_invoice_time
ON ns_invoice (invoice_time);
CREATE INDEX idx_ns_invoice_next_try_time
ON ns_invoice (next_try_time);
```
## `ns_invoice_item` 发票明细表
```sql
CREATE TABLE ns_invoice_item (
id BIGINT PRIMARY KEY,
invoice_id BIGINT NOT NULL,
line_no INT NOT NULL,
goods_name VARCHAR(255) NOT NULL,
goods_code VARCHAR(64),
spec VARCHAR(128),
unit VARCHAR(64),
quantity DECIMAL(18,6),
unit_price DECIMAL(18,6),
amount_with_tax DECIMAL(18,2),
amount_without_tax DECIMAL(18,2),
tax_rate DECIMAL(8,4),
tax_amount DECIMAL(18,2),
detail_type SMALLINT,
favoured_policy_flag SMALLINT,
zero_rate_flag SMALLINT,
favoured_policy_name VARCHAR(128),
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL
);
```
### 约束与索引建议
```sql
ALTER TABLE ns_invoice_item
ADD CONSTRAINT fk_ns_invoice_item_invoice
FOREIGN KEY (invoice_id) REFERENCES ns_invoice(id);
CREATE UNIQUE INDEX uk_ns_invoice_item_invoice_line
ON ns_invoice_item (invoice_id, line_no);
CREATE INDEX idx_ns_invoice_item_invoice_id
ON ns_invoice_item (invoice_id);
```
## `ns_invoice_delivery` 发票交付记录表
```sql
CREATE TABLE ns_invoice_delivery (
id BIGINT PRIMARY KEY,
invoice_id BIGINT NOT NULL,
delivery_type VARCHAR(16) NOT NULL,
delivery_target VARCHAR(256) NOT NULL,
cc_target VARCHAR(512),
delivery_status VARCHAR(32) NOT NULL,
delivery_message VARCHAR(1000),
delivery_attempt_no INT NOT NULL,
is_retry SMALLINT NOT NULL,
response_code VARCHAR(32),
response_body TEXT,
delivery_time DATETIME,
created_at DATETIME NOT NULL
);
```
### 约束与索引建议
```sql
ALTER TABLE ns_invoice_delivery
ADD CONSTRAINT fk_ns_invoice_delivery_invoice
FOREIGN KEY (invoice_id) REFERENCES ns_invoice(id);
CREATE INDEX idx_ns_invoice_delivery_invoice_id
ON ns_invoice_delivery (invoice_id);
CREATE INDEX idx_ns_invoice_delivery_status
ON ns_invoice_delivery (delivery_status, delivery_time);
```
## `ns_invoice_reversal` 发票逆向处理表
```sql
CREATE TABLE ns_invoice_reversal (
id BIGINT PRIMARY KEY,
invoice_id BIGINT NOT NULL,
reversal_type VARCHAR(32) NOT NULL,
source_invoice_code VARCHAR(32),
source_invoice_no VARCHAR(32),
invalid_reason VARCHAR(32),
specific_reason VARCHAR(500),
request_status VARCHAR(32) NOT NULL,
reversal_status VARCHAR(32),
platform_result_code VARCHAR(32),
platform_result_msg VARCHAR(1000),
target_invoice_id BIGINT,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL
);
```
### 约束与索引建议
```sql
ALTER TABLE ns_invoice_reversal
ADD CONSTRAINT fk_ns_invoice_reversal_invoice
FOREIGN KEY (invoice_id) REFERENCES ns_invoice(id);
CREATE INDEX idx_ns_invoice_reversal_invoice_id
ON ns_invoice_reversal (invoice_id);
CREATE INDEX idx_ns_invoice_reversal_status
ON ns_invoice_reversal (request_status, reversal_status);
```
## `ns_red_document` 红字单据主表
```sql
CREATE TABLE ns_red_document (
id BIGINT PRIMARY KEY,
invoice_id BIGINT,
document_type VARCHAR(16) NOT NULL,
bill_no VARCHAR(64),
bill_id VARCHAR(64),
bill_info_no VARCHAR(64),
bill_confirm_no VARCHAR(64),
bill_uuid VARCHAR(64),
blue_invoice_code VARCHAR(32),
blue_invoice_no VARCHAR(32),
blue_invoice_number VARCHAR(64),
blue_invoice_line VARCHAR(16),
bill_type VARCHAR(32),
bill_status VARCHAR(32),
bill_status_text VARCHAR(255),
open_status VARCHAR(32),
back_type VARCHAR(16),
apply_source VARCHAR(32),
red_reason VARCHAR(255),
apply_remark VARCHAR(1000),
pdf_url VARCHAR(1024),
callback_status VARCHAR(32),
last_sync_time DATETIME,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL
);
```
### 约束与索引建议
```sql
ALTER TABLE ns_red_document
ADD CONSTRAINT fk_ns_red_document_invoice
FOREIGN KEY (invoice_id) REFERENCES ns_invoice(id);
CREATE UNIQUE INDEX uk_ns_red_document_bill_no
ON ns_red_document (bill_no);
CREATE UNIQUE INDEX uk_ns_red_document_bill_id
ON ns_red_document (bill_id);
CREATE INDEX idx_ns_red_document_invoice_id
ON ns_red_document (invoice_id);
CREATE INDEX idx_ns_red_document_status
ON ns_red_document (document_type, bill_status, open_status);
```
## `ns_red_document_item` 红字单据明细表
```sql
CREATE TABLE ns_red_document_item (
id BIGINT PRIMARY KEY,
red_document_id BIGINT NOT NULL,
line_no INT NOT NULL,
goods_name VARCHAR(255),
model VARCHAR(128),
unit VARCHAR(64),
quantity DECIMAL(18,6),
unit_price DECIMAL(18,6),
amount DECIMAL(18,2),
tax_rate DECIMAL(8,4),
tax_amount DECIMAL(18,2),
with_tax_flag SMALLINT,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL
);
```
### 约束与索引建议
```sql
ALTER TABLE ns_red_document_item
ADD CONSTRAINT fk_ns_red_document_item_main
FOREIGN KEY (red_document_id) REFERENCES ns_red_document(id);
CREATE UNIQUE INDEX uk_ns_red_document_item_line
ON ns_red_document_item (red_document_id, line_no);
```
## `ns_billing_device` 开票设备表
```sql
CREATE TABLE ns_billing_device (
id BIGINT PRIMARY KEY,
tax_num VARCHAR(32) NOT NULL,
company_id VARCHAR(64),
extension_num VARCHAR(32),
machine_num VARCHAR(64),
terminal_num VARCHAR(64),
server_type VARCHAR(32),
invoice_type_list VARCHAR(512),
login_account VARCHAR(128),
equipment_cabinet_id VARCHAR(64),
device_status VARCHAR(32) NOT NULL,
report_tax_status VARCHAR(32),
clear_card_status VARCHAR(32),
lock_date VARCHAR(32),
single_billing_limit DECIMAL(18,2),
offline_amount DECIMAL(18,2),
offline_time VARCHAR(64),
last_status_sync_time DATETIME,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL
);
```
### 约束与索引建议
```sql
CREATE UNIQUE INDEX uk_ns_billing_device_tax_ext_machine
ON ns_billing_device (tax_num, extension_num, machine_num);
CREATE INDEX idx_ns_billing_device_tax_num
ON ns_billing_device (tax_num);
CREATE INDEX idx_ns_billing_device_status
ON ns_billing_device (device_status, report_tax_status, clear_card_status);
```
## `ns_invoice_stock_snapshot` 发票库存快照表
```sql
CREATE TABLE ns_invoice_stock_snapshot (
id BIGINT PRIMARY KEY,
device_id BIGINT,
seller_tax_no VARCHAR(32) NOT NULL,
extension_num VARCHAR(32),
machine_num VARCHAR(64),
terminal_num VARCHAR(64),
invoice_line VARCHAR(16),
invoice_code VARCHAR(32),
invoice_num_start VARCHAR(32),
invoice_num_end VARCHAR(32),
remain_num INT,
is_default SMALLINT,
source_type VARCHAR(16) NOT NULL,
snapshot_time DATETIME NOT NULL,
created_at DATETIME NOT NULL
);
```
### 约束与索引建议
```sql
ALTER TABLE ns_invoice_stock_snapshot
ADD CONSTRAINT fk_ns_invoice_stock_device
FOREIGN KEY (device_id) REFERENCES ns_billing_device(id);
CREATE INDEX idx_ns_stock_device_time
ON ns_invoice_stock_snapshot (device_id, snapshot_time);
CREATE INDEX idx_ns_stock_tax_line_time
ON ns_invoice_stock_snapshot (seller_tax_no, invoice_line, snapshot_time);
```
## `ns_enterprise_billing_config` 企业开票配置表
```sql
CREATE TABLE ns_enterprise_billing_config (
id BIGINT PRIMARY KEY,
tax_num VARCHAR(32) NOT NULL,
company_id VARCHAR(64),
use_scope VARCHAR(32),
clerker VARCHAR(128),
seller_address VARCHAR(255),
seller_tel VARCHAR(64),
seller_bank VARCHAR(255),
seller_account VARCHAR(255),
payee VARCHAR(64),
checker VARCHAR(64),
project_code VARCHAR(64),
department_name VARCHAR(128),
auth_status VARCHAR(32),
last_auth_time DATETIME,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL
);
```
### 约束与索引建议
```sql
CREATE UNIQUE INDEX uk_ns_enterprise_billing_config_tax_num
ON ns_enterprise_billing_config (tax_num);
```
## `ns_platform_event_log` 平台回调事件表
```sql
CREATE TABLE ns_platform_event_log (
id BIGINT PRIMARY KEY,
event_type VARCHAR(32) NOT NULL,
event_key VARCHAR(128) NOT NULL,
seller_tax_no VARCHAR(32),
business_key VARCHAR(128),
payload_json TEXT NOT NULL,
process_status VARCHAR(32) NOT NULL,
process_message VARCHAR(1000),
processed_at DATETIME,
created_at DATETIME NOT NULL
);
```
### 约束与索引建议
```sql
CREATE UNIQUE INDEX uk_ns_platform_event_log_event_key
ON ns_platform_event_log (event_key);
CREATE INDEX idx_ns_platform_event_log_type_status
ON ns_platform_event_log (event_type, process_status);
```
## `ns_platform_request_log` 平台请求响应日志表
```sql
CREATE TABLE ns_platform_request_log (
id BIGINT PRIMARY KEY,
request_id VARCHAR(64) NOT NULL,
business_type VARCHAR(32),
business_id VARCHAR(64),
method_name VARCHAR(128),
request_headers_masked TEXT,
request_body TEXT,
response_body TEXT,
response_code VARCHAR(32),
success_flag SMALLINT,
error_message VARCHAR(1000),
created_at DATETIME NOT NULL
);
```
### 约束与索引建议
```sql
CREATE UNIQUE INDEX uk_ns_platform_request_log_request_id
ON ns_platform_request_log (request_id);
CREATE INDEX idx_ns_platform_request_log_business
ON ns_platform_request_log (business_type, business_id);
CREATE INDEX idx_ns_platform_request_log_method_name
ON ns_platform_request_log (method_name);
```
## `ns_config_dictionary_cache` 配置字典缓存表(可选)
```sql
CREATE TABLE ns_config_dictionary_cache (
id BIGINT PRIMARY KEY,
dict_type VARCHAR(64) NOT NULL,
dict_key VARCHAR(128) NOT NULL,
dict_name VARCHAR(255),
company_id VARCHAR(64),
company_name VARCHAR(255),
extra_json TEXT,
last_sync_time DATETIME,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL
);
```
### 约束与索引建议
```sql
CREATE UNIQUE INDEX uk_ns_config_dictionary_cache_type_key
ON ns_config_dictionary_cache (dict_type, dict_key);
CREATE INDEX idx_ns_config_dictionary_cache_type
ON ns_config_dictionary_cache (dict_type);
```
## 首期最小实施 DDL 建议
若以“最小可用”为目标,建议优先建以下 7 张表:
- `ns_invoice`
- `ns_invoice_item`
- `ns_invoice_delivery`
- `ns_invoice_reversal`
- `ns_billing_device`
- `ns_invoice_stock_snapshot`
- `ns_platform_request_log`
第二批补充:
- `ns_red_document`
- `ns_red_document_item`
- `ns_platform_event_log`
- `ns_enterprise_billing_config`
## 后续建议
建议在此基础上继续完成:
- 字段注释 SQL 草案
- 状态码 / 枚举字典与字段注释联动
- PostgreSQL 16 / openGauss 方言适配版本
- 与 `docs/design/03_Technical_Design/01_Database_Design.md` 的正式章节对齐

View File

@ -0,0 +1,53 @@
---
title: 概述与接入约定
aliases:
- 概述与接入约定
- 诺税通概述与接入约定
- 概述与接入约定索引
tags:
- water-docs
- nuoshuitong
- invoice-api
- obsidian
- moc
source_docx: ../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx
source_type: converted-and-split
---
# 概述与接入约定
> [!info] 导航
> 总索引:[[README]]
> 同级分组:[[02_开票主链路]] · [[03_作废重开与冲红]] · [[04_红字信息表]] · [[05_红字确认单]] · [[06_库存票源与打印]] · [[07_设备企业与配置]] · [[08_车辆辅助与回传]] · [[09_专项能力]] · [[10_附录_通用状态码]]
> [!abstract] 说明
> 本页作为 Obsidian MOC仅保留分组导航与接口入口接口正文已下沉为单接口一页。
## 接口入口
- [源文档封面与概述](01_概述与接入约定.md#源文档封面与概述)
- [交互说明](01_概述与接入约定.md#交互说明)
## 使用说明
- 本分组保留为概览页,适合作为首次阅读入口。
- 详细接口请从其他分组或总索引进入。
---
## 源文档封面与概述
# 概述
本文档定义了诺税通-销项服务面向第三方系统的数据协议接口,主要包括:开票请求接口、开票结果查询接口、开票结果回传等接口。
# 技术规范
## 交互说明
本文档提供的接口均为post请求方式的HTTP接口参数均以在消息主体body中以application/json方式提交即请求头中Content-Type需配置为“application/json;charset=utf-8”。
说明:限定的最大长度为字符个数(一个汉字或全角符号算两个字符),最大长度中的带小数点(.表示该字段只支持数值以不带千位分隔符的十进制浮点数表示限定总长度和最大小数位如16.2表示为-9999999999999.99到9999999999999.99的数。
# 接口列表

View File

@ -0,0 +1,37 @@
---
title: 开票主链路
aliases:
- 开票主链路
- 诺税通开票主链路
- 开票主链路索引
tags:
- water-docs
- nuoshuitong
- invoice-api
- obsidian
- moc
source_docx: ../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx
source_type: converted-and-split
---
# 开票主链路
> [!info] 导航
> 总索引:[[README]]
> 同级分组:[[01_概述与接入约定]] · [[03_作废重开与冲红]] · [[04_红字信息表]] · [[05_红字确认单]] · [[06_库存票源与打印]] · [[07_设备企业与配置]] · [[08_车辆辅助与回传]] · [[09_专项能力]] · [[10_附录_通用状态码]]
> [!abstract] 说明
> 本页作为 Obsidian MOC仅保留分组导航与接口入口接口正文已下沉为单接口一页。
## 接口入口
- [[interfaces/开票请求接口|开票请求接口]]
- [[interfaces/开票结果查询接口|开票结果查询接口]]
- [[interfaces/开票结果回传|开票结果回传]]
- [[interfaces/开票结果回传_含明细|开票结果回传(含明细)]]
- [[interfaces/发票列表查询接口|发票列表查询接口]]
- [[interfaces/发票交付|发票交付]]
## 使用说明
- 点击上方单接口页进入正文。
- 适合在 Obsidian 中作为专题 MOC 使用。

View File

@ -0,0 +1,37 @@
---
title: 作废重开与冲红
aliases:
- 作废重开与冲红
- 诺税通作废重开与冲红
- 作废重开与冲红索引
tags:
- water-docs
- nuoshuitong
- invoice-api
- obsidian
- moc
source_docx: ../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx
source_type: converted-and-split
---
# 作废重开与冲红
> [!info] 导航
> 总索引:[[README]]
> 同级分组:[[01_概述与接入约定]] · [[02_开票主链路]] · [[04_红字信息表]] · [[05_红字确认单]] · [[06_库存票源与打印]] · [[07_设备企业与配置]] · [[08_车辆辅助与回传]] · [[09_专项能力]] · [[10_附录_通用状态码]]
> [!abstract] 说明
> 本页作为 Obsidian MOC仅保留分组导航与接口入口接口正文已下沉为单接口一页。
## 接口入口
- [[interfaces/发票作废申请接口|发票作废申请接口]]
- [[interfaces/发票重开接口|发票重开接口]]
- [[interfaces/快捷冲红接口|快捷冲红接口]]
- [[interfaces/空白发票作废申请|空白发票作废申请]]
- [[interfaces/蓝字发票剩余可冲红的金额_税额查询接口|蓝字发票剩余可冲红的金额、税额查询接口]]
- [[interfaces/获取关联发票接口|获取关联发票接口]]
## 使用说明
- 点击上方单接口页进入正文。
- 适合在 Obsidian 中作为专题 MOC 使用。

View File

@ -0,0 +1,37 @@
---
title: 红字信息表
aliases:
- 红字信息表
- 诺税通红字信息表
- 红字信息表索引
tags:
- water-docs
- nuoshuitong
- invoice-api
- obsidian
- moc
source_docx: ../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx
source_type: converted-and-split
---
# 红字信息表
> [!info] 导航
> 总索引:[[README]]
> 同级分组:[[01_概述与接入约定]] · [[02_开票主链路]] · [[03_作废重开与冲红]] · [[05_红字确认单]] · [[06_库存票源与打印]] · [[07_设备企业与配置]] · [[08_车辆辅助与回传]] · [[09_专项能力]] · [[10_附录_通用状态码]]
> [!abstract] 说明
> 本页作为 Obsidian MOC仅保留分组导航与接口入口接口正文已下沉为单接口一页。
## 接口入口
- [[interfaces/红字信息表申请接口_不支持拆分_不推荐使用|红字信息表申请接口(不支持拆分,不推荐使用)]]
- [[interfaces/红字信息表申请接口_支持拆分|红字信息表申请接口(支持拆分)]]
- [[interfaces/红字信息表下载接口|红字信息表下载接口]]
- [[interfaces/红字信息表查询接口|红字信息表查询接口]]
- [[interfaces/红字信息表撤销接口|红字信息表撤销接口]]
- [[interfaces/红字信息表_红字确认单回传|红字信息表/红字确认单回传]]
## 使用说明
- 点击上方单接口页进入正文。
- 适合在 Obsidian 中作为专题 MOC 使用。

View File

@ -0,0 +1,36 @@
---
title: 红字确认单
aliases:
- 红字确认单
- 诺税通红字确认单
- 红字确认单索引
tags:
- water-docs
- nuoshuitong
- invoice-api
- obsidian
- moc
source_docx: ../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx
source_type: converted-and-split
---
# 红字确认单
> [!info] 导航
> 总索引:[[README]]
> 同级分组:[[01_概述与接入约定]] · [[02_开票主链路]] · [[03_作废重开与冲红]] · [[04_红字信息表]] · [[06_库存票源与打印]] · [[07_设备企业与配置]] · [[08_车辆辅助与回传]] · [[09_专项能力]] · [[10_附录_通用状态码]]
> [!abstract] 说明
> 本页作为 Obsidian MOC仅保留分组导航与接口入口接口正文已下沉为单接口一页。
## 接口入口
- [[interfaces/红字确认单申请接口|红字确认单申请接口]]
- [[interfaces/红字确认单下载接口|红字确认单下载接口]]
- [[interfaces/红字确认单查询接口|红字确认单查询接口]]
- [[interfaces/红字确认单确认接口|红字确认单确认接口]]
- [[interfaces/红字确认单撤销接口|红字确认单撤销接口]]
## 使用说明
- 点击上方单接口页进入正文。
- 适合在 Obsidian 中作为专题 MOC 使用。

View File

@ -0,0 +1,42 @@
---
title: 库存票源与打印
aliases:
- 库存票源与打印
- 诺税通库存票源与打印
- 库存票源与打印索引
tags:
- water-docs
- nuoshuitong
- invoice-api
- obsidian
- moc
source_docx: ../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx
source_type: converted-and-split
---
# 库存票源与打印
> [!info] 导航
> 总索引:[[README]]
> 同级分组:[[01_概述与接入约定]] · [[02_开票主链路]] · [[03_作废重开与冲红]] · [[04_红字信息表]] · [[05_红字确认单]] · [[07_设备企业与配置]] · [[08_车辆辅助与回传]] · [[09_专项能力]] · [[10_附录_通用状态码]]
> [!abstract] 说明
> 本页作为 Obsidian MOC仅保留分组导航与接口入口接口正文已下沉为单接口一页。
## 接口入口
- [[interfaces/获取纸票打印编号接口|获取纸票打印编号接口]]
- [[interfaces/获取指定票种当前代码号码|获取指定票种当前代码号码]]
- [[interfaces/获取下一张发票号码代码接口_A9机柜|获取下一张发票号码代码接口A9+机柜)]]
- [[interfaces/发票库存余量查询接口|发票库存余量查询接口]]
- [[interfaces/刷新获取开票设备实时发票库存接口|刷新获取开票设备实时发票库存接口]]
- [[interfaces/票源下载接口|票源下载接口]]
- [[interfaces/查询可下载发票库存列表接口|查询可下载发票库存列表接口]]
- [[interfaces/自定义票源下载接口|自定义票源下载接口]]
- [[interfaces/刷新可下载发票库存接口|刷新可下载发票库存接口]]
- [[interfaces/乐企查询数电库存接口|乐企查询数电库存接口]]
- [[interfaces/乐企数电发票库存申领接口|乐企数电发票库存申领接口]]
## 使用说明
- 点击上方单接口页进入正文。
- 适合在 Obsidian 中作为专题 MOC 使用。

View File

@ -0,0 +1,41 @@
---
title: 设备企业与配置
aliases:
- 设备企业与配置
- 诺税通设备企业与配置
- 设备企业与配置索引
tags:
- water-docs
- nuoshuitong
- invoice-api
- obsidian
- moc
source_docx: ../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx
source_type: converted-and-split
---
# 设备企业与配置
> [!info] 导航
> 总索引:[[README]]
> 同级分组:[[01_概述与接入约定]] · [[02_开票主链路]] · [[03_作废重开与冲红]] · [[04_红字信息表]] · [[05_红字确认单]] · [[06_库存票源与打印]] · [[08_车辆辅助与回传]] · [[09_专项能力]] · [[10_附录_通用状态码]]
> [!abstract] 说明
> 本页作为 Obsidian MOC仅保留分组导航与接口入口接口正文已下沉为单接口一页。
## 接口入口
- [[interfaces/企业设备状态查询接口|企业设备状态查询接口]]
- [[interfaces/企业设备查询接口|企业设备查询接口]]
- [[interfaces/创建开票设备接口|创建开票设备接口]]
- [[interfaces/新增_修改企业开票信息|新增/修改企业开票信息]]
- [[interfaces/录入自定义字段|录入自定义字段]]
- [[interfaces/批量获取信息转换配置接口|批量获取信息转换配置接口]]
- [[interfaces/批量获取备注配置信息接口|批量获取备注配置信息接口]]
- [[interfaces/根据业务标识查询对应值列表接口|根据业务标识查询对应值列表接口]]
- [[interfaces/获取查询数电登录认证_开票实名认证二维码|获取查询数电登录认证、开票实名认证二维码]]
- [[interfaces/登录扫码认证确认接口|登录扫码认证确认接口]]
## 使用说明
- 点击上方单接口页进入正文。
- 适合在 Obsidian 中作为专题 MOC 使用。

View File

@ -0,0 +1,40 @@
---
title: 车辆辅助与回传
aliases:
- 车辆辅助与回传
- 诺税通车辆辅助与回传
- 车辆辅助与回传索引
tags:
- water-docs
- nuoshuitong
- invoice-api
- obsidian
- moc
source_docx: ../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx
source_type: converted-and-split
---
# 车辆辅助与回传
> [!info] 导航
> 总索引:[[README]]
> 同级分组:[[01_概述与接入约定]] · [[02_开票主链路]] · [[03_作废重开与冲红]] · [[04_红字信息表]] · [[05_红字确认单]] · [[06_库存票源与打印]] · [[07_设备企业与配置]] · [[09_专项能力]] · [[10_附录_通用状态码]]
> [!abstract] 说明
> 本页作为 Obsidian MOC仅保留分组导航与接口入口接口正文已下沉为单接口一页。
## 接口入口
- [[interfaces/收票入库接口_本地提取发票|收票入库接口(本地提取发票)]]
- [[interfaces/创建_查询企业车架号_合格证状态接口|创建/查询企业车架号、合格证状态接口]]
- [[interfaces/企业车架号等信息查询结果回传接口|企业车架号等信息查询结果回传接口]]
- [[interfaces/查询获取车架号是否可开票结果接口|查询获取车架号是否可开票结果接口]]
- [[interfaces/获取DAT加密包文件流接口|获取DAT加密包文件流接口]]
- [[interfaces/更新发票票据关联状态接口|更新发票票据关联状态接口]]
- [[interfaces/删除发票信息接口|删除发票信息接口]]
- [[interfaces/审核开票删除回传接口|审核开票删除回传接口]]
- [[interfaces/批量查询发票xmlUrl接口|批量查询发票xmlUrl接口]]
## 使用说明
- 点击上方单接口页进入正文。
- 适合在 Obsidian 中作为专题 MOC 使用。

View File

@ -0,0 +1,40 @@
---
title: 专项能力
aliases:
- 专项能力
- 诺税通专项能力
- 专项能力索引
tags:
- water-docs
- nuoshuitong
- invoice-api
- obsidian
- moc
source_docx: ../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx
source_type: converted-and-split
---
# 专项能力
> [!info] 导航
> 总索引:[[README]]
> 同级分组:[[01_概述与接入约定]] · [[02_开票主链路]] · [[03_作废重开与冲红]] · [[04_红字信息表]] · [[05_红字确认单]] · [[06_库存票源与打印]] · [[07_设备企业与配置]] · [[08_车辆辅助与回传]] · [[10_附录_通用状态码]]
> [!abstract] 说明
> 本页作为 Obsidian MOC仅保留分组导航与接口入口接口正文已下沉为单接口一页。
## 接口入口
- [[interfaces/查询成品油库存列表接口|查询成品油库存列表接口]]
- [[interfaces/成品油库存下载接口|成品油库存下载接口]]
- [[interfaces/刷新获取税盘实时成品油库存接口|刷新获取税盘实时成品油库存接口]]
- [[interfaces/抄报清卡|抄报清卡]]
- [[interfaces/授信额度刷新接口|授信额度刷新接口]]
- [[interfaces/查询授信额度数据|查询授信额度数据]]
- [[interfaces/乐企授信额度下载_退回接口|乐企授信额度下载/退回接口]]
- [[interfaces/乐企授信额度更新有效期接口|乐企授信额度更新有效期接口]]
- [[interfaces/获取发票勾选入账状态接口|获取发票勾选入账状态接口]]
## 使用说明
- 点击上方单接口页进入正文。
- 适合在 Obsidian 中作为专题 MOC 使用。

View File

@ -0,0 +1,41 @@
---
title: 附录:通用状态码
aliases:
- 附录:通用状态码
- 诺税通附录:通用状态码
- 附录:通用状态码索引
tags:
- water-docs
- nuoshuitong
- invoice-api
- obsidian
- moc
source_docx: ../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx
source_type: converted-and-split
---
# 附录:通用状态码
> [!info] 导航
> 总索引:[[README]]
> 同级分组:[[01_概述与接入约定]] · [[02_开票主链路]] · [[03_作废重开与冲红]] · [[04_红字信息表]] · [[05_红字确认单]] · [[06_库存票源与打印]] · [[07_设备企业与配置]] · [[08_车辆辅助与回传]] · [[09_专项能力]]
> [!abstract] 说明
> 本页作为 Obsidian MOC仅保留分组导航与接口入口接口正文已下沉为单接口一页。
## 接口入口
- [通用状态码说明](10_附录_通用状态码.md#通用状态码说明)
## 使用说明
- 本分组保留附录全文,便于各接口页统一回查状态码。
## 通用状态码说明
| | |
|:----------:|:--------------------:|
| **状态码** | **描述** |
| 200 | 成功 |
| 501 | 请求异常或服务器异常 |
更多错误码描述可见message字段。

View File

@ -0,0 +1,147 @@
---
title: 诺税通接口枚举清单
aliases:
- 诺税通枚举清单
- 诺税通参数枚举索引
tags:
- water-docs
- nuoshuitong
- invoice-api
- obsidian
- enum-index
source_docx: ../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx
source_type: extracted-summary
---
# 诺税通接口枚举清单
> [!abstract] 说明
> 本文从诺税通销项服务接口规范中提取各接口内出现的参数枚举、状态枚举与布尔/标志位语义,便于实施时统一核对。
> 原始接口正文请进入 `interfaces/` 下的单接口页查看。
## 开票主链路
### [[interfaces/开票请求接口|开票请求接口]]
- `invoiceType`1:蓝票2:红票 | 2
- `invoiceLine`p:电子增值税普通发票c:增值税普通发票(纸票)s:增值税专用发票e:收购发票(电子)f:收购发票(纸质)b:增值税电子专用发票j机动车发票u二手车发票,bs:数电专票(电子),pc:数电普票(电子)es:数电专票(纸质)ec:数电普票(纸质) | 2
- `remark`j机动车发票时备注需注明“一车一票”否则接口会自动添加该文案 | 备注,(注意:不同开票服务器类型支持的备注长度不同,请在提交前做好确认) | 数电电票200(中文计算一位) 其他发票230(中文计算两位)
- `notifyType`-1:不推送0:邮箱1:手机(默认)2:邮箱、手机 | 2
- `listFlag`0:非清单1:清单纸票超过8行自动转成清单电票无清单概念默认都传0 | 2
- `substituteFlag`0:非代开1:代开
- `withTaxFlag`0:不含税,1:含税 | 2
- `favouredPolicyFlag`0:不使用1:使用 数电发票时为空,仅传入优惠政策编码即可 | 2
- `zeroRateFlag`1:免税2:不征税3:普通零税率favouredPolicyFlag:0 zeroRateFlag:3 favouredPolicyName: 免税时,对应传值: favouredPolicyFlag:1 zeroRateFlag:1 favouredPolicyName:“免税” 不征税,对应传值: favouredPolicyFlag:1 zeroRateFlag:2 favouredPolicyName:“不征税” | 2
### [[interfaces/开票结果查询接口|开票结果查询接口]]
- `status`0:开票中1:开票完成2:开票失败3:发票生成 | 2
- `invoiceLine`p:电子增值税普通发票c:增值税普通发票(纸票)s:增值税专用发票e:收购发票(电子)f:收购发票(纸质)r:增值税普通发票(卷式)b:增值税电子专用发票j机动车发票u二手车发票bs:数电专票(电子),pc:数电普票(电子)es:数电专票(纸质)ec:数电普票(纸质) | 2
- `productOilFlag`0:非成品油1:成品油 | 2
- `vehicleFlag`0非机动车1机动车 | 2
- `listFlag`0:非清单1:清单 | 2
- `invalidReason`1:销货退回2:开票有误3:服务中止4:其他(已作废状态下的发票,且票为数电纸票且回传其他信息时返回) | 1
- `withTaxFlag`0:不含税1:含税 | 2
- `detailType`0:正常行1:折扣行2:被折扣行 | 2
- `favouredPolicyFlag`0:不使用1:使用 | 2
- `zeroRateFlag`1:免税2:不征税3:普通零税率 | 2
### [[interfaces/开票结果回传|开票结果回传]]
- `successFlag`True:开票成功false开票失败 | 1
- `vehicleFlag`0非机动车1机动车 | 2
- `invoiceStatus`1:开票成功、 2:开票失败、3:作废成功、4:作废失败5:开票失败删除成功
- `invoiceLine`p:电子增值税普通发票c:增值税普通发票(纸票)s:增值税专用发票e:收购发票(电子)f:收购发票(纸质)r:增值税普通发票(卷式)b:增值税电子专用发票j:机动车发票u二手车发票bs:数电专票(电子),pc:数电普票(电子)es:数电专票(纸质)ec:数电普票(纸质) 仅开票成功会返回 | 2
- `relatedState`0:未关联 1:关联中 2:关联成功 3:部分关联 4:关联失败) |
- `invalidReason`1:销货退回2:开票有误3:服务中止4:其他(已作废状态下的发票,且票为数电纸票且回传其他信息时返回) | 1
### [[interfaces/开票结果回传_含明细|开票结果回传(含明细)]]
- `invoiceLine`p:电子增值税普通发票c:增值税普通发票(纸票)s:增值税专用发票e:收购发票(电子)f:收购发票(纸质)r:增值税普通发票(卷式)b:增值税电子专用发票j机动车发票u二手车发票bs:数电专票(电子),pc:数电普票(电子)es:数电专票(纸质)ec:数电普票(纸质) | 1
- `productOilFlag`0:非成品油1:成品油
- `vehicleFlag`0非机动车1机动车 | 2
- `listFlag`0非清单1清单
- `invoiceStatus`1:开票成功、 2:开票失败、3:作废成功、4:作废失败5:开票失败删除成功
- `relatedState`0:未关联 1:关联中 2:关联成功 3:部分关联 4:关联失败) |
- `invalidReason`1:销货退回2:开票有误3:服务中止4:其他(已作废状态下的发票,且票为数电纸票且回传其他信息时返回) | 1
- `withTaxFlag`1:含税0:不含税
- `detailType`0:正常行1:折扣行2:被扣行
- `zeroRateFlag`1:免税2:不征税3:普通零税率
- `favouredPolicyFlag`0:不使用1:使用
### [[interfaces/发票列表查询接口|发票列表查询接口]]
- `status`0:开票中1:开票完成2:开票失败3:发票生成 | 2
- `invoiceLine`p:电子增值税普通发票c:增值税普通发票(纸票)s:增值税专用发票e:收购发票(电子)f:收购发票(纸质)r:增值税普通发票(卷式)b:增值税电子专用发票j机动车发票u二手车发票bs:数电专票(电子),pc:数电普票(电子)es:数电专票(纸质)ec:数电普票(纸质) | 2
- `productOilFlag`0:非成品油1:成品油 | 2
- `vehicleFlag`0非机动车1机动车 | 2
- `listFlag`0:非清单1:清单 | 2
- `invalidReason`1:销货退回2:开票有误3:服务中止4:其他(已作废状态下的发票,且票为数电纸票且回传其他信息时返回) | 1
- `withTaxFlag`0:不含税1:含税 | 2
- `detailType`0:正常行1:折扣行2:被折扣行 | 2
- `favouredPolicyFlag`0:不使用1:使用 | 2
- `zeroRateFlag`1:免税2:不征税3:普通零税率 | 2
## 作废重开与冲红
### [[interfaces/快捷冲红接口|快捷冲红接口]]
- `fastRedType`1:数电发票快捷冲红(数电发票必传1) | 1
- `fastRedType`1:数电快捷冲红(数电发票必传1) | 1
## 红字信息表
### [[interfaces/红字信息表申请接口_不支持拆分_不推荐使用|红字信息表申请接口(不支持拆分,不推荐使用)]]
- `billType`0:正常 1:逾期(仅销方开具)2:机动车专票-退货和开具错误3:机动车专票-销售折让和合格证不退回)4、矿产品类专用信息表涉及销售数量和金额变更 5、矿产品类专用信息表仅涉及销售金额变更不涉及数量变动 默认为0正常 注信息表类型为2退货时信息表展示蓝票所有明细行每次提交信息表开具时不允许超过8行且不转换成固定一行明细详见正数发票及清单 若根据蓝票代码号码匹配不到对应的蓝票机动车标识billType需必填
### [[interfaces/红字信息表申请接口_支持拆分|红字信息表申请接口(支持拆分)]]
- `billType`0:正常 1:逾期(仅销方开具)2:机动车专票-退货和开具错误3:机动车专票-销售折让和合格证不退回)4、矿产品类专用信息表涉及销售数量和金额变更 5、矿产品类专用信息表仅涉及销售金额变更不涉及数量变动 默认为0正常 注信息表类型为2退货时信息表展示蓝票所有明细行每次提交信息表开具时不允许超过8行且不转换成固定一行明细详见正数发票及清单 若根据蓝票代码号码匹配不到对应的蓝票机动车标识billType需必填
### [[interfaces/红字信息表查询接口|红字信息表查询接口]]
- `billType`0:正常 1:逾期(仅销方开具)2:机动车专票-退货和开具错误3:机动车专票-销售折让和合格证不退回 4、矿产品类专用信息表涉及销售数量和金额变更 5、矿产品类专用信息表仅涉及销售金额变更不涉及数量变动 | 1
- `taxRate`0:一票一税率 1:一票多税率) | 1
- `billStatus`-1:未提交 0:申请中 1:审核成功 2:审核失败 3:申请成功 4:申请失败 5:已开具 6:撤销中 7:撤销失败 8:已撤销) | 2
### [[interfaces/红字信息表_红字确认单回传|红字信息表/红字确认单回传]]
- `backType`1: 红字信息表 2红字确认单 | 2
- `billType`0:正常 1:逾期(仅销方开具)2:机动车专票-退货和开具错误3:机动车专票-销售折让和合格证不退回 4、矿产品类专用信息表涉及销售数量和金额变更 5、矿产品类专用信息表仅涉及销售金额变更不涉及数量变动 | 1
- `billStatus`-1:未提交 0:申请中 1:审核成功 2:审核失败 3:申请成功 4:申请失败 5:已开具 6:撤销中 7:撤销失败 8:已撤销 -2:删除成功) | 2
- `backType`1: 红字信息表 2红字确认单 | 2
- `openStatus`0未开具 1已开具 | 2
- `blueInvoiceLine`bs:数电专票(电子),pc:数电普票(电子)es:数电专票(纸质)ec:数电普票(纸质) p:电子增值税普通发票, c:增值税普通发票(纸票) s:增值税专用发票, b:增值税电子专用发票 | 5
## 红字确认单
### [[interfaces/红字确认单申请接口|红字确认单申请接口]]
- `blueInvoiceLine`bs:数电专票(电子), pc:数电普票(电子) es:数电专票(纸质)ec:数电普票(纸质) p:电子增值税普通发票, c:增值税普通发票(纸票) s:增值税专用发票, b:增值税电子专用发票 | 5
- `withTaxFlag`0:不含税,1:含税 | 1
- `zeroRateFlag`1:免税2:不征税3:普通零税率 | 2
### [[interfaces/红字确认单下载接口|红字确认单下载接口]]
- `billStatus`1我是购买方时必填 确认单状态0.待确认 1.已确认 2.已过期 3.销方否认 4.已撤销 | 4
### [[interfaces/红字确认单查询接口|红字确认单查询接口]]
- `openStatus`0未开具 1已开具 | 2
- `blueInvoiceLine`bs:数电专票(电子),pc:数电普票(电子)es:数电专票(纸质)ec:数电普票(纸质) p:电子增值税普通发票, c:增值税普通发票(纸票) s:增值税专用发票, b:增值税电子专用发票 | 5
## 设备企业与配置
### [[interfaces/创建开票设备接口|创建开票设备接口]]
- `serverType`1:C48, 11:诺诺开票, 14A9, 15:四川税局代开, 17:诺诺机柜, 18:税控服务器, 20:单机版, 22:数电发票开票模式(通用版), 24:数电发票开票模式(单机版), 25:数电发票开票模式(机柜版) 数电单机版和机柜版暂只支持半本地环境 | 4
- `invoiceTypelist`p:电子增值税普通发票c:增值税普通发票(纸票)s:增值税专用发票e:收购发票(电子)f:收购发票(纸质)b:增值税电子专用发票j机动车发票u二手车发票,bs:数电专票(电子),pc:数电普票(电子)es:数电专票(纸质)ec:数电普票(纸质) | -
## 车辆辅助与回传
### [[interfaces/收票入库接口_本地提取发票|收票入库接口(本地提取发票)]]
- `invoiceType`1蓝票2红票
- `withTaxFlag`0:不含税,1:含税

View File

@ -0,0 +1,341 @@
---
title: 诺税通标准枚举字典
aliases:
- 诺税通枚举字典
- 诺税通字段级枚举表
tags:
- water-docs
- nuoshuitong
- invoice-api
- obsidian
- enum-dictionary
source_docx: ../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx
source_type: normalized-from-enum-index
---
# 诺税通标准枚举字典
> [!abstract] 说明
> 本文对 `11_枚举清单.md` 中跨接口重复出现的枚举字段进行字段级归并,便于实施时统一理解与复用。
> 若同一字段在不同接口中存在补充说明或口径差异,均在“来源接口”中保留。
## 快速导航
- [[#`invoiceLine`|`invoiceLine`]]
- [[#`invoiceType`|`invoiceType`]]
- [[#`status`|`status`]]
- [[#`invoiceStatus`|`invoiceStatus`]]
- [[#`billStatus`|`billStatus`]]
- [[#`billType`|`billType`]]
- [[#`withTaxFlag`|`withTaxFlag`]]
- [[#`listFlag`|`listFlag`]]
- [[#`detailType`|`detailType`]]
- [[#`invalidReason`|`invalidReason`]]
- [[#`notifyType`|`notifyType`]]
- [[#`vehicleFlag`|`vehicleFlag`]]
- [[#`productOilFlag`|`productOilFlag`]]
- [[#`zeroRateFlag`|`zeroRateFlag`]]
- [[#`favouredPolicyFlag`|`favouredPolicyFlag`]]
- [[#`backType`|`backType`]]
- [[#`openStatus`|`openStatus`]]
- [[#`serverType`|`serverType`]]
- [[#`fastRedType`|`fastRedType`]]
- [[#`taxRate`|`taxRate`]]
- [[#`relatedState`|`relatedState`]]
- [[#`successFlag`|`successFlag`]]
- [[#`substituteFlag`|`substituteFlag`]]
- [[#`blueInvoiceLine`|`blueInvoiceLine`]]
- [[#`invoiceTypelist`|`invoiceTypelist`]]
- [[#`remark`|`remark`]]
## `invoiceLine`
> [!summary] 标准口径
> - p:电子增值税普通发票c:增值税普通发票(纸票)s:增值税专用发票e:收购发票(电子)f:收购发票(纸质)b:增值税电子专用发票j机动车发票u二手车发票,bs:数电专票(电子),pc:数电普票(电子)es:数电专票(纸质)ec:数电普票(纸质)
> - p:电子增值税普通发票c:增值税普通发票(纸票)s:增值税专用发票e:收购发票(电子)f:收购发票(纸质)r:增值税普通发票(卷式)b:增值税电子专用发票j机动车发票u二手车发票bs:数电专票(电子),pc:数电普票(电子)es:数电专票(纸质)ec:数电普票(纸质)
> - p:电子增值税普通发票c:增值税普通发票(纸票)s:增值税专用发票e:收购发票(电子)f:收购发票(纸质)r:增值税普通发票(卷式)b:增值税电子专用发票j:机动车发票u二手车发票bs:数电专票(电子),pc:数电普票(电子)es:数电专票(纸质)ec:数电普票(纸质) 仅开票成功会返回
> - p:电子增值税普通发票c:增值税普通发票(纸票)s:增值税专用发票e:收购发票(电子)f:收购发票(纸质)r:增值税普通发票(卷式)b:增值税电子专用发票j机动车发票u二手车发票bs:数电专票(电子),pc:数电普票(电子)es:数电专票(纸质)ec:数电普票(纸质)
### 来源接口
- **开票主链路 / [[interfaces/开票请求接口|开票请求接口]]**p:电子增值税普通发票c:增值税普通发票(纸票)s:增值税专用发票e:收购发票(电子)f:收购发票(纸质)b:增值税电子专用发票j机动车发票u二手车发票,bs:数电专票(电子),pc:数电普票(电子)es:数电专票(纸质)ec:数电普票(纸质)
- **开票主链路 / [[interfaces/开票结果查询接口|开票结果查询接口]]**p:电子增值税普通发票c:增值税普通发票(纸票)s:增值税专用发票e:收购发票(电子)f:收购发票(纸质)r:增值税普通发票(卷式)b:增值税电子专用发票j机动车发票u二手车发票bs:数电专票(电子),pc:数电普票(电子)es:数电专票(纸质)ec:数电普票(纸质)
- **开票主链路 / [[interfaces/开票结果回传|开票结果回传]]**p:电子增值税普通发票c:增值税普通发票(纸票)s:增值税专用发票e:收购发票(电子)f:收购发票(纸质)r:增值税普通发票(卷式)b:增值税电子专用发票j:机动车发票u二手车发票bs:数电专票(电子),pc:数电普票(电子)es:数电专票(纸质)ec:数电普票(纸质) 仅开票成功会返回
- **开票主链路 / [[interfaces/开票结果回传_含明细|开票结果回传(含明细)]]**p:电子增值税普通发票c:增值税普通发票(纸票)s:增值税专用发票e:收购发票(电子)f:收购发票(纸质)r:增值税普通发票(卷式)b:增值税电子专用发票j机动车发票u二手车发票bs:数电专票(电子),pc:数电普票(电子)es:数电专票(纸质)ec:数电普票(纸质)
- **开票主链路 / [[interfaces/发票列表查询接口|发票列表查询接口]]**p:电子增值税普通发票c:增值税普通发票(纸票)s:增值税专用发票e:收购发票(电子)f:收购发票(纸质)r:增值税普通发票(卷式)b:增值税电子专用发票j机动车发票u二手车发票bs:数电专票(电子),pc:数电普票(电子)es:数电专票(纸质)ec:数电普票(纸质)
## `invoiceType`
> [!summary] 标准口径
> - 1:蓝票2:红票
> - 1蓝票2红票
### 来源接口
- **开票主链路 / [[interfaces/开票请求接口|开票请求接口]]**1:蓝票2:红票
- **车辆辅助与回传 / [[interfaces/收票入库接口_本地提取发票|收票入库接口(本地提取发票)]]**1蓝票2红票
## `status`
> [!summary] 标准口径
> - 0:开票中1:开票完成2:开票失败3:发票生成
### 来源接口
- **开票主链路 / [[interfaces/开票结果查询接口|开票结果查询接口]]**0:开票中1:开票完成2:开票失败3:发票生成
- **开票主链路 / [[interfaces/发票列表查询接口|发票列表查询接口]]**0:开票中1:开票完成2:开票失败3:发票生成
## `invoiceStatus`
> [!summary] 标准口径
> - 1:开票成功、 2:开票失败、3:作废成功、4:作废失败5:开票失败删除成功
### 来源接口
- **开票主链路 / [[interfaces/开票结果回传|开票结果回传]]**1:开票成功、 2:开票失败、3:作废成功、4:作废失败5:开票失败删除成功
- **开票主链路 / [[interfaces/开票结果回传_含明细|开票结果回传(含明细)]]**1:开票成功、 2:开票失败、3:作废成功、4:作废失败5:开票失败删除成功
## `billStatus`
> [!summary] 标准口径
> - -1:未提交 0:申请中 1:审核成功 2:审核失败 3:申请成功 4:申请失败 5:已开具 6:撤销中 7:撤销失败 8:已撤销)
> - -1:未提交 0:申请中 1:审核成功 2:审核失败 3:申请成功 4:申请失败 5:已开具 6:撤销中 7:撤销失败 8:已撤销 -2:删除成功)
> - 1我是购买方时必填 确认单状态0.待确认 1.已确认 2.已过期 3.销方否认 4.已撤销
### 来源接口
- **红字信息表 / [[interfaces/红字信息表查询接口|红字信息表查询接口]]**-1:未提交 0:申请中 1:审核成功 2:审核失败 3:申请成功 4:申请失败 5:已开具 6:撤销中 7:撤销失败 8:已撤销)
- **红字信息表 / [[interfaces/红字信息表_红字确认单回传|红字信息表/红字确认单回传]]**-1:未提交 0:申请中 1:审核成功 2:审核失败 3:申请成功 4:申请失败 5:已开具 6:撤销中 7:撤销失败 8:已撤销 -2:删除成功)
- **红字确认单 / [[interfaces/红字确认单下载接口|红字确认单下载接口]]**1我是购买方时必填 确认单状态0.待确认 1.已确认 2.已过期 3.销方否认 4.已撤销
## `billType`
> [!summary] 标准口径
> - 0:正常 1:逾期(仅销方开具)2:机动车专票-退货和开具错误3:机动车专票-销售折让和合格证不退回)4、矿产品类专用信息表涉及销售数量和金额变更 5、矿产品类专用信息表仅涉及销售金额变更不涉及数量变动 默认为0正常 注信息表类型为2退货时信息表展示蓝票所有明细行每次提交信息表开具时不允许超过8行且不转换成固定一行明细详见正数发票及清单 若根据蓝票代码号码匹配不到对应的蓝票机动车标识billType需必填
> - 0:正常 1:逾期(仅销方开具)2:机动车专票-退货和开具错误3:机动车专票-销售折让和合格证不退回 4、矿产品类专用信息表涉及销售数量和金额变更 5、矿产品类专用信息表仅涉及销售金额变更不涉及数量变动
### 来源接口
- **红字信息表 / [[interfaces/红字信息表申请接口_不支持拆分_不推荐使用|红字信息表申请接口(不支持拆分,不推荐使用)]]**0:正常 1:逾期(仅销方开具)2:机动车专票-退货和开具错误3:机动车专票-销售折让和合格证不退回)4、矿产品类专用信息表涉及销售数量和金额变更 5、矿产品类专用信息表仅涉及销售金额变更不涉及数量变动 默认为0正常 注信息表类型为2退货时信息表展示蓝票所有明细行每次提交信息表开具时不允许超过8行且不转换成固定一行明细详见正数发票及清单 若根据蓝票代码号码匹配不到对应的蓝票机动车标识billType需必填
- **红字信息表 / [[interfaces/红字信息表申请接口_支持拆分|红字信息表申请接口(支持拆分)]]**0:正常 1:逾期(仅销方开具)2:机动车专票-退货和开具错误3:机动车专票-销售折让和合格证不退回)4、矿产品类专用信息表涉及销售数量和金额变更 5、矿产品类专用信息表仅涉及销售金额变更不涉及数量变动 默认为0正常 注信息表类型为2退货时信息表展示蓝票所有明细行每次提交信息表开具时不允许超过8行且不转换成固定一行明细详见正数发票及清单 若根据蓝票代码号码匹配不到对应的蓝票机动车标识billType需必填
- **红字信息表 / [[interfaces/红字信息表查询接口|红字信息表查询接口]]**0:正常 1:逾期(仅销方开具)2:机动车专票-退货和开具错误3:机动车专票-销售折让和合格证不退回 4、矿产品类专用信息表涉及销售数量和金额变更 5、矿产品类专用信息表仅涉及销售金额变更不涉及数量变动
- **红字信息表 / [[interfaces/红字信息表_红字确认单回传|红字信息表/红字确认单回传]]**0:正常 1:逾期(仅销方开具)2:机动车专票-退货和开具错误3:机动车专票-销售折让和合格证不退回 4、矿产品类专用信息表涉及销售数量和金额变更 5、矿产品类专用信息表仅涉及销售金额变更不涉及数量变动
## `withTaxFlag`
> [!summary] 标准口径
> - 0:不含税,1:含税
> - 0:不含税1:含税
> - 1:含税0:不含税
### 来源接口
- **开票主链路 / [[interfaces/开票请求接口|开票请求接口]]**0:不含税,1:含税
- **开票主链路 / [[interfaces/开票结果查询接口|开票结果查询接口]]**0:不含税1:含税
- **开票主链路 / [[interfaces/开票结果回传_含明细|开票结果回传(含明细)]]**1:含税0:不含税
- **开票主链路 / [[interfaces/发票列表查询接口|发票列表查询接口]]**0:不含税1:含税
- **红字确认单 / [[interfaces/红字确认单申请接口|红字确认单申请接口]]**0:不含税,1:含税
- **车辆辅助与回传 / [[interfaces/收票入库接口_本地提取发票|收票入库接口(本地提取发票)]]**0:不含税,1:含税
## `listFlag`
> [!summary] 标准口径
> - 0:非清单1:清单纸票超过8行自动转成清单电票无清单概念默认都传0
> - 0:非清单1:清单
> - 0非清单1清单
### 来源接口
- **开票主链路 / [[interfaces/开票请求接口|开票请求接口]]**0:非清单1:清单纸票超过8行自动转成清单电票无清单概念默认都传0
- **开票主链路 / [[interfaces/开票结果查询接口|开票结果查询接口]]**0:非清单1:清单
- **开票主链路 / [[interfaces/开票结果回传_含明细|开票结果回传(含明细)]]**0非清单1清单
- **开票主链路 / [[interfaces/发票列表查询接口|发票列表查询接口]]**0:非清单1:清单
## `detailType`
> [!summary] 标准口径
> - 0:正常行1:折扣行2:被折扣行
> - 0:正常行1:折扣行2:被扣行
### 来源接口
- **开票主链路 / [[interfaces/开票结果查询接口|开票结果查询接口]]**0:正常行1:折扣行2:被折扣行
- **开票主链路 / [[interfaces/开票结果回传_含明细|开票结果回传(含明细)]]**0:正常行1:折扣行2:被扣行
- **开票主链路 / [[interfaces/发票列表查询接口|发票列表查询接口]]**0:正常行1:折扣行2:被折扣行
## `invalidReason`
> [!summary] 标准口径
> - 1:销货退回2:开票有误3:服务中止4:其他(已作废状态下的发票,且票为数电纸票且回传其他信息时返回)
### 来源接口
- **开票主链路 / [[interfaces/开票结果查询接口|开票结果查询接口]]**1:销货退回2:开票有误3:服务中止4:其他(已作废状态下的发票,且票为数电纸票且回传其他信息时返回)
- **开票主链路 / [[interfaces/开票结果回传|开票结果回传]]**1:销货退回2:开票有误3:服务中止4:其他(已作废状态下的发票,且票为数电纸票且回传其他信息时返回)
- **开票主链路 / [[interfaces/开票结果回传_含明细|开票结果回传(含明细)]]**1:销货退回2:开票有误3:服务中止4:其他(已作废状态下的发票,且票为数电纸票且回传其他信息时返回)
- **开票主链路 / [[interfaces/发票列表查询接口|发票列表查询接口]]**1:销货退回2:开票有误3:服务中止4:其他(已作废状态下的发票,且票为数电纸票且回传其他信息时返回)
## `notifyType`
> [!summary] 标准口径
> - -1:不推送0:邮箱1:手机(默认)2:邮箱、手机
### 来源接口
- **开票主链路 / [[interfaces/开票请求接口|开票请求接口]]**-1:不推送0:邮箱1:手机(默认)2:邮箱、手机
## `vehicleFlag`
> [!summary] 标准口径
> - 0非机动车1机动车
### 来源接口
- **开票主链路 / [[interfaces/开票结果查询接口|开票结果查询接口]]**0非机动车1机动车
- **开票主链路 / [[interfaces/开票结果回传|开票结果回传]]**0非机动车1机动车
- **开票主链路 / [[interfaces/开票结果回传_含明细|开票结果回传(含明细)]]**0非机动车1机动车
- **开票主链路 / [[interfaces/发票列表查询接口|发票列表查询接口]]**0非机动车1机动车
## `productOilFlag`
> [!summary] 标准口径
> - 0:非成品油1:成品油
### 来源接口
- **开票主链路 / [[interfaces/开票结果查询接口|开票结果查询接口]]**0:非成品油1:成品油
- **开票主链路 / [[interfaces/开票结果回传_含明细|开票结果回传(含明细)]]**0:非成品油1:成品油
- **开票主链路 / [[interfaces/发票列表查询接口|发票列表查询接口]]**0:非成品油1:成品油
## `zeroRateFlag`
> [!summary] 标准口径
> - 1:免税2:不征税3:普通零税率favouredPolicyFlag:0 zeroRateFlag:3 favouredPolicyName: 免税时,对应传值: favouredPolicyFlag:1 zeroRateFlag:1 favouredPolicyName:“免税” 不征税,对应传值: favouredPolicyFlag:1 zeroRateFlag:2 favouredPolicyName:“不征税”
> - 1:免税2:不征税3:普通零税率
### 来源接口
- **开票主链路 / [[interfaces/开票请求接口|开票请求接口]]**1:免税2:不征税3:普通零税率favouredPolicyFlag:0 zeroRateFlag:3 favouredPolicyName: 免税时,对应传值: favouredPolicyFlag:1 zeroRateFlag:1 favouredPolicyName:“免税” 不征税,对应传值: favouredPolicyFlag:1 zeroRateFlag:2 favouredPolicyName:“不征税”
- **开票主链路 / [[interfaces/开票结果查询接口|开票结果查询接口]]**1:免税2:不征税3:普通零税率
- **开票主链路 / [[interfaces/开票结果回传_含明细|开票结果回传(含明细)]]**1:免税2:不征税3:普通零税率
- **开票主链路 / [[interfaces/发票列表查询接口|发票列表查询接口]]**1:免税2:不征税3:普通零税率
- **红字确认单 / [[interfaces/红字确认单申请接口|红字确认单申请接口]]**1:免税2:不征税3:普通零税率
## `favouredPolicyFlag`
> [!summary] 标准口径
> - 0:不使用1:使用 数电发票时为空,仅传入优惠政策编码即可
> - 0:不使用1:使用
### 来源接口
- **开票主链路 / [[interfaces/开票请求接口|开票请求接口]]**0:不使用1:使用 数电发票时为空,仅传入优惠政策编码即可
- **开票主链路 / [[interfaces/开票结果查询接口|开票结果查询接口]]**0:不使用1:使用
- **开票主链路 / [[interfaces/开票结果回传_含明细|开票结果回传(含明细)]]**0:不使用1:使用
- **开票主链路 / [[interfaces/发票列表查询接口|发票列表查询接口]]**0:不使用1:使用
## `backType`
> [!summary] 标准口径
> - 1: 红字信息表 2红字确认单
### 来源接口
- **红字信息表 / [[interfaces/红字信息表_红字确认单回传|红字信息表/红字确认单回传]]**1: 红字信息表 2红字确认单
## `openStatus`
> [!summary] 标准口径
> - 0未开具 1已开具
### 来源接口
- **红字信息表 / [[interfaces/红字信息表_红字确认单回传|红字信息表/红字确认单回传]]**0未开具 1已开具
- **红字确认单 / [[interfaces/红字确认单查询接口|红字确认单查询接口]]**0未开具 1已开具
## `serverType`
> [!summary] 标准口径
> - 1:C48, 11:诺诺开票, 14A9, 15:四川税局代开, 17:诺诺机柜, 18:税控服务器, 20:单机版, 22:数电发票开票模式(通用版), 24:数电发票开票模式(单机版), 25:数电发票开票模式(机柜版) 数电单机版和机柜版暂只支持半本地环境
### 来源接口
- **设备企业与配置 / [[interfaces/创建开票设备接口|创建开票设备接口]]**1:C48, 11:诺诺开票, 14A9, 15:四川税局代开, 17:诺诺机柜, 18:税控服务器, 20:单机版, 22:数电发票开票模式(通用版), 24:数电发票开票模式(单机版), 25:数电发票开票模式(机柜版) 数电单机版和机柜版暂只支持半本地环境
## `fastRedType`
> [!summary] 标准口径
> - 1:数电发票快捷冲红(数电发票必传1)
> - 1:数电快捷冲红(数电发票必传1)
### 来源接口
- **作废重开与冲红 / [[interfaces/快捷冲红接口|快捷冲红接口]]**1:数电快捷冲红(数电发票必传1)
## `taxRate`
> [!summary] 标准口径
> - 0:一票一税率 1:一票多税率)
### 来源接口
- **红字信息表 / [[interfaces/红字信息表查询接口|红字信息表查询接口]]**0:一票一税率 1:一票多税率)
## `relatedState`
> [!summary] 标准口径
> - 0:未关联 1:关联中 2:关联成功 3:部分关联 4:关联失败) |
### 来源接口
- **开票主链路 / [[interfaces/开票结果回传|开票结果回传]]**0:未关联 1:关联中 2:关联成功 3:部分关联 4:关联失败) |
- **开票主链路 / [[interfaces/开票结果回传_含明细|开票结果回传(含明细)]]**0:未关联 1:关联中 2:关联成功 3:部分关联 4:关联失败) |
## `successFlag`
> [!summary] 标准口径
> - True:开票成功false开票失败
### 来源接口
- **开票主链路 / [[interfaces/开票结果回传|开票结果回传]]**True:开票成功false开票失败
## `substituteFlag`
> [!summary] 标准口径
> - 0:非代开1:代开
### 来源接口
- **开票主链路 / [[interfaces/开票请求接口|开票请求接口]]**0:非代开1:代开
## `blueInvoiceLine`
> [!summary] 标准口径
> - bs:数电专票(电子),pc:数电普票(电子)es:数电专票(纸质)ec:数电普票(纸质) p:电子增值税普通发票, c:增值税普通发票(纸票) s:增值税专用发票, b:增值税电子专用发票
> - bs:数电专票(电子), pc:数电普票(电子) es:数电专票(纸质)ec:数电普票(纸质) p:电子增值税普通发票, c:增值税普通发票(纸票) s:增值税专用发票, b:增值税电子专用发票
### 来源接口
- **红字信息表 / [[interfaces/红字信息表_红字确认单回传|红字信息表/红字确认单回传]]**bs:数电专票(电子),pc:数电普票(电子)es:数电专票(纸质)ec:数电普票(纸质) p:电子增值税普通发票, c:增值税普通发票(纸票) s:增值税专用发票, b:增值税电子专用发票
- **红字确认单 / [[interfaces/红字确认单申请接口|红字确认单申请接口]]**bs:数电专票(电子), pc:数电普票(电子) es:数电专票(纸质)ec:数电普票(纸质) p:电子增值税普通发票, c:增值税普通发票(纸票) s:增值税专用发票, b:增值税电子专用发票
- **红字确认单 / [[interfaces/红字确认单查询接口|红字确认单查询接口]]**bs:数电专票(电子),pc:数电普票(电子)es:数电专票(纸质)ec:数电普票(纸质) p:电子增值税普通发票, c:增值税普通发票(纸票) s:增值税专用发票, b:增值税电子专用发票
## `invoiceTypelist`
> [!summary] 标准口径
> - p:电子增值税普通发票c:增值税普通发票(纸票)s:增值税专用发票e:收购发票(电子)f:收购发票(纸质)b:增值税电子专用发票j机动车发票u二手车发票,bs:数电专票(电子),pc:数电普票(电子)es:数电专票(纸质)ec:数电普票(纸质)
### 来源接口
- **设备企业与配置 / [[interfaces/创建开票设备接口|创建开票设备接口]]**p:电子增值税普通发票c:增值税普通发票(纸票)s:增值税专用发票e:收购发票(电子)f:收购发票(纸质)b:增值税电子专用发票j机动车发票u二手车发票,bs:数电专票(电子),pc:数电普票(电子)es:数电专票(纸质)ec:数电普票(纸质)
## `remark`
> [!summary] 标准口径
> - j机动车发票时备注需注明“一车一票”否则接口会自动添加该文案 | 备注,(注意:不同开票服务器类型支持的备注长度不同,请在提交前做好确认) | 数电电票200(中文计算一位) 其他发票230(中文计算两位)
### 来源接口
- **开票主链路 / [[interfaces/开票请求接口|开票请求接口]]**j机动车发票时备注需注明“一车一票”否则接口会自动添加该文案 | 备注,(注意:不同开票服务器类型支持的备注长度不同,请在提交前做好确认) | 数电电票200(中文计算一位) 其他发票230(中文计算两位)

View File

@ -0,0 +1,130 @@
---
title: 诺税通销项服务接口规范索引
aliases:
- 诺税通销项接口规范
- 诺税通销项服务接口目录
tags:
- water-docs
- nuoshuitong
- invoice-api
- obsidian
- moc
source_docx: ../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx
source_type: converted-and-split
---
# 诺税通销项服务接口规范索引
> [!abstract] 文档说明
> 本目录为 `诺诺网-诺税通销项服务对外接口规范v1.3.18.docx` 的 Markdown 转换结果,已进一步拆分为“单接口一页”。
> 适用于 Obsidian 检索、双链浏览与专题整理。
> 原始来源:[诺诺网-诺税通销项服务对外接口规范v1.3.18.docx](../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx)
> 配套实施清单:[NUOSHUITONG_SAAS_INTEGRATION_CHECKLIST.md](../NUOSHUITONG_SAAS_INTEGRATION_CHECKLIST.md)
## 分组导航
- [[01_概述与接入约定]]
- [[02_开票主链路]]
- [[03_作废重开与冲红]]
- [[04_红字信息表]]
- [[05_红字确认单]]
- [[06_库存票源与打印]]
- [[07_设备企业与配置]]
- [[08_车辆辅助与回传]]
- [[09_专项能力]]
- [[10_附录_通用状态码]]
- [[11_枚举清单]]
- [[12_标准枚举字典]]
## 单接口索引
### 开票主链路
- [[interfaces/开票请求接口|开票请求接口]]
- [[interfaces/开票结果查询接口|开票结果查询接口]]
- [[interfaces/开票结果回传|开票结果回传]]
- [[interfaces/开票结果回传_含明细|开票结果回传(含明细)]]
- [[interfaces/发票列表查询接口|发票列表查询接口]]
- [[interfaces/发票交付|发票交付]]
### 作废重开与冲红
- [[interfaces/发票作废申请接口|发票作废申请接口]]
- [[interfaces/发票重开接口|发票重开接口]]
- [[interfaces/获取关联发票接口|获取关联发票接口]]
- [[interfaces/快捷冲红接口|快捷冲红接口]]
- [[interfaces/空白发票作废申请|空白发票作废申请]]
- [[interfaces/蓝字发票剩余可冲红的金额_税额查询接口|蓝字发票剩余可冲红的金额、税额查询接口]]
### 红字信息表
- [[interfaces/红字信息表申请接口_不支持拆分_不推荐使用|红字信息表申请接口(不支持拆分,不推荐使用)]]
- [[interfaces/红字信息表申请接口_支持拆分|红字信息表申请接口(支持拆分)]]
- [[interfaces/红字信息表下载接口|红字信息表下载接口]]
- [[interfaces/红字信息表查询接口|红字信息表查询接口]]
- [[interfaces/红字信息表撤销接口|红字信息表撤销接口]]
- [[interfaces/红字信息表_红字确认单回传|红字信息表/红字确认单回传]]
### 红字确认单
- [[interfaces/红字确认单申请接口|红字确认单申请接口]]
- [[interfaces/红字确认单下载接口|红字确认单下载接口]]
- [[interfaces/红字确认单查询接口|红字确认单查询接口]]
- [[interfaces/红字确认单确认接口|红字确认单确认接口]]
- [[interfaces/红字确认单撤销接口|红字确认单撤销接口]]
### 库存票源与打印
- [[interfaces/获取纸票打印编号接口|获取纸票打印编号接口]]
- [[interfaces/获取指定票种当前代码号码|获取指定票种当前代码号码]]
- [[interfaces/发票库存余量查询接口|发票库存余量查询接口]]
- [[interfaces/刷新获取开票设备实时发票库存接口|刷新获取开票设备实时发票库存接口]]
- [[interfaces/获取下一张发票号码代码接口_A9机柜|获取下一张发票号码代码接口A9+机柜)]]
- [[interfaces/票源下载接口|票源下载接口]]
- [[interfaces/查询可下载发票库存列表接口|查询可下载发票库存列表接口]]
- [[interfaces/自定义票源下载接口|自定义票源下载接口]]
- [[interfaces/刷新可下载发票库存接口|刷新可下载发票库存接口]]
- [[interfaces/乐企查询数电库存接口|乐企查询数电库存接口]]
- [[interfaces/乐企数电发票库存申领接口|乐企数电发票库存申领接口]]
### 设备企业与配置
- [[interfaces/企业设备状态查询接口|企业设备状态查询接口]]
- [[interfaces/新增_修改企业开票信息|新增/修改企业开票信息]]
- [[interfaces/批量获取信息转换配置接口|批量获取信息转换配置接口]]
- [[interfaces/批量获取备注配置信息接口|批量获取备注配置信息接口]]
- [[interfaces/根据业务标识查询对应值列表接口|根据业务标识查询对应值列表接口]]
- [[interfaces/企业设备查询接口|企业设备查询接口]]
- [[interfaces/创建开票设备接口|创建开票设备接口]]
- [[interfaces/录入自定义字段|录入自定义字段]]
- [[interfaces/获取查询数电登录认证_开票实名认证二维码|获取查询数电登录认证、开票实名认证二维码]]
- [[interfaces/登录扫码认证确认接口|登录扫码认证确认接口]]
### 车辆辅助与回传
- [[interfaces/收票入库接口_本地提取发票|收票入库接口(本地提取发票)]]
- [[interfaces/创建_查询企业车架号_合格证状态接口|创建/查询企业车架号、合格证状态接口]]
- [[interfaces/企业车架号等信息查询结果回传接口|企业车架号等信息查询结果回传接口]]
- [[interfaces/获取DAT加密包文件流接口|获取DAT加密包文件流接口]]
- [[interfaces/更新发票票据关联状态接口|更新发票票据关联状态接口]]
- [[interfaces/查询获取车架号是否可开票结果接口|查询获取车架号是否可开票结果接口]]
- [[interfaces/删除发票信息接口|删除发票信息接口]]
- [[interfaces/审核开票删除回传接口|审核开票删除回传接口]]
- [[interfaces/批量查询发票xmlUrl接口|批量查询发票xmlUrl接口]]
### 专项能力
- [[interfaces/查询成品油库存列表接口|查询成品油库存列表接口]]
- [[interfaces/成品油库存下载接口|成品油库存下载接口]]
- [[interfaces/刷新获取税盘实时成品油库存接口|刷新获取税盘实时成品油库存接口]]
- [[interfaces/抄报清卡|抄报清卡]]
- [[interfaces/授信额度刷新接口|授信额度刷新接口]]
- [[interfaces/查询授信额度数据|查询授信额度数据]]
- [[interfaces/乐企授信额度下载_退回接口|乐企授信额度下载/退回接口]]
- [[interfaces/乐企授信额度更新有效期接口|乐企授信额度更新有效期接口]]
- [[interfaces/获取发票勾选入账状态接口|获取发票勾选入账状态接口]]
## 使用建议
- 先阅读 [[01_概述与接入约定]] 了解整体交互方式。
- 再按业务主题进入分组 MOC最终跳转到 `interfaces/` 下的单接口笔记。
- 若需实施口径,请同步参照 `NUOSHUITONG_SAAS_INTEGRATION_CHECKLIST.md`

View File

@ -0,0 +1,106 @@
---
title: 乐企授信额度下载/退回接口
aliases:
- 乐企授信额度下载/退回接口
- 诺税通乐企授信额度下载/退回接口
- 专项能力-乐企授信额度下载/退回接口
tags:
- water-docs
- nuoshuitong
- invoice-api
- obsidian
- single-interface
source_docx: ../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx
source_type: converted-and-split
---
# 乐企授信额度下载/退回接口
> [!info] 导航
> 上级索引:[[README]] · [[09_专项能力]]
> 文档链接:[总索引](../README.md) · [分组页](../09_专项能力.md) · [实施清单](../../NUOSHUITONG_SAAS_INTEGRATION_CHECKLIST.md)
> [!note] 来源
> 来源原件:[诺诺网-诺税通销项服务对外接口规范v1.3.18.docx](../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx)
> 接口分组:[[09_专项能力]]
## 字段摘要
> [!summary] 接口元信息
> - 接口地址:`http[s]://\<host\>[:\<port\>]/salescore/lan/creditQuota/downloadOrReturn.do`
> - 请求方式:`POST`
> - 是否回调:否
> - 是否主链路:否
> - 推荐优先级:扩展/按需
## 乐企授信额度下载/退回接口
### 接口说明
乐企模式授信额度下载\退回接口,调用该接口时,需保证对应企业税号查询过授信额度。
### 接口地址
| |
|:---|
| http\[s\]://\<host\>\[:\<port\>\]/salescore/lan/creditQuota/downloadOrReturn.do |
### 请求参数
| | | | | | |
|:--:|:--:|:--:|:--:|:--:|:--:|
| **名称** | **类型** | **必填** | **说明** | **描述** | **长度** |
| taxNum | String | 是 | 需要查询的企业税号 | 企业税号 | 20 |
| amount | BigDecimal | 是 | 需要下载\退回的金额,只能为正数数字 | 处理额度 | (12,2) |
| type | Integer | 是 | 0:下载 1:退回 | 请求类型 | 1 |
### 请求示例
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td style="text-align: left;"><p>{</p>
<p>"taxNum": "150301199811285326",</p>
<p>"amount": 100,</p>
<p>"type": 1</p>
<p>}</p></td>
</tr>
</tbody>
</table>
### 返回参数
| | | | | | |
|:--:|:--:|:--:|:--:|:--:|:--:|
| **名称** | **类型** | **必填** | **示例值** | **描述** | **长度** |
| code | Integer | 是 | 200 | 状态,200-成功非200-失败 | 6 |
| message | String | 是 | 成功 | 详细信息 | 1024 |
| data | Object | 是 | | 查询对象 | |
| vestPeriodBegin | Date | 是 | 2023-03-01 00:00:00 | 授信额度使用区间起 | \- |
| vestPeriodEnd | Date | 是 | 2023-03-31 00:00:00 | 授信额度使用区间止 | \- |
### 返回示例
成功示例:
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td><p>{</p>
<p>"code": 200,</p>
<p>"message": "成功",</p>
<p>"data": {</p>
<p>"vestPeriodBegin": "2023-03-01 00:00:00",</p>
<p>"vestPeriodEnd": "2023-03-31 00:00:00"</p>
<p>}</p>
<p>}</p></td>
</tr>
</tbody>
</table>

View File

@ -0,0 +1,104 @@
---
title: 乐企授信额度更新有效期接口
aliases:
- 乐企授信额度更新有效期接口
- 诺税通乐企授信额度更新有效期接口
- 专项能力-乐企授信额度更新有效期接口
tags:
- water-docs
- nuoshuitong
- invoice-api
- obsidian
- single-interface
source_docx: ../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx
source_type: converted-and-split
---
# 乐企授信额度更新有效期接口
> [!info] 导航
> 上级索引:[[README]] · [[09_专项能力]]
> 文档链接:[总索引](../README.md) · [分组页](../09_专项能力.md) · [实施清单](../../NUOSHUITONG_SAAS_INTEGRATION_CHECKLIST.md)
> [!note] 来源
> 来源原件:[诺诺网-诺税通销项服务对外接口规范v1.3.18.docx](../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx)
> 接口分组:[[09_专项能力]]
## 字段摘要
> [!summary] 接口元信息
> - 接口地址:`http[s]://\<host\>[:\<port\>]/salescore/lan/creditQuota/updateVestPeriod.do`
> - 请求方式:`POST`
> - 是否回调:否
> - 是否主链路:否
> - 推荐优先级:扩展/按需
## 乐企授信额度更新有效期接口
### 接口说明
乐企模式授信额度更新有效期接口,调用该接口时,需保证对应企业税号查询过授信额度。
### 接口地址
| |
|:---|
| http\[s\]://\<host\>\[:\<port\>\]/salescore/lan/creditQuota/updateVestPeriod.do |
### 请求参数
| | | | | | |
|:--------:|:--------:|:--------:|:------------------:|:--------:|:--------:|
| **名称** | **类型** | **必填** | **说明** | **描述** | **长度** |
| taxNum | String | 是 | 需要查询的企业税号 | 企业税号 | 20 |
### 请求示例
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td style="text-align: left;"><p>{</p>
<p>"taxNum": "150301199811285326"</p>
<p>}</p></td>
</tr>
</tbody>
</table>
### 返回参数
| | | | | | |
|:--:|:--:|:--:|:--:|:--:|:--:|
| **名称** | **类型** | **必填** | **示例值** | **描述** | **长度** |
| code | Integer | 是 | 200 | 状态,200-成功非200-失败 | 6 |
| message | String | 是 | 成功 | 详细信息 | 1024 |
| data | Object | 是 | | 查询对象 | |
| vestPeriodBegin | Date | 是 | 2023-03-01 00:00:00 | 授信额度使用区间起 | \- |
| vestPeriodEnd | Date | 是 | 2023-03-31 00:00:00 | 授信额度使用区间止 | \- |
| vestPeriod | String | 是 | 202303 | 授信额度属期 格式yyyyMM | 6 |
### 返回示例
成功示例:
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td><p>{</p>
<p>"code": 200,</p>
<p>"message": "成功",</p>
<p>"data": {</p>
<p>"vestPeriodBegin": "2023-03-01 00:00:00",</p>
<p>"vestPeriodEnd": "2023-03-31 00:00:00",</p>
<p>"vestPeriod": "202303"</p>
<p>}</p>
<p>}</p></td>
</tr>
</tbody>
</table>

View File

@ -0,0 +1,170 @@
---
title: 乐企数电发票库存申领接口
aliases:
- 乐企数电发票库存申领接口
- 诺税通乐企数电发票库存申领接口
- 库存票源与打印-乐企数电发票库存申领接口
tags:
- water-docs
- nuoshuitong
- invoice-api
- obsidian
- single-interface
source_docx: ../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx
source_type: converted-and-split
---
# 乐企数电发票库存申领接口
> [!info] 导航
> 上级索引:[[README]] · [[06_库存票源与打印]]
> 文档链接:[总索引](../README.md) · [分组页](../06_库存票源与打印.md) · [实施清单](../../NUOSHUITONG_SAAS_INTEGRATION_CHECKLIST.md)
> [!note] 来源
> 来源原件:[诺诺网-诺税通销项服务对外接口规范v1.3.18.docx](../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx)
> 接口分组:[[06_库存票源与打印]]
## 字段摘要
> [!summary] 接口元信息
> - 接口地址:`http[s]://\<host\>[:\<port\>]/salescore/lan/fullStock/applyStock.do`
> - 请求方式:`POST`
> - 是否回调:否
> - 是否主链路:否
> - 推荐优先级:扩展/按需
## 乐企数电发票库存申领接口
### 接口说明
向纳税人提供批量预赋码功能用于企业给数字化电子发票自动赋发票号码。每次最多申请5000份数字化电子发票。
### 接口地址
| |
|:------------------------------------------------------------------------|
| http\[s\]://\<host\>\[:\<port\>\]/salescore/lan/fullStock/applyStock.do |
### 请求参数
| | | | | | |
|:--:|:--:|:--:|:--:|:--:|:--:|
| **名称** | **类型** | **必填** | **说明** | **描述** | **长度** |
| taxNum | String | 是 | 企业税号 | 申领发票的纳税人识别号或统一社会信用代码 | 20 |
| applyNum | Integer | 是 | 申领数量 | 申领数量最大值5000 | 10 |
### 请求示例
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td style="text-align: left;"><p>{</p>
<p>"applyNum": 2,</p>
<p>"taxNum": "339901999999199"</p>
<p>}</p></td>
</tr>
</tbody>
</table>
### 返回参数
<table>
<colgroup>
<col style="width: 14%" />
<col style="width: 11%" />
<col style="width: 7%" />
<col style="width: 15%" />
<col style="width: 35%" />
<col style="width: 15%" />
</colgroup>
<tbody>
<tr>
<td style="text-align: center;"><strong>名称</strong></td>
<td style="text-align: center;"><strong>类型</strong></td>
<td style="text-align: center;"><strong>必填</strong></td>
<td style="text-align: center;"><strong>示例值</strong></td>
<td style="text-align: center;"><strong>描述</strong></td>
<td style="text-align: center;"><strong>长度</strong></td>
</tr>
<tr>
<td style="text-align: center;">code</td>
<td style="text-align: center;">Integer</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">200</td>
<td style="text-align: center;">状态,200-成功非200-失败</td>
<td style="text-align: center;">6</td>
</tr>
<tr>
<td style="text-align: center;">message</td>
<td style="text-align: center;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">成功</td>
<td style="text-align: center;">详细信息</td>
<td style="text-align: center;">1024</td>
</tr>
<tr>
<td style="text-align: center;">data</td>
<td style="text-align: center;">Object</td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;">查询对象</td>
<td style="text-align: center;"></td>
</tr>
<tr>
<td colspan="6" style="text-align: center;"><strong>数据信息</strong></td>
</tr>
<tr>
<td style="text-align: center;">applyNum</td>
<td style="text-align: center;">Integer</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">2</td>
<td style="text-align: center;">领用数量</td>
<td style="text-align: center;">10</td>
</tr>
<tr>
<td style="text-align: center;">invoiceNumStart</td>
<td style="text-align: center;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">23446000000000000042</td>
<td style="text-align: center;"><blockquote>
<p>发票起始号码</p>
</blockquote></td>
<td style="text-align: center;">20</td>
</tr>
<tr>
<td style="text-align: center;">invoiceNumEnd</td>
<td style="text-align: center;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">23446000000000000043</td>
<td style="text-align: center;">发票终止号码</td>
<td style="text-align: center;">20</td>
</tr>
</tbody>
</table>
### 返回示例
成功示例:
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td><p>{</p>
<p>"code": 200,</p>
<p>"message": "成功",</p>
<p>"data": {</p>
<p>"applyNum": 2,</p>
<p>"invoiceNumStart": "23446000000000000042",</p>
<p>"invoiceNumEnd": "23446000000000000043"</p>
<p>}</p>
<p>}</p></td>
</tr>
</tbody>
</table>

View File

@ -0,0 +1,105 @@
---
title: 乐企查询数电库存接口
aliases:
- 乐企查询数电库存接口
- 诺税通乐企查询数电库存接口
- 库存票源与打印-乐企查询数电库存接口
tags:
- water-docs
- nuoshuitong
- invoice-api
- obsidian
- single-interface
source_docx: ../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx
source_type: converted-and-split
---
# 乐企查询数电库存接口
> [!info] 导航
> 上级索引:[[README]] · [[06_库存票源与打印]]
> 文档链接:[总索引](../README.md) · [分组页](../06_库存票源与打印.md) · [实施清单](../../NUOSHUITONG_SAAS_INTEGRATION_CHECKLIST.md)
> [!note] 来源
> 来源原件:[诺诺网-诺税通销项服务对外接口规范v1.3.18.docx](../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx)
> 接口分组:[[06_库存票源与打印]]
## 字段摘要
> [!summary] 接口元信息
> - 接口地址:`http[s]://\<host\>[:\<port\>]/salescore/lan/fullStock/queryFullStock.do`
> - 请求方式:`POST`
> - 是否回调:否
> - 是否主链路:否
> - 推荐优先级:扩展/按需
## 乐企查询数电库存接口
### 接口说明
用于查询数电发票库存
### 接口地址
| |
|:---|
| http\[s\]://\<host\>\[:\<port\>\]/salescore/lan/fullStock/queryFullStock.do |
### 请求参数
| | | | | | |
|:--------:|:--------:|:--------:|:------------------:|:--------:|:--------:|
| **名称** | **类型** | **必填** | **说明** | **描述** | **长度** |
| taxNum | String | 是 | 需要查询的企业税号 | 企业税号 | 20 |
### 请求示例
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td style="text-align: left;"><p>{</p>
<p>"taxNum": "150301199811285326"</p>
<p>}</p></td>
</tr>
</tbody>
</table>
### 返回参数
| | | | | | |
|:--:|:--:|:--:|:--:|:--:|:--:|
| **名称** | **类型** | **必填** | **示例值** | **描述** | **长度** |
| code | Integer | 是 | 200 | 状态,200-成功非200-失败 | 6 |
| message | String | 是 | 成功 | 详细信息 | 1024 |
| data | Object | 是 | | 查询对象 | |
| **数据信息** | | | | | |
| availableNum | Integer | 是 | 1 | 可用库存数量 | \- |
| lockNum | Integer | 是 | 1 | 锁定库存数量 | \- |
| applyTime | String | 是 | 2023-03-01 10:00:00 | 最后领用时间 | \- |
### 返回示例
成功示例:
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td><p>{</p>
<p>"code": 200,</p>
<p>"message": "成功",</p>
<p>"data": {</p>
<p>"availableNum": 1,</p>
<p>"lockNum": 1,</p>
<p>"applyTime": "2023-03-01 10:00:00"</p>
<p>}</p>
<p>}</p></td>
</tr>
</tbody>
</table>

View File

@ -0,0 +1,137 @@
---
title: 企业设备查询接口
aliases:
- 企业设备查询接口
- 诺税通企业设备查询接口
- 设备企业与配置-企业设备查询接口
tags:
- water-docs
- nuoshuitong
- invoice-api
- obsidian
- single-interface
source_docx: ../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx
source_type: converted-and-split
---
# 企业设备查询接口
> [!info] 导航
> 上级索引:[[README]] · [[07_设备企业与配置]]
> 文档链接:[总索引](../README.md) · [分组页](../07_设备企业与配置.md) · [实施清单](../../NUOSHUITONG_SAAS_INTEGRATION_CHECKLIST.md)
> [!note] 来源
> 来源原件:[诺诺网-诺税通销项服务对外接口规范v1.3.18.docx](../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx)
> 接口分组:[[07_设备企业与配置]]
## 字段摘要
> [!summary] 接口元信息
> - 接口地址:`|`
> - 请求方式:`POST`
> - 是否回调:否
> - 是否主链路:否
> - 推荐优先级:扩展/按需
## 企业设备查询接口
### 接口说明
与3.19相比返回增加了包括开票员id在内的全量设备信息以票种+设备唯一返回
### 接口地址
| | |
|:---|----|
| http\[s\]://\<host\>\[:\<port\>\]/salescore/extensioninfo/queryExtensionList.do | |
### 请求参数
| | | | | | |
|:--:|:--:|:--:|:--:|:--:|:--:|
| **名称** | **类型** | **必须** | **示例值** | **描述** | **最大长度** |
| companyId | Long | 否 | 10162 | 公司id | |
| taxnum | String | 是 | 150301199811285326 | 税号 | 20 |
| extensionNum | String | 否 | 0 | 分机号 | 12 |
| machineNum | String | 否 | 661565671900 | 机器号 | 12 |
| invoiceLine | String | 否 | c | 发票种类p:电子增值税普通发票c:增值税普通发票(纸票)s:增值税专用发票e:收购发票(电子)f:收购发票(纸质)r:增值税普通发票(卷式)b:增值税电子专用发票j机动车发票u二手车发票bs:数电专票(电子),pc:数电普票(电子)es:数电专票(纸质)ec:数电普票(纸质) | |
| clerkId | String | 否 | 1 | 开票员id | |
### 请求示例
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td style="text-align: left;"><p>{</p>
<p>    "companyId" :"10162",</p>
<p>    "taxnum" : "150301199811285326",</p>
<p>    "clerkId" : "1",</p>
<p>    "invoiceLine" : "c",</p>
<p>    "machineNum" : "661565671900",</p>
<p>    "extensionNum" : "0"</p>
<p>}</p></td>
</tr>
</tbody>
</table>
### 返回参数
| | | | | | | |
|:--:|:--:|:--:|:--:|:--:|:--:|:--:|
| **名称** | **类型** | **必填** | **示例值** | **更多限制** | **描述** | **最大长度** |
| code | Integer | 是 | 200 | | 状态,200-成功非200-失败 | 6 |
| message | String | | 成功 | | 详细信息 | 1024 |
| data | Object | | | | 数据对象 | |
| 数据信息 | | | | | | |
| extensionId | Long | | 1373 | | extension设备表的主键 | |
| InvoiceType | String | | c | | 发票种类p:电子增值税普通发票c:增值税普通发票(纸票)s:增值税专用发票e:收购发票(电子)f:收购发票(纸质)r:增值税普通发票(卷式)b:增值税电子专用发票j机动车发票u二手车发票bs:数电专票(电子),pc:数电普票(电子)es:数电专票(纸质)ec:数电普票(纸质) | |
| extensionNum | Integer | | 0 | | 分机号 | 12 |
| machineNum | String | | 661565671900 | | 机器编码 | 12 |
| terminalNum | Integer | | 1 | | 终端号 | 10 |
| serverType | Integer | | 14 | | 开票服务器类型 | |
| reportTaxStatus | Integer | | 1 | | 报税状态 -1:未知 0:未抄报 1:已抄报 | |
| clearCardStatus | Integer | | 1 | | 清卡状态 -1:未知 0:未清卡 1:已清卡 | |
| lockDate | String | | 2022-06-15 | | 锁死日期 | |
| singleBillingLimit | BigDecimal | | 999999.99 | | 单张开票限额 | |
| offlineAmount | BigDecimal | | 9999999991.00 | | 离线剩余金额 | |
| offlineTime | BigDecimal | | 720.00 | | 离线时限(h) | |
| updateTime | String | | 2022-05-25 07:37:02 | | 更新时间 | |
| clerkIds | String | | 1 | | 开票员id,多个用逗号隔开 | |
| loginAccount | String | | | | 数电账号 | |
### 返回示例
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td style="text-align: left;"><p>{</p>
<p>    "code": 200,</p>
<p>    "message": "成功",</p>
<p>    "data": [</p>
<p>        {</p>
<p>            "invoiceType": "c",</p>
<p>            "extensionNum": 0,</p>
<p>            "machineNum": "661565671900",</p>
<p>            "terminalNum": 1,</p>
<p>            "serverType": 14,</p>
<p>            "reportTaxStatus": 1,</p>
<p>            "clearCardStatus": 1,</p>
<p>            "lockDate": "2022-06-15",</p>
<p>            "singleBillingLimit": "999999.99",</p>
<p>            "offlineAmount": "9999999991.00",</p>
<p>            "offlineTime": "720.00",</p>
<p>            "updateTime": "2022-05-25 07:37:02",</p>
<p>            "clerkIds": "1"</p>
<p>        }</p>
<p>    ]</p>
<p>}</p></td>
</tr>
</tbody>
</table>

View File

@ -0,0 +1,178 @@
---
title: 企业设备状态查询接口
aliases:
- 企业设备状态查询接口
- 诺税通企业设备状态查询接口
- 设备企业与配置-企业设备状态查询接口
tags:
- water-docs
- nuoshuitong
- invoice-api
- obsidian
- single-interface
source_docx: ../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx
source_type: converted-and-split
---
# 企业设备状态查询接口
> [!info] 导航
> 上级索引:[[README]] · [[07_设备企业与配置]]
> 文档链接:[总索引](../README.md) · [分组页](../07_设备企业与配置.md) · [实施清单](../../NUOSHUITONG_SAAS_INTEGRATION_CHECKLIST.md)
> [!note] 来源
> 来源原件:[诺诺网-诺税通销项服务对外接口规范v1.3.18.docx](../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx)
> 接口分组:[[07_设备企业与配置]]
## 字段摘要
> [!summary] 接口元信息
> - 接口地址:`http[s]://\<host\>[:\<port\>]/salescore/extensioninfo/queryEquipmentStatusList.do`
> - 请求方式:`POST`
> - 是否回调:否
> - 是否主链路:是
> - 推荐优先级P1开票前保障
## 企业设备状态查询接口
### 接口说明
企业设备状态查询接口。
### 接口地址
| |
|:---|
| http\[s\]://\<host\>\[:\<port\>\]/salescore/extensioninfo/queryEquipmentStatusList.do |
### 请求参数(用json格式接收)
| | | | | |
|:-------------:|:--------:|:--------:|:--------:|:--------:|
| **名称** | **类型** | **必填** | **描述** | **长度** |
| extensionNum | String | 选填 | 分机号 | 5 |
| machineNumber | String | 选填 | 机器编号 | 12 |
| sellerTaxnum | String | 是 | 销方税号 | 20 |
### 请求示例
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td><p>{</p>
<p>"extensionNum": "0",</p>
<p>"machineNumber": "123",</p>
<p>"sellerTaxnum": "150301199811285326"</p>
<p>}</p></td>
</tr>
</tbody>
</table>
### 返回参数
| | | | | |
|:--:|:--:|:--:|:--:|:--:|
| **名称** | **类型** | **必填** | **描述** | **长度** |
| code | Integer | 是 | 状态,200-成功非200-失败 | 6 |
| message | String | 是 | 详细信息 | 1024 |
| data | List | | 查询成功则返回企业设备状态信息 | |
| 企业设备状态 | | | | |
| invoiceLine | String | 是 | 发票种类p:电子增值税普通发票c:增值税普通发票(纸票)s:增值税专用发票e:收购发票(电子)f:收购发票(纸质)r:增值税普通发票(卷式)b:增值税电子专用发票j机动车发票u二手车发票 | |
| reportTaxStatus | Integer | | 报税状态 -1:未知 0:未抄报 1:已抄报 | |
| clearCardStatus | Integer | | 清卡状态 -1:未知 0:未清卡 1:已清卡 | |
| lockDate | Date | | 锁死日期 | |
| singleBillingLimit | BigDecimal | | 单张开票限额 | |
| offlineAmount | BigDecimal | | 离线剩余金额 | |
| offlineTime | BigDecimal | | 离线时限(h) | |
| updateTime | Date | | 更新时间 | |
### 返回示例
成功示例:
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td><p>{</p>
<p>    "code":200,</p>
<p>    "message":"成功",</p>
<p>    "data":[</p>
<p>        {</p>
<p>            "invoiceLine":"s",</p>
<p>            "lockDate":"2020-07-01",</p>
<p>            "reportTaxStatus":1,</p>
<p>            "clearCardStatus":-1,</p>
<p>            "offlineAmount":"111111111080.99",</p>
<p>            "offlineTime":"999.00",</p>
<p>            "singleBillingLimit":"100000000.00",</p>
<p>            "updateTime":"2020-11-25 01:00:01"</p>
<p>        },</p>
<p>        {</p>
<p>            "invoiceLine":"c",</p>
<p>            "lockDate":"2020-07-01",</p>
<p>            "reportTaxStatus":1,</p>
<p>            "clearCardStatus":-1,</p>
<p>            "offlineAmount":"111111111019.60",</p>
<p>            "offlineTime":"999.00",</p>
<p>            "singleBillingLimit":"100000000.00",</p>
<p>            "updateTime":"2020-11-25 01:00:01"</p>
<p>        },</p>
<p>        {</p>
<p>            "invoiceLine":"p",</p>
<p>            "lockDate":"2020-06-15",</p>
<p>            "reportTaxStatus":1,</p>
<p>            "clearCardStatus":-1,</p>
<p>            "offlineAmount":"320122.95",</p>
<p>            "offlineTime":"999.00",</p>
<p>            "singleBillingLimit":"9999.99",</p>
<p>            "updateTime":"2021-02-02 11:32:01"</p>
<p>        },</p>
<p>        {</p>
<p>            "invoiceLine":"j",</p>
<p>            "lockDate":"2020-06-15",</p>
<p>            "reportTaxStatus":1,</p>
<p>            "clearCardStatus":-1,</p>
<p>            "offlineAmount":"999999999.00",</p>
<p>            "offlineTime":"999.00",</p>
<p>            "singleBillingLimit":"10000000.00",</p>
<p>            "updateTime":"2020-11-25 01:00:02"</p>
<p>        },</p>
<p>        {</p>
<p>            "invoiceLine":"r",</p>
<p>            "lockDate":"2020-06-15",</p>
<p>            "reportTaxStatus":1,</p>
<p>            "clearCardStatus":-1,</p>
<p>            "offlineAmount":"1111111.11",</p>
<p>            "offlineTime":"999.00",</p>
<p>            "singleBillingLimit":"10000000.00",</p>
<p>            "updateTime":"2020-11-25 01:00:02"</p>
<p>        }</p>
<p>    ]</p>
<p>}</p></td>
</tr>
</tbody>
</table>
失败示例:
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td><p>{</p>
<p>    "code":900,</p>
<p>    "message":"不存在该设备抄报税信息",</p>
<p>    "data":null</p>
<p>}</p></td>
</tr>
</tbody>
</table>

View File

@ -0,0 +1,192 @@
---
title: 企业车架号等信息查询结果回传接口
aliases:
- 企业车架号等信息查询结果回传接口
- 诺税通企业车架号等信息查询结果回传接口
- 车辆辅助与回传-企业车架号等信息查询结果回传接口
tags:
- water-docs
- nuoshuitong
- invoice-api
- obsidian
- single-interface
source_docx: ../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx
source_type: converted-and-split
---
# 企业车架号等信息查询结果回传接口
> [!info] 导航
> 上级索引:[[README]] · [[08_车辆辅助与回传]]
> 文档链接:[总索引](../README.md) · [分组页](../08_车辆辅助与回传.md) · [实施清单](../../NUOSHUITONG_SAAS_INTEGRATION_CHECKLIST.md)
> [!note] 来源
> 来源原件:[诺诺网-诺税通销项服务对外接口规范v1.3.18.docx](../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx)
> 接口分组:[[08_车辆辅助与回传]]
## 字段摘要
> [!summary] 接口元信息
> - 接口地址:`用户通过查询企业车架号、合格证状态接口中的callbackUrl字段提供回调地址。`
> - 请求方式:`POST`
> - 是否回调:是
> - 是否主链路:否
> - 推荐优先级:扩展/按需
## 企业车架号等信息查询结果回传接口
### 接口说明
企业车架号等信息查询结果回传接口。
### 接口地址
用户通过查询企业车架号、合格证状态接口中的callbackUrl字段提供回调地址。
### 请求参数
| | | | | | |
|:--:|:--:|:--:|:--:|:--:|:--:|
| **名称** | **类型** | **必须** | **示例值** | **更多限制** | **描述** |
| vehicleCode | String | 是 | 5656565 | 支持数字、字母、星号 | 车架号 |
| sellerTaxnum | String | 是 | 338801999999001 | 必填 | 车架号所属企业税号,进项归集则需传购方企业税号 |
| status | String | 是 | 1 | 必填 | 查询状态 1:查询成功2查询失败 |
| certificate | String | 否 | 125999915630 | 非必填 | 合格证号 |
| extensionNumber | integer | 否 | 123 | 非必填 | 分机号 |
| machineCode | String | 否 | 123456789012 | 非必填 | 机器编号 |
| terminalNum | String | 否 | 0 | 非必填 | 终端号 |
| importCertifyNum | String | 否 | 343455555 | 非必填 | 进口证明书号(进口车才有) |
| describe | String | 否 | | 非必填 | 描述信息 |
| brandModel | String | 否 | | 非必填 | 厂牌型号 |
| engineNum | String | 否 | | 非必填 | 发动机号码 |
| vehicleType | String | 否 | | 非必填 | 车辆类型 |
| inspectionOddNum | String | 否 | \- | 非必填 | 商检单号 |
| productOrigin | String | 否 | 上海 | 非必填 | 产地 |
| requestSrc | String | 是 | 3 | 必填 | 请求来源(0:未知;1-页面添加;2-页面导入;3-api进项调用;4-api用户调用;) |
| vehicleStatus | String | 是 | 1 | 必填 | 车架号状态1-可开票;3-未知;4-不可开票 |
### 请求示例
查询成功回调(表示该车架号可开票):
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td style="text-align: left;"><p>{</p>
<p>"vehicleCode": "5656565",</p>
<p>"sellerTaxnum": "338801999999001",</p>
<p>"certificate": "125999915630",</p>
<p>"status": "1",</p>
<p>"extensionNumber": "123",</p>
<p>"machineCode": "123456789012",</p>
<p>"importCertifyNum": "343455555",</p>
<p>"describe": "机动车合格证号可用",</p>
<p>"brandModel": "",</p>
<p>"engineNum": "",</p>
<p>"vehicleType": "",</p>
<p>"inspectionOddNum": "",</p>
<p>"productOrigin": "",</p>
<p>"requestSrc": "4",</p>
<p>"vehicleStatus": "1"</p>
<p>}</p></td>
</tr>
</tbody>
</table>
查询失败回调(表示该车架号不可开票):
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td style="text-align: left;"><p>{</p>
<p>"vehicleCode": "5656565",</p>
<p>"sellerTaxnum": "338801999999001",</p>
<p>"certificate": "125999915630",</p>
<p>"status": "2",</p>
<p>"describe": "合格证存在,不属于本企业",</p>
<p>"requestSrc": "4",</p>
<p>"vehicleStatus": "4"</p>
<p>}</p></td>
</tr>
</tbody>
</table>
【describe】字段文案包含
1、合格证已被使用
2、查询到合格证信息已使用不允许开具发票
3、未查询到合格证信息不允许开具发票
4、合格证存在不属于本企业
### 返回参数
<table>
<colgroup>
<col style="width: 15%" />
<col style="width: 12%" />
<col style="width: 8%" />
<col style="width: 15%" />
<col style="width: 14%" />
<col style="width: 24%" />
<col style="width: 9%" />
</colgroup>
<tbody>
<tr>
<td style="text-align: center;"><strong>名称</strong></td>
<td style="text-align: center;"><strong>类型</strong></td>
<td style="text-align: center;"><strong>必须</strong></td>
<td style="text-align: center;"><strong>示例值</strong></td>
<td style="text-align: center;"><strong>更多限制</strong></td>
<td style="text-align: center;"><strong>描述</strong></td>
<td style="text-align: center;"><strong>最大长度</strong></td>
</tr>
<tr>
<td style="text-align: left;">code</td>
<td style="text-align: left;">Integer</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">0000</td>
<td style="text-align: left;"></td>
<td style="text-align: left;"><p>状态,0000-成功,</p>
<p>非0000-失败</p></td>
<td style="text-align: left;">6</td>
</tr>
<tr>
<td style="text-align: left;">message</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">成功</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">详细信息</td>
<td style="text-align: left;">1024</td>
</tr>
</tbody>
</table>
### 返回示例
示例:
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td style="text-align: left;"><p>{</p>
<p>"code": 0000,</p>
<p>"message": "成功"</p>
<p>}</p></td>
</tr>
</tbody>
</table>

View File

@ -0,0 +1,132 @@
---
title: 创建/查询企业车架号、合格证状态接口
aliases:
- 创建/查询企业车架号、合格证状态接口
- 诺税通创建/查询企业车架号、合格证状态接口
- 车辆辅助与回传-创建/查询企业车架号、合格证状态接口
tags:
- water-docs
- nuoshuitong
- invoice-api
- obsidian
- single-interface
source_docx: ../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx
source_type: converted-and-split
---
# 创建/查询企业车架号、合格证状态接口
> [!info] 导航
> 上级索引:[[README]] · [[08_车辆辅助与回传]]
> 文档链接:[总索引](../README.md) · [分组页](../08_车辆辅助与回传.md) · [实施清单](../../NUOSHUITONG_SAAS_INTEGRATION_CHECKLIST.md)
> [!note] 来源
> 来源原件:[诺诺网-诺税通销项服务对外接口规范v1.3.18.docx](../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx)
> 接口分组:[[08_车辆辅助与回传]]
## 字段摘要
> [!summary] 接口元信息
> - 接口地址:`http[s]://\<host\>[:\<port\>]/salescore/lan/query/vehicleCodeIsInvoice.do`
> - 请求方式:`POST`
> - 是否回调:否
> - 是否主链路:否
> - 推荐优先级:扩展/按需
## 创建/查询企业车架号、合格证状态接口
### 接口说明
仅用于请求车架号在税局的是否可开票状态,改接口返回成功仅说明提交查询请求成功,因需和税局交互,故需异步通过查询或回调获取查询结果。请求成功的数据可至诺税通-库存管理-车辆库存中查看。
### 接口地址
| |
|:---|
| http\[s\]://\<host\>\[:\<port\>\]/salescore/lan/query/vehicleCodeIsInvoice.do |
### 请求参数
| | | | | | | |
|:--:|:--:|:--:|:--:|:--:|:--:|:--:|
| **名称** | **类型** | **必须** | **示例值** | **更多限制** | **描述** | **最大长度** |
| vehicleCode | String | 是 | 5656565 | 支持数字、字母、星号 | 车架号 | 23 |
| sellerTaxnum | String | 是 | 338801999999001 | 必填 | 车架号所属企业税号,进项归集则需传购方企业税号 | 20 |
| certificate | String | 否 | 125999915630 | 非必填 | 合格证号 | 50 |
| vehicle Type | String | 否 | 辉腾 | 非必填 | 车辆类型 | 40 |
| brandModel | String | 否 | 大众 | 非必填 | 厂牌型号 | 60 |
| warehouse | String | 否 | 上海 | 非必填 | 所在仓库 | 50 |
| extensionNum | String | 否 | 0 | 非必填 | 分机号 | 5 |
| machineNumber | String | 否 | 1234565654 | 非必填 | 机器编号 | 12 |
| terminalNum | String | 否 | 0 | 非必填 | 终端号 | 12 |
| engineNum | String | 否 | 21166621 | 非必填 | 发动机号码 | 50 |
| importCertifyNum | String | 否 | 343455555 | 非必填 | 进口证明书号 | 36 |
| inspectionOddNum | String | 否 | \- | 非必填 | 商检单号 | 32 |
| productOrigin | String | 否 | \- | 非必填 | 产地 | 32 |
| displacement | String | 否 | | 非必填 | 排量 | 50 |
| callbackUrl | String | 否 | http://127.0.0.1:8080/ | 当请求来源不是3时必填 | 回调地址 | 255 |
| requestSrc | String | 否 | 4 | 非必填 | 请求来源(0:未知;1-页面添加;2-页面导入;3-api进项调用;4-api用户调用;)默认为4 | 1 |
| refreshFlag | String | 否 | 1 | 非必填 | 刷新标记。(0:不需要调用电票进行刷新;1-需要调用)默认为1 | 1 |
### 请求示例
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td style="text-align: left;"><p>{</p>
<p>"vehicleCode": "5656565",</p>
<p>"sellerTaxnum": "338801999999001",</p>
<p>"certificate": "125999915630",</p>
<p>"callbackUrl": "http://127.0.0.1:8080/"</p>
<p>"brandModel": "品牌型号"</p>
<p>"warehouse": "上海"</p>
<p>}</p></td>
</tr>
</tbody>
</table>
### 返回参数
| | | | | | | |
|:--:|:--:|:--:|:--:|:--:|:--:|:--:|
| **名称** | **类型** | **必须** | **示例值** | **更多限制** | **描述** | **最大长度** |
| code | Integer | 是 | 200 | | 状态,200-成功非200-失败 | 6 |
| message | String | 是 | 提交成功 | | 详细信息 | 1024 |
### 返回示例
成功示例:
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td style="text-align: left;"><p>{</p>
<p>"code": 200,</p>
<p>"message": "提交成功"</p>
<p>}</p></td>
</tr>
</tbody>
</table>
失败示例:
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td style="text-align: left;"><p>{</p>
<p>"code": 3001,</p>
<p>"message": "结果查询中,请稍候重试"</p>
<p>}</p></td>
</tr>
</tbody>
</table>

View File

@ -0,0 +1,230 @@
---
title: 创建开票设备接口
aliases:
- 创建开票设备接口
- 诺税通创建开票设备接口
- 设备企业与配置-创建开票设备接口
tags:
- water-docs
- nuoshuitong
- invoice-api
- obsidian
- single-interface
source_docx: ../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx
source_type: converted-and-split
---
# 创建开票设备接口
> [!info] 导航
> 上级索引:[[README]] · [[07_设备企业与配置]]
> 文档链接:[总索引](../README.md) · [分组页](../07_设备企业与配置.md) · [实施清单](../../NUOSHUITONG_SAAS_INTEGRATION_CHECKLIST.md)
> [!note] 来源
> 来源原件:[诺诺网-诺税通销项服务对外接口规范v1.3.18.docx](../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx)
> 接口分组:[[07_设备企业与配置]]
## 字段摘要
> [!summary] 接口元信息
> - 接口地址:`http[s]://\<host\>[:\<port\>]/salescore/extensioninfo/insertExtension.do`
> - 请求方式:`POST`
> - 是否回调:否
> - 是否主链路:否
> - 推荐优先级:扩展/按需
## 创建开票设备接口
### 接口说明
新增开票设备接口,开票设备唯一性规则:当开票员存在时 同一个开票员+开票设备+票种唯一,当不存在开票员时,针对数电设备分机号或登录账号不可重复,针对其他设备,机器编号不可重复。
### 接口地址
| |
|:---|
| http\[s\]://\<host\>\[:\<port\>\]/salescore/extensioninfo/insertExtension.do |
### 请求参数
<table>
<colgroup>
<col style="width: 25%" />
<col style="width: 10%" />
<col style="width: 8%" />
<col style="width: 43%" />
<col style="width: 11%" />
</colgroup>
<tbody>
<tr>
<td style="text-align: center;"><strong>名称</strong></td>
<td style="text-align: center;"><strong>类型</strong></td>
<td style="text-align: center;"><strong>必填</strong></td>
<td style="text-align: center;"><strong>描述</strong></td>
<td style="text-align: center;"><strong>长度</strong></td>
</tr>
<tr>
<td style="text-align: center;">taxNum</td>
<td style="text-align: center;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">企业税号</td>
<td style="text-align: center;">20</td>
</tr>
<tr>
<td style="text-align: center;">extensionNum</td>
<td style="text-align: center;">Integer</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">分机号 0--65535数字</td>
<td style="text-align: center;">-</td>
</tr>
<tr>
<td style="text-align: center;">terminalNum</td>
<td style="text-align: center;">Integer</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">终端号</td>
<td style="text-align: center;">2</td>
</tr>
<tr>
<td style="text-align: center;">machineNum</td>
<td style="text-align: center;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">机器编号 非数电设备必填</td>
<td style="text-align: center;">32</td>
</tr>
<tr>
<td style="text-align: center;">serverType</td>
<td style="text-align: center;">Integer</td>
<td style="text-align: center;"></td>
<td style="text-align: center;"><p>开票服务器类型 传对应的数字枚举</p>
<p>1:C48,</p>
<p>11:诺诺开票,</p>
<p>14A9,</p>
<p>15:四川税局代开,</p>
<p>17:诺诺机柜,</p>
<p>18:税控服务器,</p>
<p>20:单机版,</p>
<p>22:数电发票开票模式(通用版),</p>
<p>24:数电发票开票模式(单机版),</p>
<p>25:数电发票开票模式(机柜版)</p>
<p>数电单机版和机柜版暂只支持半本地环境</p></td>
<td style="text-align: center;">4</td>
</tr>
<tr>
<td style="text-align: center;">loginAccount</td>
<td style="text-align: center;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">数电开票账号 开票服务器类型为数电时必传</td>
<td style="text-align: center;">20</td>
</tr>
<tr>
<td style="text-align: center;">elePassword</td>
<td style="text-align: center;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">数电开票密码使用aes加密 开票服务器类型为数电时必传</td>
<td style="text-align: center;">加密前1-20位</td>
</tr>
<tr>
<td style="text-align: center;">equipmentCabinetId</td>
<td style="text-align: center;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">机柜序列号 当服务器类型为诺诺机柜时必传</td>
<td style="text-align: center;">30</td>
</tr>
<tr>
<td style="text-align: center;">taxMachinePwd</td>
<td style="text-align: center;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">设备证书口令 当服务器类型为诺诺机柜时必传</td>
<td style="text-align: center;">35</td>
</tr>
<tr>
<td style="text-align: center;">taxPlatPwd</td>
<td style="text-align: center;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">设备口令 当服务器类型为诺诺机柜时必传</td>
<td style="text-align: center;">100</td>
</tr>
<tr>
<td style="text-align: center;">serverAddress</td>
<td style="text-align: center;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">服务器地址 当开票服务为A9或C48时必传</td>
<td style="text-align: center;">100</td>
</tr>
<tr>
<td style="text-align: center;">invoiceTypelist</td>
<td style="text-align: center;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: center;"><p>当前设备可开发票种类,使用,隔开</p>
<p>p:电子增值税普通发票c:增值税普通发票(纸票)s:增值税专用发票e:收购发票(电子)f:收购发票(纸质)b:增值税电子专用发票j机动车发票u二手车发票,bs:数电专票(电子),pc:数电普票(电子)es:数电专票(纸质)ec:数电普票(纸质)</p></td>
<td style="text-align: center;">-</td>
</tr>
<tr>
<td style="text-align: center;">clerkList</td>
<td style="text-align: center;">List&lt;Long&gt;</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">开票员userId集合 当设备需要绑定开票员时必传</td>
<td style="text-align: center;">-</td>
</tr>
<tr>
<td style="text-align: center;">projectList</td>
<td style="text-align: center;">List&lt;String&gt;</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">项目编码集合 当设备需要绑定设备信息时必传</td>
<td style="text-align: center;">-</td>
</tr>
</tbody>
</table>
### 请求示例
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td style="text-align: left;"><p>{</p>
<p>"taxnum": "150301199811285326",</p>
<p>"projectList": ["BJ01-002","20221008"],</p>
<p>"serverType": 14,</p>
<p>"extensionNum": "5",</p>
<p>"machineNum": "123456987456",</p>
<p>"terminalNum": "5",</p>
<p>"serverAddress": "123456",</p>
<p>"clerkList": [8,7],</p>
<p>"companName": "移动测试盘326",</p>
<p>"invoiceTypelist": "b,s,p,c"</p>
<p>}</p></td>
</tr>
</tbody>
</table>
### 返回参数
| | | | | | |
|:--------:|:--------:|:--------:|:----------:|:-------------------------:|:--------:|
| **名称** | **类型** | **必填** | **示例值** | **描述** | **长度** |
| code | Integer | 是 | 200 | 状态,200-成功非200-失败 | 6 |
| message | String | 是 | 成功 | 详细信息 | 1024 |
| data | String | 是 | 123456789 | 当前新增设备的唯一标识 | 20 |
### 返回示例
成功示例:
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td><p>{</p>
<p>"code":200,</p>
<p>"message": "成功",</p>
<p>"data": "123456789"</p>
<p>}</p></td>
</tr>
</tbody>
</table>

View File

@ -0,0 +1,117 @@
---
title: 删除发票信息接口
aliases:
- 删除发票信息接口
- 诺税通删除发票信息接口
- 车辆辅助与回传-删除发票信息接口
tags:
- water-docs
- nuoshuitong
- invoice-api
- obsidian
- single-interface
source_docx: ../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx
source_type: converted-and-split
---
# 删除发票信息接口
> [!info] 导航
> 上级索引:[[README]] · [[08_车辆辅助与回传]]
> 文档链接:[总索引](../README.md) · [分组页](../08_车辆辅助与回传.md) · [实施清单](../../NUOSHUITONG_SAAS_INTEGRATION_CHECKLIST.md)
> [!note] 来源
> 来源原件:[诺诺网-诺税通销项服务对外接口规范v1.3.18.docx](../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx)
> 接口分组:[[08_车辆辅助与回传]]
## 字段摘要
> [!summary] 接口元信息
> - 接口地址:`http[s]://\<host\>[:\<port\>]/salescore/lan/invoiceList/delete.do`
> - 请求方式:`POST`
> - 是否回调:否
> - 是否主链路:否
> - 推荐优先级:扩展/按需
## 删除发票信息接口
### 接口说明
支持开票失败状态发票删除以及开票中状态发票撤回,传入订单编号删除时支持删除审核开票记录。
### 接口地址
| |
|-----------------------------------------------------------------------|
| http\[s\]://\<host\>\[:\<port\>\]/salescore/lan/invoiceList/delete.do |
### 请求参数(用json格式接收)
| | | | | |
|:--:|:--:|:--:|:--:|:--:|
| **名称** | **类型** | **必填** | **描述** | **长度** |
| sellerTaxnum | String | 是 | 销方税号15-20位 | 20 |
| valueType | Integer | 是 | 值类型0发票流水号1订单编号 | \- |
| value | String | 是 | 若值类型为0value为发票流水号的值若值类型为1value为订单编号的值 | \- |
### 请求示例
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td style="text-align: left;"><p>{</p>
<p>"sellerTaxnum": "150301199811285326",</p>
<p>"value": "21051310255001000228",</p>
<p>"valueType": 0</p>
<p>}</p></td>
</tr>
</tbody>
</table>
### 返回参数
| | | | | |
|:--------:|:--------:|:--------:|:-------------------------:|:--------:|
| **名称** | **类型** | **必填** | **描述** | **长度** |
| code | Integer | 是 | 状态,200-成功非200-失败 | 6 |
| message | String | 是 | 详细信息 | 1024 |
### 返回示例
成功示例:
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td><p>{</p>
<p>    "code":200,</p>
<p>    "message":"成功",</p>
<p>    "data":  null</p>
<p>}</p></td>
</tr>
</tbody>
</table>
失败示例:
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td><p>{</p>
<p>"code": 900,</p>
<p>"message": "非开票失败、开票中状态的发票信息不允许删除",</p>
<p>"data": null</p>
<p>}</p></td>
</tr>
</tbody>
</table>

View File

@ -0,0 +1,118 @@
---
title: 刷新可下载发票库存接口
aliases:
- 刷新可下载发票库存接口
- 诺税通刷新可下载发票库存接口
- 库存票源与打印-刷新可下载发票库存接口
tags:
- water-docs
- nuoshuitong
- invoice-api
- obsidian
- single-interface
source_docx: ../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx
source_type: converted-and-split
---
# 刷新可下载发票库存接口
> [!info] 导航
> 上级索引:[[README]] · [[06_库存票源与打印]]
> 文档链接:[总索引](../README.md) · [分组页](../06_库存票源与打印.md) · [实施清单](../../NUOSHUITONG_SAAS_INTEGRATION_CHECKLIST.md)
> [!note] 来源
> 来源原件:[诺诺网-诺税通销项服务对外接口规范v1.3.18.docx](../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx)
> 接口分组:[[06_库存票源与打印]]
## 字段摘要
> [!summary] 接口元信息
> - 接口地址:`http[s]://\<host\>[:\<port\>]/salescore/lan/stock/flushDownloadableStock.do`
> - 请求方式:`POST`
> - 是否回调:否
> - 是否主链路:否
> - 推荐优先级:扩展/按需
## 刷新可下载发票库存接口
### 接口说明
从税局获取局端可下载发票的信息,仅支持开票服务器类型为诺诺机柜和诺诺开票。控制一分钟之内只能操作一次,请勿频繁操作。
### 接口地址
| |
|:---|
| http\[s\]://\<host\>\[:\<port\>\]/salescore/lan/stock/flushDownloadableStock.do |
### 请求参数
| | | | | |
|:-------------:|:--------:|:--------:|:------------------:|:--------:|
| **名称** | **类型** | **必填** | **描述** | **长度** |
| sellerTaxnum | String | 是 | 销方税号15-20位 | 20 |
| extensionNum | Integer | 是 | 分机号,纯数字 | \- |
| machineNumber | String | 是 | 机器编号12位数字 | 12 |
### 请求示例
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td><p>{</p>
<p>"extensionNum": 0,</p>
<p>"machineNumber": "661565671900",</p>
<p>"sellerTaxnum": "150301199811285326"</p>
<p>}</p></td>
</tr>
</tbody>
</table>
### 返回参数
| | | | | |
|:--------:|:--------:|:--------:|:-------------------------:|:--------:|
| **名称** | **类型** | **必填** | **描述** | **长度** |
| code | Integer | 是 | 状态,200-成功非200-失败 | 6 |
| message | String | 是 | 详细信息 | 1024 |
| data | Object | | | |
### 返回示例
成功示例:
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td style="text-align: left;"><p>{</p>
<p>"code": 200,</p>
<p>"message": "成功",</p>
<p>"data": null</p>
<p>}</p></td>
</tr>
</tbody>
</table>
失败示例:
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td><p>{</p>
<p>"code": 900,</p>
<p>"message": "一分钟之内只能操作一次,请勿频繁操作",</p>
<p>"data": null</p>
<p>}</p></td>
</tr>
</tbody>
</table>

View File

@ -0,0 +1,118 @@
---
title: 刷新获取开票设备实时发票库存接口
aliases:
- 刷新获取开票设备实时发票库存接口
- 诺税通刷新获取开票设备实时发票库存接口
- 库存票源与打印-刷新获取开票设备实时发票库存接口
tags:
- water-docs
- nuoshuitong
- invoice-api
- obsidian
- single-interface
source_docx: ../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx
source_type: converted-and-split
---
# 刷新获取开票设备实时发票库存接口
> [!info] 导航
> 上级索引:[[README]] · [[06_库存票源与打印]]
> 文档链接:[总索引](../README.md) · [分组页](../06_库存票源与打印.md) · [实施清单](../../NUOSHUITONG_SAAS_INTEGRATION_CHECKLIST.md)
> [!note] 来源
> 来源原件:[诺诺网-诺税通销项服务对外接口规范v1.3.18.docx](../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx)
> 接口分组:[[06_库存票源与打印]]
## 字段摘要
> [!summary] 接口元信息
> - 接口地址:`http[s]://\<host\>[:\<port\>]/salescore/lan/stock/refreshLocalStock.do`
> - 请求方式:`POST`
> - 是否回调:否
> - 是否主链路:否
> - 推荐优先级:扩展/按需
## 刷新获取开票设备实时发票库存接口
### 接口说明
触发刷新获取税盘实时库存接口,仅下发查询指令,需配合库存余量查询接口获取刷新后的实时库存。
### 接口地址
| |
|:---|
| http\[s\]://\<host\>\[:\<port\>\]/salescore/lan/stock/refreshLocalStock.do |
### 请求参数
| | | | | |
|:-------------:|:--------:|:--------:|:------------------:|:--------:|
| **名称** | **类型** | **必填** | **描述** | **长度** |
| sellerTaxnum | String | 是 | 销方税号15-20位 | 20 |
| extensionNum | Integer | 否 | 分机号,纯数字 | \- |
| machineNumber | String | 否 | 机器编号12位数字 | 12 |
### 请求示例
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td><p>{</p>
<p>"extensionNum": 0,</p>
<p>"machineNumber": "661565671900",</p>
<p>"sellerTaxnum": "150301199811285326"</p>
<p>}</p></td>
</tr>
</tbody>
</table>
### 返回参数
| | | | | |
|:--------:|:--------:|:--------:|:-------------------------:|:--------:|
| **名称** | **类型** | **必填** | **描述** | **长度** |
| code | Integer | 是 | 状态,200-成功非200-失败 | 6 |
| message | String | 是 | 详细信息 | 1024 |
| data | Object | | | |
### 返回示例
成功示例:
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td style="text-align: left;"><p>{</p>
<p>"code": 200,</p>
<p>"message": "成功",</p>
<p>"data": null</p>
<p>}</p></td>
</tr>
</tbody>
</table>
失败示例:
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td><p>{</p>
<p>"code": 900,</p>
<p>"message": "未找到设备!",</p>
<p>"data": null</p>
<p>}</p></td>
</tr>
</tbody>
</table>

View File

@ -0,0 +1,118 @@
---
title: 刷新获取税盘实时成品油库存接口
aliases:
- 刷新获取税盘实时成品油库存接口
- 诺税通刷新获取税盘实时成品油库存接口
- 专项能力-刷新获取税盘实时成品油库存接口
tags:
- water-docs
- nuoshuitong
- invoice-api
- obsidian
- single-interface
source_docx: ../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx
source_type: converted-and-split
---
# 刷新获取税盘实时成品油库存接口
> [!info] 导航
> 上级索引:[[README]] · [[09_专项能力]]
> 文档链接:[总索引](../README.md) · [分组页](../09_专项能力.md) · [实施清单](../../NUOSHUITONG_SAAS_INTEGRATION_CHECKLIST.md)
> [!note] 来源
> 来源原件:[诺诺网-诺税通销项服务对外接口规范v1.3.18.docx](../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx)
> 接口分组:[[09_专项能力]]
## 字段摘要
> [!summary] 接口元信息
> - 接口地址:`http[s]://\<host\>[:\<port\>]/salescore/lan/oilStock/refreshProductOil.do`
> - 请求方式:`POST`
> - 是否回调:否
> - 是否主链路:否
> - 推荐优先级:扩展/按需
## 刷新获取税盘实时成品油库存接口
### 接口说明
刷新成品油库存接口
### 接口地址
| |
|:---|
| http\[s\]://\<host\>\[:\<port\>\]/salescore/lan/oilStock/refreshProductOil.do |
### 请求参数
| | | | | |
|:-------------:|:--------:|:--------:|:------------------:|:--------:|
| **名称** | **类型** | **必填** | **描述** | **长度** |
| sellerTaxnum | String | 是 | 销方税号15-20位 | 20 |
| extensionNum | Integer | 是 | 分机号,纯数字 | \- |
| machineNumber | String | 否 | 机器编号12位数字 | 12 |
### 请求示例
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td><p>{</p>
<p>"extensionNum": 0,</p>
<p>"machineNumber": "661565671900",</p>
<p>"sellerTaxnum": "150301199811285326"</p>
<p>}</p></td>
</tr>
</tbody>
</table>
### 返回参数
| | | | | |
|:--------:|:--------:|:--------:|:-------------------------:|:--------:|
| **名称** | **类型** | **必填** | **描述** | **长度** |
| code | Integer | 是 | 状态,200-成功非200-失败 | 6 |
| message | String | 是 | 详细信息 | 1024 |
| data | Object | | | |
### 返回示例
成功示例:
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td style="text-align: left;"><p>{</p>
<p>"code": 200,</p>
<p>"message": "成功",</p>
<p>"data": null</p>
<p>}</p></td>
</tr>
</tbody>
</table>
失败示例:
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td><p>{</p>
<p>"code": 913,</p>
<p>"message": "不支持的开票服务器类型!",</p>
<p>"data": null</p>
<p>}</p></td>
</tr>
</tbody>
</table>

View File

@ -0,0 +1,181 @@
---
title: 发票交付
aliases:
- 发票交付
- 诺税通发票交付
- 开票主链路-发票交付
tags:
- water-docs
- nuoshuitong
- invoice-api
- obsidian
- single-interface
source_docx: ../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx
source_type: converted-and-split
---
# 发票交付
> [!info] 导航
> 上级索引:[[README]] · [[02_开票主链路]]
> 文档链接:[总索引](../README.md) · [分组页](../02_开票主链路.md) · [实施清单](../../NUOSHUITONG_SAAS_INTEGRATION_CHECKLIST.md)
> [!note] 来源
> 来源原件:[诺诺网-诺税通销项服务对外接口规范v1.3.18.docx](../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx)
> 接口分组:[[02_开票主链路]]
## 字段摘要
> [!summary] 接口元信息
> - 接口地址:`http[s]://\<host\>[:\<port\>]/salescore/lan/invoice/delivery.do`
> - 请求方式:`POST`
> - 是否回调:否
> - 是否主链路:是
> - 推荐优先级P1
## 发票交付
### 接口说明
发票交付接口,用于提供给企业对诺税通中开具的发票进行交付,具体的短信、邮件发送通道根据不同企业配置决定。
### 接口地址
| |
|:--------------------------------------------------------------------|
| http\[s\]://\<host\>\[:\<port\>\]/salescore/lan/invoice/delivery.do |
### 请求参数
<table>
<colgroup>
<col style="width: 23%" />
<col style="width: 13%" />
<col style="width: 11%" />
<col style="width: 24%" />
<col style="width: 16%" />
<col style="width: 11%" />
</colgroup>
<tbody>
<tr>
<td style="text-align: center;"><strong>名称</strong></td>
<td style="text-align: center;"><strong>类型</strong></td>
<td style="text-align: center;"><strong>必须</strong></td>
<td style="text-align: center;"><strong>示例值</strong></td>
<td style="text-align: center;"><strong>描述</strong></td>
<td style="text-align: center;"><strong>最大长度</strong></td>
</tr>
<tr>
<td style="text-align: left;">sellerTaxnum</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">150301199811285326</td>
<td style="text-align: left;">销方税号;销方税号和销方组织编码其一必填</td>
<td style="text-align: left;"></td>
</tr>
<tr>
<td style="text-align: left;">sellerCompanyCode</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">10162</td>
<td style="text-align: left;">销方组织编码;销方税号和销方组织编码其一必填</td>
<td style="text-align: left;"></td>
</tr>
<tr>
<td style="text-align: left;">invoiceCode</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">050001901011</td>
<td style="text-align: left;">发票代码12或10位</td>
<td style="text-align: left;">12</td>
</tr>
<tr>
<td style="text-align: left;">invoiceNumber</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">93693692</td>
<td style="text-align: left;"><p>发票号码</p>
<p>8或20位</p></td>
<td style="text-align: left;">20</td>
</tr>
<tr>
<td style="text-align: left;">notifyPhone</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: center;">交付手机号码;交付电话号码和交付邮箱至少有一个不为空,仅支持一个</td>
<td style="text-align: left;"></td>
</tr>
<tr>
<td style="text-align: left;">notifyEmail</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: center;">交付邮箱地址;交付电话号码和交付邮箱至少有一个不为空,仅支持一个</td>
<td style="text-align: left;"></td>
</tr>
<tr>
<td style="text-align: left;">ccPhone</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;">抄送手机号当推送手机notifyPhone有值时才允许填写多个中间用英文逗号隔开最多可填写5个</td>
<td style="text-align: left;">100</td>
</tr>
<tr>
<td style="text-align: left;">ccEmail</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;">抄送邮箱当推送邮箱notifyEmail有值时才允许填写多个中间用英文逗号隔开最多可填写5个</td>
<td style="text-align: left;">250</td>
</tr>
</tbody>
</table>
### 请求实例
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td><p>{</p>
<p>"sellerTaxnum": "150301199811285326",</p>
<p>"sellerCompanyCode": "",</p>
<p>"invoiceCode": "",</p>
<p>"invoiceNumber": "93693692",</p>
<p>"notifyPhone": "15669968255",</p>
<p>"notifyEmail": "zhuyihui@nnuo.com"</p>
<p>}</p></td>
</tr>
</tbody>
</table>
### 返回参数
| | | | | |
|:--------:|:--------:|:--------:|:-------------------------:|:--------:|
| **名称** | **类型** | **必填** | **描述** | **长度** |
| code | Integer | 是 | 状态,200-成功非200-失败 | 6 |
| message | String | 是 | 详细信息 | 1024 |
| data | Object | | | |
### 返回示例
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td><p>{</p>
<p>"code": 200,</p>
<p>"message": "成功",</p>
<p>"data": null</p>
<p>}</p></td>
</tr>
</tbody>
</table>

View File

@ -0,0 +1,146 @@
---
title: 发票作废申请接口
aliases:
- 发票作废申请接口
- 诺税通发票作废申请接口
- 作废重开与冲红-发票作废申请接口
tags:
- water-docs
- nuoshuitong
- invoice-api
- obsidian
- single-interface
source_docx: ../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx
source_type: converted-and-split
---
# 发票作废申请接口
> [!info] 导航
> 上级索引:[[README]] · [[03_作废重开与冲红]]
> 文档链接:[总索引](../README.md) · [分组页](../03_作废重开与冲红.md) · [实施清单](../../NUOSHUITONG_SAAS_INTEGRATION_CHECKLIST.md)
> [!note] 来源
> 来源原件:[诺诺网-诺税通销项服务对外接口规范v1.3.18.docx](../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx)
> 接口分组:[[03_作废重开与冲红]]
## 字段摘要
> [!summary] 接口元信息
> - 接口地址:`http[s]://\<host\>[:\<port\>]/salescore/lan/invalid-oneInvoice.do`
> - 请求方式:`POST`
> - 是否回调:否
> - 是否主链路:是
> - 推荐优先级P1
## 发票作废申请接口
### 接口说明
申请发票作废。
### 接口地址
| |
|:----------------------------------------------------------------------|
| http\[s\]://\<host\>\[:\<port\>\]/salescore/lan/invalid-oneInvoice.do |
### 请求参数
| | | | | | | |
|:--:|:--:|:--:|:--:|:--:|:--:|:--:|
| **名称** | **类型** | **必须** | **示例值** | **更多限制** | **描述** | **最大长度** |
| invoiceId | String | 是 | 18081620564001000232 | 必填 | 发票请求流水号 | 20 |
| sellerTaxnum | String | 否 | 339901999999610 | 企业税号和组织编码必填其一 | 发票对应的销方企业税号 | 20 |
| companyCode | String | 否 | | 企业税号和组织编码必填其一 | 组织编码 | 20 |
| invoiceCode | String | 是 | 125999915630 | 必填 | 对应发票代码 | 12 |
| invoiceNumber | String | 是 | 00130865 | 必填 | 对应发票号码 | 8 |
| invalidReason | Integer | 否 | | 数电纸票时需要传1:销货退回;2:开票有误;3:服务中止;4:其他),默认 2 | 作废原因 | 1 |
| specificReason | String | 否 | | 数电纸票且作废原因选择4-其他时需要传 | 其他作废原因详情 | 255 |
| columnFirst | String | 否 | 退货单号123 | 否 | 自定义列1 | |
| columnSecond | String | 否 | 退货单号123 | 否 | 自定义列2 | |
| columnThree | String | 否 | 退货单号123 | 否 | 自定义列3 | |
| <span id="_Toc14732" class="anchor"></span>invalidUserCode | String | 否 | 123 | 否 | 作废操作人用户编码优先使用操作人id | 20 |
| invalidUserId | Long | 否 | 1 | 否 | 作废操作人ID | 11 |
### 请求示例
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td style="text-align: left;"><p>{</p>
<p>"invoiceId": "18081620564001000232",</p>
<p>"sellerTaxnum": "339901999999610",</p>
<p>"invoiceCode": "125999915630",</p>
<p>"invoiceNumber": "00130865"</p>
<p>}</p></td>
</tr>
</tbody>
</table>
### 返回参数
| | | | | | | |
|:--:|:--:|:--:|:--:|:--:|:--:|:--:|
| **名称** | **类型** | **必须** | **示例值** | **更多限制** | **描述** | **最大长度** |
| code | Integer | 是 | 200 | | 状态,200-成功非200-失败 | 6 |
| message | String | 是 | 作废成功 | | 详细信息 | 1024 |
| data | String | 是 | 18081620564001000232 | | 提交成功则返回发票请求流水号 | 32 |
### 返回示例
成功示例:
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td style="text-align: left;"><p>{</p>
<p>"code": 200,</p>
<p>"message": "作废成功",</p>
<p>"data": "18081620564001000232"</p>
<p>}</p></td>
</tr>
</tbody>
</table>
失败示例:
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td style="text-align: left;"><p>{</p>
<p>"code": 9151,</p>
<p>"message": "非当月纸票不能作废"</p>
<p>}</p></td>
</tr>
</tbody>
</table>
### 状态码说明
| | |
|:----------:|:---------------------------------------------------------:|
| **状态码** | **描述** |
| 2733 | 发票不存在 |
| 2739 | 开票未完成,不可进行作废 |
| 2740 | 电票暂不支持作废 |
| 2741 | 发票被冲红不支持作废 |
| 2743 | 非当月发票不支持作废 |
| 2744 | 不支持重复作废 |
| 2749 | 发票已经作废 |
| 2751 | 企业税号不能为空 |
| 2755 | 入参invoiceId不能为空 |
| 2756 | 入参invoiceCode不能为空 |
| 2757 | 入参invoiceNumber不能为空 |
| 2758 | 入参invoiceId查询的发票记录中发票代码和入参发票代码不匹配 |
| 2759 | 入参invoiceId查询的发票记录中发票号码和入参发票号码不匹配 |

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,146 @@
---
title: 发票库存余量查询接口
aliases:
- 发票库存余量查询接口
- 诺税通发票库存余量查询接口
- 库存票源与打印-发票库存余量查询接口
tags:
- water-docs
- nuoshuitong
- invoice-api
- obsidian
- single-interface
source_docx: ../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx
source_type: converted-and-split
---
# 发票库存余量查询接口
> [!info] 导航
> 上级索引:[[README]] · [[06_库存票源与打印]]
> 文档链接:[总索引](../README.md) · [分组页](../06_库存票源与打印.md) · [实施清单](../../NUOSHUITONG_SAAS_INTEGRATION_CHECKLIST.md)
> [!note] 来源
> 来源原件:[诺诺网-诺税通销项服务对外接口规范v1.3.18.docx](../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx)
> 接口分组:[[06_库存票源与打印]]
## 字段摘要
> [!summary] 接口元信息
> - 接口地址:`http[s]://\<host\>[:\<port\>]/salescore/lan/queryStockInfoList.do`
> - 请求方式:`POST`
> - 是否回调:否
> - 是否主链路:是
> - 推荐优先级P1开票前保障
## 发票库存余量查询接口
### 接口说明
查询开票设备的发票库存余量。
### 接口地址
| |
|:----------------------------------------------------------------------|
| http\[s\]://\<host\>\[:\<port\>\]/salescore/lan/queryStockInfoList.do |
### 请求参数(用json格式接收)
| | | | | | |
|:--:|:--:|:--:|:--:|:--:|:--:|
| **名称** | **类型** | **必填** | **其他说明** | **描述** | **长度** |
| extensionNum | String | 否 | | 分机号 | 5 |
| machineNumber | String | 否 | | 机器编号 | 12 |
| sellerTaxnum | String | 否 | 销方税号、销方公司编码、销方公司名字三个必填其一 | 销方税号 | 20 |
| sellerCompanyCode | String | 否 | 销方税号、销方公司编码、销方公司名字三个必填其一 | 销方公司编码 | 20 |
| sellerCompanyName | String | 否 | 销方税号、销方公司编码、销方公司名字三个必填其一 | 销方公司名字 | 100 |
| searchRange | Integer | 否 | | 查询范围,0:全部,1:仅在诺税通开票设备中维护的设备余量信息;默认0 | 1 |
### 请求示例
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td><p>{</p>
<p>  "extensionNum": "0",</p>
<p>  "machineNumber": "661565671900",</p>
<p>  "sellerTaxnum": "150301199811285326",</p>
<p>  "sellerCompanyName":"移动测试盘326",</p>
<p>  "sellerCompanyCode" : "1100"</p>
<p>}</p></td>
</tr>
</tbody>
</table>
### 返回参数
| | | | | |
|:--:|:--:|:--:|:--:|:--:|
| **名称** | **类型** | **必填** | **描述** | **长度** |
| code | Integer | 是 | 状态,200-成功非200-失败 | 6 |
| message | String | 是 | 详细信息 | 1024 |
| data | List | | 查询成功则返回红字申请信息 | |
| 库存信息 | | | | |
| sellerTaxnum | String | | 销方税号 | |
| extensionNum | Integer | | 分机号 | |
| machineNumber | String | | 机器编号 | |
| stocks | List | | 库存信息列表 | |
| 库存明细 | | | | |
| terminalNum | Integer | | 终端号 | |
| invoiceLine | String | | 发票种类p:电子增值税普通发票c:增值税普通发票(纸票)s:增值税专用发票e:收购发票(电子)f:收购发票(纸质)r:增值税普通发票(卷式)b:增值税电子专用发票j机动车发票u二手车发票 | |
| invoiceCode | String | | 发票代码 | |
| invoiceNumStart | String | | 起始号码 | |
| inoviceNumEnd | String | | 终止号码 | |
| remainNum | Integer | | 剩余分数 | |
| isDefault | Integer | | 是否默认卷1-是 0-否(默认) | |
| createTime | Date | | 更新时间 | |
### 返回示例
成功示例:
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td><p>{</p>
<p>"code": 200,</p>
<p>"message": "成功",</p>
<p>"data": [</p>
<p>{</p>
<p>"sellerTaxnum": "150301199811285326",</p>
<p>"extensionNum": 0,</p>
<p>"machineNumber": null,</p>
<p>"stocks": [</p>
<p>{</p>
<p>"terminalNum": 0,</p>
<p>"invoiceLine": "s",</p>
<p>"invoiceCode": "5000201530",</p>
<p>"invoiceNumStart": "71895758",</p>
<p>"invoiceNumEnd": "0",</p>
<p>"remainNum": 0,</p>
<p>"createTime": "2021-06-04 17:20:24"</p>
<p>},</p>
<p>{</p>
<p>"terminalNum": 0,</p>
<p>"invoiceLine": "s",</p>
<p>"invoiceCode": "5000201530",</p>
<p>"invoiceNumStart": "85199644",</p>
<p>"invoiceNumEnd": "0",</p>
<p>"remainNum": 0,</p>
<p>"createTime": "2021-06-04 17:20:24"</p>
<p>}</p>
<p>]</p>
<p>}</p>
<p>]</p>
<p>}</p></td>
</tr>
</tbody>
</table>

View File

@ -0,0 +1,186 @@
---
title: 发票重开接口
aliases:
- 发票重开接口
- 诺税通发票重开接口
- 作废重开与冲红-发票重开接口
tags:
- water-docs
- nuoshuitong
- invoice-api
- obsidian
- single-interface
source_docx: ../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx
source_type: converted-and-split
---
# 发票重开接口
> [!info] 导航
> 上级索引:[[README]] · [[03_作废重开与冲红]]
> 文档链接:[总索引](../README.md) · [分组页](../03_作废重开与冲红.md) · [实施清单](../../NUOSHUITONG_SAAS_INTEGRATION_CHECKLIST.md)
> [!note] 来源
> 来源原件:[诺诺网-诺税通销项服务对外接口规范v1.3.18.docx](../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx)
> 接口分组:[[03_作废重开与冲红]]
## 字段摘要
> [!summary] 接口元信息
> - 接口地址:`http[s]://\<host\>[:\<port\>]/salescore/lan/reInvoice.do`
> - 请求方式:`POST`
> - 是否回调:否
> - 是否主链路:否
> - 推荐优先级:扩展/按需
## 发票重开接口
### 接口说明
当请求诺税通开具的发票返回开票失败时,可通过调用该接口触发开票失败的发票数据重新发起开票。
### 接口地址
| |
|--------------------------------------------------------------|
| http\[s\]://\<host\>\[:\<port\>\]/salescore/lan/reInvoice.do |
### 请求参数
<table>
<colgroup>
<col style="width: 22%" />
<col style="width: 13%" />
<col style="width: 11%" />
<col style="width: 38%" />
<col style="width: 13%" />
</colgroup>
<tbody>
<tr>
<td style="text-align: center;"><strong>名称</strong></td>
<td style="text-align: center;"><strong>类型</strong></td>
<td style="text-align: center;"><strong>必填</strong></td>
<td style="text-align: center;"><strong>描述</strong></td>
<td style="text-align: center;"><strong>长度</strong></td>
</tr>
<tr>
<td style="text-align: center;">sellerTaxNum</td>
<td style="text-align: center;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: center;"><p>销方税号</p>
<p>企业税号和组织编码必填其一</p></td>
<td style="text-align: center;">20</td>
</tr>
<tr>
<td style="text-align: center;">companyCode</td>
<td style="text-align: center;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: center;"><p>组织编码</p>
<p>企业税号和组织编码必填其一</p></td>
<td style="text-align: center;">20</td>
</tr>
<tr>
<td style="text-align: center;">invoiceId</td>
<td style="text-align: center;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">发票流水号(invoiceId和orderNo任一必填)</td>
<td style="text-align: center;">32</td>
</tr>
<tr>
<td style="text-align: center;">orderNo</td>
<td style="text-align: center;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">订单号(invoiceId和orderNo任一必填)</td>
<td style="text-align: center;">32</td>
</tr>
<tr>
<td style="text-align: center;">nextInvoiceCode</td>
<td style="text-align: center;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: left;"><p>下一张发票代码</p>
<p>支持票种c普通发票纸质f收购发票纸质</p>
<p>指定发票卷重开时必传</p></td>
<td style="text-align: center;">12</td>
</tr>
<tr>
<td style="text-align: left;">nextInvoiceNum</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;"></td>
<td style="text-align: left;"><p>下一张发票号码</p>
<p>支持票种c普通发票纸质f收购发票纸质</p>
<p>当【下一张发票代码】有值时,【下一张发票号码】和【发票终止号码】二选一必填</p></td>
<td style="text-align: left;"></td>
</tr>
<tr>
<td style="text-align: left;">invoiceNumEnd</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;"></td>
<td style="text-align: left;"><p>发票终止号码</p>
<p>支持票种c普通发票纸质f收购发票纸质</p>
<p>当【下一张发票代码】有值时,【下一张发票号码】和【发票终止号码】二选一必填</p></td>
<td style="text-align: center;"></td>
</tr>
</tbody>
</table>
### 请求示例
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td><p>{</p>
<p>"invoiceId": "21031114572601000143",</p>
<p>"orderNo": "21031114572601000143",</p>
<p>"sellerTaxnum": "150301199811285326",</p>
<p>"nextInvoiceNum": "1234456",</p>
<p>"nextInvoiceCode": "123456"</p>
<p>}</p></td>
</tr>
</tbody>
</table>
### 返回参数
| | | | | |
|:--------:|:--------:|:--------:|:-------------------------:|:--------:|
| **名称** | **类型** | **必填** | **描述** | **长度** |
| code | Integer | 是 | 状态,200-成功非200-失败 | 6 |
| message | String | 是 | 详细信息 | 1024 |
### 返回示例
成功示例:
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td><p>{</p>
<p>"code": 200,</p>
<p>"message": "成功"</p>
<p>}</p></td>
</tr>
</tbody>
</table>
失败示例:
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td><p>{</p>
<p>"code": 2733,</p>
<p>"message": "该发票不存在"</p>
<p>}</p></td>
</tr>
</tbody>
</table>

View File

@ -0,0 +1,140 @@
---
title: 审核开票删除回传接口
aliases:
- 审核开票删除回传接口
- 诺税通审核开票删除回传接口
- 车辆辅助与回传-审核开票删除回传接口
tags:
- water-docs
- nuoshuitong
- invoice-api
- obsidian
- single-interface
source_docx: ../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx
source_type: converted-and-split
---
# 审核开票删除回传接口
> [!info] 导航
> 上级索引:[[README]] · [[08_车辆辅助与回传]]
> 文档链接:[总索引](../README.md) · [分组页](../08_车辆辅助与回传.md) · [实施清单](../../NUOSHUITONG_SAAS_INTEGRATION_CHECKLIST.md)
> [!note] 来源
> 来源原件:[诺诺网-诺税通销项服务对外接口规范v1.3.18.docx](../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx)
> 接口分组:[[08_车辆辅助与回传]]
## 字段摘要
> [!summary] 接口元信息
> - 接口地址:`用户通过开票请求中的bizCallbackUrl字段提供回调地址。`
> - 请求方式:`POST`
> - 是否回调:是
> - 是否主链路:否
> - 推荐优先级:扩展/按需
## 审核开票删除回传接口
### 接口说明
返回审核开票删除信息的订单编号和税号等信息
注意:请按照文档要求提供接口。
### 接口地址
用户通过开票请求中的bizCallbackUrl字段提供回调地址。
### 请求参数(用json格式接收)
| | | | | | |
|:--:|:--:|:--:|:--:|:--:|:--:|
| **名称** | **类型** | **必须** | **示例值** | **描述** | **最大长度** |
| orderNo | String | 是 | 20220426094552511469 | 订单编号 | 64 |
| sellerTaxnum | String | 是 | 150301199811285326 | 销方税号 | 20 |
| invoiceStatus | Integer | 是 | 6 | 发票处理结果: 6审核开票删除 | 1 |
| formId | String | 否 | CB00696BD1094735849897E66029AB45 | 流程审批单id,回传给oa时必须 | 50 |
| formType | int | 否 | 2 | 流程类型1用印申请,2:蓝票开具申请,3:红票开具申请,4:发票作废申请),回传给oa时必须 | |
| deleteDate | String | 是 | 2022-04-26 14:45:30 | 删除时间yyyy-MM-dd HH:mm:ss格式 | |
| deleteUserId | long | 是 | 1 | 删除操作人id | |
| deleteUserName | String | 是 | 张三 | 删除操作人名称 | |
### 请求示例
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td><p>{</p>
<p>"deleteDate":"2022-04-29 15:51:39",</p>
<p>"deleteUserId":1,</p>
<p>"deleteUserName":"张三",</p>
<p>"formId":"7BCB5E90EAF64B9C903D920BF82591E4",</p>
<p>"formType":2,</p>
<p>"orderNo":"20220425091325328406",</p>
<p>"sellerTaxnum":"150301199811285326"</p>
<p>}</p></td>
</tr>
</tbody>
</table>
### 返回参数
<table>
<colgroup>
<col style="width: 15%" />
<col style="width: 12%" />
<col style="width: 8%" />
<col style="width: 16%" />
<col style="width: 30%" />
<col style="width: 17%" />
</colgroup>
<tbody>
<tr>
<td style="text-align: center;"><strong>名称</strong></td>
<td style="text-align: center;"><strong>类型</strong></td>
<td style="text-align: center;"><strong>必须</strong></td>
<td style="text-align: center;"><strong>示例值</strong></td>
<td style="text-align: center;"><strong>描述</strong></td>
<td style="text-align: center;"><strong>最大长度</strong></td>
</tr>
<tr>
<td style="text-align: left;">code</td>
<td style="text-align: left;">Integer</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">200</td>
<td style="text-align: left;"><p>状态,0000或200-成功,</p>
<p>非0000非200-失败</p></td>
<td style="text-align: left;">6</td>
</tr>
<tr>
<td style="text-align: left;">message</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">成功</td>
<td style="text-align: left;">详细信息</td>
<td style="text-align: left;">1024</td>
</tr>
</tbody>
</table>
### 返回示例
示例:
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td style="text-align: left;"><p>{</p>
<p>"code": 200,</p>
<p>"message": "成功"</p>
<p>}</p></td>
</tr>
</tbody>
</table>

View File

@ -0,0 +1,620 @@
---
title: 开票结果回传
aliases:
- 开票结果回传
- 诺税通开票结果回传
- 开票主链路-开票结果回传
tags:
- water-docs
- nuoshuitong
- invoice-api
- obsidian
- single-interface
source_docx: ../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx
source_type: converted-and-split
---
# 开票结果回传
> [!info] 导航
> 上级索引:[[README]] · [[02_开票主链路]]
> 文档链接:[总索引](../README.md) · [分组页](../02_开票主链路.md) · [实施清单](../../NUOSHUITONG_SAAS_INTEGRATION_CHECKLIST.md)
> [!note] 来源
> 来源原件:[诺诺网-诺税通销项服务对外接口规范v1.3.18.docx](../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx)
> 接口分组:[[02_开票主链路]]
## 字段摘要
> [!summary] 接口元信息
> - 接口地址:`用户通过开票请求中的bizCallbackUrl字段提供回调地址。`
> - 请求方式:`POST`
> - 是否回调:是
> - 是否主链路:是
> - 推荐优先级P0如采用回调模式
## 开票结果回传
### 接口说明
返回开票申请结果。
注意:请按照文档要求提供接口。
### 接口地址
用户通过开票请求中的bizCallbackUrl字段提供回调地址。
### 请求参数(用json格式接收)
<table>
<colgroup>
<col style="width: 15%" />
<col style="width: 12%" />
<col style="width: 8%" />
<col style="width: 15%" />
<col style="width: 14%" />
<col style="width: 20%" />
<col style="width: 13%" />
</colgroup>
<tbody>
<tr>
<td style="text-align: center;"><strong>名称</strong></td>
<td style="text-align: center;"><strong>类型</strong></td>
<td style="text-align: center;"><strong>必须</strong></td>
<td style="text-align: center;"><strong>示例值</strong></td>
<td style="text-align: center;"><strong>更多限制</strong></td>
<td style="text-align: center;"><strong>描述</strong></td>
<td style="text-align: center;"><strong>最大长度</strong></td>
</tr>
<tr>
<td style="text-align: left;">orderNo</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;">订单编号</td>
<td style="text-align: left;">64</td>
</tr>
<tr>
<td style="text-align: left;">sellerTaxnum</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">339901999999610</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">销方税号</td>
<td style="text-align: left;">20</td>
</tr>
<tr>
<td style="text-align: left;">invoiceId</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">20011617430401068182</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">发票流水号</td>
<td style="text-align: left;">32</td>
</tr>
<tr>
<td style="text-align: left;">successFlag</td>
<td style="text-align: left;">boolean</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">true</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">True:开票成功false开票失败</td>
<td style="text-align: left;">1</td>
</tr>
<tr>
<td style="text-align: left;">vehicleFlag</td>
<td style="text-align: left;">Integer</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">0</td>
<td style="text-align: left;">可不填默认0</td>
<td style="text-align: left;">0非机动车。1机动车</td>
<td style="text-align: left;">2</td>
</tr>
<tr>
<td style="text-align: left;">productOilFlag</td>
<td style="text-align: left;">Integer</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">0</td>
<td style="text-align: left;">可不填默认0</td>
<td style="text-align: left;">成品油标志0非成品油1成品油默认为0</td>
<td style="text-align: left;">2</td>
</tr>
<tr>
<td style="text-align: center;">invoiceStatus</td>
<td style="text-align: center;">Integer</td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;"><p>发票处理结果: 1:开票成功、 2:开票失败、3:作废成功、4:作废失败5:开票失败删除成功。</p>
<p>结果处于开票成功、 开票失败、作废成功、作废失败,开票失败删除成功触发回传</p></td>
<td style="text-align: center;">1</td>
</tr>
<tr>
<td style="text-align: left;">errorMessage</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">[9999]HX1000 4003-发票数据写盘失败[TCD_769_25,离线发票累计金额超限!],发票代码或号码为空</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">开票异常信息</td>
<td style="text-align: left;">128</td>
</tr>
<tr>
<td style="text-align: left;">pdfUrl</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">https://inv.jss.com.cn/group1/M00/A6/4C/wKgHPll_IU-AVELfAACNq5bmzFM769.pdf</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">发票pdf地址仅开票成功且版式文件为pdf时返回</td>
<td style="text-align: left;">255</td>
</tr>
<tr>
<td style="text-align: center;">paperPdfUrl</td>
<td style="text-align: center;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;">纸票pdf地址含底图</td>
<td style="text-align: center;">256</td>
</tr>
<tr>
<td style="text-align: left;">imageUrl</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;">发票jpg地址清单票发票主信息与清单信息以”,”隔开,仅开票成功会返回</td>
<td style="text-align: left;">255</td>
</tr>
<tr>
<td style="text-align: left;">ofdUrl</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;">发票ofd地址仅开票成功且版式文件为ofd时返回</td>
<td style="text-align: left;">255</td>
</tr>
<tr>
<td style="text-align: left;">orderDate</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">2022-05-12</td>
<td style="text-align: left;">年-月-日</td>
<td style="text-align: left;">订单日期</td>
<td style="text-align: left;">10</td>
</tr>
<tr>
<td style="text-align: left;">deliverDate</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">2022-05-12</td>
<td style="text-align: left;">年-月-日</td>
<td style="text-align: left;">发货日期</td>
<td style="text-align: left;">10</td>
</tr>
<tr>
<td style="text-align: left;">invoiceTime</td>
<td style="text-align: left;">Date</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">1604576878000</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">开票日期,仅开票成功会返回</td>
<td style="text-align: left;">13</td>
</tr>
<tr>
<td style="text-align: center;">invalidTime</td>
<td style="text-align: center;">Date</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">1615985882000</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">作废日期,仅作废成功后返回</td>
<td style="text-align: center;">13</td>
</tr>
<tr>
<td style="text-align: left;">invoiceCode</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">125999915630</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">发票代码,仅开票成功会返回</td>
<td style="text-align: left;">12</td>
</tr>
<tr>
<td style="text-align: left;">invoiceNumber</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">00130865</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">发票号码,仅开票成功会返回</td>
<td style="text-align: left;">20</td>
</tr>
<tr>
<td style="text-align: left;">allElectronicInvoiceNumber</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;">数电发票号码,仅数电发票(电票+纸票)开票成功会返回</td>
<td style="text-align: left;">20</td>
</tr>
<tr>
<td style="text-align: center;">oriInvoiceCode</td>
<td style="text-align: center;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;">红票对应的蓝票发票代码</td>
<td style="text-align: left;">12</td>
</tr>
<tr>
<td style="text-align: center;">oriInvoiceNumber</td>
<td style="text-align: center;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;">红票对应的蓝票发票号码</td>
<td style="text-align: left;">20</td>
</tr>
<tr>
<td style="text-align: center;">oldEleInvoiceNumber</td>
<td style="text-align: center;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;">红票对应的蓝票数电发票号码</td>
<td style="text-align: left;">20</td>
</tr>
<tr>
<td style="text-align: left;">billNo</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;">红字申请流水号,仅红字专票返回</td>
<td style="text-align: left;">24</td>
</tr>
<tr>
<td style="text-align: left;">billInfoNo</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;">红字申请表编号,仅红字专票返回</td>
<td style="text-align: left;">24</td>
</tr>
<tr>
<td style="text-align: left;">taxFreeAmountTotal</td>
<td style="text-align: left;">BigDecimal</td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;">不含税金额,仅开票成功会返回</td>
<td style="text-align: left;">15.2</td>
</tr>
<tr>
<td style="text-align: left;">taxTotal</td>
<td style="text-align: left;">BigDecimal</td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;">税额,仅开票成功会返回</td>
<td style="text-align: left;">15.2</td>
</tr>
<tr>
<td style="text-align: left;">taxAmountTotal</td>
<td style="text-align: left;">BigDecimal</td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;">含税金额,仅开票成功会返回</td>
<td style="text-align: left;">15.2</td>
</tr>
<tr>
<td style="text-align: left;">buyerName</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">浙江爱信诺</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">购方名称,仅开票成功会返回</td>
<td style="text-align: left;">100</td>
</tr>
<tr>
<td style="text-align: left;">buyerTaxnum</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">339901999999103</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">购方税号,仅开票成功会返回</td>
<td style="text-align: left;">20</td>
</tr>
<tr>
<td style="text-align: left;">sellerName</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">浙江爱信诺</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">销方名称,仅开票成功会返回</td>
<td style="text-align: left;">100</td>
</tr>
<tr>
<td style="text-align: left;">invoiceLine</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">1</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">发票种类p:电子增值税普通发票c:增值税普通发票(纸票)s:增值税专用发票e:收购发票(电子)f:收购发票(纸质)r:增值税普通发票(卷式)b:增值税电子专用发票j:机动车发票u二手车发票bs:数电专票(电子),pc:数电普票(电子)es:数电专票(纸质)ec:数电普票(纸质) 仅开票成功会返回</td>
<td style="text-align: left;">2</td>
</tr>
<tr>
<td style="text-align: center;">columnFirst</td>
<td style="text-align: center;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;">有值就回传</td>
<td style="text-align: center;">企业开票时传入自定义字段1</td>
<td style="text-align: center;"></td>
</tr>
<tr>
<td style="text-align: center;">columnSecond</td>
<td style="text-align: center;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;">有值就回传</td>
<td style="text-align: center;">企业开票时传入自定义字段2</td>
<td style="text-align: center;"></td>
</tr>
<tr>
<td style="text-align: center;">columnThree</td>
<td style="text-align: center;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;">有值就回传</td>
<td style="text-align: center;">企业开票时传入自定义字段3</td>
<td style="text-align: center;"></td>
</tr>
<tr>
<td style="text-align: left;">requestSrc</td>
<td style="text-align: center;">Integer</td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;">开票方式,0:api接口 1:手工开票 2:批量导入 5:本地提取</td>
<td style="text-align: center;">1</td>
</tr>
<tr>
<td style="text-align: left;">mailNo</td>
<td style="text-align: center;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;">快递单号</td>
<td style="text-align: center;"></td>
</tr>
<tr>
<td style="text-align: left;">businessType</td>
<td style="text-align: center;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;">枚举值来源为基础字典配置</td>
<td style="text-align: center;">业务类型</td>
<td style="text-align: center;"></td>
</tr>
<tr>
<td style="text-align: left;">relatedState</td>
<td style="text-align: center;">Integer</td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;">有值就回传</td>
<td style="text-align: center;">关联状态(0:未关联 1:关联中 2:关联成功 3:部分关联 4:关联失败)</td>
<td style="text-align: center;"></td>
</tr>
<tr>
<td style="text-align: left;">buyerManagerName</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;">购买方经办人姓名,数电特有字段</td>
<td style="text-align: left;">16</td>
</tr>
<tr>
<td style="text-align: left;">managerCardType</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: center;">101-组织机构代码证,102-营业执照,103-税务登记证, 199-其他单位证件, 201-居民身份证, 202-军官证, 203-武警警官证, 204-士兵证, 205-军队离退休干部证, 206-残疾人证, 207-残疾军人证1-8级, 208-外国护照, 210-港澳居民来往内地通行证, 212-中华人民共和国往来港澳通行证, 213-台湾居民来往大陆通行证, 214-大陆居民往来台湾通行证, 215-外国人居留证, 216-外交官证 299-其他个人证件</td>
<td style="text-align: left;">经办人证件类型数电特有字段</td>
<td style="text-align: left;">40</td>
</tr>
<tr>
<td style="text-align: left;">managerCardNo</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;">经办人证件号码数电特有字段,证件类型有值时必填</td>
<td style="text-align: left;">20</td>
</tr>
<tr>
<td style="text-align: left;">billId</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;">仅数电红票回传</td>
<td style="text-align: left;">红字确认单流水号</td>
<td style="text-align: left;">32</td>
</tr>
<tr>
<td style="text-align: left;">billConfirmNo</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;">仅数电红票回传</td>
<td style="text-align: left;">红字确认单编号</td>
<td style="text-align: left;">32</td>
</tr>
<tr>
<td style="text-align: left;">billUuid</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;">仅数电红票回传</td>
<td style="text-align: left;">红字确认单UUID</td>
<td style="text-align: left;">32</td>
</tr>
<tr>
<td style="text-align: left;">specificFactor</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;"><p>特定要素0普通发票 01成品油 03建筑服务 04货物运输发票 05不动产销售发票 06不动产租赁发票 09旅客运输发票 14机动车 16农产品收购 33二手车反向开具</p>
<p>35 矿产品发票</p></td>
<td style="text-align: left;">2</td>
</tr>
<tr>
<td style="text-align: left;">invalidReason</td>
<td style="text-align: left;">Integer</td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;">数电纸票作废原因 1:销货退回;2:开票有误;3:服务中止;4:其他(已作废状态下的发票,且票为数电纸票且回传其他信息时返回)</td>
<td style="text-align: left;">1</td>
</tr>
<tr>
<td style="text-align: left;">specificReason</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;">其他作废原因详情作废原因为4 且回传其他信息时返回)</td>
<td style="text-align: left;">255</td>
</tr>
<tr>
<td style="text-align: left;">subjectAccountCode</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">T123</td>
<td style="text-align: left;">核算主体编码</td>
<td style="text-align: left;">维护在诺税通的“核算主体编码”</td>
<td style="text-align: left;">200</td>
</tr>
<tr>
<td style="text-align: left;">subjectAccount</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">核算主体名称</td>
<td style="text-align: left;">核算主体名称</td>
<td style="text-align: left;">核算主体名称</td>
<td style="text-align: left;">200</td>
</tr>
<tr>
<td style="text-align: left;">redReason</td>
<td style="text-align: left;">Integer</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">1</td>
<td style="text-align: left;">1销售退回2开票有误3服务终止4销售折让</td>
<td style="text-align: left;">冲红原因</td>
<td style="text-align: left;">1</td>
</tr>
<tr>
<td style="text-align: left;">naturalPersonFlag</td>
<td style="text-align: left;">Integer</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">0</td>
<td style="text-align: left;"></td>
<td style="text-align: center;">购买方自然人标志0-否默认、1-是</td>
<td style="text-align: left;">2</td>
</tr>
<tr>
<td style="text-align: left;"><span id="_Toc30139" class="anchor"></span>customerCode</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: center;">客户编码</td>
<td style="text-align: left;">64</td>
</tr>
</tbody>
</table>
### 请求示例
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td style="text-align: left;"><p>{</p>
<p>"buyerName":"个人",</p>
<p>"buyerTaxnum":"339901999999142",</p>
<p>"imageUrl":"",</p>
<p>"invoiceCode":"131880930610",</p>
<p>"invoiceId":"20111014474101989690",</p>
<p>"invoiceLine":"p",</p>
<p>"invoiceNumber":"61001098",</p>
<p>"invoiceTime":1604994991000,</p>
<p>"orderNo":"20170104120207971529",</p>
<p>"pdfUrl":"https://invtest.nntest.cn/fp/tKhNlLpWjoP84chMYndBjLxrATHP7jJAEK71fHqOJVpzR7q39iU4mBTNBtjfHAANtFoj04OLAjWzfbYJIJhzhA.pdf",</p>
<p>"sellerName":"演示公司",</p>
<p>"successFlag":true,</p>
<p>"taxAmountTotal":1.09,</p>
<p>"taxFreeAmountTotal":0.09,</p>
<p>"sellerTaxnum":"339901999999610",</p>
<p>"taxTotal":0.01,</p>
<p>"taxOfficeCode":"税务机关代码",</p>
<p>"intactCertificateNum":"税务机关名称",</p>
<p>"organizationCode":"完整凭证号码",</p>
<p>"mailNo":"SF67263555514",</p>
<p>"relatedState":2,</p>
<p>"customerCode":"263555514"</p>
<p>}</p></td>
</tr>
</tbody>
</table>
### 返回参数
| | | | | | | |
|:--:|:--:|:--:|:--:|:--:|:--:|:--:|
| **名称** | **类型** | **必须** | **示例值** | **更多限制** | **描述** | **最大长度** |
| code | String | 是 | 0000 | | 状态码字符串”0000”表示成功非”0000”的字符串表示失败 | 6 |
| message | String | 是 | 同步成功 | | 详细信息 | 1024 |
### 返回示例
成功示例:
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td style="text-align: left;"><p>{</p>
<p>"code": "0000",</p>
<p>"message": "业务方接收同步成功"</p>
<p>}</p></td>
</tr>
</tbody>
</table>
失败示例:
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td style="text-align: left;"><p>{</p>
<p>"code": "9999",</p>
<p>"message": "同步失败的异常信息"</p>
<p>}</p></td>
</tr>
</tbody>
</table>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,106 @@
---
title: 录入自定义字段
aliases:
- 录入自定义字段
- 诺税通录入自定义字段
- 设备企业与配置-录入自定义字段
tags:
- water-docs
- nuoshuitong
- invoice-api
- obsidian
- single-interface
source_docx: ../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx
source_type: converted-and-split
---
# 录入自定义字段
> [!info] 导航
> 上级索引:[[README]] · [[07_设备企业与配置]]
> 文档链接:[总索引](../README.md) · [分组页](../07_设备企业与配置.md) · [实施清单](../../NUOSHUITONG_SAAS_INTEGRATION_CHECKLIST.md)
> [!note] 来源
> 来源原件:[诺诺网-诺税通销项服务对外接口规范v1.3.18.docx](../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx)
> 接口分组:[[07_设备企业与配置]]
## 字段摘要
> [!summary] 接口元信息
> - 接口地址:`http[s]://\<host\>[:\<port\>]/salescore/operation/definedColumn/batchSave.do`
> - 请求方式:`POST`
> - 是否回调:否
> - 是否主链路:否
> - 推荐优先级:扩展/按需
## 录入自定义字段
### 接口说明
根据订单号或流水号录入自定义字段信息。
### 接口地址
| |
|:---|
| http\[s\]://\<host\>\[:\<port\>\]/salescore/operation/definedColumn/batchSave.do |
### 请求参数
| | | | | |
|:--:|:--:|:--:|:--:|:--:|
| **名称** | **类型** | **必填** | **描述** | **长度** |
| sellerTaxnum | String | 是 | 销方税号 | 20 |
| orderNos | List | 否 | 订单号 订单号和发票流水号二选一必填,都传入则优先使用流水号 | 500 |
| invoiceIds | List | 否 | 发票流水号 订单号和发票流水号二选一必填,都传入则优先使用流水号 | 500 |
| columnFirst | String | 否 | 自定义字段一,三个自定义字段不可全为空 | \- |
| columnSecond | String | 否 | 自定义字段二,三个自定义字段不可全为空 | \- |
| columnThree | String | 否 | 自定义字段三,三个自定义字段不可全为空 | \- |
### 请求示例
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td style="text-align: left;"><p>{</p>
<p>"orderNos": [</p>
<p>"123456789"</p>
<p>],</p>
<p>"sellerTaxnum": "150301199811285326"</p>
<p>"columnFirst": "自定义字段1"</p>
<p>"columnSecond": "自定义字段2"</p>
<p>"columnThree": "自定义字段3"</p>
<p>}</p></td>
</tr>
</tbody>
</table>
### 返回参数
| | | | | | |
|:--------:|:--------:|:--------:|:----------:|:-------------------------:|:--------:|
| **名称** | **类型** | **必填** | **示例值** | **描述** | **长度** |
| code | Integer | 是 | 200 | 状态,200-成功非200-失败 | 6 |
| message | String | 是 | 成功 | 详细信息 | 1024 |
### 返回示例
成功示例:
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td><p>{</p>
<p>"code":200,</p>
<p>"message": "成功"</p>
<p>}</p></td>
</tr>
</tbody>
</table>

View File

@ -0,0 +1,402 @@
---
title: 快捷冲红接口
aliases:
- 快捷冲红接口
- 诺税通快捷冲红接口
- 作废重开与冲红-快捷冲红接口
tags:
- water-docs
- nuoshuitong
- invoice-api
- obsidian
- single-interface
source_docx: ../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx
source_type: converted-and-split
---
# 快捷冲红接口
> [!info] 导航
> 上级索引:[[README]] · [[03_作废重开与冲红]]
> 文档链接:[总索引](../README.md) · [分组页](../03_作废重开与冲红.md) · [实施清单](../../NUOSHUITONG_SAAS_INTEGRATION_CHECKLIST.md)
> [!note] 来源
> 来源原件:[诺诺网-诺税通销项服务对外接口规范v1.3.18.docx](../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx)
> 接口分组:[[03_作废重开与冲红]]
## 字段摘要
> [!summary] 接口元信息
> - 接口地址:`http[s]://\<host\>[:\<port\>]/salescore/lan/ fastRepeatedRedSingle.do`
> - 请求方式:`POST`
> - 是否回调:否
> - 是否主链路:否
> - 推荐优先级:扩展/按需
## 快捷冲红接口
### 接口说明
支持直接请求蓝字发票直接触发开具对应的红字发票或红字信息表。
注:数电发票使用此接口开取红票
### 接口地址
| |
|:---|
| http\[s\]://\<host\>\[:\<port\>\]/salescore/lan/ fastRepeatedRedSingle.do |
### 请求参数
<table>
<colgroup>
<col style="width: 25%" />
<col style="width: 14%" />
<col style="width: 5%" />
<col style="width: 43%" />
<col style="width: 11%" />
</colgroup>
<tbody>
<tr>
<td style="text-align: center;"><strong>名称</strong></td>
<td style="text-align: center;"><strong>类型</strong></td>
<td style="text-align: center;"><strong>必填</strong></td>
<td style="text-align: center;"><strong>描述</strong></td>
<td style="text-align: center;"><strong>长度</strong></td>
</tr>
<tr>
<td style="text-align: center;">sellerTaxnum</td>
<td style="text-align: center;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: left;"><p>销方税号15-20位</p>
<p>销方税号和组织编码必填其一</p></td>
<td style="text-align: center;">20</td>
</tr>
<tr>
<td style="text-align: center;">companyCode</td>
<td style="text-align: center;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: center;"><p>组织编码</p>
<p>企业税号和组织编码必填其一</p></td>
<td style="text-align: center;">20</td>
</tr>
<tr>
<td style="text-align: center;">invoiceId</td>
<td style="text-align: center;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">蓝票流水号 非数电发票时必填</td>
<td style="text-align: center;">20</td>
</tr>
<tr>
<td style="text-align: center;">invoiceCode</td>
<td style="text-align: left;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">蓝票发票代码 非数电发票时必填</td>
<td style="text-align: center;">12</td>
</tr>
<tr>
<td style="text-align: center;">invoiceNumber</td>
<td style="text-align: left;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">蓝票发票号码 非数电发票时必填</td>
<td style="text-align: center;">8</td>
</tr>
<tr>
<td style="text-align: center;">billId</td>
<td style="text-align: center;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: center;"><p>红字确认单申请单号</p>
<p>与billNo、billUuid三选一必填</p></td>
<td style="text-align: center;">32</td>
</tr>
<tr>
<td style="text-align: center;">billNo</td>
<td style="text-align: center;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: center;"><p>红字确认单编号 数电发票时填写</p>
<p>与billId、billUuid三选一必填</p></td>
<td style="text-align: center;">32</td>
</tr>
<tr>
<td style="text-align: center;">billUuid</td>
<td style="text-align: center;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: center;"><p>红字确认单uuid 数电发票时填写</p>
<p>与billId、billNo三选一必填</p></td>
<td style="text-align: center;">32</td>
</tr>
<tr>
<td style="text-align: center;">fastRedType</td>
<td style="text-align: left;">Integer</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">快捷冲红类型 不填或者0为普通快捷冲红 1:数电发票快捷冲红(数电发票必传1)</td>
<td style="text-align: center;">1</td>
</tr>
<tr>
<td style="text-align: center;">invoiceLine</td>
<td style="text-align: left;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: center;"><p>数电发票跨票种冲红时传入,发票票种:(非数电发票时不需要传)</p>
<p>bs:数电专票(电子),</p>
<p>pc:数电普票(电子)</p>
<p>es:数电专票(纸质)</p>
<p>ec:数电普票(纸质)</p>
<p>1、默认为对应蓝票数电票种</p>
<p>2、蓝票为es 时可选择 bs、es进行冲红</p>
<p>3、蓝票为ec时可选择pc、ec进行冲红</p>
<p>4、蓝票为数电电票时只能拿原票种冲红</p></td>
<td style="text-align: center;">2</td>
</tr>
<tr>
<td style="text-align: left;">orderNo</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">红字发票对应订单编号</td>
<td style="text-align: left;">64</td>
</tr>
<tr>
<td style="text-align: left;">columnFirst</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">自定义列1</td>
<td style="text-align: left;"></td>
</tr>
<tr>
<td style="text-align: left;">columnSecond</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">自定义列2</td>
<td style="text-align: left;"></td>
</tr>
<tr>
<td style="text-align: left;">columnThree</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">自定义列3</td>
<td style="text-align: left;"></td>
</tr>
</tbody>
</table>
### 请求示例
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td><p>{</p>
<p>"sellerTaxnum": "150301199811285326",</p>
<p>"invoiceId": "14111111111",</p>
<p>"invoiceCode": "11111111",</p>
<p>"invoiceNumber": "22222222",</p>
<p>"billId": "22222222",</p>
<p>"billNo": "22222222",</p>
<p>"billUuid": "123456",</p>
<p>"fastRedType": 1,</p>
<p>"invoiceLine": "es",</p>
<p>"orderNo": "123456908888",</p>
<p>"columnFirst": "c1",</p>
<p>"columnSecond": "c2",</p>
<p>"columnThree": "c3"</p>
<p>}</p></td>
</tr>
</tbody>
</table>
### 返回参数
<table>
<colgroup>
<col style="width: 20%" />
<col style="width: 11%" />
<col style="width: 8%" />
<col style="width: 46%" />
<col style="width: 13%" />
</colgroup>
<tbody>
<tr>
<td style="text-align: center;"><strong>名称</strong></td>
<td style="text-align: center;"><strong>类型</strong></td>
<td style="text-align: center;"><strong>必填</strong></td>
<td style="text-align: center;"><strong>描述</strong></td>
<td style="text-align: center;"><strong>长度</strong></td>
</tr>
<tr>
<td style="text-align: center;">code</td>
<td style="text-align: center;">Integer</td>
<td style="text-align: center;"></td>
<td style="text-align: center;"><p>状态,200-成功非200-失败</p>
<p>不代表冲红成功/失败</p></td>
<td style="text-align: center;">6</td>
</tr>
<tr>
<td style="text-align: center;">message</td>
<td style="text-align: center;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">详细信息</td>
<td style="text-align: center;">1024</td>
</tr>
<tr>
<td style="text-align: center;">data</td>
<td style="text-align: center;">Object</td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
</tr>
<tr>
<td colspan="5" style="text-align: center;">data内字段说明</td>
</tr>
<tr>
<td style="text-align: center;">sellerTaxnum</td>
<td style="text-align: center;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">销方税号</td>
<td style="text-align: center;">20</td>
</tr>
<tr>
<td style="text-align: center;">blueInvoiceId</td>
<td style="text-align: center;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">蓝票流水号 非数电发票时必填</td>
<td style="text-align: center;">20</td>
</tr>
<tr>
<td style="text-align: center;">blueInvoiceCode</td>
<td style="text-align: center;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">蓝票代码 非数电发票时必填</td>
<td style="text-align: center;">12</td>
</tr>
<tr>
<td style="text-align: center;">blueInvoiceNumber</td>
<td style="text-align: center;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">蓝票号码 非数电发票时必填</td>
<td style="text-align: center;">8</td>
</tr>
<tr>
<td style="text-align: center;">redInvoiceId</td>
<td style="text-align: center;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">(蓝票非专票时的字段)红票流水号,非专票时必有值</td>
<td style="text-align: center;">20</td>
</tr>
<tr>
<td style="text-align: center;">redOrderNo</td>
<td style="text-align: center;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">(蓝票非专票时的字段)红票orderNo非专票时必有值</td>
<td style="text-align: center;">64</td>
</tr>
<tr>
<td style="text-align: center;">redBillNo</td>
<td style="text-align: center;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">(蓝票专票时的字段)红字信息表流水号(billNo),不是billInfoNo。专票时必有值</td>
<td style="text-align: center;">24</td>
</tr>
<tr>
<td style="text-align: center;">reason</td>
<td style="text-align: center;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">失败原因,冲红失败时才会有值</td>
<td style="text-align: center;">2000</td>
</tr>
<tr>
<td style="text-align: center;">billId</td>
<td style="text-align: center;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">红字确认单申请单号</td>
<td style="text-align: center;">32</td>
</tr>
<tr>
<td style="text-align: center;">billNo</td>
<td style="text-align: center;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">红字确认单编号 数电发票时必填</td>
<td style="text-align: center;">32</td>
</tr>
<tr>
<td style="text-align: center;">billUuid</td>
<td style="text-align: center;">String</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">红字确认单uuid 数电发票时必填</td>
<td style="text-align: center;">32</td>
</tr>
<tr>
<td style="text-align: center;">fastRedType</td>
<td style="text-align: left;">Integer</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">快捷冲红类型 不填或者0为普通快捷冲红 1:数电快捷冲红(数电发票必传1)</td>
<td style="text-align: center;">1</td>
</tr>
</tbody>
</table>
### 返回示例
成功示例:
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td style="text-align: left;"><p>{</p>
<p>"code": 200,</p>
<p>"message": "成功",</p>
<p>"data": {</p>
<p>"blueInvoiceId": "21122410310201000295",</p>
<p>"blueInvoiceCode": "111100020026",</p>
<p>"blueInvoiceNumber": "92482083",</p>
<p>"redInvoiceId": "12312312312",</p>
<p>"redOrderNo": "12123123123123",</p>
<p>"redBillNo": null,</p>
<p>"billId": "22222222",</p>
<p>"billNo": "22222222",</p>
<p>"billUuid": "123456",</p>
<p>"fastRedType": 1,</p>
<p>"reason": ""</p>
<p>}</p>
<p>}</p></td>
</tr>
<tr>
<td style="text-align: left;"></td>
</tr>
</tbody>
</table>
失败示例:
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td><p>{</p>
<p>"code": 200,</p>
<p>"message": "成功",</p>
<p>"data": {</p>
<p>"blueInvoiceId": "21122410310201000295",</p>
<p>"blueInvoiceCode": "111100020026",</p>
<p>"blueInvoiceNumber": "92482083",</p>
<p>"redInvoiceId": null,</p>
<p>"redOrderNo": null,</p>
<p>"redBillNo": null,</p>
<p>"redBillNo": null,</p>
<p>"billId": "22222222",</p>
<p>"billNo": "22222222",</p>
<p>"billUuid": "123456",</p>
<p>"fastRedType": 1,</p>
<p>"reason": "未知异常"</p>
<p>}</p>
<p>}</p></td>
</tr>
</tbody>
</table>

View File

@ -0,0 +1,122 @@
---
title: 成品油库存下载接口
aliases:
- 成品油库存下载接口
- 诺税通成品油库存下载接口
- 专项能力-成品油库存下载接口
tags:
- water-docs
- nuoshuitong
- invoice-api
- obsidian
- single-interface
source_docx: ../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx
source_type: converted-and-split
---
# 成品油库存下载接口
> [!info] 导航
> 上级索引:[[README]] · [[09_专项能力]]
> 文档链接:[总索引](../README.md) · [分组页](../09_专项能力.md) · [实施清单](../../NUOSHUITONG_SAAS_INTEGRATION_CHECKLIST.md)
> [!note] 来源
> 来源原件:[诺诺网-诺税通销项服务对外接口规范v1.3.18.docx](../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx)
> 接口分组:[[09_专项能力]]
## 字段摘要
> [!summary] 接口元信息
> - 接口地址:`http[s]://\<host\>[:\<port\>]/salescore/lan/oilStock/downloadProductOil.do`
> - 请求方式:`POST`
> - 是否回调:否
> - 是否主链路:否
> - 推荐优先级:扩展/按需
## 成品油库存下载接口
### 接口说明
触发从税局局端下载成品油库存到税盘的接口
### 接口地址
| |
|:---|
| http\[s\]://\<host\>\[:\<port\>\]/salescore/lan/oilStock/downloadProductOil.do |
### 请求参数
| | | | | |
|:-------------:|:--------:|:--------:|:------------------:|:--------:|
| **名称** | **类型** | **必填** | **描述** | **长度** |
| sellerTaxnum | String | 是 | 销方税号15-20位 | 20 |
| extensionNum | Integer | 是 | 分机号,纯数字 | \- |
| machineNumber | String | 否 | 机器编号12位数字 | 12 |
| taxCode | String | 是 | 税收分类编码 | 19 |
| num | Double | 是 | 下载数量(升) | \- |
### 请求示例
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td><p>{</p>
<p>"extensionNum": 0,</p>
<p>"machineNumber": "661565671900",</p>
<p>"num": 1,</p>
<p>"sellerTaxnum": "150301199811285326",</p>
<p>"taxCode": "1070101060100000000"</p>
<p>}</p></td>
</tr>
</tbody>
</table>
### 返回参数
| | | | | |
|:--------:|:--------:|:--------:|:-------------------------:|:--------:|
| **名称** | **类型** | **必填** | **描述** | **长度** |
| code | Integer | 是 | 状态,200-成功非200-失败 | 6 |
| message | String | 是 | 详细信息 | 1024 |
| data | Object | | | |
### 返回示例
成功示例:
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td style="text-align: left;"><p>{</p>
<p>"code": 200,</p>
<p>"message": "成功",</p>
<p>"data": null</p>
<p>}</p></td>
</tr>
</tbody>
</table>
失败示例:
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td><p>{</p>
<p>"code": 913,</p>
<p>"message": "[AA99]库存不够!",</p>
<p>"data": null</p>
<p>}</p></td>
</tr>
</tbody>
</table>

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,100 @@
---
title: 批量获取信息转换配置接口
aliases:
- 批量获取信息转换配置接口
- 诺税通批量获取信息转换配置接口
- 设备企业与配置-批量获取信息转换配置接口
tags:
- water-docs
- nuoshuitong
- invoice-api
- obsidian
- single-interface
source_docx: ../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx
source_type: converted-and-split
---
# 批量获取信息转换配置接口
> [!info] 导航
> 上级索引:[[README]] · [[07_设备企业与配置]]
> 文档链接:[总索引](../README.md) · [分组页](../07_设备企业与配置.md) · [实施清单](../../NUOSHUITONG_SAAS_INTEGRATION_CHECKLIST.md)
> [!note] 来源
> 来源原件:[诺诺网-诺税通销项服务对外接口规范v1.3.18.docx](../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx)
> 接口分组:[[07_设备企业与配置]]
## 字段摘要
> [!summary] 接口元信息
> - 接口地址:`http[s]://\<host\>[:\<port\>]/salescore/lan/infoConvert/batch.do`
> - 请求方式:`POST`
> - 是否回调:否
> - 是否主链路:否
> - 推荐优先级:扩展/按需
## 批量获取信息转换配置接口
### 接口说明
批量获取信息转换配置供应链使用最多支持500个税号的查询。
### 接口地址
| |
|:---------------------------------------------------------------------|
| http\[s\]://\<host\>\[:\<port\>\]/salescore/lan/infoConvert/batch.do |
请求方式POST
Content-Typeapplication/x-www-form-urlencoded
### 请求参数
| | | | | |
|:----------:|:----------:|:--------:|:-------------------------------:|:--------:|
| **名称** | **类型** | **必填** | **描述** | **长度** |
| taxNumList | String\[\] | 是 | 销方税号列表最多支持500组税号 | \- |
### 返回参数
| | | | | |
|:--:|:--:|:--:|:--:|:--:|
| **名称** | **类型** | **必填** | **描述** | **长度** |
| code | Integer | 是 | 状态,200-成功非200-失败 | 6 |
| message | String | 是 | 详细信息 | 1024 |
| data | Object | | | |
| data内字段说明 | | | | |
| taxnum | String | 是 | 销方税号 | |
| customerOpenFlag | int | 是 | 客户信息转换开关:0-关1-开默认值0 | |
| customerProcessNode | String | 是 | 客户信息处理节点提交开票时SUBMIT_INVOICE,创建订单时ORDER_SAVE,开票时INVOICE | |
| goodsOpenFlag | int | 是 | 商品信息转换开关:0-关1-开默认值0 | |
| goodsProcessNode | String | 是 | 商品信息处理节点提交开票时SUBMIT_INVOICE,创建订单时ORDER_SAVE,开票时INVOICE | |
### 返回示例
成功示例:
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td style="text-align: left;"><p>{</p>
<p>"code": 200,</p>
<p>"message": "成功",</p>
<p>"data": [</p>
<p>{</p>
<p>"taxnum": "150301199811285326",</p>
<p>"goodsOpenFlag": 1,</p>
<p>"goodsProcessNode": "INVOICE",</p>
<p>"customerOpenFlag": 1,</p>
<p>"customerProcessNode": "INVOICE"</p>
<p>}</p>
<p>]</p>
<p>}</p></td>
</tr>
</tbody>
</table>

View File

@ -0,0 +1,148 @@
---
title: 批量获取备注配置信息接口
aliases:
- 批量获取备注配置信息接口
- 诺税通批量获取备注配置信息接口
- 设备企业与配置-批量获取备注配置信息接口
tags:
- water-docs
- nuoshuitong
- invoice-api
- obsidian
- single-interface
source_docx: ../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx
source_type: converted-and-split
---
# 批量获取备注配置信息接口
> [!info] 导航
> 上级索引:[[README]] · [[07_设备企业与配置]]
> 文档链接:[总索引](../README.md) · [分组页](../07_设备企业与配置.md) · [实施清单](../../NUOSHUITONG_SAAS_INTEGRATION_CHECKLIST.md)
> [!note] 来源
> 来源原件:[诺诺网-诺税通销项服务对外接口规范v1.3.18.docx](../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx)
> 接口分组:[[07_设备企业与配置]]
## 字段摘要
> [!summary] 接口元信息
> - 接口地址:`http[s]://\<host\>[:\<port\>]/salescore/lan/config/remarkConf/batch.do`
> - 请求方式:`POST`
> - 是否回调:否
> - 是否主链路:否
> - 推荐优先级:扩展/按需
## 批量获取备注配置信息接口
### 接口说明
批量获取备注配置信息供应链使用最多支持500组数据的查询。
### 接口地址
| |
|:---|
| http\[s\]://\<host\>\[:\<port\>\]/salescore/lan/config/remarkConf/batch.do |
### 请求参数
| | | | | |
|:------------:|:--------:|:--------:|:--------:|:--------:|
| **名称** | **类型** | **必填** | **描述** | **长度** |
| taxnum | String | 否 | 企业税号 | 20 |
| businessType | String | 否 | 业务标识 | 2 |
| processNode | String | 否 | 处理节点 | 100 |
| buyerTaxnum | String | 否 | 购方税号 | 20 |
| buyerName | String | 否 | 购方名称 | 100 |
### 请求示例
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td><p>[</p>
<p>{</p>
<p>"businessType": "1",</p>
<p>"buyerName": "",</p>
<p>"buyerTaxnum": "",</p>
<p>"processNode": "INVOICE",</p>
<p>"taxnum": "3333333333333333"</p>
<p>}</p>
<p>]</p></td>
</tr>
</tbody>
</table>
### 返回参数
| | | | | | |
|:--:|:--:|:--:|:--:|:--:|:--:|
| **名称** | | **类型** | **必填** | **描述** | **长度** |
| code | | Integer | 是 | 状态,200-成功非200-失败 | 6 |
| message | | String | 是 | 详细信息 | 1024 |
| data | | Object | | | |
| data内字段说明 | | | | | |
| taxnum | | String | | 企业税号 | 20 |
| businessType | | String | | 业务标识 | 2 |
| processNode | | String | | 处理节点 | 100 |
| buyerTaxnum | | String | | 请求中的购方税号 | 20 |
| buyerName | | String | | 请求中的购方名称 | 100 |
| configs | | Object | | 备注配置信息 | \- |
| buyerInfoList | | Object | | 模板的全部购方信息 | \- |
| configs内字段说明 | | | | | |
| idx | | int | | 序号 | |
| paramCode | | String | | 对应参数代码 | |
| remarkTitle | | String | | 备注名称 | |
| rowNo | | int | | 行号 | |
| valSource | | int | | 取值来源 | |
| buyerInfoList内字段说明 | | | | | |
| buyerTaxnum | String | | | 购方税号 | |
| buyerName | String | | | 购方名称 | |
### 返回示例
成功示例:
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td style="text-align: left;"><p>{</p>
<p>"code": 200,</p>
<p>"message": "成功",</p>
<p>"data": [</p>
<p>{</p>
<p>"taxnum": "3333333333333333",</p>
<p>"businessType": "1",</p>
<p>"processNode": "INVOICE",</p>
<p>"buyerName": "",</p>
<p>"buyerTaxnum": "",</p>
<p>"configs": [</p>
<p>{</p>
<p>"idx": 0,</p>
<p>"rowNo": 1,</p>
<p>"remarkTitle": "出口",</p>
<p>"paramCode": "",</p>
<p>"valSource": 1</p>
<p>},</p>
<p>{</p>
<p>"idx": 1,</p>
<p>"rowNo": 2,</p>
<p>"remarkTitle": "外币金额:",</p>
<p>"paramCode": "FOREIGN_CURRENCY_AMOUNT",</p>
<p>"valSource": 1</p>
<p>}</p>
<p>]</p>
<p>}</p>
<p>]</p>
<p>}</p></td>
</tr>
</tbody>
</table>

View File

@ -0,0 +1,121 @@
---
title: 抄报清卡
aliases:
- 抄报清卡
- 诺税通抄报清卡
- 专项能力-抄报清卡
tags:
- water-docs
- nuoshuitong
- invoice-api
- obsidian
- single-interface
source_docx: ../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx
source_type: converted-and-split
---
# 抄报清卡
> [!info] 导航
> 上级索引:[[README]] · [[09_专项能力]]
> 文档链接:[总索引](../README.md) · [分组页](../09_专项能力.md) · [实施清单](../../NUOSHUITONG_SAAS_INTEGRATION_CHECKLIST.md)
> [!note] 来源
> 来源原件:[诺诺网-诺税通销项服务对外接口规范v1.3.18.docx](../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx)
> 接口分组:[[09_专项能力]]
## 字段摘要
> [!summary] 接口元信息
> - 接口地址:`http[s]://\<host\>[:\<port\>]/salescore/extensioninfo/reportAndClear.do`
> - 请求方式:`POST`
> - 是否回调:否
> - 是否主链路:否
> - 推荐优先级:扩展/按需
## 抄报清卡
### 接口说明
触发抄报清卡
### 接口地址
| |
|:---|
| http\[s\]://\<host\>\[:\<port\>\]/salescore/extensioninfo/reportAndClear.do |
### 请求参数
| | | | | |
|:------------:|:--------:|:--------:|:--------:|:--------:|
| **名称** | **类型** | **必填** | **描述** | **长度** |
| taxnum | String | 是 | 销方税号 | 20 |
| extensionNum | String | 否 | 分机号 | |
| machineNum | String | 否 | 机器号 | |
### 请求示例
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td><p>{</p>
<p>"taxnum": "150301199811285326",</p>
<p>"extensionNum": "1",</p>
<p>"machineNum": "123456789123"</p>
<p>}</p></td>
</tr>
</tbody>
</table>
### 返回参数
| | | | | |
|:------------:|:--------:|:--------:|:--------------------------:|:--------:|
| **名称** | **类型** | **必填** | **描述** | **长度** |
| code | Integer | 是 | 状态,200-成功非200-失败 | 6 |
| message | String | 是 | 详细信息 | 1024 |
| data | String | 否 | 触发失败的原因以及设备信息 | |
| extensionNum | String | 否 | 分机号 | |
| machineNum | String | 否 | 机器号 | |
| reason | String | 否 | 触发失败的原因 | |
### 返回示例
成功示例:
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td style="text-align: left;"><p>{</p>
<p>"code": 200,</p>
<p>"message": "成功",</p>
<p>"data": null</p>
<p>}</p></td>
</tr>
</tbody>
</table>
失败返回示例:
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td style="text-align: left;"><p>{</p>
<p>"code": 400,</p>
<p>"message": "税号不能为空",</p>
<p>"data": null</p>
<p>}</p></td>
</tr>
</tbody>
</table>

View File

@ -0,0 +1,124 @@
---
title: 授信额度刷新接口
aliases:
- 授信额度刷新接口
- 诺税通授信额度刷新接口
- 专项能力-授信额度刷新接口
tags:
- water-docs
- nuoshuitong
- invoice-api
- obsidian
- single-interface
source_docx: ../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx
source_type: converted-and-split
---
# 授信额度刷新接口
> [!info] 导航
> 上级索引:[[README]] · [[09_专项能力]]
> 文档链接:[总索引](../README.md) · [分组页](../09_专项能力.md) · [实施清单](../../NUOSHUITONG_SAAS_INTEGRATION_CHECKLIST.md)
> [!note] 来源
> 来源原件:[诺诺网-诺税通销项服务对外接口规范v1.3.18.docx](../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx)
> 接口分组:[[09_专项能力]]
## 字段摘要
> [!summary] 接口元信息
> - 接口地址:`http[s]://\<host\>[:\<port\>]/salescore/lan/creditQuota/query.do`
> - 请求方式:`POST`
> - 是否回调:否
> - 是否主链路:否
> - 推荐优先级:扩展/按需
## 授信额度刷新接口
### 接口说明
获取数电发票税局最新授信额度,该接口根据不同设备类型返回不同结果。如果乐企模式则同步返回授信额度数据。如果非乐企模式为异步查询需搭配接口3.57使用,来获取查询结果。
### 接口地址
| |
|:---------------------------------------------------------------------|
| http\[s\]://\<host\>\[:\<port\>\]/salescore/lan/creditQuota/query.do |
### 请求参数
| | | | | | |
|:--:|:--:|:--:|:--:|:--:|:--:|
| **名称** | **类型** | **必填** | **说明** | **描述** | **长度** |
| taxNum | String | 是 | 需要查询的企业税号 | 企业税号 | 20 |
| type | Integer | 否 | 分机号与请求类型二选一必填,均传入已分机号匹配到的设备为准 | 请求类型 0:乐企 1:数电普通 | \- |
| extensionNum | Integer | 否 | 分机号与请求类型二选一必填,均传入已分机号匹配到的设备为准 | 分机号 | 0-99999 |
### 请求示例
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td style="text-align: left;"><p>{</p>
<p>"taxNum": "150301199811285326",</p>
<p>"type": 1</p>
<p>}</p></td>
</tr>
</tbody>
</table>
### 返回参数
| | | | | | |
|:--:|:--:|:--:|:--:|:--:|:--:|
| **名称** | **类型** | **必填** | **示例值** | **描述** | **长度** |
| code | Integer | 是 | 200 | 状态,200-成功非200-失败 | 6 |
| message | String | 是 | 成功 | 详细信息 | 1024 |
| data | Object | 是 | | 查询对象 | |
| 乐企模式返回字段 | | | | | |
| creditFlag | String | 是 | Y | 暂停授信标志 Y暂停 N未暂停 | 1 |
| creditQuotaAmount | BigDecimal | 是 | 10000.00 | 本月授信额度 | 12,2 |
| downloadAmount | BigDecimal | 是 | 10000.00 | 可用剩余额度 | 12,2 |
| downloadRemainAmount | BigDecimal | 是 | 10000.00 | 已下载额度 | 12,2 |
| remainAmount | BigDecimal | 是 | 10000.00 | 已下载未使用额度 | 12,2 |
| taxnum | String | 是 | 150301199811285326 | 企业税号 | 20 |
| vestPeriod | String | 否 | 202303 | 属期 格式yyyyMM | |
| creditUpdateTime | Date | 是 | 2023-03-06 00:00:00 | 授信额度更新时间 | |
### 返回示例
成功示例:
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td><p>{</p>
<p>"code": "200",</p>
<p>"message": "查询成功" ,</p>
<p>"data": {</p>
<p>"creditFlag": "Y",</p>
<p>"creditQuotaAmount": "10000.00" ,</p>
<p>"downloadAmount": "10000.00",</p>
<p>"downloadRemainAmount": "10000.00",</p>
<p>"remainAmount": "10000.00",</p>
<p>"taxnum": "150301199811285326",</p>
<p>"vestPeriod": "202303",</p>
<p>"creditUpdateTime": "2023-03-06 00:00:00"</p>
<p>}</p>
<p>}</p>
<p>非乐企:</p>
<p>{</p>
<p>"code": "200",</p>
<p>"message": "查询成功" ,</p>
<p>"data": ""</p>
<p>}</p></td>
</tr>
</tbody>
</table>

View File

@ -0,0 +1,123 @@
---
title: 新增/修改企业开票信息
aliases:
- 新增/修改企业开票信息
- 诺税通新增/修改企业开票信息
- 设备企业与配置-新增/修改企业开票信息
tags:
- water-docs
- nuoshuitong
- invoice-api
- obsidian
- single-interface
source_docx: ../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx
source_type: converted-and-split
---
# 新增/修改企业开票信息
> [!info] 导航
> 上级索引:[[README]] · [[07_设备企业与配置]]
> 文档链接:[总索引](../README.md) · [分组页](../07_设备企业与配置.md) · [实施清单](../../NUOSHUITONG_SAAS_INTEGRATION_CHECKLIST.md)
> [!note] 来源
> 来源原件:[诺诺网-诺税通销项服务对外接口规范v1.3.18.docx](../../../design/04_Appendix/Archive/03_Design_Docs/诺诺网-诺税通销项服务对外接口规范v1.3.18.docx)
> 接口分组:[[07_设备企业与配置]]
## 字段摘要
> [!summary] 接口元信息
> - 接口地址:`http[s]://\<host\>[:\<port\>]/salescore/lan/seller/save.do`
> - 请求方式:`POST`
> - 是否回调:否
> - 是否主链路:否
> - 推荐优先级:扩展/按需
## 新增/修改企业开票信息
### 接口说明
创建/修改企业开票信息接口
### 接口地址
| |
|:---------------------------------------------------------------|
| http\[s\]://\<host\>\[:\<port\>\]/salescore/lan/seller/save.do |
### 请求参数
| | | | | |
|:--:|:--:|:--:|:--:|:--:|
| **名称** | **类型** | **必填** | **描述** | **长度** |
| taxNum | String | 是 | 企业税号 | 1520 |
| useScope | Integer | 必填 | 使用范围0企业,1:个人,2部门,3项目 | 1 |
| clerker | String | 必填 | 使用范围是个人时必填,填入用户管理手机号,使用范围为公司、部门、项目时非必填,直接填入值 | 100 |
| sellerAddress | String | 必填 | 公司地址 | 100 |
| sellerTel | String | 必填 | 公司电话 | 20 |
| sellerBank | String | 必填 | 开户银行 | 100 |
| sellerAccount | String | 必填 | 银行账号 | 50 |
| payee | String | 选填 | 收款人 | 20 |
| checker | String | 选填 | 复核人 | 20 |
| projectCode | String | 选填 | 当前企业下的项目编码 使用范围为项目时必填 | 64 |
| departmentName | String | 选填 | 当前企业下的部门名称 使用范围为部门时必填 | 100 |
注意:
1. 公司地址+公司电话总共不得超过100个字符
2. 开户银行+银行账号总共不得超过100个字符
### 请求示例
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td style="text-align: left;"><p>{</p>
<p>  "taxNum": "33333333333333333",</p>
<p>  "useScope": 1,</p>
<p>  "clerker": "13655554433",</p>
<p>  "sellerAddress": "地址",</p>
<p>  "sellerTel": "tel",</p>
<p>  "sellerAccount": "account",</p>
<p>  "sellerBank": "bank",</p>
<p>  "payee": "",</p>
<p>  "checker": "",</p>
<p>"projectCode": "test123",</p>
<p>  "departmentName": "测试部门"</p>
<p>}</p></td>
</tr>
</tbody>
</table>
### 返回参数
| | | | | |
|:--------:|:--------:|:--------:|:-------------------------:|:--------:|
| **名称** | **类型** | **必填** | **描述** | **长度** |
| code | Integer | 是 | 状态,200-成功非200-失败 | 6 |
| message | String | 是 | 详细信息 | 1024 |
| data | Object | | | |
### 返回示例
成功示例:
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr>
<td style="text-align: left;"><p>{</p>
<p>"code": 200,</p>
<p>"message": "成功",</p>
<p>"data": null</p>
<p>}</p></td>
</tr>
</tbody>
</table>

Some files were not shown because too many files have changed in this diff Show More