{"_id":"@waffo/waffo-node","_rev":"20-1776ecf7304edbf8fefe339fe42cb400","name":"@waffo/waffo-node","dist-tags":{"latest":"3.1.0"},"versions":{"2.0.2":{"name":"@waffo/waffo-node","version":"2.0.2","keywords":["waffo","payment","sdk","nodejs","typescript","ewallet","payment-gateway","rsa","api-client"],"author":{"url":"https://waffo.com","name":"Waffo","email":"support@waffo.com"},"license":"MIT","_id":"@waffo/waffo-node@2.0.2","maintainers":[{"name":"waffo-js","email":"js@waffo.com"},{"name":"hill-waffo","email":"zhaoxuan.hong@waffo.com"},{"name":"tangjiaj","email":"jj@waffo.com"},{"name":"fronzenvista","email":"wuze.wang@waffo.co"}],"homepage":"https://github.com/waffo-com/waffo-node#readme","bugs":{"url":"https://github.com/waffo-com/waffo-node/issues"},"dist":{"shasum":"6a3de3cad0865706bc83a5e9eac409302bd37730","tarball":"https://registry.npmjs.org/@waffo/waffo-node/-/waffo-node-2.0.2.tgz","fileCount":11,"integrity":"sha512-yr2G8ts8G7areUZ4kAIVnBpo/rmqiDLoZSdNRVwIsnobrfORbF5U8MJb2jPy27nIew5xyslE4UwrGNPJ9RUD0g==","signatures":[{"sig":"MEYCIQCYD+e4hJdfPIeoCidhH08OVYE/MAKfyDxCC2Tfn2hYeQIhAMmdvX8+UCHCoWKbNpU0U5CEBNMIkHwQETKTqBnOICTz","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":917914},"main":"./dist/index.js","types":"./dist/index.d.ts","module":"./dist/index.mjs","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"gitHead":"6f5f391af4ceae0a5599cea0017ab5c7f3d204dc","scripts":{"lint":"eslint src","test":"vitest run","build":"tsup","clean":"rm -rf dist","format":"prettier --write \"src/**/*.ts\"","prepare":"husky","lint:fix":"eslint src --fix","test:watch":"vitest","format:check":"prettier --check \"src/**/*.ts\"","test:coverage":"vitest run --coverage","prepublishOnly":"npm run clean && npm run build"},"_npmUser":{"name":"hill-waffo","email":"zhaoxuan.hong@waffo.com"},"repository":{"url":"git+https://github.com/waffo-com/waffo-node.git","type":"git"},"_npmVersion":"10.8.2","description":"Official Node.js SDK for the Waffo payment platform. Supports order management, refunds, and secure RSA-signed API communication.","directories":{},"lint-staged":{"src/**/*.ts":["eslint --fix","prettier --write"]},"_nodeVersion":"20.19.6","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","husky":"^9.1.7","eslint":"^9.39.2","vitest":"^2.1.8","prettier":"^3.7.4","@eslint/js":"^9.39.2","typescript":"^5.9.3","@types/node":"^25.0.3","lint-staged":"^16.2.7","typescript-eslint":"^8.50.1","@vitest/coverage-v8":"^2.1.8","eslint-config-prettier":"^10.1.8","eslint-plugin-prettier":"^5.5.4"},"_npmOperationalInternal":{"tmp":"tmp/waffo-node_2.0.2_1767577940033_0.9413445351222185","host":"s3://npm-registry-packages-npm-production"}},"2.0.3":{"name":"@waffo/waffo-node","version":"2.0.3","keywords":["waffo","payment","sdk","nodejs","typescript","ewallet","payment-gateway","rsa","api-client"],"author":{"url":"https://waffo.com","name":"Waffo","email":"support@waffo.com"},"license":"MIT","_id":"@waffo/waffo-node@2.0.3","maintainers":[{"name":"waffo-js","email":"js@waffo.com"},{"name":"hill-waffo","email":"zhaoxuan.hong@waffo.com"},{"name":"tangjiaj","email":"jj@waffo.com"},{"name":"fronzenvista","email":"wuze.wang@waffo.co"}],"homepage":"https://github.com/waffo-com/waffo-node#readme","bugs":{"url":"https://github.com/waffo-com/waffo-node/issues"},"dist":{"shasum":"6084954277ceb25fd3bef05afe61cc9164ad1ce5","tarball":"https://registry.npmjs.org/@waffo/waffo-node/-/waffo-node-2.0.3.tgz","fileCount":11,"integrity":"sha512-erg/9eVzo9FUDerImcdXqmNVF5ZIAPyNnS5Ijz2+GScLpZH2AndkKxXKsM7jc/ItrX9EndQTLcQ5qTpCOBAXKA==","signatures":[{"sig":"MEUCIQC9j6O9GEqEIgrVJ0aFGKdvksOJLIVw+lKVeDVR9hgYxwIgQ5G95V6oP+WX+9D0dRMxyKjhd2wFvJAiNoVDV9eLTrY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":919631},"main":"./dist/index.js","types":"./dist/index.d.ts","module":"./dist/index.mjs","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"gitHead":"bf28ad41b54ab244de49be1b2be8c7083e637fcd","scripts":{"lint":"eslint src","test":"vitest run","build":"tsup","clean":"rm -rf dist","format":"prettier --write \"src/**/*.ts\"","prepare":"husky","lint:fix":"eslint src --fix","test:watch":"vitest","format:check":"prettier --check \"src/**/*.ts\"","test:coverage":"vitest run --coverage","prepublishOnly":"npm run clean && npm run build"},"_npmUser":{"name":"hill-waffo","email":"zhaoxuan.hong@waffo.com"},"repository":{"url":"git+https://github.com/waffo-com/waffo-node.git","type":"git"},"_npmVersion":"10.8.2","description":"Official Node.js SDK for the Waffo payment platform. Supports order management, refunds, and secure RSA-signed API communication.","directories":{},"lint-staged":{"src/**/*.ts":["eslint --fix","prettier --write"]},"_nodeVersion":"20.19.6","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","husky":"^9.1.7","eslint":"^9.39.2","vitest":"^2.1.8","prettier":"^3.7.4","@eslint/js":"^9.39.2","typescript":"^5.9.3","@types/node":"^25.0.3","lint-staged":"^16.2.7","typescript-eslint":"^8.50.1","@vitest/coverage-v8":"^2.1.8","eslint-config-prettier":"^10.1.8","eslint-plugin-prettier":"^5.5.4"},"_npmOperationalInternal":{"tmp":"tmp/waffo-node_2.0.3_1767780592494_0.6999129826343753","host":"s3://npm-registry-packages-npm-production"}},"2.0.4":{"name":"@waffo/waffo-node","version":"2.0.4","keywords":["waffo","payment","psp","subscription","sdk","ewallet","payment-gateway"],"author":{"name":"Waffo","email":"merchant.support@waffo.com"},"license":"MIT","_id":"@waffo/waffo-node@2.0.4","maintainers":[{"name":"waffo-js","email":"js@waffo.com"},{"name":"hill-waffo","email":"zhaoxuan.hong@waffo.com"},{"name":"tangjiaj","email":"jj@waffo.com"},{"name":"fronzenvista","email":"wuze.wang@waffo.co"}],"homepage":"https://github.com/waffo-com/waffo-sdk/tree/main/packages/waffo-node","bugs":{"url":"https://github.com/waffo-com/waffo-sdk/issues"},"dist":{"shasum":"47d3fff8158c03fb13dceca7d6633243446bcb19","tarball":"https://registry.npmjs.org/@waffo/waffo-node/-/waffo-node-2.0.4.tgz","fileCount":9,"integrity":"sha512-lt+vav6zKqc+Wg2ZO2BSWVynVUAoyCdDcqYmGaAAyMeEv6P80d//vDtPxmA2xkDVNoGtQLXFuZc2/LNgpABspQ==","signatures":[{"sig":"MEYCIQDSvyupSlGLKu1C1PTvf++FaanvwOfxOJD2Z+3H/rbhgQIhAJArc9JEXWOoOdAKCEWkCfplVcmjcP9Wnm8tEzJVBABH","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":427596},"main":"./dist/index.js","types":"./dist/index.d.ts","module":"./dist/index.mjs","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"gitHead":"49f1cb0e44fa9bf8a52931f0c307a79661690a73","scripts":{"dev":"tsup --watch","lint":"eslint src --ext .ts","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"fronzenvista","email":"wuze.wang@waffo.co"},"repository":{"url":"git+https://github.com/waffo-com/waffo-sdk.git","type":"git"},"_npmVersion":"10.8.2","description":"Official Waffo PSP Node.js SDK","directories":{},"_nodeVersion":"20.20.0","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","eslint":"^8.56.0","vitest":"^1.0.0","typescript":"^5.3.0","@types/node":"^20.0.0","@typescript-eslint/parser":"^6.19.0","@typescript-eslint/eslint-plugin":"^6.19.0"},"_npmOperationalInternal":{"tmp":"tmp/waffo-node_2.0.4_1769147520204_0.07092700098011728","host":"s3://npm-registry-packages-npm-production"}},"2.1.0":{"name":"@waffo/waffo-node","version":"2.1.0","keywords":["waffo","payment","psp","subscription","sdk","ewallet","payment-gateway"],"author":{"name":"Waffo","email":"merchant.support@waffo.com"},"license":"MIT","_id":"@waffo/waffo-node@2.1.0","maintainers":[{"name":"waffo-js","email":"js@waffo.com"},{"name":"hill-waffo","email":"zhaoxuan.hong@waffo.com"},{"name":"tangjiaj","email":"jj@waffo.com"},{"name":"fronzenvista","email":"wuze.wang@waffo.co"}],"homepage":"https://github.com/waffo-com/waffo-sdk/tree/main/packages/waffo-node","bugs":{"url":"https://github.com/waffo-com/waffo-sdk/issues"},"dist":{"shasum":"5990be1fd55011c4a093241cf76c4382d531b8ef","tarball":"https://registry.npmjs.org/@waffo/waffo-node/-/waffo-node-2.1.0.tgz","fileCount":9,"integrity":"sha512-Up3mFi2T5+M+i0Tz5VZPOduCjLgIdkdxpbxVLf+1K154lhF9vI7iKtI2p3MiLgwOYQsP9gg97FTwFUyhAkMs5w==","signatures":[{"sig":"MEYCIQCHIrUKPN3WjBAdQmuApTpioprhEBAz3SZAolyBavoZ5AIhAIXNuKvuLTC4HHahcl/4Zo885OGCwtmWDpqmGpWXpQNj","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":413892},"main":"./dist/index.js","types":"./dist/index.d.ts","module":"./dist/index.mjs","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"gitHead":"60e109afdf8280809a990d02209d1d59659c1291","scripts":{"dev":"tsup --watch","lint":"eslint src --ext .ts","test":"vitest run","build":"tsup","test:e2e":"vitest run --config vitest.e2e.config.ts","typecheck":"tsc --noEmit","test:watch":"vitest","test:e2e:ui":"E2E_HEADLESS=false vitest run --config vitest.e2e.config.ts","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"fronzenvista","email":"wuze.wang@waffo.co"},"repository":{"url":"git+https://github.com/waffo-com/waffo-sdk.git","type":"git"},"_npmVersion":"10.8.2","description":"Official Waffo PSP Node.js SDK","directories":{},"_nodeVersion":"20.20.0","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","yaml":"^2.3.0","eslint":"^8.56.0","vitest":"^1.0.0","playwright":"^1.40.0","typescript":"^5.3.0","@types/node":"^20.0.0","@typescript-eslint/parser":"^6.19.0","@typescript-eslint/eslint-plugin":"^6.19.0"},"_npmOperationalInternal":{"tmp":"tmp/waffo-node_2.1.0_1770208406285_0.6938280671677048","host":"s3://npm-registry-packages-npm-production"}},"2.2.0":{"name":"@waffo/waffo-node","version":"2.2.0","keywords":["waffo","payment","psp","subscription","sdk","ewallet","payment-gateway"],"author":{"name":"Waffo","email":"merchant.support@waffo.com"},"license":"MIT","_id":"@waffo/waffo-node@2.2.0","maintainers":[{"name":"waffo-js","email":"js@waffo.com"},{"name":"hill-waffo","email":"zhaoxuan.hong@waffo.com"},{"name":"tangjiaj","email":"jj@waffo.com"},{"name":"fronzenvista","email":"wuze.wang@waffo.co"}],"homepage":"https://github.com/waffo-com/waffo-sdk/tree/main/packages/waffo-node","bugs":{"url":"https://github.com/waffo-com/waffo-sdk/issues"},"dist":{"shasum":"c10ae9af55704014bad7d252af564f4786d338cf","tarball":"https://registry.npmjs.org/@waffo/waffo-node/-/waffo-node-2.2.0.tgz","fileCount":9,"integrity":"sha512-ZYokXuJq9QU56nbJwL1NVeFKAgVq0qv14C8DE0oXf0CiVjGxSpjU72uAupvmOFobiUEvRvbeTxVWR06lmcHXDQ==","signatures":[{"sig":"MEYCIQDKot3q3uEckPYuP2RI+bHEwCtcz4S2Wil1uvoYiFCIJQIhAMOOg3mMCrkghh+C35MXl1LElCRQTLap1XmWVz1Zj6on","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":421748},"main":"./dist/index.js","types":"./dist/index.d.ts","module":"./dist/index.mjs","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"gitHead":"bd2fb0e6dcbe6dd5c283a676262ca1ccd4c7010c","scripts":{"dev":"tsup --watch","lint":"eslint src --ext .ts","test":"vitest run","build":"tsup","test:e2e":"vitest run --config vitest.e2e.config.ts","typecheck":"tsc --noEmit","test:watch":"vitest","test:e2e:ui":"E2E_HEADLESS=false vitest run --config vitest.e2e.config.ts","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"fronzenvista","email":"wuze.wang@waffo.co"},"repository":{"url":"git+https://github.com/waffo-com/waffo-sdk.git","type":"git"},"_npmVersion":"10.8.2","description":"Official Waffo PSP Node.js SDK","directories":{},"_nodeVersion":"20.20.0","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","yaml":"^2.3.0","eslint":"^8.56.0","vitest":"^1.0.0","playwright":"^1.40.0","typescript":"^5.3.0","@types/node":"^20.0.0","@typescript-eslint/parser":"^6.19.0","@typescript-eslint/eslint-plugin":"^6.19.0"},"_npmOperationalInternal":{"tmp":"tmp/waffo-node_2.2.0_1770876655661_0.330190125505891","host":"s3://npm-registry-packages-npm-production"}},"2.3.0":{"name":"@waffo/waffo-node","version":"2.3.0","keywords":["waffo","payment","psp","subscription","sdk","ewallet","payment-gateway"],"author":{"name":"Waffo","email":"merchant.support@waffo.com"},"license":"MIT","_id":"@waffo/waffo-node@2.3.0","maintainers":[{"name":"waffo-js","email":"js@waffo.com"},{"name":"hill-waffo","email":"zhaoxuan.hong@waffo.com"},{"name":"tangjiaj","email":"jj@waffo.com"},{"name":"fronzenvista","email":"wuze.wang@waffo.co"}],"homepage":"https://github.com/waffo-com/waffo-sdk/tree/main/packages/waffo-node","bugs":{"url":"https://github.com/waffo-com/waffo-sdk/issues"},"dist":{"shasum":"e7a1afbb046811ecc066b816036404106930e7b0","tarball":"https://registry.npmjs.org/@waffo/waffo-node/-/waffo-node-2.3.0.tgz","fileCount":9,"integrity":"sha512-aDXYaETqvYbrpTl2/eRMUAZ6hO4bsfZeuwEpCVf6KqLYFv8vLGliaOtDlTl47E/EbfeLkPwx1clSKus/+4HEaw==","signatures":[{"sig":"MEQCIH9f8wE+EdAt6kI1EtvopL2JnTPJwM2YDlYeKBjxxWtsAiAHPaI+dXUEIsdMyT8BX5tvddMOBbeILH5w+CDtae1hAQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":434376},"main":"./dist/index.js","types":"./dist/index.d.ts","module":"./dist/index.mjs","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"gitHead":"ee83ead96719bb2491491db27a457c727e5a9d7c","scripts":{"dev":"tsup --watch","lint":"eslint src --ext .ts","test":"vitest run","build":"tsup","test:e2e":"vitest run --config vitest.e2e.config.ts","typecheck":"tsc --noEmit","test:watch":"vitest","test:e2e:ui":"E2E_HEADLESS=false vitest run --config vitest.e2e.config.ts","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"fronzenvista","email":"wuze.wang@waffo.co"},"repository":{"url":"git+https://github.com/waffo-com/waffo-sdk.git","type":"git"},"_npmVersion":"10.8.2","description":"Official Waffo PSP Node.js SDK","directories":{},"_nodeVersion":"20.20.0","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","yaml":"^2.3.0","eslint":"^8.56.0","vitest":"^1.0.0","playwright":"^1.40.0","typescript":"^5.3.0","@types/node":"^20.0.0","@typescript-eslint/parser":"^6.19.0","@typescript-eslint/eslint-plugin":"^6.19.0"},"_npmOperationalInternal":{"tmp":"tmp/waffo-node_2.3.0_1771929708232_0.18952831250652102","host":"s3://npm-registry-packages-npm-production"}},"2.3.1":{"name":"@waffo/waffo-node","version":"2.3.1","keywords":["waffo","payment","psp","subscription","sdk","ewallet","payment-gateway"],"author":{"name":"Waffo","email":"merchant.support@waffo.com"},"license":"MIT","_id":"@waffo/waffo-node@2.3.1","maintainers":[{"name":"waffo-js","email":"js@waffo.com"},{"name":"hill-waffo","email":"zhaoxuan.hong@waffo.com"},{"name":"tangjiaj","email":"jj@waffo.com"},{"name":"fronzenvista","email":"wuze.wang@waffo.co"}],"homepage":"https://github.com/waffo-com/waffo-sdk/tree/main/packages/waffo-node","bugs":{"url":"https://github.com/waffo-com/waffo-sdk/issues"},"dist":{"shasum":"2e8f8d7205d9e902b0fe6d0f285eb910eb016fcf","tarball":"https://registry.npmjs.org/@waffo/waffo-node/-/waffo-node-2.3.1.tgz","fileCount":9,"integrity":"sha512-178A7THEw9Z9Jy9SRP6vF1pw2XDkLIAqVIGr/qIGti3Bo1g16wI/nTpL4ZZ5bBFlWS+PC7qrU1eyp17pYaZxfw==","signatures":[{"sig":"MEUCIQCM+AmUcTolMQW3KrmRR2SnFaajj5tuQ/DqMp0iBq2rWAIgFyZ1SHmL/ribxS3cz7UUkcLiUTTIlnw4McFVvyUo0p4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":437613},"main":"./dist/index.js","types":"./dist/index.d.ts","module":"./dist/index.mjs","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"gitHead":"5cbf730e7bdad6529384d9dc6faab1355b8563d0","scripts":{"dev":"tsup --watch","lint":"eslint src --ext .ts","test":"vitest run","build":"tsup","test:e2e":"vitest run --config vitest.e2e.config.ts","typecheck":"tsc --noEmit","test:watch":"vitest","test:e2e:ui":"E2E_HEADLESS=false vitest run --config vitest.e2e.config.ts","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"fronzenvista","email":"wuze.wang@waffo.co"},"repository":{"url":"git+https://github.com/waffo-com/waffo-sdk.git","type":"git"},"_npmVersion":"10.8.2","description":"Official Waffo PSP Node.js SDK","directories":{},"_nodeVersion":"20.20.0","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","yaml":"^2.3.0","eslint":"^8.56.0","vitest":"^1.0.0","playwright":"^1.40.0","typescript":"^5.3.0","@types/node":"^20.0.0","@typescript-eslint/parser":"^6.19.0","@typescript-eslint/eslint-plugin":"^6.19.0"},"_npmOperationalInternal":{"tmp":"tmp/waffo-node_2.3.1_1772349053570_0.20252404570053928","host":"s3://npm-registry-packages-npm-production"}},"2.3.2":{"name":"@waffo/waffo-node","version":"2.3.2","keywords":["waffo","payment","psp","subscription","sdk","ewallet","payment-gateway"],"author":{"name":"Waffo","email":"merchant.support@waffo.com"},"license":"MIT","_id":"@waffo/waffo-node@2.3.2","maintainers":[{"name":"waffo-js","email":"js@waffo.com"},{"name":"hill-waffo","email":"zhaoxuan.hong@waffo.com"},{"name":"tangjiaj","email":"jj@waffo.com"},{"name":"fronzenvista","email":"wuze.wang@waffo.co"}],"homepage":"https://github.com/waffo-com/waffo-sdk/tree/main/packages/waffo-node","bugs":{"url":"https://github.com/waffo-com/waffo-sdk/issues"},"dist":{"shasum":"06cfdbe38d638d9029b6f5c22fb1aa96c3c6a9ba","tarball":"https://registry.npmjs.org/@waffo/waffo-node/-/waffo-node-2.3.2.tgz","fileCount":9,"integrity":"sha512-nrA6iVIb250ThCm9rUThI06XHKVVljTOcLimivKgQzNY28ji064P+pOPSEkyYGXEEq9jcdWhgtBzUC8Mcv2R0A==","signatures":[{"sig":"MEQCIFvFlGQ8E92yFsigBQROcyNOYVpNOa9wH9e3R1HB1/OfAiBwp+kdTFjf+hiIRcA/FU8kF3wJ+IjBbx9oWOqZ3kxMAQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":446241},"main":"./dist/index.js","types":"./dist/index.d.ts","module":"./dist/index.mjs","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"gitHead":"247d5b1d0e2f368158fe13fde0c7b8c7a48eb21a","scripts":{"dev":"tsup --watch","lint":"eslint src --ext .ts","test":"vitest run","build":"tsup","test:e2e":"vitest run --config vitest.e2e.config.ts","typecheck":"tsc --noEmit","test:watch":"vitest","test:e2e:ui":"E2E_HEADLESS=false vitest run --config vitest.e2e.config.ts","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"fronzenvista","email":"wuze.wang@waffo.co"},"repository":{"url":"git+https://github.com/waffo-com/waffo-sdk.git","type":"git"},"_npmVersion":"10.8.2","description":"Official Waffo PSP Node.js SDK","directories":{},"_nodeVersion":"20.20.0","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","yaml":"^2.3.0","eslint":"^8.56.0","vitest":"^1.0.0","playwright":"^1.40.0","typescript":"^5.3.0","@types/node":"^20.0.0","@typescript-eslint/parser":"^6.19.0","@typescript-eslint/eslint-plugin":"^6.19.0"},"_npmOperationalInternal":{"tmp":"tmp/waffo-node_2.3.2_1772450127492_0.35977476569155153","host":"s3://npm-registry-packages-npm-production"}},"2.3.3":{"name":"@waffo/waffo-node","version":"2.3.3","keywords":["waffo","payment","psp","subscription","sdk","ewallet","payment-gateway"],"author":{"name":"Waffo","email":"merchant.support@waffo.com"},"license":"MIT","_id":"@waffo/waffo-node@2.3.3","maintainers":[{"name":"waffo-js","email":"js@waffo.com"},{"name":"hill-waffo","email":"zhaoxuan.hong@waffo.com"},{"name":"tangjiaj","email":"jj@waffo.com"},{"name":"fronzenvista","email":"wuze.wang@waffo.co"}],"homepage":"https://github.com/waffo-com/waffo-sdk/tree/main/packages/waffo-node","bugs":{"url":"https://github.com/waffo-com/waffo-sdk/issues"},"dist":{"shasum":"b0e52cfb28ee1804af7c71643b8965c81bba7d04","tarball":"https://registry.npmjs.org/@waffo/waffo-node/-/waffo-node-2.3.3.tgz","fileCount":9,"integrity":"sha512-VJanPU0Eys6xBpdVuqmuKpGSLysr8m3WheK3ILPZgnLUov/mPYRmiwbQQW5JzkV03NxnLWKhZCdNjEB/v9WpAA==","signatures":[{"sig":"MEUCIF0iAG95JrwWLvvYQ5/F+N2hkH3DOqnU1D7tcJWOFF+vAiEAykyZ24GwnQTIBhI5vwIQLFauB1+KtWBmvNLnUuTv8Ck=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":446879},"main":"./dist/index.js","types":"./dist/index.d.ts","module":"./dist/index.mjs","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"gitHead":"d1153d5425c2fd821381fa37c571bc995edd5187","scripts":{"dev":"tsup --watch","lint":"eslint src --ext .ts","test":"vitest run","build":"tsup","test:e2e":"vitest run --config vitest.e2e.config.ts","typecheck":"tsc --noEmit","test:watch":"vitest","test:e2e:ui":"E2E_HEADLESS=false vitest run --config vitest.e2e.config.ts","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"fronzenvista","email":"wuze.wang@waffo.co"},"repository":{"url":"git+https://github.com/waffo-com/waffo-sdk.git","type":"git"},"_npmVersion":"10.8.2","description":"Official Waffo PSP Node.js SDK","directories":{},"_nodeVersion":"20.20.0","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","yaml":"^2.3.0","eslint":"^8.56.0","vitest":"^1.0.0","playwright":"^1.40.0","typescript":"^5.3.0","@types/node":"^20.0.0","@typescript-eslint/parser":"^6.19.0","@typescript-eslint/eslint-plugin":"^6.19.0"},"_npmOperationalInternal":{"tmp":"tmp/waffo-node_2.3.3_1772528049829_0.9226304590994747","host":"s3://npm-registry-packages-npm-production"}},"2.3.4":{"name":"@waffo/waffo-node","version":"2.3.4","keywords":["waffo","payment","psp","subscription","sdk","ewallet","payment-gateway"],"author":{"name":"Waffo","email":"merchant.support@waffo.com"},"license":"MIT","_id":"@waffo/waffo-node@2.3.4","maintainers":[{"name":"waffo-js","email":"js@waffo.com"},{"name":"hill-waffo","email":"zhaoxuan.hong@waffo.com"},{"name":"tangjiaj","email":"jj@waffo.com"},{"name":"fronzenvista","email":"wuze.wang@waffo.co"}],"homepage":"https://github.com/waffo-com/waffo-sdk/tree/main/packages/waffo-node","bugs":{"url":"https://github.com/waffo-com/waffo-sdk/issues"},"dist":{"shasum":"7b70eb08075aabefb71ddc17293ec56e9944164f","tarball":"https://registry.npmjs.org/@waffo/waffo-node/-/waffo-node-2.3.4.tgz","fileCount":9,"integrity":"sha512-0RQL2G0tEXHQPEXT/7p8muZnMXxn1A0/Hhoc+XqNMFcHlO8Qlll0UHv3A/EDvXXDtcKQ4xeolow+ugX1kAQ44A==","signatures":[{"sig":"MEYCIQCcTLzXO83/eW60ncHI51zQNaLWsluxrFJ/Go1K+xckRQIhANeFIPNPPhuvXk9Vaig96W3mH75loqhg1+wUVObVNPhX","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":447403},"main":"./dist/index.js","types":"./dist/index.d.ts","module":"./dist/index.mjs","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"gitHead":"eca15ff834a1ba6f9eadf32795e6133e276b7aad","scripts":{"dev":"tsup --watch","lint":"eslint src --ext .ts","test":"vitest run","build":"tsup","test:e2e":"vitest run --config vitest.e2e.config.ts","typecheck":"tsc --noEmit","test:watch":"vitest","test:e2e:ui":"E2E_HEADLESS=false vitest run --config vitest.e2e.config.ts","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"fronzenvista","email":"wuze.wang@waffo.co"},"repository":{"url":"git+https://github.com/waffo-com/waffo-sdk.git","type":"git"},"_npmVersion":"10.8.2","description":"Official Waffo PSP Node.js SDK","directories":{},"_nodeVersion":"20.20.0","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","yaml":"^2.3.0","eslint":"^8.56.0","vitest":"^1.0.0","playwright":"^1.40.0","typescript":"^5.3.0","@types/node":"^20.0.0","@typescript-eslint/parser":"^6.19.0","@typescript-eslint/eslint-plugin":"^6.19.0"},"_npmOperationalInternal":{"tmp":"tmp/waffo-node_2.3.4_1773140211675_0.26407390757894866","host":"s3://npm-registry-packages-npm-production"}},"2.4.0":{"name":"@waffo/waffo-node","version":"2.4.0","keywords":["waffo","payment","psp","subscription","sdk","ewallet","payment-gateway"],"author":{"name":"Waffo","email":"merchant.support@waffo.com"},"license":"MIT","_id":"@waffo/waffo-node@2.4.0","maintainers":[{"name":"waffo-js","email":"js@waffo.com"},{"name":"hill-waffo","email":"zhaoxuan.hong@waffo.com"},{"name":"tangjiaj","email":"jj@waffo.com"},{"name":"fronzenvista","email":"wuze.wang@waffo.co"}],"homepage":"https://github.com/waffo-com/waffo-sdk/tree/main/packages/waffo-node","bugs":{"url":"https://github.com/waffo-com/waffo-sdk/issues"},"dist":{"shasum":"e26748ae078f242ad9977e36aa2f7e6ecd455c22","tarball":"https://registry.npmjs.org/@waffo/waffo-node/-/waffo-node-2.4.0.tgz","fileCount":9,"integrity":"sha512-EoL+pxmdAYXvRMSlOHl/fntsSyPX7XujhX4xmoePfDqVMti382hFrmGso845eG81bYglCR1k+yHT8ha5Lna7Sw==","signatures":[{"sig":"MEQCIFVsfv0qe0NX9oOYmVwVhs/hrV8XHEVFLN2bOKlKB7H6AiBRhZxQ9/5qdnMrbgSifM1HWuh+IH5zXjXoqdvpMtmdEQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":451643},"main":"./dist/index.js","types":"./dist/index.d.ts","module":"./dist/index.mjs","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"gitHead":"1877ad3fea808d6ab6438091a34634930a249629","scripts":{"dev":"tsup --watch","lint":"eslint src --ext .ts","test":"vitest run","build":"tsup","test:e2e":"vitest run --config vitest.e2e.config.ts","typecheck":"tsc --noEmit","test:watch":"vitest","test:e2e:ui":"E2E_HEADLESS=false vitest run --config vitest.e2e.config.ts","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"fronzenvista","email":"wuze.wang@waffo.co"},"repository":{"url":"git+https://github.com/waffo-com/waffo-sdk.git","type":"git"},"_npmVersion":"10.8.2","description":"Official Waffo PSP Node.js SDK","directories":{},"_nodeVersion":"20.20.1","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","yaml":"^2.3.0","eslint":"^8.56.0","vitest":"^1.0.0","playwright":"^1.40.0","typescript":"^5.3.0","@types/node":"^20.0.0","@typescript-eslint/parser":"^6.19.0","@typescript-eslint/eslint-plugin":"^6.19.0"},"_npmOperationalInternal":{"tmp":"tmp/waffo-node_2.4.0_1773624717594_0.24194727804975313","host":"s3://npm-registry-packages-npm-production"}},"2.5.0":{"name":"@waffo/waffo-node","version":"2.5.0","keywords":["waffo","payment","psp","subscription","sdk","ewallet","payment-gateway"],"author":{"name":"Waffo","email":"merchant.support@waffo.com"},"license":"MIT","_id":"@waffo/waffo-node@2.5.0","maintainers":[{"name":"zephyr-waffo","email":"xichen.wu@waffo.com"},{"name":"mohuiling","email":"huiling.mo@waffo.com"},{"name":"waffo-js","email":"js@waffo.com"},{"name":"hill-waffo","email":"zhaoxuan.hong@waffo.com"},{"name":"tangjiaj","email":"jj@waffo.com"},{"name":"fronzenvista","email":"wuze.wang@waffo.co"}],"homepage":"https://github.com/waffo-com/waffo-sdk/tree/main/packages/waffo-node","bugs":{"url":"https://github.com/waffo-com/waffo-sdk/issues"},"dist":{"shasum":"cc64578bfe2543e0811e1f0d1e2e6aee60c983af","tarball":"https://registry.npmjs.org/@waffo/waffo-node/-/waffo-node-2.5.0.tgz","fileCount":9,"integrity":"sha512-4CcEJ2GK7riXkXW5OsS5AYXu3TAzAupp3i9VF/8lTnlWJXySJzKtPW2KV0S/LlRNuHENW5zlDgJj5+ahVv8VpQ==","signatures":[{"sig":"MEUCIQDRwnxqj4eAD7U8IUHT7bgtEk/LQw/dIrnfNQbLz9qkbAIgDFEHD90hChBFSAXBZI02U5EX8Nd2QW9aJ17fjh2B7JI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":466835},"main":"./dist/index.js","types":"./dist/index.d.ts","module":"./dist/index.mjs","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"gitHead":"c23c86f2148a2c33506ba5b23d7f5a46ebf315ce","scripts":{"dev":"tsup --watch","lint":"eslint src --ext .ts","test":"vitest run","build":"tsup","test:e2e":"vitest run --config vitest.e2e.config.ts","typecheck":"tsc --noEmit","test:watch":"vitest","test:e2e:ui":"E2E_HEADLESS=false vitest run --config vitest.e2e.config.ts","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"fronzenvista","email":"wuze.wang@waffo.co"},"repository":{"url":"git+https://github.com/waffo-com/waffo-sdk.git","type":"git"},"_npmVersion":"10.8.2","description":"Official Waffo PSP Node.js SDK","directories":{},"_nodeVersion":"20.20.2","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","yaml":"^2.3.0","eslint":"^8.56.0","vitest":"^1.0.0","playwright":"^1.40.0","typescript":"^5.3.0","@types/node":"^20.0.0","@typescript-eslint/parser":"^6.19.0","@typescript-eslint/eslint-plugin":"^6.19.0"},"_npmOperationalInternal":{"tmp":"tmp/waffo-node_2.5.0_1778662389126_0.20794600149158993","host":"s3://npm-registry-packages-npm-production"}},"2.5.1":{"name":"@waffo/waffo-node","version":"2.5.1","keywords":["waffo","payment","psp","subscription","sdk","ewallet","payment-gateway"],"author":{"name":"Waffo","email":"merchant.support@waffo.com"},"license":"MIT","_id":"@waffo/waffo-node@2.5.1","maintainers":[{"name":"zephyr-waffo","email":"xichen.wu@waffo.com"},{"name":"mohuiling","email":"huiling.mo@waffo.com"},{"name":"waffo-js","email":"js@waffo.com"},{"name":"zhongyuan.zhao","email":"zhongyuan.zhao@waffo.com"},{"name":"hill-waffo","email":"zhaoxuan.hong@waffo.com"},{"name":"tangjiaj","email":"jj@waffo.com"},{"name":"fronzenvista","email":"wuze.wang@waffo.co"}],"homepage":"https://github.com/waffo-com/waffo-sdk/tree/main/packages/waffo-node","bugs":{"url":"https://github.com/waffo-com/waffo-sdk/issues"},"dist":{"shasum":"0439ccca1a1ea8d3a47c9a98f55b13db8e11994e","tarball":"https://registry.npmjs.org/@waffo/waffo-node/-/waffo-node-2.5.1.tgz","fileCount":9,"integrity":"sha512-MU3FnQgLbeb+Jm05d8QHs+6rXhHPgGCifKhqWDyoKYV9SIdiKnuh2Zlhwbm/QHOnX8Qkw9yQzYMobW+ETNKCEw==","signatures":[{"sig":"MEQCIC98pXyNP3BX+M63w7acEaNxUpDxHnVMMvLmw6E1Ox1tAiBpKuduv/s27BOYECgaldcx9wlftc4AoFihQmuCtgUqKw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":475149},"main":"./dist/index.js","types":"./dist/index.d.ts","module":"./dist/index.mjs","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"gitHead":"f5be0ad9b23ee7adedf67b8cc1155ec24b617018","scripts":{"dev":"tsup --watch","lint":"eslint src --ext .ts","test":"vitest run","build":"tsup","test:e2e":"vitest run --config vitest.e2e.config.ts","typecheck":"tsc --noEmit","test:watch":"vitest","test:e2e:ui":"E2E_HEADLESS=false vitest run --config vitest.e2e.config.ts","test:coverage":"vitest run --coverage","prepublishOnly":"npm run typecheck && npm run build && npm test"},"_npmUser":{"name":"zhongyuan.zhao","email":"zhongyuan.zhao@waffo.com"},"repository":{"url":"git+https://github.com/waffo-com/waffo-sdk.git","type":"git"},"_npmVersion":"10.8.2","description":"Official Waffo PSP Node.js SDK","directories":{},"_nodeVersion":"20.20.2","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","yaml":"^2.3.0","eslint":"^8.56.0","vitest":"^1.0.0","playwright":"^1.40.0","typescript":"^5.3.0","@types/node":"^20.0.0","@typescript-eslint/parser":"^6.19.0","@typescript-eslint/eslint-plugin":"^6.19.0"},"_npmOperationalInternal":{"tmp":"tmp/waffo-node_2.5.1_1783321257795_0.436668799501833","host":"s3://npm-registry-packages-npm-production"}},"2.6.0":{"name":"@waffo/waffo-node","version":"2.6.0","keywords":["waffo","payment","psp","subscription","sdk","ewallet","payment-gateway"],"author":{"name":"Waffo","email":"merchant.support@waffo.com"},"license":"MIT","_id":"@waffo/waffo-node@2.6.0","maintainers":[{"name":"zephyr-waffo","email":"xichen.wu@waffo.com"},{"name":"mohuiling","email":"huiling.mo@waffo.com"},{"name":"waffo-js","email":"js@waffo.com"},{"name":"zhongyuan.zhao","email":"zhongyuan.zhao@waffo.com"},{"name":"hill-waffo","email":"zhaoxuan.hong@waffo.com"},{"name":"tangjiaj","email":"jj@waffo.com"},{"name":"fronzenvista","email":"wuze.wang@waffo.co"}],"homepage":"https://github.com/waffo-com/waffo-sdk/tree/main/packages/waffo-node","bugs":{"url":"https://github.com/waffo-com/waffo-sdk/issues"},"dist":{"shasum":"90018262458f729f4a3e5a84851b72a214a06186","tarball":"https://registry.npmjs.org/@waffo/waffo-node/-/waffo-node-2.6.0.tgz","fileCount":9,"integrity":"sha512-SGU2t+heElaH5redq6pvLYXvSNJV5L7j7b5vFlbjck4VoNkFHWMbIVrt1z4WFzqm/R1bn4AW5JQ9cF77b/nqNA==","signatures":[{"sig":"MEQCIBEUBMWe3yvOyvfjQOsMfZeMf2lYDTB3vQFwUfKxPgtAAiBWVB0vgg6vtbIDeYRpMXZRVjX9xHNqonkOJ+UmoeOrGQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":491826},"main":"./dist/index.js","types":"./dist/index.d.ts","module":"./dist/index.mjs","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"gitHead":"5d5266687d7476835d073a622bc4ffd7aadcbcd0","scripts":{"dev":"tsup --watch","lint":"eslint src --ext .ts","test":"vitest run","build":"tsup","test:e2e":"vitest run --config vitest.e2e.config.ts","typecheck":"tsc --noEmit","test:watch":"vitest","test:e2e:ui":"E2E_HEADLESS=false vitest run --config vitest.e2e.config.ts","test:coverage":"vitest run --coverage","prepublishOnly":"npm run typecheck && npm run build && npm test"},"_npmUser":{"name":"zhongyuan.zhao","email":"zhongyuan.zhao@waffo.com"},"repository":{"url":"git+https://github.com/waffo-com/waffo-sdk.git","type":"git"},"_npmVersion":"10.8.2","description":"Official Waffo PSP Node.js SDK","directories":{},"_nodeVersion":"20.20.2","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","yaml":"^2.3.0","eslint":"^8.56.0","vitest":"^1.0.0","playwright":"^1.40.0","typescript":"^5.3.0","@types/node":"^20.0.0","@typescript-eslint/parser":"^6.19.0","@typescript-eslint/eslint-plugin":"^6.19.0"},"_npmOperationalInternal":{"tmp":"tmp/waffo-node_2.6.0_1784272989632_0.700562373372636","host":"s3://npm-registry-packages-npm-production"}},"2.7.0":{"name":"@waffo/waffo-node","version":"2.7.0","keywords":["waffo","payment","psp","subscription","sdk","ewallet","payment-gateway"],"author":{"name":"Waffo","email":"merchant.support@waffo.com"},"license":"MIT","_id":"@waffo/waffo-node@2.7.0","maintainers":[{"name":"zephyr-waffo","email":"xichen.wu@waffo.com"},{"name":"mohuiling","email":"huiling.mo@waffo.com"},{"name":"waffo-js","email":"js@waffo.com"},{"name":"zhongyuan.zhao","email":"zhongyuan.zhao@waffo.com"},{"name":"hill-waffo","email":"zhaoxuan.hong@waffo.com"},{"name":"tangjiaj","email":"jj@waffo.com"},{"name":"fronzenvista","email":"wuze.wang@waffo.co"}],"homepage":"https://github.com/waffo-com/waffo-sdk/tree/main/packages/waffo-node","bugs":{"url":"https://github.com/waffo-com/waffo-sdk/issues"},"dist":{"shasum":"9c61bd83c0dcbb32ceef116c5b8eab48dac593fa","tarball":"https://registry.npmjs.org/@waffo/waffo-node/-/waffo-node-2.7.0.tgz","fileCount":9,"integrity":"sha512-p2BLwjrCagMjSsPj9Hoft0tkfUZ+0relbCOenJZ32bczIrkQmPJ9B54ofMaBksIpMgPNRl0xC90PFCqP6WVgYg==","signatures":[{"sig":"MEUCIHFYuaq01uB2kEmUNM+Opz/CCI2Vg0jQDKRVYnQpxS4yAiEA2SmbqBYRImjG5p+tXynbQwxsYnZ2CMNWbmdkaSBEnas=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":492620},"main":"./dist/index.js","types":"./dist/index.d.ts","module":"./dist/index.mjs","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"gitHead":"31127ce08ea877419d6b7bdd871ae0b86fe82883","scripts":{"dev":"tsup --watch","lint":"eslint src --ext .ts","test":"vitest run","build":"tsup","test:e2e":"vitest run --config vitest.e2e.config.ts","typecheck":"tsc --noEmit","test:watch":"vitest","test:e2e:ui":"E2E_HEADLESS=false vitest run --config vitest.e2e.config.ts","test:coverage":"vitest run --coverage","prepublishOnly":"npm run typecheck && npm run build && npm test"},"_npmUser":{"name":"zhongyuan.zhao","email":"zhongyuan.zhao@waffo.com"},"repository":{"url":"git+https://github.com/waffo-com/waffo-sdk.git","type":"git"},"_npmVersion":"10.8.2","description":"Official Waffo PSP Node.js SDK","directories":{},"_nodeVersion":"20.20.2","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","yaml":"^2.3.0","eslint":"^8.56.0","vitest":"^1.0.0","playwright":"^1.40.0","typescript":"^5.3.0","@types/node":"^20.0.0","@typescript-eslint/parser":"^6.19.0","@typescript-eslint/eslint-plugin":"^6.19.0"},"_npmOperationalInternal":{"tmp":"tmp/waffo-node_2.7.0_1785245966858_0.2895604590484375","host":"s3://npm-registry-packages-npm-production"}},"3.0.0":{"name":"@waffo/waffo-node","version":"3.0.0","keywords":["waffo","payment","psp","subscription","sdk","ewallet","payment-gateway"],"author":{"name":"Waffo","email":"merchant.support@waffo.com"},"license":"MIT","_id":"@waffo/waffo-node@3.0.0","maintainers":[{"name":"zephyr-waffo","email":"xichen.wu@waffo.com"},{"name":"mohuiling","email":"huiling.mo@waffo.com"},{"name":"waffo-js","email":"js@waffo.com"},{"name":"zhongyuan.zhao","email":"zhongyuan.zhao@waffo.com"},{"name":"hill-waffo","email":"zhaoxuan.hong@waffo.com"},{"name":"tangjiaj","email":"jj@waffo.com"},{"name":"fronzenvista","email":"wuze.wang@waffo.co"}],"homepage":"https://github.com/waffo-com/waffo-sdk/tree/main/packages/waffo-node","bugs":{"url":"https://github.com/waffo-com/waffo-sdk/issues"},"dist":{"shasum":"fc3a0c1e3f93a65b5d376f01a5dca4998a48968c","tarball":"https://registry.npmjs.org/@waffo/waffo-node/-/waffo-node-3.0.0.tgz","fileCount":9,"integrity":"sha512-XQ7nJ5g6yW0I1gVhyNNSPMq3wNSYXt5++VereUpg8rmHVpel178U/5g7OFsYLwAV29BJRTpLOiy55jzgtz1yjw==","signatures":[{"sig":"MEUCIHJAEC0onbai+KSgqnD7bDj0mbqwbBZrsAGCDjpXzyBpAiEA3DnUn46z9azPhU7eTrl10VPIOPXbvebfy0b3QufI6uw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":493326},"main":"./dist/index.js","types":"./dist/index.d.ts","module":"./dist/index.mjs","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"gitHead":"49b33d33f402970a1ba22dd305c8fbff4925ceaa","scripts":{"dev":"tsup --watch","lint":"eslint src --ext .ts","test":"vitest run","build":"tsup","test:e2e":"vitest run --config vitest.e2e.config.ts","typecheck":"tsc --noEmit","test:watch":"vitest","test:e2e:ui":"E2E_HEADLESS=false vitest run --config vitest.e2e.config.ts","test:coverage":"vitest run --coverage","prepublishOnly":"npm run typecheck && npm run build && npm test"},"_npmUser":{"name":"zhongyuan.zhao","email":"zhongyuan.zhao@waffo.com"},"repository":{"url":"git+https://github.com/waffo-com/waffo-sdk.git","type":"git"},"_npmVersion":"10.8.2","description":"Official Waffo PSP Node.js SDK","directories":{},"_nodeVersion":"20.20.2","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","yaml":"^2.3.0","eslint":"^8.56.0","vitest":"^1.0.0","playwright":"^1.40.0","typescript":"^5.3.0","@types/node":"^20.0.0","@typescript-eslint/parser":"^6.19.0","@typescript-eslint/eslint-plugin":"^6.19.0"},"_npmOperationalInternal":{"tmp":"tmp/waffo-node_3.0.0_1785300529562_0.7876431932919268","host":"s3://npm-registry-packages-npm-production"}},"3.0.1":{"name":"@waffo/waffo-node","version":"3.0.1","keywords":["waffo","payment","psp","subscription","sdk","ewallet","payment-gateway"],"author":{"name":"Waffo","email":"merchant.support@waffo.com"},"license":"MIT","_id":"@waffo/waffo-node@3.0.1","maintainers":[{"name":"zephyr-waffo","email":"xichen.wu@waffo.com"},{"name":"mohuiling","email":"huiling.mo@waffo.com"},{"name":"waffo-js","email":"js@waffo.com"},{"name":"zhongyuan.zhao","email":"zhongyuan.zhao@waffo.com"},{"name":"hill-waffo","email":"zhaoxuan.hong@waffo.com"},{"name":"tangjiaj","email":"jj@waffo.com"},{"name":"fronzenvista","email":"wuze.wang@waffo.co"}],"homepage":"https://github.com/waffo-com/waffo-sdk/tree/main/packages/waffo-node","bugs":{"url":"https://github.com/waffo-com/waffo-sdk/issues"},"dist":{"shasum":"91c83220ddabaefdfa465f7c4b062429dc6a1530","tarball":"https://registry.npmjs.org/@waffo/waffo-node/-/waffo-node-3.0.1.tgz","fileCount":9,"integrity":"sha512-NjQlVTDpp70DoZwcdtN2v46hc2z6E5QBWpeYRAgTQcpBevs1X+cvVsGYwE+jiJQYQO5ncwH1mb1yWWQpoAlChA==","signatures":[{"sig":"MEUCIBquUyCHMlNIoBA8rafZqy+vC4K25WMyw3pJiijyRk0AAiEArISxxdEMD5YBP61tE9whIC4k9Dx0t2UgKOJT3rFLmtA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":493610},"main":"./dist/index.js","types":"./dist/index.d.ts","module":"./dist/index.mjs","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"gitHead":"9e8058c8df2df653b9d70891061412050eb4b80e","scripts":{"dev":"tsup --watch","lint":"eslint src --ext .ts","test":"vitest run","build":"tsup","test:e2e":"vitest run --config vitest.e2e.config.ts","typecheck":"tsc --noEmit","test:watch":"vitest","test:e2e:ui":"E2E_HEADLESS=false vitest run --config vitest.e2e.config.ts","test:coverage":"vitest run --coverage","prepublishOnly":"npm run typecheck && npm run build && npm test"},"_npmUser":{"name":"zhongyuan.zhao","email":"zhongyuan.zhao@waffo.com"},"repository":{"url":"git+https://github.com/waffo-com/waffo-sdk.git","type":"git"},"_npmVersion":"10.8.2","description":"Official Waffo PSP Node.js SDK","directories":{},"_nodeVersion":"20.20.2","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","yaml":"^2.3.0","eslint":"^8.56.0","vitest":"^1.0.0","playwright":"^1.40.0","typescript":"^5.3.0","@types/node":"^20.0.0","@typescript-eslint/parser":"^6.19.0","@typescript-eslint/eslint-plugin":"^6.19.0"},"_npmOperationalInternal":{"tmp":"tmp/waffo-node_3.0.1_1785829459550_0.44763081778746105","host":"s3://npm-registry-packages-npm-production"}},"3.1.0":{"name":"@waffo/waffo-node","version":"3.1.0","description":"Official Waffo PSP Node.js SDK","main":"./dist/index.js","module":"./dist/index.mjs","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"engines":{"node":">=18.0.0"},"scripts":{"build":"tsup","dev":"tsup --watch","test":"vitest run","test:watch":"vitest","test:coverage":"vitest run --coverage","test:e2e":"vitest run --config vitest.e2e.config.ts","test:e2e:ui":"E2E_HEADLESS=false vitest run --config vitest.e2e.config.ts","lint":"eslint src --ext .ts","typecheck":"tsc --noEmit","prepublishOnly":"npm run typecheck && npm run build && npm test"},"keywords":["waffo","payment","psp","subscription","sdk","ewallet","payment-gateway"],"author":{"name":"Waffo","email":"merchant.support@waffo.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/waffo-com/waffo-sdk.git"},"homepage":"https://github.com/waffo-com/waffo-sdk/tree/main/packages/waffo-node","bugs":{"url":"https://github.com/waffo-com/waffo-sdk/issues"},"devDependencies":{"@types/node":"^20.0.0","typescript":"^5.3.0","tsup":"^8.0.0","vitest":"^1.0.0","eslint":"^8.56.0","@typescript-eslint/eslint-plugin":"^6.19.0","@typescript-eslint/parser":"^6.19.0","playwright":"^1.40.0","yaml":"^2.3.0"},"_id":"@waffo/waffo-node@3.1.0","gitHead":"28ee12a01b0e76c8414d0802c3c59f3cf831a134","_nodeVersion":"20.20.2","_npmVersion":"10.8.2","dist":{"integrity":"sha512-EqYhiJS9cSF8M4NmCwiV3Dkk/APmuafrTB1e3cPEqqN8r/1P0mzTFCGkeEODEX21r4cIRzCN4kzVG7CTtAw+OA==","shasum":"b8ebfbaee1f6e6c23df87927d3218a2f55cbfa91","tarball":"https://registry.npmjs.org/@waffo/waffo-node/-/waffo-node-3.1.0.tgz","fileCount":9,"unpackedSize":504817,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCeKmD9aloh471QJOBs/8p16r746mWagcFx8bGZzErpXQIhAL2UdfMMnNX9TcUBq7L0poKHjBwd23rvCsxtXNKgQhNL"}]},"_npmUser":{"name":"zhongyuan.zhao","email":"zhongyuan.zhao@waffo.com"},"directories":{},"maintainers":[{"name":"zephyr-waffo","email":"xichen.wu@waffo.com"},{"name":"mohuiling","email":"huiling.mo@waffo.com"},{"name":"waffo-js","email":"js@waffo.com"},{"name":"zhongyuan.zhao","email":"zhongyuan.zhao@waffo.com"},{"name":"hill-waffo","email":"zhaoxuan.hong@waffo.com"},{"name":"tangjiaj","email":"jj@waffo.com"},{"name":"fronzenvista","email":"wuze.wang@waffo.co"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/waffo-node_3.1.0_1788514729433_0.1930118117620203"},"_hasShrinkwrap":false}},"time":{"created":"2026-01-05T01:52:19.948Z","modified":"2026-09-04T09:38:49.725Z","2.0.2":"2026-01-05T01:52:20.289Z","2.0.3":"2026-01-07T10:09:52.675Z","2.0.4":"2026-01-23T05:52:00.347Z","2.1.0":"2026-02-04T12:33:26.428Z","2.2.0":"2026-02-12T06:10:55.839Z","2.3.0":"2026-02-24T10:41:48.368Z","2.3.1":"2026-03-01T07:10:53.736Z","2.3.2":"2026-03-02T11:15:27.650Z","2.3.3":"2026-03-03T08:54:09.965Z","2.3.4":"2026-03-10T10:56:51.844Z","2.4.0":"2026-03-16T01:31:57.741Z","2.5.0":"2026-05-13T08:53:09.288Z","2.5.1":"2026-07-06T07:00:57.974Z","2.6.0":"2026-07-17T07:23:09.800Z","2.7.0":"2026-07-28T13:39:27.001Z","3.0.0":"2026-07-29T04:48:49.706Z","3.0.1":"2026-08-04T07:44:19.711Z","3.1.0":"2026-09-04T09:38:49.564Z"},"bugs":{"url":"https://github.com/waffo-com/waffo-sdk/issues"},"author":{"name":"Waffo","email":"merchant.support@waffo.com"},"license":"MIT","homepage":"https://github.com/waffo-com/waffo-sdk/tree/main/packages/waffo-node","keywords":["waffo","payment","psp","subscription","sdk","ewallet","payment-gateway"],"repository":{"type":"git","url":"git+https://github.com/waffo-com/waffo-sdk.git"},"description":"Official Waffo PSP Node.js SDK","maintainers":[{"name":"zephyr-waffo","email":"xichen.wu@waffo.com"},{"name":"mohuiling","email":"huiling.mo@waffo.com"},{"name":"waffo-js","email":"js@waffo.com"},{"name":"zhongyuan.zhao","email":"zhongyuan.zhao@waffo.com"},{"name":"hill-waffo","email":"zhaoxuan.hong@waffo.com"},{"name":"tangjiaj","email":"jj@waffo.com"},{"name":"fronzenvista","email":"wuze.wang@waffo.co"}],"readme":"# Waffo Node.js SDK\n\n<!-- Synced with waffo-sdk/README.md @ commit 53f0d42 -->\n\n**English** | [中文](README_CN.md)\n\n[![npm version](https://img.shields.io/npm/v/@waffo/waffo-node.svg)](https://www.npmjs.com/package/@waffo/waffo-node)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)\n[![Node.js Version](https://img.shields.io/node/v/@waffo/waffo-node.svg)](https://nodejs.org)\n\nOfficial Node.js/TypeScript SDK for [Waffo Payment Platform](https://www.waffo.com), providing one-stop global payment solutions for AI products, SaaS services, and more.\n\n## Latest Release Highlights\n\n- **Subscription update API**: Added `subscription().update()` with `amount`, `trialPeriodAmount`, and `scheduledAmounts` support.\n- **Scheduled amount coverage**: Added `scheduledAmounts` fields across subscription create, change, update, and inquiry product info types.\n- **E2E and contract hardening**: Added subscription update E2E coverage, auto-injected `captureRequestedAt` for `order.capture()`, and expanded nested schema field validation.\n\n## Introduction\n\n### Core Features\n\n- **Global Payments**: Support for credit cards, debit cards, e-wallets, virtual accounts, and more payment methods covering mainstream global payment channels\n- **Subscription Management**: Complete subscription lifecycle management with trial periods, recurring billing, and subscription upgrades/downgrades\n- **Refund Processing**: Flexible full/partial refund capabilities with refund status tracking\n- **Webhook Notifications**: Real-time payment result push notifications for payments, refunds, subscription status changes, and more\n- **Security & Reliability**: PCI DSS certified, RSA signature verification, enforced TLS 1.2+ encryption\n\n### Use Cases\n\n| Scenario | Description |\n|----------|-------------|\n| **AI Products** | ChatGPT-like applications, AI writing tools, AI image generation with usage-based billing or subscriptions |\n| **SaaS Services** | Enterprise software subscriptions, online collaboration tools, cloud services with periodic payments |\n| **Content Platforms** | Membership subscriptions, paid content, tipping scenarios |\n\n## Table of Contents\n\n- [Latest Release Highlights](#latest-release-highlights)\n- [Requirements](#requirements)\n- [Installation](#installation)\n- [Quick Start](#quick-start)\n- [Configuration](#configuration)\n  - [Framework Integration](#framework-integration)\n- [API Usage](#api-usage)\n  - [Order Management](#order-management)\n  - [Subscription Management](#subscription-management)\n  - [Refund Query](#refund-query)\n  - [Merchant Configuration](#merchant-configuration)\n- [Webhook Handling](#webhook-handling)\n- [Payment Method Types](#payment-method-types)\n- [Advanced Configuration](#advanced-configuration)\n  - [Custom HTTP Transport](#custom-http-transport-axios)\n  - [TLS Security Configuration](#tls-security-configuration)\n  - [Debug Logging](#debug-logging)\n- [Handling New API Fields (ExtraParams)](#handling-new-api-fields-extraparams)\n- [Error Handling](#error-handling)\n- [Support](#support)\n- [License](#license)\n- [Development & Testing](#development-testing)\n\n## Requirements\n\n- Node.js >= 18.0.0\n- npm, yarn, or pnpm\n\n### Version Compatibility\n\n| Node.js Version | Support Status |\n|-----------------|----------------|\n| 22.x | ✅ Fully Supported |\n| 20.x LTS | ✅ Fully Supported (Recommended) |\n| 18.x LTS | ✅ Fully Supported |\n| < 18.x | ❌ Not Supported |\n\n## Installation\n\n```bash\nnpm install @waffo/waffo-node\n# or\nyarn add @waffo/waffo-node\n# or\npnpm add @waffo/waffo-node\n```\n\n## Quick Start\n\n### 1. Initialize the SDK\n\n```typescript\nimport { Waffo, Environment } from '@waffo/waffo-node';\n\nconst waffo = new Waffo({\n  apiKey: 'your-api-key',\n  privateKey: 'your-base64-encoded-private-key',\n  waffoPublicKey: 'waffo-public-key',  // From Waffo Dashboard\n  merchantId: 'your-merchant-id',       // Auto-injected into requests\n  environment: Environment.SANDBOX,     // SANDBOX or PRODUCTION\n});\n```\n\n### 2. Create a Payment Order\n\n```typescript\nimport { randomUUID } from 'crypto';\n\n// Generate idempotency key (max 32 chars)\nconst paymentRequestId = randomUUID().replace(/-/g, '');\n// Important: Persist this ID to database for retry and query\n\nconst response = await waffo.order().create({\n  paymentRequestId,\n  merchantOrderId: `ORDER_${Date.now()}`,\n  orderCurrency: 'HKD',\n  orderAmount: '100.00',\n  orderDescription: 'Test Product',\n  notifyUrl: 'https://your-site.com/webhook',\n  userInfo: {\n    userId: 'user_123',\n    userEmail: 'user@example.com',\n    userTerminal: 'WEB',\n  },\n  paymentInfo: {\n    productName: 'ONE_TIME_PAYMENT',\n  },\n  goodsInfo: {\n    goodsUrl: 'https://your-site.com/product/001',\n  },\n});\n\nif (response.isSuccess()) {\n  const data = response.getData();\n  console.log('Redirect URL:', data.orderAction);\n  console.log('Acquiring Order ID:', data.acquiringOrderId);\n  console.log('Order Status:', data.orderStatus);\n} else {\n  console.log('Error:', response.getMessage());\n}\n```\n\n### 3. Query Order Status\n\n```typescript\nconst response = await waffo.order().inquiry({\n  acquiringOrderId: 'acquiring_order_id',\n});\n\nif (response.isSuccess()) {\n  const data = response.getData();\n  console.log('Order Status:', data.orderStatus);\n  console.log('Merchant Order ID:', data.merchantOrderId);\n  console.log('Order Amount:', data.orderAmount);\n  console.log('Order Currency:', data.orderCurrency);\n  // Tip: Verify amount and currency match your records\n}\n```\n\n## Configuration\n\n### Full Configuration Options\n\n```typescript\nimport { Waffo, Environment } from '@waffo/waffo-node';\n\nconst waffo = new Waffo({\n  // Required\n  apiKey: 'your-api-key',                    // API Key\n  privateKey: 'your-base64-private-key',     // Base64 encoded merchant private key\n  waffoPublicKey: 'waffo-public-key',        // Waffo public key (from Dashboard)\n  environment: Environment.SANDBOX,           // SANDBOX or PRODUCTION (required)\n\n  // Optional\n  merchantId: 'your-merchant-id',            // Default merchant ID (auto-injected)\n  connectTimeout: 10000,                     // Connection timeout in ms (default: 10000)\n  readTimeout: 30000,                        // Read timeout in ms (default: 30000)\n  logger: console,                           // Custom logger\n  httpTransport: customTransport,            // Custom HTTP transport\n});\n```\n\n### Environment Variables\n\n```bash\n# Set environment variables\nexport WAFFO_API_KEY=your-api-key\nexport WAFFO_PRIVATE_KEY=your-private-key\nexport WAFFO_PUBLIC_KEY=waffo-public-key       # Waffo public key\nexport WAFFO_ENVIRONMENT=SANDBOX               # Required: SANDBOX or PRODUCTION\nexport WAFFO_MERCHANT_ID=your-merchant-id      # Optional\n```\n\n```typescript\nimport { Waffo } from '@waffo/waffo-node';\n\nconst waffo = Waffo.fromEnv();\n```\n\n### Environment URLs\n\n| Environment | Base URL | Description |\n|-------------|----------|-------------|\n| `SANDBOX` | `https://api-sandbox.waffo.com` | Test environment |\n| `PRODUCTION` | `https://api.waffo.com` | Production environment |\n\n> **Important**: Environment must be explicitly specified. SDKs do not default to any environment to prevent accidental requests to wrong environments.\n\n### Request-Level Configuration\n\n```typescript\nconst response = await waffo.order().create(params, {\n  connectTimeout: 10000,\n  readTimeout: 30000,\n});\n```\n\n### Framework Integration\n\n#### Express Integration\n\n```typescript\nimport express from 'express';\nimport { Waffo, Environment } from '@waffo/waffo-node';\n\nconst app = express();\nconst waffo = new Waffo({\n  apiKey: process.env.WAFFO_API_KEY!,\n  privateKey: process.env.WAFFO_PRIVATE_KEY!,\n  waffoPublicKey: process.env.WAFFO_PUBLIC_KEY!,\n  environment: Environment.SANDBOX,\n});\n\n// Webhook endpoint\napp.post('/webhook', express.raw({ type: 'application/json' }), async (req, res) => {\n  const body = req.body.toString();\n  const signature = req.headers['x-signature'] as string;\n\n  const webhookHandler = waffo.webhook()\n    .onPayment((notification) => {\n      console.log('Payment received:', notification.result?.acquiringOrderId);\n    });\n\n  const result = await webhookHandler.handleWebhook(body, signature);\n  res.setHeader('X-SIGNATURE', result.responseSignature);\n  res.status(200).json(result.responseBody);\n});\n\napp.listen(3000);\n```\n\n#### NestJS Integration\n\n```typescript\n// waffo.module.ts\nimport { Module, Global } from '@nestjs/common';\nimport { Waffo, Environment } from '@waffo/waffo-node';\n\n@Global()\n@Module({\n  providers: [\n    {\n      provide: 'WAFFO',\n      useFactory: () => {\n        return new Waffo({\n          apiKey: process.env.WAFFO_API_KEY!,\n          privateKey: process.env.WAFFO_PRIVATE_KEY!,\n          waffoPublicKey: process.env.WAFFO_PUBLIC_KEY!,\n          environment: Environment.SANDBOX,\n        });\n      },\n    },\n  ],\n  exports: ['WAFFO'],\n})\nexport class WaffoModule {}\n\n// payment.controller.ts\nimport { Controller, Post, Body, Headers, Inject, Res } from '@nestjs/common';\nimport { Waffo } from '@waffo/waffo-node';\nimport { Response } from 'express';\n\n@Controller('payment')\nexport class PaymentController {\n  constructor(@Inject('WAFFO') private readonly waffo: Waffo) {}\n\n  @Post('webhook')\n  async handleWebhook(\n    @Body() body: string,\n    @Headers('x-signature') signature: string,\n    @Res() res: Response,\n  ) {\n    const webhookHandler = this.waffo.webhook()\n      .onPayment((notification) => {\n        console.log('Payment received:', notification.result?.acquiringOrderId);\n      });\n\n    const result = await webhookHandler.handleWebhook(body, signature);\n    res.setHeader('X-SIGNATURE', result.responseSignature);\n    res.status(200).json(result.responseBody);\n  }\n}\n```\n\n#### Fastify Integration\n\n```typescript\nimport Fastify from 'fastify';\nimport { Waffo, Environment } from '@waffo/waffo-node';\n\nconst fastify = Fastify();\nconst waffo = new Waffo({\n  apiKey: process.env.WAFFO_API_KEY!,\n  privateKey: process.env.WAFFO_PRIVATE_KEY!,\n  waffoPublicKey: process.env.WAFFO_PUBLIC_KEY!,\n  environment: Environment.SANDBOX,\n});\n\n// Register raw body parser for webhooks\nfastify.addContentTypeParser('application/json', { parseAs: 'string' }, (req, body, done) => {\n  done(null, body);\n});\n\nfastify.post('/webhook', async (request, reply) => {\n  const body = request.body as string;\n  const signature = request.headers['x-signature'] as string;\n\n  const webhookHandler = waffo.webhook()\n    .onPayment((notification) => {\n      console.log('Payment received:', notification.result?.acquiringOrderId);\n    });\n\n  const result = await webhookHandler.handleWebhook(body, signature);\n  reply.header('X-SIGNATURE', result.responseSignature);\n  return result.responseBody;\n});\n\nfastify.listen({ port: 3000 });\n```\n\n## API Usage\n\n### Order Management\n\n#### Create Order\n\n```typescript\nimport { randomUUID } from 'crypto';\n\nconst response = await waffo.order().create({\n  paymentRequestId: randomUUID().replace(/-/g, ''),  // Idempotency key, persist it\n  merchantOrderId: `ORDER_${Date.now()}`,\n  orderCurrency: 'BRL',  // Brazilian Real\n  orderAmount: '100.00',\n  orderDescription: 'Product Name',\n  orderRequestedAt: new Date().toISOString(),\n  merchantInfo: {\n    merchantId: 'your-merchant-id',\n  },\n  userInfo: {\n    userId: 'user_123',\n    userEmail: 'user@example.com',\n    userTerminal: 'WEB',\n  },\n  paymentInfo: {\n    productName: 'ONE_TIME_PAYMENT',\n    payMethodType: 'CREDITCARD',  // CREDITCARD, DEBITCARD, EWALLET, VA, etc.\n    // payMethodName: 'CC_VISA',  // Optional: specify exact payment method\n  },\n  goodsInfo: {\n    goodsUrl: 'https://your-site.com/product/001',\n  },\n  notifyUrl: 'https://your-site.com/webhook',\n  successRedirectUrl: 'https://your-site.com/success',\n  failedRedirectUrl: 'https://your-site.com/failed',\n  cancelRedirectUrl: 'https://your-site.com/cancel',\n});\n\nif (response.isSuccess()) {\n  const data = response.getData();\n  console.log('Checkout URL:', data.orderAction);\n}\n```\n\n#### Combine Multiple Payment Methods\n\n```typescript\n// Allow user to choose between credit card or debit card\npaymentInfo: {\n  productName: 'ONE_TIME_PAYMENT',\n  payMethodType: 'CREDITCARD,DEBITCARD',  // Comma-separated for multiple types\n}\n```\n\n#### Query Order\n\n```typescript\nconst response = await waffo.order().inquiry({\n  acquiringOrderId: 'acquiring_order_id',\n});\n```\n\n#### Cancel Order\n\n```typescript\nconst response = await waffo.order().cancel({\n  acquiringOrderId: 'acquiring_order_id',\n  orderRequestedAt: new Date().toISOString(),\n});\n```\n\n#### Refund Order\n\n```typescript\nimport { randomUUID } from 'crypto';\n\n// Generate idempotency key (max 32 chars)\nconst refundRequestId = randomUUID().replace(/-/g, '');\n// Important: Persist this ID for retry and query\n\nconst response = await waffo.order().refund({\n  refundRequestId,\n  acquiringOrderId: 'acquiring_order_id',\n  refundAmount: '50.00',\n  refundReason: 'Customer requested refund',\n});\n```\n\n#### Capture Order\n\n```typescript\n// For pre-authorized payments\nconst response = await waffo.order().capture({\n  paymentRequestId: 'unique-request-id',\n  merchantId: 'merchant-123',\n  captureAmount: '10.00',\n});\n```\n\n### Subscription Management\n\n#### Create Subscription\n\n```typescript\nimport { randomUUID } from 'crypto';\n\nconst subscriptionRequest = randomUUID().replace(/-/g, '');\n\nconst response = await waffo.subscription().create({\n  subscriptionRequest,\n  merchantSubscriptionId: `MSUB_${Date.now()}`,\n  currency: 'HKD',\n  amount: '99.00',\n  payMethodType: 'CREDITCARD,DEBITCARD,APPLEPAY,GOOGLEPAY',\n  productInfo: {\n    description: 'Monthly Subscription',\n    periodType: 'MONTHLY',\n    periodInterval: '1',\n  },\n  userInfo: {\n    userId: 'user_123',\n    userEmail: 'user@example.com',\n  },\n  requestedAt: new Date().toISOString(),\n  successRedirectUrl: 'https://your-site.com/subscription/success',\n  failedRedirectUrl: 'https://your-site.com/subscription/failed',\n  cancelRedirectUrl: 'https://your-site.com/subscription/cancel',\n  notifyUrl: 'https://your-site.com/webhook/subscription',\n  subscriptionManagementUrl: 'https://your-site.com/subscription/manage',\n});\n\nif (response.isSuccess()) {\n  const data = response.getData();\n  console.log('Waffo Subscription ID:', data.subscriptionId);\n  console.log('Status:', data.subscriptionStatus);\n  console.log('Action:', data.subscriptionAction);\n}\n```\n\n#### Subscription with Trial Period\n\n```typescript\nproductInfo: {\n  description: 'Monthly subscription with 7-day free trial',\n  periodType: 'MONTHLY',\n  periodInterval: '1',\n  numberOfPeriod: '12',\n  // Trial period configuration\n  trialPeriodType: 'DAILY',\n  trialPeriodInterval: '7',\n  trialPeriodAmount: '0',  // Free trial\n  numberOfTrialPeriod: '1',\n}\n```\n\n#### Query Subscription\n\n```typescript\n// Query by subscriptionId\nconst response = await waffo.subscription().inquiry({\n  subscriptionId: 'subscription_id',\n  paymentDetails: 1,  // 1: include payment details, 0: exclude\n});\n\n// Or query by subscriptionRequest\nconst response = await waffo.subscription().inquiry({\n  subscriptionRequest: 'subscription_request',\n});\n```\n\n#### Cancel Subscription\n\n```typescript\nconst response = await waffo.subscription().cancel({\n  subscriptionId: 'subscription_id',\n});\n```\n\n#### Get Subscription Management URL\n\n```typescript\nconst response = await waffo.subscription().manage({\n  subscriptionId: 'subscription_id',\n});\n\nif (response.isSuccess()) {\n  const managementUrl = response.getData().managementUrl;\n  // Redirect user to this URL to manage subscription\n}\n```\n\n<!-- sdk-sync:start:Update%20Subscription -->\n#### Update Subscription\n\nUpdate the billing amounts of an active subscription without re-authorization. Provide `subscriptionRequest` or `subscriptionId`. To charge a seat add-on immediately, include `topupInfo`; the updated billing amounts take effect from the next billing period.\n\n```typescript\nconst response = await waffo.subscription().update({\n  subscriptionId: 'subscription_id',\n  amount: '129.00',  // New per-period amount from the next billing period\n  productInfo: {\n    trialPeriodAmount: '0',\n    scheduledAmounts: [\n      { period: '2', amount: '99.00' },   // Per-period override\n      { period: '3', amount: '129.00' },\n    ],\n  },\n  topupInfo: {\n    topupRequest: 'mimo-topup-001', // Idempotency key for this top-up\n    topupAmount: '30.00',           // Amount charged immediately\n    description: 'Seat add-on 3 seats',\n    orderExpiredAt: '2030-01-01T00:00:00Z',\n  },\n});\n\nif (response.isSuccess()) {\n  const data = response.getData();\n  console.log('Previous Amount:', data.previousAmount);\n  console.log('New Amount:', data.newAmount);\n  console.log('Next Effective Period:', data.nextEffectivePeriod);\n  console.log('Top-up Order:', data.topupInfo?.acquiringOrderId);\n  console.log('Top-up Status:', data.topupInfo?.topupStatus);\n}\n```\n<!-- sdk-sync:end:Update%20Subscription -->\n\n### Subscription Change (Upgrade/Downgrade)\n\nChange an existing subscription to a new plan (upgrade or downgrade).\n\n#### Change Subscription\n\n```typescript\nimport { randomUUID } from 'crypto';\nimport { WaffoUnknownStatusError } from '@waffo/waffo-node';\n\n// New subscription request ID for the change\nconst subscriptionRequest = randomUUID().replace(/-/g, '');\nconst originSubscriptionRequest = 'original-subscription-request-id';\n\ntry {\n  const response = await waffo.subscription().change({\n    subscriptionRequest,\n    originSubscriptionRequest,\n    remainingAmount: '50.00',  // Remaining value from original subscription\n    currency: 'HKD',\n    requestedAt: new Date().toISOString(),\n    notifyUrl: 'https://your-site.com/webhook/subscription',\n    productInfoList: [\n      {\n        description: 'Annual Premium Subscription (12 months)',\n        periodType: 'MONTHLY',\n        periodInterval: '12',\n        amount: '999.00',\n      },\n    ],\n    userInfo: {\n      userId: 'user_123',\n      userEmail: 'user@example.com',\n    },\n    goodsInfo: {\n      goodsId: 'GOODS_PREMIUM',\n      goodsName: 'Premium Plan',\n    },\n    paymentInfo: {\n      productName: 'SUBSCRIPTION',\n    },\n    // Optional fields\n    merchantSubscriptionId: `MSUB_UPGRADE_${Date.now()}`,\n    successRedirectUrl: 'https://your-site.com/subscription/upgrade/success',\n    failedRedirectUrl: 'https://your-site.com/subscription/upgrade/failed',\n    cancelRedirectUrl: 'https://your-site.com/subscription/upgrade/cancel',\n    subscriptionManagementUrl: 'https://your-site.com/subscription/manage',\n  });\n\n  if (response.isSuccess()) {\n    const data = response.getData();\n    console.log('Change Status:', data.subscriptionChangeStatus);\n    console.log('New Subscription ID:', data.subscriptionId);\n\n    // Handle different statuses\n    if (data.subscriptionChangeStatus === 'AUTHORIZATION_REQUIRED') {\n      // User needs to authorize the change\n      const action = JSON.parse(data.subscriptionAction);\n      console.log('Redirect user to:', action.webUrl);\n    } else if (data.subscriptionChangeStatus === 'SUCCESS') {\n      // Change completed successfully\n      console.log('Subscription upgraded successfully');\n    }\n  }\n} catch (error) {\n  if (error instanceof WaffoUnknownStatusError) {\n    // Status unknown - DO NOT assume failure! User may have completed payment\n    console.error('Unknown status, need to query:', error.message);\n\n    // Correct handling: Call inquiry API to confirm actual status\n    const inquiryResponse = await waffo.subscription().changeInquiry({\n      subscriptionRequest,\n      originSubscriptionRequest,\n    });\n    // Or wait for Webhook callback\n  } else {\n    throw error;\n  }\n}\n```\n\n#### Subscription Change Status Values\n\n| Status | Description |\n|--------|-------------|\n| `IN_PROGRESS` | Change is being processed |\n| `AUTHORIZATION_REQUIRED` | User needs to authorize the change (redirect to webUrl) |\n| `SUCCESS` | Change completed successfully |\n| `CLOSED` | Change was closed (timeout or failed) |\n\n#### Query Subscription Change Status\n\n```typescript\nconst response = await waffo.subscription().changeInquiry({\n  subscriptionRequest: 'new-subscription-request-id',\n  originSubscriptionRequest: 'original-subscription-request-id',\n});\n\nif (response.isSuccess()) {\n  const data = response.getData();\n  console.log('Change Status:', data.subscriptionChangeStatus);\n  console.log('New Subscription ID:', data.subscriptionId);\n  console.log('Remaining Amount:', data.remainingAmount);\n  console.log('Currency:', data.currency);\n}\n```\n\n### Refund Query\n\n```typescript\n// Query by refundRequestId (merchant-generated idempotency key)\nconst response = await waffo.refund().inquiry({\n  refundRequestId: 'refund_request_id',\n});\n\n// Or query by acquiringRefundOrderId (Waffo refund order ID)\nconst response = await waffo.refund().inquiry({\n  acquiringRefundOrderId: 'acquiring_refund_order_id',\n});\n```\n\n### Merchant Configuration\n\n#### Query Merchant Configuration\n\n```typescript\n// merchantId is auto-injected from config if not provided\nconst response = await waffo.merchantConfig().inquiry({});\n\nif (response.isSuccess()) {\n  const data = response.getData();\n  console.log('Daily Limit:', data.totalDailyLimit);\n  console.log('Remaining Daily Limit:', data.remainingDailyLimit);\n  console.log('Transaction Limit:', data.transactionLimit);\n}\n```\n\n#### Query Available Payment Methods\n\nThe `payMethodDetails` response includes the payment method category, supported currency, order amount limits, and refund policy. `currentStatus` can be absent when real-time availability is temporarily unavailable.\n\n```typescript\n// merchantId is auto-injected from config if not provided\nconst response = await waffo.payMethodConfig().inquiry({});\n\nif (response.isSuccess()) {\n  const data = response.getData();\n  for (const detail of data?.payMethodDetails ?? []) {\n    console.log({\n      name: detail.payMethodName,\n      type: detail.payMethodType,\n      country: detail.country,\n      currency: detail.currency,\n      amountRange: [detail.orderAmountMin, detail.orderAmountMax],\n      refundAllowed: detail.refundAllowed,\n      currentStatus: detail.currentStatus,\n    });\n  }\n} else {\n  console.error('Pay method config inquiry failed:', response.getCode(), response.getMessage());\n}\n```\n\n### Wallet Address Inquiry (x402)\n\nInquire the on-chain stablecoin receiving address for an x402 payment. The response returns the target network, the on-chain token contract, and the Waffo platform wallet address to send funds to. Phase 1 supports `USDC`.\n\n```typescript\n// paymentRequestId: unique idempotency key for this inquiry\n// orderCurrency: settlement currency of the order (Phase 1 supports USDC)\n// merchantInfo is auto-injected from config if not provided\nconst response = await waffo.wallet().inquiry({\n  paymentRequestId: 'unique-request-id',\n  orderCurrency: 'USDC',\n});\n\nif (response.isSuccess()) {\n  const data = response.getData();\n  console.log('Network:', data?.network); // CAIP-2 network id, e.g. eip155:8453 (Base mainnet)\n  console.log('Asset:', data?.asset);     // on-chain token contract address\n  console.log('Pay to:', data?.payTo);    // Waffo platform receiving wallet address\n} else {\n  console.error('Wallet inquiry failed:', response.getCode(), response.getMessage());\n}\n```\n\n#### Wallet Inquiry Response Fields\n\n| Field | Description |\n|-------|-------------|\n| `network` | CAIP-2 network id (Phase 1: `eip155:8453`, Base mainnet) |\n| `asset` | On-chain token contract address for the network + currency |\n| `payTo` | Waffo platform receiving wallet address (send funds here) |\n\n## Webhook Handling\n\nWaffo pushes payment results, refund results, subscription status changes, and more via webhooks.\n\n### Webhook Handler Example\n\n```typescript\nimport { Waffo, Environment } from '@waffo/waffo-node';\nimport express from 'express';\n\nconst app = express();\nconst waffo = new Waffo({ /* config */ });\n\n// Create webhook handler\nconst webhookHandler = waffo.webhook()\n  .onPayment((notification) => {\n    console.log('Payment notification received:');\n    console.log('  Acquiring Order ID:', notification.result?.acquiringOrderId);\n    console.log('  Order Status:', notification.result?.orderStatus);\n    console.log('  Payment Amount:', notification.result?.orderAmount);\n    console.log('  Payment Currency:', notification.result?.orderCurrency);\n\n    // Tip: First verify amount and currency match your records\n    // Then handle based on orderStatus\n\n    if (notification.result?.orderStatus === 'PAY_SUCCESS') {\n      // Payment successful - update order status, deliver goods, etc.\n    }\n  })\n  .onRefund((notification) => {\n    console.log('Refund notification:', notification.result?.acquiringRefundOrderId);\n    // Handle refund notification\n  })\n  .onSubscriptionStatus((notification) => {\n    console.log('Subscription status notification:');\n    console.log('  Subscription ID:', notification.result?.subscriptionId);\n    console.log('  Subscription Status:', notification.result?.subscriptionStatus);\n\n    switch (notification.result?.subscriptionStatus) {\n      case 'ACTIVE':\n        // Subscription activated - grant membership privileges\n        break;\n      case 'CLOSE':\n        // Subscription closed (timeout or failed)\n        break;\n      case 'MERCHANT_CANCELLED':\n        // Merchant cancelled subscription\n        break;\n      case 'USER_CANCELLED':\n        // User cancelled subscription\n        break;\n      case 'CHANNEL_CANCELLED':\n        // Channel cancelled subscription\n        break;\n      case 'EXPIRED':\n        // Subscription expired\n        break;\n    }\n  })\n  .onSubscriptionPeriodChanged((notification) => {\n    console.log('Subscription period changed:', notification.result?.subscriptionId);\n    // Key fields to track:\n    // - notification.result?.period: Current period number\n    // - notification.result?.nextChargeAt: Next billing time\n    // - notification.result?.subscriptionStatus: Subscription status\n    // - notification.result?.orderStatus: Current billing order status (SUCCESS/FAILED)\n    // - notification.result?.orderAmount: Billing amount\n    // - notification.result?.orderCurrency: Billing currency\n  })\n  .onSubscriptionChange((notification) => {\n    console.log('Subscription change notification:');\n    console.log('  Change Request ID:', notification.result?.subscriptionRequest);\n    console.log('  Change Status:', notification.result?.subscriptionChangeStatus);\n    console.log('  Origin Subscription:', notification.result?.originSubscriptionId);\n    console.log('  New Subscription:', notification.result?.subscriptionId);\n\n    if (notification.result?.subscriptionChangeStatus === 'SUCCESS') {\n      // Subscription change successful\n      // - Original subscription is now MERCHANT_CANCELLED\n      // - New subscription is now ACTIVE\n      // Update user's subscription level accordingly\n    } else if (notification.result?.subscriptionChangeStatus === 'CLOSED') {\n      // Subscription change failed/closed\n      // Original subscription remains unchanged\n    }\n  });\n\n// Express route\napp.post('/webhook', express.raw({ type: 'application/json' }), async (req, res) => {\n  const body = req.body.toString();\n  const signature = req.headers['x-signature'] as string;\n\n  const result = await webhookHandler.handleWebhook(body, signature);\n\n  res.setHeader('X-SIGNATURE', result.responseSignature);\n  res.status(200).json(result.responseBody);\n});\n```\n\n### Webhook Notification Types\n\n| Event Type | Handler Method | Description |\n|------------|----------------|-------------|\n| `PAYMENT_NOTIFICATION` | `onPayment()` | Payment result notification (triggered on every payment attempt, including retries) |\n| `REFUND_NOTIFICATION` | `onRefund()` | Refund result notification |\n| `SUBSCRIPTION_STATUS_NOTIFICATION` | `onSubscriptionStatus()` | Subscription status change notification (triggered when subscription main record status changes) |\n| `SUBSCRIPTION_PERIOD_CHANGED_NOTIFICATION` | `onSubscriptionPeriodChanged()` | Subscription period change notification (final result of each period) |\n| `SUBSCRIPTION_CHANGE_NOTIFICATION` | `onSubscriptionChange()` | Subscription change (upgrade/downgrade) result notification |\n\n### Subscription Notification Types Explained\n\n| Notification Type | Trigger Condition | Scope | Includes Retry Events | Typical Use Case |\n|-------------------|-------------------|-------|----------------------|------------------|\n| `SUBSCRIPTION_STATUS_NOTIFICATION` | Subscription main record status changes | Subscription level | No | Track subscription lifecycle: first payment success activation (ACTIVE), cancellation (MERCHANT_CANCELLED, CHANNEL_CANCELLED), first payment failure close (CLOSE), etc. |\n| `SUBSCRIPTION_PERIOD_CHANGED_NOTIFICATION` | Subscription period reaches final state | Period level | No (only final result) | Only need final result of each period, no intermediate retry events |\n| `SUBSCRIPTION_CHANGE_NOTIFICATION` | Subscription change (upgrade/downgrade) completes | Change request level | No (only final result) | Track subscription change results: SUCCESS or CLOSED |\n| `PAYMENT_NOTIFICATION` | Every payment order | Payment order level | Yes (includes all retries) | Need complete details of every payment attempt, including failure reasons, timestamps, retry details |\n\n> **Selection Guide**:\n> - If you only care about subscription activation/cancellation, use `SUBSCRIPTION_STATUS_NOTIFICATION`\n> - If you only care about final renewal result of each period, use `SUBSCRIPTION_PERIOD_CHANGED_NOTIFICATION`\n> - If you only care about subscription change (upgrade/downgrade) final result, use `SUBSCRIPTION_CHANGE_NOTIFICATION`\n> - If you need to track every payment attempt (including retries), use `PAYMENT_NOTIFICATION`\n\n> **Subscription Payment Note**: Each period's payment (including first payment and renewals) triggers `PAYMENT_NOTIFICATION` events. You can get subscription-related info (subscriptionId, period, etc.) from `subscriptionInfo`.\n\n> **Subscription Change (Upgrade/Downgrade) Webhook Note**:\n> When a subscription change is processed, the following notifications are triggered:\n> - `SUBSCRIPTION_CHANGE_NOTIFICATION`: When subscription change completes (SUCCESS or CLOSED)\n> - `SUBSCRIPTION_STATUS_NOTIFICATION`: When original subscription status changes to `MERCHANT_CANCELLED`\n> - `SUBSCRIPTION_STATUS_NOTIFICATION`: When new subscription status changes to `ACTIVE`\n> - `PAYMENT_NOTIFICATION`: If upgrade requires additional payment (price difference)\n\n### Webhook Notification Payload Examples\n\nThe following examples show the actual payload structure for each notification type.\n\n#### PAYMENT_NOTIFICATION\n\n```json\n{\n  \"eventType\": \"PAYMENT_NOTIFICATION\",\n  \"result\": {\n    \"acquiringOrderId\": \"A2026xxxxxxxxxxxxxxxxxxxx\",\n    \"orderStatus\": \"PAY_SUCCESS\",\n    \"orderAmount\": \"109.00\",\n    \"orderCurrency\": \"USD\",\n    \"finalDealAmount\": \"109.00\",\n    \"userCurrency\": \"USD\",\n    \"orderDescription\": \"Sample Product\",\n    \"orderRequestedAt\": \"2026-02-28T10:05:58.000Z\",\n    \"orderCompletedAt\": \"2026-02-28T10:06:10.000Z\",\n    \"orderUpdatedAt\": \"2026-02-28T10:06:10.000Z\",\n    \"refundExpiryAt\": \"2026-08-26T23:59:59.999Z\",\n    \"userInfo\": {\n      \"userId\": \"user@example.com\",\n      \"userEmail\": \"user@example.com\"\n    },\n    \"merchantInfo\": {\n      \"merchantId\": \"YOUR_MERCHANT_ID\"\n    },\n    \"goodsInfo\": {\n      \"goodsId\": \"goods_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\",\n      \"goodsName\": \"Sample Product\"\n    },\n    \"addressInfo\": {},\n    \"paymentInfo\": {\n      \"productName\": \"SUBSCRIPTION\",\n      \"payMethodType\": \"CREDITCARD\",\n      \"payMethodName\": \"CC_VISA\",\n      \"payMethodProperties\": \"{\\\"cardToken\\\":\\\"CARD_TOKEN_XXXXXXXXXXXXXXXXXXXX\\\",\\\"cardTransactionType\\\":\\\"CIT\\\"}\",\n      \"payMethodResponse\": \"{\\\"maskCardData\\\":\\\"XXXX42****XX4242\\\"}\"\n    },\n    \"subscriptionInfo\": {\n      \"subscriptionId\": \"SC2026xxxxxxxxxxxxxxxxxxxxxxxxxx\",\n      \"subscriptionRequest\": \"sub_req_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\",\n      \"merchantRequest\": \"sub_req_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\",\n      \"period\": \"1\"\n    },\n    \"cancelRedirectUrl\": \"https://YOUR_DOMAIN/checkout/YOUR_CHECKOUT_ID\"\n  }\n}\n```\n\nFor x402 stablecoin payments, `PAYMENT_NOTIFICATION.result` also includes `x402Info` with `x402Request`, `paymentSignatureHeader`, and `x402Response`.\n\n#### SUBSCRIPTION_STATUS_NOTIFICATION / SUBSCRIPTION_PERIOD_CHANGED_NOTIFICATION\n\nThese two notification types share the same payload structure:\n\n```json\n{\n  \"eventType\": \"SUBSCRIPTION_STATUS_NOTIFICATION\",\n  \"result\": {\n    \"subscriptionId\": \"SC2026xxxxxxxxxxxxxxxxxxxxxxxxxx\",\n    \"subscriptionRequest\": \"sub_req_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\",\n    \"merchantSubscriptionId\": \"sub_req_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\",\n    \"subscriptionStatus\": \"ACTIVE\",\n    \"currency\": \"USD\",\n    \"userCurrency\": \"USD\",\n    \"amount\": \"109.00\",\n    \"requestedAt\": \"2026-02-28T10:05:58.000Z\",\n    \"updatedAt\": \"2026-02-28T10:06:10.000Z\",\n    \"userInfo\": {\n      \"userId\": \"user@example.com\",\n      \"userEmail\": \"user@example.com\"\n    },\n    \"merchantInfo\": {\n      \"merchantId\": \"YOUR_MERCHANT_ID\"\n    },\n    \"goodsInfo\": {\n      \"goodsId\": \"goods_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\",\n      \"goodsName\": \"Sample Product\"\n    },\n    \"productInfo\": {\n      \"periodType\": \"MONTHLY\",\n      \"periodInterval\": \"1\",\n      \"currentPeriod\": \"1\",\n      \"startDateTime\": \"2026-02-28T10:06:10.000Z\",\n      \"nextPaymentDateTime\": \"2026-03-28T10:06:10.000Z\",\n      \"description\": \"Sample Product\"\n    },\n    \"paymentInfo\": {\n      \"productName\": \"SUBSCRIPTION\",\n      \"payMethodType\": \"CREDITCARD\",\n      \"payMethodName\": \"CC_VISA\",\n      \"payMethodProperties\": \"{}\"\n    },\n    \"paymentDetails\": [\n      {\n        \"period\": \"1\",\n        \"acquiringOrderId\": \"A2026xxxxxxxxxxxxxxxxxxxx\",\n        \"orderAmount\": \"109.00\",\n        \"orderCurrency\": \"USD\",\n        \"orderStatus\": \"PAY_SUCCESS\",\n        \"orderUpdatedAt\": \"2026-02-28T10:06:10.000Z\"\n      }\n    ]\n  }\n}\n```\n\n<!-- sdk-sync:start:Payment%20Method%20Types -->\n## Payment Method Types\n\n### payMethodType Reference\n\n| Type | Description | Example payMethodName |\n|------|-------------|----------------------|\n| `CREDITCARD` | Credit Card | CC_VISA, CC_MASTERCARD, CC_AMEX, CC_JCB, etc. |\n| `DEBITCARD` | Debit Card | DC_VISA, DC_MASTERCARD, DC_ELO, etc. |\n| `EWALLET` | E-Wallet | GCASH, DANA, PROMPTPAY, GRABPAY, etc. |\n| `VA` | Virtual Account | BCA, BNI, BRI, MANDIRI, etc. |\n| `APPLEPAY` | Apple Pay | APPLEPAY |\n| `GOOGLEPAY` | Google Pay | GOOGLEPAY |\n\n### Usage Examples\n\nSpecify a type and let the user choose on the checkout page:\n\n```json\n{\"paymentInfo\": {\"payMethodType\": \"CREDITCARD\"}}\n```\n\nSpecify an exact payment method:\n\n```json\n{\"paymentInfo\": {\"payMethodType\": \"CREDITCARD\", \"payMethodName\": \"CC_VISA\"}}\n```\n\nCombine multiple types:\n\n```json\n{\"paymentInfo\": {\"payMethodType\": \"CREDITCARD,DEBITCARD\"}}\n```\n\nSelect an e-wallet channel:\n\n```json\n{\"paymentInfo\": {\"payMethodType\": \"EWALLET\", \"payMethodName\": \"GCASH\"}}\n```\n\n> **Note**: For available `ProductName`, `PayMethodType`, `PayMethodName` values, merchants can log in to [Waffo Portal](https://dashboard.waffo.com) to view contracted payment methods (Home → Service → Pay-in).\n<!-- sdk-sync:end:Payment%20Method%20Types -->\n\n## Advanced Configuration\n\n### Custom HTTP Transport (axios)\n\nThe SDK uses native `fetch` by default. For connection pooling or advanced features, implement custom transport:\n\n```typescript\nimport { Waffo, Environment } from '@waffo/waffo-node';\nimport type { HttpTransport, HttpRequest, HttpResponse } from '@waffo/waffo-node';\nimport axios, { AxiosInstance } from 'axios';\nimport https from 'https';\n\n// Create custom HTTP transport using axios\nclass AxiosHttpTransport implements HttpTransport {\n  private client: AxiosInstance;\n\n  constructor() {\n    this.client = axios.create({\n      timeout: 30000,\n      httpsAgent: new https.Agent({\n        minVersion: 'TLSv1.2',\n        maxVersion: 'TLSv1.3',\n      }),\n    });\n  }\n\n  async send(request: HttpRequest): Promise<HttpResponse> {\n    try {\n      const response = await this.client.request({\n        method: request.method as 'POST' | 'GET',\n        url: request.url,\n        headers: request.headers,\n        data: request.body,\n        timeout: request.timeout,\n        validateStatus: () => true, // Don't throw on non-2xx\n      });\n\n      // Convert headers to Record<string, string>\n      const headers: Record<string, string> = {};\n      Object.entries(response.headers).forEach(([key, value]) => {\n        if (typeof value === 'string') {\n          headers[key] = value;\n        }\n      });\n\n      return {\n        statusCode: response.status,\n        headers,\n        body: typeof response.data === 'string'\n          ? response.data\n          : JSON.stringify(response.data),\n      };\n    } catch (error) {\n      if (axios.isAxiosError(error) && error.code === 'ECONNABORTED') {\n        throw new Error('Request timeout');\n      }\n      throw error;\n    }\n  }\n}\n\nconst waffo = new Waffo({\n  apiKey: 'your-api-key',\n  privateKey: 'your-private-key',\n  waffoPublicKey: 'waffo-public-key',\n  environment: Environment.SANDBOX,\n  httpTransport: new AxiosHttpTransport(),\n});\n```\n\n### TLS Security Configuration\n\nThe SDK enforces **TLS 1.2 or higher** by default for all HTTPS communication.\n\nWhen implementing custom HTTP transport, ensure TLS 1.2+ is configured:\n\n```typescript\nimport https from 'https';\n\nconst httpsAgent = new https.Agent({\n  minVersion: 'TLSv1.2',\n  maxVersion: 'TLSv1.3',\n  // Optional: reject unauthorized certificates (default: true)\n  rejectUnauthorized: true,\n});\n\n// Use with axios or other HTTP clients\nimport axios from 'axios';\nconst client = axios.create({\n  httpsAgent,\n});\n```\n\n### Debug Logging\n\nEnable debug logging to troubleshoot issues during development:\n\n```bash\n# Enable all Waffo SDK debug logs\nDEBUG=waffo:* npm start\n\n# Enable only HTTP request/response logs\nDEBUG=waffo:http npm start\n\n# Enable only signing logs\nDEBUG=waffo:sign npm start\n```\n\nOr configure programmatically:\n\n```typescript\nconst waffo = new Waffo({\n  // ... other config\n  logger: {\n    debug: (msg: string) => console.debug('[WAFFO]', msg),\n    info: (msg: string) => console.info('[WAFFO]', msg),\n    warn: (msg: string) => console.warn('[WAFFO]', msg),\n    error: (msg: string) => console.error('[WAFFO]', msg),\n  },\n});\n```\n\n### Timeout Configuration Recommendations\n\n| Operation Type | Connect Timeout | Read Timeout | Notes |\n|----------------|-----------------|--------------|-------|\n| Create Order | 5s | 30s | Recommended |\n| Create Subscription | 5s | 30s | Recommended |\n| Refund Operation | 5s | 30s | Recommended |\n| Query Operations | 5s | 15s | Can be shorter |\n\n### Connection Pool Recommendations\n\n| Scenario | Max Connections | Max Per Route | Notes |\n|----------|-----------------|---------------|-------|\n| Low Traffic (< 10 QPS) | 20 | 10 | Default config sufficient |\n| Medium Traffic (10-100 QPS) | 50 | 20 | Consider using OkHttp |\n| High Traffic (> 100 QPS) | 100-200 | 50 | Consider Apache HttpClient |\n\n### Instance Reuse\n\nSDK instances are **thread-safe**. Recommended to use as singleton in your application:\n\n```typescript\n// Create once, reuse everywhere\nconst waffo = new Waffo({ /* config */ });\n\nexport { waffo };\n```\n\n### RSA Utilities\n\n```typescript\nimport { RsaUtils } from '@waffo/waffo-node';\n\n// Generate key pair (for testing)\nconst keyPair = RsaUtils.generateKeyPair();\nconsole.log('Public Key (submit to Waffo):', keyPair.publicKey);\nconsole.log('Private Key (keep on your server):', keyPair.privateKey);\n\n// Sign data\nconst signature = RsaUtils.sign(data, privateKey);\n\n// Verify signature\nconst isValid = RsaUtils.verify(data, signature, publicKey);\n```\n\n## Handling New API Fields (ExtraParams)\n\nWhen Waffo API adds new fields that are not yet defined in the SDK, you can use the ExtraParams feature to access these fields without waiting for an SDK update.\n\n### Reading Unknown Fields from Responses\n\n```typescript\n// Get extra field from response\nconst response = await waffo.order().inquiry({ paymentRequestId: 'REQ001' });\nif (response.isSuccess()) {\n  const data = response.getData();\n\n  // Access field not yet defined in SDK\n  const newField = data.extraParams?.['newField'];\n\n  // Or use type assertion if you know the type\n  const typedValue = data.extraParams?.['newField'] as string;\n}\n\n// Get extra field from webhook notification\nwebhookHandler.onPaymentNotification((notification) => {\n  const result = notification.result;\n  const newField = result.extraParams?.['newField'];\n});\n```\n\n### Sending Extra Fields in Requests\n\n```typescript\n// TypeScript types include index signature [key: string]: unknown\n// You can directly add extra fields to any request\nconst response = await waffo.order().create({\n  paymentRequestId: 'REQ001',\n  merchantOrderId: 'ORDER001',\n  // ... other required fields\n  newField: 'value',           // Extra field - no type error\n  nested: { key: 123 }         // Nested object - works too\n});\n```\n\n### Important Notes\n\n> **Upgrade SDK Promptly**\n>\n> ExtraParams is designed as a **temporary solution** for accessing new API fields before SDK updates.\n>\n> **Best Practices:**\n> 1. Check SDK release notes regularly for new field support\n> 2. Once SDK officially supports the field, migrate from `getExtraParam(\"field\")` to the official getter (e.g., `getField()`)\n> 3. The SDK logs a warning when you use `getExtraParam()` on officially supported fields\n>\n> **Why migrate?**\n> - Official getters provide type safety\n> - Better IDE auto-completion and documentation\n> - Reduced risk of typos in field names\n\n## Error Handling\n\n### Error Handling Pattern\n\nSDKs use a hybrid error handling approach:\n- **Business errors**: Returned via `ApiResponse`, check with `response.isSuccess()`\n- **Unknown status exceptions**: Only for **write operations** (may affect funds or status), network timeout or server returning E0001 error code throws `WaffoUnknownStatusError`\n\n### Methods That Throw Unknown Status Exception\n\nOnly these methods that may affect funds or status throw `WaffoUnknownStatusError`:\n\n| Method | Description |\n|--------|-------------|\n| `order().create()` | Create order, may initiate payment |\n| `order().refund()` | Refund, may cause fund changes |\n| `order().cancel()` | Cancel order, affects order status |\n| `subscription().create()` | Create subscription, may cause initial charge |\n| `subscription().cancel()` | Cancel subscription, affects subscription status |\n\n**Query methods do not throw this exception** (e.g., `inquiry()`), because query operations can be safely retried without affecting funds or status.\n\n### WaffoUnknownStatusError Handling\n\n> ⚠️ **IMPORTANT WARNING**\n>\n> When `WaffoUnknownStatusError` is caught, it means **the operation result is uncertain**.\n>\n> **DO NOT directly close the order or assume payment failed!** The user may have already completed payment.\n>\n> **Correct handling:**\n> 1. Call `waffo.order().inquiry()` to query actual order status\n> 2. Or wait for Waffo webhook callback notification\n> 3. Use Waffo's returned order status as the final authority\n\n```typescript\nimport { Waffo, WaffoUnknownStatusError } from '@waffo/waffo-node';\n\ntry {\n  const response = await waffo.order().create(params);\n\n  if (response.isSuccess()) {\n    // Handle success\n    const data = response.getData();\n    console.log('Redirect URL:', data.orderAction);\n  } else {\n    // Handle business error (non-E0001 error code)\n    console.log('Error:', response.getMessage());\n  }\n} catch (error) {\n  if (error instanceof WaffoUnknownStatusError) {\n    // ⚠️ IMPORTANT: Payment status unknown\n    //\n    // [WRONG] Do not close order directly! User may have paid\n    // [CORRECT]\n    //   1. Call inquiry API to query actual order status\n    //   2. Or wait for Waffo webhook callback\n    //   3. Use Waffo's returned status as authority\n\n    console.warn('Status unknown, need to query:', error.message);\n\n    // Query order status (inquiry doesn't throw, can call directly)\n    const inquiryResponse = await waffo.order().inquiry({\n      paymentRequestId: params.paymentRequestId,\n    });\n\n    if (inquiryResponse.isSuccess()) {\n      const status = inquiryResponse.getData().orderStatus;\n      console.log('Actual order status:', status);\n    } else {\n      // Query failed, wait for webhook callback\n      console.error('Query failed, waiting for webhook callback');\n    }\n  } else {\n    throw error;\n  }\n}\n```\n\n### WaffoUnknownStatusError Trigger Scenarios\n\n| Scenario | Description |\n|----------|-------------|\n| Network Timeout | Request timeout, cannot determine if server received request |\n| Connection Failed | Network connection failed, cannot determine server status |\n| E0001 Error Code | Server returned E0001, indicating processing status unknown |\n\n### Error Code Classification\n\nError codes are classified by first letter:\n\n| Prefix | Category | Description |\n|--------|----------|-------------|\n| **S** | SDK Internal Error | SDK client internal error such as network timeout, signing failure, etc. |\n| **A** | Merchant Related | Parameter, signature, permission, contract issues on merchant side |\n| **B** | User Related | User status, balance, authorization issues |\n| **C** | System Related | Waffo system or payment channel issues |\n| **D** | Risk Related | Risk control rejection |\n| **E** | Unknown Status | Server returned unknown status |\n\n### Complete Error Code Table\n\n#### SDK Internal Errors (Sxxxx)\n\n| Code | Description | Exception Type | Handling Suggestion |\n|------|-------------|----------------|---------------------|\n| `S0001` | Network Error | `WaffoUnknownStatusError` | **Status unknown**, need to query order to confirm |\n| `S0002` | Invalid Public Key | `WaffoError` | Check if public key is valid Base64 encoded X509 format |\n| `S0003` | RSA Signing Failed | `WaffoError` | Check if private key format is correct |\n| `S0004` | Response Signature Verification Failed | `ApiResponse.error()` | Check Waffo public key config, contact Waffo |\n| `S0005` | Request Serialization Failed | `ApiResponse.error()` | Check request parameter format |\n| `S0006` | SDK Unknown Error | `ApiResponse.error()` | Check logs, contact technical support |\n| `S0007` | Invalid Private Key | `WaffoError` | Check if private key is valid Base64 encoded PKCS8 format |\n\n> **Important**: `S0001` and `E0001` (returned by server) indicate **unknown status**. Do not close order directly! Should call query API or wait for webhook to confirm actual status.\n\n#### Merchant Related Errors (Axxxxx)\n\n| Code | Description | HTTP Status |\n|------|-------------|-------------|\n| `0` | Success | 200 |\n| `A0001` | Invalid API Key | 401 |\n| `A0002` | Invalid Signature | 401 |\n| `A0003` | Parameter Validation Failed | 400 |\n| `A0004` | Insufficient Permission | 401 |\n| `A0005` | Merchant Limit Exceeded | 400 |\n| `A0006` | Merchant Status Abnormal | 400 |\n| `A0007` | Unsupported Transaction Currency | 400 |\n| `A0008` | Transaction Amount Exceeded | 400 |\n| `A0009` | Order Not Found | 400 |\n| `A0010` | Merchant Contract Does Not Allow This Operation | 400 |\n| `A0011` | Idempotent Parameter Mismatch | 400 |\n| `A0012` | Merchant Account Insufficient Balance | 400 |\n| `A0013` | Order Already Paid, Cannot Cancel | 400 |\n| `A0014` | Refund Rules Do Not Allow Refund | 400 |\n| `A0015` | Payment Channel Does Not Support Cancel | 400 |\n| `A0016` | Payment Channel Rejected Cancel | 400 |\n| `A0017` | Payment Channel Does Not Support Refund | 400 |\n| `A0018` | Payment Method Does Not Match Merchant Contract | 400 |\n| `A0019` | Cannot Refund Due to Chargeback Dispute | 400 |\n| `A0020` | Payment Amount Exceeds Single Transaction Limit | 400 |\n| `A0021` | Cumulative Payment Amount Exceeds Daily Limit | 400 |\n| `A0022` | Multiple Products Exist, Need to Specify Product Name | 400 |\n| `A0023` | Token Expired, Cannot Create Order | 400 |\n| `A0024` | Exchange Rate Expired, Cannot Process Order | 400 |\n| `A0026` | Unsupported Checkout Language | 400 |\n| `A0027` | Refund Count Reached Limit (50 times) | 400 |\n| `A0029` | Invalid Card Data Provided by Merchant | 400 |\n| `A0030` | Card BIN Not Found | 400 |\n| `A0031` | Unsupported Card Scheme or Card Type | 400 |\n| `A0032` | Invalid Payment Token Data | 400 |\n| `A0033` | Multiple Payment Methods with Same Name, Need to Specify Country | 400 |\n| `A0034` | Order Expiry Time Provided by Merchant Has Passed | 400 |\n| `A0035` | Current Order Does Not Support Capture Operation | 400 |\n| `A0036` | Current Order Status Does Not Allow Capture Operation | 400 |\n| `A0037` | User Payment Token Invalid or Expired | 400 |\n| `A0038` | MIT Transaction Requires Verified User Payment Token | 400 |\n| `A0039` | Order Already Refunded by Chargeback Prevention Service | 400 |\n| `A0040` | Order Cannot Be Created Concurrently | 400 |\n| `A0045` | MIT Transaction Cannot Process, tokenId Status Unverified | 400 |\n\n#### User Related Errors (Bxxxxx)\n\n| Code | Description | HTTP Status |\n|------|-------------|-------------|\n| `B0001` | User Status Abnormal | 400 |\n| `B0002` | User Limit Exceeded | 400 |\n| `B0003` | User Insufficient Balance | 400 |\n| `B0004` | User Did Not Pay Within Timeout | 400 |\n| `B0005` | User Authorization Failed | 400 |\n| `B0006` | Invalid Phone Number | 400 |\n| `B0007` | Invalid Email Format | 400 |\n\n#### System Related Errors (Cxxxxx)\n\n| Code | Description | HTTP Status |\n|------|-------------|-------------|\n| `C0001` | System Error | 500 |\n| `C0002` | Merchant Contract Invalid | 500 |\n| `C0003` | Order Status Invalid, Cannot Continue Processing | 500 |\n| `C0004` | Order Information Mismatch | 500 |\n| `C0005` | Payment Channel Rejected | 503 |\n| `C0006` | Payment Channel Error | 503 |\n| `C0007` | Payment Channel Under Maintenance | 503 |\n\n#### Risk Related Errors (Dxxxxx)\n\n| Code | Description | HTTP Status |\n|------|-------------|-------------|\n| `D0001` | Risk Control Rejected | 406 |\n\n#### Unknown Status Errors (Exxxxx)\n\n| Code | Description | HTTP Status |\n|------|-------------|-------------|\n| `E0001` | Unknown Status (Need to query or wait for callback) | 500 |\n\n> **Note**: When receiving `E0001` error code, it indicates transaction status is unknown. **Do not close order directly**, should call query API to confirm actual status, or wait for webhook callback notification.\n\n## Development & Testing\n\n### Build Commands\n\n```bash\n# Install dependencies\nnpm install\n\n# Build the SDK\nnpm run build\n\n# Run tests\nnpm test\n\n# Type check\nnpm run typecheck\n\n# Lint\nnpm run lint\n\n# Format code\nnpm run format\n```\n\n### Generate Types from OpenAPI\n\n```bash\n# From monorepo root\n./scripts/generate-types.sh node\n```\n\n### Run Test Vectors\n\n```bash\n# Run cross-language test vectors\nnpm run test:vectors\n```\n\n## Support\n\n- Documentation: [Waffo Developer Docs](https://dashboard-sandbox.waffo.com/docs/)\n- Issues: [GitHub Issues](https://github.com/waffo-com/waffo-sdk/issues)\n- Technical Support: merchant.support@waffo.com\n\n## License\n\nMIT License - See [LICENSE](LICENSE) file for details.\n","readmeFilename":"README.md"}