@reeboot/strapi-payment-plugin 0.0.0 → 0.0.1

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 (38) hide show
  1. package/README.md +82 -9
  2. package/dist/_chunks/{App-DoUUpjp-.mjs → App-DD7GyuRr.mjs} +572 -297
  3. package/dist/_chunks/{App-BGle38NN.js → App-KZVBFRwo.js} +569 -294
  4. package/dist/admin/index.js +2 -2
  5. package/dist/admin/index.mjs +2 -2
  6. package/dist/admin/src/pluginId.d.ts +1 -1
  7. package/dist/server/index.js +952 -6988
  8. package/dist/server/index.mjs +951 -6987
  9. package/dist/server/src/bootstrap.d.ts +11 -5
  10. package/dist/server/src/config/index.d.ts +2 -0
  11. package/dist/server/src/content-types/index.d.ts +123 -1
  12. package/dist/server/src/content-types/product.d.ts +63 -0
  13. package/dist/server/src/content-types/subscription.d.ts +60 -0
  14. package/dist/server/src/controllers/controller.d.ts +5 -1
  15. package/dist/server/src/controllers/index.d.ts +29 -29
  16. package/dist/server/src/controllers/product.d.ts +18 -0
  17. package/dist/server/src/controllers/subscription.d.ts +16 -0
  18. package/dist/server/src/controllers/webhook.d.ts +10 -0
  19. package/dist/server/src/index.d.ts +177 -65
  20. package/dist/server/src/routes/index.d.ts +4 -15
  21. package/dist/server/src/routes/product.d.ts +2 -0
  22. package/dist/server/src/routes/subscription.d.ts +5 -0
  23. package/dist/server/src/routes/{product-routes.d.ts → webhook.d.ts} +3 -1
  24. package/dist/server/src/services/index.d.ts +17 -16
  25. package/dist/server/src/services/paypalDriver.d.ts +44 -4
  26. package/dist/server/src/services/product.d.ts +7 -0
  27. package/dist/server/src/services/service.d.ts +7 -14
  28. package/dist/server/src/services/stripeDriver.d.ts +31 -0
  29. package/dist/server/src/services/subscription.d.ts +9 -0
  30. package/dist/server/src/services/sync.d.ts +13 -0
  31. package/package.json +4 -3
  32. package/dist/server/controllers/product.d.ts +0 -12
  33. package/dist/server/controllers/subscription.d.ts +0 -12
  34. package/dist/server/services/product.d.ts +0 -7
  35. package/dist/server/services/subscription.d.ts +0 -7
  36. package/dist/server/src/controllers/productController.d.ts +0 -9
  37. package/dist/server/src/controllers/subscriptionController.d.ts +0 -9
  38. package/dist/server/src/routes/subscription-routes.d.ts +0 -13
@@ -6,164 +6,6 @@ const reactRouterDom = require("react-router-dom");
6
6
  const react = require("react");
7
7
  const designSystem = require("@strapi/design-system");
8
8
  const formik = require("formik");
9
- const HomePage = () => {
10
- const [transactions, setTransactions] = react.useState([]);
11
- const [loading, setLoading] = react.useState(false);
12
- const [error, setError] = react.useState(null);
13
- const [stats, setStats] = react.useState({
14
- totalRevenue: 0,
15
- totalTransactions: 0,
16
- successRate: 0
17
- });
18
- const [searchTerm, setSearchTerm] = react.useState("");
19
- const [filter, setFilter] = react.useState("all");
20
- const fetchData = async () => {
21
- setLoading(true);
22
- setError(null);
23
- try {
24
- const response = await fetch("/payment-plugin/transactions");
25
- if (!response.ok) {
26
- throw new Error("Failed to fetch transactions");
27
- }
28
- const data = await response.json();
29
- setTransactions(data.data);
30
- const totalAmount = data.data.reduce(
31
- (sum, t) => sum + t.amount,
32
- 0
33
- );
34
- const successCount = data.data.filter(
35
- (t) => t.status === "completed"
36
- ).length;
37
- const successRate = data.data.length > 0 ? successCount / data.data.length * 100 : 0;
38
- setStats({
39
- totalRevenue: totalAmount,
40
- totalTransactions: data.data.length,
41
- successRate
42
- });
43
- } catch (err) {
44
- if (err instanceof Error) {
45
- setError(err.message);
46
- } else {
47
- setError("An unknown error occurred");
48
- }
49
- } finally {
50
- setLoading(false);
51
- }
52
- };
53
- react.useEffect(() => {
54
- fetchData();
55
- }, []);
56
- const handleSearch = (e) => {
57
- setSearchTerm(e.target.value);
58
- };
59
- const handleFilterChange = (e) => {
60
- setFilter(e.target.value);
61
- };
62
- const filteredTransactions = transactions.filter((transaction) => {
63
- const matchesSearch = [
64
- transaction.id,
65
- transaction.customer,
66
- transaction.amount.toString()
67
- ].some(
68
- (field) => field.toLowerCase().includes(searchTerm.toLowerCase())
69
- );
70
- const matchesFilter = filter === "all" || transaction.status === filter;
71
- return matchesSearch && matchesFilter;
72
- });
73
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { padding: 6, background: "neutral0", children: [
74
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", as: "h1", textColor: "primary600", style: { marginBottom: "2rem" }, children: "Payment Plugin Home" }),
75
- /* @__PURE__ */ jsxRuntime.jsxs(
76
- designSystem.Box,
77
- {
78
- padding: 4,
79
- background: "neutral100",
80
- borderRadius: "4px",
81
- border: "1px solid #e0e0e0",
82
- style: { marginBottom: "2rem" },
83
- children: [
84
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "beta", as: "h2", textColor: "neutral800", style: { marginBottom: "1rem" }, children: "Payment Statistics" }),
85
- loading && /* @__PURE__ */ jsxRuntime.jsx("p", { children: "Loading statistics..." }),
86
- error && /* @__PURE__ */ jsxRuntime.jsx("p", { style: { color: "red" }, children: error }),
87
- !loading && !error && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Grid.Root, { gap: 4, children: [
88
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 4, s: 12, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { padding: 4, background: "neutral0", borderRadius: "4px", border: "1px solid #e0e0e0", children: [
89
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "epsilon", textColor: "neutral800", children: "Total Revenue" }),
90
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "alpha", textColor: "primary600", children: [
91
- "$",
92
- stats.totalRevenue.toFixed(2)
93
- ] })
94
- ] }) }),
95
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 4, s: 12, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { padding: 4, background: "neutral0", borderRadius: "4px", border: "1px solid #e0e0e0", children: [
96
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "epsilon", textColor: "neutral800", children: "Total Transactions" }),
97
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", textColor: "primary600", children: stats.totalTransactions })
98
- ] }) }),
99
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 4, s: 12, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { padding: 4, background: "neutral0", borderRadius: "4px", border: "1px solid #e0e0e0", children: [
100
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "epsilon", textColor: "neutral800", children: "Successful Payments" }),
101
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "alpha", textColor: "primary600", children: [
102
- stats.successRate.toFixed(2),
103
- "%"
104
- ] })
105
- ] }) })
106
- ] })
107
- ]
108
- }
109
- ),
110
- /* @__PURE__ */ jsxRuntime.jsxs(
111
- designSystem.Box,
112
- {
113
- padding: 4,
114
- background: "neutral100",
115
- borderRadius: "4px",
116
- border: "1px solid #e0e0e0",
117
- children: [
118
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "beta", as: "h2", textColor: "neutral800", style: { marginBottom: "1rem" }, children: "Transactions" }),
119
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginBottom: "1rem", display: "flex", gap: "1rem", alignItems: "center", flexWrap: "wrap" }, children: [
120
- /* @__PURE__ */ jsxRuntime.jsx(
121
- designSystem.TextInput,
122
- {
123
- label: "Search Transactions",
124
- value: searchTerm,
125
- onChange: handleSearch,
126
- placeholder: "Search by ID, email, or amount",
127
- style: { flex: 1, minWidth: "200px" }
128
- }
129
- ),
130
- /* @__PURE__ */ jsxRuntime.jsxs("select", { value: filter, onChange: handleFilterChange, style: { minWidth: "150px" }, children: [
131
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All Transactions" }),
132
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "completed", children: "Successful" }),
133
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "failed", children: "Failed" }),
134
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "pending", children: "Pending" })
135
- ] })
136
- ] }),
137
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { overflowX: "auto" }, children: [
138
- loading && /* @__PURE__ */ jsxRuntime.jsx("p", { children: "Loading transactions..." }),
139
- error && /* @__PURE__ */ jsxRuntime.jsx("p", { style: { color: "red" }, children: error }),
140
- !loading && !error && /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: filteredTransactions.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Table, { children: [
141
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Thead, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tr, { children: [
142
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: "ID" }),
143
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: "Amount" }),
144
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: "Currency" }),
145
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: "Status" }),
146
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: "Date" }),
147
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: "Customer" })
148
- ] }) }),
149
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tbody, { children: filteredTransactions.map((transaction) => /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tr, { children: [
150
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: transaction.id }),
151
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Td, { children: [
152
- "$",
153
- transaction.amount.toFixed(2)
154
- ] }),
155
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: transaction.currency }),
156
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: transaction.status }),
157
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: new Date(transaction.date).toLocaleDateString() }),
158
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: transaction.customer })
159
- ] }, transaction.id)) })
160
- ] }) : /* @__PURE__ */ jsxRuntime.jsx("p", { children: "No transactions found" }) })
161
- ] })
162
- ]
163
- }
164
- )
165
- ] });
166
- };
167
9
  const ConfigurationPage = () => {
168
10
  const [stripeSecretKey, setStripeSecretKey] = react.useState("");
169
11
  const [stripePublishableKey, setStripePublishableKey] = react.useState("");
@@ -171,6 +13,7 @@ const ConfigurationPage = () => {
171
13
  const [paypalClientId, setPaypalClientId] = react.useState("");
172
14
  const [paypalClientSecret, setPaypalClientSecret] = react.useState("");
173
15
  const [paypalWebhookId, setPaypalWebhookId] = react.useState("");
16
+ const [returnURL, setReturnURL] = react.useState(`${window.location.origin}/strapi-payment-plugin/webhook/stripe`);
174
17
  const [configStatus, setConfigStatus] = react.useState({
175
18
  stripe: false,
176
19
  paypal: false
@@ -178,7 +21,7 @@ const ConfigurationPage = () => {
178
21
  react.useEffect(() => {
179
22
  const fetchConfigStatus = async () => {
180
23
  try {
181
- const response = await fetch("/payment-plugin/config-status");
24
+ const response = await fetch("/strapi-payment-plugin/config-status");
182
25
  if (response.ok) {
183
26
  const data = await response.json();
184
27
  setConfigStatus(data);
@@ -190,7 +33,7 @@ const ConfigurationPage = () => {
190
33
  fetchConfigStatus();
191
34
  }, []);
192
35
  const handleSave = async () => {
193
- const response = await fetch("/payment-plugin/config", {
36
+ const response = await fetch("/strapi-payment-plugin/config", {
194
37
  method: "POST",
195
38
  headers: {
196
39
  "Content-Type": "application/json"
@@ -214,10 +57,90 @@ const ConfigurationPage = () => {
214
57
  alert("Failed to save configuration");
215
58
  }
216
59
  };
60
+ async function onclickTest() {
61
+ try {
62
+ const returnUrl = returnURL;
63
+ const response = await fetch("/strapi-payment-plugin/test-payment", {
64
+ method: "POST",
65
+ headers: {
66
+ "Content-Type": "application/json"
67
+ },
68
+ body: JSON.stringify({
69
+ amount: 1e3,
70
+ // $10.00
71
+ currency: "usd",
72
+ paymentMethod: "pm_card_visa",
73
+ // Test card
74
+ returnUrl
75
+ })
76
+ });
77
+ if (response.ok) {
78
+ const result = await response.json();
79
+ alert(`Payment successful!
80
+ Payment ID: ${result.paymentId}
81
+ Return URL: ${returnUrl}`);
82
+ } else {
83
+ const error = await response.json();
84
+ alert(`Payment failed:
85
+ ${error.message}`);
86
+ }
87
+ } catch (err) {
88
+ if (err instanceof Error) {
89
+ alert(`Error testing payment:
90
+ ${err.message}`);
91
+ } else {
92
+ alert("An unknown error occurred while testing payment");
93
+ }
94
+ }
95
+ }
96
+ async function onclickTestWithRedirect() {
97
+ try {
98
+ const returnUrl = returnURL;
99
+ const response = await fetch("/strapi-payment-plugin/test-payment-with-redirect", {
100
+ method: "POST",
101
+ headers: {
102
+ "Content-Type": "application/json"
103
+ },
104
+ body: JSON.stringify({
105
+ productId: "price_1Rryf5FYBY9tFLhrxZRaCvC8"
106
+ // Example product ID
107
+ })
108
+ });
109
+ if (response.ok) {
110
+ const result = await response.json();
111
+ if (result.paymentLink) {
112
+ window.location.href = result.paymentLink;
113
+ } else {
114
+ alert(`Payment successful!
115
+ Payment ID: ${result.paymentId}`);
116
+ }
117
+ } else {
118
+ const error = await response.json();
119
+ alert(`Payment failed:
120
+ ${error.message}`);
121
+ }
122
+ } catch (err) {
123
+ if (err instanceof Error) {
124
+ alert(`Error testing payment:
125
+ ${err.message}`);
126
+ } else {
127
+ alert("An unknown error occurred while testing payment");
128
+ }
129
+ }
130
+ }
217
131
  return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Main, { children: [
218
132
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Main, { title: "Payment Plugin Configuration" }),
219
133
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Main, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { padding: 6, background: "neutral0", children: [
220
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", as: "h1", textColor: "primary600", style: { marginBottom: "2rem" }, children: "Payment Configuration" }),
134
+ /* @__PURE__ */ jsxRuntime.jsx(
135
+ designSystem.Typography,
136
+ {
137
+ variant: "alpha",
138
+ as: "h1",
139
+ textColor: "primary600",
140
+ style: { marginBottom: "2rem" },
141
+ children: "Payment Configuration"
142
+ }
143
+ ),
221
144
  /* @__PURE__ */ jsxRuntime.jsxs(
222
145
  designSystem.Box,
223
146
  {
@@ -227,32 +150,67 @@ const ConfigurationPage = () => {
227
150
  border: "1px solid #e0e0e0",
228
151
  style: { marginBottom: "2rem" },
229
152
  children: [
230
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "beta", as: "h2", textColor: "neutral800", style: { marginBottom: "1rem" }, children: "Payment Configuration" }),
153
+ /* @__PURE__ */ jsxRuntime.jsx(
154
+ designSystem.Typography,
155
+ {
156
+ variant: "beta",
157
+ as: "h2",
158
+ textColor: "neutral800",
159
+ style: { marginBottom: "1rem" },
160
+ children: "Payment Configuration"
161
+ }
162
+ ),
231
163
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Grid.Root, { gap: 6, style: { marginBottom: "2rem" }, children: [
232
164
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 6, s: 12, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", alignItems: "center", children: [
233
165
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "gamma", as: "h3", textColor: "neutral800", children: "Stripe Status  " }),
234
166
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { alignItems: "center", children: [
235
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: {
236
- width: "10px",
237
- height: "10px",
238
- borderRadius: "50%",
239
- backgroundColor: configStatus.stripe ? "green" : "red",
240
- marginRight: "8px"
241
- } }),
242
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", fontWeight: "bold", textColor: configStatus.stripe ? "success600" : "danger600", children: configStatus.stripe ? "Connected" : "Not Connected" })
167
+ /* @__PURE__ */ jsxRuntime.jsx(
168
+ "div",
169
+ {
170
+ style: {
171
+ width: "10px",
172
+ height: "10px",
173
+ borderRadius: "50%",
174
+ backgroundColor: configStatus.stripe ? "green" : "red",
175
+ marginRight: "8px"
176
+ }
177
+ }
178
+ ),
179
+ /* @__PURE__ */ jsxRuntime.jsx(
180
+ designSystem.Typography,
181
+ {
182
+ variant: "pi",
183
+ fontWeight: "bold",
184
+ textColor: configStatus.stripe ? "success600" : "danger600",
185
+ children: configStatus.stripe ? "Connected" : "Not Connected"
186
+ }
187
+ )
243
188
  ] })
244
189
  ] }) }),
245
190
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 6, s: 12, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", alignItems: "center", children: [
246
191
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "gamma", as: "h3", textColor: "neutral800", children: "PayPal Status  " }),
247
192
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { alignItems: "center", children: [
248
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: {
249
- width: "10px",
250
- height: "10px",
251
- borderRadius: "50%",
252
- backgroundColor: configStatus.paypal ? "green" : "red",
253
- marginRight: "8px"
254
- } }),
255
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", fontWeight: "bold", textColor: configStatus.paypal ? "success600" : "danger600", children: configStatus.paypal ? "Connected" : "Not Connected" })
193
+ /* @__PURE__ */ jsxRuntime.jsx(
194
+ "div",
195
+ {
196
+ style: {
197
+ width: "10px",
198
+ height: "10px",
199
+ borderRadius: "50%",
200
+ backgroundColor: configStatus.paypal ? "green" : "red",
201
+ marginRight: "8px"
202
+ }
203
+ }
204
+ ),
205
+ /* @__PURE__ */ jsxRuntime.jsx(
206
+ designSystem.Typography,
207
+ {
208
+ variant: "pi",
209
+ fontWeight: "bold",
210
+ textColor: configStatus.paypal ? "success600" : "danger600",
211
+ children: configStatus.paypal ? "Connected" : "Not Connected"
212
+ }
213
+ )
256
214
  ] })
257
215
  ] }) })
258
216
  ] }),
@@ -266,7 +224,16 @@ const ConfigurationPage = () => {
266
224
  border: "1px solid #e0e0e0",
267
225
  style: { marginBottom: "1rem", width: "100%" },
268
226
  children: [
269
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "gamma", as: "h3", textColor: "neutral800", style: { marginBottom: "1rem" }, children: "Stripe Configuration" }),
227
+ /* @__PURE__ */ jsxRuntime.jsx(
228
+ designSystem.Typography,
229
+ {
230
+ variant: "gamma",
231
+ as: "h3",
232
+ textColor: "neutral800",
233
+ style: { marginBottom: "1rem" },
234
+ children: "Stripe Configuration"
235
+ }
236
+ ),
270
237
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 8, alignItems: "initial", children: [
271
238
  /* @__PURE__ */ jsxRuntime.jsx(
272
239
  designSystem.TextInput,
@@ -325,7 +292,16 @@ const ConfigurationPage = () => {
325
292
  border: "1px solid #e0e0e0",
326
293
  style: { marginBottom: "1rem", width: "100%" },
327
294
  children: [
328
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "gamma", as: "h3", textColor: "neutral800", style: { marginBottom: "1rem" }, children: "PayPal Configuration" }),
295
+ /* @__PURE__ */ jsxRuntime.jsx(
296
+ designSystem.Typography,
297
+ {
298
+ variant: "gamma",
299
+ as: "h3",
300
+ textColor: "neutral800",
301
+ style: { marginBottom: "1rem" },
302
+ children: "PayPal Configuration (not implemented for now)"
303
+ }
304
+ ),
329
305
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 8, alignItems: "initial", children: [
330
306
  /* @__PURE__ */ jsxRuntime.jsx(
331
307
  designSystem.TextInput,
@@ -334,7 +310,7 @@ const ConfigurationPage = () => {
334
310
  name: "paypalClientId",
335
311
  value: paypalClientId,
336
312
  onChange: (e) => setPaypalClientId(e.target.value),
337
- disabled: configStatus.paypal,
313
+ disabled: true,
338
314
  style: {
339
315
  border: configStatus.paypal ? "2px solid #4CAF50" : "",
340
316
  width: "100%"
@@ -350,7 +326,7 @@ const ConfigurationPage = () => {
350
326
  value: paypalClientSecret,
351
327
  onChange: (e) => setPaypalClientSecret(e.target.value),
352
328
  type: "password",
353
- disabled: configStatus.paypal,
329
+ disabled: true,
354
330
  style: {
355
331
  border: configStatus.paypal ? "2px solid #4CAF50" : ""
356
332
  },
@@ -365,7 +341,7 @@ const ConfigurationPage = () => {
365
341
  name: "paypalWebhookId",
366
342
  value: paypalWebhookId,
367
343
  onChange: (e) => setPaypalWebhookId(e.target.value),
368
- disabled: configStatus.paypal,
344
+ disabled: true,
369
345
  style: {
370
346
  border: configStatus.paypal ? "2px solid #4CAF50" : ""
371
347
  },
@@ -380,12 +356,63 @@ const ConfigurationPage = () => {
380
356
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleSave, style: { marginTop: "1rem" }, children: "Save Configuration" })
381
357
  ]
382
358
  }
359
+ ),
360
+ /* @__PURE__ */ jsxRuntime.jsxs(
361
+ designSystem.Box,
362
+ {
363
+ padding: 4,
364
+ background: "neutral100",
365
+ borderRadius: "4px",
366
+ border: "1px solid #e0e0e0",
367
+ style: { marginTop: "2rem" },
368
+ children: [
369
+ /* @__PURE__ */ jsxRuntime.jsx(
370
+ designSystem.Typography,
371
+ {
372
+ variant: "beta",
373
+ as: "h2",
374
+ textColor: "neutral800",
375
+ style: { marginBottom: "1rem" },
376
+ children: "Stripe Payment Testing"
377
+ }
378
+ ),
379
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", style: { marginBottom: "1rem" }, children: "Test Stripe payment generation and handling" }),
380
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { style: { marginBottom: "1rem" }, children: /* @__PURE__ */ jsxRuntime.jsx(
381
+ designSystem.TextInput,
382
+ {
383
+ placeholder: "Return URL (e.g., https://example.com/return)",
384
+ name: "returnUrl",
385
+ id: "returnUrl",
386
+ style: { marginBottom: "1rem", width: "100%" },
387
+ value: returnURL,
388
+ onChange: (e) => setReturnURL(e.target.value),
389
+ defaultValue: `${window.location.origin}/strapi-payment-plugin/webhook/stripe`
390
+ }
391
+ ) }),
392
+ /* @__PURE__ */ jsxRuntime.jsx(
393
+ designSystem.Button,
394
+ {
395
+ onClick: onclickTest,
396
+ style: { marginBottom: "1rem" },
397
+ children: "Test Stripe Payment"
398
+ }
399
+ ),
400
+ /* @__PURE__ */ jsxRuntime.jsx(
401
+ designSystem.Button,
402
+ {
403
+ onClick: onclickTestWithRedirect,
404
+ style: { marginBottom: "1rem", marginLeft: "1rem" },
405
+ children: "Test Stripe Payment with Redirect"
406
+ }
407
+ )
408
+ ]
409
+ }
383
410
  )
384
411
  ] }) })
385
412
  ] });
386
413
  };
387
414
  const TransactionList = ({ transactions, onViewDetails, onStatusUpdate }) => {
388
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Table, { children: [
415
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Table, { style: { fontSize: "14px" }, children: [
389
416
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Thead, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tr, { children: [
390
417
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: "ID" }),
391
418
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: "Amount" }),
@@ -393,6 +420,7 @@ const TransactionList = ({ transactions, onViewDetails, onStatusUpdate }) => {
393
420
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: "Status" }),
394
421
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: "Date" }),
395
422
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: "Customer" }),
423
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: "Gateway" }),
396
424
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: "Actions" })
397
425
  ] }) }),
398
426
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tbody, { children: transactions.map((transaction) => /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tr, { children: [
@@ -418,6 +446,7 @@ const TransactionList = ({ transactions, onViewDetails, onStatusUpdate }) => {
418
446
  ) : transaction.status }),
419
447
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: new Date(transaction.date).toLocaleDateString() }),
420
448
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: transaction.customer }),
449
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: transaction.gateway }),
421
450
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "secondary", size: "S", onClick: () => onViewDetails(transaction), children: "View" }) })
422
451
  ] }, transaction.id)) })
423
452
  ] });
@@ -492,7 +521,7 @@ const TransactionsPage = () => {
492
521
  setLoading(true);
493
522
  setError(null);
494
523
  try {
495
- const response = await fetch("/payment-plugin/transactions");
524
+ const response = await fetch("/strapi-payment-plugin/transactions?gateway=all&status=all");
496
525
  if (!response.ok) {
497
526
  throw new Error("Failed to fetch transactions");
498
527
  }
@@ -529,7 +558,7 @@ const TransactionsPage = () => {
529
558
  const handleRefund = async () => {
530
559
  if (!selectedTransaction) return;
531
560
  try {
532
- const response = await fetch("/payment-plugin/refund", {
561
+ const response = await fetch("/strapi-payment-plugin/refund", {
533
562
  method: "POST",
534
563
  headers: {
535
564
  "Content-Type": "application/json"
@@ -560,19 +589,6 @@ const TransactionsPage = () => {
560
589
  }
561
590
  }
562
591
  };
563
- const handleStatusUpdate = async (transactionId, newStatus) => {
564
- try {
565
- setTransactions(transactions.map(
566
- (t) => t.id === transactionId ? { ...t, status: newStatus } : t
567
- ));
568
- } catch (err) {
569
- if (err instanceof Error) {
570
- setError(err.message);
571
- } else {
572
- setError("An unknown error occurred");
573
- }
574
- }
575
- };
576
592
  return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Main, { children: [
577
593
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Main, { title: "Transactions" }),
578
594
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { padding: 6, background: "neutral0", children: [
@@ -612,8 +628,7 @@ const TransactionsPage = () => {
612
628
  TransactionList,
613
629
  {
614
630
  transactions: filteredTransactions,
615
- onViewDetails: handleViewDetails,
616
- onStatusUpdate: handleStatusUpdate
631
+ onViewDetails: handleViewDetails
617
632
  }
618
633
  ) : /* @__PURE__ */ jsxRuntime.jsx("p", { children: "No transactions found" }) })
619
634
  ] })
@@ -645,19 +660,14 @@ const DashboardPage = () => {
645
660
  setLoading(true);
646
661
  setError(null);
647
662
  try {
648
- const response = await fetch("/payment-plugin/transactions");
663
+ const response = await fetch("/strapi-payment-plugin/transactions?gateway=all&status=all");
649
664
  if (!response.ok) {
650
665
  throw new Error("Failed to fetch transactions");
651
666
  }
652
667
  const data = await response.json();
653
668
  setTransactions(data.data.slice(0, 5));
654
- const totalAmount = data.data.reduce(
655
- (sum, t) => sum + t.amount,
656
- 0
657
- );
658
- const successCount = data.data.filter(
659
- (t) => t.status === "completed"
660
- ).length;
669
+ const totalAmount = data.data.reduce((sum, t) => sum + t.amount, 0);
670
+ const successCount = data.data.filter((t) => t.status === "completed").length;
661
671
  const successRate = data.data.length > 0 ? successCount / data.data.length * 100 : 0;
662
672
  setStats({
663
673
  totalRevenue: totalAmount,
@@ -690,53 +700,90 @@ const DashboardPage = () => {
690
700
  border: "1px solid #e0e0e0",
691
701
  style: { marginBottom: "2rem" },
692
702
  children: [
693
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "beta", as: "h2", textColor: "neutral800", style: { marginBottom: "1rem" }, children: "Payment Statistics" }),
703
+ /* @__PURE__ */ jsxRuntime.jsx(
704
+ designSystem.Typography,
705
+ {
706
+ variant: "beta",
707
+ as: "h2",
708
+ textColor: "neutral800",
709
+ style: { marginBottom: "1rem" },
710
+ children: "Payment Statistics"
711
+ }
712
+ ),
694
713
  loading && /* @__PURE__ */ jsxRuntime.jsx("p", { children: "Loading statistics..." }),
695
714
  error && /* @__PURE__ */ jsxRuntime.jsx("p", { style: { color: "red" }, children: error }),
696
715
  !loading && !error && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Grid.Root, { gap: 4, children: [
697
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 4, s: 12, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { padding: 4, background: "neutral0", borderRadius: "4px", border: "1px solid #e0e0e0", children: [
698
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "epsilon", textColor: "neutral800", children: "Total Revenue" }),
699
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "alpha", textColor: "primary600", children: [
700
- "$",
701
- stats.totalRevenue.toFixed(2)
702
- ] })
703
- ] }) }),
704
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 4, s: 12, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { padding: 4, background: "neutral0", borderRadius: "4px", border: "1px solid #e0e0e0", children: [
705
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "epsilon", textColor: "neutral800", children: "Total Transactions" }),
706
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", textColor: "primary600", children: stats.totalTransactions })
707
- ] }) }),
708
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 4, s: 12, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { padding: 4, background: "neutral0", borderRadius: "4px", border: "1px solid #e0e0e0", children: [
709
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "epsilon", textColor: "neutral800", children: "Successful Payments" }),
710
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "alpha", textColor: "primary600", children: [
711
- stats.successRate.toFixed(2),
712
- "%"
713
- ] })
714
- ] }) })
716
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 4, s: 12, children: /* @__PURE__ */ jsxRuntime.jsx(
717
+ designSystem.Box,
718
+ {
719
+ padding: 4,
720
+ background: "neutral0",
721
+ borderRadius: "4px",
722
+ border: "1px solid #e0e0e0",
723
+ children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", alignItems: "center", direction: "column", children: [
724
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "epsilon", textColor: "neutral800", children: "Total Revenues" }),
725
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "alpha", textColor: "primary600", children: [
726
+ "$",
727
+ stats.totalRevenue.toFixed(2)
728
+ ] })
729
+ ] })
730
+ }
731
+ ) }),
732
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 4, s: 12, children: /* @__PURE__ */ jsxRuntime.jsx(
733
+ designSystem.Box,
734
+ {
735
+ padding: 4,
736
+ background: "neutral0",
737
+ borderRadius: "4px",
738
+ border: "1px solid #e0e0e0",
739
+ children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", alignItems: "center", direction: "column", children: [
740
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "epsilon", textColor: "neutral800", children: "Total Transactions" }),
741
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", textColor: "primary600", children: stats.totalTransactions })
742
+ ] })
743
+ }
744
+ ) }),
745
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 4, s: 12, children: /* @__PURE__ */ jsxRuntime.jsx(
746
+ designSystem.Box,
747
+ {
748
+ padding: 4,
749
+ background: "neutral0",
750
+ borderRadius: "4px",
751
+ border: "1px solid #e0e0e0",
752
+ children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", alignItems: "center", direction: "column", children: [
753
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "epsilon", textColor: "neutral800", children: "Successful Payments" }),
754
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "alpha", textColor: "primary600", children: [
755
+ stats.successRate.toFixed(2),
756
+ "%"
757
+ ] })
758
+ ] })
759
+ }
760
+ ) })
715
761
  ] })
716
762
  ]
717
763
  }
718
764
  ),
719
- /* @__PURE__ */ jsxRuntime.jsxs(
720
- designSystem.Box,
721
- {
722
- padding: 4,
723
- background: "neutral100",
724
- borderRadius: "4px",
725
- border: "1px solid #e0e0e0",
726
- children: [
727
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "beta", as: "h2", textColor: "neutral800", style: { marginBottom: "1rem" }, children: "Recent Transactions" }),
728
- loading && /* @__PURE__ */ jsxRuntime.jsx("p", { children: "Loading transactions..." }),
729
- error && /* @__PURE__ */ jsxRuntime.jsx("p", { style: { color: "red" }, children: error }),
730
- !loading && !error && /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: transactions.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(TransactionList, { transactions, onViewDetails: () => {
731
- } }) : /* @__PURE__ */ jsxRuntime.jsx("p", { children: "No recent transactions" }) })
732
- ]
733
- }
734
- )
765
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { padding: 4, background: "neutral100", borderRadius: "4px", border: "1px solid #e0e0e0", children: [
766
+ /* @__PURE__ */ jsxRuntime.jsx(
767
+ designSystem.Typography,
768
+ {
769
+ variant: "beta",
770
+ as: "h2",
771
+ textColor: "neutral800",
772
+ style: { marginBottom: "1rem" },
773
+ children: "Recent Transactions"
774
+ }
775
+ ),
776
+ loading && /* @__PURE__ */ jsxRuntime.jsx("p", { children: "Loading transactions..." }),
777
+ error && /* @__PURE__ */ jsxRuntime.jsx("p", { style: { color: "red" }, children: error }),
778
+ !loading && !error && /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: transactions.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(TransactionList, { transactions, onViewDetails: () => {
779
+ } }) : /* @__PURE__ */ jsxRuntime.jsx("p", { children: "No recent transactions" }) })
780
+ ] })
735
781
  ] })
736
782
  ] });
737
783
  };
738
784
  const ProductsPage = () => {
739
785
  const [products, setProducts] = react.useState([]);
786
+ const [stripeProducts, setStripeProducts] = react.useState([]);
740
787
  const [loading, setLoading] = react.useState(false);
741
788
  const [error, setError] = react.useState(null);
742
789
  const [isModalOpen, setIsModalOpen] = react.useState(false);
@@ -745,7 +792,7 @@ const ProductsPage = () => {
745
792
  setLoading(true);
746
793
  setError(null);
747
794
  try {
748
- const response = await fetch("/payment-plugin/products");
795
+ const response = await fetch("/strapi-payment-plugin/products");
749
796
  if (!response.ok) {
750
797
  throw new Error("Failed to fetch products");
751
798
  }
@@ -761,17 +808,51 @@ const ProductsPage = () => {
761
808
  setLoading(false);
762
809
  }
763
810
  };
811
+ const fetchStripeProducts = async () => {
812
+ setLoading(true);
813
+ setError(null);
814
+ try {
815
+ const response = await fetch("/strapi-payment-plugin/products/stripeProducts");
816
+ if (!response.ok) {
817
+ throw new Error("Failed to fetch Stripe products");
818
+ }
819
+ const data = await response.json();
820
+ console.log("Stripe Products:", data);
821
+ setStripeProducts(data);
822
+ } catch (err) {
823
+ if (err instanceof Error) {
824
+ setError(err.message);
825
+ } else {
826
+ setError("An unknown error occurred");
827
+ }
828
+ } finally {
829
+ setLoading(false);
830
+ }
831
+ };
764
832
  react.useEffect(() => {
765
833
  fetchProducts();
834
+ fetchStripeProducts();
766
835
  }, []);
767
- const handleEdit = (product) => {
768
- setCurrentProduct(product);
836
+ const handleCreate = () => {
837
+ setCurrentProduct({
838
+ documentId: "",
839
+ id: 0,
840
+ name: "",
841
+ description: "",
842
+ price: 0,
843
+ currency: "USD",
844
+ isSubscription: false,
845
+ subscriptionInterval: "month"
846
+ });
769
847
  setIsModalOpen(true);
770
848
  };
849
+ const handleEdit = (product) => {
850
+ location.href = `/admin/content-manager/collection-types/plugin::strapi-payment-plugin.product/${product.documentId}`;
851
+ };
771
852
  const handleDelete = async (id) => {
772
853
  if (confirm("Are you sure you want to delete this product?")) {
773
854
  try {
774
- const response = await fetch(`/payment-plugin/products/${id}`, {
855
+ const response = await fetch(`/strapi-payment-plugin/products/${id}`, {
775
856
  method: "DELETE"
776
857
  });
777
858
  if (!response.ok) {
@@ -787,20 +868,179 @@ const ProductsPage = () => {
787
868
  }
788
869
  }
789
870
  };
871
+ const handleSync = async (id) => {
872
+ try {
873
+ const response = await fetch(`/strapi-payment-plugin/products/${id}/sync`, {
874
+ method: "POST"
875
+ });
876
+ if (!response.ok) {
877
+ throw new Error("Failed to sync product");
878
+ }
879
+ const result = await response.json();
880
+ alert(result.message);
881
+ fetchProducts();
882
+ } catch (err) {
883
+ if (err instanceof Error) {
884
+ setError(err.message);
885
+ } else {
886
+ setError("An unknown error occurred");
887
+ }
888
+ }
889
+ };
890
+ const handleImport = async (stripeProductId) => {
891
+ try {
892
+ const response = await fetch("/strapi-payment-plugin/products/import", {
893
+ method: "POST",
894
+ headers: {
895
+ "Content-Type": "application/json"
896
+ },
897
+ body: JSON.stringify({ stripeProductId })
898
+ });
899
+ if (!response.ok) {
900
+ throw new Error("Failed to import product");
901
+ }
902
+ const result = await response.json();
903
+ alert(result.message);
904
+ fetchProducts();
905
+ fetchStripeProducts();
906
+ } catch (err) {
907
+ if (err instanceof Error) {
908
+ setError(err.message);
909
+ } else {
910
+ setError("An unknown error occurred");
911
+ }
912
+ }
913
+ };
914
+ const handleSubmit = async (values) => {
915
+ if (!currentProduct) return;
916
+ try {
917
+ const method = currentProduct.id ? "PUT" : "POST";
918
+ const url = currentProduct.id ? `/strapi-payment-plugin/products/${currentProduct.id}` : "/strapi-payment-plugin/products";
919
+ const response = await fetch(url, {
920
+ method,
921
+ headers: {
922
+ "Content-Type": "application/json"
923
+ },
924
+ body: JSON.stringify({ data: values })
925
+ });
926
+ if (!response.ok) {
927
+ throw new Error(`Failed to ${currentProduct.id ? "update" : "create"} product`);
928
+ }
929
+ setIsModalOpen(false);
930
+ fetchProducts();
931
+ } catch (err) {
932
+ if (err instanceof Error) {
933
+ setError(err.message);
934
+ } else {
935
+ setError("An unknown error occurred");
936
+ }
937
+ }
938
+ };
790
939
  return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Main, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { padding: 6, background: "neutral0", children: [
791
940
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", as: "h1", textColor: "primary600", style: { marginBottom: "2rem" }, children: "Products" }),
792
941
  error && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Alert, { variant: "danger", style: { marginBottom: "1rem" }, children: error }),
793
942
  loading && /* @__PURE__ */ jsxRuntime.jsx("p", { children: "Loading products..." }),
794
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Root, { children: [
795
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Trigger, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { children: "Create product" }) }),
943
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Root, { open: isModalOpen, onOpenChange: setIsModalOpen, children: [
944
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Trigger, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleCreate, children: "Create product" }) }),
796
945
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Content, { children: [
797
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Header, { children: [
798
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Title, { children: currentProduct ? currentProduct.id ? "Edit Product" : "Create Product" : "Product" }),
799
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.CloseButton, {})
800
- ] }),
801
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Body, {})
946
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Title, { children: currentProduct ? currentProduct.id ? "Edit Product" : "Create Product" : "Product" }) }),
947
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Body, { children: /* @__PURE__ */ jsxRuntime.jsx(
948
+ formik.Formik,
949
+ {
950
+ initialValues: {
951
+ documentId: currentProduct?.documentId || "",
952
+ id: currentProduct?.id || 0,
953
+ name: currentProduct?.name || "",
954
+ description: currentProduct?.description || "",
955
+ price: currentProduct?.price || 0,
956
+ currency: currentProduct?.currency || "USD",
957
+ isSubscription: currentProduct?.isSubscription || false,
958
+ subscriptionInterval: currentProduct?.subscriptionInterval || "month"
959
+ },
960
+ onSubmit: handleSubmit,
961
+ children: ({ values, handleChange, setFieldValue }) => /* @__PURE__ */ jsxRuntime.jsx(formik.Form, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", direction: "column", gap: 4, col: 12, children: [
962
+ /* @__PURE__ */ jsxRuntime.jsx(
963
+ designSystem.TextInput,
964
+ {
965
+ label: "Name",
966
+ name: "name",
967
+ placeHolder: "Product Name",
968
+ value: values.name,
969
+ onChange: handleChange,
970
+ required: true
971
+ }
972
+ ),
973
+ /* @__PURE__ */ jsxRuntime.jsx(
974
+ designSystem.Textarea,
975
+ {
976
+ label: "Description",
977
+ name: "description",
978
+ placeholder: "Product Description",
979
+ value: values.description,
980
+ onChange: handleChange
981
+ }
982
+ ),
983
+ /* @__PURE__ */ jsxRuntime.jsx(
984
+ designSystem.TextInput,
985
+ {
986
+ label: "Price",
987
+ name: "price",
988
+ type: "number",
989
+ placeholder: "Product Price",
990
+ value: values.price,
991
+ onChange: handleChange,
992
+ required: true
993
+ }
994
+ ),
995
+ /* @__PURE__ */ jsxRuntime.jsxs(
996
+ designSystem.SingleSelect,
997
+ {
998
+ label: "Currency",
999
+ name: "currency",
1000
+ placeholder: "Select Currency",
1001
+ value: values.currency,
1002
+ onChange: handleChange,
1003
+ children: [
1004
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "USD", children: "USD" }),
1005
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "EUR", children: "EUR" }),
1006
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "GBP", children: "GBP" })
1007
+ ]
1008
+ }
1009
+ ),
1010
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { style: { marginTop: "1rem" }, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "pi", textColor: "neutral800", children: [
1011
+ /* @__PURE__ */ jsxRuntime.jsx(
1012
+ formik.Field,
1013
+ {
1014
+ type: "checkbox",
1015
+ name: "isSubscription",
1016
+ checked: values.isSubscription,
1017
+ onChange: () => setFieldValue("isSubscription", !values.isSubscription)
1018
+ }
1019
+ ),
1020
+ " Is Subscription"
1021
+ ] }) }),
1022
+ values.isSubscription && /* @__PURE__ */ jsxRuntime.jsxs(
1023
+ designSystem.SingleSelect,
1024
+ {
1025
+ label: "Subscription Interval",
1026
+ name: "subscriptionInterval",
1027
+ value: values.subscriptionInterval,
1028
+ onChange: handleChange,
1029
+ children: [
1030
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "day", children: "Day" }),
1031
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "week", children: "Week" }),
1032
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "month", children: "Month" }),
1033
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "year", children: "Year" })
1034
+ ]
1035
+ }
1036
+ ),
1037
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { type: "submit", style: { marginTop: "1rem" }, children: currentProduct?.id ? "Update" : "Create" })
1038
+ ] }) })
1039
+ }
1040
+ ) })
802
1041
  ] })
803
1042
  ] }),
1043
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "beta", as: "h2", textColor: "primary600", style: { margin: "2rem 0 1rem" }, children: "Local Products" }),
804
1044
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Root, { gap: 4, children: products.map((product) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 4, s: 12, children: /* @__PURE__ */ jsxRuntime.jsxs(
805
1045
  designSystem.Box,
806
1046
  {
@@ -818,13 +1058,38 @@ const ProductsPage = () => {
818
1058
  product.isSubscription ? `/ ${product.subscriptionInterval}` : ""
819
1059
  ] }),
820
1060
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral600", style: { marginTop: "1rem" }, children: product.description }),
1061
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral600", style: { marginTop: "1rem" }, children: product.stripeProductId ? "✅ Synced with Stripe" : "⚠️ Not synced with Stripe" }),
821
1062
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { style: { marginTop: "1rem", gap: "1rem" }, children: [
822
1063
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "secondary", onClick: () => handleEdit(product), children: "Edit" }),
823
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "danger", onClick: () => handleDelete(product.id), children: "Delete" })
1064
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "danger", onClick: () => handleDelete(product.id), children: "Delete" }),
1065
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: () => handleSync(product.id), children: product.stripeProductId ? "Sync" : "Create in Stripe" })
824
1066
  ] })
825
1067
  ]
826
1068
  },
827
1069
  product.id
1070
+ ) }, product.id)) }),
1071
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "beta", as: "h2", textColor: "primary600", style: { margin: "2rem 0 1rem" }, children: "Stripe Products (Available for Import)" }),
1072
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Root, { gap: 4, children: stripeProducts.filter(
1073
+ (product) => !products.some((localProduct) => localProduct.stripeProductId === product.id)
1074
+ ).map((product) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 4, s: 12, children: /* @__PURE__ */ jsxRuntime.jsxs(
1075
+ designSystem.Box,
1076
+ {
1077
+ padding: 4,
1078
+ background: "neutral100",
1079
+ borderRadius: "4px",
1080
+ border: "1px solid #e0e0e0",
1081
+ children: [
1082
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "beta", as: "h2", textColor: "neutral800", children: product.name }),
1083
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { textColor: "red", children: [
1084
+ product?.default_price?.unit_amount / 100,
1085
+ " ",
1086
+ product?.default_price?.currency
1087
+ ] }),
1088
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral600", style: { marginTop: "1rem" }, children: product.description }),
1089
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { style: { marginTop: "1rem", gap: "1rem" }, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: () => handleImport(product.id), children: "Import from Stripe" }) })
1090
+ ]
1091
+ },
1092
+ product.id
828
1093
  ) }, product.id)) })
829
1094
  ] }) });
830
1095
  };
@@ -839,7 +1104,7 @@ const SubscriptionsPage = () => {
839
1104
  setLoading(true);
840
1105
  setError(null);
841
1106
  try {
842
- const response = await fetch("/payment-plugin/subscriptions");
1107
+ const response = await fetch("/strapi-payment-plugin/subscriptions");
843
1108
  if (!response.ok) {
844
1109
  throw new Error("Failed to fetch subscriptions");
845
1110
  }
@@ -857,7 +1122,7 @@ const SubscriptionsPage = () => {
857
1122
  };
858
1123
  const fetchProducts = async () => {
859
1124
  try {
860
- const response = await fetch("/payment-plugin/products");
1125
+ const response = await fetch("/strapi-payment-plugin/products");
861
1126
  if (!response.ok) {
862
1127
  throw new Error("Failed to fetch products");
863
1128
  }
@@ -878,7 +1143,7 @@ const SubscriptionsPage = () => {
878
1143
  const handleDelete = async (id) => {
879
1144
  if (confirm("Are you sure you want to delete this subscription?")) {
880
1145
  try {
881
- const response = await fetch(`/payment-plugin/subscriptions/${id}`, {
1146
+ const response = await fetch(`/strapi-payment-plugin/subscriptions/${id}`, {
882
1147
  method: "DELETE"
883
1148
  });
884
1149
  if (!response.ok) {
@@ -898,7 +1163,7 @@ const SubscriptionsPage = () => {
898
1163
  if (!currentSubscription) return;
899
1164
  try {
900
1165
  const method = currentSubscription.id ? "PUT" : "POST";
901
- const url = currentSubscription.id ? `/payment-plugin/subscriptions/${currentSubscription.id}` : "/payment-plugin/subscriptions";
1166
+ const url = currentSubscription.id ? `/strapi-payment-plugin/subscriptions/${currentSubscription.id}` : "/strapi-payment-plugin/subscriptions";
902
1167
  const response = await fetch(url, {
903
1168
  method,
904
1169
  headers: {
@@ -919,6 +1184,25 @@ const SubscriptionsPage = () => {
919
1184
  }
920
1185
  }
921
1186
  };
1187
+ const handleSync = async (id) => {
1188
+ try {
1189
+ const response = await fetch(`/strapi-payment-plugin/subscriptions/${id}/sync`, {
1190
+ method: "POST"
1191
+ });
1192
+ if (!response.ok) {
1193
+ throw new Error("Failed to sync subscription");
1194
+ }
1195
+ const result = await response.json();
1196
+ alert(result.message);
1197
+ fetchSubscriptions();
1198
+ } catch (err) {
1199
+ if (err instanceof Error) {
1200
+ setError(err.message);
1201
+ } else {
1202
+ setError("An unknown error occurred");
1203
+ }
1204
+ }
1205
+ };
922
1206
  return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Main, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { padding: 6, background: "neutral0", children: [
923
1207
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", as: "h1", textColor: "primary600", style: { marginBottom: "2rem" }, children: "Subscriptions" }),
924
1208
  error && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Alert, { variant: "danger", style: { marginBottom: "1rem" }, children: error }),
@@ -932,7 +1216,7 @@ const SubscriptionsPage = () => {
932
1216
  {
933
1217
  initialValues: {
934
1218
  id: currentSubscription?.id || 0,
935
- product: currentSubscription?.product || { id: 0, name: "" },
1219
+ product: currentSubscription?.product || { documentId: "", name: "", description: "", id: 0 },
936
1220
  user: currentSubscription?.user || { id: 0, email: "" },
937
1221
  status: currentSubscription?.status || "active",
938
1222
  startDate: currentSubscription?.startDate || (/* @__PURE__ */ new Date()).toISOString().split("T")[0],
@@ -944,18 +1228,16 @@ const SubscriptionsPage = () => {
944
1228
  designSystem.SingleSelect,
945
1229
  {
946
1230
  placeholder: "Product",
947
- name: "product.id",
948
- value: values.product.id || "",
949
- onChange: (e) => {
950
- const selectedProduct = products.find(
951
- (p) => p.id === parseInt(e.target.value)
952
- );
953
- setFieldValue("product", selectedProduct || { id: 0, name: "" });
1231
+ name: "product.documentId",
1232
+ value: values.product.documentId || "",
1233
+ onChange: (selectedDocumentId) => {
1234
+ setFieldValue("product", products.find((product) => product.documentId === selectedDocumentId));
1235
+ setFieldValue("product.documentId", selectedDocumentId);
954
1236
  },
955
1237
  required: true,
956
1238
  children: [
957
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: "Select a product" }),
958
- products.map((product) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: product.id, children: product.name }, product.id))
1239
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "", children: "Select a product" }),
1240
+ products.map((product) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: product.documentId, children: product.name }, product.id))
959
1241
  ]
960
1242
  }
961
1243
  ),
@@ -975,13 +1257,15 @@ const SubscriptionsPage = () => {
975
1257
  placeholder: "Status",
976
1258
  name: "status",
977
1259
  value: values.status,
978
- onChange: handleChange,
1260
+ onChange: (selectedStatus) => {
1261
+ setFieldValue("status", selectedStatus);
1262
+ },
979
1263
  children: [
980
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "active", children: "Active" }),
981
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "canceled", children: "Canceled" }),
982
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "past_due", children: "Past Due" }),
983
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "unpaid", children: "Unpaid" }),
984
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "trialing", children: "Trialing" })
1264
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "active", children: "Active" }),
1265
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "canceled", children: "Canceled" }),
1266
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "past_due", children: "Past Due" }),
1267
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "unpaid", children: "Unpaid" }),
1268
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "trialing", children: "Trialing" })
985
1269
  ]
986
1270
  }
987
1271
  ),
@@ -1037,9 +1321,11 @@ const SubscriptionsPage = () => {
1037
1321
  "End Date: ",
1038
1322
  subscription.endDate
1039
1323
  ] }),
1324
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral600", style: { marginTop: "1rem" }, children: subscription.stripeSubscriptionId ? "✅ Synced with Stripe" : "⚠️ Not synced with Stripe" }),
1040
1325
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { style: { marginTop: "1rem", gap: "1rem" }, children: [
1041
1326
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "secondary", onClick: () => handleEdit(subscription), children: "Edit" }),
1042
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "danger", onClick: () => handleDelete(subscription.id), children: "Delete" })
1327
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "danger", onClick: () => handleDelete(subscription.id), children: "Delete" }),
1328
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: () => handleSync(subscription.id), children: subscription.stripeSubscriptionId ? "Sync" : "Create in Stripe" })
1043
1329
  ] })
1044
1330
  ]
1045
1331
  },
@@ -1064,18 +1350,7 @@ const NavigationMenu = () => {
1064
1350
  /* @__PURE__ */ jsxRuntime.jsx("li", { style: { marginBottom: "1rem" }, children: /* @__PURE__ */ jsxRuntime.jsx(
1065
1351
  reactRouterDom.NavLink,
1066
1352
  {
1067
- to: "/plugins/payment-plugin/",
1068
- style: ({ isActive }) => ({
1069
- color: isActive ? "#7b79ff" : "inherit",
1070
- textDecoration: "none"
1071
- }),
1072
- children: "Home"
1073
- }
1074
- ) }),
1075
- /* @__PURE__ */ jsxRuntime.jsx("li", { style: { marginBottom: "1rem" }, children: /* @__PURE__ */ jsxRuntime.jsx(
1076
- reactRouterDom.NavLink,
1077
- {
1078
- to: "/plugins/payment-plugin/dashboard",
1353
+ to: "/plugins/strapi-payment-plugin/dashboard",
1079
1354
  style: ({ isActive }) => ({
1080
1355
  color: isActive ? "#7b79ff" : "inherit",
1081
1356
  textDecoration: "none"
@@ -1086,7 +1361,7 @@ const NavigationMenu = () => {
1086
1361
  /* @__PURE__ */ jsxRuntime.jsx("li", { style: { marginBottom: "1rem" }, children: /* @__PURE__ */ jsxRuntime.jsx(
1087
1362
  reactRouterDom.NavLink,
1088
1363
  {
1089
- to: "/plugins/payment-plugin/transactions",
1364
+ to: "/plugins/strapi-payment-plugin/transactions",
1090
1365
  style: ({ isActive }) => ({
1091
1366
  color: isActive ? "#7b79ff" : "inherit",
1092
1367
  textDecoration: "none"
@@ -1097,7 +1372,7 @@ const NavigationMenu = () => {
1097
1372
  /* @__PURE__ */ jsxRuntime.jsx("li", { style: { marginBottom: "1rem" }, children: /* @__PURE__ */ jsxRuntime.jsx(
1098
1373
  reactRouterDom.NavLink,
1099
1374
  {
1100
- to: "/plugins/payment-plugin/products",
1375
+ to: "/plugins/strapi-payment-plugin/products",
1101
1376
  style: ({ isActive }) => ({
1102
1377
  color: isActive ? "#7b79ff" : "inherit",
1103
1378
  textDecoration: "none"
@@ -1108,7 +1383,7 @@ const NavigationMenu = () => {
1108
1383
  /* @__PURE__ */ jsxRuntime.jsx("li", { style: { marginBottom: "1rem" }, children: /* @__PURE__ */ jsxRuntime.jsx(
1109
1384
  reactRouterDom.NavLink,
1110
1385
  {
1111
- to: "/plugins/payment-plugin/subscriptions",
1386
+ to: "/plugins/strapi-payment-plugin/subscriptions",
1112
1387
  style: ({ isActive }) => ({
1113
1388
  color: isActive ? "#7b79ff" : "inherit",
1114
1389
  textDecoration: "none"
@@ -1119,7 +1394,7 @@ const NavigationMenu = () => {
1119
1394
  /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsx(
1120
1395
  reactRouterDom.NavLink,
1121
1396
  {
1122
- to: "/plugins/payment-plugin/configuration",
1397
+ to: "/plugins/strapi-payment-plugin/configuration",
1123
1398
  style: ({ isActive }) => ({
1124
1399
  color: isActive ? "#7b79ff" : "inherit",
1125
1400
  textDecoration: "none"
@@ -1136,7 +1411,7 @@ const App = () => {
1136
1411
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex" }, children: [
1137
1412
  /* @__PURE__ */ jsxRuntime.jsx(NavigationMenu, {}),
1138
1413
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: { marginLeft: "200px", flex: 1 }, children: /* @__PURE__ */ jsxRuntime.jsxs(reactRouterDom.Routes, { children: [
1139
- /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Route, { index: true, element: /* @__PURE__ */ jsxRuntime.jsx(HomePage, {}) }),
1414
+ /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Route, { index: true, element: /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Navigate, { to: "dashboard" }) }),
1140
1415
  /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Route, { path: "/dashboard", element: /* @__PURE__ */ jsxRuntime.jsx(DashboardPage, {}) }),
1141
1416
  /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Route, { path: "/transactions", element: /* @__PURE__ */ jsxRuntime.jsx(TransactionsPage, {}) }),
1142
1417
  /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Route, { path: "/products", element: /* @__PURE__ */ jsxRuntime.jsx(ProductsPage, {}) }),