วัตถุประสงค์หนึ่งที่กำหนดให้ E-Tax Invoice ต้องเป็น PDF/A-3 คือ การแนบข้อมูล XML ที่สามารถนำไปใช้ประมวลผลได้ทันที เป็นการเตรียมเปลี่ยนผ่านความเชื่อจากยุคสมัยทึ่ยึดติดกระดาษมาสู่อิเล็กทรอนิกส์
ข้อมูลนั้นคือ ขมธอ.3–2560 “ข้อเสนอแนะมาตรฐานด้านเทคโนโลยีสารสนเทศและการสื่อสารที่จำเป็นต่อธุรกรรมทางอิเล็กทรอนิกส์ ว่าด้วยข้อความอิเล็กทรอนิกส์สำหรับการซื้อขายสินค้าและบริการ” หรือระบุเป็นรหัสในข้อมูล XML “ER3–2560”
JavaScript Library
การเขียนโค้ด JavaScript เพื่อจัดการ XML นั้นไม่ง่าย หรือกล่าวอีกนัยหนึ่ง JavaScript ไม่ถูกชะตากับ XML เอาเสียเลย เทคนิคที่ใช้จึงควรสร้างหรือตัดแต่งข้อมูลโดยใช้ Object ที่เป็น built-in datatype ซึ่งสะดวกมากกว่า เสร็จแล้วค่อยแปลงผลลัพธ์สุดท้ายจาก Object เป็น XML
xml-js เป็น open source สำหรับแปลงข้อมูลระหว่าง XML กับ JavaScript Object ทั้งสองทางมีทั้งหมด 4 ฟังก์ชั่นให้เรียกใช้ คือ - js2xml เป็นฟังก์ชั่นที่ใช้เพื่อสร้าง XML จาก Object
ก่อนที่จะเลือก xml-js ผมได้ทดสอบ library อีกตัว x2js ซึ่งเคยใช้ในงานสร้างไฟล์ excel ก่อนหน้านั้น ปรากฏว่ามีปัญหากับโครงสร้าง XML ที่เป็น array ยังไม่แม่นยำพอ และไม่ค่อยถูกใจกับการออกแบบการเก็บค่า prefix และ attribute รวมทั้งไม่แสดงข้อความเตือน หากโครงสร้าง XML ไม่ถูกต้อง
ทดสอบ XML to JSON
ขั้นตอนแรกที่ทำคือ หาตัวอย่าง XML ของ E-Tax Invoice มาทดลองแปลงเป็น Object เพื่อดูโครงสร้างและการตั้งชื่อ key
ตัวอย่างจาก TEDA E-Tax Invoice & E-Receipt schema ข้อควรระวัง ตัวอย่างไฟล์ XML บางไฟล์เป็น schema version 1.8 (ER3-2558) ซึ่งใช้ไม่ได้ ตรวจสอบกับ XML E-Tax Schema Validator ของสรรพากรไม่ผ่าน
นอกจากนี้เราอาจใช้ XML จาก E-Tax Invoice ตัวจริงที่เป็น PDF จากร้านค้า กรณีนี้เราสามารถแยก XML file ที่ซ่อนอยู่ข้างใน PDF ออกมา โดยใช้โปรแกรม Firefox browser (หรือ Adobe PDF Reader)
เมื่อได้ไฟล์ XML มาแล้ว เราเขียนโค้ดสั้น ๆ ด้วย NodeJS แปลง XML เป็น JSON เพื่อดูโครงสร้างตัวอย่าง
สร้าง folder ใหม่ test
สร้าง package.json ภายใน folder npm init
ติดตั้ง package module ที่ต้องการ npm install xml-js
สร้างไฟล์ index.js เขียนโค้ดตามตัวอย่างด้านล่าง สมมุติว่าไฟล์ XML ต้นแบบชื่อ “text.xml” เสร็จแล้วสามารถเรียก node index เพื่อ run code
const convert = require('xml-js')
const fs = require('fs')
const xml = fs.readFileSync('test.xml', 'utf8')
const json = convert.xml2json(xml, {compact: true, spaces: 2})
console.log(json)
// fs.writeFileSync('test.json', json)
ตอนนี้เราสามารถเปรียบเทียบโครงสร้างของ XML กับ JSON ที่ได้ หากเราเขียนโค้ดเพื่อเตรียมข้อมูลเป็นObject ได้ตามโครงสร้างตัวอย่าง ก็สามารถแปลงกลับมาเป็น XML ตอนจบได้
ภาพด้านล่างเป็นตัวอย่างเทียบ ระหว่าง XML กับ JSON ที่มีข้อมูลตรงกัน ซึ่งช่วยให้เข้าใจโครงสร้างที่ต้องใช้เทียบกับ XML tag สำหรับแปลงไป-กลับ ได้แก่ `_attributes` และ `_text`
ER3–2560
การทำความเข้าใจโครงสร้างข้อมูล E-Tax Invoice เป็นส่วนที่กินเวลามากที่สุด อ้างอิงจากเอกสาร ขมธอ.3–2560 วิธีการอ่านสเปคข้อมูลเริ่มต้นจากตาราง แต่ภายในตารางจะอ้างอิงถึงคำอธิบายเพิ่มเติม และในคำอธิบายก็อาจอ้างอิงถึงภาคผนวกที่อ้างถึงข้อมูลภายนอกอีกทีหนึ่ง
เนื่องจากเอกสารนี้ไม่มี hyperlink ไม่สามารถทำ bookmark คลิ๊กไปดูหัวข้อที่อ้างอิงแล้วกลับมาที่เดิมได้ ต้องใช้วิธีเปิดค้างไว้ 3 แท็บ และอาจทำ screenshot ตรงที่จำเป็นเพื่อใช้แชร์หรือค้นคว้าภายหลังเก็บไว้เอง
ตารางอธิบาย schema
คำอธิบายข้อมูลย่อย
ภาคผนวก อ้างอิงข้อมูลอื่น
Schema level 1:
ตอนแรกที่เห็นตารางอธิบาย Schema ที่ยาวเหยียด เชื่อว่าแทบทุกคนมีความรู้สึกเหมือนกัน สำหรับผมรู้สึกเหมือนกับมีอาหารมื้อใหญ่อยู่เต็มโต๊ะเกินกว่าจะกินหมดในคราวเดียว ต้องถอยออกมาวางแผนว่าจะจัดการอย่างไร ใช้เวลาอยู่หลายวันค่อย ๆ สำรวจกลับไปกลับมาจึงพอรู้ทางหนีทีไล่
โครงสร้างชั้นที่หนึ่ง สังเกตตัวเลขคุมตัวเดียว จากคอลัมน์ Index ในตาราง ประกอบด้วย 3 ส่วน
(1) Document context นิยามโครงสร้างข้อมูลว่าอ้างอิงมาตรฐาน สำหรับ E-Tax Invoice ทุกประเภท ระบุเหมือนกันหมด (ER3–2560)
<rsm:ExchangedDocumentContext>
<ram:GuidelineSpecifiedDocumentContextParameter>
<ram:ID schemeAgencyID="ETDA" schemeVersionID="v2.0">ER3-2560</ram:ID>
</ram:GuidelineSpecifiedDocumentContextParameter>
</rsm:ExchangedDocumentContext>
(2) Document Identity ระบุข้อมูลบ่งชี้ของเอกสาร เช่น
(3) Trade information รายละเอียดของธุรกรรมภายในบิล เป็นส่วนที่มีรายละเอียดยืดยาว ยุบยับ ซึ่งจะต้องเจาะลึกลงไปอธิบายใน level 2
Schema level 2: เจาะลึก Trade information
รายละเอียดของธุรกรรมภายในบิล สามารถแบ่งออกเป็น 4 กลุ่มใหญ่ แนะนำให้ดู slide จาก ETDA ประกอบ
เงื่อนไข (R) ห้ามเว้นว่าง และ (BD) เว้นได้ สำหรับเอกสารแต่ละประเภทอาจไม่เหมือนกัน เพื่อไม่ให้สับสน ผมอ้างอิงจากเงื่อนไขของ ใบกำกับภาษี ดูเฉพาะคอลัมน์ TIV ในตาราง
(3.1) Trade Agreement ข้อมูลคู่ค้า
(3.2) Trade Delivery ข้อมูลจัดส่ง
(3.3) Trade Settlement ข้อมูลการเงิน
(3.4) Trade Line Item รายการสินค้า
Party schema: ข้อมูลผู้เกี่ยวข้อง
ส่วนที่เยิ่นเย้อที่สุดทำให้ตารางดูเยอะ คือ ข้อมูลของผู้เกี่ยวข้องต่าง ๆ ซึ่งเป็นส่วนที่มีรายละเอียดภายในเหมือนกัน ได้แก่ ชื่อ, เลขผู้เสียภาษี ที่อยู่, ช่องทางติดต่อ
(xyz) XYZ party ข้อมูลผู้เกี่ยข้อง
ตามปกติ ผู้เกี่ยวข้องที่สำคัญมีอยู่แค่ 2 กลุ่ม ผู้ขาย และ ผู้ซื้อ เท่านั้น สำหรับ E-Tax Invoice กลุ่มอื่น ๆ ไม่จำเป็นต้องใช้
เมื่อเข้าใจโครงสร้างข้างต้น โดยเฉพาะส่วนของที่อยู่ ก็สามารถเขียนโค้ดให้สร้างข้อมูลตามรูปแบบที่เหมือนกันเพื่อใช้กับผู้เกี่ยวข้องทั้งหมดได้
ส่วนที่ต้องอุทานว่า อิหยังว่ะ การกำหนดเงื่อนไขที่อยู่แบบมีโครงสร้าง จังหวัด, อำเภอ และตำบล ห้ามใช้ชื่อเรียกในที่อยู่ตามบัตรประชาชน และทะเบียนพาณิชย์ ที่อยู่ที่เราใช้ส่งจดหมาย และสั่งสินค้าออนไลน์กันทั่วไป แต่ต้องระบุเป็นรหัสมาตรฐาน มอก. 1099–2548 (TISI 1099) ที่ไม่คุ้นเคย เช่น ที่อยู่ของแขวงท่าข้าม ใช้รหัสไปรษณีย์ 10150 จะต้องใช้รหัสมาตรฐานต่อไปนี้ 10 หมายถึง จังหวัดกรุงเทพมหานคร, 1021 หมายถึง เขตบางขุนเทียน และ 102105 หมายถึง แขวงท่าข้าม
เฉพาะข้อมูลผู้ขาย (seller) บังคับให้ระบุที่อยู่แบบมีโครงสร้าง รหัสไปรษณีย์, รหัสประเทศ, รหัสจังหวัด, รหัสอำเภอ และรหัสตำบล
ข้อมูลผู้เกี่ยวข้องอื่นที่ไม่ใช่ผู้ขาย สามารถระบุแบบมีโครงสร้างหรือไม่มีโครงสร้างก็ได้ แต่บังคับให้ต้องระบุ รหัสไปรษณีย์ และ รหัสประเทศ เสมอ
โชคดีที่ข้อบังคับให้ระบุที่อยู่แบบมีโครงสร้าง ใช้บังคับเฉพาะข้อมูลของผู้ขายเท่านั้น นอกนั้นสามารถใช้แบบไม่มีโครงสร้างเป็น บรรทัดที่ 1, 2 กับรหัสไปรษณีย์ได้
เพราะในทางปฏิบัติจริง สำหรับพนักงานตามบริษัทห้างร้านที่เปิดใบกำกับภาษี ถึงแม้จะรู้ที่อยู่ของลูกค้า แต่ก็ไม่สามารถแปลให้เป็นรหัสมาตรฐานดังกล่าวได้ ยกเว้นแต่จะใช้โปรแกรมเปิดบิลที่ออกแบบให้เชื่อมโยงกับตารางรหัส
Trade Delivery Schema: ข้อมูลจัดส่ง
เป็นส่วนข้อมูลที่การค้าภายในประเทศไม่จำเป็นต้องมี แต่เข้าใจว่าโครงสร้างนี้ยกมาจากการค้าระหว่างประเทศ จึงกลายเป็นเงื่อนไขบังคับติดมาด้วย
เราสามารถหลอก Schemtron ให้ตรวจผ่าน ด้วยโครงดังนี้
<ram:ApplicableHeaderTradeDelivery>
<ram:ActualDeliverySupplyChainEvent/></ram:ApplicableHeaderTradeDelivery>
Data to Schema Mapping
เมื่อพอเข้าใจโครงสร้างของข้อมูลแล้ว จะเห็นว่าถึงแม้ว่าจะใช้ JavaScript Object แต่ชื่อของ key ซึ่งตรงกับชื่อ element ใน XML ก็ยาวจนทำให้ไม่สะดวกต่อการอ้างถึง เมื่อต้องใช้คำนวณหรือประมวลผล
ดังนั้นจึงต้องออกแบบโค้ดให้ทำงานเป็น 2 ขั้นตอน
เตรียมข้อมูล (Data) โดยใช้ชื่อที่สะดวกต่อการเขียนโค้ดเพื่อประมวลผล อาจต้องอ่านจาก database มาประกอบ หรือคำนวณตัวเลขจำนวนเงินต่าง ๆ เพื่อให้มีฟิลด์ที่สอดคล้องกับโครงสร้าง
{
"seller": {
"name": "OWNDAYS (THAILAND)CO.,LTD.",
"taxid": "0115558017774",
"taxbr": "00032",
...,
},
}
แปลง Data เป็น Object ที่มีชื่อตาม schema เพื่อแปลงเป็น XML ต่อไป
{
"rsm:SupplyChainTradeTransaction": {
"ram:ApplicableHeaderTradeAgreement": {
"ram:SellerTradeParty": {
"ram:Name": {
"_text": "OWNDAYS (THAILAND)CO.,LTD."
},
"ram:SpecifiedTaxRegistration": {
"ram:ID": {
"_attributes": {
"schemeID": "TXID"
},
"_text": "011555801777400032"
}
},
...,
}
}
}
}
ผมใช้วิธีออกแบบตาราง mapping ระหว่างชื่อ key ที่เป็นข้อมูลเตรียม กับชื่อ element ของ XML เอาไว้เทียบ ข้อมูลบางอย่างอาจเกิดจากการเขียนโค้ดแปลงหรือใช้สูตรคำนวณจะสะดวกกว่า
เลขรหัสตำบล 6 หลัก สามารถตัดเป็นรหัสอำเภอ (4 หลักแรก) และจังหวัด (2 หลักแรก) จึงไม่จำเป็นต้องมีข้อมูลซ้ำซ้อนในส่วนเตรียมข้อมูล - 102105 แขวงท่าข้าม - 1021 เขตบางขุนเทียน - 10 กรุงเทพมหานคร
อัตราภาษีในระดับบรรทัดรายงานของส่วนเตรียมข้อมูลใช้เฉพาะ Rate เป็น 0, 7 หรือ -1 (ยกเว้นภาษี) แปลงเป็น XML (TypeCode : Rate) ได้เช่น (VAT : 0), (VAT : 7) และ (FRE : 0)
ยอดเงินรวม, มูลค่าภาษีรวม สามารถรวมจากยอดที่อยู่ในระดับบรรทัดรายการ
มูลค่าสุดท้าย (GrandTotalAmount) สามารถคำนวณจาก มูลค่าก่อนภาษี (BasisTotalAmount) + มูลค่าภาษี (TaxTotalAmount)
Tax ID classification
เลขผู้เสียภาษีกำหนดให้ระบุประเภทเป็น attribute SchemaID ใน XML ในทางปฏิบัติเราไม่ควรออกแบบให้เป็นภาระของผู้ใช้ที่ต้องระบุสิ่งที่ต้องคิดวิเคราะห์โดยไม่จำเป็น ซึ่งมีโอกาสที่ทัศนะของแต่ละคนคลาดเคลื่อนเข้าใจไม่ตรงกัน
TXID เลขผู้เสียภาษี
NIDN เลขบัตรประชาชน
CCIP เลขหนังสือเดินทาง (ต่างด้าว)
OTHR อื่น ๆ
เงื่อนไขเพิ่มเติมของ TXID นั้นกำหนดให้ระบุเลขผู้เสียภาษีตามด้วยเลขสาขาอีก 5 ตัว กลายเป็น 18 ตัว เนื่องจากเลขสาขาเป็นเลขที่ใช้สำหรับผู้จดทะเบียนภาษีมูลค่าเพิ่มทั้งนิติบุคคลและบุคคลธรรมดา ทำให้เกิดความคลุมเครือดังนี้ TXID หมายถึง นิติบุคคล หรือ เลขผู้จดทะเบียนภาษีมูลค่าเพิ่มกันแน่ หากหมายถึง นิติบุคคล แล้วบุคคลธรรมดาที่จดทะเบียนสาขาภาษีมูลค่าเพิ่มมากกว่า 1 แห่ง จะระบุสาขาใน NIDN อย่างไร หาก TXID หมายถึง ผู้จดทะเบียนภาษีมูลค่าเพิ่ม ในทางปฏิบัติจะตรวจสอบอย่างไรว่าจดภาษีมูลค่าเพิ่มหรือไม่
Tambon with Amphure Province API
คุณ kongvut ทำข้อมูล Metadata of Thailand Province name (ข้อมูลจังหวัด อำเภอ ตำบล ของประเทศไทย) ให้สามารถนำมาใช้กับโปรแกรมได้
ผมลองเอา api_revert_tambon_with_amphure_province.json มาแสดงผลด้วย HCSV เอาไว้เป็นเครื่องมือช่วยค้นหารหัสที่ต้องการ จากชื่อตำบล ชื่ออำเภอ หรือรหัสไปรษณีย์
Tax and Monetary ภาษีและมูลค่าทางการเงิน
ความยุ่งเหยิงของโครงสร้างนี้ อยู่ตรงที่ความซับซ้อนของข้อยกเว้นในระบบภาษีมูลค่าเพิ่ม ทำให้มีสินค้าบางรายการอาจยกเว้นภาษี มิติของจำนวนเงินทางการค้าที่มีเพียงมูลค่าก่อนภาษีกับมูลค่าภาษี ไม่สามารถแจกแจงให้ตรวจสอบแยกประเภทภาษีได้ จึงจำเป็นมีตัวเลขส่วน Trade Tax ที่ดูเหมือนซ้ำซ้อนกับตัวเลขของ Summation ในบางกรณี
ธุรกิจแต่ละประเภทอาจไม่เหมือนกัน บิลที่ใช้ภายในประเทศทุกวันนี้ มีอะไรที่หลากหลาย ผมแนะนำให้ลองตั้งโจทย์หลาย ๆ แบบที่คิดว่าจะเจอ และหาทางหยอดตัวเลข ให้ลงช่องต่าง ๆ ตามโครงสร้างดู
บิลขายสินค้าที่ราคายังไม่รวม VAT
บิลขายสินค้าที่ราคารวม VAT แล้ว
ในบิลเดียวกัน มีทั้งสินค้าคิด VAT เพิ่มและยกเว้นภาษี
ในบิลเดียวกัน มีทั้งสินค้าที่ราคารวม VAT และยกเว้นภาษี
บิลที่มีส่วนลดต่อรายการ เช่น ขนมถุง 35 บาท แต่ขาย 3 ถุง ลด 5 บาท (3 ถุง 100)
บิลที่มีหลายรายการ แล้วมีส่วนลดท้ายบิล เช่น ลดคูปอง 10 บาท
3.4 Line Items
ข้อมูลเกี่ยวกับตัวเลข ในบรรทัดรายการ
(3.4.3) Agreement ราคาและส่วนลด (ต่อหน่วย)
(3.4.4) Delivery เงื่อนไขการส่งมอบสินค้า
(3.4.5.1) Trade Tax การคำนวณภาษี (มุมมองภาษี) เหมือนกับ 3.3.2 ด้านบนแต่เป็นการคำนวณระดับรายการ
(3.4.5.2) AllowanceCharge ส่วนลดหรือค่าธรรมเนียม (ต่อรายการ)
(3.4.5.3) Summation สรุปยอด (มุมมองการชำระ)
3.3 Trade Settlement
ข้อมูลที่เป็นยอดสรุป (รวมมาจาก Line Item?)
(3.3.2) Trade Tax สรุปการคำนวณภาษี(มุมมองภาษี)
(3.3.5) Summation สรุปยอด(มุมมองการชำระ)
ตัวอย่าง Trade Tax กับ Summation กรณีบิลที่มีสินค้าคิดภาษี 100 บาท และยกเว้นภาษี 10 บาท
{
"TradeTax": [
{ "TypeCode":"VAT", "Rate":7, "Basis":100, "Tax":7 },
{ "TypeCode":"FRE", "Rate":0, "Basis":10, "Tax": 0 }
],
"Summation": {
"Amount": 110,
"Basis": 110,
"Tax": 7,
"GrandTotal": 117
},
"Items": [
{ "Name": "สินค้า VAT..", "Price":100, "Qty":1,
"TradeTax": { "TypeCode":"VAT", "Rate":7, "Basis":100, "Tax":7 },
"Summation": { "Tax":7, "Amount":100, "Total":107}
},
{ "Name": "สินค้า NOVAT..", "Price":10, "Qty":1,
"TradeTax": { "TypeCode":"FRE", "Rate":0, "Basis":10, "Tax":0 },
"Summation": { "Tax":0, "Amount":10, "Total":10}
}
]
}
บิลทดสอบ
วิธีการทดสอบง่ายที่สุดคือ นำไฟล์ XML ที่ได้ส่งไปทดสอบกับเพจของสรรพากรโดยตรง หากข้อมูลตรงไหนไม่ถูกต้องก็จะมีคำอธิบายให้เราทราบ
หากไม่แน่ใจตรงจุดไหน ก็อาจ edit ไฟล์ XML นั้นโดยตรงก่อน ส่งไปทดสอบใหม่ จนได้ข้อสรุปว่าแบบไหนใช้ได้ แบบไหนใช้ไม่ได้ แล้วค่อยกลับไปปรับโค้ดอีกทีหนึ่ง
เช่น ตามเอกสารอ้างอิง คำอธิบายใช้คำว่า “ชื่อตำบล” ก็อาจลองใส่ชื่อตำบล แทนที่จะเป็นรหัสตำบล หากตรวจไม่ผ่านก็รู้แล้วว่า ข้อมูลนี้บังคับใช้รหัสเท่านั้น
สำหรับตัวอย่างบิลที่ทดสอบจนผ่าน มีรายละเอียดที่เรียกว่าค่อนข้างซับซ้อนต่อการคำนวณและจัดรูปแบบให้ได้ตาม Schema ที่กำหนดไว้
ภายในบิลมีส่วนลดบางรายการ และมีส่วนลดรวมด้านล่างอีกชั้นหนึ่ง ซึ่งการแสดงบิลลักษณะนี้ Schema ยังมีข้อจำกัด หากส่วนลดมีผลกระทบต่อการคำนวณภาษี ต้องใช้วิธีเอาส่วนลดรวมกลับไปกระทบคำนวณเป็นส่วนลดของสินค้าแต่ละรายการ เพื่อให้ได้มูลค่าต่าง ๆ เฉพาะของรายการนั้น (LineTradeSettlement) สามารถยันยอดกับตัวเลขสรุปได้ (HeaderTradeSettlement)
นอกจากนี้ยังมีรายการที่คิดภาษีและยกเว้นภาษีปนกันในบิลเดียว เมื่อสรุปการคำนวณภาษีจะต้องทำเป็นตัวเลข 2 ชุด ที่มี (TypeCode : Rate) แตกต่างกัน คือ (VAT : 7) และ (FRE : 0)
การทดสอบอื่น ที่คิดว่าจะทำเพิ่ม เพื่อทดสอบ Schematron
เลขผู้เสียภาษีแบบต่าง ๆ บุคคลธรรมดา และต่างด้าว
ลูกค้าที่ไม่รับใบกำกับภาษี (ไม่ให้ ชื่อ, ที่อยู่และเลขผู้เสียภาษี)
ภาษีอัตรา 0 (ขายราชการ และบริษัท BOI)
คำนวณภาษีรวมใน กรณีคำนวณถอดภาษีระดับบรรทัดมารวมกัน ไม่ตรงกับคำนวณจากยอดรวม
อ้างอิง
ขมธอ.3–2560 (ER3–2560) เอกสารอธิบาย E-Tax Invoice Schema
xml-js open source สำหรับแปลงข้อมูลระหว่าง XML กับ JavaScript Object
E-Tax Invoice & Receipt schema ไฟล์โครงสร้างข้อมูลจาก TEDA กรณีต้องการติดตั้ง XML Validator Tools (Schematron) ใช้งานเอง
XML E-Tax Schema Validation ของสรรพากร สามารถ upload ไฟล์ XML ไปตรวจสอบ มีแจ้งรายละเอียดจุดที่มีปัญหาใน XML เหมาะสำหรับ developer ใช้ตรวจสอบ
PDF & XML Validation ของ TEDA ตรวจสอบ PDF หรือ XML ว่าผ่านหรือไม่ผ่าน เหมาะสำหรับผู้ใช้ทั่วไป
XML presentation slides ของ ETDA อธิบายโครงสร้างของ XML
มอก. 1099–2548 (TISI 1099) รหัสมาตรฐานสำหรับ จังหวัด, อำเภอ และตำบล ใช้กับที่อยู่แบบมีโครงสร้าง
Metadata of Thailand Province name (ข้อมูลจังหวัด อำเภอ ตำบล ของประเทศไทย พร้อมรหัสมาตรฐาน) เป็น API
Country Code ISO 3166 dataset เป็น API
unece code list recommend มาตรฐานรหัสต่าง ๆ ที่อ้างถึงในภาคผนวก ER3–2560 เช่น รหัสหน่วยวัด
Comments