{"id":16758,"date":"2026-02-27T04:13:28","date_gmt":"2026-02-27T04:13:28","guid":{"rendered":"https:\/\/www.hashmicro.com\/my\/blog\/?p=16758"},"modified":"2026-03-10T08:53:45","modified_gmt":"2026-03-10T08:53:45","slug":"3-way-matching-invoice","status":"publish","type":"post","link":"https:\/\/www.hashmicro.com\/my\/blog\/3-way-matching-invoice\/","title":{"rendered":"3-Way Matching: What It Is, How It Works, and Why AP Teams Depend on It"},"content":{"rendered":"<p><!-- WARNING: COMPETITOR DATA WAS MOCK (Google Search Failed) --><br \/>\n<\/p>\n<p><span style=\"font-weight: 400;\">Every accounts payable team hits the same pressure point sooner or later. You place an order, the goods arrive, then an invoice shows up and you have to <a href=\"https:\/\/www.hashmicro.com\/my\/blog\/invoice-payment\/\">decide fast whether it is safe to pay.<\/a><\/span><\/p>\n<p><span style=\"font-weight: 400;\">If you skip a proper check, you <a href=\"https:\/\/www.hashmicro.com\/my\/blog\/what-is-procurement-management-system\/\">risk paying for items that never landed<\/a>, accepting a price that was never approved, or clearing a bill that does not belong to your company. Those mistakes rarely look huge on one invoice, but they add up quietly and they always surface at the worst time.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">This guide walks you through the exact checks you should run, the messy spots that usually slow teams down, and the practical fixes that make approvals quicker without losing control, so keep reading because the later sections include simple habits you can apply right away to cut exceptions, protect your cash, and keep your vendor payments clean.<\/span><\/p>\n<table style=\"border-collapse: collapse; background-color: #fffacd; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); border-radius: 25px 25px 25px 25px;\" width=\"100%\">\n<tbody>\n<tr>\n<td style=\"padding: 15px; border: none;\">\n<h3 style=\"margin-bottom: 10px;\"><span style=\"background-color: #8a0e19; color: #ffffff; padding: 5px;\"><b>Key Takeaways<\/b><\/span><\/h3>\n<ul>\n<li data-start=\"750\" data-end=\"870\">\n<p data-start=\"753\" data-end=\"870\"><a href=\"#Three-hrms\">Three way<\/a> matching works because it verifies one transaction across three documents: PO, GRN, and supplier invoice.<\/p>\n<\/li>\n<li data-start=\"871\" data-end=\"972\">\n<p data-start=\"874\" data-end=\"972\">Your PO <a href=\"#Your-hrms\">quality drives everything<\/a>. If the PO is vague or unapproved, exceptions will rise later.<\/p>\n<\/li>\n<li data-start=\"871\" data-end=\"972\">\n<p data-start=\"874\" data-end=\"972\">Your GRN is your <a href=\"#Gets-hrms\">proof of receipt<\/a>. If receiving posts late or records poorly, invoices will get stuck.<\/p>\n<\/li>\n<\/ul>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><!-- <div id=\"toc_group_article\" style=''>\r\n\t<p style='font-size:25px;font-weight:bold; margin-bottom:0px'>\r\n\t\tTable of Content\r\n\t<\/p>\r\n\t<ul id=\"list_toc\" class='list_toc'><\/ul>\r\n<\/div>\r\n\r\n<div class=\"dropdown-fixed-top\" id=\"dropdown-fixed-top\">\r\n\t<div class=\"row\">\r\n\t\t<p id=\"pilihDaftarIsi\">Content Lists<\/p>\r\n\t\t<p><i class=\"td-icon-menu-down\"><\/i><\/p>\r\n\t<\/div>\r\n\t\r\n\t<div>\r\n\t\t<ul id=\"list_toc_top\" class='list_toc'><\/ul>\r\n\t<\/div>\r\n<\/div> -->\r\n\r\n<!-- TOC mobile -->\r\n<div id=\"placeholder-toc\"><\/div>\r\n<div id=\"toc\">\r\n    <div class=\"header\">\r\n\t<span class=\"toc-title\" id=\"toc-title\">Table of Content<\/span>\t\r\n\t <i class=\"toc-icon\">\r\n        <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"30\" height=\"30\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#000\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"header-icon\">\r\n          <path d=\"m6 9 6 6 6-6\" \/>\r\n        <\/svg>\r\n      <\/i>\r\n\t<\/div>\r\n    <div class=\"list\">\r\n      <ul id=\"toc-list\"><\/ul>\r\n    <\/div>\r\n <\/div>\r\n<!-- TOC mobile -->\r\n\r\n<style>\r\n\t@media (max-width: 992px) {\r\n\t\t#toc_group_article {\r\n\t\t\tpadding-top: 24px;\r\n\t\t}\r\n\t}\r\n\t\r\n\t#list_toc_float {\r\n\t\tmax-height: calc(100vh - 250px);\r\n\t\toverflow-y: auto;\r\n\t}\r\n\t\r\n\t#list_toc_top {\r\n\t\tdisplay: none;\r\n\t\tbackground: #fff;\r\n\t\tmargin-bottom: 4px;\r\n\t}\r\n\t\r\n\t#list_toc_top li {\r\n\t\tdisplay: block;\r\n\t\tmargin-left: 0;\r\n\t\tlist-style: none;\r\n\t}\r\n\t\r\n\t#list_toc_top a {\r\n\t\tpadding: 5px;\r\n\t\tdisplay: block;\r\n\t}\r\n\t\r\n\t#list_toc_top.show {\r\n\t\tdisplay: block;\r\n\t}\r\n\r\n\t#list_toc_top a {\r\n\t\tcolor: #434343;\r\n\t\tborder-bottom: 1px solid #bbb;\r\n\t}\r\n\t\r\n\t.dropdown-fixed-top {\r\n\t\tposition: fixed;\r\n\t\ttop: 59px;\r\n\t\twidth: 100%;\r\n\t\tz-index: 99;\r\n\t\tborder-bottom: 2px solid #9c171e;\r\n\t\tpadding: 12px;\r\n\t\tbackground: #fff;\r\n\t\twidth: 100%;\r\n\t\tcursor: pointer;\r\n\t\tdisplay: none;\r\n\t\tleft: 0;\r\n\t\tbox-shadow: 0 -2px 7px 6px rgba(0, 0, 0, 0.17);\r\n\t}\r\n\t\r\n\t#dropdown-fixed-top.show {\r\n\t\tanimation: showAnim 0.5s ease;\r\n\t\tdisplay: block;\r\n\t\topacity: 1;\r\n\t}\r\n\t\r\n\t@keyframes showAnim {\r\n\t\tfrom {\r\n\t\t\tdisplay: none;\r\n\t\t\topacity: 0;\r\n\t\t}\r\n\t\tto {\r\n\t\t\tdisplay: block;\r\n\t\t\topacity: 1;\r\n\t\t}\r\n\t}\r\n\t\r\n\t.dropdown-fixed-top #list_toc_top {\r\n\t\tmax-height: calc(50vh - 110px);\r\n\t\toverflow-y: scroll;\r\n\t}\r\n\t\r\n\t.dropdown-fixed-top .row {\r\n\t\tdisplay: flex;\r\n\t\tjustify-content: space-between\r\n\t}\r\n\t\r\n\t.dropdown-fixed-top .row p {\r\n\t\tmargin-bottom: 0;\r\n\t}\r\n\t\r\n\t#pilihDaftarIsi {\r\n\t\tmax-width: 100%;\r\n\t\toverflow: hidden;\r\n\t\twhite-space: nowrap;\r\n\t}\r\n\t\r\n\t@media (min-width: 1018px) {\r\n\t\t.dropdown-fixed-top {\r\n\t\t\tdisplay: none;\r\n\t\t}\r\n\t}\r\n\t\r\n\t#list_toc li {margin-bottom: 0;margin-top: 5px;}\r\n\t#list_toc > li > ul {padding-left: 20px;margin-bottom: 0;}\r\n\t#list_toc{height:max-content;transition:ease-in-out}\r\n\t#list_toc li {margin-bottom: 0;margin-top: 5px;}\r\n\t#list_toc_float li.active > a {color:#b1252d;background: #ffe1e3;}\r\n\t#list_toc_top li.active > a {color:#b1252d;background: #ffe1e3;}\r\n\t#list_toc_float li a {padding:3px 7px}\r\n\t#list_toc_float li a {\r\n\t\tdisplay: block;\r\n\t\tcolor: #000;\r\n\t\tmargin-bottom: 6px;\r\n\t\tpadding-top: 2px;\r\n\t\tpadding-bottom: 2px;\r\n\t\ttransition: all 0.2s ease-in-out;\r\n\t\tfont-size: 15px;\r\n\t\tline-height: 18px;\r\n\t}\r\n\t#list_toc_float li{list-style:none;list-style-position:inside; margin-left:0;}\r\n\t#list_toc_float a:hover{color:#b1252d;}\r\n\t\r\n\t#toc_group_float{\r\n\t\tline-height: 24px;\r\n\t\tmax-height: calc(100vh - 100px);\r\n\t\toverflow: auto;\r\n\t\tz-index: 99;\r\n\t\tdisplay:none!important;\r\n\t\tbackground:#fff;\r\n\t\ttransition:all 0.5s linear\r\n\t}\r\n\t\r\n\t@media (min-width:1019px){\r\n\t\t#toc_group_float {\r\n\t\t\tdisplay:block!important;\r\n\t\t}\r\n\t\t#toc_group_article {\r\n\t\t\tdisplay:none;\r\n\t\t}\t\t\t\t\r\n\t}\r\n\r\n<\/style>\r\n\r\n<style>\r\n\t@media (max-width: 992px) {\r\n\t\t#toc_group_article {\r\n\t\t\tpadding-top: 24px;\r\n\t\t}\r\n\t}\r\n\t\r\n\t#list_toc_float {\r\n\t\tmax-height: calc(100vh - 250px);\r\n\t\toverflow-y: auto;\r\n\t}\r\n\t\r\n\t#list_toc_top {\r\n\t\tdisplay: none;\r\n\t\tbackground: #fff;\r\n\t\tmargin-bottom: 4px;\r\n\t}\r\n\t\r\n\t#list_toc_top li {\r\n\t\tdisplay: block;\r\n\t\tmargin-left: 0;\r\n\t\tlist-style: none;\r\n\t}\r\n\t\r\n\t#list_toc_top a {\r\n\t\tpadding: 5px;\r\n\t\tdisplay: block;\r\n\t}\r\n\t\r\n\t#list_toc_top.show {\r\n\t\tdisplay: block;\r\n\t}\r\n\r\n\t#list_toc_top a {\r\n\t\tcolor: #434343;\r\n\t\tborder-bottom: 1px solid #bbb;\r\n\t}\r\n\t\r\n\t.dropdown-fixed-top {\r\n\t\tposition: fixed;\r\n\t\ttop: 59px;\r\n\t\twidth: 100%;\r\n\t\tz-index: 99;\r\n\t\tborder-bottom: 2px solid #9c171e;\r\n\t\tpadding: 12px;\r\n\t\tbackground: #fff;\r\n\t\twidth: 100%;\r\n\t\tcursor: pointer;\r\n\t\tdisplay: none;\r\n\t\tleft: 0;\r\n\t\tbox-shadow: 0 -2px 7px 6px rgba(0, 0, 0, 0.17);\r\n\t}\r\n\t\r\n\t#dropdown-fixed-top.show {\r\n\t\tanimation: showAnim 0.5s ease;\r\n\t\tdisplay: block;\r\n\t\topacity: 1;\r\n\t}\r\n\t\r\n\t@keyframes showAnim {\r\n\t\tfrom {\r\n\t\t\tdisplay: none;\r\n\t\t\topacity: 0;\r\n\t\t}\r\n\t\tto {\r\n\t\t\tdisplay: block;\r\n\t\t\topacity: 1;\r\n\t\t}\r\n\t}\r\n\t\r\n\t.dropdown-fixed-top #list_toc_top {\r\n\t\tmax-height: calc(50vh - 110px);\r\n\t\toverflow-y: scroll;\r\n\t}\r\n\t\r\n\t.dropdown-fixed-top .row {\r\n\t\tdisplay: flex;\r\n\t\tjustify-content: space-between\r\n\t}\r\n\t\r\n\t.dropdown-fixed-top .row p {\r\n\t\tmargin-bottom: 0;\r\n\t}\r\n\t\r\n\t#pilihDaftarIsi {\r\n\t\tmax-width: 100%;\r\n\t\toverflow: hidden;\r\n\t\twhite-space: nowrap;\r\n\t}\r\n\t\r\n\t@media (min-width: 1018px) {\r\n\t\t.dropdown-fixed-top {\r\n\t\t\tdisplay: none;\r\n\t\t}\r\n\t}\r\n\t\r\n\t#list_toc li {margin-bottom: 0;margin-top: 5px;}\r\n\t#list_toc > li > ul {padding-left: 20px;margin-bottom: 0;}\r\n\t#list_toc{height:max-content;transition:ease-in-out}\r\n\t#list_toc li {margin-bottom: 0;margin-top: 5px;}\r\n\t#list_toc_float li.active > a {color:#b1252d;background: #ffe1e3;}\r\n\t#list_toc_top li.active > a {color:#b1252d;background: #ffe1e3;}\r\n\t#list_toc_float li a {padding:3px 7px}\r\n\t#list_toc_float li a {\r\n\t\tdisplay: block;\r\n\t\tcolor: #000;\r\n\t\tmargin-bottom: 6px;\r\n\t\tpadding-top: 2px;\r\n\t\tpadding-bottom: 2px;\r\n\t\ttransition: all 0.2s ease-in-out;\r\n\t\tfont-size: 15px;\r\n\t\tline-height: 18px;\r\n\t}\r\n\t#list_toc_float li{list-style:none;list-style-position:inside; margin-left:0;}\r\n\t#list_toc_float a:hover{color:#b1252d;}\r\n\t\r\n\t#toc_group_float{\r\n\t\tline-height: 24px;\r\n\t\tmax-height: calc(100vh - 100px);\r\n\t\toverflow: auto;\r\n\t\tz-index: 99;\r\n\t\tdisplay:none!important;\r\n\t\tbackground:#fff;\r\n\t\ttransition:all 0.5s linear\r\n\t}\r\n\t\r\n\t@media (min-width:1019px){\r\n\t\t#toc_group_float {\r\n\t\t\tdisplay:block!important;\r\n\t\t\t}\r\n\t\t\t\t#toc_group_article {\r\n\t\t\tdisplay:none;\r\n\t\t}\r\n\t}\r\n\r\n<\/style>\r\n\r\n<!-- START ToC styling  -->\r\n<style>\r\n\t\/* Simple styling for the TOC *\/\r\n\t\r\n\t#toc ul li:last-child {\r\n    padding-bottom: 16px; \/* Adjust the value as needed *\/\r\n}\r\n\r\n.td-fix-index {\r\n\t transform: unset !important;\r\n     -webkit-transform: unset !important; \r\n}\r\n.footer-contact .td-fix-index {\r\n\t transform: translateZ(0) !important;\r\n     -webkit-transform: translateZ(0) !important; \r\n}\r\n\t.tdb_single_content .tdb-block-inner.td-fix-index{\r\n\t\tposition: static;\r\n\t}\r\n\t\r\n\r\n\t\r\n#toc {\r\n  background-color: #FFF;\r\n\tpadding: 17px 24px 0px 24px !important;\r\n  margin-bottom: 20px;\r\n\/*   border: 1px solid #9C171E; *\/\r\n  border-radius: 6px;\r\n\tdisplay: none;\r\n  max-width: 100%;\r\n  transition: .4s ease height;\r\n\tmargin-left: 0;\r\n\toverflow: hidden;\r\n}\r\n\r\n#toc .header{\r\n  display: flex;\r\n  align-items: center;\r\n  justify-content: space-between;\r\n\tbackground-color: transparent;\r\n}\r\n\t\r\n\t#toc.sticky .header{\r\n\t\tpadding: 4px 0;\r\n\t}\r\n\t\r\n.header p{\r\n  font-size: 18px !important;\r\n  font-weight: 600 !important;\r\n  color: #393939;\r\n   margin-bottom: 0;\r\n  \/* margin-top: 20px; *\/\r\n}\r\n\r\n.toc-icon{\r\n  float: right;\r\n\/*   visibility: hidden; *\/\r\n}\r\n\r\n\t.toc-title{\r\n\t\tmargin-right: auto;\r\n\/* \t\tpadding-left: 20px; *\/\r\n\t\tfont-weight: 600;\r\n\t\talign-self: center;\t}\t\r\n\r\n#toc ul {\r\n  list-style-type: none;\r\n  padding-left: 0;\r\n}\r\n\t\r\n#toc.sticky ul{\r\n\toverflow-y: auto;\r\n\tmax-height: 250px;\r\n\tmargin-top: 0px;\r\n\tpadding-top: 20px;\r\n\/* \tborder-top: 1px solid #d3d3d3; *\/\r\n}\r\n\t\r\n#toc ul li {\r\n\/*   margin-bottom: 10px; *\/\r\n  margin-bottom: 10px;\r\n\tmargin-left: 0;\r\n\ttransition: .2s ease;\r\n\tcursor: pointer;\r\n}\r\n\t\r\n\t#toc.sticky ul li {\r\n\t  margin-right: 10px;\r\n\t}\r\n\t\r\n.td-post-content #toc-list li a:hover, .td-post-content #toc-list a.active{\r\n\tbackground-color: #FFF;\r\n\/* \tpadding: 8px 16px 8px 16px; *\/\r\n\tpadding: 4px 16px 4px 16px;\r\n\tborder-radius: 6px;\r\n\tcolor: #9c171e !important;\r\n\tfont-weight: 600 !important;\r\n}\r\n\t\r\n\t.td-post-content #toc-list li:hover a, .td-post-content #toc-list a.active{\r\n\t\tcolor: #9C171E !important;\r\n\t\tfont-weight: 600 !important;\r\n\t}\r\n\t\r\n.td-post-content #toc-list a.active{\r\n\tfont-weight: bold !important;\r\n\tcolor: #9C171E !important;\r\n}\r\n\t\r\n#toc a, .td-post-content #toc-list a {\r\n  text-decoration: none;\r\n  color: #ea1717 !important;\r\n  transition: .2s ease;\r\n\tfont-weight: 400 !important;\r\n\tdisplay: block;\r\n\t\r\n\tpadding: 4px 16px 4px 0;\r\n}\r\n\r\n#toc.sticky {\r\n  position: fixed;\r\n\/*   top: 73px; *\/\r\n\tbottom: 0;\r\n  z-index: 100; \r\n  box-shadow: 0 2px 5px rgba(0,0,0,0.1); \r\n\twidth: 100%; \r\n\tbackground-color: #FFF;\r\n\/* \tbackground-color: #FFF1F1; *\/\r\n\tborder-bottom: 1px solid #ea1717;\r\n\/*   border: 1px solid #393939; *\/\r\n  box-shadow: 0px 0px 14px 0px #00000040;\r\n  cursor: pointer;\r\n\tanimation: fadein .3s ease;\r\n\tpadding: 12px 16px !important;\r\n}\r\n\t\r\n\t.fadein{\r\n\t\tanimation: fadein .3s ease;\r\n\t}\r\n\t\r\n\t.fadeout{\r\n\t\tanimation: fadeout .3s ease;\r\n\t}\r\n\t\r\n\t\r\n\t@keyframes fadein{\r\n\t\t0% {\r\n\t\t\topacity: 0;\r\n\t\t}\r\n\t\t100%{\r\n\t\t\topacity: 1;\r\n\t\t}\r\n\t}\r\n\t\r\n\t@keyframes fadeout{\r\n\t\t0% {\r\n\t\t\topacity: 1;\r\n\t\t}\r\n\t\t100%{\r\n\t\t\topacity: 0;\r\n\t\t}\r\n\t}\r\n\r\n\t\r\n#toc.sticky .header p{\r\n\tmargin-bottom: 10px;\r\n\tmargin-top: 10px;\r\n}\r\n\r\n#toc.sticky .toc-icon{\r\n  visibility: visible;\r\n\/* \ttransition: 0.4s ease; *\/\r\n}\r\n\t\r\n\t.toc-icon{\r\n\t\talign-items: center;\r\n    \tdisplay: flex;\r\n\t}\r\n\t\r\n\tsvg.header-icon{\r\n\/* \t\tbackground-color: #9c171e; *\/\r\n\t\tbackground-color: #FFF;\r\n\t\tborder-radius: 30px;\r\n\t\tpadding: 5px;\r\n\t}\r\n\r\n#toc.sticky .list{\r\n\/*   max-height: 0; *\/\r\n  transition: height 0.4s ease;\r\n}\r\n\t\r\n\t#toc .list{\r\n\/*   max-height: 0; *\/\r\n  transition: height 0.4s ease;\r\n}\r\n\r\n#toc .header.active .toc-icon{\r\n\ttransform: rotate(0deg); \r\n\topacity: 1;\r\n}\r\n\r\n\t#toc .header.active + .list {\r\n\t  max-height: 200px; \/* Adjust this value as needed *\/\r\n\t  opacity: 1;\r\n\t}\r\n\t\r\n\t#placeholder-toc{\r\n\/* \t\tdisplay: none; *\/\r\n\t}\r\n\t\r\n\t@media (min-width: 768px) and (max-width: 991px){\r\n\t\t#toc.sticky{\r\n\/* \t\t\ttop: 104px; *\/\r\n\t\t\tbottom: 0px;\r\n\t\t}\r\n\t\t\r\n\t\t#toc{\r\n\t\t\twidth: unset !important;\r\n\t\t}\r\n\t}\r\n\t\r\n\t@media (max-width: 767px){\r\n\t\t#toc{\r\n\t\t\twidth: 100% !important;\r\n\t\t\tdisplay: inline-block;\r\n\t\t}\r\n\t\t\r\n\t\t#toc.sticky{\r\n\t\t\twidth: 90% !important;\r\n\/* \t\t\ttop: 81px; *\/\r\n\t\t\tbottom: 60px;\r\n\t\t\tmargin-left: auto;\r\n\t\t\tmargin-right: auto;\r\n\t\t\tpadding: 0 16px;\r\n\t\t\tright: 5%;\r\n\t\t}\r\n\t}\r\n\t\r\n\t<\/style>\r\n<!-- END ToC styling  -->\r\n\r\n<!-- ToC List for mobile -->\r\n<script>\r\n \/\/ Generate TOC based on headings\r\ndocument.addEventListener(\"DOMContentLoaded\", function() {\r\n  \/\/ Get the element that will contain the TOC\r\n  const tocList = document.getElementById('toc-list');\r\n\r\n  \/\/ Get the element with the ID 'article-left'\r\n  const article = document.querySelector('.td-post-content');\r\n\r\n  \/\/ Find all h2 elements within 'myarticle'\r\n  const headers = article.getElementsByTagName('h2');\r\n\r\n  \/\/ Loop through the h2 elements and create a list item for each one\r\n  for (let i = 0; i < headers.length; i++) {\r\n    const header = headers[i];\r\n    const headerText = header.textContent;\r\n\/\/     const headerId = 'header-' + i;\r\n    const headerId = headerText\r\n    .toLowerCase()\r\n    .trim()\r\n    .replace(\/[^\\w\\s-]\/g, '')  \/\/ hapus tanda baca\r\n    .replace(\/\\s+\/g, '-'); \/\/ ganti spasi jadi \"-\"\r\n\r\n    \/\/ Set an ID for the header if it doesn't have one\r\n    header.setAttribute('id', headerId);\r\n\r\n    \/\/ Create a list item for the TOC\r\n    const listItem = document.createElement('li');\r\n\r\n    \/\/ Create a link for the list item\r\n    const link = document.createElement('a');\r\n    link.setAttribute('href', '#' + headerId);\r\n    link.textContent = headerText;\r\n\r\n    \/\/ Append the link to the list item\r\n    listItem.appendChild(link);\r\n\r\n    \/\/ Append the list item to the TOC list\r\n    tocList.appendChild(listItem);\r\n  }\r\n});\r\n\r\n\/\/ Keep height and placement of content using placeholder in place of TOC\r\ndocument.addEventListener(\"DOMContentLoaded\", function() {\r\n  const toc = document.querySelector('#toc');\r\n  const placeholderToc = document.querySelector('#placeholder-toc');\r\n\r\n  function setPlaceholderHeight() {\r\n    placeholderToc.style.height = `${toc.offsetHeight}px`;\r\n  }\r\n\r\n  \/\/ Set the initial height of the placeholder\r\n  setPlaceholderHeight();\r\n\r\n  \/\/ Update the height on window resize\r\n  window.addEventListener('resize', setPlaceholderHeight);\r\n});\r\n  const tocTitle = document.querySelector('#toc-title'); \/\/ Assuming header-faq is the element for TOC title\r\n\r\n\/\/ Sticky TOC and update heading\r\ndocument.addEventListener(\"DOMContentLoaded\", function() {\r\n  const toc = document.querySelector('#toc');\r\n  const footer = document.querySelector('.td-footer-template-wrap');\r\n  const tocParent = toc.parentElement;\r\n  const divTop = tocParent.getBoundingClientRect().top + window.pageYOffset;\r\n  const tocHeight = toc.offsetHeight;\r\n  const triggerPoint = divTop + tocHeight + 700;\r\n  const footerHeight = footer.offsetHeight;\r\n  const triggerFooterPoint = footer.getBoundingClientRect().top + window.pageYOffset - footerHeight - footerHeight - footerHeight;\r\n  const phtoc = document.querySelector('#placeholder-toc');\r\n  const headers = document.querySelectorAll('.td-post-content h2');\r\n  const navLinks = document.querySelectorAll('#toc-list a');\r\n\t\r\n\tconst panel2 = document.querySelector(\"#toc .list\");\r\n\tvar icon = document.querySelector(\".toc-icon\");\r\n\r\n  let activeLink = null; \/\/ Declare activeLink outside the loop\r\n\t\r\n  \/\/ Function to handle scroll and add\/remove .sticky class\r\n  function handleScroll() {\r\n    const windowTop = window.pageYOffset || document.documentElement.scrollTop;\r\n    let currentHeader = '';\r\n\r\n    \/\/ Highlight user progress as the heading comes\r\n    headers.forEach(header => {\r\n\t\tconst headerTop = header.offsetTop;\r\n\t\tconst headerHeight = header.clientHeight;\r\n\t\tif (window.scrollY >= (headerTop - headerHeight + 700)) {\r\n\t\t\tconst currentHeaderId = header.getAttribute('id');\r\n\t\t\tconst currentHeaderText = document.getElementById(currentHeaderId).textContent;\r\n\/\/ \t\t\tconsole.log(\"current header text:\", currentHeaderText);\r\n\t\t\ttocTitle.textContent = currentHeaderText;\r\n\t\t\tcurrentHeader = currentHeaderId;\r\n\t\t\t\r\n\t\t\tif(window.innerWidth < 767){\r\n\t\t\t\ttocTitle.textContent = 'Table of Content';\r\n\t\t\t}\r\n\t\t}\r\n\t});\r\n\r\n    navLinks.forEach(link => {\r\n      link.classList.remove('active');\r\n      if(currentHeader != '') {\r\n\t\t  if (link.getAttribute('href').includes(currentHeader)) {\r\n\t\t\t  link.classList.add('active');\r\n\t\t  }\r\n\t  }\r\n    });\r\n\/\/     if (windowTop < triggerFooterPoint) {\r\n\/\/         toc.style.display = 'block';\r\n\/\/ \t}else{\r\n\/\/         toc.style.display = 'none';\r\n\/\/ \t}\r\n    \/\/ Update TOC title if sticky\r\n    if (windowTop > triggerPoint) {\r\n      if (!toc.classList.contains('sticky')) {\r\n        phtoc.style.display = \"block\";\r\n        toc.classList.add('sticky');\r\n        toc.style.width = `${tocParent.offsetWidth}px`; \/\/ Set width to match the parent element\r\n        toc.setAttribute('style', 'width: ' + tocParent.offsetWidth + 'px !important;');\r\n        toc.style.backgroundColor = \"#FFF\";\r\n\t\tpanel2.style.height = '0px';\r\n\t\t  icon.style.transform = \"rotate(180deg)\";\r\n\t\t  if(window.innerWidth < 767){\r\n\/\/ \t\t\t  const tocs = document.querySelector('#toc.sticky');\r\n\t\t\t  tocTitle.textContent = 'Table of Content'; \/\/ Reset title\r\n       \t\t  toc.style.width = '150px'; \/\/ Set width to match the parent element\r\n\t\t  }\r\n      }\r\n      if (currentHeader) {\r\n\/\/         console.log(\"activeLink:\", activeLink);\r\n        if (activeLink) {\r\n\/\/           tocTitle.textContent = activeLink.textContent; \/\/ Update TOC title\r\n          tocTitle.textContent = activeLink ? activeLink.textContent : \"\"; \/\/ Update title only if activeLink exists\r\n        }\r\n      }\r\n    } else {\r\n      toc.classList.remove('sticky');\r\n      phtoc.style.display = \"none\";\r\n      toc.style.width = 'unset'; \/\/ Reset to original width\r\n      toc.style.backgroundColor = \"#FFF\";\r\n      tocTitle.textContent = 'Table of Content'; \/\/ Reset title\r\n\t\tpanel2.style.height = panel2.scrollHeight + \"px\";\r\n\t\ticon.style.transform = \"rotate(180deg)\";\r\n    }\r\n  }\r\n\r\n    \/\/ Attach the scroll event listener to the window\r\n    window.addEventListener('scroll', handleScroll);\r\n\r\n    \/\/ Initial call to handleScroll to set the correct state on load\r\n    handleScroll();\r\n});\r\n\t\r\n\t\/\/ Open toggle TOC\r\n\t  document.addEventListener(\"DOMContentLoaded\", function() {\r\n\t\tvar tocHeader = document.querySelector(\"#toc .header\");\r\n\t\tvar toc = document.querySelector(\"#toc\");\r\n\t\tvar icon = document.querySelector(\".toc-icon\");\r\n\t\tconst tocTitle = document.querySelector('#toc-title');\r\n\t\tconst tocs = document.querySelector('#toc.sticky');\r\n \t\tconst tocParent = toc.parentElement;\t\t  \r\n\r\n\t\t  tocHeader.addEventListener(\"click\", function() {\r\n\t\t\tvar panel = this.nextElementSibling;\r\n\t\t\tif (panel.style.height !== '0px') { \/\/ Check if height is not 0px\r\n\t\t\t  panel.style.height = '0px'; \/\/ Set height to 0 for full collapse\r\n\t\t\t  icon.style.transform = \"rotate(180deg)\";\r\n\/\/ \t\t\t\ttoc.style.paddingBottom = '6px'; \r\n\t\t\t\tif(window.innerWidth > 768){\r\n\t\t\t\t\tif(!toc.classList.contains('sticky')){\r\n\t\t\t\t\t\ttoc.style.width = \"unset\";\r\n\/\/ \t\t\t\t\t\ttoc.setAttribute('style', 'width: ' + tocParent.offsetWidth + 'px !important;');\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (toc.classList.contains('sticky')){\r\n\t\t\t\t\t\ttoc.style.width = '${tocParent.offsetWidth}px';\r\n\t\t\t\t\t\ttoc.setAttribute('style', 'width: ' + tocParent.offsetWidth + 'px !important;');\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tif(window.innerWidth < 767){\r\n\t\t\t\t\ttoc.style.width = \"unset\"; \/\/ Reset width\r\n\t\t\t\t}\r\n\t\t\t\ttoc.style.backgroundColor = \"#FFF1F1\";\r\n\t\t\t} else {\r\n\t\t\t  panel.style.height = panel.scrollHeight + \"px\";\r\n\t\t\t  icon.style.transform = \"rotate(0deg)\";\r\n\t\t\t  toc.style.backgroundColor = \"#FFF\";\r\n\t\t\t  tocTitle.textContent = 'Table of Content'; \/\/ Reset title\r\n\t\t\t\ttoc.style.paddingBottom = '24px';\r\n\t\t\t \tif(window.innerWidth < 767){\r\n\t\t\t\t\ttoc.style.width = `${tocParent.offsetWidth}px`; \/\/ Set width to match the parent element\r\n\t\t\t\t\ttoc.setAttribute('style', 'width: ' + tocParent.offsetWidth + 'px !important;');\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t  });\r\n\r\n\t\t  \/\/ Close TOC when a link inside it is clicked\r\n\t\t  var tocLinks = document.querySelectorAll(\"#toc .list a\");\r\n\t\t  tocLinks.forEach(function(link) {\r\n\t\t\tlink.addEventListener(\"click\", function() {\r\n\t\t\t  var panel = document.querySelector(\"#toc .list\");\r\n\t\t\t  panel.style.height = '0px'; \/\/ Set height to 0 for full collapse\r\n\t\t\t  icon.style.transform = \"rotate(180deg)\";\r\n\t\t\t  toc.style.backgroundColor = \"#FFF\";\r\n\t\t\t});\r\n\t\t  });\r\n\t\t});\r\n<\/script>\r\n\r\n<!-- <script>\r\n\tvar pilihDaftarIsi = document.getElementById('pilihDaftarIsi');\r\n\t\r\n\tdocument.addEventListener('DOMContentLoaded', function() {\r\n\t\tvar dropdownFixedTop = document.querySelector('.dropdown-fixed-top');\r\n\r\n\t\tdropdownFixedTop.addEventListener('click', function() {\r\n\t\t\tvar dropdownContent = this.querySelector('.list_toc');\r\n\t\t\tdropdownContent.classList.toggle('show');\r\n\t\t});\r\n\r\n\t\twindow.addEventListener('click', function(event) {\r\n\t\t\tvar listTocTop = document.getElementById('list_toc_top');\r\n\r\n\t\t\tif (!dropdownFixedTop.contains(event.target)) {\r\n\t\t\t\tlistTocTop.classList.remove('show');\r\n\t\t\t}\r\n\t\t});\r\n\t});\r\n\t\r\n\tvar daftarIsiContainer = document.getElementById('toc_group_article');\r\n\tvar dropdownFixedTop = document.getElementById('dropdown-fixed-top');\r\n    var triggered = false; \/\/ Flag to keep track of whether the function has been triggered\r\n\r\n    window.addEventListener('scroll', function() {\r\n        if (!triggered && isCompletelyScrolledPast(daftarIsiContainer)) {\r\n            showSectionDropdownFixedTop(false);\r\n            triggered = true;\r\n        } else if (triggered && !isCompletelyScrolledPast(daftarIsiContainer)) {\r\n            showSectionDropdownFixedTop(true);\r\n            triggered = false;\r\n        }\r\n    });\r\n\r\n    function isCompletelyScrolledPast(element) {\r\n        var elementTop = element.getBoundingClientRect().top;\r\n        var elementBottom = element.getBoundingClientRect().bottom;\r\n        return elementTop < 0 && elementBottom < 0;\r\n    }\r\n\r\n    function showSectionDropdownFixedTop(show) {\r\n\t\tif (show) {\r\n\t\t\tdropdownFixedTop.classList.remove(\"show\");\r\n\t\t} else {\r\n\t\t\tdropdownFixedTop.classList.add(\"show\");\r\n\t\t}\r\n    }\r\n\r\n\/\/ Scrollspy function to highlight the active TOC item based on the scroll position\r\n  function scrollSpy(tocClass) {\r\n    const scrollPosition = window.scrollY;\r\n\r\n    \/\/ Find the active h2 and h3 headings based on their position in the corresponding TOC\r\n    let activeH2 = null;\r\n    let activeH3 = null;\r\n\r\n    const tocItems = document.querySelectorAll(`.${tocClass} li`);\r\n    tocItems.forEach(item => {\r\n      const a = item.querySelector('a');\r\n      if (!a) return;\r\n      const href = a.getAttribute('href');\r\n      const targetId = href.substring(1); \/\/ Remove the '#' from the href to get the target ID\r\n      const targetElement = document.getElementById(targetId);\r\n      if (!targetElement) return;\r\n\r\n      const targetTop = targetElement.getBoundingClientRect().top + scrollPosition;\r\n      const nextItem = item.nextElementSibling;\r\n      const nextTop = nextItem ? nextItem.getBoundingClientRect().top + scrollPosition : Infinity;\r\n\r\n      if (targetTop <= scrollPosition + 150) {\r\n        if (a.parentElement.parentElement === tocItems) {\r\n          \/\/ The h2 heading is at the root level of the TOC\r\n          activeH2 = { id: targetId, level: 'h2' };\r\n        } else {\r\n          \/\/ The h3 heading is nested under an h2 heading\r\n          const parentH2 = a.parentElement.parentElement.previousElementSibling;\r\n          if (parentH2) {\r\n            const h2Link = parentH2.querySelector('a');\r\n            if (h2Link) {\r\n              const h2Href = h2Link.getAttribute('href');\r\n              const h2Id = h2Href.substring(1);\r\n              activeH2 = { id: h2Id, level: 'h2' };\r\n            }\r\n          }\r\n          activeH3 = { id: targetId, level: 'h3' };\r\n        }\r\n      }\r\n\r\n      if (targetTop > scrollPosition + 150 && nextTop > scrollPosition + 150 && !activeH3) {\r\n        \/\/ Reset the activeH2 when there are no more active h3 headings\r\n        activeH2 = null;\r\n      }\r\n    });\r\n\r\n    \/\/ Update the active state for the TOC items\r\n    tocItems.forEach(item => {\r\n      item.classList.remove('active');\r\n      const a = item.querySelector('a');\r\n      if (a) {\r\n        const href = a.getAttribute('href');\r\n        const targetId = href.substring(1);\r\n        if ((activeH2 && activeH2.id === targetId) || (activeH3 && activeH3.id === targetId)) {\r\n          item.classList.add('active');\r\n\t\t  pilihDaftarIsi.innerHTML = a.textContent;\r\n        }\r\n      }\r\n    });\r\n  }\r\n\r\n  \/\/ Call scrollSpy for each TOC on window scroll\r\n  const tocClasses = ['list_toc', 'list_toc_float', 'list_toc_top']; \/\/ Add other TOC class names here if you have more than two instances\r\n  tocClasses.forEach(tocClass => {\r\n    window.addEventListener('scroll', () => scrollSpy(tocClass));\r\n  });\r\n<\/script> -->\r\n<!-- END script lama -->\r\n\t\r\n<script>\r\n    \/\/ Scrollspy function to highlight the active TOC item based on the scroll position\r\n  function scrollSpy(tocClass) {\r\n    const scrollPosition = window.scrollY;\r\n\r\n    \/\/ Find the active h2 and h3 headings based on their position in the corresponding TOC\r\n    let activeH2 = null;\r\n    let activeH3 = null;\r\n\r\n    const tocItems = document.querySelectorAll(`.${tocClass} li`);\r\n    tocItems.forEach(item => {\r\n      const a = item.querySelector('a');\r\n      if (!a) return;\r\n      const href = a.getAttribute('href');\r\n      const targetId = href.substring(1); \/\/ Remove the '#' from the href to get the target ID\r\n      const targetElement = document.getElementById(targetId);\r\n      if (!targetElement) return;\r\n\r\n      const targetTop = targetElement.getBoundingClientRect().top + scrollPosition;\r\n      const nextItem = item.nextElementSibling;\r\n      const nextTop = nextItem ? nextItem.getBoundingClientRect().top + scrollPosition : Infinity;\r\n\r\n      if (targetTop <= scrollPosition + 150) {\r\n        if (a.parentElement.parentElement === tocItems) {\r\n          \/\/ The h2 heading is at the root level of the TOC\r\n          activeH2 = { id: targetId, level: 'h2' };\r\n        } else {\r\n          \/\/ The h3 heading is nested under an h2 heading\r\n          const parentH2 = a.parentElement.parentElement.previousElementSibling;\r\n          if (parentH2) {\r\n            const h2Link = parentH2.querySelector('a');\r\n            if (h2Link) {\r\n              const h2Href = h2Link.getAttribute('href');\r\n              const h2Id = h2Href.substring(1);\r\n              activeH2 = { id: h2Id, level: 'h2' };\r\n            }\r\n          }\r\n          activeH3 = { id: targetId, level: 'h3' };\r\n        }\r\n      }\r\n\r\n      if (targetTop > scrollPosition + 150 && nextTop > scrollPosition + 150 && !activeH3) {\r\n        \/\/ Reset the activeH2 when there are no more active h3 headings\r\n        activeH2 = null;\r\n      }\r\n    });\r\n\r\n    \/\/ Update the active state for the TOC items\r\n    tocItems.forEach(item => {\r\n      item.classList.remove('active');\r\n      const a = item.querySelector('a');\r\n      if (a) {\r\n        const href = a.getAttribute('href');\r\n        const targetId = href.substring(1);\r\n        if ((activeH2 && activeH2.id === targetId) || (activeH3 && activeH3.id === targetId)) {\r\n          item.classList.add('active');\r\n        }\r\n      }\r\n    });\r\n  }\r\n\r\n  \/\/ Call scrollSpy for each TOC on window scroll\r\n  const tocClasses = ['list_toc', 'list_toc_float', 'list_toc_top']; \/\/ Add other TOC class names here if you have more than two instances\r\n  tocClasses.forEach(tocClass => {\r\n    window.addEventListener('scroll', () => scrollSpy(tocClass));\r\n  });\r\n<\/script>\r\n\t\r\n\r\n<!-- ToC List for desktop side bar, diganti jadi inject by php, di code snippet \"Sidebar Accordion\" -->\r\n<!-- <script>\r\n\tdocument.addEventListener('DOMContentLoaded', function() {\r\n        \/\/ Fungsi untuk mengubah teks menjadi format id\r\n        function formatId(text) {\r\n            return text.trim().replace(\/[^\\w\\d]+\/g, '_');\r\n        }\r\n\r\n        \/\/ Fungsi untuk membuat nested list\r\n        function createNestedList(parentNode, children) {\r\n            if (children.length === 0) return;\r\n\r\n            const nestedUl = document.createElement('ul');\r\n            children.forEach(child => {\r\n                const nestedLi = document.createElement('li');\r\n                const nestedA = document.createElement('a');\r\n                nestedA.textContent = child.title;\r\n                nestedA.href = `#${child.id}`;\r\n                nestedLi.appendChild(nestedA);\r\n                nestedUl.appendChild(nestedLi);\r\n\r\n                if (child.children.length > 0) {\r\n                    createNestedList(nestedLi, child.children);\r\n                }\r\n            });\r\n\r\n            parentNode.appendChild(nestedUl);\r\n        }\r\n\r\n        \/\/ Membuat objek untuk menyimpan daftar h2 dan h3 beserta judulnya\r\n        const headings = [];\r\n\r\n           \/\/ Mengambil semua elemen h2 dan h3\r\n        const elements = document.querySelectorAll('.td-post-content h2');\r\n\t\t\t\/\/, .td-post-content h3\r\n\r\n        elements.forEach(element => {\r\n            if (element.tagName === 'H2') {\r\n                const id = formatId(element.textContent);\r\n                element.id = id;\r\n\t\t\t\tif(element.textContent.toLowerCase() === \"key takeaways\") {return;} \/\/ Biar ga nampilin Key Takeaways di ToC\r\n                headings.push({ level: 'h2', id: id, title: element.textContent, children: [] });\r\n            } else if (element.tagName === 'H3') {\r\n                const id = formatId(element.textContent);\r\n                element.id = id;\r\n                if (headings.length > 0) {\r\n                    headings[headings.length - 1].children.push({ level: 'h3', id: id, title: element.textContent, children: [] });\r\n                }\r\n            }\r\n        });\r\n\r\n        \/\/ Membuat list HTML dari objek headings\r\n        const ul = document.getElementById('list_toc');\r\n        let currentUl = ul;\r\n        headings.forEach(heading => {\r\n            const li = document.createElement('li');\r\n            const a = document.createElement('a');\r\n            a.textContent = heading.title;\r\n            a.href = `#${heading.id}`;\r\n            li.appendChild(a);\r\n\r\n            if (heading.level === 'h2') {\r\n                \/\/ Menyimpan ul saat ini untuk menambahkan nested ul\r\n                currentUl = li;\r\n                ul.appendChild(li);\r\n            } else if (heading.level === 'h3') {\r\n                if (!currentUl.lastElementChild || currentUl.lastElementChild.tagName !== 'UL') {\r\n                    \/\/ Jika belum ada nested ul, buat satu\r\n                    const nestedUl = document.createElement('ul');\r\n                    currentUl.appendChild(nestedUl);\r\n                    currentUl = nestedUl;\r\n                }\r\n                currentUl.appendChild(li);\r\n            }\r\n\r\n            createNestedList(li, heading.children);\r\n        });\r\n\t\t\/\/ Dapatkan elemen ul dengan id 'list_toc_float'\r\nconst ulFloat = document.getElementById('list_toc');\r\nconst ulJourney = document.getElementById('list_journey');\r\n\r\n\/\/ Dapatkan isi (child elements) dari ul dengan id 'list_toc_float'\r\n\tif (ulFloat !== null) {\r\n\t\tconst clonedChildren = ulFloat.cloneNode(true).children;\r\n\t\tconst ulToc = document.getElementById('list_toc_float');\r\n\t\tconst ulTocTop = document.getElementById('list_toc_top');\r\n\t\tif ((ulToc !== null || ulToc !== undefined) && window.innerWidth > 1018){\r\n\t\t\tulToc.append(...clonedChildren);\r\n\t\t} else {\r\n\t\t\tulTocTop.append(...clonedChildren);\r\n\t\t}\r\n\t} \r\n\r\n\tif (ulJourney !== null) {\r\n\t\tconst clonedChildrenJourney = ulJourney.cloneNode(true).children;\r\n\t\tconst ulTocJourney = document.getElementById('list_toc_journey');\r\n\t\tulTocJourney.append(...clonedChildrenJourney);\r\n\t} \r\n\r\n\r\n\r\n\r\n\t\r\n        \/\/ Fungsi untuk mengambil tinggi navbar\r\n        function getNavbarHeight() {\r\n            const navbar = document.getElementById('tdi_34');\r\n            return navbar ? navbar.offsetHeight : 0;\r\n        }\r\n\r\n        \/\/ Fungsi untuk menambahkan offset posisi scroll\r\n        function scrollToElementWithOffset(elementId) {\r\n            const element = document.getElementById(elementId);\r\n            if (element) {\r\n                const offset = getNavbarHeight();\r\n                const elementPosition = element.getBoundingClientRect().top;\r\n                const offsetPosition = elementPosition - offset-40;\r\n\r\n                window.scrollBy({\r\n                    top: offsetPosition,\r\n                    behavior: 'smooth'\r\n                });\r\n            }\r\n        }\r\n\r\n        \/\/ Fungsi untuk menangani klik pada tautan judul\r\n        function handleTitleClick(event) {\r\n            event.preventDefault();\r\n            const href = event.target.getAttribute('href').substr(1);\r\n            scrollToElementWithOffset(href);\r\n        }\r\n\r\n        \/\/ Tambahkan event listener untuk semua tautan judul\r\n        const titleLinks = document.querySelectorAll('a[href^=\"#\"]');\r\n        titleLinks.forEach(link => {\r\n            link.addEventListener('click', handleTitleClick);\r\n        });\r\n\t});\r\n    <\/script> -->\r\n<!-- \t<style>#toc_group_float{display:block !important}<\/style> -->\r\n<a href=\"https:\/\/www.hashmicro.com\/my\/invoicing-software?medium=moneysite-banner\" target=\"_blank\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/www.hashmicro.com\/my\/blog\/wp-content\/uploads\/2025\/08\/e-Invoicing-Software.webp\" data-desktop-src=\"https:\/\/www.hashmicro.com\/my\/blog\/wp-content\/uploads\/2025\/08\/e-Invoicing-Software.webp\" data-mobile-src=\"\" alt=\"eInvoicing\" class=\"responsive-image-banner\"><\/a>\r\n\r\n<script>\r\n    \/\/ check which image to use based on screensize\r\n    document.addEventListener(\"DOMContentLoaded\", function() {\r\n        function updateImageSource() {\r\n            var images = document.querySelectorAll('.responsive-image-banner');\r\n            var screenWidth = window.innerWidth;\r\n\r\n            images.forEach(function(img) {\r\n                var mobileSrc = img.getAttribute('data-mobile-src');\r\n                var desktopSrc = img.getAttribute('data-desktop-src');\r\n\r\n                if (screenWidth < 576 && mobileSrc) {\r\n                    img.setAttribute('src', mobileSrc);\r\n                } else {\r\n                    img.setAttribute('src', desktopSrc);\r\n                }\r\n            });\r\n        }\r\n\r\n        \/\/ Initial check\r\n        updateImageSource();\r\n\r\n        \/\/ Update on resize\r\n        window.addEventListener('resize', updateImageSource);\r\n    });\r\n<\/script><span id=\"Three-hrms\"><\/span><\/p>\n<h2><b>The Three Documents That Keep Your Payments Honest<\/b><\/h2>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-16805\" src=\"https:\/\/www.hashmicro.com\/my\/blog\/wp-content\/uploads\/2026\/02\/The-Three-Documents-That-Keep-Your-Payments-Honest.webp\" alt=\"The Three Documents That Keep Your Payments Honest\" width=\"800\" height=\"450\" srcset=\"https:\/\/www.hashmicro.com\/my\/blog\/wp-content\/uploads\/2026\/02\/The-Three-Documents-That-Keep-Your-Payments-Honest.webp 800w, https:\/\/www.hashmicro.com\/my\/blog\/wp-content\/uploads\/2026\/02\/The-Three-Documents-That-Keep-Your-Payments-Honest-300x169.webp 300w, https:\/\/www.hashmicro.com\/my\/blog\/wp-content\/uploads\/2026\/02\/The-Three-Documents-That-Keep-Your-Payments-Honest-768x432.webp 768w, https:\/\/www.hashmicro.com\/my\/blog\/wp-content\/uploads\/2026\/02\/The-Three-Documents-That-Keep-Your-Payments-Honest-747x420.webp 747w, https:\/\/www.hashmicro.com\/my\/blog\/wp-content\/uploads\/2026\/02\/The-Three-Documents-That-Keep-Your-Payments-Honest-150x84.webp 150w, https:\/\/www.hashmicro.com\/my\/blog\/wp-content\/uploads\/2026\/02\/The-Three-Documents-That-Keep-Your-Payments-Honest-696x392.webp 696w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/p>\n<p><span style=\"font-weight: 400;\">This verification method cross checks three documents before you approve a supplier invoice for payment. Those three documents are:<\/span><\/p>\n<ol>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">The Purchase Order PO: an internal document that authorises the purchase of specific goods or services at an agreed price and quantity.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">The Goods Receipt Note GRN: a record that confirms your receiving team actually received and inspected the items tied to the PO.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">The Supplier Invoice: the bill from your vendor requesting payment for what they delivered.<\/span><\/li>\n<\/ol>\n<p><span style=\"font-weight: 400;\">Your goal stays simple. All three documents should agree. The quantities, unit prices, and line item descriptions on the supplier bill should match what you ordered on the PO and what you received based on the GRN. When they match, you can approve payment with confidence. When they do not, you pause and investigate before money leaves your account.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">This differs from 2 way matching, which compares the supplier bill against the PO only. It also differs from 4 way matching, which adds a quality or inspection acceptance document. If you purchase physical goods, this three document check usually gives you the right balance: strong control without extra admin friction.<\/span><\/p>\n<p><span style=\"font-weight: 400;\"><span id=\"Your-hrms\"><span id=\"Gets-hrms\">It also supports audit expectations in COSO and SOX aligned environments because it creates a clear record of how you verified spend before payment. In Malaysia, it fits the push toward stronger traceability as e Invoice Malaysia becomes more common across vendors. When suppliers submit structured data through LHDN IRBM channels such as MyInvois, <a href=\"https:\/\/www.hashmicro.com\/my\/blog\/purchase-order\/\">you can reconcile transactions faster<\/a>, but only if your PO and GRN records stay complete, consistent, and easy to retrieve.<\/span><\/span><\/span><\/p>\n<h2><b>How Your Invoice Gets Cleared Without Guesswork<\/b><\/h2>\n<p>&nbsp;<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-16804\" src=\"https:\/\/www.hashmicro.com\/my\/blog\/wp-content\/uploads\/2026\/02\/How-Your-Invoice-Gets-Cleared-Without-Guesswork-e1772166310572.webp\" alt=\"How Your Invoice Gets Cleared Without Guesswork\" width=\"757\" height=\"345\" srcset=\"https:\/\/www.hashmicro.com\/my\/blog\/wp-content\/uploads\/2026\/02\/How-Your-Invoice-Gets-Cleared-Without-Guesswork-e1772166310572.webp 757w, https:\/\/www.hashmicro.com\/my\/blog\/wp-content\/uploads\/2026\/02\/How-Your-Invoice-Gets-Cleared-Without-Guesswork-e1772166310572-300x137.webp 300w, https:\/\/www.hashmicro.com\/my\/blog\/wp-content\/uploads\/2026\/02\/How-Your-Invoice-Gets-Cleared-Without-Guesswork-e1772166310572-150x68.webp 150w, https:\/\/www.hashmicro.com\/my\/blog\/wp-content\/uploads\/2026\/02\/How-Your-Invoice-Gets-Cleared-Without-Guesswork-e1772166310572-696x317.webp 696w\" sizes=\"(max-width: 757px) 100vw, 757px\" \/><\/p>\n<p><span style=\"font-weight: 400;\">You understand the workflow faster when you walk through it in order. You will touch procurement, receiving, and accounts payable, and each team produces one piece of proof you need.<\/span><\/p>\n<h3><b>Step 1: Your PO Sets the Ground Rules<\/b><\/h3>\n<p><span style=\"font-weight: 400;\">Your process starts in procurement. When you need goods or services from a vendor, your team raises a purchase order. <a href=\"https:\/\/www.hashmicro.com\/my\/blog\/purchasing-system\/\">Your PO should state what you order<\/a>, how many units you want, the agreed unit price, delivery terms, and payment terms. You also need internal approval based on your spend limits, then you send the PO to the supplier.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Your PO acts like the anchor for the whole check. If your PO looks vague, misses quantities, or carries unconfirmed pricing, you will feel the pain later. If you want fewer holds, you need clean PO discipline from day one, not after the invoice arrives.<\/span><\/p>\n<h3><b>Step 2: Your Receiving Team Records Reality With a GRN<\/b><\/h3>\n<p><span style=\"font-weight: 400;\">When the supplier delivers the order, your receiving team counts and inspects the goods. They confirm quantities and condition, then they record the result in a Goods Receipt Note. Some teams call it a <a href=\"https:\/\/www.hashmicro.com\/my\/blog\/delivery-note\/\">receiving report or delivery receipt<\/a>.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Your GRN should capture the receipt date, the related PO number, items received, quantities received, and any damage or short shipment notes. This document matters because it proves what your business actually received. It also gives you leverage when a supplier claims everything was delivered but your warehouse recorded a short shipment or damaged items.<\/span><\/p>\n<h3><b>Step 3: Your Supplier Invoice Arrives in the Queue<\/b><\/h3>\n<p><span style=\"font-weight: 400;\">Next, your supplier sends an invoice. It usually references the PO number, lists delivered items, shows quantities and prices, and gives a total with payment terms and a due date.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Once the invoice hits your AP workflow, do not approve it just because it looks familiar. This is where teams get burned, especially when month end pressure pushes everyone to clear the queue fast.<\/span><\/p>\n<h3><b>Step 4: You Compare the PO, GRN, and Invoice Line by Line<\/b><\/h3>\n<p><span style=\"font-weight: 400;\">This step is the core of the verification. You compare the supplier bill, the PO, and the GRN across a few checks:<\/span><\/p>\n<ol>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Quantities: Does the billed quantity match what your GRN shows, and does it still align with what you ordered?<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Unit prices: Does the billed unit price match the price on your PO?<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Line items: Do descriptions and item codes refer to the same items across all documents?<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Totals: Do the extended amounts calculate correctly, and does the final total add up?<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><\/li>\n<\/ol>\n<p><span style=\"font-weight: 400;\">Most teams also set tolerance thresholds so tiny differences do not trigger constant holds. You might allow a 1 to 2% variance on invoice value to handle rounding or minor charges. The key is consistency: define tolerance rules once, document them, then apply them the same way every time. If you change the rule depending on who is chasing payment, you create audit risk and repeat disputes.<\/span><\/p>\n<h3><b>Step 5: You Approve Fast or You Hold With a Clear Reason<\/b><\/h3>\n<p><span style=\"font-weight: 400;\">If everything aligns within tolerance, you approve the invoice for payment and schedule it according to the agreed terms.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">If you spot a mismatch, you put the invoice on hold and raise an exception. You then resolve the root cause before you pay. That might mean asking for a corrected invoice, clarifying pricing, or fixing receiving records. In real operations, this is the part where <a href=\"https:\/\/www.hashmicro.com\/my\/blog\/accounting-automation\/\">invoices get stuck for days<\/a> if the GRN is late or if procurement confirms a price change that never made it into a PO update.<\/span><\/p>\n<style>\r\n    #custom-quote {\r\n        background-color: #f0f0f0;\r\n        padding: 20px;\r\n        border-radius: 12px;\r\n        margin: 20px;\r\n        display: flex;\r\n        flex-direction: column;\r\n    }\r\n\r\n    #custom-quote .quote-body {\r\n        display: flex;\r\n        flex-direction: row;\r\n        align-items: flex-start;\r\n        gap: 15px;\r\n        font-size: 16px;\r\n        line-height: 1.5;\r\n        font-style: italic;\r\n    }\r\n\r\n    #custom-quote .quote-icon {\r\n        width: 40px;\r\n        height: 40px;\r\n        flex-shrink: 0;\r\n    }\r\n\r\n    #custom-quote .quote-author-wrapper {\r\n        margin-top: 15px;\r\n        align-self: flex-start;\r\n        margin-left: 55px; \r\n\t\tmargin-bottom: 0px;\r\n    }\r\n\r\n    #custom-quote em {\r\n        font-family: 'Roboto Serif', serif !important;\r\n        font-size: 12px;\r\n        font-weight: bold;\r\n        font-style: normal;\r\n    }\r\n\r\n    @media screen and (max-width: 768px) {\r\n        #custom-quote {\r\n            margin: 15px 0;\r\n            padding: 15px;\r\n        }\r\n        \r\n        #custom-quote .quote-body {\r\n            gap: 12px;\r\n        }\r\n\r\n        #custom-quote .quote-author-wrapper {\r\n            margin-left: 52px;\r\n        }\r\n    }\r\n\r\n    @media screen and (max-width: 480px) {\r\n        #custom-quote {\r\n            margin: 10px 0;\r\n            padding: 12px;\r\n        }\r\n\r\n        #custom-quote .quote-body {\r\n            font-size: 14px;\r\n            gap: 10px;\r\n        }\r\n\r\n        #custom-quote .quote-icon {\r\n            width: 32px;\r\n            height: 32px;\r\n        }\r\n\r\n        #custom-quote .quote-author-wrapper {\r\n            margin-top: 10px;\r\n            margin-left: 42px;\r\n        }\r\n    }\r\n<\/style>\r\n\r\n<div id=\"custom-quote\">\r\n    <div class=\"quote-body\">\r\n        <img decoding=\"async\" src=\"https:\/\/www.hashmicro.com\/my\/blog\/wp-content\/uploads\/2025\/12\/quote.webp\" alt=\"Quote Icon\" class=\"quote-icon\">\r\n        <div>\r\n            Invoice clearance isn\u2019t about speed, it\u2019s about proof. When your PO sets clear terms, your GRN confirms what arrived, and your invoice matches both line by line, approvals move fast and disputes shrink.        <\/div>\r\n    <\/div>\r\n    <p class=\"quote-author-wrapper\">\r\n        <em>Angela Tan, Regional Manager<\/em>\r\n    <\/p>\r\n<\/div>\n<h2><b>A Real Numbers Example You Can Copy Into Training<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">Imagine this scenario:<\/span><\/p>\n<p><b>Your business issues Purchase Order 4421 to a stationery supplier for:<\/b><\/p>\n<ol>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">100 units of A4 paper reams at RM 12.00 each equals RM 1,200.00<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">50 units of ballpoint pen boxes at RM 8.00 each equals RM 400.00<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><span style=\"font-weight: 400;\"> PO total equals RM 1,600.00<\/span><\/li>\n<\/ol>\n<p><b>Your warehouse receives the delivery and records GRN 8801:<\/b><\/p>\n<ol>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">A4 paper reams received: 95 units because 5 units are missing<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Ballpoint pen boxes received: 50 units<\/span><\/li>\n<\/ol>\n<p><b>Your supplier sends Invoice INV 20260601:<\/b><\/p>\n<ol>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">100 units of A4 paper reams at RM 12.00 equals RM 1,200.00<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">50 units of ballpoint pen boxes at RM 8.00 equals RM 400.00<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><span style=\"font-weight: 400;\"> Invoice total equals RM 1,600.00<\/span><\/li>\n<\/ol>\n<p><span style=\"font-weight: 400;\">When you run the three document check, you spot the issue immediately. The supplier bill claims 100 reams, but your GRN shows 95 received. Your payable amount should be RM 1,540.00, calculated as 95 times RM 12 plus 50 times RM 8. You hold the <a href=\"https:\/\/www.hashmicro.com\/my\/blog\/debit-note\/\">invoice and ask the supplier for a credit note<\/a> of RM 60.00 or delivery of the missing 5 reams before you release payment.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Without this verification, you would have paid RM 60.00 for goods you did not receive.<\/span><\/p>\n<h2><b>When Matching Fails, Here Is What You Do Next<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">A failed match, often called a matching exception, does not automatically mean fraud. Most exceptions happen because of admin mistakes: partial deliveries billed as complete, pricing changed without a formal PO update, or invoice lines that do not reflect what your receiving team recorded.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Still, treat every exception seriously because it can also signal duplicate invoices, inflated quantities, or billing for items that never arrived.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">When you flag an exception, use a simple resolution path:<\/span><\/p>\n<ol>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Identify the discrepancy type: quantity, price, or line item mismatch.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Find the source document that carries the error: supplier bill, PO, or GRN.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Escalate to the right owner: procurement for pricing, receiving for quantity, supplier for billing.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Resolve and document: corrected invoice, credit note, or PO amendment, plus a recorded reason.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Re check and approve once the documents align.<\/span><\/li>\n<\/ol>\n<p><span style=\"font-weight: 400;\">Track your exception rate. A healthy process often sits around 5 to 15% of invoices. If yours runs higher, the problem usually starts upstream with weak PO discipline, inconsistent receiving practices, or suppliers that invoice inaccurately.<\/span><\/p>\n<h2><b>Why This Control Pays You Back Every Month<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">This control protects your business through four benefits: financial accuracy, fraud prevention, audit readiness, and smoother vendor relationships.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Financial accuracy comes first. If you skip verification, you will overpay over time, even without intentional fraud. Small errors compound, especially when you process high invoice volumes.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Audit readiness matters just as much. Auditors want proof that you control spend approvals and that you verify payment decisions. A documented workflow gives you that proof, including clear evidence of holds and resolutions. In Malaysia, that record becomes even more valuable because structured <a href=\"https:\/\/www.pwc.com\/my\/en\/perspective\/tax\/230620-onboarding-malaysia-to-e-invoicing.html\">e invoicing makes transactions easier to trace<\/a>, so your internal evidence needs to be just as organised when questions come up.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Supplier relationships also improve when your process stays consistent. You catch issues early, you explain holds with documentation, and you resolve disputes before they spiral into bigger payment delays.<\/span><\/p>\n<h2><b>How Matching Helps You Shut Down Common Fraud Plays<\/b><\/h2>\n<p><span style=\"font-weight: 400;\"><a href=\"https:\/\/www.hashmicro.com\/my\/blog\/invoice-fraud\/\">Fraud shows up more often<\/a> than many teams expect, especially when controls feel loose or inconsistent. A three document check helps you block several common patterns.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Fictitious vendor fraud happens when someone creates a fake supplier and submits invoices for goods or services that were never ordered or received. Your process stops that immediately because you cannot verify a bill without a valid PO and GRN.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Duplicate invoice fraud happens when the same invoice gets submitted twice, whether by mistake or with intent. When you link bills to PO and GRN records, you make duplicates easier to catch and harder to approve, especially when your system enforces unique references and keeps a clean approval history.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Inflated invoice fraud happens when a supplier bills higher quantities or higher prices than you agreed. Your process exposes it because you compare quantities to the GRN and prices to the PO.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Internal procurement abuse also becomes harder when your PO approvals follow clear authorisation rules. Even if someone tries to push a questionable order, they still need receiving confirmation before the bill can clear, and that extra step is often what prevents silent leakage.<\/span><\/p>\n<h2><b>Why Manual Matching Starts to Hurt When Volume Grows<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">This process sounds simple on paper. Manual execution is where things fall apart, especially when invoices pile up.<\/span><\/p>\n<p><strong>1. <b>Time Cost Per Invoice When You Do It Manually<\/b><\/strong><\/p>\n<p><span style=\"font-weight: 400;\">Manual checks force your team to pull the PO, locate the GRN, then compare each invoice line item against both. In practice, this can take 10 to 20 minutes per invoice. If you process 200 invoices a month, that becomes 33 to 67 staff hours spent on verification alone.<\/span><\/p>\n<p><strong>2. Error Rate Rises When You Rush<\/strong><\/p>\n<p>When your team races through a backlog, mistakes creep in. You can miss a subtle price difference, match the wrong PO, or overlook a quantity mismatch. High volume repetitive work drains attention fast, and month end pressure makes it worse.<\/p>\n<p><strong>3. Late Payments Become the Default<\/strong><\/p>\n<p>Slow checks lead to late approvals. Late approvals lead to late payments. You lose early payment discounts, risk late payment penalties, and strain supplier trust.<\/p>\n<p><strong>4. Your Team Wastes Time Chasing Documents<br \/>\n<\/strong>Manual checks often turn into document chasing. Procurement holds the PO, receiving holds the GRN, AP holds the invoice. When each document lives in a different place, your team spends too much time messaging, emailing, and waiting.<\/p>\n<p><strong>5. You Lose a Clean Audit Trail<br \/>\n<\/strong>Spreadsheets and email chains do not give you a reliable approval history. You cannot easily prove who verified what, when they did it, what they found, and why they approved or held a bill. That gap creates audit risk, especially if you need to explain old payments months later. If you operate in Malaysia and deal with structured submissions, that gap becomes more visible because external records look clean while your internal story looks fragmented.<\/p>\n<h2><b>Best Practices That Make Matching Smooth Instead of Painful<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">Whether you run checks manually or with software, these practices help you cut exceptions, speed up approvals, and reduce overpayment risk.<\/span><\/p>\n<ol>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Standardise PO creation and require a PO before purchasing. The biggest reason matching fails is buying outside the PO process. A clear policy reduces chaos immediately.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Train receiving staff to record accurate GRNs. Your GRN drives quantity verification. If receiving records look sloppy, your AP work becomes guesswork.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Define and document tolerance thresholds. Decide what variance you accept, such as 1 to 2% on value or a flat RM amount per line, then apply it consistently.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Centralise document storage and link records by PO number. When you store PO, GRN, and invoice in one system, you eliminate document chasing and speed up approvals.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Set a clear exception workflow with owners and deadlines. Every exception needs an owner, a target resolution time, and a recorded outcome so bills do not sit on hold forever.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Review exception patterns monthly. If one supplier triggers repeat mismatches, address it directly. If one category or team creates constant errors, fix the upstream process.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Consider automation once volume climbs. Automated checks apply your rules instantly, route exceptions to the right owner, and preserve a clean audit trail without extra admin load.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Align your control with Malaysia e invoice obligations. As structured invoice formats become more common through MyInvois and other LHDN IRBM linked flows, your PO and GRN data needs to stay structured too. Treat the shift as a chance to tighten your end to end verification, not just a compliance task.<\/span><\/li>\n<\/ol>\n<h2 id=\"conclusion\"><strong>Conclusion<\/strong><\/h2>\n<p data-start=\"0\" data-end=\"367\">Three way matching helps you keep vendor payments clean because it forces one simple reality check before money leaves your account. When your PO, GRN, and supplier invoice line up, you can approve payment with confidence. When they do not, you catch problems early, avoid overpaying, and reduce the kind of disputes that drain time and damage supplier relationships.<\/p>\n<p data-start=\"369\" data-end=\"774\" data-is-last-node=\"\" data-is-only-node=\"\">As your invoice volume grows, this control becomes even more valuable. It keeps approvals consistent, protects your audit trail, and prevents manual chaos from turning into late payments and repeated exceptions. In Malaysia, structured e invoicing also raises the bar for traceability, so clean PO and GRN records make reconciliation smoother and help you stay organised when reviews or questions come up.<\/p>\n<h2><strong>Frequently Asked Questions About Three Way Matching<\/strong><\/h2>\n<ul class=\"bottom_faq\">\n<li>\n<details>\n<summary><strong>What is three way matching, and why do you need it before paying a supplier invoice?<\/strong><\/summary>\n<p>Three way matching is a payment control that checks one transaction across three documents: the Purchase Order, the Goods Receipt Note, and the supplier invoice. You use it to confirm you ordered the items, you actually received them, and the supplier billed you correctly, before money leaves your account.<\/p>\n<\/details>\n<\/li>\n<li>\n<details>\n<summary><strong>What do you check first when an invoice arrives in your AP queue?<\/strong><\/summary>\n<p>Start by confirming the invoice ties back to a valid PO, then verify billed quantities against the GRN and billed prices against the PO. If anything does not align, hold the invoice and resolve the mismatch before you approve payment.<\/p>\n<\/details>\n<\/li>\n<li>\n<details>\n<summary><strong>Why do invoices get stuck during three way matching?<\/strong><\/summary>\n<p>Most delays happen when the GRN is posted late, the PO details are incomplete, or the supplier invoices a partial delivery as if it was complete. Any of these creates an exception that needs follow up before you can clear the invoice.<\/p>\n<\/details>\n<\/li>\n<li>\n<details>\n<summary><strong>How can you reduce three way matching exceptions without losing control?<\/strong><\/summary>\n<p>Keep PO creation disciplined, train receiving teams to record GRNs accurately and on time, define tolerance thresholds that your team applies consistently, and store PO, GRN, and invoices in one system so your team stops chasing documents across departments.<\/p>\n<\/details>\n<\/li>\n<\/ul>\n<p><script type=\"application\/ld+json\">\n{\n  \"@context\": \"https:\/\/schema.org\",\n  \"@type\": \"FAQPage\",\n  \"mainEntity\": [{\n    \"@type\": \"Question\",\n    \"name\": \"What is three way matching, and why do you need it before paying a supplier invoice?\",\n    \"acceptedAnswer\": {\n      \"@type\": \"Answer\",\n      \"text\": \"Three way matching is a payment control that checks one transaction across three documents: the Purchase Order, the Goods Receipt Note, and the supplier invoice. You use it to confirm you ordered the items, you actually received them, and the supplier billed you correctly, before money leaves your account.\"\n    }\n  },{\n    \"@type\": \"Question\",\n    \"name\": \"What do you check first when an invoice arrives in your AP queue?\",\n    \"acceptedAnswer\": {\n      \"@type\": \"Answer\",\n      \"text\": \"Start by confirming the invoice ties back to a valid PO, then verify billed quantities against the GRN and billed prices against the PO. If anything does not align, hold the invoice and resolve the mismatch before you approve payment.\"\n    }\n  },{\n    \"@type\": \"Question\",\n    \"name\": \"Why do invoices get stuck during three way matching?\",\n    \"acceptedAnswer\": {\n      \"@type\": \"Answer\",\n      \"text\": \"Most delays happen when the GRN is posted late, the PO details are incomplete, or the supplier invoices a partial delivery as if it was complete. Any of these creates an exception that needs follow up before you can clear the invoice.\"\n    }\n  },{\n    \"@type\": \"Question\",\n    \"name\": \"How can you reduce three way matching exceptions without losing control?\",\n    \"acceptedAnswer\": {\n      \"@type\": \"Answer\",\n      \"text\": \"Keep PO creation disciplined, train receiving teams to record GRNs accurately and on time, define tolerance thresholds that your team applies consistently, and store PO, GRN, and invoices in one system so your team stops chasing documents across departments.\"\n    }\n  }]\n}\n<\/script><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Every accounts payable team hits the same pressure point sooner or later. You place an order, the goods arrive, then an invoice shows up and you have to decide fast whether it is safe to pay. If you skip a proper check, you risk paying for items that never landed, accepting a price that was [&hellip;]<\/p>\n","protected":false},"author":39,"featured_media":16806,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[221],"tags":[],"class_list":{"0":"post-16758","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-invoicing"},"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.6 (Yoast SEO v26.6) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>3-Way Matching in Accounts Payable: Process, Steps, and Benefits<\/title>\n<meta name=\"description\" content=\"Verify PO, GRN, and invoices with 3-way matching. Learn the steps, reduce exceptions, and avoid overpayments.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.hashmicro.com\/my\/blog\/3-way-matching-invoice\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"3-Way Matching: What It Is, How It Works, and Why AP Teams Depend on It\" \/>\n<meta property=\"og:description\" content=\"Verify PO, GRN, and invoices with 3-way matching. Learn the steps, reduce exceptions, and avoid overpayments.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.hashmicro.com\/my\/blog\/3-way-matching-invoice\/\" \/>\n<meta property=\"og:site_name\" content=\"HashMicro Malaysia\" \/>\n<meta property=\"article:published_time\" content=\"2026-02-27T04:13:28+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-03-10T08:53:45+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.hashmicro.com\/my\/blog\/wp-content\/uploads\/2026\/02\/3-way-matching-invoice.webp\" \/>\n\t<meta property=\"og:image:width\" content=\"800\" \/>\n\t<meta property=\"og:image:height\" content=\"450\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/webp\" \/>\n<meta name=\"author\" content=\"Siti binti Rahman\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Siti binti Rahman\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"13 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.hashmicro.com\/my\/blog\/3-way-matching-invoice\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.hashmicro.com\/my\/blog\/3-way-matching-invoice\/\"},\"author\":{\"name\":\"Siti binti Rahman\",\"@id\":\"https:\/\/www.hashmicro.com\/my\/blog\/#\/schema\/person\/e4dba2ae170a31d8f85bf173ebfbf7a5\"},\"headline\":\"3-Way Matching: What It Is, How It Works, and Why AP Teams Depend on It\",\"datePublished\":\"2026-02-27T04:13:28+00:00\",\"dateModified\":\"2026-03-10T08:53:45+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.hashmicro.com\/my\/blog\/3-way-matching-invoice\/\"},\"wordCount\":2703,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.hashmicro.com\/my\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.hashmicro.com\/my\/blog\/3-way-matching-invoice\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.hashmicro.com\/my\/blog\/wp-content\/uploads\/2026\/02\/3-way-matching-invoice.webp\",\"articleSection\":[\"Invoicing\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.hashmicro.com\/my\/blog\/3-way-matching-invoice\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.hashmicro.com\/my\/blog\/3-way-matching-invoice\/\",\"url\":\"https:\/\/www.hashmicro.com\/my\/blog\/3-way-matching-invoice\/\",\"name\":\"3-Way Matching in Accounts Payable: Process, Steps, and Benefits\",\"isPartOf\":{\"@id\":\"https:\/\/www.hashmicro.com\/my\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.hashmicro.com\/my\/blog\/3-way-matching-invoice\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.hashmicro.com\/my\/blog\/3-way-matching-invoice\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.hashmicro.com\/my\/blog\/wp-content\/uploads\/2026\/02\/3-way-matching-invoice.webp\",\"datePublished\":\"2026-02-27T04:13:28+00:00\",\"dateModified\":\"2026-03-10T08:53:45+00:00\",\"description\":\"Verify PO, GRN, and invoices with 3-way matching. Learn the steps, reduce exceptions, and avoid overpayments.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.hashmicro.com\/my\/blog\/3-way-matching-invoice\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.hashmicro.com\/my\/blog\/3-way-matching-invoice\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.hashmicro.com\/my\/blog\/3-way-matching-invoice\/#primaryimage\",\"url\":\"https:\/\/www.hashmicro.com\/my\/blog\/wp-content\/uploads\/2026\/02\/3-way-matching-invoice.webp\",\"contentUrl\":\"https:\/\/www.hashmicro.com\/my\/blog\/wp-content\/uploads\/2026\/02\/3-way-matching-invoice.webp\",\"width\":800,\"height\":450,\"caption\":\"3 way matching invoice\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.hashmicro.com\/my\/blog\/3-way-matching-invoice\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.hashmicro.com\/my\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"3-Way Matching: What It Is, How It Works, and Why AP Teams Depend on It\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.hashmicro.com\/my\/blog\/#website\",\"url\":\"https:\/\/www.hashmicro.com\/my\/blog\/\",\"name\":\"HashMicro Malaysia\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/www.hashmicro.com\/my\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.hashmicro.com\/my\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.hashmicro.com\/my\/blog\/#organization\",\"name\":\"HashMicro Malaysia\",\"url\":\"https:\/\/www.hashmicro.com\/my\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.hashmicro.com\/my\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.hashmicro.com\/my\/blog\/wp-content\/uploads\/2025\/09\/logo.webp\",\"contentUrl\":\"https:\/\/www.hashmicro.com\/my\/blog\/wp-content\/uploads\/2025\/09\/logo.webp\",\"width\":422,\"height\":255,\"caption\":\"HashMicro Malaysia\"},\"image\":{\"@id\":\"https:\/\/www.hashmicro.com\/my\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.hashmicro.com\/my\/blog\/#\/schema\/person\/e4dba2ae170a31d8f85bf173ebfbf7a5\",\"name\":\"Siti binti Rahman\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.hashmicro.com\/my\/blog\/#\/schema\/person\/image\/\",\"url\":\"http:\/\/www.hashmicro.com\/my\/blog\/wp-content\/uploads\/2025\/10\/cropped-Siti-binti-Rahman-MY-1080x1080-BG-cafe-96x96.webp\",\"contentUrl\":\"http:\/\/www.hashmicro.com\/my\/blog\/wp-content\/uploads\/2025\/10\/cropped-Siti-binti-Rahman-MY-1080x1080-BG-cafe-96x96.webp\",\"caption\":\"Siti binti Rahman\"},\"description\":\"Siti binti Rahman specializes in accounting-related topics, crafting articles that simplify complex financial concepts for business owners and finance professionals. Her content includes practical guides on accounting automation, compliance, and financial reporting. Through well-researched and accessible writing, she supports readers in improving their financial management strategies.\",\"url\":\"https:\/\/www.hashmicro.com\/my\/blog\/author\/siti-binti-rahman\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"3-Way Matching in Accounts Payable: Process, Steps, and Benefits","description":"Verify PO, GRN, and invoices with 3-way matching. Learn the steps, reduce exceptions, and avoid overpayments.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.hashmicro.com\/my\/blog\/3-way-matching-invoice\/","og_locale":"en_US","og_type":"article","og_title":"3-Way Matching: What It Is, How It Works, and Why AP Teams Depend on It","og_description":"Verify PO, GRN, and invoices with 3-way matching. Learn the steps, reduce exceptions, and avoid overpayments.","og_url":"https:\/\/www.hashmicro.com\/my\/blog\/3-way-matching-invoice\/","og_site_name":"HashMicro Malaysia","article_published_time":"2026-02-27T04:13:28+00:00","article_modified_time":"2026-03-10T08:53:45+00:00","og_image":[{"width":800,"height":450,"url":"https:\/\/www.hashmicro.com\/my\/blog\/wp-content\/uploads\/2026\/02\/3-way-matching-invoice.webp","type":"image\/webp"}],"author":"Siti binti Rahman","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Siti binti Rahman","Est. reading time":"13 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.hashmicro.com\/my\/blog\/3-way-matching-invoice\/#article","isPartOf":{"@id":"https:\/\/www.hashmicro.com\/my\/blog\/3-way-matching-invoice\/"},"author":{"name":"Siti binti Rahman","@id":"https:\/\/www.hashmicro.com\/my\/blog\/#\/schema\/person\/e4dba2ae170a31d8f85bf173ebfbf7a5"},"headline":"3-Way Matching: What It Is, How It Works, and Why AP Teams Depend on It","datePublished":"2026-02-27T04:13:28+00:00","dateModified":"2026-03-10T08:53:45+00:00","mainEntityOfPage":{"@id":"https:\/\/www.hashmicro.com\/my\/blog\/3-way-matching-invoice\/"},"wordCount":2703,"commentCount":0,"publisher":{"@id":"https:\/\/www.hashmicro.com\/my\/blog\/#organization"},"image":{"@id":"https:\/\/www.hashmicro.com\/my\/blog\/3-way-matching-invoice\/#primaryimage"},"thumbnailUrl":"https:\/\/www.hashmicro.com\/my\/blog\/wp-content\/uploads\/2026\/02\/3-way-matching-invoice.webp","articleSection":["Invoicing"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.hashmicro.com\/my\/blog\/3-way-matching-invoice\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.hashmicro.com\/my\/blog\/3-way-matching-invoice\/","url":"https:\/\/www.hashmicro.com\/my\/blog\/3-way-matching-invoice\/","name":"3-Way Matching in Accounts Payable: Process, Steps, and Benefits","isPartOf":{"@id":"https:\/\/www.hashmicro.com\/my\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.hashmicro.com\/my\/blog\/3-way-matching-invoice\/#primaryimage"},"image":{"@id":"https:\/\/www.hashmicro.com\/my\/blog\/3-way-matching-invoice\/#primaryimage"},"thumbnailUrl":"https:\/\/www.hashmicro.com\/my\/blog\/wp-content\/uploads\/2026\/02\/3-way-matching-invoice.webp","datePublished":"2026-02-27T04:13:28+00:00","dateModified":"2026-03-10T08:53:45+00:00","description":"Verify PO, GRN, and invoices with 3-way matching. Learn the steps, reduce exceptions, and avoid overpayments.","breadcrumb":{"@id":"https:\/\/www.hashmicro.com\/my\/blog\/3-way-matching-invoice\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.hashmicro.com\/my\/blog\/3-way-matching-invoice\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.hashmicro.com\/my\/blog\/3-way-matching-invoice\/#primaryimage","url":"https:\/\/www.hashmicro.com\/my\/blog\/wp-content\/uploads\/2026\/02\/3-way-matching-invoice.webp","contentUrl":"https:\/\/www.hashmicro.com\/my\/blog\/wp-content\/uploads\/2026\/02\/3-way-matching-invoice.webp","width":800,"height":450,"caption":"3 way matching invoice"},{"@type":"BreadcrumbList","@id":"https:\/\/www.hashmicro.com\/my\/blog\/3-way-matching-invoice\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.hashmicro.com\/my\/blog\/"},{"@type":"ListItem","position":2,"name":"3-Way Matching: What It Is, How It Works, and Why AP Teams Depend on It"}]},{"@type":"WebSite","@id":"https:\/\/www.hashmicro.com\/my\/blog\/#website","url":"https:\/\/www.hashmicro.com\/my\/blog\/","name":"HashMicro Malaysia","description":"","publisher":{"@id":"https:\/\/www.hashmicro.com\/my\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.hashmicro.com\/my\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.hashmicro.com\/my\/blog\/#organization","name":"HashMicro Malaysia","url":"https:\/\/www.hashmicro.com\/my\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.hashmicro.com\/my\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.hashmicro.com\/my\/blog\/wp-content\/uploads\/2025\/09\/logo.webp","contentUrl":"https:\/\/www.hashmicro.com\/my\/blog\/wp-content\/uploads\/2025\/09\/logo.webp","width":422,"height":255,"caption":"HashMicro Malaysia"},"image":{"@id":"https:\/\/www.hashmicro.com\/my\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.hashmicro.com\/my\/blog\/#\/schema\/person\/e4dba2ae170a31d8f85bf173ebfbf7a5","name":"Siti binti Rahman","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.hashmicro.com\/my\/blog\/#\/schema\/person\/image\/","url":"http:\/\/www.hashmicro.com\/my\/blog\/wp-content\/uploads\/2025\/10\/cropped-Siti-binti-Rahman-MY-1080x1080-BG-cafe-96x96.webp","contentUrl":"http:\/\/www.hashmicro.com\/my\/blog\/wp-content\/uploads\/2025\/10\/cropped-Siti-binti-Rahman-MY-1080x1080-BG-cafe-96x96.webp","caption":"Siti binti Rahman"},"description":"Siti binti Rahman specializes in accounting-related topics, crafting articles that simplify complex financial concepts for business owners and finance professionals. Her content includes practical guides on accounting automation, compliance, and financial reporting. Through well-researched and accessible writing, she supports readers in improving their financial management strategies.","url":"https:\/\/www.hashmicro.com\/my\/blog\/author\/siti-binti-rahman\/"}]}},"order_j":"","_links":{"self":[{"href":"https:\/\/www.hashmicro.com\/my\/blog\/wp-json\/wp\/v2\/posts\/16758","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.hashmicro.com\/my\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.hashmicro.com\/my\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.hashmicro.com\/my\/blog\/wp-json\/wp\/v2\/users\/39"}],"replies":[{"embeddable":true,"href":"https:\/\/www.hashmicro.com\/my\/blog\/wp-json\/wp\/v2\/comments?post=16758"}],"version-history":[{"count":10,"href":"https:\/\/www.hashmicro.com\/my\/blog\/wp-json\/wp\/v2\/posts\/16758\/revisions"}],"predecessor-version":[{"id":17487,"href":"https:\/\/www.hashmicro.com\/my\/blog\/wp-json\/wp\/v2\/posts\/16758\/revisions\/17487"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.hashmicro.com\/my\/blog\/wp-json\/wp\/v2\/media\/16806"}],"wp:attachment":[{"href":"https:\/\/www.hashmicro.com\/my\/blog\/wp-json\/wp\/v2\/media?parent=16758"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.hashmicro.com\/my\/blog\/wp-json\/wp\/v2\/categories?post=16758"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.hashmicro.com\/my\/blog\/wp-json\/wp\/v2\/tags?post=16758"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}