@reeboot/strapi-payment-plugin 0.0.6 → 0.0.7
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.
- package/README.md +21 -0
- package/dist/_chunks/{Analytics-CQmAVKsq.mjs → Analytics-CncK5kn-.mjs} +6 -7
- package/dist/_chunks/{Analytics-CLjtRWYA.js → Analytics-c8KBuG3k.js} +6 -7
- package/dist/_chunks/{App-DXN62SV6.mjs → App-B5AB8Omu.mjs} +7 -7
- package/dist/_chunks/{App-Dk7XtjNA.js → App-Cih9sWu1.js} +7 -7
- package/dist/_chunks/{Customers-BQzVBQDT.mjs → Customers-BVk2gx7w.mjs} +51 -118
- package/dist/_chunks/{Customers-BNDi4QBH.js → Customers-CZWOnN26.js} +50 -117
- package/dist/_chunks/{Dashboard-UUwohHZa.js → Dashboard-CEif4jQn.js} +60 -84
- package/dist/_chunks/{Dashboard-CuHC-dit.mjs → Dashboard-DAjD8Q_6.mjs} +60 -84
- package/dist/_chunks/{Orders-CitNCdWE.js → Orders-DZXb54VO.js} +73 -146
- package/dist/_chunks/{Orders-65mNfu2i.mjs → Orders-DdJqI1HB.mjs} +74 -147
- package/dist/_chunks/{PaymentList-B0CAzInT.mjs → PaymentList-3HWK7PMz.mjs} +14 -39
- package/dist/_chunks/{PaymentList-Dy1BAFoD.js → PaymentList-APfyYD1h.js} +14 -39
- package/dist/_chunks/{Payments-FnhoV_2B.mjs → Payments-DFL-Cwgy.mjs} +97 -103
- package/dist/_chunks/{Payments-TOnygGIW.js → Payments-VzDGbK4W.js} +96 -102
- package/dist/_chunks/{Settings-BJtDagUs.js → Settings-B1tR3WOm.js} +157 -161
- package/dist/_chunks/{Settings-EoLSuZLe.mjs → Settings-SALxClBu.mjs} +157 -161
- package/dist/_chunks/{index-2Zd_T7bD.mjs → index-CB6TMitx.mjs} +1 -1
- package/dist/_chunks/{index-CHEgJ7e5.js → index-D-fFikb8.js} +1 -1
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/server/index.js +7 -34
- package/dist/server/index.mjs +7 -34
- package/package.json +1 -1
- /package/dist/server/src/{types → services/types}/api.d.ts +0 -0
- /package/dist/server/src/{types → services/types}/customer.d.ts +0 -0
- /package/dist/server/src/{types → services/types}/index.d.ts +0 -0
- /package/dist/server/src/{types → services/types}/order.d.ts +0 -0
- /package/dist/server/src/{types → services/types}/payment.d.ts +0 -0
|
@@ -4,7 +4,7 @@ import { Modal, Typography, Box, Tabs, Flex, Button, Alert, Grid, Card, Badge, T
|
|
|
4
4
|
import { useIntl } from "react-intl";
|
|
5
5
|
import { useFetchClient } from "@strapi/strapi/admin";
|
|
6
6
|
import { Duplicate, Code, Key, EyeStriked, Eye, Globe } from "@strapi/icons";
|
|
7
|
-
import { P as PLUGIN_ID } from "./index-
|
|
7
|
+
import { P as PLUGIN_ID } from "./index-CB6TMitx.mjs";
|
|
8
8
|
const IntegrationModal = ({ onClose, publishableKey }) => {
|
|
9
9
|
const [copied, setCopied] = useState(null);
|
|
10
10
|
const copyToClipboard = (text, type) => {
|
|
@@ -197,10 +197,13 @@ const Settings = () => {
|
|
|
197
197
|
const [saving, setSaving] = useState(false);
|
|
198
198
|
const [error, setError] = useState(null);
|
|
199
199
|
const [success, setSuccess] = useState(null);
|
|
200
|
+
const [testStatus, setTestStatus] = useState("idle");
|
|
201
|
+
const [testMessage, setTestMessage] = useState("");
|
|
200
202
|
const [hasChanges, setHasChanges] = useState(false);
|
|
201
203
|
const [showIntegrationModal, setShowIntegrationModal] = useState(false);
|
|
202
204
|
const [showSecretKey, setShowSecretKey] = useState(false);
|
|
203
205
|
const [showWebhookSecret, setShowWebhookSecret] = useState(false);
|
|
206
|
+
const [showResetConfirm, setShowResetConfirm] = useState(false);
|
|
204
207
|
useEffect(() => {
|
|
205
208
|
fetchSettings();
|
|
206
209
|
}, []);
|
|
@@ -209,51 +212,34 @@ const Settings = () => {
|
|
|
209
212
|
setLoading(true);
|
|
210
213
|
const { data } = await get(`/${PLUGIN_ID}/admin/config`);
|
|
211
214
|
if (data.success && data.data) {
|
|
212
|
-
const
|
|
213
|
-
|
|
215
|
+
const bc = data.data;
|
|
216
|
+
setSettings({
|
|
214
217
|
stripe: {
|
|
215
|
-
publishableKey:
|
|
216
|
-
secretKey:
|
|
217
|
-
webhookSecret:
|
|
218
|
-
apiVersion:
|
|
219
|
-
enabled:
|
|
218
|
+
publishableKey: bc.stripe?.publishableKey || "",
|
|
219
|
+
secretKey: bc.stripe?.secretKey || "",
|
|
220
|
+
webhookSecret: bc.stripe?.webhookSecret || "",
|
|
221
|
+
apiVersion: bc.stripe?.apiVersion || "2024-06-20",
|
|
222
|
+
enabled: bc.stripe?.enabled ?? true
|
|
220
223
|
},
|
|
221
224
|
payments: {
|
|
222
|
-
defaultCurrency:
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
captureMethod: backendConfig.payment?.captureMethod || "automatic",
|
|
228
|
-
confirmationMethod: backendConfig.payment?.confirmationMethod || "automatic"
|
|
229
|
-
},
|
|
230
|
-
webhooks: {
|
|
231
|
-
enabled: true,
|
|
232
|
-
endpoints: {
|
|
233
|
-
paymentSucceeded: "",
|
|
234
|
-
paymentFailed: "",
|
|
235
|
-
refundCreated: "",
|
|
236
|
-
invoiceCreated: ""
|
|
237
|
-
},
|
|
238
|
-
retries: 3,
|
|
239
|
-
timeout: 30
|
|
225
|
+
defaultCurrency: bc.payment?.defaultCurrency || "usd",
|
|
226
|
+
enableRefunds: bc.payment?.enableRefunds ?? true,
|
|
227
|
+
enablePartialRefunds: bc.payment?.enablePartialRefunds ?? true,
|
|
228
|
+
refundWindow: bc.payment?.refundWindow || 30,
|
|
229
|
+
captureMethod: bc.payment?.captureMethod || "automatic"
|
|
240
230
|
},
|
|
241
231
|
ui: {
|
|
242
232
|
showPaymentStatus: true,
|
|
243
233
|
showCustomerInfo: true,
|
|
244
234
|
enableNotifications: true,
|
|
245
|
-
theme: "auto",
|
|
246
235
|
compactView: false
|
|
247
236
|
},
|
|
248
237
|
security: {
|
|
249
|
-
enableIpFiltering: false,
|
|
250
|
-
allowedIps: [],
|
|
251
238
|
requireAuthentication: true,
|
|
252
239
|
enableAuditLog: true,
|
|
253
240
|
sessionTimeout: 60
|
|
254
241
|
}
|
|
255
|
-
};
|
|
256
|
-
setSettings(initialSettings);
|
|
242
|
+
});
|
|
257
243
|
}
|
|
258
244
|
setLoading(false);
|
|
259
245
|
} catch (err) {
|
|
@@ -265,10 +251,7 @@ const Settings = () => {
|
|
|
265
251
|
if (!settings) return;
|
|
266
252
|
setSettings((prev) => ({
|
|
267
253
|
...prev,
|
|
268
|
-
[section]: {
|
|
269
|
-
...prev[section],
|
|
270
|
-
[key]: value
|
|
271
|
-
}
|
|
254
|
+
[section]: { ...prev[section], [key]: value }
|
|
272
255
|
}));
|
|
273
256
|
setHasChanges(true);
|
|
274
257
|
setSuccess(null);
|
|
@@ -278,14 +261,11 @@ const Settings = () => {
|
|
|
278
261
|
setSaving(true);
|
|
279
262
|
setError(null);
|
|
280
263
|
if (!settings) return;
|
|
281
|
-
|
|
264
|
+
await put(`/${PLUGIN_ID}/admin/config`, {
|
|
282
265
|
stripe: settings.stripe,
|
|
283
266
|
payment: settings.payments,
|
|
284
|
-
logging: {
|
|
285
|
-
|
|
286
|
-
}
|
|
287
|
-
};
|
|
288
|
-
await put(`/${PLUGIN_ID}/admin/config`, payload);
|
|
267
|
+
logging: { enableWebhookLogging: true }
|
|
268
|
+
});
|
|
289
269
|
setHasChanges(false);
|
|
290
270
|
setSuccess("Settings saved successfully");
|
|
291
271
|
setTimeout(() => setSuccess(null), 3e3);
|
|
@@ -295,32 +275,41 @@ const Settings = () => {
|
|
|
295
275
|
setSaving(false);
|
|
296
276
|
}
|
|
297
277
|
};
|
|
298
|
-
const resetSettings = () => {
|
|
299
|
-
if (confirm("Are you sure you want to reset all settings to default? This action cannot be undone.")) {
|
|
300
|
-
fetchSettings();
|
|
301
|
-
setHasChanges(false);
|
|
302
|
-
}
|
|
303
|
-
};
|
|
304
278
|
const testConnection = async () => {
|
|
305
279
|
try {
|
|
306
280
|
setSaving(true);
|
|
281
|
+
setTestStatus("idle");
|
|
307
282
|
const { data } = await get(`/${PLUGIN_ID}/admin/config`);
|
|
308
283
|
if (data.success) {
|
|
309
|
-
|
|
284
|
+
setTestStatus("success");
|
|
285
|
+
setTestMessage("Connection to backend successful!");
|
|
310
286
|
} else {
|
|
311
287
|
throw new Error("Failed to connect");
|
|
312
288
|
}
|
|
313
289
|
} catch (err) {
|
|
314
|
-
|
|
290
|
+
setTestStatus("error");
|
|
291
|
+
setTestMessage("Connection test failed. Check your API keys and server logs.");
|
|
315
292
|
} finally {
|
|
316
293
|
setSaving(false);
|
|
294
|
+
setTimeout(() => setTestStatus("idle"), 4e3);
|
|
317
295
|
}
|
|
318
296
|
};
|
|
297
|
+
const copyToClipboard = (text) => {
|
|
298
|
+
navigator.clipboard.writeText(text);
|
|
299
|
+
};
|
|
319
300
|
if (loading) {
|
|
320
301
|
return /* @__PURE__ */ jsx(Box, { padding: 4, children: /* @__PURE__ */ jsx(Flex, { justifyContent: "center", alignItems: "center", style: { minHeight: "400px" }, children: /* @__PURE__ */ jsx(Typography, { variant: "beta", children: formatMessage({ id: "payment-plugin.settings.loading", defaultMessage: "Loading settings..." }) }) }) });
|
|
321
302
|
}
|
|
322
303
|
if (!settings) {
|
|
323
|
-
return /* @__PURE__ */ jsx(Box, { padding: 4, children: /* @__PURE__ */ jsx(
|
|
304
|
+
return /* @__PURE__ */ jsx(Box, { padding: 4, children: /* @__PURE__ */ jsx(
|
|
305
|
+
Alert,
|
|
306
|
+
{
|
|
307
|
+
variant: "danger",
|
|
308
|
+
closeLabel: formatMessage({ id: "payment-plugin.alert.close", defaultMessage: "Close alert" }),
|
|
309
|
+
onClose: () => setError(null),
|
|
310
|
+
children: formatMessage({ id: "payment-plugin.settings.error", defaultMessage: "Failed to load settings" })
|
|
311
|
+
}
|
|
312
|
+
) });
|
|
324
313
|
}
|
|
325
314
|
return /* @__PURE__ */ jsxs(Box, { children: [
|
|
326
315
|
/* @__PURE__ */ jsx(Box, { marginBottom: 4, children: /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "center", children: [
|
|
@@ -331,45 +320,46 @@ const Settings = () => {
|
|
|
331
320
|
defaultMessage: "Configure your payment plugin settings"
|
|
332
321
|
}) })
|
|
333
322
|
] }),
|
|
334
|
-
/* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
|
335
|
-
hasChanges && /* @__PURE__ */ jsx(
|
|
336
|
-
/* @__PURE__ */ jsx(Button, { variant: "secondary", onClick:
|
|
337
|
-
/* @__PURE__ */ jsx(
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
variant: "secondary",
|
|
341
|
-
onClick: testConnection,
|
|
342
|
-
disabled: saving,
|
|
343
|
-
children: formatMessage({ id: "payment-plugin.settings.testConnection", defaultMessage: "Test Connection" })
|
|
344
|
-
}
|
|
345
|
-
),
|
|
346
|
-
/* @__PURE__ */ jsx(
|
|
347
|
-
Button,
|
|
348
|
-
{
|
|
349
|
-
onClick: saveSettings,
|
|
350
|
-
disabled: !hasChanges || saving,
|
|
351
|
-
loading: saving,
|
|
352
|
-
children: formatMessage({ id: "payment-plugin.settings.save", defaultMessage: "Save Settings" })
|
|
353
|
-
}
|
|
354
|
-
),
|
|
355
|
-
/* @__PURE__ */ jsx(
|
|
356
|
-
Button,
|
|
357
|
-
{
|
|
358
|
-
variant: "tertiary",
|
|
359
|
-
startIcon: /* @__PURE__ */ jsx(Code, {}),
|
|
360
|
-
onClick: () => setShowIntegrationModal(true),
|
|
361
|
-
children: formatMessage({ id: "payment-plugin.settings.integration", defaultMessage: "Integration Guide" })
|
|
362
|
-
}
|
|
363
|
-
)
|
|
323
|
+
/* @__PURE__ */ jsxs(Flex, { gap: 2, alignItems: "center", children: [
|
|
324
|
+
hasChanges && /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "warning600", children: "Unsaved changes" }),
|
|
325
|
+
/* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: () => setShowResetConfirm(true), children: formatMessage({ id: "payment-plugin.settings.reset", defaultMessage: "Reset" }) }),
|
|
326
|
+
/* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: testConnection, disabled: saving, children: formatMessage({ id: "payment-plugin.settings.testConnection", defaultMessage: "Test Connection" }) }),
|
|
327
|
+
/* @__PURE__ */ jsx(Button, { onClick: saveSettings, disabled: !hasChanges || saving, loading: saving, children: formatMessage({ id: "payment-plugin.settings.save", defaultMessage: "Save Settings" }) }),
|
|
328
|
+
/* @__PURE__ */ jsx(Button, { variant: "tertiary", startIcon: /* @__PURE__ */ jsx(Code, {}), onClick: () => setShowIntegrationModal(true), children: formatMessage({ id: "payment-plugin.settings.integration", defaultMessage: "Integration Guide" }) })
|
|
364
329
|
] })
|
|
365
330
|
] }) }),
|
|
366
|
-
error && /* @__PURE__ */ jsx(Box, { marginBottom: 4, children: /* @__PURE__ */ jsx(
|
|
367
|
-
|
|
331
|
+
error && /* @__PURE__ */ jsx(Box, { marginBottom: 4, children: /* @__PURE__ */ jsx(
|
|
332
|
+
Alert,
|
|
333
|
+
{
|
|
334
|
+
variant: "danger",
|
|
335
|
+
closeLabel: formatMessage({ id: "payment-plugin.alert.close", defaultMessage: "Close alert" }),
|
|
336
|
+
onClose: () => setError(null),
|
|
337
|
+
children: error
|
|
338
|
+
}
|
|
339
|
+
) }),
|
|
340
|
+
success && /* @__PURE__ */ jsx(Box, { marginBottom: 4, children: /* @__PURE__ */ jsx(
|
|
341
|
+
Alert,
|
|
342
|
+
{
|
|
343
|
+
variant: "success",
|
|
344
|
+
closeLabel: formatMessage({ id: "payment-plugin.alert.close", defaultMessage: "Close alert" }),
|
|
345
|
+
onClose: () => setSuccess(null),
|
|
346
|
+
children: success
|
|
347
|
+
}
|
|
348
|
+
) }),
|
|
349
|
+
testStatus !== "idle" && /* @__PURE__ */ jsx(Box, { marginBottom: 4, children: /* @__PURE__ */ jsx(
|
|
350
|
+
Alert,
|
|
351
|
+
{
|
|
352
|
+
variant: testStatus === "success" ? "success" : "danger",
|
|
353
|
+
closeLabel: formatMessage({ id: "payment-plugin.alert.close", defaultMessage: "Close alert" }),
|
|
354
|
+
onClose: () => setTestStatus("idle"),
|
|
355
|
+
children: testMessage
|
|
356
|
+
}
|
|
357
|
+
) }),
|
|
368
358
|
/* @__PURE__ */ jsxs(Grid.Root, { gap: 6, children: [
|
|
369
359
|
/* @__PURE__ */ jsx(Grid.Item, { col: 12, children: /* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsxs(Box, { padding: 5, children: [
|
|
370
360
|
/* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "center", marginBottom: 4, children: [
|
|
371
361
|
/* @__PURE__ */ jsxs(Flex, { gap: 2, alignItems: "center", children: [
|
|
372
|
-
/* @__PURE__ */ jsx(
|
|
362
|
+
/* @__PURE__ */ jsx(Key, { width: "1.5rem", height: "1.5rem" }),
|
|
373
363
|
/* @__PURE__ */ jsx(Typography, { variant: "beta", tag: "h2", children: formatMessage({ id: "payment-plugin.settings.stripe", defaultMessage: "Stripe API Configuration" }) })
|
|
374
364
|
] }),
|
|
375
365
|
/* @__PURE__ */ jsx(Badge, { variant: settings.stripe.enabled ? "success" : "neutral", children: settings.stripe.enabled ? "Stripe Active" : "Stripe Disabled" })
|
|
@@ -386,10 +376,8 @@ const Settings = () => {
|
|
|
386
376
|
Button,
|
|
387
377
|
{
|
|
388
378
|
variant: "ghost",
|
|
389
|
-
onClick: () =>
|
|
390
|
-
|
|
391
|
-
alert("Copied to clipboard");
|
|
392
|
-
},
|
|
379
|
+
onClick: () => copyToClipboard(settings.stripe.publishableKey),
|
|
380
|
+
"aria-label": "Copy publishable key",
|
|
393
381
|
children: /* @__PURE__ */ jsx(Duplicate, { width: "1rem", height: "1rem" })
|
|
394
382
|
}
|
|
395
383
|
)
|
|
@@ -409,6 +397,7 @@ const Settings = () => {
|
|
|
409
397
|
{
|
|
410
398
|
variant: "ghost",
|
|
411
399
|
onClick: () => setShowSecretKey(!showSecretKey),
|
|
400
|
+
"aria-label": showSecretKey ? "Hide secret key" : "Show secret key",
|
|
412
401
|
children: showSecretKey ? /* @__PURE__ */ jsx(EyeStriked, { width: "1rem", height: "1rem" }) : /* @__PURE__ */ jsx(Eye, { width: "1rem", height: "1rem" })
|
|
413
402
|
}
|
|
414
403
|
),
|
|
@@ -416,10 +405,8 @@ const Settings = () => {
|
|
|
416
405
|
Button,
|
|
417
406
|
{
|
|
418
407
|
variant: "ghost",
|
|
419
|
-
onClick: () =>
|
|
420
|
-
|
|
421
|
-
alert("Copied to clipboard");
|
|
422
|
-
},
|
|
408
|
+
onClick: () => copyToClipboard(settings.stripe.secretKey),
|
|
409
|
+
"aria-label": "Copy secret key",
|
|
423
410
|
children: /* @__PURE__ */ jsx(Duplicate, { width: "1rem", height: "1rem" })
|
|
424
411
|
}
|
|
425
412
|
)
|
|
@@ -440,6 +427,7 @@ const Settings = () => {
|
|
|
440
427
|
{
|
|
441
428
|
variant: "ghost",
|
|
442
429
|
onClick: () => setShowWebhookSecret(!showWebhookSecret),
|
|
430
|
+
"aria-label": showWebhookSecret ? "Hide webhook secret" : "Show webhook secret",
|
|
443
431
|
children: showWebhookSecret ? /* @__PURE__ */ jsx(EyeStriked, { width: "1rem", height: "1rem" }) : /* @__PURE__ */ jsx(Eye, { width: "1rem", height: "1rem" })
|
|
444
432
|
}
|
|
445
433
|
),
|
|
@@ -447,10 +435,8 @@ const Settings = () => {
|
|
|
447
435
|
Button,
|
|
448
436
|
{
|
|
449
437
|
variant: "ghost",
|
|
450
|
-
onClick: () =>
|
|
451
|
-
|
|
452
|
-
alert("Copied to clipboard");
|
|
453
|
-
},
|
|
438
|
+
onClick: () => copyToClipboard(settings.stripe.webhookSecret),
|
|
439
|
+
"aria-label": "Copy webhook secret",
|
|
454
440
|
children: /* @__PURE__ */ jsx(Duplicate, { width: "1rem", height: "1rem" })
|
|
455
441
|
}
|
|
456
442
|
)
|
|
@@ -474,13 +460,13 @@ const Settings = () => {
|
|
|
474
460
|
/* @__PURE__ */ jsx(
|
|
475
461
|
Switch,
|
|
476
462
|
{
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
463
|
+
checked: settings.stripe.enabled,
|
|
464
|
+
onCheckedChange: (checked) => handleSettingChange("stripe", "enabled", checked),
|
|
465
|
+
"aria-label": formatMessage({ id: "payment-plugin.settings.enabled", defaultMessage: "Enable Stripe Payments" })
|
|
480
466
|
}
|
|
481
467
|
),
|
|
482
468
|
/* @__PURE__ */ jsxs(Box, { children: [
|
|
483
|
-
/* @__PURE__ */ jsx(Typography, { fontWeight: "bold", children: formatMessage({ id: "payment-plugin.settings.
|
|
469
|
+
/* @__PURE__ */ jsx(Typography, { fontWeight: "bold", children: formatMessage({ id: "payment-plugin.settings.gatewayStatus", defaultMessage: "Payment Gateway Status" }) }),
|
|
484
470
|
/* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: settings.stripe.enabled ? "Your plugin is currently accepting payments through Stripe." : "Stripe payments are disabled. Customers will not be able to checkout." })
|
|
485
471
|
] })
|
|
486
472
|
] }) }) })
|
|
@@ -537,9 +523,9 @@ const Settings = () => {
|
|
|
537
523
|
/* @__PURE__ */ jsx(
|
|
538
524
|
Switch,
|
|
539
525
|
{
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
526
|
+
checked: settings.security.requireAuthentication,
|
|
527
|
+
onCheckedChange: (checked) => handleSettingChange("security", "requireAuthentication", checked),
|
|
528
|
+
"aria-label": formatMessage({ id: "payment-plugin.settings.requireAuth", defaultMessage: "Require Authentication" })
|
|
543
529
|
}
|
|
544
530
|
),
|
|
545
531
|
/* @__PURE__ */ jsxs(Box, { children: [
|
|
@@ -551,9 +537,9 @@ const Settings = () => {
|
|
|
551
537
|
/* @__PURE__ */ jsx(
|
|
552
538
|
Switch,
|
|
553
539
|
{
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
540
|
+
checked: settings.security.enableAuditLog,
|
|
541
|
+
onCheckedChange: (checked) => handleSettingChange("security", "enableAuditLog", checked),
|
|
542
|
+
"aria-label": formatMessage({ id: "payment-plugin.settings.auditLog", defaultMessage: "Enable Audit Log" })
|
|
557
543
|
}
|
|
558
544
|
),
|
|
559
545
|
/* @__PURE__ */ jsxs(Box, { children: [
|
|
@@ -561,10 +547,13 @@ const Settings = () => {
|
|
|
561
547
|
/* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: "Detailed logs of all transaction attempts and configuration changes." })
|
|
562
548
|
] })
|
|
563
549
|
] }) }),
|
|
564
|
-
/* @__PURE__ */ jsx(Grid.Item, { col: 12,
|
|
550
|
+
/* @__PURE__ */ jsx(Grid.Item, { col: 12, children: /* @__PURE__ */ jsx(
|
|
565
551
|
TextInput,
|
|
566
552
|
{
|
|
567
|
-
label: formatMessage({
|
|
553
|
+
label: formatMessage({
|
|
554
|
+
id: "payment-plugin.settings.sessionTimeout",
|
|
555
|
+
defaultMessage: "Checkout Session Timeout (Minutes)"
|
|
556
|
+
}),
|
|
568
557
|
type: "number",
|
|
569
558
|
value: settings.security.sessionTimeout.toString(),
|
|
570
559
|
onChange: (e) => handleSettingChange("security", "sessionTimeout", parseInt(e.target.value) || 60)
|
|
@@ -574,62 +563,69 @@ const Settings = () => {
|
|
|
574
563
|
] }) }) }),
|
|
575
564
|
/* @__PURE__ */ jsx(Grid.Item, { col: 12, children: /* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsxs(Box, { padding: 5, children: [
|
|
576
565
|
/* @__PURE__ */ jsx(Typography, { variant: "beta", tag: "h2", marginBottom: 4, children: formatMessage({ id: "payment-plugin.settings.ui", defaultMessage: "Admin Interface Customization" }) }),
|
|
577
|
-
/* @__PURE__ */
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
] }) }),
|
|
617
|
-
/* @__PURE__ */ jsx(Grid.Item, { col: 3, children: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, children: [
|
|
618
|
-
/* @__PURE__ */ jsxs(Flex, { alignItems: "center", gap: 2, children: [
|
|
619
|
-
/* @__PURE__ */ jsx(
|
|
620
|
-
Switch,
|
|
621
|
-
{
|
|
622
|
-
checked: settings.ui.compactView,
|
|
623
|
-
onChange: (checked) => handleSettingChange("ui", "compactView", checked)
|
|
624
|
-
}
|
|
625
|
-
),
|
|
626
|
-
/* @__PURE__ */ jsx(Typography, { fontWeight: "bold", children: formatMessage({ id: "payment-plugin.settings.compactView", defaultMessage: "Compact Mode" }) })
|
|
627
|
-
] }),
|
|
628
|
-
/* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: "Dense layout for tables" })
|
|
629
|
-
] }) })
|
|
630
|
-
] })
|
|
566
|
+
/* @__PURE__ */ jsx(Grid.Root, { gap: 4, children: [
|
|
567
|
+
{
|
|
568
|
+
key: "showPaymentStatus",
|
|
569
|
+
label: formatMessage({ id: "payment-plugin.settings.showStatus", defaultMessage: "Payment Status" }),
|
|
570
|
+
hint: "Show status badges in lists",
|
|
571
|
+
value: settings.ui.showPaymentStatus
|
|
572
|
+
},
|
|
573
|
+
{
|
|
574
|
+
key: "showCustomerInfo",
|
|
575
|
+
label: formatMessage({ id: "payment-plugin.settings.showCustomerInfo", defaultMessage: "Customer Data" }),
|
|
576
|
+
hint: "Display sensitive customer info",
|
|
577
|
+
value: settings.ui.showCustomerInfo
|
|
578
|
+
},
|
|
579
|
+
{
|
|
580
|
+
key: "enableNotifications",
|
|
581
|
+
label: formatMessage({ id: "payment-plugin.settings.notifications", defaultMessage: "Notifications" }),
|
|
582
|
+
hint: "Browser alerts for success",
|
|
583
|
+
value: settings.ui.enableNotifications
|
|
584
|
+
},
|
|
585
|
+
{
|
|
586
|
+
key: "compactView",
|
|
587
|
+
label: formatMessage({ id: "payment-plugin.settings.compactView", defaultMessage: "Compact Mode" }),
|
|
588
|
+
hint: "Dense layout for tables",
|
|
589
|
+
value: settings.ui.compactView
|
|
590
|
+
}
|
|
591
|
+
].map(({ key, label, hint, value }) => /* @__PURE__ */ jsx(Grid.Item, { col: 3, children: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, children: [
|
|
592
|
+
/* @__PURE__ */ jsxs(Flex, { alignItems: "center", gap: 2, children: [
|
|
593
|
+
/* @__PURE__ */ jsx(
|
|
594
|
+
Switch,
|
|
595
|
+
{
|
|
596
|
+
checked: value,
|
|
597
|
+
onCheckedChange: (checked) => handleSettingChange("ui", key, checked),
|
|
598
|
+
"aria-label": label
|
|
599
|
+
}
|
|
600
|
+
),
|
|
601
|
+
/* @__PURE__ */ jsx(Typography, { fontWeight: "bold", children: label })
|
|
602
|
+
] }),
|
|
603
|
+
/* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: hint })
|
|
604
|
+
] }) }, key)) })
|
|
631
605
|
] }) }) })
|
|
632
606
|
] }),
|
|
607
|
+
showResetConfirm && /* @__PURE__ */ jsx(Modal.Root, { open: true, onOpenChange: () => setShowResetConfirm(false), children: /* @__PURE__ */ jsxs(Modal.Content, { children: [
|
|
608
|
+
/* @__PURE__ */ jsx(Modal.Header, { children: /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", as: "h2", children: formatMessage({ id: "payment-plugin.settings.resetConfirm.title", defaultMessage: "Reset Settings?" }) }) }),
|
|
609
|
+
/* @__PURE__ */ jsx(Modal.Body, { children: /* @__PURE__ */ jsx(Typography, { children: formatMessage({
|
|
610
|
+
id: "payment-plugin.settings.resetConfirm.body",
|
|
611
|
+
defaultMessage: "This will reload settings from the server and discard all unsaved changes."
|
|
612
|
+
}) }) }),
|
|
613
|
+
/* @__PURE__ */ jsxs(Modal.Footer, { children: [
|
|
614
|
+
/* @__PURE__ */ jsx(Button, { variant: "tertiary", onClick: () => setShowResetConfirm(false), children: formatMessage({ id: "payment-plugin.settings.cancel", defaultMessage: "Cancel" }) }),
|
|
615
|
+
/* @__PURE__ */ jsx(
|
|
616
|
+
Button,
|
|
617
|
+
{
|
|
618
|
+
variant: "danger-light",
|
|
619
|
+
onClick: () => {
|
|
620
|
+
setShowResetConfirm(false);
|
|
621
|
+
fetchSettings();
|
|
622
|
+
setHasChanges(false);
|
|
623
|
+
},
|
|
624
|
+
children: formatMessage({ id: "payment-plugin.settings.resetConfirm", defaultMessage: "Reset" })
|
|
625
|
+
}
|
|
626
|
+
)
|
|
627
|
+
] })
|
|
628
|
+
] }) }),
|
|
633
629
|
showIntegrationModal && /* @__PURE__ */ jsx(
|
|
634
630
|
IntegrationModal,
|
|
635
631
|
{
|
|
@@ -37,7 +37,7 @@ const index = {
|
|
|
37
37
|
defaultMessage: "Payment Management"
|
|
38
38
|
},
|
|
39
39
|
Component: async () => {
|
|
40
|
-
const { App } = await Promise.resolve().then(() => require("./App-
|
|
40
|
+
const { App } = await Promise.resolve().then(() => require("./App-Cih9sWu1.js"));
|
|
41
41
|
return App;
|
|
42
42
|
}
|
|
43
43
|
});
|
package/dist/admin/index.js
CHANGED
package/dist/admin/index.mjs
CHANGED
package/dist/server/index.js
CHANGED
|
@@ -411,36 +411,20 @@ const stripeController = {
|
|
|
411
411
|
const body = ctx.request.body;
|
|
412
412
|
const unparsedBody = body?.[Symbol.for("unparsedBody")] || body?.[Symbol.for("koa-body-unparsed-body")] || ctx.request.rawBody || ctx.rawBody;
|
|
413
413
|
const rawBody = unparsedBody || ctx.request.body;
|
|
414
|
-
const debugInfo = {
|
|
415
|
-
hasUnparsedBody: !!unparsedBody,
|
|
416
|
-
unparsedBodyType: typeof unparsedBody,
|
|
417
|
-
isBodyBuffer: Buffer.isBuffer(ctx.request.body),
|
|
418
|
-
keys: body ? Object.keys(body) : [],
|
|
419
|
-
symbols: body ? Object.getOwnPropertySymbols(body).map((s) => s.toString()) : []
|
|
420
|
-
};
|
|
421
|
-
strapi.log.info("Webhook Debug:", debugInfo);
|
|
422
414
|
if (!signature) {
|
|
423
415
|
return ctx.badRequest("Missing Stripe signature");
|
|
424
416
|
}
|
|
425
|
-
if (signature === "t=123,v1=abc") {
|
|
426
|
-
ctx.body = { debug: debugInfo };
|
|
427
|
-
return;
|
|
428
|
-
}
|
|
429
417
|
const stripeService2 = strapi.plugin("payment-plugin").service("stripe");
|
|
430
418
|
const event = await stripeService2.constructEvent(rawBody, signature);
|
|
431
419
|
await stripeService2.handleWebhook(event);
|
|
432
420
|
ctx.body = { received: true };
|
|
433
421
|
} catch (error) {
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
bodyKeys: keys,
|
|
441
|
-
bodySymbols: symbols
|
|
442
|
-
});
|
|
443
|
-
ctx.badRequest(`Webhook Error: ${error.message} | Keys: ${keys.join(",")} | Symbols: ${symbols.join(",")}`);
|
|
422
|
+
if (error.message.includes("No signatures found matching") || error.message.includes("Webhook payload must be provided as a string or a Buffer")) {
|
|
423
|
+
strapi.log.error('Stripe Webhook Error: Payload is not raw. Ensure "includeUnparsed: true" is set in config/middlewares.ts for "strapi::body".');
|
|
424
|
+
return ctx.badRequest("Webhook verification failed: Payload must be raw. Check your Strapi configuration for strapi::body middleware.");
|
|
425
|
+
}
|
|
426
|
+
strapi.log.error("Failed to handle webhook", { error: error.message, stack: error.stack });
|
|
427
|
+
ctx.badRequest(`Webhook Error: ${error.message}`);
|
|
444
428
|
}
|
|
445
429
|
},
|
|
446
430
|
/**
|
|
@@ -1787,30 +1771,19 @@ const stripeService = ({ strapi: strapi2 }) => {
|
|
|
1787
1771
|
const stripeConfig = config2.stripe || {};
|
|
1788
1772
|
const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET || stripeConfig.webhookSecret || (process.env.STRIPE_SECRET_KEY?.startsWith("whsec_") ? process.env.STRIPE_SECRET_KEY : null);
|
|
1789
1773
|
const logger = getLogger();
|
|
1790
|
-
logger.info("Attempting to construct webhook event", {
|
|
1791
|
-
hasPayload: !!payload,
|
|
1792
|
-
payloadType: typeof payload,
|
|
1793
|
-
isBuffer: Buffer.isBuffer(payload),
|
|
1794
|
-
hasSignature: !!signature,
|
|
1795
|
-
hasSecret: !!webhookSecret,
|
|
1796
|
-
secretPrefix: webhookSecret ? webhookSecret.substring(0, 6) : "none"
|
|
1797
|
-
});
|
|
1798
1774
|
if (!webhookSecret) {
|
|
1799
1775
|
throw new Error("Stripe webhook secret not configured. Please set STRIPE_WEBHOOK_SECRET environment variable.");
|
|
1800
1776
|
}
|
|
1801
1777
|
try {
|
|
1802
1778
|
let verifiedPayload = payload;
|
|
1803
1779
|
if (typeof payload === "object" && !Buffer.isBuffer(payload)) {
|
|
1804
|
-
logger.warn("Webhook payload is an object, verification will likely fail. Expected raw body.");
|
|
1805
1780
|
verifiedPayload = JSON.stringify(payload);
|
|
1806
1781
|
}
|
|
1807
1782
|
return stripe2.webhooks.constructEvent(verifiedPayload, signature, webhookSecret);
|
|
1808
1783
|
} catch (error) {
|
|
1809
1784
|
logger.error("Failed to construct webhook event", {
|
|
1810
1785
|
message: error.message,
|
|
1811
|
-
type: error.type
|
|
1812
|
-
// Don't log full stack to keep logs cleaner but enough info for debugging
|
|
1813
|
-
shortStack: error.stack?.split("\n").slice(0, 3).join("\n")
|
|
1786
|
+
type: error.type
|
|
1814
1787
|
});
|
|
1815
1788
|
throw error;
|
|
1816
1789
|
}
|