Views: 50
MLR(旧)からMLS(新)へ:Peppolのメッセージ応答は何が変わるのか
2026-09-24
2026年7月1日からすでにMLSへの移行期間が開始されており、MLSの送受信に向けた実装・準備が進められています。[7]
Peppol Message Level Statusの現行仕様はv1.1.0です。[2]
2024年10月に、次の記事でPeppolのMessage Level Response(MLR)からMessage Level Status(MLS)への移行について紹介していました。
-
Peppolメッセージ応答の進化:MLRからMLSへの移行と追加機能 [17]
その後、MLSは正式仕様となり、2026年7月2日に Peppol Message Level Status v1.1.0、Peppol Network Policy、MLS Phase-in Planが公開され、MLR廃止計画も公開されています。[2][6][7][8]
本稿では、従来のMessage Level Responseを MLR(旧)、新しいMessage Level Statusを MLS(新) と表記します。
|
Note
|
MLS(新)はMLR(旧)の単なる名称変更ではありません。MLR(旧)はEnd User間のbusiness documentとしてvalidation結果を通知する仕組みであるのに対し、MLS(新)はC3から、原則としてC2へ送られるService Provider間のmessage processing及びC4へのdelivery statusを通知するeDeliveryの仕組みです。MLS_TOが有効に指定されている場合は、そのfallback chainで決定されたService Providerが実効的な受信者になります。[2][3][9] |
Peppol Service Provider Operational Guideline on MLS の現行仕様はv1.0.0です.[3]
1. MLR(旧)とMLS(新)の基本的な違い
1.1 MLR(旧)が通知していたもの
MLR(旧)Message Level Response はPeppol Post-Award BISとして定義され、受信したbusiness documentについて、[9]
この文書は、
仕様上、次の処理へ進めることができるか
というvalidation結果を通知するものでした。
代表的なResponse Codeは次の3つです。
| 表示 | 状態 | 意味 |
|---|---|---|
|
MLR(旧) |
Acceptance |
validationをfatal errorなしで通過し、次の処理へ進める。 |
|
MLR(旧) |
Acknowledgement |
business messageとして受領・識別したが、conformance validationは実施していない。 |
|
MLR(旧) |
Rejection |
conformance ruleに対するerrorがあり、それ以上処理しない。 |
MLR(旧)の`AP`は、BuyerがInvoiceを業務上承認したという意味ではありません。あくまでmessage levelのvalidation結果です。
1.2 MLR(旧)の論理的な応答とPeppol Network上の通信
MLR(旧)では、論理的なbusiness responseとPeppol Network上の通信経路を区別する必要があります。
通常のbusiness documentは、
C1 ------> C2 ------> C3 ------> C4
と配送されます。
これに対するMLR(旧)は、論理的には元business documentのreceiverからsenderへ返されます。
C4 ------------------------------> C1
MLR(旧)
しかしPeppol Network上では逆方向に、
C4 ------> C3 ------> C2 ------> C1
と配送されるため、network上ではC3からC2への通信を経由します。
したがって、
MLR(旧)
論理的な応答主体 : C4 → C1
Network上の通信 : C3 → C2を経由
と整理するのが適切です。
1.3 MLS(新)はC3自身が原則C2へ返す
図1に示すように、MLS(新)Message Level Status は、受信側Service ProviderであるC3自身が送信するstatus messageです。通常の受信先は元business documentを送信したC2ですが、`MLS_TO`が有効に指定されている場合には、そのfallback chainで決定されたService Providerが実効受信者になります。[2][3]
C1 ------> C2 ------> C3 ------> C4
^ |
| |
+-- MLS(新)-+
C3 → C2(基本形)
つまりMLS(新)は、
論理的な送信者 = C3
論理的な受信者 = C2(基本形)/`MLS_TO`で決定された受信Service Provider
というService Provider間の通信です。
| MLR(旧) | MLS(新) | |
|---|---|---|
|
位置付け |
Post-Award BIS |
eDelivery |
|
論理的な送信者 |
C4 End User |
C3 Service Provider |
|
論理的な受信者 |
C1 End User |
C2 Service Provider(又は`MLS_TO`で決定された受信Service Provider) |
|
Network上の逆方向通信 |
C3 → C2を経由 |
C3 → C2(又は`MLS_TO`で決定された受信Service Provider) |
|
主目的 |
business documentのvalidation結果 |
C3での処理結果及びC4へのdelivery status |
2. AP、AB、REとInvoice Responseの違い
2.1 同じコードでも意味が違う
MLR(旧)とMLS(新)はどちらも`AP`、AB、`RE`を使用しますが、その意味は同じではありません。
| コード | MLR(旧) | MLS(新) |
|---|---|---|
|
|
validationをfatal errorなしで通過した |
C4への配送が成功し、C3が確認可能なacknowledgementを得た |
|
|
文書は受領したがconformance validationを実施していない |
C4へ転送したが、C3には到達を確認する方法がない |
|
|
validation等に問題があり、それ以上処理しない |
conformance violation等でRejectした、又はC4への恒久的な配送に失敗した |
特に、
MLR(旧)AP
= validation成功
MLS(新)AP
= C4への配送成功+確認あり
という違いが重要です。[2]
JP PINT Invoiceが公式SchematronをPASSしただけでは、MLS(新)`AP`にはなりません。
2.2 MLS(新)REはvalidation failureだけではない
MLS(新)では、C4への恒久的なdelivery failureも`RE`として扱います。[2]
代表的なStatus Reason Codeには次があります。
| Reason Code | 意味 |
|---|---|
|
|
XML Schema validation error |
|
|
Standard Compliance violation、fatal Schematron error等 |
|
|
Schematron warning |
|
|
C4への恒久的なdelivery failure |
Schematron warningである`BW`だけを理由としてbusiness documentをRejectすることはできません。
また、MLS(新)のReject理由はclosed listとして整理されており、各Service Providerが任意の独自理由で`RE`を返す仕組みではありません。
2.3 Invoice Responseは業務応答
Invoiceの業務処理状況をSellerへ通知するのはMLS(新)ではなく、*Invoice Response(業務応答)*です。[10]
| コード | 意味 |
|---|---|
|
|
BuyerがreadableなInvoiceを受領し、処理へ回せる状態 |
|
|
BuyerのシステムでInvoice処理を開始した |
|
|
問い合わせ中 |
|
|
条件付きで受け入れた |
|
|
BuyerがInvoiceをそれ以上処理しない |
|
|
BuyerがInvoiceを最終承認した |
|
|
支払処理を開始又は支払済み |
同じ`AP`でも、
MLR(旧)AP
= 文書validation成功
MLS(新)AP
= C4への配送成功・確認あり
Invoice Response AP
= BuyerによるInvoiceの業務上の最終承認
と意味が異なります。
したがって、
message / delivery status
= MLS(新)
business processing status
= Invoice Response
と分けて考える必要があります。
3. JP PINT InvoiceとSelf Billingでの扱い
図2は、通常のJP PINT InvoiceとSelf Billing Invoiceで、C1からC4へのbusiness documentの向きと、C3から送信されるMLS(新)の基本的な向きを対比したものです。C1/C4をSeller/Buyerに固定して理解するのではなく、そのbusiness documentにおけるsender/receiverの役割として理解する必要があります。
3.1 通常のJP PINT Invoice
図2上段に示すように、通常のJP PINT Invoiceでは、
Seller C1
|
v
Seller側 C2
|
v
Buyer側 C3
|
v
Buyer C4
となります。
MLS(新)は、
Buyer側 C3
|
| MLS(新)
v
Seller側 C2
へ返されます。
これは`MLS_TO`で別の有効な受信Service Providerを指定していない場合の基本形です。`MLS_TO`が有効な場合には、そのfallback chainで決定されたService Providerが受信者になります。[3]
SellerであるC1へMLS(新)が直接送信されるわけではありません。
したがって、SellerがMLS(新)の結果を知るためには、C2であるService ProviderがUI、API、notification等によってC1へ情報を提供する必要があります。
3.2 Self Billing Invoiceでは方向が逆になる
図2下段に示すように、JP BIS Self Billing Invoice、すなわち仕入明細書ではBuyerがSelf Billing Invoiceを作成し、Sellerへ送ります。
Buyer C1
|
v
Buyer側 C2
|
v
Seller側 C3
|
v
Seller C4
この場合のMLS(新)は、
Seller側 C3
|
| MLS(新)
v
Buyer側 C2
へ返されます。
ここでも`MLS_TO`が有効に指定されていれば、実効受信者はそのfallback chainによって決定されます。[3]
C1を常にSeller、C4を常にBuyerと固定的に考えてはいけません。
3.3 Self Billingの業務上の異議はMLS(新)ではない
Self Billing Invoiceについて、
XML Schemaに違反している
JP PINT Self Billingのfatal ruleに違反している
SellerであるC4へ配送できない
といった問題はMLS(新)の領域です。
一方、
数量が違う
単価が合意内容と違う
取引内容が違う
仕入明細書の内容にSellerが同意しない
といった問題はbusiness levelの問題です。
MLS(新)`RE`を、Sellerによる仕入明細書の業務上の拒否と解釈してはいけません。
4. MLS(新)の導入とMLR(旧)の廃止
4.1 移行スケジュール
図3に示すように、OpenPeppolの Peppol MLR Deprecation and Phase-out Plan v1.0.0 では、MLR廃止はMLS導入と連動して進められます。[7][8]
| Milestone | 日付 | 内容 |
|---|---|---|
|
T1 |
2026年7月1日 |
MLSへの移行期間開始。MLS関連仕様が適用され、各SPはMLSの送受信に向けた実装・準備を開始する。この時点ではMLRは引き続き利用可能であり、MLSへの切替えはまだ必須ではない。 |
|
T2 |
2027年3月1日 |
MLS sending activation window開始。MLS送信を開始したSPは、そのbusiness documentについてMLR送信を停止する。 |
|
T3 |
2027年4月1日 |
すべてのSPでMLS送信が必須。SLRも適用。MLRは例外的なfallbackのみ。 |
4.2 同一文書にMLR(旧)とMLS(新)を両方返さない
移行期間中にはMLR(旧)とMLS(新)が共存します。
しかし、同じbusiness documentについて両方を返すことは認められていません。
One business document
MUST only be responded with
either MLR or MLS.
両方を扱える場合にはMLSが優先されます。
4.3 MLS_TYPE、MLS_TO、SLR
| 値 | 意味 |
|---|---|
|
|
negative MLSである`RE`の場合だけ返す |
|
|
`RE`に加えて、positive MLSである`AP`又は`AB`も返す |
デフォルトは`FAILURE_ONLY`です。[6]
また`MLS_TO`によってMLSの送信先を指定できます。`MLS_TO`がない場合、又は指定値を利用できない場合には、規定されたfallback chainに従って実効受信者が決定されます。[2][3]
Service Provider Identification Scheme(SPIS)と`0242`
図4に示すように、MLS SBDHではC1/C4のEnd Userではなく、MLSを送受信するService ProviderをSender/Receiverとして識別します。その識別に使用するのがService Provider Identification Scheme(SPIS)です。
MLSでは、SBDHのSender及びReceiverにEnd UserのParticipant IDを使用せず、Service Providerを識別するための Service Provider Identification Scheme(SPIS) を使用します。MLS SBDHのparty identifierは`iso6523-actorid-upis`を使用し、そのParticipant Identifier Schemeは`0242`です。SenderはMLSを送信するC3、Receiverは`MLS_TO`のfallback chainによって決定された実効的なMLS受信Service Providerです。End Userの識別子をSender又はReceiverとして使用してはいけません。[3]
0242`は個々のService Providerそのものを表す番号ではなく、OpenPeppol Service Provider Identification Scheme を表すscheme codeです。SPISの識別子本体であるSPID(Service Provider ID)は、必須の6桁`Main ID、任意の`Peppol Use Case ID`、任意の`Service Provider Suffix`から構成されます。`Main ID`はService Providerを一意に識別する6桁番号で、OpenPeppolによって割り当てられます。これは物理的なAPサーバー1台ごとに別番号が発行されるという意味ではなく、OpenPeppol Service Providerを識別するMain IDです。必要に応じてUse Case IDやService Provider Suffixを付加して用途やSP内部の識別を拡張できます。[4][5]
0242:000270
この例では、
0242 = SPISを示すParticipant Identifier Scheme
000270 = OpenPeppolが割り当てた6桁のMain ID
という関係になります。したがって、`0242`だけでは特定のService Providerを識別できません。`0242`と、そのSPに割り当てられたMain IDを組み合わせてService Providerを識別します。
MLSのOperational Guidelineでは、MLS関連のParticipant Identifier Schemeはすべて`0242`とされ、Main IDを使用する基本形は、
0242:<6桁のMain ID>
です。さらにMLS用のUse Case IDを使用する場合には、例えば、
0242:987654-MLS
0242:987654-MLS.svc01
のような形式も使用できます。[3]
これは、例えば日本のEnd Userを識別するParticipant Identifier Schemeの一つである`0188`などとは役割が異なります。
End Userの識別
0188:...
Service Providerの識別
0242:000270
さらに、M1、M2、M3という時刻が重要になります。
| 時刻 | 意味 |
|---|---|
|
M1 |
元business documentをC2が送信したAS4 timestamp |
|
M2 |
C3がMLSを送信したAS4 timestamp |
|
M3 |
C2がMLSを受信した時刻 |
対象となるメッセージについて、
M2 - M1 <= 20分
M3 - M1 <= 25分
したがってMLS対応には、
-
元business documentとのcorrelation
-
M1、M2、M3の記録
-
retry / queue
-
SMP capability
-
MLS_TO
-
MLS_TYPE
なども含まれます。
5. JP PINTのvalidationとMLS(新)のReject
5.1 BIS本文には計算規則がある
MLS必須化によって、JP PINTでは「何をMLS(新)`RE`にするのか」が重要になります。
例えば、日本の消費税についてはTax category taxable amountである`IBT-116`を、
IBT-116
=
該当するInvoice line net amount(IBT-131)の合計
+
該当するDocument level charge amount(IBT-099)の合計
-
該当するDocument level allowance amount(IBT-092)の合計
としてTax category code及びTax rateごとに計算し、そのうえで、
IBT-117
=
IBT-116 × IBT-119 / 100
としてTax category tax amountを計算します。[12]
5.2 Schematronとは何を検証するものか
PeppolのInvoice validationでは、XML SchemaとSchematronが異なる役割を担っています。
XML Schemaは主として、
要素が存在するか
要素の並びが正しいか
文字列、数値、日付などのデータ型が正しいか
といったXML文書としての構造を検証します。
一方、SchematronはXPathを使用して、XML Schemaだけでは表現しにくいbusiness ruleを検証します。
例えば、
Invoice total amount
=
Line amountの合計
+
Charge
-
Allowance
のような複数項目間の計算関係や、
Tax category code = S
である場合には
Tax rateが必要
といった条件付きのルールを機械的に検証できます。
| 検証 | 主な対象 | 例 |
|---|---|---|
|
XML Schema |
XML構造、要素、属性、データ型 |
必須要素が存在するか、数値項目に文字列が入っていないか |
|
Schematron |
Business Rule、項目間関係、計算規則、条件 |
合計金額が明細の合計と一致するか、条件に応じた項目が設定されているか |
Peppolでは、BISやSemantic Modelで定義したBusiness TermがUBLなどのXML要素へBindingされ、そのXML文書に対してSchematronによるvalidationが行われます。
BIS / Semantic Model
|
v
Business Rules
|
v
Syntax Binding
|
v
UBL XML
|
v
Schematron
|
v
PASS / warning / fatal
したがってSchematronは、単なるXML文法チェックではありません。
BISで定義されたbusiness ruleについて、実際に交換されるXML documentがそのルールに適合しているかを客観的に判定するためのmachine-readable validation artefactです。
5.3 Schematron ruleはXPathで項目間の関係を検証する
Schematronでは、通常、対象となるXML要素をXPathで選択し、その値や他の要素との関係を`test`として記述します。
概念的には、
<rule context="...">
<assert test="計算条件">
Business rule violation
</assert>
</rule>
のような形になります。
Schematron の <assert> では、test 属性に「正しいデータで成立すべき条件」を XPath で記述します。
test の評価結果が true であれば検証に合格し、false であれば assertion failure としてエラーが報告されます。
Schematron validatorは、XMLに記載された値を読み取り、
条件が true
-> rule PASS
条件が false
-> validation error
と判定します。
Peppolではruleごとにseverityが設定され、`fatal`や`warning`などとしてvalidation結果が示されます。
MLS(新)との関係では、特に`fatal`となる共通のconformance ruleが重要です。
C3が受信したbusiness documentについて公式Schematronのfatal errorを検出した場合には、Standard Compliance violationとしてMLS(新)の`RE`につながり得るためです。
5.4 Schematronで検出されない計算規則
この問題について、OpenPeppol Helpdeskへ次のIssueを登録しています。
PEPPOL-23582
JP PINT 2025-Q4 validation defect:
Schematron does not appear to validate calculation rules defined in JP PINT BIS
JP PINT 2025-Q4 の検証不備:
JP PINT BISで規定されている計算規則がSchematronで検証されていない可能性
|
Note
|
JP PINT BISでは、課税対象額や税額、合計金額などについて、項目間の計算関係がBusiness Ruleとして規定されています。 |
しかし、2025-Q4版のSchematronでは、これらの計算規則の一部について対応する検証ルールが実装されておらず、BIS上は不正な値であってもSchematron検証を通過してしまう可能性があります。
BISで計算規則を規定するのであれば、その適合性を機械的かつ客観的に確認できるSchematron ruleも整備する必要があります。
現在のJP PINTでは、
IBT-117
=
IBT-116 × IBT-119 / 100
についてはSchematronによるvalidationがあります。[13]
しかし、
IBT-116
=
sum(IBT-131)
+
sum(IBT-099)
-
sum(IBT-092)
をTax category code及びTax rateごとに検証するruleなど、BIS本文に規定される一部の計算規則について対応するSchematron validationが確認できないという問題があります。
BIS本文にnormativeな計算規則があっても、その計算を検証するSchematron ruleがvalidation artefactとして実装されていなければ、通常のSchematron validationではその誤りを検出できません。
5.5 課税対象額の例
例えば、10%課税のInvoice line net amount(IBT-131)の合計が100,000円で、該当する文書レベルのcharge及びallowanceがないとします。
Invoice line net amount の合計
= 100,000円
Document level charge
= 0円
Document level allowance
= 0円
したがって、本来のIBT-116
= 100,000円
ところが、Tax breakdownの文書レベルの金額として、意図的に10倍の課税対象額を記載したとします。
IBT-116 = 1,000,000円
IBT-119 = 10%
IBT-117 = 100,000円
この場合でも、最終税額についてだけ確認すれば、
IBT-117
=
IBT-116 × IBT-119 / 100
100,000
=
1,000,000 × 10 / 100
となるため、`IBT-117`は報告された`IBT-116`と税率に対して算術的には整合しています。
しかし、本来検証すべき課税対象額は、
IBT-116
=
100,000 + 0 - 0
=
100,000円
であり、報告された1,000,000円とは900,000円も異なります。
この例では丸め誤差や端数処理では説明できず、Tax breakdownの課税対象額そのものが明らかに誤っています。
それでも`IBT-117 = IBT-116 × IBT-119 / 100`だけを検証している限り、税額と誤った課税対象額の組合せ自体は整合してしまいます。
したがって重要なのは、最終税額だけでなく、文書レベルのTax breakdownに記載された`IBT-116`が、該当する明細、文書レベルcharge及びallowanceから正しく集計されていることを検証することです。
5.6 明細行金額についても同じ問題がある
同様の問題はInvoice line net amount(IBT-131)にもあります。
明細行金額についてBISが、
Invoice line net amount
=
Quantity
× Item net price
/ Item price base quantity
+ Line charge
- Line allowance
という計算規則を定めているのであれば、報告されたIBT-131がこの式から求めた値と一致することもmachine-readable ruleで確認する必要があります。
例えば、
Quantity = 10
Unit price = 1,000円
Price base quantity = 1
Charge = 0円
Allowance = 0円
なら、
正しいIBT-131
=
10 × 1,000 / 1
=
10,000円
です。
ところが、
IBT-131 = 12,000円
と報告し、その誤った金額をそのまま文書レベル合計へ使用すると、
IBT-106
=
sum(IBT-131)
という集計だけは一致させることができます。
したがって、単価・数量からIBT-131を再計算するruleと、IBT-131からIBT-106を集計するruleは、それぞれ別にvalidationする必要があります。
5.7 `u:slack()`を使った1円の許容差
金額計算のvalidationでは、計算方法や丸め処理の違いによって、ごく小さな差額が生じる場合があります。
Peppol BIS Billingでは、このような差を扱うために`u:slack()`関数が使用されています。[14]
例えば、次のような関数です。
<function xmlns="http://www.w3.org/1999/XSL/Transform"
name="u:slack"
as="xs:boolean">
<param name="exp" as="xs:decimal"/>
<param name="val" as="xs:decimal"/>
<param name="diff" as="xs:decimal"/>
<sequence select="
xs:decimal($exp + $diff) >= $val
and
xs:decimal($exp - $diff) <= $val"/>
</function>
ここで、
$exp = documentに記載された金額
$val = ruleから計算した金額
$diff = 許容する差額
です。
したがって、
u:slack($reportedAmount, $calculatedAmount, 1)
とすると、
| reportedAmount - calculatedAmount | <= 1
すなわち、円建てのJP PINT Invoiceであれば、計算結果との差を*±1円まで許容*するvalidationとすることができます。
|
Note
|
ここでの`1`は、JP PINTの円建て計算向けの提案値です。既存のPeppol BIS Billingで用いられている許容差をそのまま引用するものではありません。 |
5.8 Schematron追加案:IBT-131
Invoice line net amountについては、数量、単価、価格基準数量、明細行charge及びallowanceから計算した値と、実際に報告されたIBT-131を比較します。
以下のrule IDは提案用であり、公式rule IDではありません。
<rule context="cac:InvoiceLine | cac:CreditNoteLine">
<let name="lineExtensionAmount"
value="
if (cbc:LineExtensionAmount)
then xs:decimal(cbc:LineExtensionAmount)
else 0"/>
<let name="quantity"
value="
if (/ubl-invoice:Invoice)
then
(if (cbc:InvoicedQuantity)
then xs:decimal(cbc:InvoicedQuantity)
else 1)
else
(if (cbc:CreditedQuantity)
then xs:decimal(cbc:CreditedQuantity)
else 1)"/>
<let name="priceAmount"
value="
if (cac:Price/cbc:PriceAmount)
then xs:decimal(cac:Price/cbc:PriceAmount)
else 0"/>
<let name="baseQuantity"
value="
if (cac:Price/cbc:BaseQuantity
and xs:decimal(cac:Price/cbc:BaseQuantity) != 0)
then xs:decimal(cac:Price/cbc:BaseQuantity)
else 1"/>
<let name="chargesTotal"
value="
sum(
cac:AllowanceCharge[
normalize-space(cbc:ChargeIndicator) = 'true'
]/cbc:Amount/xs:decimal(.)
)"/>
<let name="allowancesTotal"
value="
sum(
cac:AllowanceCharge[
normalize-space(cbc:ChargeIndicator) = 'false'
]/cbc:Amount/xs:decimal(.)
)"/>
<let name="calculatedLineAmount"
value="
($quantity * ($priceAmount div $baseQuantity))
+ $chargesTotal
- $allowancesTotal"/>
<assert id="JP-PINT-PROPOSAL-LINE-AMOUNT"
flag="fatal"
test="
u:slack(
$lineExtensionAmount,
$calculatedLineAmount,
1
)">
Invoice line net amount MUST equal the calculated
line amount within a tolerance of 1 JPY.
</assert>
</rule>
例えば、計算結果が10,000円の場合、
9,999円 PASS
10,000円 PASS
10,001円 PASS
9,998円 FAIL
10,002円 FAIL
となります。
5.9 Schematron追加案:IBT-116
より重要なのが、Tax category taxable amount(IBT-116)のvalidationです。
BIS本文の計算関係は、
IBT-116
=
同じTax category code及びTax rateの
sum(IBT-131)
+
sum(IBT-099)
-
sum(IBT-092)
です。
これについても、報告されたIBT-116と、明細等から再計算した金額を`u:slack()`で比較できます。
以下も提案用の例です。
<rule context="cac:TaxTotal/cac:TaxSubtotal">
<let name="taxCategoryCode"
value="
normalize-space(cac:TaxCategory/cbc:ID)"/>
<let name="taxRate"
value="
if (cac:TaxCategory/cbc:Percent)
then xs:decimal(cac:TaxCategory/cbc:Percent)
else 0"/>
<let name="reportedTaxableAmount"
value="
xs:decimal(cbc:TaxableAmount)"/>
<let name="lineTotal"
value="
sum(
/ubl-invoice:Invoice/cac:InvoiceLine[
cac:Item/cac:ClassifiedTaxCategory[
normalize-space(cbc:ID) = $taxCategoryCode
and
(
if (cbc:Percent)
then xs:decimal(cbc:Percent)
else 0
) = $taxRate
]
]/cbc:LineExtensionAmount/xs:decimal(.)
)"/>
<let name="chargeTotal"
value="
sum(
/ubl-invoice:Invoice/cac:AllowanceCharge[
normalize-space(cbc:ChargeIndicator) = 'true'
and
cac:TaxCategory[
normalize-space(cbc:ID) = $taxCategoryCode
and
(
if (cbc:Percent)
then xs:decimal(cbc:Percent)
else 0
) = $taxRate
]
]/cbc:Amount/xs:decimal(.)
)"/>
<let name="allowanceTotal"
value="
sum(
/ubl-invoice:Invoice/cac:AllowanceCharge[
normalize-space(cbc:ChargeIndicator) = 'false'
and
cac:TaxCategory[
normalize-space(cbc:ID) = $taxCategoryCode
and
(
if (cbc:Percent)
then xs:decimal(cbc:Percent)
else 0
) = $taxRate
]
]/cbc:Amount/xs:decimal(.)
)"/>
<let name="calculatedTaxableAmount"
value="
$lineTotal
+ $chargeTotal
- $allowanceTotal"/>
<assert id="JP-PINT-PROPOSAL-TAXABLE-AMOUNT"
flag="fatal"
test="
u:slack(
$reportedTaxableAmount,
$calculatedTaxableAmount,
1
)">
Tax category taxable amount MUST equal
the sum of line net amounts plus document level
charges minus document level allowances
for the same tax category and tax rate,
within a tolerance of 1 JPY.
</assert>
</rule>
このruleのポイントは、単にInvoice全体の明細を合計するのではなく、
Tax category code
+
Tax rate
が同じものだけを選択して集計することです。
例えば、
10%対象 IBT-131 合計 100,000円
10%対象 IBT-099 0円
10%対象 IBT-092 0円
計算されたIBT-116 100,000円
の場合、
報告 IBT-116 = 99,999円 PASS
報告 IBT-116 = 100,000円 PASS
報告 IBT-116 = 100,001円 PASS
報告 IBT-116 = 100,002円 FAIL
となります。
先の例のように、
報告 IBT-116 = 1,000,000円
であれば、
計算値 = 100,000円
報告値 = 1,000,000円
差額 = 900,000円
であり、1円のslackを大きく超えるため、明確に`fatal`となります。
5.10 Schematron PASSとBIS適合は同じではない
Schematronで検出されない
≠
BIS本文の規則が存在しない
BIS本文にnormativeな計算規則として規定されているのであれば、business documentは本来その規則にも適合する必要があります。
また、
公式Schematron PASS
≠
BIS本文のすべてのnormative ruleを
検証済み
です。
Schematronは、それ自身に実装されているruleしか検証できません。
一方で、
Schematronで検出されない
≠
各C3が独自validatorを実装する義務がある
とも考える必要があります。
5.11 MLS(新)では相互運用性問題になる
各C3が独自validationを行うと、例えば、
同じJP PINT Invoice
|
+------------+------------+
| |
C3-A C3-B
| |
公式Schematronのみ 独自計算validation
| |
PASS FAIL
| |
C4へ配送 MLS(新)RE / BV
となり、同じJP PINT Invoiceについて受信側Service Providerごとに結果が異なる可能性があります。
これは単なるvalidator品質の問題ではなく、Peppolネットワークにおけるinteroperabilityの問題です。
5.12 共通validation artefactが重要になる
MLS必須化後は、
BIS / Semantic Model
|
v
Business Rules
|
v
公式validation artefacts
|
v
共通の適合性判定
|
v
必要な場合のみ
MLS(新)RE
という関係を明確にする必要があります。
特に、MLSによるRejectの根拠とする計算ruleについては、各Service Providerの独自実装に任せるのではなく、共通のmachine-readable validation ruleとして提供することが望まれます。
また、
-
BIS本文
-
Semantic Model
-
Syntax Binding
-
Business Rules
-
Schematron
に矛盾がある場合には、各Service Providerが独自にどれかを正しいと判断して`RE`を返すのではなく、Japan PA / OpenPeppolへSpecification defectとして報告し、規定又はvalidation artefactを共通ルールとして修正することが重要です。
5.13 提言
JP PINT BIS本文にnormativeな計算ruleとして規定されている金額については、対応するSchematron ruleを整備することを提案します。
特に、
| 対象 | 検証すべき関係 |
|---|---|
|
IBT-131 |
数量、単価、基準数量、明細charge及びallowanceから明細行金額を再計算 |
|
IBT-106 |
各IBT-131を合計して文書レベルの明細行合計と照合 |
|
IBT-116 |
Tax category及びTax rateごとにIBT-131、IBT-099及びIBT-092から課税対象額を再計算 |
|
IBT-117 |
IBT-116とIBT-119からTax category tax amountを再計算 |
という一連の計算チェーンを共通Schematronで検証できるようにすることが望まれます。
Quantity / Price
|
v
IBT-131
|
+------------------+
| |
v v
IBT-106 Tax category別集計
|
v
IBT-116
|
v
IBT-117
円建ての場合には、例えば、
u:slack(
reported value,
calculated value,
1
)
によって±1円の許容差を含めた客観的な適合性判定を行う方法が考えられます。
重要なのは、1円という許容差を設けることによって計算ruleを曖昧にすることではありません。
むしろ、
BISで規定された計算式
|
v
Schematronで再計算
|
v
u:slack(..., 1)
|
+-- 差額 <= 1円 -> PASS
|
+-- 差額 > 1円 -> fatal
とすることにより、許容する差額の範囲まで含めて共通ルールとして明確にできます。
BISで計算規則をnormativeに定義するのであれば、その規則に対する客観的な適合性判定を可能とするSchematron ruleも原則として提供するべきです。
これにより、各Service Providerが異なる独自ロジックで計算妥当性を判断することを避け、同じJP PINT Invoiceに対して共通のvalidation結果を得られるようにすることができます。
これは単なるvalidatorの品質改善ではなく、MLS(新)によるRejectを含めたPeppol Network全体のinteroperabilityを確保するための要件と考えます。
5.14 まとめ
MLR(旧)からMLS(新)への移行は、単なる名称変更ではありません。
MLR(旧)
= End User間のbusiness documentとして
validation結果を通知
(Peppol Network上ではC3→C2を経由)
MLS(新)
= C3自身がC2(又は`MLS_TO`で決定された受信SP)へ返す
message / delivery status
Invoice Response
= Invoiceのbusiness processing status
Buyer → Seller
特に、同じ`AP`、AB、`RE`でも意味が異なる点に注意が必要です。
MLS必須化によって、JP PINTの公式validation artefactの役割もより重要になります。
JP PINT BIS本文にnormativeな計算ruleが存在していても、公式Schematronでその一部が検証されていない場合、各Service Providerによる独自validationが異なるMLS結果を生む可能性があります。
そのため、
-
JP PINT BISのnormative requirements
-
Business Rules
-
公式Schematronその他のvalidation artefacts
-
MLS(新)`RE`の条件
を整合させることが、これまで以上に重要になると考えます。
参考文献
-
[1] OpenPeppol, Peppol Business Message Envelope (SBDH) v2.0.2, 2026-07-02
https://docs.peppol.eu/edelivery/envelope/Peppol-EDN-Business-Message-Envelope-2.0.2-2026-07-02.pdf -
[2] OpenPeppol, Peppol Message Level Status Specification v1.1.0, 2026-07-02
https://docs.peppol.eu/edelivery/specs/mls/v1.1.0/mls/spec/ -
[3] OpenPeppol, Peppol Service Provider Operational Guideline on MLS v1.0.0, 2026-07-02
https://docs.peppol.eu/edelivery/guidelines/mls/SPOG%20on%20MLS%201.0.0%202026-07-02.pdf -
[4] OpenPeppol, OpenPeppol Service Provider Identification Scheme (SPIS) v1.0.0, 2025-05-08
https://docs.peppol.eu/edelivery/policies/OpenPeppol-SP-ID-Scheme%201.0.0.pdf -
[5] OpenPeppol, Peppol Code Lists – Participant identifier schemes v9.7, 2026-07-02
https://docs.peppol.eu/edelivery/codelists/v9.7/Peppol%20Code%20Lists%20-%20Participant%20identifier%20schemes%20v9.7.html -
[6] OpenPeppol, Peppol Network Policy v1.0.0, 2026-07-02
https://docs.peppol.eu/edelivery/policies/Peppol%20Network%20Policy%201.0.0%202026-07-02.pdf -
[7] OpenPeppol, Peppol MLS Phase-in v1.0.0, 2026-07-02
https://docs.peppol.eu/edelivery/changelog/2026-07/Peppol%20MLS%20Phase-In%201.0.0%202026-07-02.pdf -
[8] OpenPeppol, Peppol MLR Deprecation and Phase-out Plan v1.0.0, 2026-07-02
https://docs.peppol.eu/edelivery/changelog/2026-07/Peppol%20MLR%20Phase-Out%201.0.0%202026-07-02.pdf -
[9] OpenPeppol, Peppol BIS Message Level Response
https://docs.peppol.eu/poacc/upgrade-3/profiles/36-mlr/ -
[10] OpenPeppol, Peppol BIS Invoice Response 3.2
https://docs.peppol.eu/poacc/upgrade-3/profiles/63-invoiceresponse/ -
[11] OpenPeppol, Peppol Specifications for Japan
https://docs.peppol.eu/poac/jp/ -
[12] OpenPeppol, JP PINT BIS 2025-Q4
https://docs.peppol.eu/poac/jp/2025-Q4/pint-jp/bis/ -
[13] OpenPeppol, ALIGNED-IBRP-051-JP
https://docs.peppol.eu/poac/jp/2025-Q4/pint-jp/trn-invoice/rule/aligned-ibrp-051-jp/ -
[14] OpenPeppol, PEPPOL-EN16931-R120 – Invoice line net amount validation rule
https://docs.peppol.eu/poacc/billing/3.0/rules/ubl-peppol/PEPPOL-EN16931-R120/ -
[15] 三分一技術士事務所, JP PINTの計算規則とSchematron validationに関する参考記事
https://www.sambuichi.jp/?p=15540 -
[16] 三分一技術士事務所, JP PINT解体新書4 C4自動処理と記載金額の検算
https://www.sambuichi.jp/?p=9301 -
[17] 三分一技術士事務所, Peppolメッセージ応答の進化:MLRからMLSへの移行と追加機能
https://www.sambuichi.jp/?p=13686
- 1. MLR(旧)とMLS(新)の基本的な違い
- 2. AP、AB、REとInvoice Responseの違い
- 3. JP PINT InvoiceとSelf Billingでの扱い
- 4. MLS(新)の導入とMLR(旧)の廃止
- 5. JP PINTのvalidationとMLS(新)のReject
- 5.1 BIS本文には計算規則がある
- 5.2 Schematronとは何を検証するものか
- 5.3 Schematron ruleはXPathで項目間の関係を検証する
- 5.4 Schematronで検出されない計算規則
- 5.5 課税対象額の例
- 5.6 明細行金額についても同じ問題がある
- 5.7 `u:slack()`を使った1円の許容差
- 5.8 Schematron追加案:IBT-131
- 5.9 Schematron追加案:IBT-116
- 5.10 Schematron PASSとBIS適合は同じではない
- 5.11 MLS(新)では相互運用性問題になる
- 5.12 共通validation artefactが重要になる
- 5.13 提言
- 5.14 まとめ
- 参考文献
コメントを残す