马来西亚 e-Invoice 字段校验器(中小企业适用)
把电子发票 XML 的每个字段对照 LHDN 数据结构表格里的 49 条规则逐项核对:每一行都写明表格、UBL 路径和文件里实际写的是什么。从不作合规结论。
🔒 100% 浏览器内运行 · 零服务器上传
马来西亚规则与特殊情况
这个工具查的每一条规则都来自同一个地方:LHDN SDK 站点 Invoice v1.0 的数据结构表格,读取于 2026-11-08——每个元素的 Mandatory(必填)列、Number of Chars(字符数)列和 Cardinality(基数)列。这个工具不发明规则,也不自己加一条。表格写“Required”或“Mandatory where applicable”,这里就照那个说法:必填字段没有就直说;有条件字段的触发条件在文件里看不到,就报告为未评判,从不说它通过了。
| 查什么 | 表格是怎么写的 |
|---|---|
| 电子发票类型代码、发票号码、开具日期和时间、发票货币 | 每项基数 1-1、必填;类型代码 2 个字符,必须是已公布的电子发票类型之一(01、02……)。 |
| 供应商名称(300 字符)、供应商 TIN(14 字符)、MSIC 代码(5 字符)、地址、电话 | 每项必填,长度按表格自己的上限;电话号码最多 20 字符。 |
| 税款小计:税款金额、应税金额、税种编号 | 税款金额和税种编号在每一项小计里都必填;应税金额以免税(类型 E)为条件。 |
| 每一行:说明(300 字符)、分类、单价、税款、小计、数量 | 除数量外每项每行都必填;说明超过 300 字符会把上限和实际长度一起列出来。 |
| 买方:名称、TIN、注册号码、地址、电话 | 每项必填,长度按表格上限(买方 TIN 14 字符、地址行 150 字符)。 |
| 供应商的 SST 注册号、货币兑换率、免税明细 | 以表格点名的触发条件为条件:出现类型 02 的小计、货币不是 MYR、免税小计。触发条件看不见,就不评判。 |
- 从不作结论。每一行发现都是说“表格标记为必填,而这个文件里没有”。它从不说“LHDN 会拒绝这个”,也不计算任何接收结果。
- 这个工具不查的内容列在页面上,而且每次运行之后还留着:签名是否有效、金额之间的算术关系、开具日期是否是今天(UTC)、MSIC / 分类代码对照 LHDN 完整代码表(这里只查自带的两个代码表)、买方的税务居住身份。
- 金额、日期和数字从不解析,也不重算。校验器只读有没有、长度和代码值,文件里的任何金额都不会被加总、比较或四舍五入。
- 元素按本地名匹配。文件用
Cbc:、cbc:还是其他前缀写同一个命名空间,读出来都一样。 - 各方识别号码用 schemeID 区分。表格里有三条规则都指向
PartyIdentification/ID;写下来的 TIN、BRN、SST 各带自己的schemeID,每条规则只读它自己的那一种。 - 每条规则都直接读自表格本身,读取日期和每条规则一起记录在这一页,就像一张费率表。表格一变,规则就重新读;这一页从不为任何文件断言合规结果。
你粘贴的内容不会离开浏览器:本页是静态 JavaScript,没有任何网络请求。
处理前后
处理前
<?xml version="1.0" encoding="UTF-8"?>
<ubl:Invoice xmlns:ubl="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2.1"
xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2">
<cbc:ID>INV20261108002</cbc:ID>
<cbc:IssueDate>2026-11-08</cbc:IssueDate>
<cbc:IssueDate>2026-11-08</cbc:IssueDate>
<cbc:IssueTime>09:15:00</cbc:IssueTime>
<cbc:InvoiceTypeCode listVersionID="1.0">01</cbc:InvoiceTypeCode>
<cbc:DocumentCurrencyCode>MYR</cbc:DocumentCurrencyCode>
<cbc:TaxCurrencyCode>MYR</cbc:TaxCurrencyCode>
<cac:Signature>
<cbc:ID>sig-001</cbc:ID>
</cac:Signature>
<cac:AccountingSupplierParty>
<cac:Party>
<cac:PartyIdentification>
<cbc:ID schemeID="BRN">202501123456</cbc:ID>
</cac:PartyIdentification>
<cac:PartyIdentification>
<cbc:ID schemeID="SST">B16-1234567890</cbc:ID>
</cac:PartyIdentification>
<cbc:IndustryClassificationCode name="Computer programming activities" schemeID="MSIC">62012</cbc:IndustryClassificationCode>
<cac:PostalAddress>
<cac:AddressLine>
<cbc:Line>12, Jalan Teknologi 3/1, Taman Sains</cbc:Line>
</cac:AddressLine>
<cbc:CityName>Cyberjaya</cbc:CityName>
<cbc:PostalZone>63000</cbc:PostalZone>
<cbc:CountrySubentityCode>10</cbc:CountrySubentityCode>
<cac:Country>
<cbc:IdentificationCode>MYS</cbc:IdentificationCode>
</cac:Country>
</cac:PostalAddress>
<cac:Contact>
<cbc:Telephone>+603-8311 0000</cbc:Telephone>
<cbc:ElectronicMail>billing@hoelee.com</cbc:ElectronicMail>
</cac:Contact>
<cac:PartyLegalEntity>
<cbc:RegistrationName>Hoelee Enterprise</cbc:RegistrationName>
</cac:PartyLegalEntity>
</cac:Party>
</cac:AccountingSupplierParty>
<cac:AccountingCustomerParty>
<cac:Party>
<cac:PartyIdentification>
<cbc:ID schemeID="TIN">C87654321090</cbc:ID>
</cac:PartyIdentification>
<cac:PartyLegalEntity>
<cbc:RegistrationName>Restoran Aisyah Sdn. Bhd.</cbc:RegistrationName>
</cac:PartyLegalEntity>
<cac:PostalAddress>
<cac:AddressLine>
<cbc:Line>8, Jalan Persiaran Merdeka</cbc:Line>
</cac:AddressLine>
<cbc:CityName>Shah Alam</cbc:CityName>
<cbc:CountrySubentityCode>10</cbc:CountrySubentityCode>
<cac:Country>
<cbc:IdentificationCode>MYS</cbc:IdentificationCode>
</cac:Country>
</cac:PostalAddress>
<cac:Contact>
<cbc:Telephone>+603-5511 2222</cbc:Telephone>
</cac:Contact>
</cac:Party>
</cac:AccountingCustomerParty>
<cac:TaxTotal>
<cbc:TaxAmount currencyID="MYR">37.40</cbc:TaxAmount>
<cac:TaxSubtotal>
<cbc:TaxableAmount currencyID="MYR">400.00</cbc:TaxableAmount>
<cbc:TaxAmount currencyID="MYR">32.00</cbc:TaxAmount>
<cac:TaxCategory>
<cbc:ID>02</cbc:ID>
<cbc:Percent>8.00</cbc:Percent>
</cac:TaxCategory>
</cac:TaxSubtotal>
<cac:TaxSubtotal>
<cac:TaxCategory>
<cbc:ID>99</cbc:ID>
<cbc:Percent>10.00</cbc:Percent>
</cac:TaxCategory>
</cac:TaxSubtotal>
</cac:TaxTotal>
<cac:LegalMonetaryTotal>
<cbc:LineExtensionAmount currencyID="MYR">454.00</cbc:LineExtensionAmount>
<cbc:TaxExclusiveAmount currencyID="MYR">454.00</cbc:TaxExclusiveAmount>
<cbc:TaxInclusiveAmount currencyID="MYR">491.40</cbc:TaxInclusiveAmount>
<cbc:PayableAmount currencyID="MYR">491.40</cbc:PayableAmount>
</cac:LegalMonetaryTotal>
<cac:InvoiceLine>
<cbc:ID>1</cbc:ID>
<cbc:InvoicedQuantity unitCode="EA">1</cbc:InvoicedQuantity>
<cbc:LineExtensionAmount currencyID="MYR">400.00</cbc:LineExtensionAmount>
<cac:TaxTotal>
<cbc:TaxAmount currencyID="MYR">32.00</cbc:TaxAmount>
<cac:TaxSubtotal>
<cbc:TaxableAmount currencyID="MYR">400.00</cbc:TaxableAmount>
<cbc:TaxAmount currencyID="MYR">32.00</cbc:TaxAmount>
<cac:TaxCategory>
<cbc:ID>02</cbc:ID>
<cbc:Percent>8.00</cbc:Percent>
</cac:TaxCategory>
</cac:TaxSubtotal>
</cac:TaxTotal>
<cac:Item>
<cbc:Description>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</cbc:Description>
<cac:CommodityClassification>
<cbc:ItemClassificationCode listID="CLASS">T10</cbc:ItemClassificationCode>
</cac:CommodityClassification>
</cac:Item>
<cac:Price>
<cbc:PriceAmount currencyID="MYR">400.00</cbc:PriceAmount>
</cac:Price>
</cac:InvoiceLine>
<cac:InvoiceLine>
<cbc:ID>2</cbc:ID>
<cbc:InvoicedQuantity unitCode="EA">6</cbc:InvoicedQuantity>
<cbc:LineExtensionAmount currencyID="MYR">54.00</cbc:LineExtensionAmount>
<cac:TaxTotal>
<cbc:TaxAmount currencyID="MYR">5.40</cbc:TaxAmount>
<cac:TaxSubtotal>
<cbc:TaxableAmount currencyID="MYR">54.00</cbc:TaxableAmount>
<cbc:TaxAmount currencyID="MYR">5.40</cbc:TaxAmount>
<cac:TaxCategory>
<cbc:ID>01</cbc:ID>
<cbc:Percent>10.00</cbc:Percent>
</cac:TaxCategory>
</cac:TaxSubtotal>
</cac:TaxTotal>
<cac:Item>
<cbc:Description>IP camera 4MP — wired</cbc:Description>
<cac:CommodityClassification>
<cbc:ItemClassificationCode listID="CLASS">P10</cbc:ItemClassificationCode>
</cac:CommodityClassification>
</cac:Item>
<cac:Price>
<cbc:PriceAmount currencyID="MYR">10.00</cbc:PriceAmount>
</cac:Price>
</cac:InvoiceLine>
</ubl:Invoice> 处理后
<?xml version="1.0" encoding="UTF-8"?>
<ubl:Invoice xmlns:ubl="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2.1"
xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2">
<cbc:ID>INV20261108003</cbc:ID>
<cbc:IssueDate>2026-11-08</cbc:IssueDate>
<cbc:IssueTime>09:15:00</cbc:IssueTime>
<cbc:InvoiceTypeCode listVersionID="1.0">01</cbc:InvoiceTypeCode>
<cbc:DocumentCurrencyCode>MYR</cbc:DocumentCurrencyCode>
<cbc:TaxCurrencyCode>MYR</cbc:TaxCurrencyCode>
<cac:Signature>
<cbc:ID>sig-001</cbc:ID>
</cac:Signature>
<cac:AccountingSupplierParty>
<cac:Party>
<cac:PartyIdentification>
<cbc:ID schemeID="TIN">C12345678901</cbc:ID>
</cac:PartyIdentification>
<cac:PartyIdentification>
<cbc:ID schemeID="BRN">202501123456</cbc:ID>
</cac:PartyIdentification>
<cac:PartyIdentification>
<cbc:ID schemeID="SST">B16-1234567890</cbc:ID>
</cac:PartyIdentification>
<cbc:IndustryClassificationCode name="Computer programming activities" schemeID="MSIC">62012</cbc:IndustryClassificationCode>
<cac:PostalAddress>
<cac:AddressLine>
<cbc:Line>12, Jalan Teknologi 3/1, Taman Sains</cbc:Line>
</cac:AddressLine>
<cbc:CityName>Cyberjaya</cbc:CityName>
<cbc:PostalZone>63000</cbc:PostalZone>
<cbc:CountrySubentityCode>10</cbc:CountrySubentityCode>
<cac:Country>
<cbc:IdentificationCode>MYS</cbc:IdentificationCode>
</cac:Country>
</cac:PostalAddress>
<cac:Contact>
<cbc:Telephone>+603-8311 0000</cbc:Telephone>
<cbc:ElectronicMail>billing@hoelee.com</cbc:ElectronicMail>
</cac:Contact>
<cac:PartyLegalEntity>
<cbc:RegistrationName>Hoelee Enterprise</cbc:RegistrationName>
</cac:PartyLegalEntity>
</cac:Party>
</cac:AccountingSupplierParty>
<cac:AccountingCustomerParty>
<cac:Party>
<cac:PartyIdentification>
<cbc:ID schemeID="TIN">C87654321090</cbc:ID>
</cac:PartyIdentification>
<cac:PartyIdentification>
<cbc:ID schemeID="BRN">202901234567</cbc:ID>
</cac:PartyIdentification>
<cac:PartyLegalEntity>
<cbc:RegistrationName>Restoran Aisyah Sdn. Bhd.</cbc:RegistrationName>
</cac:PartyLegalEntity>
<cac:PostalAddress>
<cac:AddressLine>
<cbc:Line>8, Jalan Persiaran Merdeka</cbc:Line>
</cac:AddressLine>
<cbc:CityName>Shah Alam</cbc:CityName>
<cbc:CountrySubentityCode>10</cbc:CountrySubentityCode>
<cac:Country>
<cbc:IdentificationCode>MYS</cbc:IdentificationCode>
</cac:Country>
</cac:PostalAddress>
<cac:Contact>
<cbc:Telephone>+603-5511 2222</cbc:Telephone>
</cac:Contact>
</cac:Party>
</cac:AccountingCustomerParty>
<cac:TaxTotal>
<cbc:TaxAmount currencyID="MYR">37.40</cbc:TaxAmount>
<cac:TaxSubtotal>
<cbc:TaxableAmount currencyID="MYR">400.00</cbc:TaxableAmount>
<cbc:TaxAmount currencyID="MYR">32.00</cbc:TaxAmount>
<cac:TaxCategory>
<cbc:ID>02</cbc:ID>
<cbc:Percent>8.00</cbc:Percent>
</cac:TaxCategory>
</cac:TaxSubtotal>
<cac:TaxSubtotal>
<cbc:TaxableAmount currencyID="MYR">54.00</cbc:TaxableAmount>
<cbc:TaxAmount currencyID="MYR">5.40</cbc:TaxAmount>
<cac:TaxCategory>
<cbc:ID>01</cbc:ID>
<cbc:Percent>10.00</cbc:Percent>
</cac:TaxCategory>
</cac:TaxSubtotal>
</cac:TaxTotal>
<cac:LegalMonetaryTotal>
<cbc:LineExtensionAmount currencyID="MYR">454.00</cbc:LineExtensionAmount>
<cbc:TaxExclusiveAmount currencyID="MYR">454.00</cbc:TaxExclusiveAmount>
<cbc:TaxInclusiveAmount currencyID="MYR">491.40</cbc:TaxInclusiveAmount>
<cbc:PayableAmount currencyID="MYR">491.40</cbc:PayableAmount>
</cac:LegalMonetaryTotal>
<cac:InvoiceLine>
<cbc:ID>1</cbc:ID>
<cbc:InvoicedQuantity unitCode="EA">1</cbc:InvoicedQuantity>
<cbc:LineExtensionAmount currencyID="MYR">400.00</cbc:LineExtensionAmount>
<cac:TaxTotal>
<cbc:TaxAmount currencyID="MYR">32.00</cbc:TaxAmount>
<cac:TaxSubtotal>
<cbc:TaxableAmount currencyID="MYR">400.00</cbc:TaxableAmount>
<cbc:TaxAmount currencyID="MYR">32.00</cbc:TaxAmount>
<cac:TaxCategory>
<cbc:ID>02</cbc:ID>
<cbc:Percent>8.00</cbc:Percent>
</cac:TaxCategory>
</cac:TaxSubtotal>
</cac:TaxTotal>
<cac:Item>
<cbc:Description>Website maintenance service — November 2026</cbc:Description>
<cac:CommodityClassification>
<cbc:ItemClassificationCode listID="CLASS">T10</cbc:ItemClassificationCode>
</cac:CommodityClassification>
</cac:Item>
<cac:ItemPriceExtension>
<cbc:Amount currencyID="MYR">400.00</cbc:Amount>
</cac:ItemPriceExtension>
<cac:Price>
<cbc:PriceAmount currencyID="MYR">400.00</cbc:PriceAmount>
</cac:Price>
</cac:InvoiceLine>
<cac:InvoiceLine>
<cbc:ID>2</cbc:ID>
<cbc:InvoicedQuantity unitCode="EA">6</cbc:InvoicedQuantity>
<cbc:LineExtensionAmount currencyID="MYR">54.00</cbc:LineExtensionAmount>
<cac:TaxTotal>
<cbc:TaxAmount currencyID="MYR">5.40</cbc:TaxAmount>
<cac:TaxSubtotal>
<cbc:TaxableAmount currencyID="MYR">54.00</cbc:TaxableAmount>
<cbc:TaxAmount currencyID="MYR">5.40</cbc:TaxAmount>
<cac:TaxCategory>
<cbc:ID>01</cbc:ID>
<cbc:Percent>10.00</cbc:Percent>
</cac:TaxCategory>
</cac:TaxSubtotal>
</cac:TaxTotal>
<cac:Item>
<cbc:Description>IP camera 4MP — wired</cbc:Description>
<cac:CommodityClassification>
<cbc:ItemClassificationCode listID="CLASS">P10</cbc:ItemClassificationCode>
</cac:CommodityClassification>
</cac:Item>
<cac:ItemPriceExtension>
<cbc:Amount currencyID="MYR">54.00</cbc:Amount>
</cac:ItemPriceExtension>
<cac:Price>
<cbc:PriceAmount currencyID="MYR">10.00</cbc:PriceAmount>
</cac:Price>
</cac:InvoiceLine>
</ubl:Invoice> 使用方法
- 把会计系统里的 XML 复制出来,粘贴进输入栏。下面的示例已经是一份有六处错误的马来西亚发票,每种错误各一处。
- 按“开始处理”。输出栏会逐条列出这个文件不满足的规则:每条都点名是哪条规则、UBL 路径、表格里那个元素的名字、以及文件里实际写的是什么;接着是触发条件看不见所以未评判的规则,最后是这个工具不查的内容。勾选“显示已满足的规则”可以看见通过的那些。
- 需要的话按“复制结果”。文件本身不会被改动,什么也不会被上传;打开网络标签页会看到零请求。
常见问题
这个工具会告诉我 LHDN 接不接受我的发票吗?
不会。它从不说一份文件被接受或被拒绝,也不计算任何接收结果。每一行发现都是把文件和已公布的表格放在一起说:“表格标记为必填,而这个文件里没有”——而且“这个工具不查的内容”那张清单每次运行都会一起印出来。
为什么有的规则只写“未评判”,不写通过?
有四条规则是有条件的:只有触发条件在文件里看得见时才适用——货币不是 MYR、免税(类型 E)、服务税(类型 02)。触发条件不在文件里时,引擎没法判断这条规则适不适用,所以它写“未评判”并附上触发条件的原文,而不是装作这条通过了。
这 49 条规则从哪里来?
每一行都直接抄自 LHDN SDK 站点 Invoice v1.0 的数据结构表格,读取于 2026-11-08:Mandatory 列、Number of Chars 列和 Cardinality 列。规则模块按表格自己的说法记录元素、路径、是否必填和触发条件,读取日期也同模块一起记录,就像费率表那样。
它会查我的金额加起来对不对吗?
不会。引擎只读有没有、长度和代码值。金额、日期和数字从不解析,也不重算,所以这里不会把任何金额加总、比较或四舍五入——金额之间的算术关系在“这个工具不查的内容”清单里。
我的发票或买方的 TIN 会被上传吗?
不会。校验器是浏览器里的静态 JavaScript:打开网络标签页会看到零请求。发票上带着真实的公司注册号和真实的税号,它们不会离开这台电脑。