@abdssamie/adyen-payments 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +258 -0
  3. package/dist/client/_generated/_ignore.d.ts +1 -0
  4. package/dist/client/_generated/_ignore.d.ts.map +1 -0
  5. package/dist/client/_generated/_ignore.js +3 -0
  6. package/dist/client/_generated/_ignore.js.map +1 -0
  7. package/dist/client/index.d.ts +206 -0
  8. package/dist/client/index.d.ts.map +1 -0
  9. package/dist/client/index.js +566 -0
  10. package/dist/client/index.js.map +1 -0
  11. package/dist/component/_generated/api.d.ts +36 -0
  12. package/dist/component/_generated/api.d.ts.map +1 -0
  13. package/dist/component/_generated/api.js +31 -0
  14. package/dist/component/_generated/api.js.map +1 -0
  15. package/dist/component/_generated/component.d.ts +215 -0
  16. package/dist/component/_generated/component.d.ts.map +1 -0
  17. package/dist/component/_generated/component.js +11 -0
  18. package/dist/component/_generated/component.js.map +1 -0
  19. package/dist/component/_generated/dataModel.d.ts +46 -0
  20. package/dist/component/_generated/dataModel.d.ts.map +1 -0
  21. package/dist/component/_generated/dataModel.js +11 -0
  22. package/dist/component/_generated/dataModel.js.map +1 -0
  23. package/dist/component/_generated/server.d.ts +121 -0
  24. package/dist/component/_generated/server.d.ts.map +1 -0
  25. package/dist/component/_generated/server.js +78 -0
  26. package/dist/component/_generated/server.js.map +1 -0
  27. package/dist/component/convex.config.d.ts +3 -0
  28. package/dist/component/convex.config.d.ts.map +1 -0
  29. package/dist/component/convex.config.js +3 -0
  30. package/dist/component/convex.config.js.map +1 -0
  31. package/dist/component/private.d.ts +71 -0
  32. package/dist/component/private.d.ts.map +1 -0
  33. package/dist/component/private.js +250 -0
  34. package/dist/component/private.js.map +1 -0
  35. package/dist/component/public.d.ts +170 -0
  36. package/dist/component/public.d.ts.map +1 -0
  37. package/dist/component/public.js +210 -0
  38. package/dist/component/public.js.map +1 -0
  39. package/dist/component/schema.d.ts +101 -0
  40. package/dist/component/schema.d.ts.map +1 -0
  41. package/dist/component/schema.js +63 -0
  42. package/dist/component/schema.js.map +1 -0
  43. package/dist/react/hooks.d.ts +182 -0
  44. package/dist/react/hooks.d.ts.map +1 -0
  45. package/dist/react/hooks.js +215 -0
  46. package/dist/react/hooks.js.map +1 -0
  47. package/dist/react/index.d.ts +3 -0
  48. package/dist/react/index.d.ts.map +1 -0
  49. package/dist/react/index.js +3 -0
  50. package/dist/react/index.js.map +1 -0
  51. package/package.json +104 -0
  52. package/src/client/_generated/_ignore.ts +1 -0
  53. package/src/client/index.test.ts +196 -0
  54. package/src/client/index.ts +823 -0
  55. package/src/client/setup.test.ts +26 -0
  56. package/src/client/webhooks.test.ts +182 -0
  57. package/src/component/_generated/api.ts +52 -0
  58. package/src/component/_generated/component.ts +293 -0
  59. package/src/component/_generated/dataModel.ts +60 -0
  60. package/src/component/_generated/server.ts +156 -0
  61. package/src/component/convex.config.ts +3 -0
  62. package/src/component/private.ts +277 -0
  63. package/src/component/public.test.ts +92 -0
  64. package/src/component/public.ts +229 -0
  65. package/src/component/schema.ts +67 -0
  66. package/src/component/setup.test.ts +11 -0
  67. package/src/react/hooks.ts +488 -0
  68. package/src/react/index.ts +18 -0
  69. package/src/test.ts +18 -0
package/package.json ADDED
@@ -0,0 +1,104 @@
1
+ {
2
+ "name": "@abdssamie/adyen-payments",
3
+ "description": "A adyen payments component for Convex.",
4
+ "repository": "github:Abdssamie/adyen-payments",
5
+ "homepage": "https://github.com/Abdssamie/adyen-payments#readme",
6
+ "bugs": {
7
+ "url": "https://github.com/Abdssamie/adyen-payments/issues"
8
+ },
9
+ "version": "0.1.0",
10
+ "license": "Apache-2.0",
11
+ "keywords": [
12
+ "convex",
13
+ "component"
14
+ ],
15
+ "type": "module",
16
+ "scripts": {
17
+ "dev": "convex dev --start 'npm run dev:build'",
18
+ "dev:frontend": "cd example && vite",
19
+ "dev:build": "chokidar 'tsconfig*.json' 'src/**/*.ts' -i '**/*.test.ts' -c 'npm run build:codegen' --initial",
20
+ "predev": "convex init && npm run build:codegen",
21
+ "build": "tsc --project ./tsconfig.build.json",
22
+ "build:codegen": "npx convex codegen --component-dir ./src/component && npm run build",
23
+ "build:clean": "rm -rf dist *.tsbuildinfo && npm run build:codegen",
24
+ "typecheck": "tsc --noEmit && tsc -p example && tsc -p example/convex",
25
+ "lint": "eslint .",
26
+ "test": "vitest run --typecheck",
27
+ "test:watch": "vitest --typecheck --clearScreen false",
28
+ "test:debug": "vitest --inspect-brk --no-file-parallelism",
29
+ "test:coverage": "vitest run --coverage --coverage.reporter=text",
30
+ "preversion": "npm ci && npm run build:clean && npm run test && npm run lint && npm run typecheck",
31
+ "alpha": "npm version prerelease --preid alpha && npm publish --tag alpha && git push --follow-tags",
32
+ "release": "npm version patch && npm publish && git push --follow-tags",
33
+ "version": "(npm whoami || npm login) && vim -c 'normal o' -c 'normal o## '$npm_package_version CHANGELOG.md && prettier -w CHANGELOG.md && git add CHANGELOG.md"
34
+ },
35
+ "files": [
36
+ "dist",
37
+ "src"
38
+ ],
39
+ "exports": {
40
+ "./package.json": "./package.json",
41
+ ".": {
42
+ "types": "./dist/client/index.d.ts",
43
+ "default": "./dist/client/index.js"
44
+ },
45
+ "./react": {
46
+ "types": "./dist/react/index.d.ts",
47
+ "default": "./dist/react/index.js"
48
+ },
49
+ "./test": "./src/test.ts",
50
+ "./_generated/component.js": {
51
+ "types": "./dist/component/_generated/component.d.ts"
52
+ },
53
+ "./_generated/component": {
54
+ "types": "./dist/component/_generated/component.d.ts"
55
+ },
56
+ "./convex.config.js": {
57
+ "types": "./dist/component/convex.config.d.ts",
58
+ "default": "./dist/component/convex.config.js"
59
+ },
60
+ "./convex.config": {
61
+ "types": "./dist/component/convex.config.d.ts",
62
+ "default": "./dist/component/convex.config.js"
63
+ }
64
+ },
65
+ "peerDependencies": {
66
+ "convex": "^1.36.1",
67
+ "react": "^18.3.1 || ^19.0.0"
68
+ },
69
+ "devDependencies": {
70
+ "@convex-dev/eslint-plugin": "^2.0.0",
71
+ "@edge-runtime/vm": "^5.0.0",
72
+ "@eslint/eslintrc": "^3.3.5",
73
+ "@eslint/js": "9.39.4",
74
+ "@types/node": "^24.12.2",
75
+ "@types/react": "^19.2.14",
76
+ "@types/react-dom": "^19.2.3",
77
+ "@typescript/native-preview": "7.0.0-dev.20260614.1",
78
+ "@vitejs/plugin-react": "^6.0.2",
79
+ "chokidar-cli": "3.0.0",
80
+ "convex": "^1.41.0",
81
+ "convex-test": "0.0.49",
82
+ "eslint": "9.39.4",
83
+ "eslint-plugin-react": "^7.37.5",
84
+ "eslint-plugin-react-hooks": "^7.1.1",
85
+ "eslint-plugin-react-refresh": "^0.5.2",
86
+ "globals": "^17.5.0",
87
+ "pkg-pr-new": "^0.0.66",
88
+ "prettier": "3.8.3",
89
+ "react": "^19.2.5",
90
+ "react-dom": "^19.2.5",
91
+ "typescript": "6.0.3",
92
+ "typescript-eslint": "8.58.2",
93
+ "vite": "8.0.9",
94
+ "vitest": "4.1.4"
95
+ },
96
+ "dependencies": {
97
+ "@adyen/adyen-web": "^6.39.0",
98
+ "@adyen/api-library": "^22.0.0",
99
+ "@convex-dev/better-auth": "^0.12.4",
100
+ "better-auth": "^1.6.20"
101
+ },
102
+ "types": "./dist/client/index.d.ts",
103
+ "module": "./dist/client/index.js"
104
+ }
@@ -0,0 +1 @@
1
+ // This is only here so convex-test can detect a _generated folder
@@ -0,0 +1,196 @@
1
+ import { describe, expect, test, vi, beforeEach } from "vitest";
2
+ import { AdyenPayments, type ActionCtx } from "./index.js";
3
+ import { components, initConvexTest } from "./setup.test.js";
4
+
5
+ // Mock the Adyen SDK API calls
6
+ vi.mock("@adyen/api-library", () => {
7
+ const sessionsMock = vi.fn().mockResolvedValue({
8
+ id: "sess_123",
9
+ sessionData: "data_blob_123",
10
+ url: "https://checkout.adyen.com/pay/123",
11
+ });
12
+
13
+ const paymentMethodsMock = vi.fn().mockResolvedValue({
14
+ storedPaymentMethods: [
15
+ { id: "token_123", brand: "visa", lastFour: "1111", expiryMonth: "12", expiryYear: "2030" }
16
+ ]
17
+ });
18
+
19
+ const deleteStoredPaymentMethodMock = vi.fn().mockResolvedValue({});
20
+
21
+ const paymentsMock = vi.fn().mockResolvedValue({
22
+ pspReference: "psp_123",
23
+ resultCode: "Authorised",
24
+ paymentMethod: { type: "visa" }
25
+ });
26
+
27
+ const captureMock = vi.fn().mockResolvedValue({ pspReference: "psp_cap_123", status: "received" });
28
+ const refundMock = vi.fn().mockResolvedValue({ pspReference: "psp_ref_123", status: "received" });
29
+ const cancelMock = vi.fn().mockResolvedValue({ pspReference: "psp_can_123", status: "received" });
30
+
31
+ class CheckoutAPIMock {
32
+ PaymentsApi = {
33
+ sessions: sessionsMock,
34
+ payments: paymentsMock,
35
+ paymentMethods: paymentMethodsMock,
36
+ };
37
+ RecurringApi = {
38
+ deleteTokenForStoredPaymentDetails: deleteStoredPaymentMethodMock,
39
+ };
40
+ ModificationsApi = {
41
+ captureAuthorisedPayment: captureMock,
42
+ refundCapturedPayment: refundMock,
43
+ cancelAuthorisedPaymentByPspReference: cancelMock,
44
+ };
45
+ }
46
+
47
+ class HmacValidatorMock {
48
+ validateHMAC = vi.fn().mockReturnValue(true);
49
+ validateBankingHMAC = vi.fn().mockReturnValue(true);
50
+ }
51
+
52
+ return {
53
+ Client: vi.fn(),
54
+ CheckoutAPI: CheckoutAPIMock,
55
+ hmacValidator: HmacValidatorMock,
56
+ };
57
+ });
58
+
59
+ describe("AdyenPayments client class tests", () => {
60
+ beforeEach(() => {
61
+ process.env.ADYEN_API_KEY = "test_key";
62
+ process.env.ADYEN_MERCHANT_ACCOUNT = "test_merchant";
63
+ process.env.APP_URL = "https://example.com";
64
+ });
65
+
66
+ test("constructor configuration", () => {
67
+ const client = new AdyenPayments(components.adyenPayments);
68
+ expect(client.apiKey).toBe("test_key");
69
+ expect(client.merchantAccount).toBe("test_merchant");
70
+ expect(client.environment).toBe("TEST");
71
+ });
72
+
73
+ test("shopper operations in client context", async () => {
74
+ const t = initConvexTest();
75
+ const payments = new AdyenPayments(components.adyenPayments);
76
+
77
+ const shopperRef = await payments.createShopper(t as unknown as ActionCtx, {
78
+ shopperReference: "shopper_1",
79
+ email: "shopper1@example.com",
80
+ });
81
+ expect(shopperRef).toBe("shopper_1");
82
+ });
83
+
84
+ test("checkout session creation", async () => {
85
+ const t = initConvexTest();
86
+ const payments = new AdyenPayments(components.adyenPayments);
87
+
88
+ const session = await payments.createCheckoutSession(t as unknown as ActionCtx, {
89
+ amount: 1500,
90
+ currency: "USD",
91
+ successUrl: "https://example.com/success",
92
+ cancelUrl: "https://example.com/cancel",
93
+ });
94
+
95
+ expect(session.sessionId).toBe("sess_123");
96
+ expect(session.url).toBe("https://checkout.adyen.com/pay/123");
97
+ });
98
+
99
+ test("charging stored payment method", async () => {
100
+ const t = initConvexTest();
101
+ const payments = new AdyenPayments(components.adyenPayments);
102
+
103
+ const chargeResult = await payments.chargeStoredCard(t as unknown as ActionCtx, {
104
+ shopperReference: "shopper_1",
105
+ recurringDetailReference: "token_123",
106
+ amount: 5000,
107
+ currency: "EUR",
108
+ autoCapture: false,
109
+ });
110
+
111
+ expect(chargeResult.pspReference).toBe("psp_123");
112
+ expect(chargeResult.status).toBe("authorised");
113
+ });
114
+
115
+ test("autoCapture and captureDelayHours configuration logic", async () => {
116
+ // 1. Default constructor options
117
+ const clientDefault = new AdyenPayments(components.adyenPayments);
118
+ expect(clientDefault.captureDelayHours).toBe(0);
119
+
120
+ // 2. autoCapture: false -> captureDelayHours = -1
121
+ const clientManual = new AdyenPayments(components.adyenPayments, { autoCapture: false });
122
+ expect(clientManual.captureDelayHours).toBe(-1);
123
+
124
+ // 3. autoCapture: true -> captureDelayHours = 0
125
+ const clientAuto = new AdyenPayments(components.adyenPayments, { autoCapture: true });
126
+ expect(clientAuto.captureDelayHours).toBe(0);
127
+
128
+ // 4. autoCapture: true and captureDelayHours: -1 -> captureDelayHours = 0 (resolved conflict)
129
+ const clientConflict1 = new AdyenPayments(components.adyenPayments, { autoCapture: true, captureDelayHours: -1 });
130
+ expect(clientConflict1.captureDelayHours).toBe(0);
131
+
132
+ // 5. autoCapture: true and captureDelayHours: 24 -> captureDelayHours = 24
133
+ const clientConflict2 = new AdyenPayments(components.adyenPayments, { autoCapture: true, captureDelayHours: 24 });
134
+ expect(clientConflict2.captureDelayHours).toBe(24);
135
+ });
136
+
137
+ test("createCheckoutSession and chargeStoredCard autoCapture parameters mapping", async () => {
138
+ const t = initConvexTest();
139
+ const payments = new AdyenPayments(components.adyenPayments, { autoCapture: false });
140
+
141
+ const { CheckoutAPI } = await import("@adyen/api-library");
142
+ const checkoutInstance = new CheckoutAPI(null as any);
143
+ const sessionsSpy = vi.mocked(checkoutInstance.PaymentsApi.sessions);
144
+ const paymentsSpy = vi.mocked(checkoutInstance.PaymentsApi.payments);
145
+
146
+ sessionsSpy.mockClear();
147
+ paymentsSpy.mockClear();
148
+
149
+ // 1. Client configured with autoCapture: false, method called without override
150
+ await payments.createCheckoutSession(t as unknown as ActionCtx, {
151
+ amount: 1500,
152
+ currency: "USD",
153
+ successUrl: "https://example.com/success",
154
+ cancelUrl: "https://example.com/cancel",
155
+ });
156
+ expect(sessionsSpy).toHaveBeenCalledWith(expect.objectContaining({
157
+ captureDelayHours: -1,
158
+ }));
159
+
160
+ // 2. Client configured with autoCapture: false, method called with override autoCapture: true
161
+ sessionsSpy.mockClear();
162
+ await payments.createCheckoutSession(t as unknown as ActionCtx, {
163
+ amount: 1500,
164
+ currency: "USD",
165
+ successUrl: "https://example.com/success",
166
+ cancelUrl: "https://example.com/cancel",
167
+ autoCapture: true,
168
+ });
169
+ expect(sessionsSpy).toHaveBeenCalledWith(expect.objectContaining({
170
+ captureDelayHours: 0,
171
+ }));
172
+
173
+ // 3. chargeStoredCard client default vs override
174
+ await payments.chargeStoredCard(t as unknown as ActionCtx, {
175
+ shopperReference: "shopper_1",
176
+ recurringDetailReference: "token_123",
177
+ amount: 5000,
178
+ currency: "EUR",
179
+ });
180
+ expect(paymentsSpy).toHaveBeenCalledWith(expect.objectContaining({
181
+ captureDelayHours: -1,
182
+ }));
183
+
184
+ paymentsSpy.mockClear();
185
+ await payments.chargeStoredCard(t as unknown as ActionCtx, {
186
+ shopperReference: "shopper_1",
187
+ recurringDetailReference: "token_123",
188
+ amount: 5000,
189
+ currency: "EUR",
190
+ autoCapture: true,
191
+ });
192
+ expect(paymentsSpy).toHaveBeenCalledWith(expect.objectContaining({
193
+ captureDelayHours: 0,
194
+ }));
195
+ });
196
+ });