@ripwords/myinvois-client 0.1.0 → 0.1.3
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 +111 -0
- package/README.md +128 -4
- package/bun.lock +59 -0
- package/dist/{0X-Yw7mZEro.d.cts → 0X-CTIq3y3a.d.ts} +1 -2
- package/dist/{0X-C4IRh_fJ.d.ts → 0X-Cr3M7hci.d.cts} +1 -1
- package/dist/{1X-D_aUVsuM.d.cts → 1X-Bu4oiv8D.d.ts} +1 -2
- package/dist/{1X-C-_KHV-Q.d.ts → 1X-BywXCqtn.d.ts} +1 -2
- package/dist/{1X-Brnls9Jh.d.ts → 1X-CWwmfCzo.d.cts} +1 -1
- package/dist/{1X-BwpSoT3o.d.cts → 1X-ClnJ79HH.d.cts} +1 -1
- package/dist/{2X-DkS1BoE5.d.ts → 2X-3fSEGIuE.d.ts} +1 -2
- package/dist/{2X-Bb6elyzV.d.cts → 2X-CV9eYhog.d.cts} +1 -1
- package/dist/{2X-UdQcQW24.d.ts → 2X-DNtkJ0tj.d.cts} +1 -1
- package/dist/{2X-hClUyw26.d.cts → 2X-DnG3FY1f.d.ts} +1 -2
- package/dist/{3X-C7VFD-n-.d.cts → 3X--VWVsC84.d.cts} +1 -1
- package/dist/{3X-CLMESDvz.d.cts → 3X-BOxfatu3.d.cts} +1 -1
- package/dist/{3X-DVDyspgb.d.ts → 3X-CLdmoel1.d.ts} +1 -2
- package/dist/{3X-DFI-4RQQ.d.ts → 3X-Ynjfgoll.d.ts} +1 -2
- package/dist/{4X-DIfvpU6V.d.cts → 4X-B5ePdMky.d.ts} +1 -2
- package/dist/{4X-CvScPJTf.d.cts → 4X-BTG6o1Gn.d.ts} +1 -2
- package/dist/{4X-CIJ2JJ2w.d.ts → 4X-By9PzHaY.d.cts} +1 -1
- package/dist/{4X-CUR8jlaZ.d.ts → 4X-C7fzDWJ_.d.cts} +1 -1
- package/dist/{5X-BOUxhadJ.d.cts → 5X-B5M0Cv_K.d.cts} +1 -1
- package/dist/{5X-C6db432h.d.ts → 5X-CNAFsDm2.d.cts} +1 -1
- package/dist/{5X-CkLu7Vyd.d.cts → 5X-CjSz1zxJ.d.ts} +1 -2
- package/dist/{5X-COsZHUaQ.d.ts → 5X-dhP6fyou.d.ts} +1 -2
- package/dist/{6X-Mf32k1d0.d.cts → 6X-B9KP_vEn.d.ts} +1 -2
- package/dist/{6X-DE7RJeV6.d.cts → 6X-BHaY0TCf.d.ts} +1 -2
- package/dist/{6X-ClZDKOTC.d.ts → 6X-C3elgd-n.d.cts} +1 -1
- package/dist/{6X-C_fFIcJC.d.ts → 6X-uObUP4VG.d.cts} +1 -1
- package/dist/{7X-DoCUcp-J.d.cts → 7X-BifJnY24.d.cts} +1 -1
- package/dist/{7X-Chtd6B66.d.cts → 7X-C4eX_tAk.d.ts} +1 -2
- package/dist/{7X-BZyesooz.d.ts → 7X-D3idQBl9.d.cts} +1 -1
- package/dist/{7X-kot_VccM.d.ts → 7X-DtkQutx2.d.ts} +1 -2
- package/dist/{8X-Dr9RunRw.d.cts → 8X-5n9seY3z.d.ts} +1 -2
- package/dist/{8X-DkuKAkHz.d.ts → 8X-C6UMFvQW.d.cts} +1 -1
- package/dist/{8X-DqZyMvyV.d.cts → 8X-D6HTLShY.d.ts} +1 -2
- package/dist/{8X-Df4DOBOe.d.ts → 8X-DioBXCJ0.d.cts} +1 -1
- package/dist/{9X-BaoZtjWF.d.cts → 9X-BjffnXuq.d.cts} +1 -1
- package/dist/{9X-BDgifncF.d.ts → 9X-CHZKsIdD.d.ts} +1 -2
- package/dist/{9X-BcAb6Uso.d.cts → 9X-CJjPJgIG.d.cts} +1 -1
- package/dist/{9X-BhBWlgxG.d.ts → 9X-Cpb6V4JC.d.ts} +1 -2
- package/dist/{AX-D6XHWdrY.d.ts → AX-C0w_r3PA.d.ts} +1 -2
- package/dist/{AX-BY72FohC.d.cts → AX-DrEd2Ov6.d.cts} +1 -1
- package/dist/{BX-D_0C8Qbd.d.ts → BX-C5jc6myN.d.cts} +1 -1
- package/dist/{BX-CA0OmrUZ.d.cts → BX-RadlZ-6m.d.ts} +1 -2
- package/dist/{CX-glpQSL8x.d.cts → CX-CT1Zzb9D.d.ts} +1 -2
- package/dist/{CX-HH4cSZRX.d.ts → CX-oSgvmn3h.d.cts} +1 -1
- package/dist/{DX-Dx22ax_I.d.ts → DX-CtUeTKMM.d.ts} +1 -2
- package/dist/{DX-DimL1MDM.d.cts → DX-ZIG0enmK.d.cts} +1 -1
- package/dist/{EX-BRWh1wFc.d.ts → EX-084Yu7Wt.d.ts} +1 -2
- package/dist/{EX-Cx87Ruxl.d.cts → EX-BpWZ5ADq.d.cts} +1 -1
- package/dist/{FX-RmjwAr40.d.ts → FX-BrbQM0CW.d.ts} +1 -2
- package/dist/{FX-D81UlxNN.d.cts → FX-CvYBEc51.d.cts} +1 -1
- package/dist/{GX-CJyo7oDp.d.ts → GX-CU8PZy0G.d.cts} +1 -1
- package/dist/{GX-9i7piP9G.d.cts → GX-gKj8iAAh.d.ts} +1 -2
- package/dist/{HX-XALBTdLA.d.ts → HX-9D-ZXTy5.d.ts} +1 -2
- package/dist/{HX-20GVJAvl.d.cts → HX-DoEErDeE.d.cts} +1 -1
- package/dist/{IX-D54NGPsc.d.cts → IX-DR4Fc92A.d.ts} +1 -2
- package/dist/{IX-6SZ55QKb.d.ts → IX-jLAUHe8i.d.cts} +1 -1
- package/dist/{JX-hQ1XRmLp.d.ts → JX-DIKa9ma-.d.ts} +1 -2
- package/dist/{JX-C1RYcwQX.d.cts → JX-DX8BjYQC.d.cts} +1 -1
- package/dist/{KX-BNwunEfn.d.ts → KX-DpsJ_unT.d.ts} +1 -2
- package/dist/{KX-gQHCIgtQ.d.cts → KX-fZb4_vhw.d.cts} +1 -1
- package/dist/{LX-CHYX3X3J.d.ts → LX-D_mI1bk-.d.cts} +1 -1
- package/dist/{LX-CPurJGIh.d.cts → LX-DeXPPWUX.d.ts} +1 -2
- package/dist/{MX-BnyW5eHf.d.cts → MX-CKMjg_zK.d.ts} +1 -2
- package/dist/{MX-BPGLWSUz.d.ts → MX-DlYZhpkT.d.cts} +1 -1
- package/dist/{NX-B11fQuco.d.cts → NX-DELEEbad.d.cts} +1 -1
- package/dist/{NX-RulN5Ml3.d.ts → NX-oYdb4NDo.d.ts} +1 -2
- package/dist/{OX-T-ydRXQS.d.cts → OX-Bid9es3D.d.ts} +1 -2
- package/dist/{OX-DgKVSp7I.d.ts → OX-CKPyrIFf.d.cts} +1 -1
- package/dist/{PX-DA4A2kEv.d.ts → PX-D7jy9CFk.d.ts} +1 -2
- package/dist/{PX-p0n1SzvU.d.cts → PX-SP6NxBtG.d.cts} +1 -1
- package/dist/{QX-DrFqsMEs.d.ts → QX-BFWOR4g3.d.ts} +1 -2
- package/dist/{QX-CI1NccIB.d.cts → QX-QZA7E2O-.d.cts} +1 -1
- package/dist/{RX-Cm7vFcFN.d.ts → RX-DBcgbdeE.d.cts} +1 -1
- package/dist/{RX-DnNKol22.d.cts → RX-XHgCyMV1.d.ts} +1 -2
- package/dist/{SX-CsPPTu-W.d.ts → SX-Cl8RN8oH.d.ts} +1 -2
- package/dist/{SX-BUjiWQYz.d.cts → SX-DmiJeCMN.d.cts} +1 -1
- package/dist/{TX-DCY25MdR.d.ts → TX-C1SoDobK.d.cts} +1 -1
- package/dist/{TX-DOEpsf05.d.cts → TX-ZymoIbtr.d.ts} +1 -2
- package/dist/{UX-DgUOnTFK.d.cts → UX-D-Ndd1ov.d.ts} +1 -2
- package/dist/{UX-DauyagHy.d.ts → UX-DFVynFhQ.d.cts} +1 -1
- package/dist/{VX-kUX6LM-3.d.cts → VX-B-1b34r7.d.ts} +1 -2
- package/dist/{VX-DD4scgCe.d.ts → VX-DsRum5k3.d.cts} +1 -1
- package/dist/{WX-DPfyPFFh.d.cts → WX-0GuMjPNZ.d.ts} +1 -2
- package/dist/{WX-CjkoppdY.d.ts → WX-VReU5R5M.d.cts} +1 -1
- package/dist/{XX-C4C1gQZH.d.cts → XX-CF2NANsy.d.ts} +1 -2
- package/dist/{XX-sbsIUOnA.d.ts → XX-ChAviUMj.d.cts} +1 -1
- package/dist/{YX-DUdO8mRC.d.ts → YX-B51BbNSg.d.ts} +1 -2
- package/dist/{YX-BeT-LsiA.d.cts → YX-QfzeMEKx.d.cts} +1 -1
- package/dist/{ZX-DwfcSA-D.d.ts → ZX-BMJS1iAv.d.ts} +1 -2
- package/dist/{ZX-BuVTTq-D.d.cts → ZX-Ca2E726a.d.cts} +1 -1
- 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-CARHiGdp.cjs +472 -0
- package/dist/document-CARHiGdp.cjs.map +1 -0
- package/dist/document-D6VKMAtx.js +405 -0
- package/dist/documents-CJ8hqIGH.d.ts +858 -0
- package/dist/documents-MGs0EvXh.d.cts +859 -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 +203 -59
- package/dist/index21.cjs.map +1 -1
- package/dist/index22.cjs +104 -262
- package/dist/index22.cjs.map +1 -1
- package/dist/index23.cjs +132 -74
- package/dist/index23.cjs.map +1 -1
- package/dist/index24.cjs +59 -102
- package/dist/index24.cjs.map +1 -1
- package/dist/index25.cjs +262 -68
- package/dist/index25.cjs.map +1 -1
- package/dist/index26.cjs +74 -107
- package/dist/index26.cjs.map +1 -1
- package/dist/index27.cjs +102 -95
- package/dist/index27.cjs.map +1 -1
- package/dist/index28.cjs +68 -13
- package/dist/index28.cjs.map +1 -1
- package/dist/index29.cjs +107 -33
- package/dist/index29.cjs.map +1 -1
- package/dist/index30.cjs +95 -14
- package/dist/index30.cjs.map +1 -1
- package/dist/index31.cjs +11 -22
- package/dist/index31.cjs.map +1 -1
- package/dist/index32.cjs +31 -13
- package/dist/index32.cjs.map +1 -1
- package/dist/index33.cjs +12 -7
- package/dist/index33.cjs.map +1 -1
- package/dist/index34.cjs +22 -7
- package/dist/index34.cjs.map +1 -1
- package/dist/index35.cjs +13 -10
- package/dist/index35.cjs.map +1 -1
- package/dist/index36.cjs +7 -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 +10 -106
- package/dist/index38.cjs.map +1 -1
- package/dist/index39.cjs +6 -119
- package/dist/index39.cjs.map +1 -1
- package/dist/index40.cjs +101 -106
- package/dist/index40.cjs.map +1 -1
- package/dist/index41.cjs +106 -98
- package/dist/index41.cjs.map +1 -1
- package/dist/index42.cjs +119 -118
- package/dist/index42.cjs.map +1 -1
- package/dist/index43.cjs +106 -127
- package/dist/index43.cjs.map +1 -1
- package/dist/index44.cjs +98 -117
- package/dist/index44.cjs.map +1 -1
- package/dist/index45.cjs +118 -14
- package/dist/index45.cjs.map +1 -1
- package/dist/index46.cjs +127 -95
- package/dist/index46.cjs.map +1 -1
- package/dist/index47.cjs +117 -142
- package/dist/index47.cjs.map +1 -1
- package/dist/index48.cjs +14 -114
- package/dist/index48.cjs.map +1 -1
- package/dist/index49.cjs +95 -144
- package/dist/index49.cjs.map +1 -1
- package/dist/index5.cjs +0 -25
- package/dist/index50.cjs +142 -113
- package/dist/index50.cjs.map +1 -1
- package/dist/index51.cjs +114 -17
- package/dist/index51.cjs.map +1 -1
- package/dist/index52.cjs +144 -112
- package/dist/index52.cjs.map +1 -1
- package/dist/index53.cjs +113 -47
- package/dist/index53.cjs.map +1 -1
- package/dist/index54.cjs +17 -14
- package/dist/index54.cjs.map +1 -1
- package/dist/index55.cjs +112 -28
- package/dist/index55.cjs.map +1 -1
- package/dist/index56.cjs +47 -22
- package/dist/index56.cjs.map +1 -1
- package/dist/index57.cjs +14 -9
- package/dist/index57.cjs.map +1 -1
- package/dist/index58.cjs +28 -8
- package/dist/index58.cjs.map +1 -1
- package/dist/index58.cts.map +1 -0
- package/dist/index59.cjs +22 -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 +9 -412
- package/dist/index60.cjs.map +1 -1
- package/dist/index60.cts.map +1 -0
- package/dist/index61.cjs +8 -8
- package/dist/index61.cjs.map +1 -1
- package/dist/index61.cts.map +1 -0
- package/dist/index62.cjs +17 -9
- package/dist/index62.cjs.map +1 -1
- package/dist/index62.cts.map +1 -1
- package/dist/index63.cjs +419 -0
- package/dist/index63.cjs.map +1 -0
- package/dist/index63.cts.map +1 -1
- package/dist/index64.cjs +15 -0
- package/dist/index64.cjs.map +1 -0
- package/dist/index64.cts.map +1 -1
- package/dist/index65.cjs +10 -116
- package/dist/index65.cjs.map +1 -1
- package/dist/index65.cts.map +1 -1
- package/dist/index66.cjs +2 -228
- 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-C8PJVOaA.d.ts +25 -0
- package/dist/{msic-codes-B_1W6lZF.d.cts → msic-codes-CIKdPqag.d.cts} +11 -11
- package/dist/{payment-modes-DHihrywe.d.cts → payment-modes-BOTSRC_X.d.ts} +1 -2
- package/dist/{payment-modes-B8dNy3SM.d.ts → payment-modes-ghFEXnUl.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-W-_brwdb.d.ts} +1 -2
- package/dist/{signatures-BKi9DP2K.d.cts → signatures-hFbt_std.d.cts} +1 -1
- package/dist/{state-codes-DXSWtE6a.d.cts → state-codes-BlILGZ9d.d.cts} +1 -1
- package/dist/{state-codes-CxG1S9YY.d.ts → state-codes-oeFKlwXZ.d.ts} +1 -2
- package/dist/{tax-types-CgwxONDS.d.cts → tax-types-B5sQ8UyN.d.cts} +1 -1
- package/dist/{tax-types-CEpfSh5P.d.ts → tax-types-CsQ76JMf.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 +18 -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-B41YFOLT.d.ts +55 -0
- package/dist/unit-types-CjWNk2wS.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 +870 -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 +451 -0
- package/test/signAndSubmitInvoice.test.ts +271 -734
- package/test/signature-diagnostics.test.ts +130 -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/index66.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,98 @@
|
|
|
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
|
},
|
|
47
|
+
industryClassificationCode: '41001',
|
|
48
|
+
industryClassificationDescription: 'Test Industry',
|
|
88
49
|
},
|
|
89
50
|
|
|
51
|
+
// === BUYER (using consolidated buyer for testing) ===
|
|
90
52
|
buyer: {
|
|
91
|
-
name: '
|
|
92
|
-
tin: 'EI00000000010',
|
|
93
|
-
|
|
53
|
+
name: 'CONSOLIDATED E-INVOICE BUYER',
|
|
54
|
+
tin: 'EI00000000010', // Standard consolidated buyer TIN
|
|
55
|
+
registrationType: 'NRIC',
|
|
56
|
+
registrationNumber: process.env.NRIC_VALUE!,
|
|
94
57
|
sstRegistrationNumber: 'NA',
|
|
95
|
-
|
|
96
|
-
contactNumber: 'NA',
|
|
58
|
+
contactNumber: '+60123456789', // Valid phone number (minimum 8 chars)
|
|
97
59
|
address: {
|
|
98
60
|
addressLine0: 'NA',
|
|
99
|
-
|
|
100
|
-
addressLine2: 'NA',
|
|
101
|
-
cityName: 'Kuala Lumpur',
|
|
102
|
-
postalZone: '50000',
|
|
61
|
+
cityName: 'KUALA LUMPUR',
|
|
103
62
|
state: '14',
|
|
104
63
|
country: 'MYS',
|
|
105
64
|
},
|
|
106
65
|
},
|
|
107
66
|
|
|
67
|
+
// === SINGLE LINE ITEM (minimal) ===
|
|
108
68
|
invoiceLineItems: [
|
|
109
69
|
{
|
|
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',
|
|
70
|
+
itemClassificationCode: '001', // General goods
|
|
71
|
+
itemDescription: 'Test Product',
|
|
72
|
+
unitPrice: 100.0,
|
|
73
|
+
taxType: '01', // SST
|
|
74
|
+
taxRate: 6.0, // 6% SST
|
|
75
|
+
taxAmount: 6.0, // 6% of 100
|
|
76
|
+
totalTaxableAmountPerLine: 100.0,
|
|
77
|
+
totalAmountPerLine: 106.0, // 100 + 6
|
|
134
78
|
},
|
|
135
79
|
],
|
|
136
80
|
|
|
81
|
+
// === MONETARY TOTALS ===
|
|
137
82
|
legalMonetaryTotal: {
|
|
138
|
-
taxExclusiveAmount:
|
|
139
|
-
taxInclusiveAmount:
|
|
140
|
-
|
|
141
|
-
chargeTotalAmount: 0,
|
|
142
|
-
payableRoundingAmount: 0,
|
|
143
|
-
payableAmount: 33000,
|
|
83
|
+
taxExclusiveAmount: 100.0,
|
|
84
|
+
taxInclusiveAmount: 106.0,
|
|
85
|
+
payableAmount: 106.0,
|
|
144
86
|
},
|
|
145
87
|
|
|
88
|
+
// === TAX TOTAL ===
|
|
146
89
|
taxTotal: {
|
|
147
|
-
taxAmount:
|
|
148
|
-
taxSubtotals: [
|
|
149
|
-
{
|
|
150
|
-
taxableAmount: 30000,
|
|
151
|
-
taxAmount: 3000,
|
|
152
|
-
taxCategory: {
|
|
153
|
-
taxTypeCode: '01',
|
|
154
|
-
taxRate: 10.0,
|
|
155
|
-
},
|
|
156
|
-
},
|
|
157
|
-
],
|
|
90
|
+
taxAmount: 6.0,
|
|
158
91
|
},
|
|
159
92
|
|
|
160
|
-
|
|
161
|
-
{
|
|
162
|
-
paymentMeansCode: '01',
|
|
163
|
-
payeeFinancialAccountID: '1234567890',
|
|
164
|
-
},
|
|
165
|
-
],
|
|
166
|
-
|
|
93
|
+
// === DIGITAL SIGNATURE (placeholder - will be populated by signing process) ===
|
|
167
94
|
issuerDigitalSignature: {
|
|
168
|
-
Id: '
|
|
95
|
+
Id: 'signature',
|
|
169
96
|
'ds:SignedInfo': {
|
|
170
97
|
'ds:CanonicalizationMethod': {
|
|
171
98
|
Algorithm: 'http://www.w3.org/2006/12/xml-c14n11',
|
|
@@ -183,6 +110,7 @@ const createTestInvoiceData = (): InvoiceV1_1 => {
|
|
|
183
110
|
'ds:DigestValue': '',
|
|
184
111
|
},
|
|
185
112
|
{
|
|
113
|
+
Id: 'id-xades-signed-props',
|
|
186
114
|
URI: '#id-xades-signed-props',
|
|
187
115
|
'ds:DigestMethod': {
|
|
188
116
|
Algorithm: 'http://www.w3.org/2001/04/xmlenc#sha256',
|
|
@@ -227,689 +155,298 @@ const createTestInvoiceData = (): InvoiceV1_1 => {
|
|
|
227
155
|
}
|
|
228
156
|
}
|
|
229
157
|
|
|
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()
|
|
158
|
+
describe('MyInvois Document Generation and Submission', () => {
|
|
159
|
+
const requiredEnvVars = [
|
|
160
|
+
'CLIENT_ID',
|
|
161
|
+
'CLIENT_SECRET',
|
|
162
|
+
'TEST_PRIVATE_KEY',
|
|
163
|
+
'TEST_CERTIFICATE',
|
|
164
|
+
]
|
|
250
165
|
|
|
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
|
-
}
|
|
166
|
+
// Check environment variables
|
|
167
|
+
const missingVars = requiredEnvVars.filter(varName => !process.env[varName])
|
|
284
168
|
|
|
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 ? '✅' : '❌'}`,
|
|
169
|
+
if (missingVars.length > 0) {
|
|
170
|
+
it.skip(`Skipping tests - Missing environment variables: ${missingVars.join(', ')}`, () => {
|
|
171
|
+
expect
|
|
172
|
+
.soft(
|
|
173
|
+
false,
|
|
174
|
+
`Missing required environment variables: ${missingVars.join(', ')}`,
|
|
305
175
|
)
|
|
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()
|
|
176
|
+
.toBe(true)
|
|
360
177
|
})
|
|
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()
|
|
178
|
+
return
|
|
179
|
+
}
|
|
383
180
|
|
|
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
|
-
})
|
|
181
|
+
const CLIENT_ID = process.env.CLIENT_ID!
|
|
182
|
+
const CLIENT_SECRET = process.env.CLIENT_SECRET!
|
|
183
|
+
const PRIVATE_KEY = process.env.TEST_PRIVATE_KEY!
|
|
184
|
+
const CERTIFICATE = process.env.TEST_CERTIFICATE!
|
|
403
185
|
|
|
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
|
-
})
|
|
186
|
+
it('should extract certificate information correctly', () => {
|
|
187
|
+
console.log('🔍 Extracting certificate information...')
|
|
420
188
|
|
|
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
|
-
}
|
|
189
|
+
const certInfo = extractCertificateInfo(CERTIFICATE)
|
|
429
190
|
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
191
|
+
console.log('Certificate Info:', {
|
|
192
|
+
issuerName: certInfo.issuerName,
|
|
193
|
+
serialNumber: certInfo.serialNumber,
|
|
433
194
|
})
|
|
434
195
|
|
|
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
|
-
})
|
|
196
|
+
expect(certInfo.issuerName).toBeDefined()
|
|
197
|
+
expect(certInfo.serialNumber).toBeDefined()
|
|
198
|
+
expect(typeof certInfo.issuerName).toBe('string')
|
|
199
|
+
expect(typeof certInfo.serialNumber).toBe('string')
|
|
462
200
|
})
|
|
463
201
|
|
|
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()
|
|
202
|
+
it('should find TIN that matches certificate', async () => {
|
|
203
|
+
console.log('🔐 Finding TIN that matches certificate...')
|
|
478
204
|
|
|
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)
|
|
205
|
+
const client = new MyInvoisClient(
|
|
206
|
+
CLIENT_ID,
|
|
207
|
+
CLIENT_SECRET,
|
|
208
|
+
'sandbox',
|
|
209
|
+
CERTIFICATE,
|
|
210
|
+
PRIVATE_KEY,
|
|
211
|
+
undefined,
|
|
212
|
+
true, // debug mode
|
|
213
|
+
)
|
|
567
214
|
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
215
|
+
// Test TIN formats that might match the certificate
|
|
216
|
+
// Note: These are example TIN formats - replace with your actual test TINs
|
|
217
|
+
const testTINs = [
|
|
218
|
+
process.env.TIN_VALUE, // Environment variable if set
|
|
219
|
+
process.env.TEST_TIN_1, // Additional test TIN from environment
|
|
220
|
+
process.env.TEST_TIN_2, // Additional test TIN from environment
|
|
221
|
+
process.env.TEST_TIN_3, // Additional test TIN from environment
|
|
222
|
+
'EI00000000010', // Consolidated buyer (shouldn't work for supplier)
|
|
223
|
+
].filter(Boolean) // Remove undefined values
|
|
224
|
+
|
|
225
|
+
let certificateMatchingTIN: string | null = null
|
|
226
|
+
const validTINs: string[] = []
|
|
227
|
+
|
|
228
|
+
// Step 1: Check which TINs are valid in the system
|
|
229
|
+
console.log('📋 Step 1: Checking TIN validity...')
|
|
230
|
+
for (const tin of testTINs) {
|
|
231
|
+
try {
|
|
232
|
+
console.log(`Testing TIN validity: ${tin}`)
|
|
233
|
+
const isValid = await client.verifyTin(tin!, 'BRN', '123456789012')
|
|
234
|
+
console.log(`TIN ${tin} validity: ${isValid}`)
|
|
572
235
|
|
|
573
|
-
if (
|
|
574
|
-
|
|
575
|
-
xmlValidation.warnings.forEach(warning =>
|
|
576
|
-
console.log(` - ${warning}`),
|
|
577
|
-
)
|
|
236
|
+
if (isValid) {
|
|
237
|
+
validTINs.push(tin!)
|
|
578
238
|
}
|
|
239
|
+
} catch (error) {
|
|
240
|
+
console.log(`❌ Error testing TIN ${tin}:`, error)
|
|
241
|
+
}
|
|
242
|
+
}
|
|
579
243
|
|
|
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) + '...')
|
|
244
|
+
console.log(`📊 Found ${validTINs.length} valid TINs:`, validTINs)
|
|
589
245
|
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
246
|
+
// Step 2: Test each valid TIN with a minimal document submission to find certificate match
|
|
247
|
+
console.log('📋 Step 2: Testing certificate matching...')
|
|
248
|
+
for (const tin of validTINs) {
|
|
249
|
+
try {
|
|
250
|
+
console.log(`Testing TIN with certificate: ${tin}`)
|
|
593
251
|
|
|
594
|
-
//
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
)
|
|
599
|
-
) {
|
|
600
|
-
commonIssues.push('Missing ext namespace declaration')
|
|
601
|
-
}
|
|
252
|
+
// Create a minimal test invoice with this TIN
|
|
253
|
+
const testInvoice = createMinimalTestInvoice()
|
|
254
|
+
testInvoice.supplier.tin = tin
|
|
255
|
+
testInvoice.eInvoiceCodeOrNumber = `TEST-CERT-${Date.now()}`
|
|
602
256
|
|
|
603
|
-
//
|
|
604
|
-
|
|
605
|
-
commonIssues.push('Missing or incorrect signature target')
|
|
606
|
-
}
|
|
257
|
+
// Try to submit it
|
|
258
|
+
const { status } = await client.submitDocument([testInvoice])
|
|
607
259
|
|
|
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
|
-
)
|
|
260
|
+
if (status === 202) {
|
|
261
|
+
console.log(`✅ SUCCESS! TIN ${tin} works with certificate`)
|
|
262
|
+
certificateMatchingTIN = tin
|
|
263
|
+
break
|
|
264
|
+
} else {
|
|
265
|
+
console.log(`❌ TIN ${tin} failed with status ${status}`)
|
|
626
266
|
}
|
|
627
|
-
|
|
628
|
-
// Check for proper C14N algorithm in XML
|
|
267
|
+
} catch (error: any) {
|
|
629
268
|
if (
|
|
630
|
-
|
|
631
|
-
'
|
|
269
|
+
error.message?.includes(
|
|
270
|
+
'authenticated TIN and documents TIN is not matching',
|
|
632
271
|
)
|
|
633
272
|
) {
|
|
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}`))
|
|
273
|
+
console.log(`❌ TIN ${tin} doesn't match certificate`)
|
|
642
274
|
} else {
|
|
643
|
-
console.log(
|
|
275
|
+
console.log(`❌ TIN ${tin} failed with error:`, error.message)
|
|
644
276
|
}
|
|
645
277
|
}
|
|
278
|
+
}
|
|
646
279
|
|
|
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
|
-
)
|
|
280
|
+
// Store the certificate-matching TIN for next test
|
|
281
|
+
if (certificateMatchingTIN) {
|
|
282
|
+
process.env.VALID_SUPPLIER_TIN = certificateMatchingTIN
|
|
737
283
|
console.log(
|
|
738
|
-
|
|
284
|
+
`🎯 Certificate matching TIN found: ${certificateMatchingTIN}`,
|
|
739
285
|
)
|
|
286
|
+
} else if (validTINs.length > 0) {
|
|
287
|
+
// Fallback to first valid TIN with a warning
|
|
288
|
+
process.env.VALID_SUPPLIER_TIN = validTINs[0]
|
|
740
289
|
console.log(
|
|
741
|
-
|
|
290
|
+
`⚠️ No certificate match found, using first valid TIN: ${validTINs[0]}`,
|
|
742
291
|
)
|
|
743
292
|
console.log(
|
|
744
|
-
|
|
293
|
+
`⚠️ This will likely cause TIN mismatch error in submission test`,
|
|
745
294
|
)
|
|
295
|
+
}
|
|
746
296
|
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
})
|
|
297
|
+
// For now, pass the test if we found any valid TINs (the main goal is to test the implementation)
|
|
298
|
+
expect.soft(validTINs.length, 'No valid TINs found').toBeGreaterThan(0)
|
|
299
|
+
}, 60000) // Increased timeout for multiple submissions
|
|
751
300
|
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
debugResults.recommendations.forEach(rec => console.log(` ${rec}`))
|
|
755
|
-
}
|
|
301
|
+
it('should generate valid document structure', () => {
|
|
302
|
+
console.log('📄 Generating document structure...')
|
|
756
303
|
|
|
757
|
-
|
|
758
|
-
const methodResults = await testSubmissionHashMethods(
|
|
759
|
-
invoiceData,
|
|
760
|
-
signingCredentials,
|
|
761
|
-
)
|
|
304
|
+
const invoice = createMinimalTestInvoice()
|
|
762
305
|
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
306
|
+
// Use the valid TIN from previous test or fallback
|
|
307
|
+
const supplierTIN =
|
|
308
|
+
process.env.VALID_SUPPLIER_TIN || process.env.TIN_VALUE || 'C00000000000' // Replace with your TIN
|
|
309
|
+
invoice.supplier.tin = supplierTIN
|
|
767
310
|
|
|
768
|
-
|
|
769
|
-
console.log('\n🔧 METHOD RECOMMENDATIONS:')
|
|
770
|
-
methodResults.recommendations.forEach(rec => console.log(` ${rec}`))
|
|
771
|
-
}
|
|
311
|
+
console.log(`Using supplier TIN: ${supplierTIN}`)
|
|
772
312
|
|
|
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
|
-
}
|
|
313
|
+
const certInfo = extractCertificateInfo(CERTIFICATE)
|
|
782
314
|
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
315
|
+
const document = generateCompleteDocument([invoice], {
|
|
316
|
+
privateKeyPem: PRIVATE_KEY,
|
|
317
|
+
certificatePem: CERTIFICATE,
|
|
318
|
+
issuerName: certInfo.issuerName,
|
|
319
|
+
serialNumber: certInfo.serialNumber,
|
|
320
|
+
})
|
|
789
321
|
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
322
|
+
console.log('Generated document structure:')
|
|
323
|
+
console.log(
|
|
324
|
+
'- Namespace declarations:',
|
|
325
|
+
Object.keys(document).filter(k => k.startsWith('_')),
|
|
326
|
+
)
|
|
327
|
+
console.log('- Number of invoices:', document.Invoice.length)
|
|
328
|
+
console.log('- First invoice keys:', Object.keys(document.Invoice[0]))
|
|
329
|
+
console.log('- Has UBLExtensions:', !!document.Invoice[0].UBLExtensions)
|
|
330
|
+
console.log('- Has Signature:', !!document.Invoice[0].Signature)
|
|
331
|
+
|
|
332
|
+
// Basic structure validation
|
|
333
|
+
expect(document._D).toBe(
|
|
334
|
+
'urn:oasis:names:specification:ubl:schema:xsd:Invoice-2',
|
|
335
|
+
)
|
|
336
|
+
expect(document._A).toBe(
|
|
337
|
+
'urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2',
|
|
338
|
+
)
|
|
339
|
+
expect(document._B).toBe(
|
|
340
|
+
'urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2',
|
|
341
|
+
)
|
|
342
|
+
expect(document.Invoice).toHaveLength(1)
|
|
343
|
+
expect(document.Invoice[0].UBLExtensions).toBeDefined()
|
|
344
|
+
expect(document.Invoice[0].Signature).toBeDefined()
|
|
801
345
|
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
346
|
+
// Store document for next test
|
|
347
|
+
;(globalThis as any).testDocument = document
|
|
348
|
+
;(globalThis as any).testInvoice = invoice
|
|
805
349
|
})
|
|
806
|
-
})
|
|
807
350
|
|
|
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
|
-
}
|
|
351
|
+
it('should submit document to MyInvois successfully', async () => {
|
|
352
|
+
console.log('🚀 Submitting document to MyInvois...')
|
|
822
353
|
|
|
823
|
-
const
|
|
824
|
-
const
|
|
354
|
+
const document = (globalThis as any).testDocument
|
|
355
|
+
const invoice = (globalThis as any).testInvoice
|
|
825
356
|
|
|
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
|
|
357
|
+
if (!document || !invoice) {
|
|
358
|
+
throw new Error('Document not generated in previous test')
|
|
837
359
|
}
|
|
838
360
|
|
|
839
|
-
const invoiceData = createTestInvoiceData()
|
|
840
|
-
|
|
841
361
|
const client = new MyInvoisClient(
|
|
842
|
-
|
|
843
|
-
|
|
362
|
+
CLIENT_ID,
|
|
363
|
+
CLIENT_SECRET,
|
|
844
364
|
'sandbox',
|
|
365
|
+
CERTIFICATE,
|
|
366
|
+
PRIVATE_KEY,
|
|
845
367
|
undefined,
|
|
846
|
-
true,
|
|
368
|
+
true, // debug mode
|
|
847
369
|
)
|
|
848
370
|
|
|
849
|
-
// 2. Submit Document
|
|
850
371
|
try {
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
console.log(
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
)
|
|
372
|
+
console.log('📤 Submitting to MyInvois API...')
|
|
373
|
+
console.log('Document size:', JSON.stringify(document).length, 'bytes')
|
|
374
|
+
|
|
375
|
+
const { data: response, status } = await client.submitDocument([invoice])
|
|
376
|
+
|
|
377
|
+
console.log('📥 Response received:')
|
|
378
|
+
console.log('Status:', status)
|
|
379
|
+
console.log('Response:', JSON.stringify(response, null, 2))
|
|
380
|
+
|
|
381
|
+
// Validate response structure
|
|
382
|
+
expect(status).toBe(202) // MyInvois returns 202 Accepted
|
|
383
|
+
expect(response.submissionUid).toBeDefined()
|
|
384
|
+
expect(typeof response.submissionUid).toBe('string')
|
|
385
|
+
|
|
386
|
+
// Check for accepted/rejected documents
|
|
387
|
+
if (response.acceptedDocuments?.length > 0) {
|
|
388
|
+
console.log('✅ Documents accepted:', response.acceptedDocuments.length)
|
|
389
|
+
response.acceptedDocuments.forEach((doc, index) => {
|
|
390
|
+
console.log(` Document ${index + 1}:`, doc.invoiceCodeNumber)
|
|
391
|
+
})
|
|
869
392
|
}
|
|
870
|
-
if (
|
|
871
|
-
submissionResponse.rejectedDocuments &&
|
|
872
|
-
submissionResponse.rejectedDocuments.length > 0
|
|
873
|
-
) {
|
|
874
|
-
console.warn(
|
|
875
|
-
'Rejected Documents:',
|
|
876
|
-
submissionResponse.rejectedDocuments,
|
|
877
|
-
)
|
|
878
393
|
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
)
|
|
884
|
-
|
|
394
|
+
if (response.rejectedDocuments?.length > 0) {
|
|
395
|
+
console.log('❌ Documents rejected:', response.rejectedDocuments.length)
|
|
396
|
+
response.rejectedDocuments.forEach((doc, index) => {
|
|
397
|
+
console.log(` Document ${index + 1}:`, doc.invoiceCodeNumber)
|
|
398
|
+
if (doc.error) {
|
|
399
|
+
console.log(` Error:`, doc.error.message)
|
|
400
|
+
if (doc.error.details) {
|
|
401
|
+
doc.error.details.forEach((detail, detailIndex) => {
|
|
402
|
+
console.log(` Detail ${detailIndex + 1}:`, detail.message)
|
|
403
|
+
})
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
})
|
|
885
407
|
}
|
|
886
408
|
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
expect(submissionResponse.submissionUid).not.toBeNull()
|
|
890
|
-
|
|
409
|
+
// Get submission status
|
|
410
|
+
console.log('📊 Checking submission status...')
|
|
891
411
|
const submission = await client.getSubmissionStatus(
|
|
892
|
-
|
|
412
|
+
response.submissionUid,
|
|
893
413
|
)
|
|
894
|
-
console.log('Submission:', submission)
|
|
414
|
+
console.log('Submission status:', submission?.status)
|
|
415
|
+
|
|
895
416
|
expect(submission).toBeDefined()
|
|
896
|
-
expect(
|
|
417
|
+
expect(['InProgress', 'Valid', 'PartiallyValid', 'Invalid']).toContain(
|
|
418
|
+
submission?.status,
|
|
419
|
+
)
|
|
897
420
|
} catch (error: any) {
|
|
898
|
-
console.error('
|
|
421
|
+
console.error('💥 Submission failed:', error)
|
|
899
422
|
|
|
900
|
-
//
|
|
901
|
-
const errorMessage = error.message || error.toString()
|
|
423
|
+
// Analyze common error types
|
|
902
424
|
if (
|
|
903
|
-
|
|
425
|
+
error.message?.includes(
|
|
904
426
|
'authenticated TIN and documents TIN is not matching',
|
|
905
427
|
)
|
|
906
428
|
) {
|
|
907
|
-
console.log('\n
|
|
908
|
-
console.log(
|
|
429
|
+
console.log('\n🔍 TIN MISMATCH ERROR DETECTED!')
|
|
430
|
+
console.log(
|
|
431
|
+
'This means the TIN in the certificate does not match the TIN in the invoice.',
|
|
432
|
+
)
|
|
433
|
+
console.log(
|
|
434
|
+
'The certificate is registered to a different TIN in MyInvois system.',
|
|
435
|
+
)
|
|
436
|
+
console.log(
|
|
437
|
+
'Solution: Get the correct TIN for your certificate or get a certificate for your TIN.',
|
|
438
|
+
)
|
|
439
|
+
} else if (error.message?.includes('Invalid structure')) {
|
|
440
|
+
console.log('\n🔍 INVALID STRUCTURE ERROR DETECTED!')
|
|
441
|
+
console.log('This could be due to:')
|
|
442
|
+
console.log('1. Missing mandatory fields')
|
|
443
|
+
console.log('2. Incorrect field values')
|
|
444
|
+
console.log('3. Wrong data types')
|
|
445
|
+
console.log('4. Business rule violations')
|
|
909
446
|
}
|
|
910
447
|
|
|
911
|
-
|
|
448
|
+
// Re-throw to fail the test
|
|
912
449
|
throw error
|
|
913
450
|
}
|
|
914
|
-
},
|
|
451
|
+
}, 60000) // Extended timeout for API calls
|
|
915
452
|
})
|