马来西亚 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>

使用方法

  1. 把会计系统里的 XML 复制出来,粘贴进输入栏。下面的示例已经是一份有六处错误的马来西亚发票,每种错误各一处。
  2. 按“开始处理”。输出栏会逐条列出这个文件不满足的规则:每条都点名是哪条规则、UBL 路径、表格里那个元素的名字、以及文件里实际写的是什么;接着是触发条件看不见所以未评判的规则,最后是这个工具不查的内容。勾选“显示已满足的规则”可以看见通过的那些。
  3. 需要的话按“复制结果”。文件本身不会被改动,什么也不会被上传;打开网络标签页会看到零请求。

常见问题

这个工具会告诉我 LHDN 接不接受我的发票吗?

不会。它从不说一份文件被接受或被拒绝,也不计算任何接收结果。每一行发现都是把文件和已公布的表格放在一起说:“表格标记为必填,而这个文件里没有”——而且“这个工具不查的内容”那张清单每次运行都会一起印出来。

为什么有的规则只写“未评判”,不写通过?

有四条规则是有条件的:只有触发条件在文件里看得见时才适用——货币不是 MYR、免税(类型 E)、服务税(类型 02)。触发条件不在文件里时,引擎没法判断这条规则适不适用,所以它写“未评判”并附上触发条件的原文,而不是装作这条通过了。

这 49 条规则从哪里来?

每一行都直接抄自 LHDN SDK 站点 Invoice v1.0 的数据结构表格,读取于 2026-11-08:Mandatory 列、Number of Chars 列和 Cardinality 列。规则模块按表格自己的说法记录元素、路径、是否必填和触发条件,读取日期也同模块一起记录,就像费率表那样。

它会查我的金额加起来对不对吗?

不会。引擎只读有没有、长度和代码值。金额、日期和数字从不解析,也不重算,所以这里不会把任何金额加总、比较或四舍五入——金额之间的算术关系在“这个工具不查的内容”清单里。

我的发票或买方的 TIN 会被上传吗?

不会。校验器是浏览器里的静态 JavaScript:打开网络标签页会看到零请求。发票上带着真实的公司注册号和真实的税号,它们不会离开这台电脑。