@reeboot/strapi-payment-plugin 0.0.4 → 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 +197 -91
- package/dist/server/index.mjs +197 -91
- 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.mjs
CHANGED
|
@@ -102,7 +102,7 @@ const schema$1 = {
|
|
|
102
102
|
configurable: false
|
|
103
103
|
},
|
|
104
104
|
total_amount: {
|
|
105
|
-
type: "
|
|
105
|
+
type: "decimal",
|
|
106
106
|
required: true,
|
|
107
107
|
min: 0,
|
|
108
108
|
configurable: false,
|
|
@@ -114,13 +114,31 @@ const schema$1 = {
|
|
|
114
114
|
default: "usd",
|
|
115
115
|
configurable: false
|
|
116
116
|
},
|
|
117
|
-
|
|
117
|
+
order_status: {
|
|
118
118
|
type: "enumeration",
|
|
119
|
-
enum: [
|
|
119
|
+
enum: [
|
|
120
|
+
"pending",
|
|
121
|
+
"processing",
|
|
122
|
+
"completed",
|
|
123
|
+
"failed",
|
|
124
|
+
"refunded"
|
|
125
|
+
],
|
|
120
126
|
required: true,
|
|
121
127
|
default: "pending",
|
|
122
128
|
configurable: false
|
|
123
129
|
},
|
|
130
|
+
payment_status: {
|
|
131
|
+
type: "enumeration",
|
|
132
|
+
enum: [
|
|
133
|
+
"unpaid",
|
|
134
|
+
"paid",
|
|
135
|
+
"partially_paid",
|
|
136
|
+
"refunded"
|
|
137
|
+
],
|
|
138
|
+
required: true,
|
|
139
|
+
default: "unpaid",
|
|
140
|
+
configurable: false
|
|
141
|
+
},
|
|
124
142
|
customer: {
|
|
125
143
|
type: "relation",
|
|
126
144
|
relation: "manyToOne",
|
|
@@ -170,7 +188,7 @@ const schema = {
|
|
|
170
188
|
configurable: false
|
|
171
189
|
},
|
|
172
190
|
amount: {
|
|
173
|
-
type: "
|
|
191
|
+
type: "decimal",
|
|
174
192
|
required: true,
|
|
175
193
|
min: 0,
|
|
176
194
|
configurable: false,
|
|
@@ -182,9 +200,15 @@ const schema = {
|
|
|
182
200
|
default: "usd",
|
|
183
201
|
configurable: false
|
|
184
202
|
},
|
|
185
|
-
|
|
203
|
+
payment_status: {
|
|
186
204
|
type: "enumeration",
|
|
187
|
-
enum: [
|
|
205
|
+
enum: [
|
|
206
|
+
"pending",
|
|
207
|
+
"succeeded",
|
|
208
|
+
"failed",
|
|
209
|
+
"canceled",
|
|
210
|
+
"refunded"
|
|
211
|
+
],
|
|
188
212
|
required: true,
|
|
189
213
|
default: "pending",
|
|
190
214
|
configurable: false
|
|
@@ -381,23 +405,17 @@ const stripeController = {
|
|
|
381
405
|
async handleWebhook(ctx) {
|
|
382
406
|
try {
|
|
383
407
|
const signature = ctx.request.headers["stripe-signature"];
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
payload = ctx.request.body;
|
|
387
|
-
} else if (Buffer.isBuffer(ctx.request.body)) {
|
|
388
|
-
payload = ctx.request.body;
|
|
389
|
-
} else {
|
|
390
|
-
payload = JSON.stringify(ctx.request.body);
|
|
391
|
-
}
|
|
408
|
+
const unparsedBody = ctx.request.body?.[Symbol.for("unparsedBody")];
|
|
409
|
+
const rawBody = unparsedBody || ctx.request.body;
|
|
392
410
|
if (!signature) {
|
|
393
411
|
return ctx.badRequest("Missing Stripe signature");
|
|
394
412
|
}
|
|
395
413
|
const stripeService2 = strapi.plugin("payment-plugin").service("stripe");
|
|
396
|
-
const event = await stripeService2.constructEvent(
|
|
414
|
+
const event = await stripeService2.constructEvent(rawBody, signature);
|
|
397
415
|
await stripeService2.handleWebhook(event);
|
|
398
416
|
ctx.body = { received: true };
|
|
399
417
|
} catch (error) {
|
|
400
|
-
strapi.log.error("Failed to handle webhook", { error });
|
|
418
|
+
strapi.log.error("Failed to handle webhook", { error: error.message, stack: error.stack });
|
|
401
419
|
ctx.badRequest(`Webhook Error: ${error.message}`);
|
|
402
420
|
}
|
|
403
421
|
},
|
|
@@ -472,10 +490,11 @@ const stripeController = {
|
|
|
472
490
|
*/
|
|
473
491
|
async listPayments(ctx) {
|
|
474
492
|
try {
|
|
475
|
-
const { page = 1, pageSize = 25, status, customer: customer2, order: order2 } = ctx.query;
|
|
493
|
+
const { page = 1, pageSize = 25, payment_status, status, customer: customer2, order: order2 } = ctx.query;
|
|
476
494
|
const { id: userId } = ctx.state.user;
|
|
477
495
|
const filters = {};
|
|
478
|
-
|
|
496
|
+
const statusValue = payment_status || status;
|
|
497
|
+
if (statusValue) filters.payment_status = { $eq: statusValue };
|
|
479
498
|
if (customer2) filters.customer = { $eq: customer2 };
|
|
480
499
|
if (order2) filters.order = { $eq: order2 };
|
|
481
500
|
const isAdmin = ctx.state.user.role?.name === "Administrator";
|
|
@@ -583,7 +602,7 @@ const stripeController = {
|
|
|
583
602
|
order_number: orderNumber,
|
|
584
603
|
total_amount: totalAmount,
|
|
585
604
|
currency,
|
|
586
|
-
|
|
605
|
+
order_status: "pending",
|
|
587
606
|
customer: customerId,
|
|
588
607
|
items,
|
|
589
608
|
metadata
|
|
@@ -596,7 +615,7 @@ const stripeController = {
|
|
|
596
615
|
data: {
|
|
597
616
|
orderId: order2.documentId,
|
|
598
617
|
orderNumber: order2.order_number,
|
|
599
|
-
|
|
618
|
+
order_status: order2.order_status,
|
|
600
619
|
totalAmount: order2.total_amount,
|
|
601
620
|
currency: order2.currency,
|
|
602
621
|
created: order2.createdAt
|
|
@@ -654,10 +673,11 @@ const stripeController = {
|
|
|
654
673
|
*/
|
|
655
674
|
async listOrders(ctx) {
|
|
656
675
|
try {
|
|
657
|
-
const { page = 1, pageSize = 25, status, customer: customer2 } = ctx.query;
|
|
676
|
+
const { page = 1, pageSize = 25, order_status, status, customer: customer2 } = ctx.query;
|
|
658
677
|
const { id: userId } = ctx.state.user;
|
|
659
678
|
const filters = {};
|
|
660
|
-
|
|
679
|
+
const statusValue = order_status || status;
|
|
680
|
+
if (statusValue) filters.order_status = { $eq: statusValue };
|
|
661
681
|
if (customer2) filters.customer = { $eq: customer2 };
|
|
662
682
|
const isAdmin = ctx.state.user.role?.name === "Administrator";
|
|
663
683
|
if (!isAdmin) {
|
|
@@ -705,11 +725,11 @@ const stripeController = {
|
|
|
705
725
|
const startDate = new Date(now.getTime() - days * 24 * 60 * 60 * 1e3);
|
|
706
726
|
const [totalPayments, successfulPayments, failedPayments, totalRevenue] = await Promise.all([
|
|
707
727
|
strapi.documents("plugin::payment-plugin.payment").count({}),
|
|
708
|
-
strapi.documents("plugin::payment-plugin.payment").count({ filters: {
|
|
709
|
-
strapi.documents("plugin::payment-plugin.payment").count({ filters: {
|
|
728
|
+
strapi.documents("plugin::payment-plugin.payment").count({ filters: { payment_status: { $eq: "succeeded" } } }),
|
|
729
|
+
strapi.documents("plugin::payment-plugin.payment").count({ filters: { payment_status: { $eq: "failed" } } }),
|
|
710
730
|
strapi.documents("plugin::payment-plugin.payment").findMany({
|
|
711
731
|
filters: {
|
|
712
|
-
|
|
732
|
+
payment_status: { $eq: "succeeded" },
|
|
713
733
|
createdAt: { $gte: startDate.toISOString() }
|
|
714
734
|
},
|
|
715
735
|
fields: ["amount"]
|
|
@@ -767,7 +787,7 @@ const stripeController = {
|
|
|
767
787
|
totalPayments: payments.length,
|
|
768
788
|
totalAmount: payments.reduce((sum, p) => sum + p.amount, 0),
|
|
769
789
|
byStatus: payments.reduce((acc, p) => {
|
|
770
|
-
acc[p.
|
|
790
|
+
acc[p.payment_status] = (acc[p.payment_status] || 0) + 1;
|
|
771
791
|
return acc;
|
|
772
792
|
}, {}),
|
|
773
793
|
byCurrency: payments.reduce((acc, p) => {
|
|
@@ -857,7 +877,7 @@ const stripeController = {
|
|
|
857
877
|
const payments = await strapi.documents("plugin::payment-plugin.payment").findMany({
|
|
858
878
|
filters: {
|
|
859
879
|
createdAt: { $gte: startDate.toISOString() },
|
|
860
|
-
|
|
880
|
+
payment_status: { $eq: "succeeded" }
|
|
861
881
|
},
|
|
862
882
|
fields: ["amount", "createdAt", "currency"],
|
|
863
883
|
sort: { createdAt: "asc" }
|
|
@@ -896,37 +916,56 @@ const stripeController = {
|
|
|
896
916
|
if (!paymentId) {
|
|
897
917
|
return ctx.badRequest("Payment ID is required");
|
|
898
918
|
}
|
|
899
|
-
const
|
|
900
|
-
|
|
919
|
+
const payment2 = await strapi.documents("plugin::payment-plugin.payment").findOne({
|
|
920
|
+
documentId: paymentId,
|
|
921
|
+
populate: ["order"]
|
|
901
922
|
});
|
|
902
|
-
if (
|
|
923
|
+
if (!payment2) {
|
|
903
924
|
return ctx.notFound("Payment not found");
|
|
904
925
|
}
|
|
905
|
-
|
|
926
|
+
if (!payment2.stripe_payment_intent_id) {
|
|
927
|
+
return ctx.badRequest("This payment record does not have an associated Stripe Payment Intent ID");
|
|
928
|
+
}
|
|
906
929
|
const stripeService2 = strapi.plugin("payment-plugin").service("stripe");
|
|
907
930
|
const refund = await stripeService2.createRefund({
|
|
908
931
|
paymentIntentId: payment2.stripe_payment_intent_id,
|
|
909
|
-
amount,
|
|
932
|
+
amount: amount ? Math.round(amount * 100) : void 0,
|
|
910
933
|
reason,
|
|
911
934
|
metadata: { ...metadata, admin_refund: true }
|
|
912
935
|
});
|
|
913
936
|
await strapi.documents("plugin::payment-plugin.payment").update({
|
|
914
937
|
documentId: payment2.documentId,
|
|
915
|
-
data: {
|
|
938
|
+
data: { payment_status: "refunded" }
|
|
916
939
|
});
|
|
940
|
+
if (payment2.order) {
|
|
941
|
+
const orderId = typeof payment2.order === "object" ? payment2.order.documentId : payment2.order;
|
|
942
|
+
await strapi.documents("plugin::payment-plugin.order").update({
|
|
943
|
+
documentId: orderId,
|
|
944
|
+
data: {
|
|
945
|
+
order_status: "refunded",
|
|
946
|
+
payment_status: "refunded"
|
|
947
|
+
}
|
|
948
|
+
});
|
|
949
|
+
}
|
|
917
950
|
ctx.body = {
|
|
918
951
|
success: true,
|
|
919
952
|
data: {
|
|
920
953
|
refundId: refund.id,
|
|
921
|
-
amount: refund.amount,
|
|
954
|
+
amount: refund.amount / 100,
|
|
955
|
+
// Convert back to base units for consistency
|
|
922
956
|
currency: refund.currency,
|
|
923
957
|
status: refund.status,
|
|
924
958
|
reason: refund.reason
|
|
925
959
|
}
|
|
926
960
|
};
|
|
927
961
|
} catch (error) {
|
|
928
|
-
strapi.log.error("Failed to create admin refund", {
|
|
929
|
-
|
|
962
|
+
strapi.log.error("Failed to create admin refund:", {
|
|
963
|
+
message: error.message,
|
|
964
|
+
stack: error.stack,
|
|
965
|
+
...error.raw && { stripeError: error.raw }
|
|
966
|
+
});
|
|
967
|
+
const errorMessage = error.message || "Failed to create admin refund";
|
|
968
|
+
ctx.internalServerError(errorMessage);
|
|
930
969
|
}
|
|
931
970
|
},
|
|
932
971
|
/**
|
|
@@ -934,9 +973,10 @@ const stripeController = {
|
|
|
934
973
|
*/
|
|
935
974
|
async adminListPayments(ctx) {
|
|
936
975
|
try {
|
|
937
|
-
const { page = 1, pageSize = 25, status, customer: customer2, order: order2 } = ctx.query;
|
|
976
|
+
const { page = 1, pageSize = 25, payment_status, status, customer: customer2, order: order2 } = ctx.query;
|
|
938
977
|
const filters = {};
|
|
939
|
-
|
|
978
|
+
const statusValue = payment_status || status;
|
|
979
|
+
if (statusValue) filters.payment_status = { $eq: statusValue };
|
|
940
980
|
if (customer2) filters.customer = { $eq: customer2 };
|
|
941
981
|
if (order2) filters.order = { $eq: order2 };
|
|
942
982
|
const pageNum = parseInt(page);
|
|
@@ -985,7 +1025,7 @@ const stripeController = {
|
|
|
985
1025
|
filters,
|
|
986
1026
|
populate: {
|
|
987
1027
|
payments: {
|
|
988
|
-
filters: {
|
|
1028
|
+
filters: { payment_status: { $eq: "succeeded" } },
|
|
989
1029
|
fields: ["amount"]
|
|
990
1030
|
}
|
|
991
1031
|
},
|
|
@@ -1027,9 +1067,10 @@ const stripeController = {
|
|
|
1027
1067
|
*/
|
|
1028
1068
|
async adminListOrders(ctx) {
|
|
1029
1069
|
try {
|
|
1030
|
-
const { page = 1, pageSize = 25, status, customer: customer2 } = ctx.query;
|
|
1070
|
+
const { page = 1, pageSize = 25, order_status, status, customer: customer2 } = ctx.query;
|
|
1031
1071
|
const filters = {};
|
|
1032
|
-
|
|
1072
|
+
const statusValue = order_status || status;
|
|
1073
|
+
if (statusValue) filters.order_status = { $eq: statusValue };
|
|
1033
1074
|
if (customer2) filters.customer = { $eq: customer2 };
|
|
1034
1075
|
const pageNum = parseInt(page);
|
|
1035
1076
|
const pageSizeNum = parseInt(pageSize);
|
|
@@ -1143,19 +1184,32 @@ const stripeController = {
|
|
|
1143
1184
|
email: `sample@example.com`,
|
|
1144
1185
|
firstName: "Sample",
|
|
1145
1186
|
lastName: "Customer",
|
|
1146
|
-
confirm:
|
|
1147
|
-
|
|
1148
|
-
// Still using this for the 'test' button to show a success
|
|
1187
|
+
confirm: false,
|
|
1188
|
+
// Don't auto-confirm, let frontend handle it
|
|
1149
1189
|
metadata: { is_sample: "true" }
|
|
1150
1190
|
});
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1191
|
+
const store = strapi.store({ type: "plugin", name: "payment-plugin" });
|
|
1192
|
+
const config2 = await store.get({ key: "settings" });
|
|
1193
|
+
const staticConfig = strapi.config.get("plugin::payment-plugin") || {};
|
|
1194
|
+
const mergedConfig = { ...staticConfig || {}, ...config2 || {} };
|
|
1195
|
+
const publishableKey = mergedConfig.stripe?.publishableKey || process.env.STRIPE_PUBLISHABLE_KEY || (process.env.STRIPE_API_KEY?.startsWith("pk_") ? process.env.STRIPE_API_KEY : "") || "";
|
|
1196
|
+
strapi.log.info("Publishing key check:", {
|
|
1197
|
+
hasEnvKey: !!process.env.STRIPE_PUBLISHABLE_KEY,
|
|
1198
|
+
hasConfigKey: !!mergedConfig.stripe?.publishableKey,
|
|
1199
|
+
keyLength: publishableKey?.length || 0,
|
|
1200
|
+
keyPrefix: publishableKey?.substring(0, 7)
|
|
1201
|
+
});
|
|
1202
|
+
if (!publishableKey) {
|
|
1203
|
+
strapi.log.error("Publishable key not found in environment or config");
|
|
1204
|
+
throw new Error("Stripe publishable key not configured. Please set STRIPE_PUBLISHABLE_KEY in your .env file.");
|
|
1155
1205
|
}
|
|
1156
1206
|
ctx.body = {
|
|
1157
1207
|
success: true,
|
|
1158
|
-
data:
|
|
1208
|
+
data: {
|
|
1209
|
+
...flowResult,
|
|
1210
|
+
publishableKey,
|
|
1211
|
+
clientSecret: flowResult.stripePaymentIntent.client_secret
|
|
1212
|
+
}
|
|
1159
1213
|
};
|
|
1160
1214
|
} catch (error) {
|
|
1161
1215
|
strapi.log.error("Failed to create sample payment", { error });
|
|
@@ -1599,6 +1653,16 @@ const stripeService = ({ strapi: strapi2 }) => {
|
|
|
1599
1653
|
const stripe2 = await initializeStripe();
|
|
1600
1654
|
const logger = getLogger();
|
|
1601
1655
|
const paymentIntent = await stripe2.paymentIntents.confirm(paymentIntentId);
|
|
1656
|
+
await updateStrapiPayment(paymentIntent.id, {
|
|
1657
|
+
payment_status: mapStripeStatusToStrapi(paymentIntent.status),
|
|
1658
|
+
metadata: paymentIntent.metadata
|
|
1659
|
+
});
|
|
1660
|
+
if (paymentIntent.status === "succeeded" && paymentIntent.metadata?.strapi_order_id) {
|
|
1661
|
+
await updateStrapiOrder(paymentIntent.metadata.strapi_order_id, {
|
|
1662
|
+
order_status: "processing",
|
|
1663
|
+
payment_status: "paid"
|
|
1664
|
+
});
|
|
1665
|
+
}
|
|
1602
1666
|
logger.info("Payment confirmed", { paymentIntentId, status: paymentIntent.status });
|
|
1603
1667
|
return paymentIntent;
|
|
1604
1668
|
} catch (error) {
|
|
@@ -1671,15 +1735,25 @@ const stripeService = ({ strapi: strapi2 }) => {
|
|
|
1671
1735
|
refundData.reason = reason;
|
|
1672
1736
|
}
|
|
1673
1737
|
const refund = await stripe2.refunds.create(refundData);
|
|
1674
|
-
logger.info("Refund processed", {
|
|
1738
|
+
logger.info("Refund processed successfully", {
|
|
1675
1739
|
refundId: refund.id,
|
|
1676
1740
|
paymentIntentId,
|
|
1677
|
-
amount: refund.amount
|
|
1741
|
+
amount: refund.amount,
|
|
1742
|
+
status: refund.status
|
|
1678
1743
|
});
|
|
1679
1744
|
return refund;
|
|
1680
1745
|
} catch (error) {
|
|
1681
1746
|
const logger = getLogger();
|
|
1682
|
-
|
|
1747
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown Stripe error";
|
|
1748
|
+
logger.error("Failed to create Stripe refund", {
|
|
1749
|
+
message: errorMessage,
|
|
1750
|
+
error: error instanceof Error ? {
|
|
1751
|
+
message: error.message,
|
|
1752
|
+
stack: error.stack,
|
|
1753
|
+
...error.raw && { raw: error.raw }
|
|
1754
|
+
} : error,
|
|
1755
|
+
params
|
|
1756
|
+
});
|
|
1683
1757
|
throw error;
|
|
1684
1758
|
}
|
|
1685
1759
|
};
|
|
@@ -1707,9 +1781,18 @@ const stripeService = ({ strapi: strapi2 }) => {
|
|
|
1707
1781
|
}
|
|
1708
1782
|
});
|
|
1709
1783
|
if (existingPayments.length > 0) {
|
|
1784
|
+
const updateData = { ...data };
|
|
1785
|
+
if (data.metadata) {
|
|
1786
|
+
if (!updateData.customer && data.metadata.strapi_customer_id) {
|
|
1787
|
+
updateData.customer = data.metadata.strapi_customer_id;
|
|
1788
|
+
}
|
|
1789
|
+
if (!updateData.order && data.metadata.strapi_order_id) {
|
|
1790
|
+
updateData.order = data.metadata.strapi_order_id;
|
|
1791
|
+
}
|
|
1792
|
+
}
|
|
1710
1793
|
await strapi2.documents("plugin::payment-plugin.payment").update({
|
|
1711
1794
|
documentId: existingPayments[0].documentId,
|
|
1712
|
-
data
|
|
1795
|
+
data: updateData
|
|
1713
1796
|
});
|
|
1714
1797
|
}
|
|
1715
1798
|
} catch (error) {
|
|
@@ -1760,7 +1843,7 @@ const stripeService = ({ strapi: strapi2 }) => {
|
|
|
1760
1843
|
return strapi2.documents("plugin::payment-plugin.order").create({
|
|
1761
1844
|
data: {
|
|
1762
1845
|
...data,
|
|
1763
|
-
|
|
1846
|
+
order_status: data.order_status || "pending"
|
|
1764
1847
|
}
|
|
1765
1848
|
});
|
|
1766
1849
|
};
|
|
@@ -1773,7 +1856,7 @@ const stripeService = ({ strapi: strapi2 }) => {
|
|
|
1773
1856
|
stripe_payment_intent_id: paymentIntent.id,
|
|
1774
1857
|
amount: paymentIntent.amount / 100,
|
|
1775
1858
|
currency: paymentIntent.currency,
|
|
1776
|
-
|
|
1859
|
+
payment_status: mapStripeStatusToStrapi(paymentIntent.status),
|
|
1777
1860
|
payment_method: paymentIntent.payment_method || "card",
|
|
1778
1861
|
metadata: paymentIntent.metadata,
|
|
1779
1862
|
customer: customerId,
|
|
@@ -1851,6 +1934,12 @@ const stripeService = ({ strapi: strapi2 }) => {
|
|
|
1851
1934
|
metadata: { ...metadata, flow: "functional_api" }
|
|
1852
1935
|
});
|
|
1853
1936
|
const strapiPayment = await createStrapiPaymentRecord(paymentIntent);
|
|
1937
|
+
if (paymentIntent.status === "succeeded") {
|
|
1938
|
+
await updateStrapiOrder(strapiOrder.documentId, {
|
|
1939
|
+
order_status: "processing",
|
|
1940
|
+
payment_status: "paid"
|
|
1941
|
+
});
|
|
1942
|
+
}
|
|
1854
1943
|
return {
|
|
1855
1944
|
payment: strapiPayment,
|
|
1856
1945
|
order: strapiOrder,
|
|
@@ -1870,51 +1959,58 @@ const stripeService = ({ strapi: strapi2 }) => {
|
|
|
1870
1959
|
});
|
|
1871
1960
|
}
|
|
1872
1961
|
switch (event.type) {
|
|
1873
|
-
case "payment_intent.succeeded":
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
} catch (error) {
|
|
1893
|
-
await createStrapiPaymentRecord(paymentIntent);
|
|
1962
|
+
case "payment_intent.succeeded":
|
|
1963
|
+
case "charge.succeeded": {
|
|
1964
|
+
const obj = event.data.object;
|
|
1965
|
+
const paymentIntentId = event.type === "payment_intent.succeeded" ? obj.id : obj.payment_intent;
|
|
1966
|
+
if (!paymentIntentId) break;
|
|
1967
|
+
const metadata = obj.metadata || {};
|
|
1968
|
+
await updateStrapiPayment(paymentIntentId, {
|
|
1969
|
+
payment_status: "succeeded",
|
|
1970
|
+
metadata
|
|
1971
|
+
});
|
|
1972
|
+
const existing = await strapi2.documents("plugin::payment-plugin.payment").findMany({
|
|
1973
|
+
filters: { stripe_payment_intent_id: paymentIntentId }
|
|
1974
|
+
});
|
|
1975
|
+
if (existing.length === 0 && event.type === "payment_intent.succeeded") {
|
|
1976
|
+
await createStrapiPaymentRecord(obj);
|
|
1977
|
+
} else if (existing.length === 0 && event.type === "charge.succeeded" && obj.payment_intent) {
|
|
1978
|
+
const stripe2 = await initializeStripe();
|
|
1979
|
+
const pi = await stripe2.paymentIntents.retrieve(obj.payment_intent);
|
|
1980
|
+
await createStrapiPaymentRecord(pi);
|
|
1894
1981
|
}
|
|
1895
|
-
const orderId =
|
|
1982
|
+
const orderId = metadata.strapi_order_id;
|
|
1896
1983
|
if (orderId) {
|
|
1897
1984
|
await updateStrapiOrder(orderId, {
|
|
1898
|
-
|
|
1985
|
+
order_status: "processing",
|
|
1986
|
+
payment_status: "paid"
|
|
1899
1987
|
});
|
|
1900
1988
|
}
|
|
1901
|
-
logger.info(
|
|
1902
|
-
paymentIntentId
|
|
1903
|
-
amount: paymentIntent.amount,
|
|
1989
|
+
logger.info(`Payment succeeded handled for ${event.type}`, {
|
|
1990
|
+
paymentIntentId,
|
|
1904
1991
|
orderId
|
|
1905
1992
|
});
|
|
1906
1993
|
break;
|
|
1907
1994
|
}
|
|
1995
|
+
case "payment_intent.processing": {
|
|
1996
|
+
const paymentIntent = event.data.object;
|
|
1997
|
+
await updateStrapiPayment(paymentIntent.id, {
|
|
1998
|
+
payment_status: "pending",
|
|
1999
|
+
metadata: paymentIntent.metadata
|
|
2000
|
+
});
|
|
2001
|
+
break;
|
|
2002
|
+
}
|
|
1908
2003
|
case "payment_intent.payment_failed": {
|
|
1909
2004
|
const paymentIntent = event.data.object;
|
|
1910
2005
|
await updateStrapiPayment(paymentIntent.id, {
|
|
1911
|
-
|
|
2006
|
+
payment_status: "failed",
|
|
1912
2007
|
metadata: paymentIntent.metadata
|
|
1913
2008
|
});
|
|
1914
2009
|
const orderId = paymentIntent.metadata?.strapi_order_id;
|
|
1915
2010
|
if (orderId) {
|
|
1916
2011
|
await updateStrapiOrder(orderId, {
|
|
1917
|
-
|
|
2012
|
+
order_status: "failed",
|
|
2013
|
+
payment_status: "unpaid"
|
|
1918
2014
|
});
|
|
1919
2015
|
}
|
|
1920
2016
|
logger.warn("Payment failed", {
|
|
@@ -1927,13 +2023,14 @@ const stripeService = ({ strapi: strapi2 }) => {
|
|
|
1927
2023
|
case "payment_intent.canceled": {
|
|
1928
2024
|
const paymentIntent = event.data.object;
|
|
1929
2025
|
await updateStrapiPayment(paymentIntent.id, {
|
|
1930
|
-
|
|
2026
|
+
payment_status: "canceled",
|
|
1931
2027
|
metadata: paymentIntent.metadata
|
|
1932
2028
|
});
|
|
1933
2029
|
const orderId = paymentIntent.metadata?.strapi_order_id;
|
|
1934
2030
|
if (orderId) {
|
|
1935
2031
|
await updateStrapiOrder(orderId, {
|
|
1936
|
-
|
|
2032
|
+
order_status: "failed",
|
|
2033
|
+
payment_status: "unpaid"
|
|
1937
2034
|
});
|
|
1938
2035
|
}
|
|
1939
2036
|
logger.info("Payment canceled", {
|
|
@@ -1946,20 +2043,29 @@ const stripeService = ({ strapi: strapi2 }) => {
|
|
|
1946
2043
|
const charge = event.data.object;
|
|
1947
2044
|
if (charge.payment_intent) {
|
|
1948
2045
|
await updateStrapiPayment(charge.payment_intent, {
|
|
1949
|
-
|
|
2046
|
+
payment_status: "refunded"
|
|
1950
2047
|
});
|
|
1951
|
-
|
|
2048
|
+
let orderId = charge.metadata?.strapi_order_id;
|
|
2049
|
+
if (!orderId) {
|
|
2050
|
+
const payments = await strapi2.documents("plugin::payment-plugin.payment").findMany({
|
|
2051
|
+
filters: { stripe_payment_intent_id: charge.payment_intent },
|
|
2052
|
+
populate: ["order"]
|
|
2053
|
+
});
|
|
2054
|
+
if (payments.length > 0 && payments[0].order) {
|
|
2055
|
+
orderId = typeof payments[0].order === "object" ? payments[0].order.documentId : payments[0].order;
|
|
2056
|
+
}
|
|
2057
|
+
}
|
|
1952
2058
|
if (orderId) {
|
|
1953
2059
|
await updateStrapiOrder(orderId, {
|
|
1954
|
-
|
|
2060
|
+
order_status: "refunded",
|
|
2061
|
+
payment_status: "refunded"
|
|
1955
2062
|
});
|
|
1956
2063
|
}
|
|
1957
2064
|
}
|
|
1958
|
-
logger.info("Charge refunded", {
|
|
2065
|
+
logger.info("Charge refunded handled", {
|
|
1959
2066
|
chargeId: charge.id,
|
|
1960
2067
|
paymentIntentId: charge.payment_intent,
|
|
1961
|
-
amount: charge.amount_refunded
|
|
1962
|
-
orderId: charge.metadata?.strapi_order_id
|
|
2068
|
+
amount: charge.amount_refunded
|
|
1963
2069
|
});
|
|
1964
2070
|
break;
|
|
1965
2071
|
}
|
|
@@ -105,7 +105,14 @@ declare const _default: {
|
|
|
105
105
|
default: string;
|
|
106
106
|
configurable: boolean;
|
|
107
107
|
};
|
|
108
|
-
|
|
108
|
+
order_status: {
|
|
109
|
+
type: string;
|
|
110
|
+
enum: string[];
|
|
111
|
+
required: boolean;
|
|
112
|
+
default: string;
|
|
113
|
+
configurable: boolean;
|
|
114
|
+
};
|
|
115
|
+
payment_status: {
|
|
109
116
|
type: string;
|
|
110
117
|
enum: string[];
|
|
111
118
|
required: boolean;
|
|
@@ -174,7 +181,7 @@ declare const _default: {
|
|
|
174
181
|
default: string;
|
|
175
182
|
configurable: boolean;
|
|
176
183
|
};
|
|
177
|
-
|
|
184
|
+
payment_status: {
|
|
178
185
|
type: string;
|
|
179
186
|
enum: string[];
|
|
180
187
|
required: boolean;
|
|
@@ -36,7 +36,14 @@ declare const _default: {
|
|
|
36
36
|
default: string;
|
|
37
37
|
configurable: boolean;
|
|
38
38
|
};
|
|
39
|
-
|
|
39
|
+
order_status: {
|
|
40
|
+
type: string;
|
|
41
|
+
enum: string[];
|
|
42
|
+
required: boolean;
|
|
43
|
+
default: string;
|
|
44
|
+
configurable: boolean;
|
|
45
|
+
};
|
|
46
|
+
payment_status: {
|
|
40
47
|
type: string;
|
|
41
48
|
enum: string[];
|
|
42
49
|
required: boolean;
|
|
@@ -196,7 +196,14 @@ declare const _default: {
|
|
|
196
196
|
default: string;
|
|
197
197
|
configurable: boolean;
|
|
198
198
|
};
|
|
199
|
-
|
|
199
|
+
order_status: {
|
|
200
|
+
type: string;
|
|
201
|
+
enum: string[];
|
|
202
|
+
required: boolean;
|
|
203
|
+
default: string;
|
|
204
|
+
configurable: boolean;
|
|
205
|
+
};
|
|
206
|
+
payment_status: {
|
|
200
207
|
type: string;
|
|
201
208
|
enum: string[];
|
|
202
209
|
required: boolean;
|
|
@@ -268,7 +275,7 @@ declare const _default: {
|
|
|
268
275
|
default: string;
|
|
269
276
|
configurable: boolean;
|
|
270
277
|
};
|
|
271
|
-
|
|
278
|
+
payment_status: {
|
|
272
279
|
type: string;
|
|
273
280
|
enum: string[];
|
|
274
281
|
required: boolean;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export type PaymentStatus = 'pending' | 'succeeded' | 'failed' | 'canceled' | 'refunded';
|
|
2
|
+
export type OrderStatus = 'pending' | 'processing' | 'completed' | 'failed' | 'refunded';
|
|
3
|
+
export interface PaymentInput {
|
|
4
|
+
stripe_payment_intent_id: string;
|
|
5
|
+
amount: number;
|
|
6
|
+
currency: string;
|
|
7
|
+
payment_status: PaymentStatus;
|
|
8
|
+
payment_method?: string;
|
|
9
|
+
metadata?: Record<string, any>;
|
|
10
|
+
customer?: string;
|
|
11
|
+
order?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface OrderInput {
|
|
14
|
+
order_number: string;
|
|
15
|
+
total_amount: number;
|
|
16
|
+
currency: string;
|
|
17
|
+
order_status: OrderStatus;
|
|
18
|
+
payment_status: 'unpaid' | 'paid' | 'partially_paid' | 'refunded';
|
|
19
|
+
customer?: string;
|
|
20
|
+
items: Record<string, any>;
|
|
21
|
+
metadata?: Record<string, any>;
|
|
22
|
+
}
|
|
23
|
+
export interface CustomerInput {
|
|
24
|
+
email: string;
|
|
25
|
+
stripe_customer_id: string;
|
|
26
|
+
first_name: string;
|
|
27
|
+
last_name: string;
|
|
28
|
+
phone?: string;
|
|
29
|
+
address?: Record<string, any>;
|
|
30
|
+
metadata?: Record<string, any>;
|
|
31
|
+
}
|