@ripwords/myinvois-client 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +99 -0
- package/README.md +128 -4
- package/bun.lock +59 -0
- package/dist/{0X-Yw7mZEro.d.cts → 0X-CG1S1WKn.d.ts} +1 -2
- package/dist/{0X-C4IRh_fJ.d.ts → 0X-ChfmeAYF.d.cts} +1 -1
- package/dist/{1X-D_aUVsuM.d.cts → 1X-CmlbG02M.d.ts} +1 -2
- package/dist/{1X-BwpSoT3o.d.cts → 1X-DFikQbP0.d.cts} +1 -1
- package/dist/{1X-C-_KHV-Q.d.ts → 1X-DbFshzup.d.ts} +1 -2
- package/dist/{1X-Brnls9Jh.d.ts → 1X-jFrFCOs0.d.cts} +1 -1
- package/dist/{2X-UdQcQW24.d.ts → 2X-5cE4ojEX.d.cts} +1 -1
- package/dist/{2X-hClUyw26.d.cts → 2X-DA6J6Wd7.d.ts} +1 -2
- package/dist/{2X-Bb6elyzV.d.cts → 2X-FWZ1rYVt.d.cts} +1 -1
- package/dist/{2X-DkS1BoE5.d.ts → 2X-eC_p0QJf.d.ts} +1 -2
- package/dist/{3X-C7VFD-n-.d.cts → 3X-D9duw0Ro.d.cts} +1 -1
- package/dist/{3X-DFI-4RQQ.d.ts → 3X-DbfkwdkO.d.ts} +1 -2
- package/dist/{3X-DVDyspgb.d.ts → 3X-GxuN79Ax.d.ts} +1 -2
- package/dist/{3X-CLMESDvz.d.cts → 3X-r9xbWJ2l.d.cts} +1 -1
- package/dist/{4X-CIJ2JJ2w.d.ts → 4X-1ZkK-uH5.d.cts} +1 -1
- package/dist/{4X-CUR8jlaZ.d.ts → 4X-CLO9OuKa.d.cts} +1 -1
- package/dist/{4X-DIfvpU6V.d.cts → 4X-CnHtgO6u.d.ts} +1 -2
- package/dist/{4X-CvScPJTf.d.cts → 4X-DYz_nYSD.d.ts} +1 -2
- package/dist/{5X-COsZHUaQ.d.ts → 5X-BzPEdkbC.d.ts} +1 -2
- package/dist/{5X-C6db432h.d.ts → 5X-BziH0a09.d.cts} +1 -1
- package/dist/{5X-BOUxhadJ.d.cts → 5X-Cfe39fFc.d.cts} +1 -1
- package/dist/{5X-CkLu7Vyd.d.cts → 5X-kBF74qx1.d.ts} +1 -2
- package/dist/{6X-C_fFIcJC.d.ts → 6X-BceErbps.d.cts} +1 -1
- package/dist/{6X-DE7RJeV6.d.cts → 6X-C_xpeu6J.d.ts} +1 -2
- package/dist/{6X-ClZDKOTC.d.ts → 6X-DLWEe1bP.d.cts} +1 -1
- package/dist/{6X-Mf32k1d0.d.cts → 6X-sQZfT0ZK.d.ts} +1 -2
- package/dist/{7X-Chtd6B66.d.cts → 7X-Bet2agJ6.d.ts} +1 -2
- package/dist/{7X-kot_VccM.d.ts → 7X-BoKQxMoO.d.ts} +1 -2
- package/dist/{7X-BZyesooz.d.ts → 7X-CucHYQsA.d.cts} +1 -1
- package/dist/{7X-DoCUcp-J.d.cts → 7X-CwPAqozm.d.cts} +1 -1
- package/dist/{8X-Df4DOBOe.d.ts → 8X-BIjJ9kaV.d.cts} +1 -1
- package/dist/{8X-Dr9RunRw.d.cts → 8X-BOEWATU3.d.ts} +1 -2
- package/dist/{8X-DkuKAkHz.d.ts → 8X-CJpqd5xp.d.cts} +1 -1
- package/dist/{8X-DqZyMvyV.d.cts → 8X-s5AzkHR-.d.ts} +1 -2
- package/dist/{9X-BDgifncF.d.ts → 9X-BBDP1gZ6.d.ts} +1 -2
- package/dist/{9X-BaoZtjWF.d.cts → 9X-CP5Xp6bE.d.cts} +1 -1
- package/dist/{9X-BcAb6Uso.d.cts → 9X-D3aOVCnz.d.cts} +1 -1
- package/dist/{9X-BhBWlgxG.d.ts → 9X-DAAZV4sr.d.ts} +1 -2
- package/dist/{AX-D6XHWdrY.d.ts → AX-CmpMMhII.d.ts} +1 -2
- package/dist/{AX-BY72FohC.d.cts → AX-DFzpxGOT.d.cts} +1 -1
- package/dist/{BX-D_0C8Qbd.d.ts → BX-CyiqNE6b.d.cts} +1 -1
- package/dist/{BX-CA0OmrUZ.d.cts → BX-j78z_ju_.d.ts} +1 -2
- package/dist/{CX-glpQSL8x.d.cts → CX-B6rEhQx7.d.ts} +1 -2
- package/dist/{CX-HH4cSZRX.d.ts → CX-BTPvC3Dv.d.cts} +1 -1
- package/dist/{DX-DimL1MDM.d.cts → DX-BD4-hTCh.d.cts} +1 -1
- package/dist/{DX-Dx22ax_I.d.ts → DX-CAmMnx5a.d.ts} +1 -2
- package/dist/{EX-BRWh1wFc.d.ts → EX-CXhSC85J.d.ts} +1 -2
- package/dist/{EX-Cx87Ruxl.d.cts → EX-mTHCH0Yk.d.cts} +1 -1
- package/dist/{FX-D81UlxNN.d.cts → FX-DOOMoQl2.d.cts} +1 -1
- package/dist/{FX-RmjwAr40.d.ts → FX-DYVIJ3l0.d.ts} +1 -2
- package/dist/{GX-CJyo7oDp.d.ts → GX-8URJ7WHz.d.cts} +1 -1
- package/dist/{GX-9i7piP9G.d.cts → GX-eBOVHqi6.d.ts} +1 -2
- package/dist/{HX-20GVJAvl.d.cts → HX-49z8CzsE.d.cts} +1 -1
- package/dist/{HX-XALBTdLA.d.ts → HX-Dz5T0xXI.d.ts} +1 -2
- package/dist/{IX-6SZ55QKb.d.ts → IX-B6kblmBs.d.cts} +1 -1
- package/dist/{IX-D54NGPsc.d.cts → IX-PiKYro5a.d.ts} +1 -2
- package/dist/{JX-C1RYcwQX.d.cts → JX-DMwHLGEE.d.cts} +1 -1
- package/dist/{JX-hQ1XRmLp.d.ts → JX-Dvnt0mSK.d.ts} +1 -2
- package/dist/{KX-BNwunEfn.d.ts → KX-BUb8e0yg.d.ts} +1 -2
- package/dist/{KX-gQHCIgtQ.d.cts → KX-DaJPkefl.d.cts} +1 -1
- package/dist/{LX-CHYX3X3J.d.ts → LX-BnILxjdS.d.cts} +1 -1
- package/dist/{LX-CPurJGIh.d.cts → LX-l5ZBaGov.d.ts} +1 -2
- package/dist/{MX-BPGLWSUz.d.ts → MX-BbPO8mTj.d.cts} +1 -1
- package/dist/{MX-BnyW5eHf.d.cts → MX-C7C15AWi.d.ts} +1 -2
- package/dist/{NX-RulN5Ml3.d.ts → NX-C7nFVC-D.d.ts} +1 -2
- package/dist/{NX-B11fQuco.d.cts → NX-xy5uw7H3.d.cts} +1 -1
- package/dist/{OX-DgKVSp7I.d.ts → OX-CIzARbON.d.cts} +1 -1
- package/dist/{OX-T-ydRXQS.d.cts → OX-Dmkvcaij.d.ts} +1 -2
- package/dist/{PX-DA4A2kEv.d.ts → PX-BKZ14N7N.d.ts} +1 -2
- package/dist/{PX-p0n1SzvU.d.cts → PX-CL8waFgx.d.cts} +1 -1
- package/dist/{QX-DrFqsMEs.d.ts → QX-6xdSNtxZ.d.ts} +1 -2
- package/dist/{QX-CI1NccIB.d.cts → QX-BowAYqZb.d.cts} +1 -1
- package/dist/{RX-DnNKol22.d.cts → RX-DFoiOK5q.d.ts} +1 -2
- package/dist/{RX-Cm7vFcFN.d.ts → RX-fWoWcHTG.d.cts} +1 -1
- package/dist/{SX-BUjiWQYz.d.cts → SX-CZ3e31OT.d.cts} +1 -1
- package/dist/{SX-CsPPTu-W.d.ts → SX-D-Szi9wa.d.ts} +1 -2
- package/dist/{TX-DCY25MdR.d.ts → TX-CJhJ-HYX.d.cts} +1 -1
- package/dist/{TX-DOEpsf05.d.cts → TX-DTfkGsqn.d.ts} +1 -2
- package/dist/{UX-DgUOnTFK.d.cts → UX-Bw4HHAj4.d.ts} +1 -2
- package/dist/{UX-DauyagHy.d.ts → UX-P7-u2y70.d.cts} +1 -1
- package/dist/{VX-DD4scgCe.d.ts → VX-C8Eu5gQf.d.cts} +1 -1
- package/dist/{VX-kUX6LM-3.d.cts → VX-DCv5x_hi.d.ts} +1 -2
- package/dist/{WX-DPfyPFFh.d.cts → WX-BYtJ5_if.d.ts} +1 -2
- package/dist/{WX-CjkoppdY.d.ts → WX-DkiaqB2V.d.cts} +1 -1
- package/dist/{XX-sbsIUOnA.d.ts → XX-D4p4iK-a.d.cts} +1 -1
- package/dist/{XX-C4C1gQZH.d.cts → XX-Jo1yJO3A.d.ts} +1 -2
- package/dist/{YX-DUdO8mRC.d.ts → YX-BvGmEsVG.d.ts} +1 -2
- package/dist/{YX-BeT-LsiA.d.cts → YX-Du8zv9qz.d.cts} +1 -1
- package/dist/{ZX-BuVTTq-D.d.cts → ZX-B4jFD-21.d.cts} +1 -1
- package/dist/{ZX-DwfcSA-D.d.ts → ZX-B59AJcBY.d.ts} +1 -2
- package/dist/api/platform/platformLogin.d.ts +58 -60
- package/dist/api/platform/platformLogin.js +1 -1
- package/dist/certificate-DFK-788s.cjs +62 -0
- package/dist/certificate-DFK-788s.cjs.map +1 -0
- package/dist/certificate-aooIRf9A.js +49 -0
- package/dist/{classification-codes-C2X4xW5-.d.ts → classification-codes-BKxV-rO9.d.ts} +1 -2
- package/dist/{country-code-DsI8Mbzx.d.ts → country-code-CQuaiQm2.d.ts} +1 -2
- package/dist/{currencies-DKuDflOO.d.ts → currencies-BYJK-m6v.d.ts} +1 -2
- package/dist/document-DMIMRJV0.cjs +472 -0
- package/dist/document-DMIMRJV0.cjs.map +1 -0
- package/dist/document-NQos5fSr.js +405 -0
- package/dist/documents-BVG7KIKY.d.ts +847 -0
- package/dist/documents-C066EC9m.d.cts +848 -0
- package/dist/{e-invoice-C2TxhyrK.d.ts → e-invoice-CmbLQkHw.d.ts} +1 -2
- package/dist/{getBaseUrl-Dx6RDC8I.js → getBaseUrl-R3IdgCu3.js} +1 -2
- package/dist/{index-B1DSs-wd.d.cts → index-0-EvC6Nv.d.ts} +1 -2
- package/dist/{index-FTgB2nM6.d.ts → index-D2_HVwCz.d.cts} +1 -1
- package/dist/index.cjs +308 -12
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +233 -60
- package/dist/index.js +306 -11
- package/dist/index10.cjs +0 -34
- package/dist/index11.cjs +25 -15
- package/dist/index11.cjs.map +1 -1
- package/dist/index12.cjs +24 -0
- package/dist/index12.cjs.map +1 -0
- package/dist/index13.cjs +0 -13
- package/dist/index15.cjs +3 -2
- package/dist/index16.cjs +12 -16
- package/dist/index17.cjs +2 -2
- package/dist/index18.cjs +336 -204
- package/dist/index18.cjs.map +1 -1
- package/dist/index19.cjs +325 -105
- package/dist/index19.cjs.map +1 -1
- package/dist/index20.cjs +136 -133
- package/dist/index20.cjs.map +1 -1
- package/dist/index21.cjs +2 -63
- package/dist/index22.cjs +203 -262
- package/dist/index22.cjs.map +1 -1
- package/dist/index23.cjs +104 -74
- package/dist/index23.cjs.map +1 -1
- package/dist/index24.cjs +132 -102
- package/dist/index24.cjs.map +1 -1
- package/dist/index25.cjs +59 -68
- package/dist/index25.cjs.map +1 -1
- package/dist/index26.cjs +262 -107
- package/dist/index26.cjs.map +1 -1
- package/dist/index27.cjs +74 -95
- package/dist/index27.cjs.map +1 -1
- package/dist/index28.cjs +102 -13
- package/dist/index28.cjs.map +1 -1
- package/dist/index29.cjs +68 -33
- package/dist/index29.cjs.map +1 -1
- package/dist/index30.cjs +107 -14
- package/dist/index30.cjs.map +1 -1
- package/dist/index31.cjs +95 -24
- package/dist/index31.cjs.map +1 -1
- package/dist/index32.cjs +11 -13
- package/dist/index32.cjs.map +1 -1
- package/dist/index33.cjs +31 -7
- package/dist/index33.cjs.map +1 -1
- package/dist/index34.cjs +12 -7
- package/dist/index34.cjs.map +1 -1
- package/dist/index35.cjs +22 -10
- package/dist/index35.cjs.map +1 -1
- package/dist/index36.cjs +13 -6
- package/dist/index36.cjs.map +1 -1
- package/dist/index37.cjs +7 -101
- package/dist/index37.cjs.map +1 -1
- package/dist/index38.cjs +7 -106
- package/dist/index38.cjs.map +1 -1
- package/dist/index39.cjs +10 -119
- package/dist/index39.cjs.map +1 -1
- package/dist/index40.cjs +6 -106
- package/dist/index40.cjs.map +1 -1
- package/dist/index41.cjs +101 -98
- package/dist/index41.cjs.map +1 -1
- package/dist/index42.cjs +106 -118
- package/dist/index42.cjs.map +1 -1
- package/dist/index43.cjs +119 -127
- package/dist/index43.cjs.map +1 -1
- package/dist/index44.cjs +106 -117
- package/dist/index44.cjs.map +1 -1
- package/dist/index45.cjs +98 -14
- package/dist/index45.cjs.map +1 -1
- package/dist/index46.cjs +118 -95
- package/dist/index46.cjs.map +1 -1
- package/dist/index47.cjs +127 -142
- package/dist/index47.cjs.map +1 -1
- package/dist/index48.cjs +117 -114
- package/dist/index48.cjs.map +1 -1
- package/dist/index49.cjs +14 -144
- package/dist/index49.cjs.map +1 -1
- package/dist/index5.cjs +0 -25
- package/dist/index50.cjs +95 -113
- package/dist/index50.cjs.map +1 -1
- package/dist/index51.cjs +142 -17
- package/dist/index51.cjs.map +1 -1
- package/dist/index52.cjs +114 -112
- package/dist/index52.cjs.map +1 -1
- package/dist/index53.cjs +144 -47
- package/dist/index53.cjs.map +1 -1
- package/dist/index54.cjs +113 -14
- package/dist/index54.cjs.map +1 -1
- package/dist/index55.cjs +17 -28
- package/dist/index55.cjs.map +1 -1
- package/dist/index56.cjs +112 -22
- package/dist/index56.cjs.map +1 -1
- package/dist/index57.cjs +47 -9
- package/dist/index57.cjs.map +1 -1
- package/dist/index58.cjs +14 -8
- package/dist/index58.cjs.map +1 -1
- package/dist/index58.cts.map +1 -0
- package/dist/index59.cjs +28 -17
- package/dist/index59.cjs.map +1 -1
- package/dist/index59.cts.map +1 -1
- package/dist/index6.cjs +25 -0
- package/dist/{index5.cjs.map → index6.cjs.map} +1 -1
- package/dist/index60.cjs +22 -412
- package/dist/index60.cjs.map +1 -1
- package/dist/index60.cts.map +1 -0
- package/dist/index61.cjs +9 -8
- package/dist/index61.cjs.map +1 -1
- package/dist/index61.cts.map +1 -0
- package/dist/index62.cjs +8 -9
- package/dist/index62.cjs.map +1 -1
- package/dist/index62.cts.map +1 -1
- package/dist/index63.cjs +24 -0
- package/dist/index63.cjs.map +1 -0
- package/dist/index63.cts.map +1 -1
- package/dist/index64.cjs +419 -0
- package/dist/index64.cjs.map +1 -0
- package/dist/index64.cts.map +1 -1
- package/dist/index65.cjs +9 -116
- package/dist/index65.cjs.map +1 -1
- package/dist/index65.cts.map +1 -1
- package/dist/index66.cjs +10 -223
- package/dist/index66.cjs.map +1 -1
- package/dist/index66.cts.map +1 -1
- package/dist/index8.cjs +0 -25
- package/dist/index9.cjs +25 -0
- package/dist/{index8.cjs.map → index9.cjs.map} +1 -1
- package/dist/{msic-codes-B_1W6lZF.d.cts → msic-codes-CPWVNnpq.d.cts} +11 -11
- package/dist/msic-codes-DToUqTI6.d.ts +25 -0
- package/dist/{payment-modes-DHihrywe.d.cts → payment-modes-DA7uBIGb.d.ts} +1 -2
- package/dist/{payment-modes-B8dNy3SM.d.ts → payment-modes-FX88uyhP.d.cts} +1 -1
- package/dist/platformLogin-PGzMhw1X.cjs.map +1 -1
- package/dist/{platformLogin-DsxWWUXr.js → platformLogin-f0bNAoZI.js} +1 -2
- package/dist/{signatures-C9QPZTQd.d.ts → signatures-CG175mpg.d.ts} +1 -2
- package/dist/{state-codes-DXSWtE6a.d.cts → state-codes-CNp_6051.d.cts} +1 -1
- package/dist/{state-codes-CxG1S9YY.d.ts → state-codes-dvoTe5pC.d.ts} +1 -2
- package/dist/{tax-types-CEpfSh5P.d.ts → tax-types-tosH5I0q.d.ts} +1 -2
- package/dist/types/classification-codes.d.ts +1 -1
- package/dist/types/country-code.d.ts +1 -1
- package/dist/types/currencies.d.ts +1 -1
- package/dist/types/documents.d.ts +7 -0
- package/dist/types/e-invoice.d.ts +1 -1
- package/dist/types/index.d.ts +58 -59
- package/dist/types/msic/0X.d.ts +1 -1
- package/dist/types/msic/1X.d.ts +1 -1
- package/dist/types/msic/2X.d.ts +1 -1
- package/dist/types/msic/3X.d.ts +1 -1
- package/dist/types/msic/4X.d.ts +1 -1
- package/dist/types/msic/5X.d.ts +1 -1
- package/dist/types/msic/6X.d.ts +1 -1
- package/dist/types/msic/7X.d.ts +1 -1
- package/dist/types/msic/8X.d.ts +1 -1
- package/dist/types/msic/9X.d.ts +1 -1
- package/dist/types/msic-codes.d.ts +11 -11
- package/dist/types/payment-modes.d.ts +1 -1
- package/dist/types/signatures.d.ts +1 -1
- package/dist/types/state-codes.d.ts +1 -1
- package/dist/types/tax-types.d.ts +1 -1
- package/dist/types/unit/1X.d.ts +1 -1
- package/dist/types/unit/2X.d.ts +1 -1
- package/dist/types/unit/3X.d.ts +1 -1
- package/dist/types/unit/4X.d.ts +1 -1
- package/dist/types/unit/5X.d.ts +1 -1
- package/dist/types/unit/6X.d.ts +1 -1
- package/dist/types/unit/7X.d.ts +1 -1
- package/dist/types/unit/8X.d.ts +1 -1
- package/dist/types/unit/9X.d.ts +1 -1
- package/dist/types/unit/AX.d.ts +1 -1
- package/dist/types/unit/BX.d.ts +1 -1
- package/dist/types/unit/CX.d.ts +1 -1
- package/dist/types/unit/DX.d.ts +1 -1
- package/dist/types/unit/EX.d.ts +1 -1
- package/dist/types/unit/FX.d.ts +1 -1
- package/dist/types/unit/GX.d.ts +1 -1
- package/dist/types/unit/HX.d.ts +1 -1
- package/dist/types/unit/IX.d.ts +1 -1
- package/dist/types/unit/JX.d.ts +1 -1
- package/dist/types/unit/KX.d.ts +1 -1
- package/dist/types/unit/LX.d.ts +1 -1
- package/dist/types/unit/MX.d.ts +1 -1
- package/dist/types/unit/NX.d.ts +1 -1
- package/dist/types/unit/OX.d.ts +1 -1
- package/dist/types/unit/PX.d.ts +1 -1
- package/dist/types/unit/QX.d.ts +1 -1
- package/dist/types/unit/RX.d.ts +1 -1
- package/dist/types/unit/SX.d.ts +1 -1
- package/dist/types/unit/TX.d.ts +1 -1
- package/dist/types/unit/UX.d.ts +1 -1
- package/dist/types/unit/VX.d.ts +1 -1
- package/dist/types/unit/WX.d.ts +1 -1
- package/dist/types/unit/XX.d.ts +1 -1
- package/dist/types/unit/YX.d.ts +1 -1
- package/dist/types/unit/ZX.d.ts +1 -1
- package/dist/types/unit-types.d.ts +36 -36
- package/dist/unit-types-BKZxwVYQ.d.ts +55 -0
- package/dist/unit-types-CaOA5ZDG.d.cts +56 -0
- package/dist/utils/base64.d.ts +1 -2
- package/dist/utils/base64.js +1 -2
- package/dist/utils/certificate.d.ts +22 -0
- package/dist/utils/certificate.js +3 -0
- package/dist/utils/document.d.ts +135 -0
- package/dist/utils/document.js +3 -0
- package/dist/utils/getBaseUrl.d.ts +1 -2
- package/dist/utils/getBaseUrl.js +1 -1
- package/dist/utils/helpers.d.ts +271 -0
- package/dist/utils/helpers.js +330 -0
- package/dist/utils/signature-diagnostics.d.ts +93 -0
- package/dist/utils/signature-diagnostics.js +326 -0
- package/dist/utils/validation.d.ts +46 -0
- package/dist/utils/validation.js +134 -0
- package/myinvois-cert.conf.template +23 -0
- package/package.json +9 -3
- package/scripts/gen-cert.sh +159 -0
- package/src/api/platform/platformLogin.ts +1 -1
- package/src/index.ts +528 -1
- package/src/types/documents.d.ts +862 -0
- package/src/types/index.d.ts +1 -1
- package/src/utils/certificate.ts +60 -0
- package/src/utils/document.ts +852 -0
- package/src/utils/helpers.ts +552 -0
- package/src/utils/signature-diagnostics.ts +583 -0
- package/src/utils/validation.ts +268 -0
- package/test/MyInvoiClientWithRealData.test.ts +9 -1
- package/test/MyInvoisClient.test.ts +7 -1
- package/test/dynamicInvoiceFeatures.test.ts +449 -0
- package/test/signAndSubmitInvoice.test.ts +269 -734
- package/test/signature-diagnostics.test.ts +128 -0
- package/tsconfig.json +0 -3
- package/dist/0X-C4IRh_fJ.d.ts.map +0 -1
- package/dist/0X-Yw7mZEro.d.cts.map +0 -1
- package/dist/1X-Brnls9Jh.d.ts.map +0 -1
- package/dist/1X-BwpSoT3o.d.cts.map +0 -1
- package/dist/1X-C-_KHV-Q.d.ts.map +0 -1
- package/dist/1X-D_aUVsuM.d.cts.map +0 -1
- package/dist/2X-Bb6elyzV.d.cts.map +0 -1
- package/dist/2X-DkS1BoE5.d.ts.map +0 -1
- package/dist/2X-UdQcQW24.d.ts.map +0 -1
- package/dist/2X-hClUyw26.d.cts.map +0 -1
- package/dist/3X-C7VFD-n-.d.cts.map +0 -1
- package/dist/3X-CLMESDvz.d.cts.map +0 -1
- package/dist/3X-DFI-4RQQ.d.ts.map +0 -1
- package/dist/3X-DVDyspgb.d.ts.map +0 -1
- package/dist/4X-CIJ2JJ2w.d.ts.map +0 -1
- package/dist/4X-CUR8jlaZ.d.ts.map +0 -1
- package/dist/4X-CvScPJTf.d.cts.map +0 -1
- package/dist/4X-DIfvpU6V.d.cts.map +0 -1
- package/dist/5X-BOUxhadJ.d.cts.map +0 -1
- package/dist/5X-C6db432h.d.ts.map +0 -1
- package/dist/5X-COsZHUaQ.d.ts.map +0 -1
- package/dist/5X-CkLu7Vyd.d.cts.map +0 -1
- package/dist/6X-C_fFIcJC.d.ts.map +0 -1
- package/dist/6X-ClZDKOTC.d.ts.map +0 -1
- package/dist/6X-DE7RJeV6.d.cts.map +0 -1
- package/dist/6X-Mf32k1d0.d.cts.map +0 -1
- package/dist/7X-BZyesooz.d.ts.map +0 -1
- package/dist/7X-Chtd6B66.d.cts.map +0 -1
- package/dist/7X-DoCUcp-J.d.cts.map +0 -1
- package/dist/7X-kot_VccM.d.ts.map +0 -1
- package/dist/8X-Df4DOBOe.d.ts.map +0 -1
- package/dist/8X-DkuKAkHz.d.ts.map +0 -1
- package/dist/8X-DqZyMvyV.d.cts.map +0 -1
- package/dist/8X-Dr9RunRw.d.cts.map +0 -1
- package/dist/9X-BDgifncF.d.ts.map +0 -1
- package/dist/9X-BaoZtjWF.d.cts.map +0 -1
- package/dist/9X-BcAb6Uso.d.cts.map +0 -1
- package/dist/9X-BhBWlgxG.d.ts.map +0 -1
- package/dist/AX-BY72FohC.d.cts.map +0 -1
- package/dist/AX-D6XHWdrY.d.ts.map +0 -1
- package/dist/BX-CA0OmrUZ.d.cts.map +0 -1
- package/dist/BX-D_0C8Qbd.d.ts.map +0 -1
- package/dist/CX-HH4cSZRX.d.ts.map +0 -1
- package/dist/CX-glpQSL8x.d.cts.map +0 -1
- package/dist/DX-DimL1MDM.d.cts.map +0 -1
- package/dist/DX-Dx22ax_I.d.ts.map +0 -1
- package/dist/EX-BRWh1wFc.d.ts.map +0 -1
- package/dist/EX-Cx87Ruxl.d.cts.map +0 -1
- package/dist/FX-D81UlxNN.d.cts.map +0 -1
- package/dist/FX-RmjwAr40.d.ts.map +0 -1
- package/dist/GX-9i7piP9G.d.cts.map +0 -1
- package/dist/GX-CJyo7oDp.d.ts.map +0 -1
- package/dist/HX-20GVJAvl.d.cts.map +0 -1
- package/dist/HX-XALBTdLA.d.ts.map +0 -1
- package/dist/IX-6SZ55QKb.d.ts.map +0 -1
- package/dist/IX-D54NGPsc.d.cts.map +0 -1
- package/dist/JX-C1RYcwQX.d.cts.map +0 -1
- package/dist/JX-hQ1XRmLp.d.ts.map +0 -1
- package/dist/KX-BNwunEfn.d.ts.map +0 -1
- package/dist/KX-gQHCIgtQ.d.cts.map +0 -1
- package/dist/LX-CHYX3X3J.d.ts.map +0 -1
- package/dist/LX-CPurJGIh.d.cts.map +0 -1
- package/dist/MX-BPGLWSUz.d.ts.map +0 -1
- package/dist/MX-BnyW5eHf.d.cts.map +0 -1
- package/dist/MyInvoisClient-BrNyMjS-.d.cts +0 -178
- package/dist/MyInvoisClient-BrNyMjS-.d.cts.map +0 -1
- package/dist/MyInvoisClient-CXu4pdl-.d.ts +0 -178
- package/dist/MyInvoisClient-CXu4pdl-.d.ts.map +0 -1
- package/dist/MyInvoisClient-Cnvb5iUC.js +0 -299
- package/dist/MyInvoisClient-Cnvb5iUC.js.map +0 -1
- package/dist/MyInvoisClient-DO1dJfQq.cjs +0 -304
- package/dist/MyInvoisClient-DO1dJfQq.cjs.map +0 -1
- package/dist/NX-B11fQuco.d.cts.map +0 -1
- package/dist/NX-RulN5Ml3.d.ts.map +0 -1
- package/dist/OX-DgKVSp7I.d.ts.map +0 -1
- package/dist/OX-T-ydRXQS.d.cts.map +0 -1
- package/dist/PX-DA4A2kEv.d.ts.map +0 -1
- package/dist/PX-p0n1SzvU.d.cts.map +0 -1
- package/dist/QX-CI1NccIB.d.cts.map +0 -1
- package/dist/QX-DrFqsMEs.d.ts.map +0 -1
- package/dist/RX-Cm7vFcFN.d.ts.map +0 -1
- package/dist/RX-DnNKol22.d.cts.map +0 -1
- package/dist/SX-BUjiWQYz.d.cts.map +0 -1
- package/dist/SX-CsPPTu-W.d.ts.map +0 -1
- package/dist/TX-DCY25MdR.d.ts.map +0 -1
- package/dist/TX-DOEpsf05.d.cts.map +0 -1
- package/dist/UX-DauyagHy.d.ts.map +0 -1
- package/dist/UX-DgUOnTFK.d.cts.map +0 -1
- package/dist/VX-DD4scgCe.d.ts.map +0 -1
- package/dist/VX-kUX6LM-3.d.cts.map +0 -1
- package/dist/WX-CjkoppdY.d.ts.map +0 -1
- package/dist/WX-DPfyPFFh.d.cts.map +0 -1
- package/dist/XX-C4C1gQZH.d.cts.map +0 -1
- package/dist/XX-sbsIUOnA.d.ts.map +0 -1
- package/dist/YX-BeT-LsiA.d.cts.map +0 -1
- package/dist/YX-DUdO8mRC.d.ts.map +0 -1
- package/dist/ZX-BuVTTq-D.d.cts.map +0 -1
- package/dist/ZX-DwfcSA-D.d.ts.map +0 -1
- package/dist/api/platform/platformLogin.d.ts.map +0 -1
- package/dist/canonicalize-C_fNNpYr.cjs +0 -80
- package/dist/canonicalize-C_fNNpYr.cjs.map +0 -1
- package/dist/canonicalize-DNUrCGad.js +0 -68
- package/dist/canonicalize-DNUrCGad.js.map +0 -1
- package/dist/classification-codes-B15PbWxz.d.cts.map +0 -1
- package/dist/classification-codes-C2X4xW5-.d.ts.map +0 -1
- package/dist/country-code-DPeNFMMi.d.cts.map +0 -1
- package/dist/country-code-DsI8Mbzx.d.ts.map +0 -1
- package/dist/currencies-DKuDflOO.d.ts.map +0 -1
- package/dist/currencies-S5g1gzBU.d.cts.map +0 -1
- package/dist/e-invoice-BuwtFnlI.d.cts.map +0 -1
- package/dist/e-invoice-C2TxhyrK.d.ts.map +0 -1
- package/dist/getBaseUrl-Dx6RDC8I.js.map +0 -1
- package/dist/hashCert-Bol7lIh2.js +0 -62
- package/dist/hashCert-Bol7lIh2.js.map +0 -1
- package/dist/hashCert-mlYEuYex.cjs +0 -68
- package/dist/hashCert-mlYEuYex.cjs.map +0 -1
- package/dist/hashSignedProperties-9vj5wlYR.js +0 -83
- package/dist/hashSignedProperties-9vj5wlYR.js.map +0 -1
- package/dist/hashSignedProperties-CU_ZqqmY.cjs +0 -95
- package/dist/hashSignedProperties-CU_ZqqmY.cjs.map +0 -1
- package/dist/index-B1DSs-wd.d.cts.map +0 -1
- package/dist/index-CJNLQVjx.d.ts +0 -1
- package/dist/index-FTgB2nM6.d.ts.map +0 -1
- package/dist/index-Wy1ONBjV.d.cts +0 -1
- package/dist/index10.cjs.map +0 -1
- package/dist/index21.cjs.map +0 -1
- package/dist/index67.cjs +0 -4
- package/dist/index67.cts.map +0 -1
- package/dist/index68.cjs +0 -3
- package/dist/index68.cts.map +0 -1
- package/dist/index69.cjs +0 -4
- package/dist/index69.cts.map +0 -1
- package/dist/index70.cjs +0 -3
- package/dist/index70.cts.map +0 -1
- package/dist/index71.cjs +0 -3
- package/dist/index71.cts.map +0 -1
- package/dist/index72.cjs +0 -3
- package/dist/index72.cts.map +0 -1
- package/dist/index73.cjs +0 -3
- package/dist/index73.cts.map +0 -1
- package/dist/invoice-1_1-BJVcw-oE.d.ts +0 -432
- package/dist/invoice-1_1-BJVcw-oE.d.ts.map +0 -1
- package/dist/invoice-1_1-DWdNPRzr.d.cts +0 -432
- package/dist/invoice-1_1-DWdNPRzr.d.cts.map +0 -1
- package/dist/invoice1-1-8S-QQn7P.cjs +0 -547
- package/dist/invoice1-1-8S-QQn7P.cjs.map +0 -1
- package/dist/invoice1-1-CHuLpkFz.js +0 -504
- package/dist/invoice1-1-CHuLpkFz.js.map +0 -1
- package/dist/msic-codes-B_1W6lZF.d.cts.map +0 -1
- package/dist/msic-codes-bs0lTfSZ.d.ts +0 -26
- package/dist/msic-codes-bs0lTfSZ.d.ts.map +0 -1
- package/dist/payment-modes-B8dNy3SM.d.ts.map +0 -1
- package/dist/payment-modes-DHihrywe.d.cts.map +0 -1
- package/dist/platformLogin-DsxWWUXr.js.map +0 -1
- package/dist/populateFinalDocument-BdyYzz5Y.cjs +0 -96
- package/dist/populateFinalDocument-BdyYzz5Y.cjs.map +0 -1
- package/dist/populateFinalDocument-BpLXmgLv.js +0 -90
- package/dist/populateFinalDocument-BpLXmgLv.js.map +0 -1
- package/dist/populateSignedProperties-BJMcBQ6S.cjs +0 -58
- package/dist/populateSignedProperties-BJMcBQ6S.cjs.map +0 -1
- package/dist/populateSignedProperties-BvGN-YZH.js +0 -52
- package/dist/populateSignedProperties-BvGN-YZH.js.map +0 -1
- package/dist/sign-B61Cy3gO.cjs +0 -40
- package/dist/sign-B61Cy3gO.cjs.map +0 -1
- package/dist/sign-DzHK7UhR.js +0 -34
- package/dist/sign-DzHK7UhR.js.map +0 -1
- package/dist/signatures-BKi9DP2K.d.cts.map +0 -1
- package/dist/signatures-C9QPZTQd.d.ts.map +0 -1
- package/dist/state-codes-CxG1S9YY.d.ts.map +0 -1
- package/dist/state-codes-DXSWtE6a.d.cts.map +0 -1
- package/dist/tax-types-CEpfSh5P.d.ts.map +0 -1
- package/dist/tax-types-CgwxONDS.d.cts.map +0 -1
- package/dist/transform-BLz0S687.cjs +0 -72
- package/dist/transform-BLz0S687.cjs.map +0 -1
- package/dist/transform-D1q-U6Zj.js +0 -66
- package/dist/transform-D1q-U6Zj.js.map +0 -1
- package/dist/types/documents/index.d.ts +0 -57
- package/dist/types/documents/invoice-1_1.d.ts +0 -56
- package/dist/unit-types-1bF0KhIp.d.ts +0 -56
- package/dist/unit-types-1bF0KhIp.d.ts.map +0 -1
- package/dist/unit-types-CsrkvgfG.d.cts +0 -56
- package/dist/unit-types-CsrkvgfG.d.cts.map +0 -1
- package/dist/utils/MyInvoisClient.d.ts +0 -60
- package/dist/utils/MyInvoisClient.js +0 -13
- package/dist/utils/base64.d.ts.map +0 -1
- package/dist/utils/base64.js.map +0 -1
- package/dist/utils/debug/debug-document-hash.d.ts +0 -100
- package/dist/utils/debug/debug-document-hash.d.ts.map +0 -1
- package/dist/utils/debug/debug-document-hash.js +0 -120
- package/dist/utils/debug/debug-document-hash.js.map +0 -1
- package/dist/utils/debug/debug-invoice-submission.d.ts +0 -152
- package/dist/utils/debug/debug-invoice-submission.d.ts.map +0 -1
- package/dist/utils/debug/debug-invoice-submission.js +0 -226
- package/dist/utils/debug/debug-invoice-submission.js.map +0 -1
- package/dist/utils/getBaseUrl.d.ts.map +0 -1
- package/dist/utils/invoice1-1.d.ts +0 -117
- package/dist/utils/invoice1-1.d.ts.map +0 -1
- package/dist/utils/invoice1-1.js +0 -10
- package/dist/utils/signature/canonicalize.d.ts +0 -26
- package/dist/utils/signature/canonicalize.d.ts.map +0 -1
- package/dist/utils/signature/canonicalize.js +0 -3
- package/dist/utils/signature/hashCert.d.ts +0 -15
- package/dist/utils/signature/hashCert.d.ts.map +0 -1
- package/dist/utils/signature/hashCert.js +0 -3
- package/dist/utils/signature/hashSignedProperties.d.ts +0 -25
- package/dist/utils/signature/hashSignedProperties.d.ts.map +0 -1
- package/dist/utils/signature/hashSignedProperties.js +0 -3
- package/dist/utils/signature/populateFinalDocument.d.ts +0 -23
- package/dist/utils/signature/populateFinalDocument.d.ts.map +0 -1
- package/dist/utils/signature/populateFinalDocument.js +0 -3
- package/dist/utils/signature/populateSignedProperties.d.ts +0 -23
- package/dist/utils/signature/populateSignedProperties.d.ts.map +0 -1
- package/dist/utils/signature/populateSignedProperties.js +0 -3
- package/dist/utils/signature/sign.d.ts +0 -16
- package/dist/utils/signature/sign.d.ts.map +0 -1
- package/dist/utils/signature/sign.js +0 -3
- package/dist/utils/signature/transform.d.ts +0 -16
- package/dist/utils/signature/transform.d.ts.map +0 -1
- package/dist/utils/signature/transform.js +0 -3
- package/src/types/documents/index.d.ts +0 -1
- package/src/types/documents/invoice-1_1.d.ts +0 -439
- package/src/utils/MyInvoisClient.ts +0 -501
- package/src/utils/debug/debug-document-hash.ts +0 -249
- package/src/utils/debug/debug-invoice-submission.ts +0 -355
- package/src/utils/invoice1-1.ts +0 -671
- package/src/utils/signature/canonicalize.ts +0 -104
- package/src/utils/signature/hashCert.ts +0 -115
- package/src/utils/signature/hashSignedProperties.ts +0 -155
- package/src/utils/signature/populateFinalDocument.ts +0 -187
- package/src/utils/signature/populateSignedProperties.ts +0 -87
- package/src/utils/signature/sign.ts +0 -51
- package/src/utils/signature/transform.ts +0 -99
- package/test/canonicalize.test.ts +0 -110
- package/test/hashCert.test.ts +0 -95
- package/test/hashSignedProperties.test.ts +0 -140
- package/test/populateFinalDocument.test.ts +0 -218
- package/test/populateSignedProperties.test.ts +0 -155
- package/test/sign.test.ts +0 -70
- package/test/transform.test.ts +0 -158
|
@@ -1,171 +1,96 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
import { MyInvoisClient } from '../src/index'
|
|
2
3
|
import type { InvoiceV1_1 } from '../src/types'
|
|
3
|
-
import { MyInvoisClient } from '../src/utils/MyInvoisClient'
|
|
4
4
|
import {
|
|
5
|
-
|
|
5
|
+
generateCompleteDocument,
|
|
6
6
|
extractCertificateInfo,
|
|
7
|
-
|
|
8
|
-
generateDocumentHashForSubmission,
|
|
9
|
-
generateSignedInvoiceXML,
|
|
10
|
-
} from '../src/utils/invoice1-1'
|
|
11
|
-
import type { SigningCredentials } from '../src/types'
|
|
12
|
-
import {
|
|
13
|
-
debugDocumentHash,
|
|
14
|
-
testSubmissionHashMethods,
|
|
15
|
-
} from '../src/utils/debug/debug-document-hash'
|
|
16
|
-
import {
|
|
17
|
-
debugSignedInvoiceXML,
|
|
18
|
-
testCanonicalizationAlgorithms,
|
|
19
|
-
validateXMLStructure,
|
|
20
|
-
} from '../src/utils/debug/debug-invoice-submission'
|
|
7
|
+
} from '../src/utils/document'
|
|
21
8
|
|
|
22
9
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
10
|
+
* ⚠️ SECURITY NOTICE: This file uses environment variables for sensitive data.
|
|
11
|
+
* Never hardcode actual TIN, NRIC, certificates, or API credentials in test files.
|
|
12
|
+
* Use .env file for your actual values (already gitignored).
|
|
25
13
|
*/
|
|
26
|
-
function createTestSigningCredentials(): SigningCredentials {
|
|
27
|
-
// Test private key (THIS IS FOR TESTING ONLY - NEVER USE IN PRODUCTION)
|
|
28
|
-
const testPrivateKey = process.env.TEST_PRIVATE_KEY!
|
|
29
|
-
|
|
30
|
-
// Test certificate (THIS IS FOR TESTING ONLY)
|
|
31
|
-
const testCertificate = process.env.TEST_CERTIFICATE!
|
|
32
|
-
|
|
33
|
-
console.warn(`
|
|
34
|
-
⚠️ WARNING: Using test credentials for development only!
|
|
35
|
-
These credentials will NOT work with the actual MyInvois API.
|
|
36
|
-
You must obtain official certificates from LHDNM for production use.
|
|
37
|
-
`)
|
|
38
|
-
|
|
39
|
-
const extractedCertificate = extractCertificateInfo(testCertificate)
|
|
40
|
-
|
|
41
|
-
return {
|
|
42
|
-
privateKeyPem: testPrivateKey,
|
|
43
|
-
certificatePem: testCertificate,
|
|
44
|
-
issuerName: extractedCertificate.issuerName,
|
|
45
|
-
serialNumber: extractedCertificate.serialNumber,
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
14
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Creates minimal test invoice data that meets all mandatory requirements
|
|
17
|
+
* Following MyInvois v1.1 specification exactly
|
|
18
|
+
*/
|
|
19
|
+
const createMinimalTestInvoice = (): InvoiceV1_1 => {
|
|
20
|
+
// Use current date/time to avoid validation errors
|
|
52
21
|
const now = new Date()
|
|
53
|
-
const currentDate = now.toISOString().split('T')[0] // YYYY-MM-DD
|
|
54
|
-
const currentTime = now.toISOString().split('T')[1].split('.')[0] + 'Z' // HH:MM:SSZ
|
|
55
|
-
|
|
56
|
-
console.log(
|
|
57
|
-
'📅 Using current date/time for invoice:',
|
|
58
|
-
currentDate,
|
|
59
|
-
currentTime,
|
|
60
|
-
)
|
|
22
|
+
const currentDate = now.toISOString().split('T')[0] // YYYY-MM-DD
|
|
23
|
+
const currentTime = now.toISOString().split('T')[1].split('.')[0] + 'Z' // HH:MM:SSZ
|
|
61
24
|
|
|
62
25
|
return {
|
|
26
|
+
// === CORE MANDATORY FIELDS ===
|
|
63
27
|
eInvoiceVersion: '1.1',
|
|
64
|
-
eInvoiceTypeCode: '01',
|
|
65
|
-
eInvoiceCodeOrNumber:
|
|
28
|
+
eInvoiceTypeCode: '01', // Standard invoice
|
|
29
|
+
eInvoiceCodeOrNumber: `TEST-INV-${Date.now()}`, // Unique invoice number
|
|
66
30
|
eInvoiceDate: currentDate,
|
|
67
31
|
eInvoiceTime: currentTime,
|
|
68
32
|
invoiceCurrencyCode: 'MYR',
|
|
69
33
|
|
|
34
|
+
// === SUPPLIER (will be updated with certificate TIN) ===
|
|
70
35
|
supplier: {
|
|
71
|
-
name: '
|
|
72
|
-
tin: process.env.TIN_VALUE!,
|
|
36
|
+
name: 'Test Company Sdn Bhd',
|
|
37
|
+
tin: process.env.TIN_VALUE!, // Will be replaced with certificate TIN
|
|
73
38
|
registrationType: 'NRIC',
|
|
74
39
|
registrationNumber: process.env.NRIC_VALUE!,
|
|
75
|
-
sstRegistrationNumber: 'NA',
|
|
76
|
-
email: 'supplier@email.com',
|
|
77
40
|
contactNumber: '+60123456789',
|
|
78
|
-
industryClassificationCode: '46510',
|
|
79
41
|
address: {
|
|
80
|
-
addressLine0: '
|
|
81
|
-
addressLine1: 'Bangunan Merdeka',
|
|
82
|
-
addressLine2: 'Persiaran Jaya',
|
|
83
|
-
postalZone: '50480',
|
|
42
|
+
addressLine0: '123 Test Street',
|
|
84
43
|
cityName: 'Kuala Lumpur',
|
|
85
|
-
state: '14',
|
|
44
|
+
state: '14', // Wilayah Persekutuan Kuala Lumpur
|
|
86
45
|
country: 'MYS',
|
|
87
46
|
},
|
|
88
47
|
},
|
|
89
48
|
|
|
49
|
+
// === BUYER (using consolidated buyer for testing) ===
|
|
90
50
|
buyer: {
|
|
91
|
-
name: '
|
|
92
|
-
tin: 'EI00000000010',
|
|
93
|
-
|
|
51
|
+
name: 'CONSOLIDATED E-INVOICE BUYER',
|
|
52
|
+
tin: 'EI00000000010', // Standard consolidated buyer TIN
|
|
53
|
+
registrationType: 'NRIC',
|
|
54
|
+
registrationNumber: process.env.NRIC_VALUE!,
|
|
94
55
|
sstRegistrationNumber: 'NA',
|
|
95
|
-
|
|
96
|
-
contactNumber: 'NA',
|
|
56
|
+
contactNumber: '+60123456789', // Valid phone number (minimum 8 chars)
|
|
97
57
|
address: {
|
|
98
58
|
addressLine0: 'NA',
|
|
99
|
-
|
|
100
|
-
addressLine2: 'NA',
|
|
101
|
-
cityName: 'Kuala Lumpur',
|
|
102
|
-
postalZone: '50000',
|
|
59
|
+
cityName: 'KUALA LUMPUR',
|
|
103
60
|
state: '14',
|
|
104
61
|
country: 'MYS',
|
|
105
62
|
},
|
|
106
63
|
},
|
|
107
64
|
|
|
65
|
+
// === SINGLE LINE ITEM (minimal) ===
|
|
108
66
|
invoiceLineItems: [
|
|
109
67
|
{
|
|
110
|
-
itemClassificationCode: '
|
|
111
|
-
itemDescription: '
|
|
112
|
-
unitPrice:
|
|
113
|
-
taxType: '01',
|
|
114
|
-
taxRate:
|
|
115
|
-
taxAmount:
|
|
116
|
-
totalTaxableAmountPerLine:
|
|
117
|
-
totalAmountPerLine:
|
|
118
|
-
quantity: 1,
|
|
119
|
-
measurement: 'C62',
|
|
120
|
-
countryOfOrigin: 'MYS',
|
|
121
|
-
},
|
|
122
|
-
{
|
|
123
|
-
itemClassificationCode: '004',
|
|
124
|
-
itemDescription: 'Receipt 101 - 200',
|
|
125
|
-
unitPrice: 20000,
|
|
126
|
-
taxType: '01',
|
|
127
|
-
taxRate: 10.0,
|
|
128
|
-
taxAmount: 2000,
|
|
129
|
-
totalTaxableAmountPerLine: 20000,
|
|
130
|
-
totalAmountPerLine: 22000,
|
|
131
|
-
quantity: 1,
|
|
132
|
-
measurement: 'C62',
|
|
133
|
-
countryOfOrigin: 'MYS',
|
|
68
|
+
itemClassificationCode: '001', // General goods
|
|
69
|
+
itemDescription: 'Test Product',
|
|
70
|
+
unitPrice: 100.0,
|
|
71
|
+
taxType: '01', // SST
|
|
72
|
+
taxRate: 6.0, // 6% SST
|
|
73
|
+
taxAmount: 6.0, // 6% of 100
|
|
74
|
+
totalTaxableAmountPerLine: 100.0,
|
|
75
|
+
totalAmountPerLine: 106.0, // 100 + 6
|
|
134
76
|
},
|
|
135
77
|
],
|
|
136
78
|
|
|
79
|
+
// === MONETARY TOTALS ===
|
|
137
80
|
legalMonetaryTotal: {
|
|
138
|
-
taxExclusiveAmount:
|
|
139
|
-
taxInclusiveAmount:
|
|
140
|
-
|
|
141
|
-
chargeTotalAmount: 0,
|
|
142
|
-
payableRoundingAmount: 0,
|
|
143
|
-
payableAmount: 33000,
|
|
81
|
+
taxExclusiveAmount: 100.0,
|
|
82
|
+
taxInclusiveAmount: 106.0,
|
|
83
|
+
payableAmount: 106.0,
|
|
144
84
|
},
|
|
145
85
|
|
|
86
|
+
// === TAX TOTAL ===
|
|
146
87
|
taxTotal: {
|
|
147
|
-
taxAmount:
|
|
148
|
-
taxSubtotals: [
|
|
149
|
-
{
|
|
150
|
-
taxableAmount: 30000,
|
|
151
|
-
taxAmount: 3000,
|
|
152
|
-
taxCategory: {
|
|
153
|
-
taxTypeCode: '01',
|
|
154
|
-
taxRate: 10.0,
|
|
155
|
-
},
|
|
156
|
-
},
|
|
157
|
-
],
|
|
88
|
+
taxAmount: 6.0,
|
|
158
89
|
},
|
|
159
90
|
|
|
160
|
-
|
|
161
|
-
{
|
|
162
|
-
paymentMeansCode: '01',
|
|
163
|
-
payeeFinancialAccountID: '1234567890',
|
|
164
|
-
},
|
|
165
|
-
],
|
|
166
|
-
|
|
91
|
+
// === DIGITAL SIGNATURE (placeholder - will be populated by signing process) ===
|
|
167
92
|
issuerDigitalSignature: {
|
|
168
|
-
Id: '
|
|
93
|
+
Id: 'signature',
|
|
169
94
|
'ds:SignedInfo': {
|
|
170
95
|
'ds:CanonicalizationMethod': {
|
|
171
96
|
Algorithm: 'http://www.w3.org/2006/12/xml-c14n11',
|
|
@@ -183,6 +108,7 @@ const createTestInvoiceData = (): InvoiceV1_1 => {
|
|
|
183
108
|
'ds:DigestValue': '',
|
|
184
109
|
},
|
|
185
110
|
{
|
|
111
|
+
Id: 'id-xades-signed-props',
|
|
186
112
|
URI: '#id-xades-signed-props',
|
|
187
113
|
'ds:DigestMethod': {
|
|
188
114
|
Algorithm: 'http://www.w3.org/2001/04/xmlenc#sha256',
|
|
@@ -227,689 +153,298 @@ const createTestInvoiceData = (): InvoiceV1_1 => {
|
|
|
227
153
|
}
|
|
228
154
|
}
|
|
229
155
|
|
|
230
|
-
describe('
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
// Skip if no test credentials available
|
|
238
|
-
if (!process.env.CERTIFICATE || !process.env.PRIVATE_KEY) {
|
|
239
|
-
expect
|
|
240
|
-
.soft(
|
|
241
|
-
false,
|
|
242
|
-
'Skipping test: Missing CERTIFICATE or PRIVATE_KEY environment variables',
|
|
243
|
-
)
|
|
244
|
-
.toBe(true)
|
|
245
|
-
return
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
const invoiceData = createTestInvoiceData()
|
|
249
|
-
const signingCredentials = createTestSigningCredentials()
|
|
156
|
+
describe('MyInvois Document Generation and Submission', () => {
|
|
157
|
+
const requiredEnvVars = [
|
|
158
|
+
'CLIENT_ID',
|
|
159
|
+
'CLIENT_SECRET',
|
|
160
|
+
'TEST_PRIVATE_KEY',
|
|
161
|
+
'TEST_CERTIFICATE',
|
|
162
|
+
]
|
|
250
163
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
signingCredentials,
|
|
254
|
-
)
|
|
255
|
-
|
|
256
|
-
// Verify the XML contains expected elements
|
|
257
|
-
expect(signedXML).toContain(
|
|
258
|
-
'<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"',
|
|
259
|
-
)
|
|
260
|
-
expect(signedXML).toContain('<ds:SignatureValue>')
|
|
261
|
-
expect(signedXML).toContain('<ds:X509Certificate>')
|
|
262
|
-
expect(signedXML).toContain('<xades:SigningTime>')
|
|
263
|
-
expect(signedXML).toContain(invoiceData.eInvoiceCodeOrNumber)
|
|
264
|
-
expect(signedXML).toContain(invoiceData.supplier.name)
|
|
265
|
-
expect(signedXML).toContain(invoiceData.buyer.name)
|
|
266
|
-
|
|
267
|
-
// Verify signature elements are populated (not empty)
|
|
268
|
-
expect(signedXML).not.toContain('<ds:SignatureValue></ds:SignatureValue>')
|
|
269
|
-
expect(signedXML).not.toContain(
|
|
270
|
-
'<ds:X509Certificate></ds:X509Certificate>',
|
|
271
|
-
)
|
|
272
|
-
})
|
|
273
|
-
|
|
274
|
-
it('should generate document hash for submission', async () => {
|
|
275
|
-
if (!process.env.CERTIFICATE || !process.env.PRIVATE_KEY) {
|
|
276
|
-
expect
|
|
277
|
-
.soft(
|
|
278
|
-
false,
|
|
279
|
-
'Skipping test: Missing CERTIFICATE or PRIVATE_KEY environment variables',
|
|
280
|
-
)
|
|
281
|
-
.toBe(true)
|
|
282
|
-
return
|
|
283
|
-
}
|
|
164
|
+
// Check environment variables
|
|
165
|
+
const missingVars = requiredEnvVars.filter(varName => !process.env[varName])
|
|
284
166
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
)
|
|
292
|
-
|
|
293
|
-
const documentHash = generateDocumentHash(signedXML)
|
|
294
|
-
const base64Document = encodeDocumentForSubmission(signedXML)
|
|
295
|
-
|
|
296
|
-
// Test the alternative hash method
|
|
297
|
-
console.log('\n🔧 TESTING ALTERNATIVE HASH METHOD:')
|
|
298
|
-
try {
|
|
299
|
-
const canonicalizedHash =
|
|
300
|
-
await generateDocumentHashForSubmission(signedXML)
|
|
301
|
-
console.log(`Current hash: ${documentHash}`)
|
|
302
|
-
console.log(`Canonicalized hash: ${canonicalizedHash}`)
|
|
303
|
-
console.log(
|
|
304
|
-
`Methods are equal: ${documentHash === canonicalizedHash ? '✅' : '❌'}`,
|
|
167
|
+
if (missingVars.length > 0) {
|
|
168
|
+
it.skip(`Skipping tests - Missing environment variables: ${missingVars.join(', ')}`, () => {
|
|
169
|
+
expect
|
|
170
|
+
.soft(
|
|
171
|
+
false,
|
|
172
|
+
`Missing required environment variables: ${missingVars.join(', ')}`,
|
|
305
173
|
)
|
|
306
|
-
|
|
307
|
-
console.log('❌ Error testing canonicalized hash:', error)
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
// Verify hash is a valid hex string
|
|
311
|
-
expect(documentHash).toMatch(/^[a-f0-9]{64}$/)
|
|
312
|
-
|
|
313
|
-
// Verify base64 encoding
|
|
314
|
-
expect(() => Buffer.from(base64Document, 'base64')).not.toThrow()
|
|
315
|
-
|
|
316
|
-
// CRITICAL TEST: Verify the hash is calculated from the same minified XML that gets encoded
|
|
317
|
-
// This ensures consistency between documentHash and document (base64) values
|
|
318
|
-
const minifiedXML = signedXML
|
|
319
|
-
.replace(/>\s+</g, '><')
|
|
320
|
-
.replace(/\s+/g, ' ')
|
|
321
|
-
.replace(/>\s/g, '>')
|
|
322
|
-
.replace(/\s</g, '<')
|
|
323
|
-
.trim()
|
|
324
|
-
|
|
325
|
-
// Calculate hash of minified XML manually to verify our generateDocumentHash function
|
|
326
|
-
const crypto = require('crypto')
|
|
327
|
-
const expectedHash = crypto
|
|
328
|
-
.createHash('sha256')
|
|
329
|
-
.update(minifiedXML, 'utf8')
|
|
330
|
-
.digest('hex')
|
|
331
|
-
|
|
332
|
-
// The documentHash should match the hash of the minified XML
|
|
333
|
-
expect(documentHash).toEqual(expectedHash)
|
|
334
|
-
|
|
335
|
-
// The base64Document should decode to the same minified XML
|
|
336
|
-
const decodedDocument = Buffer.from(base64Document, 'base64').toString(
|
|
337
|
-
'utf8',
|
|
338
|
-
)
|
|
339
|
-
expect(decodedDocument).toEqual(minifiedXML)
|
|
340
|
-
})
|
|
341
|
-
|
|
342
|
-
it('should validate signing credentials properly', () => {
|
|
343
|
-
if (!process.env.CERTIFICATE || !process.env.PRIVATE_KEY) {
|
|
344
|
-
expect
|
|
345
|
-
.soft(
|
|
346
|
-
false,
|
|
347
|
-
'Skipping test: Missing CERTIFICATE or PRIVATE_KEY environment variables',
|
|
348
|
-
)
|
|
349
|
-
.toBe(true)
|
|
350
|
-
return
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
expect(() => createTestSigningCredentials()).not.toThrow()
|
|
354
|
-
|
|
355
|
-
const credentials = createTestSigningCredentials()
|
|
356
|
-
expect(credentials.privateKeyPem).toBeDefined()
|
|
357
|
-
expect(credentials.certificatePem).toBeDefined()
|
|
358
|
-
expect(credentials.issuerName).toBeDefined()
|
|
359
|
-
expect(credentials.serialNumber).toBeDefined()
|
|
174
|
+
.toBe(true)
|
|
360
175
|
})
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
describe('Real API Integration (Optional)', () => {
|
|
364
|
-
it('should submit to real MyInvois API if credentials are provided', async () => {
|
|
365
|
-
// Skip if no real API credentials
|
|
366
|
-
if (
|
|
367
|
-
!process.env.CLIENT_ID ||
|
|
368
|
-
!process.env.CLIENT_SECRET ||
|
|
369
|
-
!process.env.CERTIFICATE ||
|
|
370
|
-
!process.env.PRIVATE_KEY
|
|
371
|
-
) {
|
|
372
|
-
expect
|
|
373
|
-
.soft(
|
|
374
|
-
false,
|
|
375
|
-
'Skipping real API test: Missing required environment variables (CLIENT_ID, CLIENT_SECRET, CERTIFICATE, PRIVATE_KEY)',
|
|
376
|
-
)
|
|
377
|
-
.toBe(true)
|
|
378
|
-
return
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
const invoiceData = createTestInvoiceData()
|
|
382
|
-
const signingCredentials = createTestSigningCredentials()
|
|
176
|
+
return
|
|
177
|
+
}
|
|
383
178
|
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
const documentHash = generateDocumentHash(signedXML)
|
|
389
|
-
const base64Document = encodeDocumentForSubmission(signedXML)
|
|
390
|
-
|
|
391
|
-
// Note: This test will only run if you have real credentials
|
|
392
|
-
// and would actually submit to the MyInvois sandbox API
|
|
393
|
-
console.log('Generated signed XML length:', signedXML.length)
|
|
394
|
-
console.log('Document hash:', documentHash)
|
|
395
|
-
console.log('Base64 document length:', base64Document.length)
|
|
396
|
-
|
|
397
|
-
// For safety, we'll just validate the data format without actual submission
|
|
398
|
-
expect(signedXML).toContain('<Invoice xmlns=')
|
|
399
|
-
expect(documentHash).toMatch(/^[a-f0-9]{64}$/)
|
|
400
|
-
expect(base64Document.length).toBeGreaterThan(0)
|
|
401
|
-
}, 30000) // Longer timeout for potential API calls
|
|
402
|
-
})
|
|
179
|
+
const CLIENT_ID = process.env.CLIENT_ID!
|
|
180
|
+
const CLIENT_SECRET = process.env.CLIENT_SECRET!
|
|
181
|
+
const PRIVATE_KEY = process.env.TEST_PRIVATE_KEY!
|
|
182
|
+
const CERTIFICATE = process.env.TEST_CERTIFICATE!
|
|
403
183
|
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
const incompleteInvoice = {
|
|
407
|
-
eInvoiceVersion: '1.1',
|
|
408
|
-
eInvoiceTypeCode: '01',
|
|
409
|
-
// Missing required fields
|
|
410
|
-
} as any
|
|
411
|
-
|
|
412
|
-
// This should fail during XML generation
|
|
413
|
-
await expect(
|
|
414
|
-
generateSignedInvoiceXML(
|
|
415
|
-
incompleteInvoice,
|
|
416
|
-
createTestSigningCredentials(),
|
|
417
|
-
),
|
|
418
|
-
).rejects.toThrow()
|
|
419
|
-
})
|
|
184
|
+
it('should extract certificate information correctly', () => {
|
|
185
|
+
console.log('🔍 Extracting certificate information...')
|
|
420
186
|
|
|
421
|
-
|
|
422
|
-
const invoiceData = createTestInvoiceData()
|
|
423
|
-
const invalidCredentials = {
|
|
424
|
-
privateKeyPem: 'invalid-private-key',
|
|
425
|
-
certificatePem: 'invalid-certificate',
|
|
426
|
-
issuerName: 'invalid-issuer',
|
|
427
|
-
serialNumber: 'invalid-serial',
|
|
428
|
-
}
|
|
187
|
+
const certInfo = extractCertificateInfo(CERTIFICATE)
|
|
429
188
|
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
189
|
+
console.log('Certificate Info:', {
|
|
190
|
+
issuerName: certInfo.issuerName,
|
|
191
|
+
serialNumber: certInfo.serialNumber,
|
|
433
192
|
})
|
|
434
193
|
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
false,
|
|
440
|
-
'Skipping test: Missing CERTIFICATE or PRIVATE_KEY environment variables',
|
|
441
|
-
)
|
|
442
|
-
.toBe(true)
|
|
443
|
-
return
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
const invoiceData = createTestInvoiceData()
|
|
447
|
-
const signingCredentials = createTestSigningCredentials()
|
|
448
|
-
|
|
449
|
-
const signedXML = await generateSignedInvoiceXML(
|
|
450
|
-
invoiceData,
|
|
451
|
-
signingCredentials,
|
|
452
|
-
)
|
|
453
|
-
const sizeInBytes = Buffer.from(signedXML, 'utf8').length
|
|
454
|
-
|
|
455
|
-
// Verify document is under MyInvois limits (300KB per document)
|
|
456
|
-
expect(sizeInBytes).toBeLessThan(300 * 1024)
|
|
457
|
-
|
|
458
|
-
console.log(
|
|
459
|
-
`Generated document size: ${sizeInBytes} bytes (${(sizeInBytes / 1024).toFixed(2)} KB)`,
|
|
460
|
-
)
|
|
461
|
-
})
|
|
194
|
+
expect(certInfo.issuerName).toBeDefined()
|
|
195
|
+
expect(certInfo.serialNumber).toBeDefined()
|
|
196
|
+
expect(typeof certInfo.issuerName).toBe('string')
|
|
197
|
+
expect(typeof certInfo.serialNumber).toBe('string')
|
|
462
198
|
})
|
|
463
199
|
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
if (!process.env.CERTIFICATE || !process.env.PRIVATE_KEY) {
|
|
467
|
-
expect
|
|
468
|
-
.soft(
|
|
469
|
-
false,
|
|
470
|
-
'Skipping test: Missing CERTIFICATE or PRIVATE_KEY environment variables',
|
|
471
|
-
)
|
|
472
|
-
.toBe(true)
|
|
473
|
-
return
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
const invoiceData = createTestInvoiceData()
|
|
477
|
-
const signingCredentials = createTestSigningCredentials()
|
|
200
|
+
it('should find TIN that matches certificate', async () => {
|
|
201
|
+
console.log('🔐 Finding TIN that matches certificate...')
|
|
478
202
|
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
console.log('\n📊 VALIDATION RESULTS:')
|
|
489
|
-
console.log(
|
|
490
|
-
'XML Structure Valid:',
|
|
491
|
-
debugResults.validationResults.xmlStructure.valid,
|
|
492
|
-
)
|
|
493
|
-
console.log(
|
|
494
|
-
'Signature Elements Valid:',
|
|
495
|
-
debugResults.validationResults.signatureElements.valid,
|
|
496
|
-
)
|
|
497
|
-
console.log(
|
|
498
|
-
'Digest Values Valid:',
|
|
499
|
-
debugResults.validationResults.digestValues.valid,
|
|
500
|
-
)
|
|
501
|
-
console.log(
|
|
502
|
-
'Certificate Info Valid:',
|
|
503
|
-
debugResults.validationResults.certificateInfo.valid,
|
|
504
|
-
)
|
|
505
|
-
|
|
506
|
-
if (debugResults.validationResults.xmlStructure.errors.length > 0) {
|
|
507
|
-
console.log('\n❌ XML Structure Errors:')
|
|
508
|
-
debugResults.validationResults.xmlStructure.errors.forEach(error =>
|
|
509
|
-
console.log(` - ${error}`),
|
|
510
|
-
)
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
if (debugResults.validationResults.signatureElements.errors.length > 0) {
|
|
514
|
-
console.log('\n❌ Signature Element Errors:')
|
|
515
|
-
debugResults.validationResults.signatureElements.errors.forEach(error =>
|
|
516
|
-
console.log(` - ${error}`),
|
|
517
|
-
)
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
if (debugResults.validationResults.digestValues.errors.length > 0) {
|
|
521
|
-
console.log('\n❌ Digest Value Errors:')
|
|
522
|
-
debugResults.validationResults.digestValues.errors.forEach(error =>
|
|
523
|
-
console.log(` - ${error}`),
|
|
524
|
-
)
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
if (debugResults.validationResults.certificateInfo.errors.length > 0) {
|
|
528
|
-
console.log('\n❌ Certificate Info Errors:')
|
|
529
|
-
debugResults.validationResults.certificateInfo.errors.forEach(error =>
|
|
530
|
-
console.log(` - ${error}`),
|
|
531
|
-
)
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
console.log('\n📋 STEP-BY-STEP RESULTS:')
|
|
535
|
-
Object.entries(debugResults.stepByStepResults).forEach(
|
|
536
|
-
([step, result]) => {
|
|
537
|
-
const status = result.success ? '✅' : '❌'
|
|
538
|
-
console.log(
|
|
539
|
-
`${status} ${step}: ${result.success ? 'SUCCESS' : `FAILED - ${result.error}`}`,
|
|
540
|
-
)
|
|
541
|
-
},
|
|
542
|
-
)
|
|
543
|
-
|
|
544
|
-
if (debugResults.validationResults.canonicalizationTest) {
|
|
545
|
-
console.log('\n🔧 CANONICALIZATION TEST:')
|
|
546
|
-
console.log(
|
|
547
|
-
'Exclusive C14N Success:',
|
|
548
|
-
debugResults.validationResults.canonicalizationTest.exclusiveC14N
|
|
549
|
-
?.success,
|
|
550
|
-
)
|
|
551
|
-
console.log(
|
|
552
|
-
'C14N 1.1 Fallback Success:',
|
|
553
|
-
debugResults.validationResults.canonicalizationTest.c14n11Fallback
|
|
554
|
-
?.success,
|
|
555
|
-
)
|
|
556
|
-
console.log(
|
|
557
|
-
'Results Equal:',
|
|
558
|
-
debugResults.validationResults.canonicalizationTest.areEqual,
|
|
559
|
-
)
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
if (debugResults.signedXML) {
|
|
563
|
-
// Additional XML structure validation
|
|
564
|
-
const xmlValidation = validateXMLStructure(debugResults.signedXML)
|
|
565
|
-
console.log('\n📝 XML VALIDATION:')
|
|
566
|
-
console.log('Overall Valid:', xmlValidation.isValid)
|
|
203
|
+
const client = new MyInvoisClient(
|
|
204
|
+
CLIENT_ID,
|
|
205
|
+
CLIENT_SECRET,
|
|
206
|
+
'sandbox',
|
|
207
|
+
CERTIFICATE,
|
|
208
|
+
PRIVATE_KEY,
|
|
209
|
+
undefined,
|
|
210
|
+
true, // debug mode
|
|
211
|
+
)
|
|
567
212
|
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
213
|
+
// Test TIN formats that might match the certificate
|
|
214
|
+
// Note: These are example TIN formats - replace with your actual test TINs
|
|
215
|
+
const testTINs = [
|
|
216
|
+
process.env.TIN_VALUE, // Environment variable if set
|
|
217
|
+
process.env.TEST_TIN_1, // Additional test TIN from environment
|
|
218
|
+
process.env.TEST_TIN_2, // Additional test TIN from environment
|
|
219
|
+
process.env.TEST_TIN_3, // Additional test TIN from environment
|
|
220
|
+
'EI00000000010', // Consolidated buyer (shouldn't work for supplier)
|
|
221
|
+
].filter(Boolean) // Remove undefined values
|
|
222
|
+
|
|
223
|
+
let certificateMatchingTIN: string | null = null
|
|
224
|
+
const validTINs: string[] = []
|
|
225
|
+
|
|
226
|
+
// Step 1: Check which TINs are valid in the system
|
|
227
|
+
console.log('📋 Step 1: Checking TIN validity...')
|
|
228
|
+
for (const tin of testTINs) {
|
|
229
|
+
try {
|
|
230
|
+
console.log(`Testing TIN validity: ${tin}`)
|
|
231
|
+
const isValid = await client.verifyTin(tin!, 'BRN', '123456789012')
|
|
232
|
+
console.log(`TIN ${tin} validity: ${isValid}`)
|
|
572
233
|
|
|
573
|
-
if (
|
|
574
|
-
|
|
575
|
-
xmlValidation.warnings.forEach(warning =>
|
|
576
|
-
console.log(` - ${warning}`),
|
|
577
|
-
)
|
|
234
|
+
if (isValid) {
|
|
235
|
+
validTINs.push(tin!)
|
|
578
236
|
}
|
|
237
|
+
} catch (error) {
|
|
238
|
+
console.log(`❌ Error testing TIN ${tin}:`, error)
|
|
239
|
+
}
|
|
240
|
+
}
|
|
579
241
|
|
|
580
|
-
|
|
581
|
-
const sizeInBytes = Buffer.from(debugResults.signedXML, 'utf8').length
|
|
582
|
-
console.log(
|
|
583
|
-
`\n📏 Document Size: ${sizeInBytes} bytes (${(sizeInBytes / 1024).toFixed(2)} KB)`,
|
|
584
|
-
)
|
|
585
|
-
|
|
586
|
-
// Sample of generated XML for manual inspection
|
|
587
|
-
console.log('\n📄 XML SAMPLE (first 500 chars):')
|
|
588
|
-
console.log(debugResults.signedXML.substring(0, 500) + '...')
|
|
242
|
+
console.log(`📊 Found ${validTINs.length} valid TINs:`, validTINs)
|
|
589
243
|
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
244
|
+
// Step 2: Test each valid TIN with a minimal document submission to find certificate match
|
|
245
|
+
console.log('📋 Step 2: Testing certificate matching...')
|
|
246
|
+
for (const tin of validTINs) {
|
|
247
|
+
try {
|
|
248
|
+
console.log(`Testing TIN with certificate: ${tin}`)
|
|
593
249
|
|
|
594
|
-
//
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
)
|
|
599
|
-
) {
|
|
600
|
-
commonIssues.push('Missing ext namespace declaration')
|
|
601
|
-
}
|
|
250
|
+
// Create a minimal test invoice with this TIN
|
|
251
|
+
const testInvoice = createMinimalTestInvoice()
|
|
252
|
+
testInvoice.supplier.tin = tin
|
|
253
|
+
testInvoice.eInvoiceCodeOrNumber = `TEST-CERT-${Date.now()}`
|
|
602
254
|
|
|
603
|
-
//
|
|
604
|
-
|
|
605
|
-
commonIssues.push('Missing or incorrect signature target')
|
|
606
|
-
}
|
|
255
|
+
// Try to submit it
|
|
256
|
+
const { status } = await client.submitDocument([testInvoice])
|
|
607
257
|
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
commonIssues.push('Missing or incorrect SHA256 digest algorithm')
|
|
615
|
-
}
|
|
616
|
-
|
|
617
|
-
// Check for RSA-SHA256 signature method
|
|
618
|
-
if (
|
|
619
|
-
!debugResults.signedXML.includes(
|
|
620
|
-
'Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"',
|
|
621
|
-
)
|
|
622
|
-
) {
|
|
623
|
-
commonIssues.push(
|
|
624
|
-
'Missing or incorrect RSA-SHA256 signature algorithm',
|
|
625
|
-
)
|
|
258
|
+
if (status === 202) {
|
|
259
|
+
console.log(`✅ SUCCESS! TIN ${tin} works with certificate`)
|
|
260
|
+
certificateMatchingTIN = tin
|
|
261
|
+
break
|
|
262
|
+
} else {
|
|
263
|
+
console.log(`❌ TIN ${tin} failed with status ${status}`)
|
|
626
264
|
}
|
|
627
|
-
|
|
628
|
-
// Check for proper C14N algorithm in XML
|
|
265
|
+
} catch (error: any) {
|
|
629
266
|
if (
|
|
630
|
-
|
|
631
|
-
'
|
|
267
|
+
error.message?.includes(
|
|
268
|
+
'authenticated TIN and documents TIN is not matching',
|
|
632
269
|
)
|
|
633
270
|
) {
|
|
634
|
-
|
|
635
|
-
'XML declares different canonicalization algorithm than expected',
|
|
636
|
-
)
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
if (commonIssues.length > 0) {
|
|
640
|
-
console.log('❌ Common MyInvois Issues Found:')
|
|
641
|
-
commonIssues.forEach(issue => console.log(` - ${issue}`))
|
|
271
|
+
console.log(`❌ TIN ${tin} doesn't match certificate`)
|
|
642
272
|
} else {
|
|
643
|
-
console.log(
|
|
273
|
+
console.log(`❌ TIN ${tin} failed with error:`, error.message)
|
|
644
274
|
}
|
|
645
275
|
}
|
|
276
|
+
}
|
|
646
277
|
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
}, 30000)
|
|
651
|
-
|
|
652
|
-
it('should test canonicalization algorithms specifically', async () => {
|
|
653
|
-
if (!process.env.CERTIFICATE || !process.env.PRIVATE_KEY) {
|
|
654
|
-
expect.soft(false, 'Skipping test: Missing credentials').toBe(true)
|
|
655
|
-
return
|
|
656
|
-
}
|
|
657
|
-
|
|
658
|
-
const invoiceData = createTestInvoiceData()
|
|
659
|
-
const signingCredentials = createTestSigningCredentials()
|
|
660
|
-
|
|
661
|
-
console.log('\n🔧 CANONICALIZATION ALGORITHM TESTING')
|
|
662
|
-
console.log('=====================================')
|
|
663
|
-
|
|
664
|
-
// Generate a signed XML first to get the template
|
|
665
|
-
const signedXML = await generateSignedInvoiceXML(
|
|
666
|
-
invoiceData,
|
|
667
|
-
signingCredentials,
|
|
668
|
-
)
|
|
669
|
-
const testResults = await testCanonicalizationAlgorithms(signedXML)
|
|
670
|
-
|
|
671
|
-
console.log('Exclusive C14N Success:', testResults.exclusiveC14N.success)
|
|
672
|
-
if (!testResults.exclusiveC14N.success) {
|
|
673
|
-
console.log('Exclusive C14N Error:', testResults.exclusiveC14N.error)
|
|
674
|
-
} else {
|
|
675
|
-
console.log('Exclusive C14N Digest:', testResults.exclusiveC14N.digest)
|
|
676
|
-
}
|
|
677
|
-
|
|
678
|
-
console.log(
|
|
679
|
-
'C14N 1.1 Fallback Success:',
|
|
680
|
-
testResults.c14n11Fallback.success,
|
|
681
|
-
)
|
|
682
|
-
if (!testResults.c14n11Fallback.success) {
|
|
683
|
-
console.log(
|
|
684
|
-
'C14N 1.1 Fallback Error:',
|
|
685
|
-
testResults.c14n11Fallback.error,
|
|
686
|
-
)
|
|
687
|
-
} else {
|
|
688
|
-
console.log(
|
|
689
|
-
'C14N 1.1 Fallback Digest:',
|
|
690
|
-
testResults.c14n11Fallback.digest,
|
|
691
|
-
)
|
|
692
|
-
}
|
|
693
|
-
|
|
694
|
-
console.log('Algorithms produce same result:', testResults.areEqual)
|
|
695
|
-
|
|
696
|
-
if (
|
|
697
|
-
!testResults.areEqual &&
|
|
698
|
-
testResults.exclusiveC14N.success &&
|
|
699
|
-
testResults.c14n11Fallback.success
|
|
700
|
-
) {
|
|
701
|
-
console.log(
|
|
702
|
-
'\n⚠️ WARNING: Different canonicalization algorithms produce different results!',
|
|
703
|
-
)
|
|
704
|
-
console.log('This may be the cause of MyInvois validation failures.')
|
|
705
|
-
console.log('Exclusive C14N digest:', testResults.exclusiveC14N.digest)
|
|
706
|
-
console.log('C14N 1.1 digest:', testResults.c14n11Fallback.digest)
|
|
707
|
-
}
|
|
708
|
-
|
|
709
|
-
expect(testResults).toBeDefined()
|
|
710
|
-
})
|
|
711
|
-
|
|
712
|
-
it('should debug document hash calculation methods', async () => {
|
|
713
|
-
if (!process.env.CERTIFICATE || !process.env.PRIVATE_KEY) {
|
|
714
|
-
expect.soft(false, 'Skipping test: Missing credentials').toBe(true)
|
|
715
|
-
return
|
|
716
|
-
}
|
|
717
|
-
|
|
718
|
-
const invoiceData = createTestInvoiceData()
|
|
719
|
-
const signingCredentials = createTestSigningCredentials()
|
|
720
|
-
|
|
721
|
-
console.log('\n🔧 DOCUMENT HASH DEBUGGING')
|
|
722
|
-
console.log('===========================')
|
|
723
|
-
|
|
724
|
-
// Then debug the actual hash calculation
|
|
725
|
-
const debugResults = await debugDocumentHash(
|
|
726
|
-
invoiceData,
|
|
727
|
-
signingCredentials,
|
|
728
|
-
)
|
|
729
|
-
|
|
730
|
-
console.log('\n📊 HASH ANALYSIS RESULTS:')
|
|
731
|
-
console.log(
|
|
732
|
-
`Submission Hash: ${debugResults.documentHashes.submissionHash}`,
|
|
733
|
-
)
|
|
734
|
-
console.log(
|
|
735
|
-
`Signature Doc Digest: ${debugResults.documentHashes.signatureDocDigest}`,
|
|
736
|
-
)
|
|
278
|
+
// Store the certificate-matching TIN for next test
|
|
279
|
+
if (certificateMatchingTIN) {
|
|
280
|
+
process.env.VALID_SUPPLIER_TIN = certificateMatchingTIN
|
|
737
281
|
console.log(
|
|
738
|
-
|
|
282
|
+
`🎯 Certificate matching TIN found: ${certificateMatchingTIN}`,
|
|
739
283
|
)
|
|
284
|
+
} else if (validTINs.length > 0) {
|
|
285
|
+
// Fallback to first valid TIN with a warning
|
|
286
|
+
process.env.VALID_SUPPLIER_TIN = validTINs[0]
|
|
740
287
|
console.log(
|
|
741
|
-
|
|
288
|
+
`⚠️ No certificate match found, using first valid TIN: ${validTINs[0]}`,
|
|
742
289
|
)
|
|
743
290
|
console.log(
|
|
744
|
-
|
|
291
|
+
`⚠️ This will likely cause TIN mismatch error in submission test`,
|
|
745
292
|
)
|
|
293
|
+
}
|
|
746
294
|
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
})
|
|
295
|
+
// For now, pass the test if we found any valid TINs (the main goal is to test the implementation)
|
|
296
|
+
expect.soft(validTINs.length, 'No valid TINs found').toBeGreaterThan(0)
|
|
297
|
+
}, 60000) // Increased timeout for multiple submissions
|
|
751
298
|
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
debugResults.recommendations.forEach(rec => console.log(` ${rec}`))
|
|
755
|
-
}
|
|
299
|
+
it('should generate valid document structure', () => {
|
|
300
|
+
console.log('📄 Generating document structure...')
|
|
756
301
|
|
|
757
|
-
|
|
758
|
-
const methodResults = await testSubmissionHashMethods(
|
|
759
|
-
invoiceData,
|
|
760
|
-
signingCredentials,
|
|
761
|
-
)
|
|
302
|
+
const invoice = createMinimalTestInvoice()
|
|
762
303
|
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
304
|
+
// Use the valid TIN from previous test or fallback
|
|
305
|
+
const supplierTIN =
|
|
306
|
+
process.env.VALID_SUPPLIER_TIN || process.env.TIN_VALUE || 'C00000000000' // Replace with your TIN
|
|
307
|
+
invoice.supplier.tin = supplierTIN
|
|
767
308
|
|
|
768
|
-
|
|
769
|
-
console.log('\n🔧 METHOD RECOMMENDATIONS:')
|
|
770
|
-
methodResults.recommendations.forEach(rec => console.log(` ${rec}`))
|
|
771
|
-
}
|
|
309
|
+
console.log(`Using supplier TIN: ${supplierTIN}`)
|
|
772
310
|
|
|
773
|
-
|
|
774
|
-
console.log('\n🎯 KEY FINDINGS:')
|
|
775
|
-
if (!debugResults.areEqual.submissionVsSignature) {
|
|
776
|
-
console.log('❌ CRITICAL: Submission hash ≠ Signature digest')
|
|
777
|
-
console.log(
|
|
778
|
-
' This is likely why MyInvois rejects "Document hash is not valid"',
|
|
779
|
-
)
|
|
780
|
-
console.log(' MyInvois probably expects these to match exactly')
|
|
781
|
-
}
|
|
311
|
+
const certInfo = extractCertificateInfo(CERTIFICATE)
|
|
782
312
|
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
313
|
+
const document = generateCompleteDocument([invoice], {
|
|
314
|
+
privateKeyPem: PRIVATE_KEY,
|
|
315
|
+
certificatePem: CERTIFICATE,
|
|
316
|
+
issuerName: certInfo.issuerName,
|
|
317
|
+
serialNumber: certInfo.serialNumber,
|
|
318
|
+
})
|
|
789
319
|
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
320
|
+
console.log('Generated document structure:')
|
|
321
|
+
console.log(
|
|
322
|
+
'- Namespace declarations:',
|
|
323
|
+
Object.keys(document).filter(k => k.startsWith('_')),
|
|
324
|
+
)
|
|
325
|
+
console.log('- Number of invoices:', document.Invoice.length)
|
|
326
|
+
console.log('- First invoice keys:', Object.keys(document.Invoice[0]))
|
|
327
|
+
console.log('- Has UBLExtensions:', !!document.Invoice[0].UBLExtensions)
|
|
328
|
+
console.log('- Has Signature:', !!document.Invoice[0].Signature)
|
|
329
|
+
|
|
330
|
+
// Basic structure validation
|
|
331
|
+
expect(document._D).toBe(
|
|
332
|
+
'urn:oasis:names:specification:ubl:schema:xsd:Invoice-2',
|
|
333
|
+
)
|
|
334
|
+
expect(document._A).toBe(
|
|
335
|
+
'urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2',
|
|
336
|
+
)
|
|
337
|
+
expect(document._B).toBe(
|
|
338
|
+
'urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2',
|
|
339
|
+
)
|
|
340
|
+
expect(document.Invoice).toHaveLength(1)
|
|
341
|
+
expect(document.Invoice[0].UBLExtensions).toBeDefined()
|
|
342
|
+
expect(document.Invoice[0].Signature).toBeDefined()
|
|
801
343
|
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
344
|
+
// Store document for next test
|
|
345
|
+
;(globalThis as any).testDocument = document
|
|
346
|
+
;(globalThis as any).testInvoice = invoice
|
|
805
347
|
})
|
|
806
|
-
})
|
|
807
348
|
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
if (!process.env.CLIENT_ID || !process.env.CLIENT_SECRET) {
|
|
811
|
-
console.warn(
|
|
812
|
-
'Skipping real API test: Missing CLIENT_ID or CLIENT_SECRET environment variables',
|
|
813
|
-
)
|
|
814
|
-
expect
|
|
815
|
-
.soft(
|
|
816
|
-
false,
|
|
817
|
-
'Skipping real API test: Missing CLIENT_ID or CLIENT_SECRET environment variables',
|
|
818
|
-
)
|
|
819
|
-
.toBe(true)
|
|
820
|
-
return
|
|
821
|
-
}
|
|
349
|
+
it('should submit document to MyInvois successfully', async () => {
|
|
350
|
+
console.log('🚀 Submitting document to MyInvois...')
|
|
822
351
|
|
|
823
|
-
const
|
|
824
|
-
const
|
|
352
|
+
const document = (globalThis as any).testDocument
|
|
353
|
+
const invoice = (globalThis as any).testInvoice
|
|
825
354
|
|
|
826
|
-
if (!
|
|
827
|
-
|
|
828
|
-
'Skipping real API test: Missing PRIVATE_KEY or CERTIFICATE environment variables',
|
|
829
|
-
)
|
|
830
|
-
expect
|
|
831
|
-
.soft(
|
|
832
|
-
false,
|
|
833
|
-
'Skipping real API test: Missing PRIVATE_KEY or CERTIFICATE environment variables',
|
|
834
|
-
)
|
|
835
|
-
.toBe(true)
|
|
836
|
-
return
|
|
355
|
+
if (!document || !invoice) {
|
|
356
|
+
throw new Error('Document not generated in previous test')
|
|
837
357
|
}
|
|
838
358
|
|
|
839
|
-
const invoiceData = createTestInvoiceData()
|
|
840
|
-
|
|
841
359
|
const client = new MyInvoisClient(
|
|
842
|
-
|
|
843
|
-
|
|
360
|
+
CLIENT_ID,
|
|
361
|
+
CLIENT_SECRET,
|
|
844
362
|
'sandbox',
|
|
363
|
+
CERTIFICATE,
|
|
364
|
+
PRIVATE_KEY,
|
|
845
365
|
undefined,
|
|
846
|
-
true,
|
|
366
|
+
true, // debug mode
|
|
847
367
|
)
|
|
848
368
|
|
|
849
|
-
// 2. Submit Document
|
|
850
369
|
try {
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
console.log(
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
)
|
|
370
|
+
console.log('📤 Submitting to MyInvois API...')
|
|
371
|
+
console.log('Document size:', JSON.stringify(document).length, 'bytes')
|
|
372
|
+
|
|
373
|
+
const { data: response, status } = await client.submitDocument([invoice])
|
|
374
|
+
|
|
375
|
+
console.log('📥 Response received:')
|
|
376
|
+
console.log('Status:', status)
|
|
377
|
+
console.log('Response:', JSON.stringify(response, null, 2))
|
|
378
|
+
|
|
379
|
+
// Validate response structure
|
|
380
|
+
expect(status).toBe(202) // MyInvois returns 202 Accepted
|
|
381
|
+
expect(response.submissionUid).toBeDefined()
|
|
382
|
+
expect(typeof response.submissionUid).toBe('string')
|
|
383
|
+
|
|
384
|
+
// Check for accepted/rejected documents
|
|
385
|
+
if (response.acceptedDocuments?.length > 0) {
|
|
386
|
+
console.log('✅ Documents accepted:', response.acceptedDocuments.length)
|
|
387
|
+
response.acceptedDocuments.forEach((doc, index) => {
|
|
388
|
+
console.log(` Document ${index + 1}:`, doc.invoiceCodeNumber)
|
|
389
|
+
})
|
|
869
390
|
}
|
|
870
|
-
if (
|
|
871
|
-
submissionResponse.rejectedDocuments &&
|
|
872
|
-
submissionResponse.rejectedDocuments.length > 0
|
|
873
|
-
) {
|
|
874
|
-
console.warn(
|
|
875
|
-
'Rejected Documents:',
|
|
876
|
-
submissionResponse.rejectedDocuments,
|
|
877
|
-
)
|
|
878
391
|
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
)
|
|
884
|
-
|
|
392
|
+
if (response.rejectedDocuments?.length > 0) {
|
|
393
|
+
console.log('❌ Documents rejected:', response.rejectedDocuments.length)
|
|
394
|
+
response.rejectedDocuments.forEach((doc, index) => {
|
|
395
|
+
console.log(` Document ${index + 1}:`, doc.invoiceCodeNumber)
|
|
396
|
+
if (doc.error) {
|
|
397
|
+
console.log(` Error:`, doc.error.message)
|
|
398
|
+
if (doc.error.details) {
|
|
399
|
+
doc.error.details.forEach((detail, detailIndex) => {
|
|
400
|
+
console.log(` Detail ${detailIndex + 1}:`, detail.message)
|
|
401
|
+
})
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
})
|
|
885
405
|
}
|
|
886
406
|
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
expect(submissionResponse.submissionUid).not.toBeNull()
|
|
890
|
-
|
|
407
|
+
// Get submission status
|
|
408
|
+
console.log('📊 Checking submission status...')
|
|
891
409
|
const submission = await client.getSubmissionStatus(
|
|
892
|
-
|
|
410
|
+
response.submissionUid,
|
|
893
411
|
)
|
|
894
|
-
console.log('Submission:', submission)
|
|
412
|
+
console.log('Submission status:', submission?.status)
|
|
413
|
+
|
|
895
414
|
expect(submission).toBeDefined()
|
|
896
|
-
expect(
|
|
415
|
+
expect(['InProgress', 'Valid', 'PartiallyValid', 'Invalid']).toContain(
|
|
416
|
+
submission?.status,
|
|
417
|
+
)
|
|
897
418
|
} catch (error: any) {
|
|
898
|
-
console.error('
|
|
419
|
+
console.error('💥 Submission failed:', error)
|
|
899
420
|
|
|
900
|
-
//
|
|
901
|
-
const errorMessage = error.message || error.toString()
|
|
421
|
+
// Analyze common error types
|
|
902
422
|
if (
|
|
903
|
-
|
|
423
|
+
error.message?.includes(
|
|
904
424
|
'authenticated TIN and documents TIN is not matching',
|
|
905
425
|
)
|
|
906
426
|
) {
|
|
907
|
-
console.log('\n
|
|
908
|
-
console.log(
|
|
427
|
+
console.log('\n🔍 TIN MISMATCH ERROR DETECTED!')
|
|
428
|
+
console.log(
|
|
429
|
+
'This means the TIN in the certificate does not match the TIN in the invoice.',
|
|
430
|
+
)
|
|
431
|
+
console.log(
|
|
432
|
+
'The certificate is registered to a different TIN in MyInvois system.',
|
|
433
|
+
)
|
|
434
|
+
console.log(
|
|
435
|
+
'Solution: Get the correct TIN for your certificate or get a certificate for your TIN.',
|
|
436
|
+
)
|
|
437
|
+
} else if (error.message?.includes('Invalid structure')) {
|
|
438
|
+
console.log('\n🔍 INVALID STRUCTURE ERROR DETECTED!')
|
|
439
|
+
console.log('This could be due to:')
|
|
440
|
+
console.log('1. Missing mandatory fields')
|
|
441
|
+
console.log('2. Incorrect field values')
|
|
442
|
+
console.log('3. Wrong data types')
|
|
443
|
+
console.log('4. Business rule violations')
|
|
909
444
|
}
|
|
910
445
|
|
|
911
|
-
|
|
446
|
+
// Re-throw to fail the test
|
|
912
447
|
throw error
|
|
913
448
|
}
|
|
914
|
-
},
|
|
449
|
+
}, 60000) // Extended timeout for API calls
|
|
915
450
|
})
|