企业支付 / 框架

Odoo 企业版 ISO 20022 付款文件为什么不是“导出一份 XML”:分组、银行契约与导出守卫讲透

account_iso20022 并不只是把付款序列化成 XML;它先校验 IBAN 与币种、生成 end-to-end / UETR 标识,再由

企业 框架
进阶 开发者 1 分钟阅读
0 评论 0 点赞 0 收藏 5 阅读

很多人看到 ISO 20022 导出,会自然把它想成“把付款记录吐成一个 XML 文件”。但企业版 account_iso20022 的实现告诉你:真正难的不是 XML 语法,而是付款在导出前是否合规、标识是否稳定、journal 如何按银行契约拼装文档结构

一、付款对象先过合规门槛,才谈导出

account_payment.py 里的 _check_sepa_bank_account()_check_sepa_currency() 很直接:SEPA 付款必须有正确的 IBAN,且币种必须是 EUR。也就是说,导出不是出错时才校验,而是在付款对象层就先挡掉明显不合法的数据。

这很像框架里的“前置契约检查”:只要付款本身不满足银行网络要求,后面的 XML 生成就不该开始。

二、稳定标识不是装饰品,而是银行链路必需品

_compute_end_to_end_uuid()_compute_iso20022_uetr() 会为符合条件的付款自动生成 end-to-end id 与 UETR。它们的意义不在“多两个字段”,而在于:

  • 银行处理链路需要稳定的交易标识;
  • 后续对账、追踪、问题排查要靠这些 id 回溯;
  • import 场景下又不能乱重算,源码特地在 create() 里对导入文件做了 compute 取消处理。

这说明 Odoo 很清楚:谁有权生成标识、何时生成标识,本身就是协议的一部分

三、journal 侧决定你导出的到底是哪一种 pain 契约

account_journal.py 里的 _compute_sepa_pain_version() 会根据银行账号国家或公司 fiscal country 选择默认 pain 版本。接着 create_iso20022_credit_transfer() / create_iso20022_credit_transfer_content() 负责建立整个 Document、GrpHdr、PmtInf 等节点。

这意味着 Odoo 并不是“把付款单循环输出”。它先确定:

  • 本次使用哪个 namespace / pain 版本;
  • 组头怎么写;
  • 控制总额怎么算;
  • 优先级、服务级别、本地指令等参数如何拼进 PmtTpInf

四、逐笔交易节点才是银行契约真正落地的地方

_get_CdtTrfTxInf() 会把付款名称、EndToEndId、金额、币种、债务方/债权方账户等信息写成单笔节点。你可以把它理解成“每笔付款最终对银行说的话”。

也正因为如此,很多线上问题根本不是 XML 结构错,而是逐笔字段不符合银行预期:

  • 指令 id 太长或格式不对;
  • 币种/金额精度不匹配;
  • 债权方账户信息不完整;
  • charge bearer 或 priority 不符合银行支持范围。

五、主链路其实是“付款校验 → 标识生成 → journal 组文档”

把两组源码接起来,主链路可以理解为:

  1. payment 在模型层先满足 SEPA / ISO 约束;
  2. 自动生成协议级交易标识;
  3. journal 决定 pain 版本与 XML 文档骨架;
  4. 每笔付款再被映射到 CdtTrfTxInf 节点。

所以导出 XML 只是最后一步,可真正决定能不能被银行接受的是前面的契约守卫。

六、新手误区

1. 以为只要 XML 验证通过,银行就一定收

错。银行更在意业务字段、版本契约和合规约束。

2. 以为 UUID 只是“系统内部主键”

这些标识直接影响链路追踪和对账。

3. 以为 pain 版本随便配

不同国家/银行对版本的接受度不一样,源码已经尽量给出默认策略。

七、实战注意事项

  • 先校验 journal 的银行账号和公司国家信息,再测试导出;
  • 对接银行前确认 pain 版本和支持字段,不要只看 Odoo 默认值;
  • 导入历史付款时,注意不要误生成新的 end-to-end 标识;
  • 排查失败时,逐笔看 CdtTrfTxInf,往往比只看整份 XML 更有用。

结语

企业版 ISO 20022 模块真正处理的,不是“把付款导出成 XML”,而是把付款对象、银行协议、稳定标识和文档拼装对齐成一条可投递的支付契约链。理解这一层,才知道它为什么是框架问题,而不是格式问题。

DISCUSSION

评论区

想参与讨论?先 登录 再发表评论。
还没有评论,你可以成为第一个留言的人。