PEPPOL Envelope sender 与 EHF Billing 3.0 客户方的对应关系
明确结论
发送普通的 EHF Billing 3.0 Invoice 时,正确的对应关系是:
- SBDH
Sender:供应商,即AccountingSupplierParty - SBDH
Receiver:客户,即AccountingCustomerParty
因此,问题中的对应关系写反了。发票由供应商发送给客户,SBDH 记录的也是这份业务文档的传输方向。
不需要通过 SML/SMP 查询“所有 registrants”。通常只需使用收件方的 Peppol Participant Identifier,确认其是否支持目标文档类型和业务流程,并获取接收方的接入点信息。这一步往往由发送方使用的 Peppol Access Point 自动完成。
为什么这样对应
UBL Invoice 中的这两个角色分别代表交易双方:
cac:AccountingSupplierParty是开具发票的一方。cac:AccountingCustomerParty是接收并处理发票的一方。
普通供应商发票的消息流向如下:
AccountingSupplierParty
│
│ EHF Billing 3.0 Invoice
▼
AccountingCustomerParty
因此,SBDH 中应当写成:
Sender = AccountingSupplierParty
Receiver = AccountingCustomerParty
这里的 Sender 和 Receiver 是业务文档的发送方和接收方,并非“谁付款”和“谁收款”这类抽象角色。客户最终负责付款,并不意味着客户应被写成 Sender。
标识符如何对应
SBDH 和 UBL Invoice 通常使用不同的 XML 结构来表示同一个 Peppol 参与方标识。
例如,供应商和客户在 UBL 中的 Endpoint ID 可以写成:
<cac:AccountingSupplierParty>
<cac:Party>
<cbc:EndpointID schemeID="0192">SUPPLIER_ORG_NUMBER</cbc:EndpointID>
</cac:Party>
</cac:AccountingSupplierParty>
<cac:AccountingCustomerParty>
<cac:Party>
<cbc:EndpointID schemeID="0192">CUSTOMER_ORG_NUMBER</cbc:EndpointID>
</cac:Party>
</cac:AccountingCustomerParty>
对应的 SBDH 可以表示为:
<StandardBusinessDocumentHeader>
<HeaderVersion>1.0</HeaderVersion>
<Sender>
<Identifier Authority="iso6523-actorid-upis">
0192:SUPPLIER_ORG_NUMBER
</Identifier>
</Sender>
<Receiver>
<Identifier Authority="iso6523-actorid-upis">
0192:CUSTOMER_ORG_NUMBER
</Identifier>
</Receiver>
<!-- DocumentIdentification 和 BusinessScope 等内容省略 -->
</StandardBusinessDocumentHeader>
这两种写法的格式有所不同:
UBL EndpointID:
schemeID="0192"
值="SUPPLIER_ORG_NUMBER"
SBDH Participant Identifier:
0192:SUPPLIER_ORG_NUMBER
具体如何序列化,应以实际使用的 Peppol SBDH、Access Point 或消息服务实现为准。在没有核对实现要求前,不要把 0192: 同时写入 schemeID 和 EndpointID 的文本值。
推荐的发送步骤
1. 确定业务方向
普通 Invoice 的方向是:
Supplier → Customer
因此,供应商应设为 SBDH Sender,客户应设为 SBDH Receiver。
如果处理的是自开票、委托开票或其他特殊业务模式,则不能只根据元素名称判断方向。此时需要结合实际的文档发送者、接收者以及相应的 Peppol 业务规则来确定。
2. 填写 UBL 业务方信息
至少要确保以下信息正确:
<cac:AccountingSupplierParty>
<!-- 供应商信息 -->
</cac:AccountingSupplierParty>
<cac:AccountingCustomerParty>
<!-- 客户信息 -->
</cac:AccountingCustomerParty>
除 EndpointID 外,还可能需要填写组织编号、名称、地址和税务标识等字段。具体必填项取决于 EHF Billing 3.0 所采用的规则和业务场景。
3. 构造 SBDH
SBDH 至少要正确表达以下内容:
- Sender Participant Identifier
- Receiver Participant Identifier
- Document Type Identifier
- Process Identifier
- 文档实例标识、创建时间等头部信息
其中,Sender 和 Receiver 应与 Invoice 中实际的业务双方保持一致。
4. 查询收件方能力
发送方或其 Access Point 使用客户的 Participant Identifier 完成服务发现:
Receiver Participant Identifier
↓
SML 定位对应 SMP
↓
SMP 查询文档类型和流程
↓
取得接收 Access Point 的传输元数据
↓
发送文档
查询的重点不是客户是否出现在某个全量名单中,而是以下两项:
该客户是否支持指定的 Document Type Identifier
+
该客户是否支持指定的 Process Identifier
参与方已经注册到 Peppol,不代表它支持所有文档类型和业务流程。
是否需要查询全部 SML/SMP registrants
不需要,而且通常也不能把 SML/SMP 当作能够完整遍历的参与方目录。
SML 的主要用途,是根据 Participant Identifier 找到负责该参与方服务元数据的 SMP。SMP 则返回该参与方针对特定文档类型和流程公布的接收能力及传输信息。
发送一张发票时,通常只需查询目标客户。对应逻辑可以表示为:
receiver = "0192:CUSTOMER_ORG_NUMBER"
documentType = "<EHF/Peppol Invoice document type identifier>"
processId = "<billing process identifier>"
smp = locateSmpThroughSml(receiver)
metadata = smp.getServiceMetadata(
receiver,
documentType,
processId
)
if metadata is not found:
reject("Receiver does not support the requested document type or process")
sendInvoice(metadata.endpoint)
在实际项目中,业务系统往往不会直接操作 SML/SMP。常见的分工方式是:
ERP / 发票系统
→ 提交文档给发送方 Access Point
→ Access Point 完成 SML/SMP 发现
→ Access Point 将文档发送给接收方 Access Point
是否需要自行实现查询,取决于 Access Point 服务商提供的接口。如果服务商已经负责动态发现,业务系统就没有必要再重复实现一套 SML/SMP 查询逻辑。
注意事项
SBDH 参与方与 Access Point 不是同一个概念
SBDH Sender 和 Receiver 通常表示业务参与方,也就是 Peppol 四角模型中的最终发送方和接收方,不应直接填写双方 Access Point 运营商的信息。
Supplier(C1)
→ Sending Access Point(C2)
→ Receiving Access Point(C3)
→ Customer(C4)
普通 Invoice 的 SBDH 对应关系通常为:
Sender = C1 Supplier
Receiver = C4 Customer
C2 和 C3 是传输基础设施,不等同于 AccountingSupplierParty 或 AccountingCustomerParty。
不要只比较企业名称
路由和能力发现依赖 Participant Identifier,而不是公司名称。应同时核对:
- 标识方案,例如
0192 - 标识值
- UBL
EndpointID - SBDH
Sender、Receiver - SMP 查询所使用的 Participant Identifier
企业名称相同,不代表标识符相同。标识符格式有误也会导致 SMP 查询失败。
文档类型和流程必须匹配
即使客户能够接收 Peppol 消息,如果查询时使用了错误的 Document Type Identifier 或 Process Identifier,仍可能得到“不支持”或“未找到”的结果。
不要手工猜测这些标识符,应从当前采用的 EHF Billing 3.0、Peppol BIS Billing 规则或 Access Point 配置中获取。不同规范版本使用的完整标识符可能不同。
特殊业务场景需要单独判断
以上对应关系适用于供应商向客户发送普通 Invoice 的场景。如果业务采用 self-billing、第三方代发或其他特殊流程,则需要分别确认:
- 谁是发票中的供应商和客户;
- 谁实际发送这份业务文档;
- SBDH 规范要求记录业务参与方还是中介方;
- 对应流程在 SMP 中如何注册。
不能机械地假设所有 Invoice 都使用完全相同的路由角色。
备注:内容仅供参考。
