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