diff --git a/processor/package-lock.json b/processor/package-lock.json index fd5ecbf..bcf3a34 100644 --- a/processor/package-lock.json +++ b/processor/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "@adyen/api-library": "22.1.0", "@commercetools-backend/loggers": "22.37.0", - "@commercetools/connect-payments-sdk": "0.12.0", + "@commercetools/connect-payments-sdk": "0.13.0", "@fastify/autoload": "6.0.3", "@fastify/cors": "10.0.1", "@fastify/formbody": "8.0.1", @@ -822,12 +822,12 @@ } }, "node_modules/@commercetools/connect-payments-sdk": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@commercetools/connect-payments-sdk/-/connect-payments-sdk-0.12.0.tgz", - "integrity": "sha512-PS4W15NC4fik78K7tLcRjcU0pickY8nudgaocuEO3Q1lsBMltbzNhd1W3DXmap09O+sVlikOoIqoMIUis1cGjg==", + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@commercetools/connect-payments-sdk/-/connect-payments-sdk-0.13.0.tgz", + "integrity": "sha512-TKTlv5mDI5tRI8PyrCTXHuMmoLU9OEUp0VJC+iMU2P71m/GUVkqHeRwmvVYQKcVky7ntwT98bxf5D7Xo9NKsKA==", "dependencies": { - "@commercetools-backend/loggers": "22.35.1", - "@commercetools/platform-sdk": "7.21.0", + "@commercetools-backend/loggers": "22.37.0", + "@commercetools/platform-sdk": "7.23.0", "@commercetools/sdk-client-v2": "2.5.0", "jsonwebtoken": "9.0.2", "jwks-rsa": "3.1.0", @@ -835,39 +835,6 @@ "logform": "2.7.0" } }, - "node_modules/@commercetools/connect-payments-sdk/node_modules/@commercetools-backend/loggers": { - "version": "22.35.1", - "resolved": "https://registry.npmjs.org/@commercetools-backend/loggers/-/loggers-22.35.1.tgz", - "integrity": "sha512-x50zvi9bYOo2TSarwApHx6TACbcJHA9z5ACtSzIrPQyhDcCX0Z7qS4bwQBe2Vfw7pG5pOwNEghXcNuIthI46OQ==", - "dependencies": { - "@babel/runtime": "^7.22.15", - "@babel/runtime-corejs3": "^7.22.15", - "@types/lodash": "^4.14.198", - "@types/triple-beam": "1.3.5", - "express-winston": "4.2.0", - "fast-safe-stringify": "2.1.1", - "lodash": "4.17.21", - "logform": "2.6.0", - "triple-beam": "1.4.1", - "winston": "3.13.0" - } - }, - "node_modules/@commercetools/connect-payments-sdk/node_modules/@commercetools-backend/loggers/node_modules/logform": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/logform/-/logform-2.6.0.tgz", - "integrity": "sha512-1ulHeNPp6k/LD8H91o7VYFBng5i1BDE7HoKxVbZiGFidS1Rj65qcywLxX+pVfAPoQJEjRdvKcusKwOupHCVOVQ==", - "dependencies": { - "@colors/colors": "1.6.0", - "@types/triple-beam": "^1.3.2", - "fecha": "^4.2.0", - "ms": "^2.1.1", - "safe-stable-stringify": "^2.3.1", - "triple-beam": "^1.3.0" - }, - "engines": { - "node": ">= 12.0.0" - } - }, "node_modules/@commercetools/connect-payments-sdk/node_modules/logform": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/logform/-/logform-2.7.0.tgz", @@ -885,15 +852,15 @@ } }, "node_modules/@commercetools/platform-sdk": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@commercetools/platform-sdk/-/platform-sdk-7.21.0.tgz", - "integrity": "sha512-Oy8NmTCUAiuJ8r7kvTbv/Ve0jxnJsAKHOqEHfvg4ZjqJqM8DRzLoLa/SIzywqZbyc1eE6JEpIYsf92rArj+vWw==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@commercetools/platform-sdk/-/platform-sdk-7.23.0.tgz", + "integrity": "sha512-FYUCtWF5TXwIyPGroZiWE6NQoPmPygH1e1jfWHOMUII5IBIitIq2rQvY09ALJ8/mnC8VHN7Ngy/JMTjoUMyRDg==", "dependencies": { "@commercetools/sdk-client-v2": "^2.5.0", "@commercetools/sdk-middleware-auth": "^7.0.0", "@commercetools/sdk-middleware-http": "^7.0.0", "@commercetools/sdk-middleware-logger": "^3.0.0", - "@commercetools/ts-client": "^2.1.3" + "@commercetools/ts-client": "^2.1.6" }, "engines": { "node": ">=14" @@ -977,9 +944,9 @@ } }, "node_modules/@commercetools/ts-client": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@commercetools/ts-client/-/ts-client-2.1.3.tgz", - "integrity": "sha512-Ol1GrtibWuRPajyGPVkZDrMVr67rGBqAZkT031Re2wpFilGEmATqwBosupeerJ2Q6h7i1uF3f5JP+y6MbWSehA==", + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@commercetools/ts-client/-/ts-client-2.1.6.tgz", + "integrity": "sha512-rbGbfRw0vNwoQ9GcYExCbG/QZ4aSXOpn3WtvqnDrWmvQqWuvC71fuKSGzj0I3Ah09xVyJPfsTG5FOC1YxkFWzw==", "dependencies": { "abort-controller": "3.0.0", "buffer": "^6.0.3", @@ -2219,7 +2186,6 @@ "version": "1.19.5", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", - "license": "MIT", "dependencies": { "@types/connect": "*", "@types/node": "*" @@ -2229,7 +2195,6 @@ "version": "3.4.38", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", - "license": "MIT", "dependencies": { "@types/node": "*" } @@ -2250,7 +2215,6 @@ "version": "4.17.21", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", - "license": "MIT", "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.33", @@ -2262,7 +2226,6 @@ "version": "4.19.6", "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", - "license": "MIT", "dependencies": { "@types/node": "*", "@types/qs": "*", @@ -2282,8 +2245,7 @@ "node_modules/@types/http-errors": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", - "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", - "license": "MIT" + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", @@ -2329,7 +2291,6 @@ "version": "9.0.7", "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.7.tgz", "integrity": "sha512-ugo316mmTYBl2g81zDFnZ7cfxlut3o+/EQdaP7J8QN2kY6lJ22hmQYCK5EHcJHbrW+dkCGSCPgbG8JtYj6qSrg==", - "license": "MIT", "dependencies": { "@types/node": "*" } @@ -2342,8 +2303,7 @@ "node_modules/@types/mime": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", - "license": "MIT" + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" }, "node_modules/@types/node": { "version": "22.10.2", @@ -2356,20 +2316,17 @@ "node_modules/@types/qs": { "version": "6.9.17", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.17.tgz", - "integrity": "sha512-rX4/bPcfmvxHDv0XjfJELTTr+iB+tn032nPILqHm5wbthUUUuVtNGGqzhya9XUxjTP8Fpr0qYgSZZKxGY++svQ==", - "license": "MIT" + "integrity": "sha512-rX4/bPcfmvxHDv0XjfJELTTr+iB+tn032nPILqHm5wbthUUUuVtNGGqzhya9XUxjTP8Fpr0qYgSZZKxGY++svQ==" }, "node_modules/@types/range-parser": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", - "license": "MIT" + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" }, "node_modules/@types/send": { "version": "0.17.4", "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", - "license": "MIT", "dependencies": { "@types/mime": "^1", "@types/node": "*" @@ -2379,7 +2336,6 @@ "version": "1.15.7", "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", - "license": "MIT", "dependencies": { "@types/http-errors": "*", "@types/node": "*", @@ -3067,8 +3023,7 @@ "node_modules/buffer-equal-constant-time": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", - "license": "BSD-3-Clause" + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" }, "node_modules/buffer-from": { "version": "1.1.2", @@ -3518,7 +3473,6 @@ "version": "1.0.11", "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "license": "Apache-2.0", "dependencies": { "safe-buffer": "^5.0.1" } @@ -5586,7 +5540,6 @@ "version": "4.15.9", "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==", - "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" } @@ -5670,7 +5623,6 @@ "version": "9.0.2", "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", - "license": "MIT", "dependencies": { "jws": "^3.2.2", "lodash.includes": "^4.3.0", @@ -5692,7 +5644,6 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "license": "MIT", "dependencies": { "buffer-equal-constant-time": "1.0.1", "ecdsa-sig-formatter": "1.0.11", @@ -5703,7 +5654,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-3.1.0.tgz", "integrity": "sha512-v7nqlfezb9YfHHzYII3ef2a2j1XnGeSE/bK3WfumaYCqONAIstJbrEGapz4kadScZzEt7zYCN7bucj8C0Mv/Rg==", - "license": "MIT", "dependencies": { "@types/express": "^4.17.17", "@types/jsonwebtoken": "^9.0.2", @@ -5720,7 +5670,6 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "license": "MIT", "dependencies": { "jwa": "^1.4.1", "safe-buffer": "^5.0.1" @@ -5821,44 +5770,37 @@ "node_modules/lodash.clonedeep": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", - "license": "MIT" + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==" }, "node_modules/lodash.includes": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", - "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==", - "license": "MIT" + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" }, "node_modules/lodash.isboolean": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", - "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", - "license": "MIT" + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" }, "node_modules/lodash.isinteger": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", - "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==", - "license": "MIT" + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" }, "node_modules/lodash.isnumber": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", - "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==", - "license": "MIT" + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" }, "node_modules/lodash.isplainobject": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", - "license": "MIT" + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" }, "node_modules/lodash.isstring": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", - "license": "MIT" + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" }, "node_modules/lodash.memoize": { "version": "4.1.2", @@ -5875,8 +5817,7 @@ "node_modules/lodash.once": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", - "license": "MIT" + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" }, "node_modules/logform": { "version": "2.6.0", @@ -5907,7 +5848,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-2.3.0.tgz", "integrity": "sha512-GXn7gyHAMhO13WSKrIiNfztwxodVsP8IoZ3XfrJV4yH2x0/OeTO/FIaAHTY5YekdGgW94njfuKmyyt1E0mR6Ug==", - "license": "MIT", "dependencies": { "lodash.clonedeep": "^4.5.0", "lru-cache": "6.0.0" @@ -5917,7 +5857,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -5928,8 +5867,7 @@ "node_modules/lru-memoizer/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "license": "ISC" + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/make-dir": { "version": "4.0.0", @@ -8660,12 +8598,12 @@ } }, "@commercetools/connect-payments-sdk": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@commercetools/connect-payments-sdk/-/connect-payments-sdk-0.12.0.tgz", - "integrity": "sha512-PS4W15NC4fik78K7tLcRjcU0pickY8nudgaocuEO3Q1lsBMltbzNhd1W3DXmap09O+sVlikOoIqoMIUis1cGjg==", + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@commercetools/connect-payments-sdk/-/connect-payments-sdk-0.13.0.tgz", + "integrity": "sha512-TKTlv5mDI5tRI8PyrCTXHuMmoLU9OEUp0VJC+iMU2P71m/GUVkqHeRwmvVYQKcVky7ntwT98bxf5D7Xo9NKsKA==", "requires": { - "@commercetools-backend/loggers": "22.35.1", - "@commercetools/platform-sdk": "7.21.0", + "@commercetools-backend/loggers": "22.37.0", + "@commercetools/platform-sdk": "7.23.0", "@commercetools/sdk-client-v2": "2.5.0", "jsonwebtoken": "9.0.2", "jwks-rsa": "3.1.0", @@ -8673,38 +8611,6 @@ "logform": "2.7.0" }, "dependencies": { - "@commercetools-backend/loggers": { - "version": "22.35.1", - "resolved": "https://registry.npmjs.org/@commercetools-backend/loggers/-/loggers-22.35.1.tgz", - "integrity": "sha512-x50zvi9bYOo2TSarwApHx6TACbcJHA9z5ACtSzIrPQyhDcCX0Z7qS4bwQBe2Vfw7pG5pOwNEghXcNuIthI46OQ==", - "requires": { - "@babel/runtime": "^7.22.15", - "@babel/runtime-corejs3": "^7.22.15", - "@types/lodash": "^4.14.198", - "@types/triple-beam": "1.3.5", - "express-winston": "4.2.0", - "fast-safe-stringify": "2.1.1", - "lodash": "4.17.21", - "logform": "2.6.0", - "triple-beam": "1.4.1", - "winston": "3.13.0" - }, - "dependencies": { - "logform": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/logform/-/logform-2.6.0.tgz", - "integrity": "sha512-1ulHeNPp6k/LD8H91o7VYFBng5i1BDE7HoKxVbZiGFidS1Rj65qcywLxX+pVfAPoQJEjRdvKcusKwOupHCVOVQ==", - "requires": { - "@colors/colors": "1.6.0", - "@types/triple-beam": "^1.3.2", - "fecha": "^4.2.0", - "ms": "^2.1.1", - "safe-stable-stringify": "^2.3.1", - "triple-beam": "^1.3.0" - } - } - } - }, "logform": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/logform/-/logform-2.7.0.tgz", @@ -8721,15 +8627,15 @@ } }, "@commercetools/platform-sdk": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@commercetools/platform-sdk/-/platform-sdk-7.21.0.tgz", - "integrity": "sha512-Oy8NmTCUAiuJ8r7kvTbv/Ve0jxnJsAKHOqEHfvg4ZjqJqM8DRzLoLa/SIzywqZbyc1eE6JEpIYsf92rArj+vWw==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@commercetools/platform-sdk/-/platform-sdk-7.23.0.tgz", + "integrity": "sha512-FYUCtWF5TXwIyPGroZiWE6NQoPmPygH1e1jfWHOMUII5IBIitIq2rQvY09ALJ8/mnC8VHN7Ngy/JMTjoUMyRDg==", "requires": { "@commercetools/sdk-client-v2": "^2.5.0", "@commercetools/sdk-middleware-auth": "^7.0.0", "@commercetools/sdk-middleware-http": "^7.0.0", "@commercetools/sdk-middleware-logger": "^3.0.0", - "@commercetools/ts-client": "^2.1.3" + "@commercetools/ts-client": "^2.1.6" } }, "@commercetools/sdk-client-v2": { @@ -8780,9 +8686,9 @@ "integrity": "sha512-DhMXAA2yIch/AaGxy7st85Z1HFmeLtHWGkr9z5rX4xKjan4PHGB/IE5saAR+SNGHhs6+1Lp8vZEHDo3tFqVLmg==" }, "@commercetools/ts-client": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@commercetools/ts-client/-/ts-client-2.1.3.tgz", - "integrity": "sha512-Ol1GrtibWuRPajyGPVkZDrMVr67rGBqAZkT031Re2wpFilGEmATqwBosupeerJ2Q6h7i1uF3f5JP+y6MbWSehA==", + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@commercetools/ts-client/-/ts-client-2.1.6.tgz", + "integrity": "sha512-rbGbfRw0vNwoQ9GcYExCbG/QZ4aSXOpn3WtvqnDrWmvQqWuvC71fuKSGzj0I3Ah09xVyJPfsTG5FOC1YxkFWzw==", "requires": { "abort-controller": "3.0.0", "buffer": "^6.0.3", diff --git a/processor/package.json b/processor/package.json index cbe7bec..4dd3fe5 100644 --- a/processor/package.json +++ b/processor/package.json @@ -23,7 +23,7 @@ "dependencies": { "@adyen/api-library": "22.1.0", "@commercetools-backend/loggers": "22.37.0", - "@commercetools/connect-payments-sdk": "0.12.0", + "@commercetools/connect-payments-sdk": "0.13.0", "@fastify/autoload": "6.0.3", "@fastify/cors": "10.0.1", "@fastify/formbody": "8.0.1", diff --git a/processor/src/services/converters/create-payment.converter.ts b/processor/src/services/converters/create-payment.converter.ts index 3452cc6..4a42b1d 100644 --- a/processor/src/services/converters/create-payment.converter.ts +++ b/processor/src/services/converters/create-payment.converter.ts @@ -5,6 +5,7 @@ import { Cart, Payment } from '@commercetools/connect-payments-sdk'; import { buildReturnUrl, mapCoCoCartItemsToAdyenLineItems, populateCartAddress } from './helper.converter'; import { CreatePaymentRequestDTO } from '../../dtos/adyen-payment.dto'; import { getFutureOrderNumberFromContext } from '../../libs/fastify/context/context'; +import { paymentSDK } from '../../payment-sdk'; export class CreatePaymentConverter { public convertRequest(opts: { data: CreatePaymentRequestDTO; cart: Cart; payment: Payment }): PaymentRequest { @@ -26,7 +27,7 @@ export class CreatePaymentConverter { billingAddress: populateCartAddress(opts.cart.billingAddress), }), ...(opts.cart.shippingAddress && { - deliveryAddress: populateCartAddress(opts.cart.shippingAddress), + deliveryAddress: populateCartAddress(paymentSDK.ctCartService.getOneShippingAddress({ cart: opts.cart })), }), ...(futureOrderNumber && { merchantOrderReference: futureOrderNumber }), ...this.populateAddionalPaymentMethodData(opts.data, opts.cart), diff --git a/processor/src/services/converters/create-session.converter.ts b/processor/src/services/converters/create-session.converter.ts index 4703f3d..59b5828 100644 --- a/processor/src/services/converters/create-session.converter.ts +++ b/processor/src/services/converters/create-session.converter.ts @@ -9,6 +9,7 @@ import { import { CreateSessionRequestDTO } from '../../dtos/adyen-payment.dto'; import { Cart, Payment } from '@commercetools/connect-payments-sdk'; import { getFutureOrderNumberFromContext } from '../../libs/fastify/context/context'; +import { paymentSDK } from '../../payment-sdk'; export class CreateSessionConverter { public convertRequest(opts: { @@ -35,7 +36,7 @@ export class CreateSessionConverter { billingAddress: populateCartAddress(opts.cart.billingAddress), }), ...(opts.cart.shippingAddress && { - deliveryAddress: populateCartAddress(opts.cart.shippingAddress), + deliveryAddress: populateCartAddress(paymentSDK.ctCartService.getOneShippingAddress({ cart: opts.cart })), }), shopperEmail: opts.cart.customerEmail, ...(futureOrderNumber && { merchantOrderReference: futureOrderNumber }), diff --git a/processor/src/services/converters/helper.converter.ts b/processor/src/services/converters/helper.converter.ts index a08940e..fa7fe2b 100644 --- a/processor/src/services/converters/helper.converter.ts +++ b/processor/src/services/converters/helper.converter.ts @@ -5,7 +5,6 @@ import { LineItem as CoCoLineItem, CustomLineItem, Address as CartAddress, - ShippingInfo, Order, } from '@commercetools/connect-payments-sdk'; import { @@ -13,6 +12,8 @@ import { getCtSessionIdFromContext, getProcessorUrlFromContext, } from '../../libs/fastify/context/context'; +import { NormalizedShipping } from '@commercetools/connect-payments-sdk/dist/commercetools/types/cart.type'; +import { paymentSDK } from '../../payment-sdk'; export const mapCoCoLineItemToAdyenLineItem = (lineItem: CoCoLineItem): LineItem => { return { @@ -38,15 +39,15 @@ export const mapCoCoCustomLineItemToAdyenLineItem = (customLineItem: CustomLineI }; }; -export const mapCoCoShippingInfoToAdyenLineItem = (shippingInfo: ShippingInfo): LineItem => { - return { - description: 'Shipping', +export const mapCoCoShippingInfoToAdyenLineItem = (shippingInfo: NormalizedShipping[]): LineItem[] => { + return shippingInfo.map((shipping) => ({ + description: `Shipping - ${shipping.shippingInfo.shippingMethodName}`, quantity: 1, - amountExcludingTax: shippingInfo.taxedPrice?.totalNet.centAmount || 0, - amountIncludingTax: shippingInfo.taxedPrice?.totalGross.centAmount || 0, - taxAmount: shippingInfo.taxedPrice?.totalTax?.centAmount || 0, - taxPercentage: convertTaxPercentageToCentAmount(shippingInfo.taxRate?.amount), - }; + amountExcludingTax: shipping.shippingInfo.taxedPrice?.totalNet.centAmount || 0, + amountIncludingTax: shipping.shippingInfo.taxedPrice?.totalGross.centAmount || 0, + taxAmount: shipping.shippingInfo.taxedPrice?.totalTax?.centAmount || 0, + taxPercentage: convertTaxPercentageToCentAmount(shipping.shippingInfo.taxRate?.amount), + })); }; export const mapCoCoDiscountOnTotalPriceToAdyenLineItem = ( @@ -74,7 +75,16 @@ export const mapCoCoDiscountOnTotalPriceToAdyenLineItem = ( * @returns List of lineitems to be send to Adyen */ export const mapCoCoOrderItemsToAdyenLineItems = ( - order: Pick, + order: Pick< + Order, + | 'lineItems' + | 'customLineItems' + | 'shippingMode' + | 'shippingAddress' + | 'shippingInfo' + | 'shipping' + | 'discountOnTotalPrice' + >, ): LineItem[] => { // CoCo model between these attributes is shared between a Cart and Order hence we can re-use the existing mapping logic. return mapCoCoCartItemsToAdyenLineItems(order); @@ -89,7 +99,16 @@ export const mapCoCoOrderItemsToAdyenLineItems = ( * @returns List of lineitems to be send to Adyen */ export const mapCoCoCartItemsToAdyenLineItems = ( - cart: Pick, + cart: Pick< + Cart, + | 'lineItems' + | 'customLineItems' + | 'shippingMode' + | 'shippingAddress' + | 'shippingInfo' + | 'shipping' + | 'discountOnTotalPrice' + >, ): LineItem[] => { const aydenLineItems: LineItem[] = []; @@ -99,9 +118,7 @@ export const mapCoCoCartItemsToAdyenLineItems = ( aydenLineItems.push(mapCoCoCustomLineItemToAdyenLineItem(customLineItem)), ); - if (cart.shippingInfo) { - aydenLineItems.push(mapCoCoShippingInfoToAdyenLineItem(cart.shippingInfo)); - } + aydenLineItems.push(...mapCoCoShippingInfoToAdyenLineItem(paymentSDK.ctCartService.getNormalizedShipping({ cart }))); if (cart.discountOnTotalPrice) { aydenLineItems.push( @@ -112,7 +129,7 @@ export const mapCoCoCartItemsToAdyenLineItems = ( return aydenLineItems; }; -export const populateCartAddress = (address: CartAddress): Address => { +export const populateCartAddress = (address?: CartAddress): Address => { return { country: address?.country || '', city: address?.city || '', diff --git a/processor/test/data/coco-cart-multiple-shipping.json b/processor/test/data/coco-cart-multiple-shipping.json new file mode 100644 index 0000000..6e16c1c --- /dev/null +++ b/processor/test/data/coco-cart-multiple-shipping.json @@ -0,0 +1,507 @@ +{ + "type": "Cart", + "id": "4aa39f85-faa0-4189-8aaa-6c4e09b09d6d", + "version": 22, + "versionModifiedAt": "2024-12-23T12:31:12.074Z", + "lastMessageSequenceNumber": 1, + "createdAt": "2024-12-23T12:30:18.314Z", + "lastModifiedAt": "2024-12-23T12:31:12.074Z", + "lastModifiedBy": { + "clientId": "QVTyPEmCgawQrrGISBorkWez", + "isPlatformClient": false + }, + "createdBy": { + "clientId": "QVTyPEmCgawQrrGISBorkWez", + "isPlatformClient": false + }, + "lineItems": [ + { + "id": "f1422202-439e-4ab2-b1ac-d0c807b5f250", + "productId": "f743ab2d-a4ef-4466-9b2e-779c1372fe73", + "productKey": "willow-teapot", + "name": { + "en-US": "Willow Teapot", + "en-GB": "Willow Teapot", + "de-DE": "Teekanne >Willow<" + }, + "productType": { + "typeId": "product-type", + "id": "c6446851-767c-4378-8e8a-ec0ca91eebc9", + "version": 1 + }, + "productSlug": { + "en-US": "willow-teapot", + "en-GB": "willow-teapot", + "de-DE": "willow-teekanne" + }, + "variant": { + "id": 1, + "sku": "WTP-09", + "prices": [ + { + "id": "8c57419c-168a-4c57-bc17-fd253844f68d", + "value": { + "type": "centPrecision", + "currencyCode": "EUR", + "centAmount": 899, + "fractionDigits": 2 + } + }, + { + "id": "51269fd5-07eb-4d09-90dc-90c2f235d2fd", + "value": { + "type": "centPrecision", + "currencyCode": "GBP", + "centAmount": 899, + "fractionDigits": 2 + }, + "country": "GB" + }, + { + "id": "c5f445bc-d226-4cc6-8052-e2e48ee52fc0", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 899, + "fractionDigits": 2 + }, + "country": "US" + }, + { + "id": "ed16ed80-873c-41dd-b9a3-b498ceae4b55", + "value": { + "type": "centPrecision", + "currencyCode": "CHF", + "centAmount": 899, + "fractionDigits": 2 + } + } + ], + "images": [ + { + "url": "https://storage.googleapis.com/merchant-center-europe/sample-data/goodstore/Willow_Teapot-1.1.jpeg", + "dimensions": { + "w": 6240, + "h": 4160 + } + } + ], + "attributes": [ + { + "name": "productspec", + "value": { + "en-GB": "- Hand wash only", + "en-US": "- Hand wash only", + "de-DE": "- Handwäsche nur" + } + } + ], + "assets": [], + "availability": { + "isOnStock": true, + "availableQuantity": 95, + "version": 11, + "id": "a1269c7b-4de8-46ea-b82f-a1d45cb80ca9" + } + }, + "price": { + "id": "8c57419c-168a-4c57-bc17-fd253844f68d", + "value": { + "type": "centPrecision", + "currencyCode": "EUR", + "centAmount": 899, + "fractionDigits": 2 + } + }, + "quantity": 1, + "discountedPricePerQuantity": [], + "perMethodTaxRate": [ + { + "shippingMethodKey": "ddelizia-delivery", + "taxRate": { + "name": "Germany", + "amount": 0.1, + "includedInPrice": true, + "country": "DE", + "id": "A9myrqz8", + "subRates": [] + } + } + ], + "addedAt": "2024-12-23T12:30:25.312Z", + "lastModifiedAt": "2024-12-23T12:31:12.058Z", + "state": [ + { + "quantity": 1, + "state": { + "typeId": "state", + "id": "26f1f5f6-ae77-4314-a7bb-02ebf05b6203" + } + } + ], + "priceMode": "Platform", + "lineItemMode": "Standard", + "totalPrice": { + "type": "centPrecision", + "currencyCode": "EUR", + "centAmount": 899, + "fractionDigits": 2 + }, + "taxedPrice": { + "totalNet": { + "type": "centPrecision", + "currencyCode": "EUR", + "centAmount": 817, + "fractionDigits": 2 + }, + "totalGross": { + "type": "centPrecision", + "currencyCode": "EUR", + "centAmount": 899, + "fractionDigits": 2 + }, + "taxPortions": [ + { + "rate": 0.1, + "amount": { + "type": "centPrecision", + "currencyCode": "EUR", + "centAmount": 82, + "fractionDigits": 2 + }, + "name": "Germany" + } + ], + "totalTax": { + "type": "centPrecision", + "currencyCode": "EUR", + "centAmount": 82, + "fractionDigits": 2 + } + }, + "taxedPricePortions": [ + { + "shippingMethodKey": "ddelizia-delivery", + "taxedPrice": { + "totalNet": { + "type": "centPrecision", + "currencyCode": "EUR", + "centAmount": 817, + "fractionDigits": 2 + }, + "totalGross": { + "type": "centPrecision", + "currencyCode": "EUR", + "centAmount": 899, + "fractionDigits": 2 + }, + "taxPortions": [ + { + "rate": 0.1, + "amount": { + "type": "centPrecision", + "currencyCode": "EUR", + "centAmount": 82, + "fractionDigits": 2 + }, + "name": "Germany" + } + ], + "totalTax": { + "type": "centPrecision", + "currencyCode": "EUR", + "centAmount": 82, + "fractionDigits": 2 + } + } + } + ], + "shippingDetails": { + "targets": [ + { + "addressKey": "key1", + "quantity": 1, + "shippingMethodKey": "ddelizia-delivery" + } + ], + "valid": true + } + } + ], + "cartState": "Active", + "totalPrice": { + "type": "centPrecision", + "currencyCode": "EUR", + "centAmount": 11899, + "fractionDigits": 2 + }, + "taxedPrice": { + "totalNet": { + "type": "centPrecision", + "currencyCode": "EUR", + "centAmount": 10778, + "fractionDigits": 2 + }, + "totalGross": { + "type": "centPrecision", + "currencyCode": "EUR", + "centAmount": 11899, + "fractionDigits": 2 + }, + "taxPortions": [ + { + "rate": 0.1, + "amount": { + "type": "centPrecision", + "currencyCode": "EUR", + "centAmount": 991, + "fractionDigits": 2 + }, + "name": "Germany" + }, + { + "rate": 0.15, + "amount": { + "type": "centPrecision", + "currencyCode": "EUR", + "centAmount": 130, + "fractionDigits": 2 + }, + "name": "Germany" + } + ], + "totalTax": { + "type": "centPrecision", + "currencyCode": "EUR", + "centAmount": 1121, + "fractionDigits": 2 + } + }, + "taxedShippingPrice": { + "totalNet": { + "type": "centPrecision", + "currencyCode": "EUR", + "centAmount": 9961, + "fractionDigits": 2 + }, + "totalGross": { + "type": "centPrecision", + "currencyCode": "EUR", + "centAmount": 11000, + "fractionDigits": 2 + }, + "taxPortions": [ + { + "rate": 0.15, + "amount": { + "type": "centPrecision", + "currencyCode": "EUR", + "centAmount": 130, + "fractionDigits": 2 + }, + "name": "Germany" + }, + { + "rate": 0.1, + "amount": { + "type": "centPrecision", + "currencyCode": "EUR", + "centAmount": 909, + "fractionDigits": 2 + }, + "name": "Germany" + } + ], + "totalTax": { + "type": "centPrecision", + "currencyCode": "EUR", + "centAmount": 1039, + "fractionDigits": 2 + } + }, + "shippingMode": "Multiple", + "shipping": [ + { + "shippingKey": "ddelizia-delivery", + "shippingInfo": { + "shippingMethodName": "ddelizia-delivery", + "price": { + "type": "centPrecision", + "currencyCode": "EUR", + "centAmount": 10000, + "fractionDigits": 2 + }, + "shippingRate": { + "price": { + "type": "centPrecision", + "currencyCode": "EUR", + "centAmount": 10000, + "fractionDigits": 2 + }, + "tiers": [] + }, + "taxRate": { + "name": "Germany", + "amount": 0.1, + "includedInPrice": true, + "country": "DE", + "id": "A9myrqz8", + "subRates": [] + }, + "taxCategory": { + "typeId": "tax-category", + "id": "9d31a1a3-d4ec-4acf-bae8-628fe98287ce" + }, + "deliveries": [], + "shippingMethod": { + "typeId": "shipping-method", + "id": "e36b7100-fa45-4c7c-93dd-04e4f693856b" + }, + "taxedPrice": { + "totalNet": { + "type": "centPrecision", + "currencyCode": "EUR", + "centAmount": 9091, + "fractionDigits": 2 + }, + "totalGross": { + "type": "centPrecision", + "currencyCode": "EUR", + "centAmount": 10000, + "fractionDigits": 2 + }, + "taxPortions": [ + { + "rate": 0.1, + "amount": { + "type": "centPrecision", + "currencyCode": "EUR", + "centAmount": 909, + "fractionDigits": 2 + }, + "name": "Germany" + } + ], + "totalTax": { + "type": "centPrecision", + "currencyCode": "EUR", + "centAmount": 909, + "fractionDigits": 2 + } + }, + "shippingMethodState": "MatchesCart" + }, + "shippingAddress": { + "streetName": "Example Street", + "streetNumber": "4711", + "postalCode": "80933", + "city": "Exemplary City", + "region": "Exemplary Region", + "country": "DE", + "key": "exampleKey" + } + }, + { + "shippingKey": "express-delivery", + "shippingInfo": { + "shippingMethodName": "Express Delivery", + "price": { + "type": "centPrecision", + "currencyCode": "EUR", + "centAmount": 1000, + "fractionDigits": 2 + }, + "shippingRate": { + "price": { + "type": "centPrecision", + "currencyCode": "EUR", + "centAmount": 1000, + "fractionDigits": 2 + }, + "tiers": [] + }, + "taxRate": { + "name": "Germany", + "amount": 0.15, + "includedInPrice": true, + "country": "DE", + "id": "7IC1WxJS", + "subRates": [] + }, + "taxCategory": { + "typeId": "tax-category", + "id": "e95ee3b9-d3da-4e56-875e-aae55c99aab7" + }, + "deliveries": [], + "shippingMethod": { + "typeId": "shipping-method", + "id": "72111da9-15db-4c90-aeaf-aee8499c32fc" + }, + "taxedPrice": { + "totalNet": { + "type": "centPrecision", + "currencyCode": "EUR", + "centAmount": 870, + "fractionDigits": 2 + }, + "totalGross": { + "type": "centPrecision", + "currencyCode": "EUR", + "centAmount": 1000, + "fractionDigits": 2 + }, + "taxPortions": [ + { + "rate": 0.15, + "amount": { + "type": "centPrecision", + "currencyCode": "EUR", + "centAmount": 130, + "fractionDigits": 2 + }, + "name": "Germany" + } + ], + "totalTax": { + "type": "centPrecision", + "currencyCode": "EUR", + "centAmount": 130, + "fractionDigits": 2 + } + }, + "shippingMethodState": "MatchesCart" + }, + "shippingAddress": { + "streetName": "Example Street", + "streetNumber": "4711", + "postalCode": "80933", + "city": "Exemplary City", + "region": "Exemplary Region", + "country": "DE", + "key": "exampleKey" + } + } + ], + "customLineItems": [], + "discountCodes": [], + "directDiscounts": [], + "inventoryMode": "None", + "taxMode": "Platform", + "taxRoundingMode": "HalfEven", + "taxCalculationMode": "LineItemLevel", + "deleteDaysAfterLastModification": 90, + "refusedGifts": [], + "origin": "Customer", + "itemShippingAddresses": [ + { + "streetName": "Example Street", + "streetNumber": "4711", + "postalCode": "80933", + "city": "Exemplary City", + "region": "Exemplary Region", + "country": "DE", + "key": "key1" + } + ], + "totalLineItemQuantity": 1 +} diff --git a/processor/test/data/coco-cart.json b/processor/test/data/coco-cart-simple-shipping.json similarity index 100% rename from processor/test/data/coco-cart.json rename to processor/test/data/coco-cart-simple-shipping.json diff --git a/processor/test/services/adyen-payment.service.spec.ts b/processor/test/services/adyen-payment.service.spec.ts index df016a9..8fc0bec 100644 --- a/processor/test/services/adyen-payment.service.spec.ts +++ b/processor/test/services/adyen-payment.service.spec.ts @@ -1,34 +1,33 @@ -import { describe, test, expect, afterEach, jest, beforeEach, beforeAll, afterAll } from '@jest/globals'; -import { ConfigResponse, ModifyPayment, StatusResponse } from '../../src/services/types/operation.type'; -import { paymentSDK } from '../../src/payment-sdk'; -import { DefaultPaymentService } from '@commercetools/connect-payments-sdk/dist/commercetools/services/ct-payment.service'; import { DefaultCartService } from '@commercetools/connect-payments-sdk/dist/commercetools/services/ct-cart.service'; import { DefaultOrderService } from '@commercetools/connect-payments-sdk/dist/commercetools/services/ct-order.service'; +import { DefaultPaymentService } from '@commercetools/connect-payments-sdk/dist/commercetools/services/ct-payment.service'; +import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, jest, test } from '@jest/globals'; +import { paymentSDK } from '../../src/payment-sdk'; +import { ConfigResponse, ModifyPayment, StatusResponse } from '../../src/services/types/operation.type'; +import { mockGetCartResultShippingModeMultiple, mockGetCartResultShippingModeSimple } from '../utils/mock-cart-data'; +import { mockGetOrderResult } from '../utils/mock-order-data'; import { - mockGetPaymentResult, - mockGetPaymentAmount, - mockUpdatePaymentResult, - mockAdyenCreateSessionResponse, - mockAdyenPaymentMethodsResponse, mockAdyenCancelPaymentResponse, mockAdyenCapturePaymentResponse, mockAdyenCreatePaymentResponse, + mockAdyenCreateSessionResponse, + mockAdyenPaymentMethodsResponse, mockAdyenRefundPaymentResponse, + mockGetPaymentAmount, + mockGetPaymentResult, mockGetPaymentResultKlarnaPayLater, + mockUpdatePaymentResult, mockUpdatePaymentResultKlarnaPayLater, } from '../utils/mock-payment-data'; -import { mockGetOrderResult } from '../utils/mock-order-data'; -import { mockGetCartResult } from '../utils/mock-cart-data'; -import * as Config from '../../src/config/config'; -import { AdyenPaymentService, AdyenPaymentServiceOptions } from '../../src/services/adyen-payment.service'; -import * as StatusHandler from '@commercetools/connect-payments-sdk/dist/api/handlers/status.handler'; -import { PaymentsApi } from '@adyen/api-library/lib/src/services/checkout/paymentsApi'; import { ModificationsApi } from '@adyen/api-library/lib/src/services/checkout/modificationsApi'; +import { PaymentsApi } from '@adyen/api-library/lib/src/services/checkout/paymentsApi'; +import * as StatusHandler from '@commercetools/connect-payments-sdk/dist/api/handlers/status.handler'; import { MockAgent, setGlobalDispatcher } from 'undici'; +import * as Config from '../../src/config/config'; +import { AdyenPaymentService, AdyenPaymentServiceOptions } from '../../src/services/adyen-payment.service'; import { HealthCheckResult } from '@commercetools/connect-payments-sdk'; -import { SupportedPaymentComponentsSchemaDTO } from '../../src/dtos/operations/payment-componets.dto'; import { CreateApplePaySessionRequestDTO, CreatePaymentRequestDTO, @@ -36,13 +35,14 @@ import { NotificationRequestDTO, PaymentMethodsRequestDTO, } from '../../src/dtos/adyen-payment.dto'; +import { SupportedPaymentComponentsSchemaDTO } from '../../src/dtos/operations/payment-componets.dto'; -import * as FastifyContext from '../../src/libs/fastify/context/context'; -import { PaymentResponse } from '@adyen/api-library/lib/src/typings/checkout/paymentResponse'; -import { KlarnaDetails } from '@adyen/api-library/lib/src/typings/checkout/klarnaDetails'; -import { CardDetails } from '@adyen/api-library/lib/src/typings/checkout/cardDetails'; import { ApplePayDetails } from '@adyen/api-library/lib/src/typings/checkout/applePayDetails'; +import { CardDetails } from '@adyen/api-library/lib/src/typings/checkout/cardDetails'; +import { KlarnaDetails } from '@adyen/api-library/lib/src/typings/checkout/klarnaDetails'; +import { PaymentResponse } from '@adyen/api-library/lib/src/typings/checkout/paymentResponse'; import { NotificationRequestItem } from '@adyen/api-library/lib/src/typings/notification/notificationRequestItem'; +import * as FastifyContext from '../../src/libs/fastify/context/context'; interface FlexibleConfig { [key: string]: string; // Adjust the type according to your config values @@ -285,7 +285,83 @@ describe('adyen-payment.service', () => { const mockOrderService = jest .spyOn(DefaultOrderService.prototype, 'getOrderByPaymentId') .mockRejectedValue(new Error('Could not retrieve order')); - jest.spyOn(DefaultCartService.prototype, 'getCartByPaymentId').mockResolvedValue(mockGetCartResult()); + jest + .spyOn(DefaultCartService.prototype, 'getCartByPaymentId') + .mockResolvedValue(mockGetCartResultShippingModeSimple()); + const mockAdyenService = jest + .spyOn(ModificationsApi.prototype, 'captureAuthorisedPayment') + .mockResolvedValue(mockAdyenCapturePaymentResponse); + + // Act + const result = await paymentService.modifyPayment(modifyPaymentOpts); + + // Expect + const expectedAdyenCapturePayload = { + amount: { currency: 'USD', value: 150000 }, + lineItems: [ + { + amountExcludingTax: 150000, + amountIncludingTax: 150000, + description: 'lineitem-name-1', + id: 'variant-sku-1', + quantity: 1, + taxAmount: 0, + taxPercentage: 0, + }, + { + amountExcludingTax: 150000, + amountIncludingTax: 150000, + description: 'customLineItem-name-1', + id: 'customLineItem-id-1', + quantity: 1, + taxAmount: 0, + taxPercentage: 0, + }, + { + amountExcludingTax: 0, + amountIncludingTax: 0, + description: 'Shipping - shippingMethodName1', + quantity: 1, + taxAmount: 0, + taxPercentage: 0, + }, + ], + merchantAccount: 'adyenMerchantAccount', + reference: '123456', + }; + + expect(mockOrderService).rejects.toThrow('Could not retrieve order'); + expect(mockAdyenService).toHaveBeenCalledWith('92C12661DS923781G', expectedAdyenCapturePayload); + expect(result?.outcome).toStrictEqual('received'); + }); + + test('capturePayment with lineitems with a cart which has multiple shipments', async () => { + // Given + const modifyPaymentOpts: ModifyPayment = { + paymentId: 'dummy-paymentId', + data: { + actions: [ + { + action: 'capturePayment', + amount: { + centAmount: 150000, + currencyCode: 'USD', + }, + }, + ], + }, + }; + + jest.spyOn(DefaultPaymentService.prototype, 'getPayment').mockResolvedValue(mockGetPaymentResultKlarnaPayLater); + jest + .spyOn(DefaultPaymentService.prototype, 'updatePayment') + .mockResolvedValue(mockUpdatePaymentResultKlarnaPayLater); + const mockOrderService = jest + .spyOn(DefaultOrderService.prototype, 'getOrderByPaymentId') + .mockRejectedValue(new Error('Could not retrieve order')); + jest + .spyOn(DefaultCartService.prototype, 'getCartByPaymentId') + .mockResolvedValue(mockGetCartResultShippingModeMultiple()); const mockAdyenService = jest .spyOn(ModificationsApi.prototype, 'captureAuthorisedPayment') .mockResolvedValue(mockAdyenCapturePaymentResponse); @@ -318,7 +394,7 @@ describe('adyen-payment.service', () => { { amountExcludingTax: 0, amountIncludingTax: 0, - description: 'Shipping', + description: 'Shipping - shippingMethodName1', quantity: 1, taxAmount: 0, taxPercentage: 0, @@ -411,11 +487,11 @@ describe('adyen-payment.service', () => { }, }; - jest.spyOn(DefaultCartService.prototype, 'getCart').mockResolvedValue(mockGetCartResult()); + jest.spyOn(DefaultCartService.prototype, 'getCart').mockResolvedValue(mockGetCartResultShippingModeSimple()); jest.spyOn(DefaultCartService.prototype, 'getPaymentAmount').mockResolvedValue(mockGetPaymentAmount); jest.spyOn(DefaultPaymentService.prototype, 'createPayment').mockResolvedValue(mockGetPaymentResult); - jest.spyOn(DefaultCartService.prototype, 'addPayment').mockResolvedValue(mockGetCartResult()); + jest.spyOn(DefaultCartService.prototype, 'addPayment').mockResolvedValue(mockGetCartResultShippingModeSimple()); jest.spyOn(FastifyContext, 'getProcessorUrlFromContext').mockReturnValue('http://127.0.0.1'); jest.spyOn(FastifyContext, 'getMerchantReturnUrlFromContext').mockReturnValue('http://127.0.0.1/checkout/result'); jest.spyOn(PaymentsApi.prototype, 'payments').mockResolvedValue(mockAdyenCreatePaymentResponse); @@ -438,11 +514,11 @@ describe('adyen-payment.service', () => { }, }; - jest.spyOn(DefaultCartService.prototype, 'getCart').mockResolvedValue(mockGetCartResult()); + jest.spyOn(DefaultCartService.prototype, 'getCart').mockResolvedValue(mockGetCartResultShippingModeSimple()); jest.spyOn(DefaultCartService.prototype, 'getPaymentAmount').mockResolvedValue(mockGetPaymentAmount); jest.spyOn(DefaultPaymentService.prototype, 'createPayment').mockResolvedValue(mockGetPaymentResult); - jest.spyOn(DefaultCartService.prototype, 'addPayment').mockResolvedValue(mockGetCartResult()); + jest.spyOn(DefaultCartService.prototype, 'addPayment').mockResolvedValue(mockGetCartResultShippingModeSimple()); jest.spyOn(FastifyContext, 'getProcessorUrlFromContext').mockReturnValue('http://127.0.0.1'); jest.spyOn(FastifyContext, 'getMerchantReturnUrlFromContext').mockReturnValue('http://127.0.0.1/checkout/result'); jest.spyOn(PaymentsApi.prototype, 'payments').mockResolvedValue(mockAdyenCreatePaymentResponse); @@ -465,11 +541,11 @@ describe('adyen-payment.service', () => { }, }; - jest.spyOn(DefaultCartService.prototype, 'getCart').mockResolvedValue(mockGetCartResult()); + jest.spyOn(DefaultCartService.prototype, 'getCart').mockResolvedValue(mockGetCartResultShippingModeSimple()); jest.spyOn(DefaultCartService.prototype, 'getPaymentAmount').mockResolvedValue(mockGetPaymentAmount); jest.spyOn(DefaultPaymentService.prototype, 'createPayment').mockResolvedValue(mockGetPaymentResult); - jest.spyOn(DefaultCartService.prototype, 'addPayment').mockResolvedValue(mockGetCartResult()); + jest.spyOn(DefaultCartService.prototype, 'addPayment').mockResolvedValue(mockGetCartResultShippingModeSimple()); jest.spyOn(FastifyContext, 'getProcessorUrlFromContext').mockReturnValue('http://127.0.0.1'); jest.spyOn(FastifyContext, 'getMerchantReturnUrlFromContext').mockReturnValue('http://127.0.0.1/checkout/result'); jest.spyOn(PaymentsApi.prototype, 'payments').mockResolvedValue(mockAdyenCreatePaymentResponse); @@ -487,7 +563,7 @@ describe('adyen-payment.service', () => { data: {}, }; - jest.spyOn(DefaultCartService.prototype, 'getCart').mockResolvedValue(mockGetCartResult()); + jest.spyOn(DefaultCartService.prototype, 'getCart').mockResolvedValue(mockGetCartResultShippingModeSimple()); jest.spyOn(DefaultCartService.prototype, 'getPaymentAmount').mockResolvedValue(mockGetPaymentAmount); jest.spyOn(PaymentsApi.prototype, 'paymentMethods').mockResolvedValue(mockAdyenPaymentMethodsResponse); jest.spyOn(FastifyContext, 'getAllowedPaymentMethodsFromContext').mockReturnValue(['card']); @@ -504,11 +580,11 @@ describe('adyen-payment.service', () => { data: {}, }; - jest.spyOn(DefaultCartService.prototype, 'getCart').mockResolvedValue(mockGetCartResult()); + jest.spyOn(DefaultCartService.prototype, 'getCart').mockResolvedValue(mockGetCartResultShippingModeSimple()); jest.spyOn(DefaultCartService.prototype, 'getPaymentAmount').mockResolvedValue(mockGetPaymentAmount); jest.spyOn(DefaultPaymentService.prototype, 'createPayment').mockResolvedValue(mockGetPaymentResult); - jest.spyOn(DefaultCartService.prototype, 'addPayment').mockResolvedValue(mockGetCartResult()); + jest.spyOn(DefaultCartService.prototype, 'addPayment').mockResolvedValue(mockGetCartResultShippingModeSimple()); jest.spyOn(FastifyContext, 'getAllowedPaymentMethodsFromContext').mockReturnValue(['applepay']); jest.spyOn(FastifyContext, 'getProcessorUrlFromContext').mockReturnValue('http://127.0.0.1'); diff --git a/processor/test/services/converters/helper.converter.spec.ts b/processor/test/services/converters/helper.converter.spec.ts index c918901..69c91c6 100644 --- a/processor/test/services/converters/helper.converter.spec.ts +++ b/processor/test/services/converters/helper.converter.spec.ts @@ -18,7 +18,8 @@ import { CustomLineItem, ShippingInfo, } from '@commercetools/connect-payments-sdk'; -import CoCoCartJSON from '../../data/coco-cart.json'; +import CoCoCartSimpleJSON from '../../data/coco-cart-simple-shipping.json'; +import CoCoCartMultipleJSON from '../../data/coco-cart-multiple-shipping.json'; describe('helper.converter', () => { beforeEach(() => { @@ -82,7 +83,7 @@ describe('helper.converter', () => { }); test('should map the CoCo line items to Adyen line items', () => { - const input = CoCoCartJSON.lineItems as CoCoLineItem[]; + const input = CoCoCartSimpleJSON.lineItems as CoCoLineItem[]; const actual = mapCoCoLineItemToAdyenLineItem(input[0]); const expected: LineItem = { @@ -99,7 +100,7 @@ describe('helper.converter', () => { }); test('should map the CoCo custom line items to Adyen line items', () => { - const input: CustomLineItem[] = CoCoCartJSON.customLineItems as CustomLineItem[]; + const input: CustomLineItem[] = CoCoCartSimpleJSON.customLineItems as CustomLineItem[]; const actual = mapCoCoCustomLineItemToAdyenLineItem(input[0]); const expected: LineItem = { @@ -116,23 +117,60 @@ describe('helper.converter', () => { }); test('should map CoCo shipping info to Adyen line item', () => { - const input: ShippingInfo = CoCoCartJSON.shippingInfo as ShippingInfo; + const input: ShippingInfo = CoCoCartSimpleJSON.shippingInfo as ShippingInfo; - const actual = mapCoCoShippingInfoToAdyenLineItem(input); - const expected: LineItem = { - description: 'Shipping', - quantity: 1, - amountExcludingTax: 1344, - amountIncludingTax: 1599, - taxAmount: 255, - taxPercentage: 1900, - }; + const actual = mapCoCoShippingInfoToAdyenLineItem([ + { shippingInfo: input, shippingAddress: CoCoCartSimpleJSON.shippingAddress }, + ]); + const expected: LineItem[] = [ + { + description: 'Shipping - Standard Delivery', + quantity: 1, + amountExcludingTax: 1344, + amountIncludingTax: 1599, + taxAmount: 255, + taxPercentage: 1900, + }, + ]; + + expect(actual).toEqual(expected); + }); + + test('should map CoCo shipping info to Adyen line item when multiple shipping', () => { + const actual = mapCoCoShippingInfoToAdyenLineItem([ + { + shippingInfo: CoCoCartMultipleJSON.shipping[0].shippingInfo as ShippingInfo, + shippingAddress: CoCoCartMultipleJSON.shipping[0].shippingAddress, + }, + { + shippingInfo: CoCoCartMultipleJSON.shipping[1].shippingInfo as ShippingInfo, + shippingAddress: CoCoCartMultipleJSON.shipping[1].shippingAddress, + }, + ]); + const expected: LineItem[] = [ + { + amountExcludingTax: 9091, + amountIncludingTax: 10000, + description: 'Shipping - ddelizia-delivery', + quantity: 1, + taxAmount: 909, + taxPercentage: 1000, + }, + { + amountExcludingTax: 870, + amountIncludingTax: 1000, + description: 'Shipping - Express Delivery', + quantity: 1, + taxAmount: 130, + taxPercentage: 1500, + }, + ]; expect(actual).toEqual(expected); }); test('should map CoCo shipping info to Adyen line item', () => { - const input = CoCoCartJSON.discountOnTotalPrice as any; + const input = CoCoCartSimpleJSON.discountOnTotalPrice as any; const actual = mapCoCoDiscountOnTotalPriceToAdyenLineItem({ discountOnTotalPrice: input }); const expected: LineItem = { @@ -147,7 +185,7 @@ describe('helper.converter', () => { }); test('should map a CoCo cart to Adyen line items', () => { - const input = CoCoCartJSON as Cart; + const input = CoCoCartSimpleJSON as Cart; const actual = mapCoCoCartItemsToAdyenLineItems(input); const expected: LineItem[] = [ @@ -170,7 +208,7 @@ describe('helper.converter', () => { taxPercentage: 1900, }, { - description: 'Shipping', + description: 'Shipping - Standard Delivery', quantity: 1, amountExcludingTax: 1344, amountIncludingTax: 1599, @@ -188,4 +226,39 @@ describe('helper.converter', () => { expect(actual).toEqual(expected); }); + + test('should map a CoCo cart to Adyen line items when shipping mode is Multiple', () => { + const input = CoCoCartMultipleJSON as Cart; + + const actual = mapCoCoCartItemsToAdyenLineItems(input); + const expected: LineItem[] = [ + { + amountExcludingTax: 817, + amountIncludingTax: 899, + description: 'Willow Teapot', + id: 'WTP-09', + quantity: 1, + taxAmount: 82, + taxPercentage: 0, + }, + { + amountExcludingTax: 9091, + amountIncludingTax: 10000, + description: 'Shipping - ddelizia-delivery', + quantity: 1, + taxAmount: 909, + taxPercentage: 1000, + }, + { + amountExcludingTax: 870, + amountIncludingTax: 1000, + description: 'Shipping - Express Delivery', + quantity: 1, + taxAmount: 130, + taxPercentage: 1500, + }, + ]; + + expect(actual).toEqual(expected); + }); }); diff --git a/processor/test/utils/mock-cart-data.ts b/processor/test/utils/mock-cart-data.ts index 27e2bc0..3096c9c 100644 --- a/processor/test/utils/mock-cart-data.ts +++ b/processor/test/utils/mock-cart-data.ts @@ -1,7 +1,7 @@ -import { LineItem, CustomLineItem, ShippingInfo, Cart } from '@commercetools/connect-payments-sdk'; +import { Cart, CustomLineItem, LineItem, ShippingInfo } from '@commercetools/connect-payments-sdk'; import { randomUUID } from 'crypto'; -export const mockGetCartResult = () => { +export const mockGetCartResultShippingModeSimple = () => { const cartId = randomUUID(); const mockGetCartResult: Cart = { id: cartId, @@ -26,6 +26,12 @@ export const mockGetCartResult = () => { itemShippingAddresses: [], inventoryMode: 'ReserveOnOrder', shippingMode: 'Single', + shippingAddress: { + id: 'address-id-1', + country: 'US', + state: 'CA', + city: 'Los Angeles', + }, shippingInfo: shippingInfo, createdAt: '2024-01-01T00:00:00Z', lastModifiedAt: '2024-01-01T00:00:00Z', @@ -33,6 +39,48 @@ export const mockGetCartResult = () => { return mockGetCartResult; }; +export const mockGetCartResultShippingModeMultiple = () => { + const cartId = randomUUID(); + const mockGetCartResult: Cart = { + id: cartId, + version: 1, + lineItems: [lineItem], + customLineItems: [customLineItem], + totalPrice: { + type: 'centPrecision', + currencyCode: 'USD', + centAmount: 150000, + fractionDigits: 2, + }, + cartState: 'Ordered', + origin: 'Customer', + taxMode: 'ExternalAmount', + taxRoundingMode: 'HalfEven', + taxCalculationMode: 'LineItemLevel', + discountCodes: [], + directDiscounts: [], + refusedGifts: [], + itemShippingAddresses: [], + inventoryMode: 'ReserveOnOrder', + shippingMode: 'Multiple', + shipping: [ + { + shippingKey: 'shipping-key-1', + shippingAddress: { + id: 'address-id-1', + country: 'US', + state: 'CA', + city: 'Los Angeles', + }, + shippingInfo: shippingInfo, + }, + ], + createdAt: '2024-01-01T00:00:00Z', + lastModifiedAt: '2024-01-01T00:00:00Z', + }; + return mockGetCartResult; +}; + const lineItem: LineItem = { id: 'lineitem-id-1', productId: 'product-id-1',