@reeboot/strapi-payment-plugin 0.0.3 → 0.0.5
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/dist/_chunks/{Analytics-nBSdLT2v.js → Analytics-CLjtRWYA.js} +68 -51
- package/dist/_chunks/{Analytics-DSJqY9ng.mjs → Analytics-CQmAVKsq.mjs} +68 -51
- package/dist/_chunks/App-DXN62SV6.mjs +118 -0
- package/dist/_chunks/App-Dk7XtjNA.js +120 -0
- package/dist/_chunks/{Customers-BpFzfglV.js → Customers-BNDi4QBH.js} +113 -51
- package/dist/_chunks/{Customers-C6FH7-zG.mjs → Customers-BQzVBQDT.mjs} +114 -52
- package/dist/_chunks/Dashboard-CuHC-dit.mjs +311 -0
- package/dist/_chunks/Dashboard-UUwohHZa.js +311 -0
- package/dist/_chunks/{Orders-CBkT2YfP.mjs → Orders-65mNfu2i.mjs} +140 -80
- package/dist/_chunks/{Orders-OG-pwV-B.js → Orders-CitNCdWE.js} +139 -79
- package/dist/_chunks/PaymentList-B0CAzInT.mjs +137 -0
- package/dist/_chunks/PaymentList-Dy1BAFoD.js +136 -0
- package/dist/_chunks/{Payments-DSDJ-HWm.mjs → Payments-FnhoV_2B.mjs} +175 -136
- package/dist/_chunks/{Payments-BLen1P9N.js → Payments-TOnygGIW.js} +173 -134
- package/dist/_chunks/Settings-BJtDagUs.js +644 -0
- package/dist/_chunks/Settings-EoLSuZLe.mjs +644 -0
- package/dist/_chunks/{index-DS_PYNkf.mjs → index-2Zd_T7bD.mjs} +1 -1
- package/dist/_chunks/{index-BqqrpI6D.js → index-CHEgJ7e5.js} +1 -1
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/admin/src/components/CustomerList.d.ts +1 -13
- package/dist/admin/src/components/IntegrationModal.d.ts +7 -0
- package/dist/admin/src/components/OrderList.d.ts +1 -19
- package/dist/admin/src/components/PaymentCard.d.ts +2 -33
- package/dist/admin/src/components/PaymentList.d.ts +3 -11
- package/dist/admin/src/components/RefundModal.d.ts +2 -8
- package/dist/admin/src/types/index.d.ts +47 -0
- package/dist/server/index.js +198 -92
- package/dist/server/index.mjs +198 -92
- package/dist/server/src/content-types/index.d.ts +9 -2
- package/dist/server/src/content-types/order/index.d.ts +8 -1
- package/dist/server/src/content-types/payment/index.d.ts +1 -1
- package/dist/server/src/index.d.ts +9 -2
- package/dist/server/src/types/api.d.ts +31 -0
- package/dist/server/src/types/customer.d.ts +2 -0
- package/dist/server/src/types/index.d.ts +4 -179
- package/dist/server/src/types/order.d.ts +2 -0
- package/dist/server/src/types/payment.d.ts +2 -0
- package/package.json +8 -7
- package/dist/_chunks/App-B83DZ9NG.js +0 -70
- package/dist/_chunks/App-BUSTbkyy.mjs +0 -68
- package/dist/_chunks/Dashboard-CNMTzSyc.js +0 -180
- package/dist/_chunks/Dashboard-Dbwl0ZBo.mjs +0 -180
- package/dist/_chunks/Settings-Dq1xy32B.js +0 -357
- package/dist/_chunks/Settings-jmGslDsB.mjs +0 -357
- package/dist/admin/src/pages/HomePage.d.ts +0 -2
package/dist/server/index.js
CHANGED
|
@@ -105,7 +105,7 @@ const schema$1 = {
|
|
|
105
105
|
configurable: false
|
|
106
106
|
},
|
|
107
107
|
total_amount: {
|
|
108
|
-
type: "
|
|
108
|
+
type: "decimal",
|
|
109
109
|
required: true,
|
|
110
110
|
min: 0,
|
|
111
111
|
configurable: false,
|
|
@@ -117,13 +117,31 @@ const schema$1 = {
|
|
|
117
117
|
default: "usd",
|
|
118
118
|
configurable: false
|
|
119
119
|
},
|
|
120
|
-
|
|
120
|
+
order_status: {
|
|
121
121
|
type: "enumeration",
|
|
122
|
-
enum: [
|
|
122
|
+
enum: [
|
|
123
|
+
"pending",
|
|
124
|
+
"processing",
|
|
125
|
+
"completed",
|
|
126
|
+
"failed",
|
|
127
|
+
"refunded"
|
|
128
|
+
],
|
|
123
129
|
required: true,
|
|
124
130
|
default: "pending",
|
|
125
131
|
configurable: false
|
|
126
132
|
},
|
|
133
|
+
payment_status: {
|
|
134
|
+
type: "enumeration",
|
|
135
|
+
enum: [
|
|
136
|
+
"unpaid",
|
|
137
|
+
"paid",
|
|
138
|
+
"partially_paid",
|
|
139
|
+
"refunded"
|
|
140
|
+
],
|
|
141
|
+
required: true,
|
|
142
|
+
default: "unpaid",
|
|
143
|
+
configurable: false
|
|
144
|
+
},
|
|
127
145
|
customer: {
|
|
128
146
|
type: "relation",
|
|
129
147
|
relation: "manyToOne",
|
|
@@ -173,7 +191,7 @@ const schema = {
|
|
|
173
191
|
configurable: false
|
|
174
192
|
},
|
|
175
193
|
amount: {
|
|
176
|
-
type: "
|
|
194
|
+
type: "decimal",
|
|
177
195
|
required: true,
|
|
178
196
|
min: 0,
|
|
179
197
|
configurable: false,
|
|
@@ -185,9 +203,15 @@ const schema = {
|
|
|
185
203
|
default: "usd",
|
|
186
204
|
configurable: false
|
|
187
205
|
},
|
|
188
|
-
|
|
206
|
+
payment_status: {
|
|
189
207
|
type: "enumeration",
|
|
190
|
-
enum: [
|
|
208
|
+
enum: [
|
|
209
|
+
"pending",
|
|
210
|
+
"succeeded",
|
|
211
|
+
"failed",
|
|
212
|
+
"canceled",
|
|
213
|
+
"refunded"
|
|
214
|
+
],
|
|
191
215
|
required: true,
|
|
192
216
|
default: "pending",
|
|
193
217
|
configurable: false
|
|
@@ -384,23 +408,17 @@ const stripeController = {
|
|
|
384
408
|
async handleWebhook(ctx) {
|
|
385
409
|
try {
|
|
386
410
|
const signature = ctx.request.headers["stripe-signature"];
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
payload = ctx.request.body;
|
|
390
|
-
} else if (Buffer.isBuffer(ctx.request.body)) {
|
|
391
|
-
payload = ctx.request.body;
|
|
392
|
-
} else {
|
|
393
|
-
payload = JSON.stringify(ctx.request.body);
|
|
394
|
-
}
|
|
411
|
+
const unparsedBody = ctx.request.body?.[Symbol.for("unparsedBody")];
|
|
412
|
+
const rawBody = unparsedBody || ctx.request.body;
|
|
395
413
|
if (!signature) {
|
|
396
414
|
return ctx.badRequest("Missing Stripe signature");
|
|
397
415
|
}
|
|
398
416
|
const stripeService2 = strapi.plugin("payment-plugin").service("stripe");
|
|
399
|
-
const event = await stripeService2.constructEvent(
|
|
417
|
+
const event = await stripeService2.constructEvent(rawBody, signature);
|
|
400
418
|
await stripeService2.handleWebhook(event);
|
|
401
419
|
ctx.body = { received: true };
|
|
402
420
|
} catch (error) {
|
|
403
|
-
strapi.log.error("Failed to handle webhook", { error });
|
|
421
|
+
strapi.log.error("Failed to handle webhook", { error: error.message, stack: error.stack });
|
|
404
422
|
ctx.badRequest(`Webhook Error: ${error.message}`);
|
|
405
423
|
}
|
|
406
424
|
},
|
|
@@ -475,10 +493,11 @@ const stripeController = {
|
|
|
475
493
|
*/
|
|
476
494
|
async listPayments(ctx) {
|
|
477
495
|
try {
|
|
478
|
-
const { page = 1, pageSize = 25, status, customer: customer2, order: order2 } = ctx.query;
|
|
496
|
+
const { page = 1, pageSize = 25, payment_status, status, customer: customer2, order: order2 } = ctx.query;
|
|
479
497
|
const { id: userId } = ctx.state.user;
|
|
480
498
|
const filters = {};
|
|
481
|
-
|
|
499
|
+
const statusValue = payment_status || status;
|
|
500
|
+
if (statusValue) filters.payment_status = { $eq: statusValue };
|
|
482
501
|
if (customer2) filters.customer = { $eq: customer2 };
|
|
483
502
|
if (order2) filters.order = { $eq: order2 };
|
|
484
503
|
const isAdmin = ctx.state.user.role?.name === "Administrator";
|
|
@@ -586,7 +605,7 @@ const stripeController = {
|
|
|
586
605
|
order_number: orderNumber,
|
|
587
606
|
total_amount: totalAmount,
|
|
588
607
|
currency,
|
|
589
|
-
|
|
608
|
+
order_status: "pending",
|
|
590
609
|
customer: customerId,
|
|
591
610
|
items,
|
|
592
611
|
metadata
|
|
@@ -599,7 +618,7 @@ const stripeController = {
|
|
|
599
618
|
data: {
|
|
600
619
|
orderId: order2.documentId,
|
|
601
620
|
orderNumber: order2.order_number,
|
|
602
|
-
|
|
621
|
+
order_status: order2.order_status,
|
|
603
622
|
totalAmount: order2.total_amount,
|
|
604
623
|
currency: order2.currency,
|
|
605
624
|
created: order2.createdAt
|
|
@@ -657,10 +676,11 @@ const stripeController = {
|
|
|
657
676
|
*/
|
|
658
677
|
async listOrders(ctx) {
|
|
659
678
|
try {
|
|
660
|
-
const { page = 1, pageSize = 25, status, customer: customer2 } = ctx.query;
|
|
679
|
+
const { page = 1, pageSize = 25, order_status, status, customer: customer2 } = ctx.query;
|
|
661
680
|
const { id: userId } = ctx.state.user;
|
|
662
681
|
const filters = {};
|
|
663
|
-
|
|
682
|
+
const statusValue = order_status || status;
|
|
683
|
+
if (statusValue) filters.order_status = { $eq: statusValue };
|
|
664
684
|
if (customer2) filters.customer = { $eq: customer2 };
|
|
665
685
|
const isAdmin = ctx.state.user.role?.name === "Administrator";
|
|
666
686
|
if (!isAdmin) {
|
|
@@ -708,11 +728,11 @@ const stripeController = {
|
|
|
708
728
|
const startDate = new Date(now.getTime() - days * 24 * 60 * 60 * 1e3);
|
|
709
729
|
const [totalPayments, successfulPayments, failedPayments, totalRevenue] = await Promise.all([
|
|
710
730
|
strapi.documents("plugin::payment-plugin.payment").count({}),
|
|
711
|
-
strapi.documents("plugin::payment-plugin.payment").count({ filters: {
|
|
712
|
-
strapi.documents("plugin::payment-plugin.payment").count({ filters: {
|
|
731
|
+
strapi.documents("plugin::payment-plugin.payment").count({ filters: { payment_status: { $eq: "succeeded" } } }),
|
|
732
|
+
strapi.documents("plugin::payment-plugin.payment").count({ filters: { payment_status: { $eq: "failed" } } }),
|
|
713
733
|
strapi.documents("plugin::payment-plugin.payment").findMany({
|
|
714
734
|
filters: {
|
|
715
|
-
|
|
735
|
+
payment_status: { $eq: "succeeded" },
|
|
716
736
|
createdAt: { $gte: startDate.toISOString() }
|
|
717
737
|
},
|
|
718
738
|
fields: ["amount"]
|
|
@@ -770,7 +790,7 @@ const stripeController = {
|
|
|
770
790
|
totalPayments: payments.length,
|
|
771
791
|
totalAmount: payments.reduce((sum, p) => sum + p.amount, 0),
|
|
772
792
|
byStatus: payments.reduce((acc, p) => {
|
|
773
|
-
acc[p.
|
|
793
|
+
acc[p.payment_status] = (acc[p.payment_status] || 0) + 1;
|
|
774
794
|
return acc;
|
|
775
795
|
}, {}),
|
|
776
796
|
byCurrency: payments.reduce((acc, p) => {
|
|
@@ -860,7 +880,7 @@ const stripeController = {
|
|
|
860
880
|
const payments = await strapi.documents("plugin::payment-plugin.payment").findMany({
|
|
861
881
|
filters: {
|
|
862
882
|
createdAt: { $gte: startDate.toISOString() },
|
|
863
|
-
|
|
883
|
+
payment_status: { $eq: "succeeded" }
|
|
864
884
|
},
|
|
865
885
|
fields: ["amount", "createdAt", "currency"],
|
|
866
886
|
sort: { createdAt: "asc" }
|
|
@@ -899,37 +919,56 @@ const stripeController = {
|
|
|
899
919
|
if (!paymentId) {
|
|
900
920
|
return ctx.badRequest("Payment ID is required");
|
|
901
921
|
}
|
|
902
|
-
const
|
|
903
|
-
|
|
922
|
+
const payment2 = await strapi.documents("plugin::payment-plugin.payment").findOne({
|
|
923
|
+
documentId: paymentId,
|
|
924
|
+
populate: ["order"]
|
|
904
925
|
});
|
|
905
|
-
if (
|
|
926
|
+
if (!payment2) {
|
|
906
927
|
return ctx.notFound("Payment not found");
|
|
907
928
|
}
|
|
908
|
-
|
|
929
|
+
if (!payment2.stripe_payment_intent_id) {
|
|
930
|
+
return ctx.badRequest("This payment record does not have an associated Stripe Payment Intent ID");
|
|
931
|
+
}
|
|
909
932
|
const stripeService2 = strapi.plugin("payment-plugin").service("stripe");
|
|
910
933
|
const refund = await stripeService2.createRefund({
|
|
911
934
|
paymentIntentId: payment2.stripe_payment_intent_id,
|
|
912
|
-
amount,
|
|
935
|
+
amount: amount ? Math.round(amount * 100) : void 0,
|
|
913
936
|
reason,
|
|
914
937
|
metadata: { ...metadata, admin_refund: true }
|
|
915
938
|
});
|
|
916
939
|
await strapi.documents("plugin::payment-plugin.payment").update({
|
|
917
940
|
documentId: payment2.documentId,
|
|
918
|
-
data: {
|
|
941
|
+
data: { payment_status: "refunded" }
|
|
919
942
|
});
|
|
943
|
+
if (payment2.order) {
|
|
944
|
+
const orderId = typeof payment2.order === "object" ? payment2.order.documentId : payment2.order;
|
|
945
|
+
await strapi.documents("plugin::payment-plugin.order").update({
|
|
946
|
+
documentId: orderId,
|
|
947
|
+
data: {
|
|
948
|
+
order_status: "refunded",
|
|
949
|
+
payment_status: "refunded"
|
|
950
|
+
}
|
|
951
|
+
});
|
|
952
|
+
}
|
|
920
953
|
ctx.body = {
|
|
921
954
|
success: true,
|
|
922
955
|
data: {
|
|
923
956
|
refundId: refund.id,
|
|
924
|
-
amount: refund.amount,
|
|
957
|
+
amount: refund.amount / 100,
|
|
958
|
+
// Convert back to base units for consistency
|
|
925
959
|
currency: refund.currency,
|
|
926
960
|
status: refund.status,
|
|
927
961
|
reason: refund.reason
|
|
928
962
|
}
|
|
929
963
|
};
|
|
930
964
|
} catch (error) {
|
|
931
|
-
strapi.log.error("Failed to create admin refund", {
|
|
932
|
-
|
|
965
|
+
strapi.log.error("Failed to create admin refund:", {
|
|
966
|
+
message: error.message,
|
|
967
|
+
stack: error.stack,
|
|
968
|
+
...error.raw && { stripeError: error.raw }
|
|
969
|
+
});
|
|
970
|
+
const errorMessage = error.message || "Failed to create admin refund";
|
|
971
|
+
ctx.internalServerError(errorMessage);
|
|
933
972
|
}
|
|
934
973
|
},
|
|
935
974
|
/**
|
|
@@ -937,9 +976,10 @@ const stripeController = {
|
|
|
937
976
|
*/
|
|
938
977
|
async adminListPayments(ctx) {
|
|
939
978
|
try {
|
|
940
|
-
const { page = 1, pageSize = 25, status, customer: customer2, order: order2 } = ctx.query;
|
|
979
|
+
const { page = 1, pageSize = 25, payment_status, status, customer: customer2, order: order2 } = ctx.query;
|
|
941
980
|
const filters = {};
|
|
942
|
-
|
|
981
|
+
const statusValue = payment_status || status;
|
|
982
|
+
if (statusValue) filters.payment_status = { $eq: statusValue };
|
|
943
983
|
if (customer2) filters.customer = { $eq: customer2 };
|
|
944
984
|
if (order2) filters.order = { $eq: order2 };
|
|
945
985
|
const pageNum = parseInt(page);
|
|
@@ -988,7 +1028,7 @@ const stripeController = {
|
|
|
988
1028
|
filters,
|
|
989
1029
|
populate: {
|
|
990
1030
|
payments: {
|
|
991
|
-
filters: {
|
|
1031
|
+
filters: { payment_status: { $eq: "succeeded" } },
|
|
992
1032
|
fields: ["amount"]
|
|
993
1033
|
}
|
|
994
1034
|
},
|
|
@@ -1030,9 +1070,10 @@ const stripeController = {
|
|
|
1030
1070
|
*/
|
|
1031
1071
|
async adminListOrders(ctx) {
|
|
1032
1072
|
try {
|
|
1033
|
-
const { page = 1, pageSize = 25, status, customer: customer2 } = ctx.query;
|
|
1073
|
+
const { page = 1, pageSize = 25, order_status, status, customer: customer2 } = ctx.query;
|
|
1034
1074
|
const filters = {};
|
|
1035
|
-
|
|
1075
|
+
const statusValue = order_status || status;
|
|
1076
|
+
if (statusValue) filters.order_status = { $eq: statusValue };
|
|
1036
1077
|
if (customer2) filters.customer = { $eq: customer2 };
|
|
1037
1078
|
const pageNum = parseInt(page);
|
|
1038
1079
|
const pageSizeNum = parseInt(pageSize);
|
|
@@ -1146,19 +1187,32 @@ const stripeController = {
|
|
|
1146
1187
|
email: `sample@example.com`,
|
|
1147
1188
|
firstName: "Sample",
|
|
1148
1189
|
lastName: "Customer",
|
|
1149
|
-
confirm:
|
|
1150
|
-
|
|
1151
|
-
// Still using this for the 'test' button to show a success
|
|
1190
|
+
confirm: false,
|
|
1191
|
+
// Don't auto-confirm, let frontend handle it
|
|
1152
1192
|
metadata: { is_sample: "true" }
|
|
1153
1193
|
});
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1194
|
+
const store = strapi.store({ type: "plugin", name: "payment-plugin" });
|
|
1195
|
+
const config2 = await store.get({ key: "settings" });
|
|
1196
|
+
const staticConfig = strapi.config.get("plugin::payment-plugin") || {};
|
|
1197
|
+
const mergedConfig = { ...staticConfig || {}, ...config2 || {} };
|
|
1198
|
+
const publishableKey = mergedConfig.stripe?.publishableKey || process.env.STRIPE_PUBLISHABLE_KEY || (process.env.STRIPE_API_KEY?.startsWith("pk_") ? process.env.STRIPE_API_KEY : "") || "";
|
|
1199
|
+
strapi.log.info("Publishing key check:", {
|
|
1200
|
+
hasEnvKey: !!process.env.STRIPE_PUBLISHABLE_KEY,
|
|
1201
|
+
hasConfigKey: !!mergedConfig.stripe?.publishableKey,
|
|
1202
|
+
keyLength: publishableKey?.length || 0,
|
|
1203
|
+
keyPrefix: publishableKey?.substring(0, 7)
|
|
1204
|
+
});
|
|
1205
|
+
if (!publishableKey) {
|
|
1206
|
+
strapi.log.error("Publishable key not found in environment or config");
|
|
1207
|
+
throw new Error("Stripe publishable key not configured. Please set STRIPE_PUBLISHABLE_KEY in your .env file.");
|
|
1158
1208
|
}
|
|
1159
1209
|
ctx.body = {
|
|
1160
1210
|
success: true,
|
|
1161
|
-
data:
|
|
1211
|
+
data: {
|
|
1212
|
+
...flowResult,
|
|
1213
|
+
publishableKey,
|
|
1214
|
+
clientSecret: flowResult.stripePaymentIntent.client_secret
|
|
1215
|
+
}
|
|
1162
1216
|
};
|
|
1163
1217
|
} catch (error) {
|
|
1164
1218
|
strapi.log.error("Failed to create sample payment", { error });
|
|
@@ -1287,7 +1341,7 @@ const routes$2 = {
|
|
|
1287
1341
|
},
|
|
1288
1342
|
{
|
|
1289
1343
|
method: "POST",
|
|
1290
|
-
path: "/payments/confirm/:
|
|
1344
|
+
path: "/payments/confirm/:paymentIntentId",
|
|
1291
1345
|
handler: "stripe.confirmPayment",
|
|
1292
1346
|
config: {
|
|
1293
1347
|
policies: []
|
|
@@ -1602,6 +1656,16 @@ const stripeService = ({ strapi: strapi2 }) => {
|
|
|
1602
1656
|
const stripe2 = await initializeStripe();
|
|
1603
1657
|
const logger = getLogger();
|
|
1604
1658
|
const paymentIntent = await stripe2.paymentIntents.confirm(paymentIntentId);
|
|
1659
|
+
await updateStrapiPayment(paymentIntent.id, {
|
|
1660
|
+
payment_status: mapStripeStatusToStrapi(paymentIntent.status),
|
|
1661
|
+
metadata: paymentIntent.metadata
|
|
1662
|
+
});
|
|
1663
|
+
if (paymentIntent.status === "succeeded" && paymentIntent.metadata?.strapi_order_id) {
|
|
1664
|
+
await updateStrapiOrder(paymentIntent.metadata.strapi_order_id, {
|
|
1665
|
+
order_status: "processing",
|
|
1666
|
+
payment_status: "paid"
|
|
1667
|
+
});
|
|
1668
|
+
}
|
|
1605
1669
|
logger.info("Payment confirmed", { paymentIntentId, status: paymentIntent.status });
|
|
1606
1670
|
return paymentIntent;
|
|
1607
1671
|
} catch (error) {
|
|
@@ -1674,15 +1738,25 @@ const stripeService = ({ strapi: strapi2 }) => {
|
|
|
1674
1738
|
refundData.reason = reason;
|
|
1675
1739
|
}
|
|
1676
1740
|
const refund = await stripe2.refunds.create(refundData);
|
|
1677
|
-
logger.info("Refund processed", {
|
|
1741
|
+
logger.info("Refund processed successfully", {
|
|
1678
1742
|
refundId: refund.id,
|
|
1679
1743
|
paymentIntentId,
|
|
1680
|
-
amount: refund.amount
|
|
1744
|
+
amount: refund.amount,
|
|
1745
|
+
status: refund.status
|
|
1681
1746
|
});
|
|
1682
1747
|
return refund;
|
|
1683
1748
|
} catch (error) {
|
|
1684
1749
|
const logger = getLogger();
|
|
1685
|
-
|
|
1750
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown Stripe error";
|
|
1751
|
+
logger.error("Failed to create Stripe refund", {
|
|
1752
|
+
message: errorMessage,
|
|
1753
|
+
error: error instanceof Error ? {
|
|
1754
|
+
message: error.message,
|
|
1755
|
+
stack: error.stack,
|
|
1756
|
+
...error.raw && { raw: error.raw }
|
|
1757
|
+
} : error,
|
|
1758
|
+
params
|
|
1759
|
+
});
|
|
1686
1760
|
throw error;
|
|
1687
1761
|
}
|
|
1688
1762
|
};
|
|
@@ -1710,9 +1784,18 @@ const stripeService = ({ strapi: strapi2 }) => {
|
|
|
1710
1784
|
}
|
|
1711
1785
|
});
|
|
1712
1786
|
if (existingPayments.length > 0) {
|
|
1787
|
+
const updateData = { ...data };
|
|
1788
|
+
if (data.metadata) {
|
|
1789
|
+
if (!updateData.customer && data.metadata.strapi_customer_id) {
|
|
1790
|
+
updateData.customer = data.metadata.strapi_customer_id;
|
|
1791
|
+
}
|
|
1792
|
+
if (!updateData.order && data.metadata.strapi_order_id) {
|
|
1793
|
+
updateData.order = data.metadata.strapi_order_id;
|
|
1794
|
+
}
|
|
1795
|
+
}
|
|
1713
1796
|
await strapi2.documents("plugin::payment-plugin.payment").update({
|
|
1714
1797
|
documentId: existingPayments[0].documentId,
|
|
1715
|
-
data
|
|
1798
|
+
data: updateData
|
|
1716
1799
|
});
|
|
1717
1800
|
}
|
|
1718
1801
|
} catch (error) {
|
|
@@ -1763,7 +1846,7 @@ const stripeService = ({ strapi: strapi2 }) => {
|
|
|
1763
1846
|
return strapi2.documents("plugin::payment-plugin.order").create({
|
|
1764
1847
|
data: {
|
|
1765
1848
|
...data,
|
|
1766
|
-
|
|
1849
|
+
order_status: data.order_status || "pending"
|
|
1767
1850
|
}
|
|
1768
1851
|
});
|
|
1769
1852
|
};
|
|
@@ -1776,7 +1859,7 @@ const stripeService = ({ strapi: strapi2 }) => {
|
|
|
1776
1859
|
stripe_payment_intent_id: paymentIntent.id,
|
|
1777
1860
|
amount: paymentIntent.amount / 100,
|
|
1778
1861
|
currency: paymentIntent.currency,
|
|
1779
|
-
|
|
1862
|
+
payment_status: mapStripeStatusToStrapi(paymentIntent.status),
|
|
1780
1863
|
payment_method: paymentIntent.payment_method || "card",
|
|
1781
1864
|
metadata: paymentIntent.metadata,
|
|
1782
1865
|
customer: customerId,
|
|
@@ -1854,6 +1937,12 @@ const stripeService = ({ strapi: strapi2 }) => {
|
|
|
1854
1937
|
metadata: { ...metadata, flow: "functional_api" }
|
|
1855
1938
|
});
|
|
1856
1939
|
const strapiPayment = await createStrapiPaymentRecord(paymentIntent);
|
|
1940
|
+
if (paymentIntent.status === "succeeded") {
|
|
1941
|
+
await updateStrapiOrder(strapiOrder.documentId, {
|
|
1942
|
+
order_status: "processing",
|
|
1943
|
+
payment_status: "paid"
|
|
1944
|
+
});
|
|
1945
|
+
}
|
|
1857
1946
|
return {
|
|
1858
1947
|
payment: strapiPayment,
|
|
1859
1948
|
order: strapiOrder,
|
|
@@ -1873,51 +1962,58 @@ const stripeService = ({ strapi: strapi2 }) => {
|
|
|
1873
1962
|
});
|
|
1874
1963
|
}
|
|
1875
1964
|
switch (event.type) {
|
|
1876
|
-
case "payment_intent.succeeded":
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
} catch (error) {
|
|
1896
|
-
await createStrapiPaymentRecord(paymentIntent);
|
|
1965
|
+
case "payment_intent.succeeded":
|
|
1966
|
+
case "charge.succeeded": {
|
|
1967
|
+
const obj = event.data.object;
|
|
1968
|
+
const paymentIntentId = event.type === "payment_intent.succeeded" ? obj.id : obj.payment_intent;
|
|
1969
|
+
if (!paymentIntentId) break;
|
|
1970
|
+
const metadata = obj.metadata || {};
|
|
1971
|
+
await updateStrapiPayment(paymentIntentId, {
|
|
1972
|
+
payment_status: "succeeded",
|
|
1973
|
+
metadata
|
|
1974
|
+
});
|
|
1975
|
+
const existing = await strapi2.documents("plugin::payment-plugin.payment").findMany({
|
|
1976
|
+
filters: { stripe_payment_intent_id: paymentIntentId }
|
|
1977
|
+
});
|
|
1978
|
+
if (existing.length === 0 && event.type === "payment_intent.succeeded") {
|
|
1979
|
+
await createStrapiPaymentRecord(obj);
|
|
1980
|
+
} else if (existing.length === 0 && event.type === "charge.succeeded" && obj.payment_intent) {
|
|
1981
|
+
const stripe2 = await initializeStripe();
|
|
1982
|
+
const pi = await stripe2.paymentIntents.retrieve(obj.payment_intent);
|
|
1983
|
+
await createStrapiPaymentRecord(pi);
|
|
1897
1984
|
}
|
|
1898
|
-
const orderId =
|
|
1985
|
+
const orderId = metadata.strapi_order_id;
|
|
1899
1986
|
if (orderId) {
|
|
1900
1987
|
await updateStrapiOrder(orderId, {
|
|
1901
|
-
|
|
1988
|
+
order_status: "processing",
|
|
1989
|
+
payment_status: "paid"
|
|
1902
1990
|
});
|
|
1903
1991
|
}
|
|
1904
|
-
logger.info(
|
|
1905
|
-
paymentIntentId
|
|
1906
|
-
amount: paymentIntent.amount,
|
|
1992
|
+
logger.info(`Payment succeeded handled for ${event.type}`, {
|
|
1993
|
+
paymentIntentId,
|
|
1907
1994
|
orderId
|
|
1908
1995
|
});
|
|
1909
1996
|
break;
|
|
1910
1997
|
}
|
|
1998
|
+
case "payment_intent.processing": {
|
|
1999
|
+
const paymentIntent = event.data.object;
|
|
2000
|
+
await updateStrapiPayment(paymentIntent.id, {
|
|
2001
|
+
payment_status: "pending",
|
|
2002
|
+
metadata: paymentIntent.metadata
|
|
2003
|
+
});
|
|
2004
|
+
break;
|
|
2005
|
+
}
|
|
1911
2006
|
case "payment_intent.payment_failed": {
|
|
1912
2007
|
const paymentIntent = event.data.object;
|
|
1913
2008
|
await updateStrapiPayment(paymentIntent.id, {
|
|
1914
|
-
|
|
2009
|
+
payment_status: "failed",
|
|
1915
2010
|
metadata: paymentIntent.metadata
|
|
1916
2011
|
});
|
|
1917
2012
|
const orderId = paymentIntent.metadata?.strapi_order_id;
|
|
1918
2013
|
if (orderId) {
|
|
1919
2014
|
await updateStrapiOrder(orderId, {
|
|
1920
|
-
|
|
2015
|
+
order_status: "failed",
|
|
2016
|
+
payment_status: "unpaid"
|
|
1921
2017
|
});
|
|
1922
2018
|
}
|
|
1923
2019
|
logger.warn("Payment failed", {
|
|
@@ -1930,13 +2026,14 @@ const stripeService = ({ strapi: strapi2 }) => {
|
|
|
1930
2026
|
case "payment_intent.canceled": {
|
|
1931
2027
|
const paymentIntent = event.data.object;
|
|
1932
2028
|
await updateStrapiPayment(paymentIntent.id, {
|
|
1933
|
-
|
|
2029
|
+
payment_status: "canceled",
|
|
1934
2030
|
metadata: paymentIntent.metadata
|
|
1935
2031
|
});
|
|
1936
2032
|
const orderId = paymentIntent.metadata?.strapi_order_id;
|
|
1937
2033
|
if (orderId) {
|
|
1938
2034
|
await updateStrapiOrder(orderId, {
|
|
1939
|
-
|
|
2035
|
+
order_status: "failed",
|
|
2036
|
+
payment_status: "unpaid"
|
|
1940
2037
|
});
|
|
1941
2038
|
}
|
|
1942
2039
|
logger.info("Payment canceled", {
|
|
@@ -1949,20 +2046,29 @@ const stripeService = ({ strapi: strapi2 }) => {
|
|
|
1949
2046
|
const charge = event.data.object;
|
|
1950
2047
|
if (charge.payment_intent) {
|
|
1951
2048
|
await updateStrapiPayment(charge.payment_intent, {
|
|
1952
|
-
|
|
2049
|
+
payment_status: "refunded"
|
|
1953
2050
|
});
|
|
1954
|
-
|
|
2051
|
+
let orderId = charge.metadata?.strapi_order_id;
|
|
2052
|
+
if (!orderId) {
|
|
2053
|
+
const payments = await strapi2.documents("plugin::payment-plugin.payment").findMany({
|
|
2054
|
+
filters: { stripe_payment_intent_id: charge.payment_intent },
|
|
2055
|
+
populate: ["order"]
|
|
2056
|
+
});
|
|
2057
|
+
if (payments.length > 0 && payments[0].order) {
|
|
2058
|
+
orderId = typeof payments[0].order === "object" ? payments[0].order.documentId : payments[0].order;
|
|
2059
|
+
}
|
|
2060
|
+
}
|
|
1955
2061
|
if (orderId) {
|
|
1956
2062
|
await updateStrapiOrder(orderId, {
|
|
1957
|
-
|
|
2063
|
+
order_status: "refunded",
|
|
2064
|
+
payment_status: "refunded"
|
|
1958
2065
|
});
|
|
1959
2066
|
}
|
|
1960
2067
|
}
|
|
1961
|
-
logger.info("Charge refunded", {
|
|
2068
|
+
logger.info("Charge refunded handled", {
|
|
1962
2069
|
chargeId: charge.id,
|
|
1963
2070
|
paymentIntentId: charge.payment_intent,
|
|
1964
|
-
amount: charge.amount_refunded
|
|
1965
|
-
orderId: charge.metadata?.strapi_order_id
|
|
2071
|
+
amount: charge.amount_refunded
|
|
1966
2072
|
});
|
|
1967
2073
|
break;
|
|
1968
2074
|
}
|