@easypayment/medusa-paypal 0.6.3 → 0.6.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/.medusa/server/src/admin/index.js +7 -10
- package/.medusa/server/src/admin/index.mjs +7 -10
- package/.medusa/server/src/api/store/payment-collections/[id]/payment-sessions/route.d.ts.map +1 -1
- package/.medusa/server/src/api/store/payment-collections/[id]/payment-sessions/route.js.map +1 -1
- package/.medusa/server/src/api/store/paypal/capture-order/route.d.ts.map +1 -1
- package/.medusa/server/src/api/store/paypal/capture-order/route.js +1 -11
- package/.medusa/server/src/api/store/paypal/capture-order/route.js.map +1 -1
- package/.medusa/server/src/api/store/paypal/create-order/route.d.ts.map +1 -1
- package/.medusa/server/src/api/store/paypal/create-order/route.js +0 -9
- package/.medusa/server/src/api/store/paypal/create-order/route.js.map +1 -1
- package/.medusa/server/src/api/store/paypal/webhook/route.d.ts.map +1 -1
- package/.medusa/server/src/api/store/paypal/webhook/route.js +162 -115
- package/.medusa/server/src/api/store/paypal/webhook/route.js.map +1 -1
- package/.medusa/server/src/api/store/paypal-complete/route.d.ts.map +1 -1
- package/.medusa/server/src/api/store/paypal-complete/route.js +46 -24
- package/.medusa/server/src/api/store/paypal-complete/route.js.map +1 -1
- package/.medusa/server/src/jobs/paypal-webhook-retry.d.ts.map +1 -1
- package/.medusa/server/src/jobs/paypal-webhook-retry.js +97 -43
- package/.medusa/server/src/jobs/paypal-webhook-retry.js.map +1 -1
- package/.medusa/server/src/modules/paypal/migrations/20270201000000_add_webhook_dead_letter.d.ts +6 -0
- package/.medusa/server/src/modules/paypal/migrations/20270201000000_add_webhook_dead_letter.d.ts.map +1 -0
- package/.medusa/server/src/modules/paypal/migrations/20270201000000_add_webhook_dead_letter.js +20 -0
- package/.medusa/server/src/modules/paypal/migrations/20270201000000_add_webhook_dead_letter.js.map +1 -0
- package/.medusa/server/src/modules/paypal/payment-provider/service.d.ts.map +1 -1
- package/.medusa/server/src/modules/paypal/payment-provider/service.js +0 -42
- package/.medusa/server/src/modules/paypal/payment-provider/service.js.map +1 -1
- package/.medusa/server/src/modules/paypal/service.d.ts +0 -8
- package/.medusa/server/src/modules/paypal/service.d.ts.map +1 -1
- package/.medusa/server/src/modules/paypal/service.js +6 -114
- package/.medusa/server/src/modules/paypal/service.js.map +1 -1
- package/.medusa/server/src/modules/paypal/types/config.d.ts +0 -2
- package/.medusa/server/src/modules/paypal/types/config.d.ts.map +1 -1
- package/.medusa/server/src/modules/paypal/types/config.js +0 -9
- package/.medusa/server/src/modules/paypal/types/config.js.map +1 -1
- package/.medusa/server/src/modules/paypal/webhook-processor.d.ts +21 -17
- package/.medusa/server/src/modules/paypal/webhook-processor.d.ts.map +1 -1
- package/.medusa/server/src/modules/paypal/webhook-processor.js +195 -99
- package/.medusa/server/src/modules/paypal/webhook-processor.js.map +1 -1
- package/README.md +156 -152
- package/package.json +1 -1
- package/src/admin/routes/settings/paypal/_components/Tabs.tsx +48 -52
- package/src/admin/routes/settings/paypal/paypal-settings/page.tsx +0 -23
- package/src/api/store/payment-collections/[id]/payment-sessions/route.ts +56 -65
- package/src/api/store/paypal/capture-order/route.ts +266 -276
- package/src/api/store/paypal/create-order/route.ts +0 -9
- package/src/api/store/paypal/webhook/route.ts +325 -246
- package/src/api/store/paypal-complete/route.ts +105 -76
- package/src/jobs/paypal-webhook-retry.ts +149 -85
- package/src/modules/paypal/migrations/20270201000000_add_webhook_dead_letter.ts +17 -0
- package/src/modules/paypal/payment-provider/service.ts +1079 -1121
- package/src/modules/paypal/service.ts +6 -127
- package/src/modules/paypal/types/config.ts +33 -47
- package/src/modules/paypal/webhook-processor.ts +377 -215
- package/.medusa/server/src/api/admin/paypal/rotate-credentials/route.d.ts +0 -3
- package/.medusa/server/src/api/admin/paypal/rotate-credentials/route.d.ts.map +0 -1
- package/.medusa/server/src/api/admin/paypal/rotate-credentials/route.js +0 -9
- package/.medusa/server/src/api/admin/paypal/rotate-credentials/route.js.map +0 -1
- package/.medusa/server/src/jobs/paypal-reconcile.d.ts +0 -7
- package/.medusa/server/src/jobs/paypal-reconcile.d.ts.map +0 -1
- package/.medusa/server/src/jobs/paypal-reconcile.js +0 -109
- package/.medusa/server/src/jobs/paypal-reconcile.js.map +0 -1
- package/.medusa/server/src/modules/paypal/utils/crypto.d.ts +0 -4
- package/.medusa/server/src/modules/paypal/utils/crypto.d.ts.map +0 -1
- package/.medusa/server/src/modules/paypal/utils/crypto.js +0 -47
- package/.medusa/server/src/modules/paypal/utils/crypto.js.map +0 -1
- package/src/api/admin/paypal/rotate-credentials/route.ts +0 -8
- package/src/jobs/paypal-reconcile.ts +0 -113
- package/src/modules/paypal/utils/crypto.ts +0 -51
|
@@ -3,54 +3,77 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.POST = POST;
|
|
4
4
|
const webhook_processor_1 = require("../../../../modules/paypal/webhook-processor");
|
|
5
5
|
const REPLAY_WINDOW_MINUTES = (() => {
|
|
6
|
-
const
|
|
7
|
-
return Number.isFinite(
|
|
6
|
+
const v = Number(process.env.PAYPAL_WEBHOOK_REPLAY_WINDOW_MINUTES);
|
|
7
|
+
return Number.isFinite(v) && v > 0 ? v : 60;
|
|
8
8
|
})();
|
|
9
9
|
function getHeader(headers, name) {
|
|
10
10
|
const direct = headers[name];
|
|
11
|
-
if (Array.isArray(direct))
|
|
11
|
+
if (Array.isArray(direct))
|
|
12
12
|
return direct[0];
|
|
13
|
-
|
|
14
|
-
if (typeof direct === "string") {
|
|
13
|
+
if (typeof direct === "string")
|
|
15
14
|
return direct;
|
|
15
|
+
const lower = name.toLowerCase();
|
|
16
|
+
const key = Object.keys(headers).find((h) => h.toLowerCase() === lower);
|
|
17
|
+
if (!key)
|
|
18
|
+
return undefined;
|
|
19
|
+
const val = headers[key];
|
|
20
|
+
return Array.isArray(val) ? val[0] : val;
|
|
21
|
+
}
|
|
22
|
+
function validateRequest(req) {
|
|
23
|
+
const payload = (req.body || {});
|
|
24
|
+
const eventId = String(payload?.id || payload?.event_id || "").trim();
|
|
25
|
+
const eventType = String(payload?.event_type || payload?.eventType || "").trim();
|
|
26
|
+
if (!eventId || !eventType) {
|
|
27
|
+
return { ok: false, status: 400, message: "Missing required fields: id and event_type" };
|
|
16
28
|
}
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
29
|
+
const transmissionTimeHeader = getHeader(req.headers, "paypal-transmission-time");
|
|
30
|
+
if (!transmissionTimeHeader) {
|
|
31
|
+
return {
|
|
32
|
+
ok: false,
|
|
33
|
+
status: 400,
|
|
34
|
+
message: "Missing required header: paypal-transmission-time",
|
|
35
|
+
};
|
|
22
36
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
37
|
+
const transmissionMs = Date.parse(transmissionTimeHeader);
|
|
38
|
+
if (!Number.isFinite(transmissionMs)) {
|
|
39
|
+
return {
|
|
40
|
+
ok: false,
|
|
41
|
+
status: 400,
|
|
42
|
+
message: "Invalid paypal-transmission-time header value",
|
|
43
|
+
};
|
|
29
44
|
}
|
|
30
|
-
const
|
|
31
|
-
if (
|
|
32
|
-
|
|
45
|
+
const ageMs = Math.abs(Date.now() - transmissionMs);
|
|
46
|
+
if (ageMs > REPLAY_WINDOW_MINUTES * 60 * 1000) {
|
|
47
|
+
return {
|
|
48
|
+
ok: false,
|
|
49
|
+
status: 400,
|
|
50
|
+
message: `Webhook rejected: outside ${REPLAY_WINDOW_MINUTES}-minute replay window`,
|
|
51
|
+
};
|
|
33
52
|
}
|
|
34
|
-
|
|
35
|
-
|
|
53
|
+
return {
|
|
54
|
+
ok: true,
|
|
55
|
+
eventId,
|
|
56
|
+
eventType,
|
|
57
|
+
transmissionId: getHeader(req.headers, "paypal-transmission-id") || null,
|
|
58
|
+
transmissionTime: new Date(transmissionMs),
|
|
59
|
+
};
|
|
36
60
|
}
|
|
37
61
|
function resolveWebhookId(environment, settings) {
|
|
38
62
|
const ids = (settings?.webhook_ids || {});
|
|
39
|
-
const legacyLive = settings?.webhook_id_live;
|
|
40
|
-
const legacySandbox = settings?.webhook_id_sandbox;
|
|
41
63
|
if (environment === "live") {
|
|
42
|
-
return ids.live ||
|
|
64
|
+
return (ids.live ||
|
|
65
|
+
settings?.webhook_id_live ||
|
|
66
|
+
process.env.PAYPAL_WEBHOOK_ID_LIVE);
|
|
43
67
|
}
|
|
44
|
-
return ids.sandbox ||
|
|
68
|
+
return (ids.sandbox ||
|
|
69
|
+
settings?.webhook_id_sandbox ||
|
|
70
|
+
process.env.PAYPAL_WEBHOOK_ID_SANDBOX);
|
|
45
71
|
}
|
|
46
72
|
async function verifyWebhookSignature(paypal, environment, body, headers) {
|
|
47
|
-
if (isReplay(headers)) {
|
|
48
|
-
throw new Error("PayPal webhook replay protection triggered");
|
|
49
|
-
}
|
|
50
73
|
const settings = await paypal.getSettings().catch(() => ({ data: {} }));
|
|
51
74
|
const webhookId = resolveWebhookId(environment, settings?.data || {});
|
|
52
75
|
if (!webhookId) {
|
|
53
|
-
throw new Error(`
|
|
76
|
+
throw new Error(`PayPal webhook ID not configured for environment "${environment}". Set PAYPAL_WEBHOOK_ID_${environment.toUpperCase()} or configure it in admin settings.`);
|
|
54
77
|
}
|
|
55
78
|
const base = environment === "live"
|
|
56
79
|
? "https://api-m.paypal.com"
|
|
@@ -65,15 +88,11 @@ async function verifyWebhookSignature(paypal, environment, body, headers) {
|
|
|
65
88
|
webhook_id: webhookId,
|
|
66
89
|
webhook_event: body,
|
|
67
90
|
};
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
verifyPayload.transmission_time,
|
|
74
|
-
];
|
|
75
|
-
if (requiredHeaders.some((value) => !value)) {
|
|
76
|
-
throw new Error("Missing required PayPal webhook signature headers");
|
|
91
|
+
const missing = Object.entries(verifyPayload)
|
|
92
|
+
.filter(([k, v]) => k !== "webhook_id" && k !== "webhook_event" && !v)
|
|
93
|
+
.map(([k]) => k);
|
|
94
|
+
if (missing.length > 0) {
|
|
95
|
+
throw new Error(`Missing required PayPal webhook headers: ${missing.join(", ")}`);
|
|
77
96
|
}
|
|
78
97
|
const resp = await fetch(`${base}/v1/notifications/verify-webhook-signature`, {
|
|
79
98
|
method: "POST",
|
|
@@ -84,34 +103,53 @@ async function verifyWebhookSignature(paypal, environment, body, headers) {
|
|
|
84
103
|
body: JSON.stringify(verifyPayload),
|
|
85
104
|
});
|
|
86
105
|
const json = await resp.json().catch(() => ({}));
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
throw new Error(`PayPal
|
|
106
|
+
const debugId = resp.headers.get("paypal-debug-id") || json?.debug_id;
|
|
107
|
+
if (!resp.ok) {
|
|
108
|
+
throw new Error(`PayPal signature verification API error (${resp.status}): ${JSON.stringify(json)}` +
|
|
109
|
+
(debugId ? ` debug_id=${debugId}` : ""));
|
|
110
|
+
}
|
|
111
|
+
if (json?.verification_status !== "VERIFIED") {
|
|
112
|
+
throw new Error(`PayPal webhook signature not verified. Status: ${json?.verification_status}` +
|
|
113
|
+
(debugId ? ` debug_id=${debugId}` : ""));
|
|
90
114
|
}
|
|
91
115
|
}
|
|
92
116
|
async function POST(req, res) {
|
|
93
117
|
const paypal = req.scope.resolve("paypal_onboarding");
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
transmission_id: transmissionId,
|
|
110
|
-
});
|
|
111
|
-
if ((existingByTransmission || []).length > 0) {
|
|
118
|
+
const validation = validateRequest(req);
|
|
119
|
+
if (!validation.ok) {
|
|
120
|
+
console.warn("[PayPal] webhook: validation failed:", validation.message);
|
|
121
|
+
return res.status(validation.status).json({ message: validation.message });
|
|
122
|
+
}
|
|
123
|
+
const { eventId, eventType, transmissionId, transmissionTime } = validation;
|
|
124
|
+
const payload = (req.body || {});
|
|
125
|
+
if (transmissionId) {
|
|
126
|
+
try {
|
|
127
|
+
const existing = await paypal.listPayPalWebhookEvents({ transmission_id: transmissionId });
|
|
128
|
+
if ((existing || []).length > 0) {
|
|
129
|
+
console.info("[PayPal] webhook: duplicate transmission_id", {
|
|
130
|
+
transmissionId,
|
|
131
|
+
eventId,
|
|
132
|
+
});
|
|
112
133
|
return res.json({ ok: true, duplicate: true });
|
|
113
134
|
}
|
|
114
135
|
}
|
|
136
|
+
catch (e) {
|
|
137
|
+
console.warn("[PayPal] webhook: transmission_id dedup check failed:", e?.message);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
try {
|
|
141
|
+
const creds = await paypal.getActiveCredentials();
|
|
142
|
+
await verifyWebhookSignature(paypal, creds.environment, payload, req.headers);
|
|
143
|
+
}
|
|
144
|
+
catch (e) {
|
|
145
|
+
console.error("[PayPal] webhook: signature verification failed:", e?.message);
|
|
146
|
+
return res
|
|
147
|
+
.status(401)
|
|
148
|
+
.json({ message: e?.message || "Webhook signature verification failed" });
|
|
149
|
+
}
|
|
150
|
+
const eventVersion = (0, webhook_processor_1.normalizeEventVersion)(payload);
|
|
151
|
+
let recordId = null;
|
|
152
|
+
try {
|
|
115
153
|
const recordResult = await paypal.createWebhookEventRecord({
|
|
116
154
|
event_id: eventId,
|
|
117
155
|
event_type: eventType,
|
|
@@ -123,81 +161,90 @@ async function POST(req, res) {
|
|
|
123
161
|
attempt_count: 1,
|
|
124
162
|
});
|
|
125
163
|
if (!recordResult.created) {
|
|
164
|
+
console.info("[PayPal] webhook: duplicate event_id", { eventId, eventType });
|
|
126
165
|
return res.json({ ok: true, duplicate: true });
|
|
127
166
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
}
|
|
140
|
-
return res.json({ ok: true, ignored: true });
|
|
141
|
-
}
|
|
142
|
-
const processed = await (0, webhook_processor_1.processPayPalWebhookEvent)(req.scope, {
|
|
143
|
-
eventType,
|
|
144
|
-
payload,
|
|
167
|
+
recordId = recordResult.event?.id ?? null;
|
|
168
|
+
}
|
|
169
|
+
catch (e) {
|
|
170
|
+
console.error("[PayPal] webhook: failed to create DB record:", e?.message);
|
|
171
|
+
return res.status(500).json({ message: "Failed to record webhook event" });
|
|
172
|
+
}
|
|
173
|
+
if (!(0, webhook_processor_1.isAllowedEventType)(eventType)) {
|
|
174
|
+
console.info("[PayPal] webhook: unsupported event type, ignoring", { eventType });
|
|
175
|
+
await paypal.recordAuditEvent("webhook_unsupported_event", {
|
|
176
|
+
event_id: eventId,
|
|
177
|
+
event_type: eventType,
|
|
145
178
|
});
|
|
146
|
-
if (
|
|
147
|
-
await paypal
|
|
148
|
-
|
|
179
|
+
if (recordId) {
|
|
180
|
+
await paypal
|
|
181
|
+
.updateWebhookEventRecord({
|
|
182
|
+
id: recordId,
|
|
183
|
+
status: "ignored",
|
|
184
|
+
processed_at: new Date(),
|
|
185
|
+
})
|
|
186
|
+
.catch(() => { });
|
|
187
|
+
}
|
|
188
|
+
return res.json({ ok: true, ignored: true });
|
|
189
|
+
}
|
|
190
|
+
try {
|
|
191
|
+
const processed = await (0, webhook_processor_1.processPayPalWebhookEvent)(req.scope, { eventType, payload });
|
|
192
|
+
if (recordId) {
|
|
193
|
+
await paypal
|
|
194
|
+
.updateWebhookEventRecord({
|
|
195
|
+
id: recordId,
|
|
149
196
|
status: "processed",
|
|
150
197
|
processed_at: new Date(),
|
|
151
198
|
resource_id: processed.refundId || processed.captureId || processed.orderId || null,
|
|
152
|
-
})
|
|
199
|
+
})
|
|
200
|
+
.catch(() => { });
|
|
153
201
|
}
|
|
154
|
-
console.info("[PayPal] webhook", {
|
|
202
|
+
console.info("[PayPal] webhook: processed", {
|
|
155
203
|
event_id: eventId,
|
|
156
204
|
event_type: eventType,
|
|
157
205
|
order_id: processed.orderId,
|
|
158
206
|
capture_id: processed.captureId,
|
|
159
207
|
refund_id: processed.refundId,
|
|
160
208
|
cart_id: processed.cartId,
|
|
209
|
+
session_updated: processed.sessionUpdated,
|
|
161
210
|
});
|
|
162
|
-
|
|
163
|
-
await paypal.recordMetric("webhook_success");
|
|
164
|
-
}
|
|
165
|
-
catch {
|
|
166
|
-
// ignore metrics failures
|
|
167
|
-
}
|
|
211
|
+
await paypal.recordMetric("webhook_success").catch(() => { });
|
|
168
212
|
return res.json({ ok: true });
|
|
169
213
|
}
|
|
170
214
|
catch (e) {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
await paypal.recordAuditEvent("webhook_failed", {
|
|
190
|
-
event_id: payload?.id || payload?.event_id,
|
|
191
|
-
event_type: payload?.event_type || payload?.eventType,
|
|
192
|
-
message: e?.message || String(e),
|
|
193
|
-
});
|
|
194
|
-
await paypal.recordMetric("webhook_failed");
|
|
215
|
+
console.error("[PayPal] webhook: processing failed", {
|
|
216
|
+
event_id: eventId,
|
|
217
|
+
event_type: eventType,
|
|
218
|
+
error: e?.message,
|
|
219
|
+
});
|
|
220
|
+
const retryable = (0, webhook_processor_1.isRetryableError)(e);
|
|
221
|
+
const nextStatus = retryable ? "failed" : "dead_letter";
|
|
222
|
+
if (recordId) {
|
|
223
|
+
await paypal
|
|
224
|
+
.updateWebhookEventRecord({
|
|
225
|
+
id: recordId,
|
|
226
|
+
status: nextStatus,
|
|
227
|
+
attempt_count: 1,
|
|
228
|
+
next_retry_at: retryable ? (0, webhook_processor_1.computeNextRetryAt)(1) : null,
|
|
229
|
+
last_error: e?.message || String(e),
|
|
230
|
+
})
|
|
231
|
+
.catch(() => { });
|
|
195
232
|
}
|
|
196
|
-
|
|
197
|
-
|
|
233
|
+
await paypal
|
|
234
|
+
.recordAuditEvent("webhook_processing_failed", {
|
|
235
|
+
event_id: eventId,
|
|
236
|
+
event_type: eventType,
|
|
237
|
+
retryable,
|
|
238
|
+
message: e?.message || String(e),
|
|
239
|
+
})
|
|
240
|
+
.catch(() => { });
|
|
241
|
+
await paypal.recordMetric("webhook_failed").catch(() => { });
|
|
242
|
+
if (!retryable) {
|
|
243
|
+
return res.status(200).json({ ok: false, message: e?.message });
|
|
198
244
|
}
|
|
199
|
-
|
|
200
|
-
|
|
245
|
+
return res
|
|
246
|
+
.status(500)
|
|
247
|
+
.json({ message: e?.message || "PayPal webhook processing error" });
|
|
201
248
|
}
|
|
202
249
|
}
|
|
203
250
|
//# sourceMappingURL=route.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route.js","sourceRoot":"","sources":["../../../../../../../src/api/store/paypal/webhook/route.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"route.js","sourceRoot":"","sources":["../../../../../../../src/api/store/paypal/webhook/route.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../src/api/store/paypal-complete/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAK7E,wBAAsB,IAAI,CAAC,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,cAAc,
|
|
1
|
+
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../src/api/store/paypal-complete/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAK7E,wBAAsB,IAAI,CAAC,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,cAAc,2BAmGjE"}
|
|
@@ -8,21 +8,6 @@ async function POST(req, res) {
|
|
|
8
8
|
return res.status(400).json({ error: "cart_id is required" });
|
|
9
9
|
}
|
|
10
10
|
try {
|
|
11
|
-
// Step 1 — read paymentAction from DB settings (same pattern as capture-order)
|
|
12
|
-
const paypal = req.scope.resolve("paypal_onboarding");
|
|
13
|
-
const settings = await paypal.getSettings().catch(() => ({}));
|
|
14
|
-
const settingsData = settings && typeof settings === "object" && "data" in settings
|
|
15
|
-
? (settings.data ?? {})
|
|
16
|
-
: {};
|
|
17
|
-
const additionalSettings = (settingsData.additional_settings || {});
|
|
18
|
-
const paymentAction = typeof additionalSettings.paymentAction === "string"
|
|
19
|
-
? additionalSettings.paymentAction
|
|
20
|
-
: "capture";
|
|
21
|
-
// "authorize" mode → session status = "authorized"
|
|
22
|
-
// "capture" mode → session status = "captured"
|
|
23
|
-
const sessionStatus = paymentAction === "authorize" ? "authorized" : "captured";
|
|
24
|
-
const timestampKey = paymentAction === "authorize" ? "authorized_at" : "captured_at";
|
|
25
|
-
// Step 2 — find the PayPal session for this cart
|
|
26
11
|
const query = req.scope.resolve("query");
|
|
27
12
|
const { data: carts } = await query.graph({
|
|
28
13
|
entity: "cart",
|
|
@@ -30,6 +15,7 @@ async function POST(req, res) {
|
|
|
30
15
|
"id",
|
|
31
16
|
"payment_collection.payment_sessions.id",
|
|
32
17
|
"payment_collection.payment_sessions.data",
|
|
18
|
+
"payment_collection.payment_sessions.status",
|
|
33
19
|
"payment_collection.payment_sessions.provider_id",
|
|
34
20
|
"payment_collection.payment_sessions.created_at",
|
|
35
21
|
"payment_collection.payment_sessions.amount",
|
|
@@ -44,16 +30,52 @@ async function POST(req, res) {
|
|
|
44
30
|
if (!session) {
|
|
45
31
|
return res.status(400).json({ error: "No PayPal payment session found for cart" });
|
|
46
32
|
}
|
|
47
|
-
//
|
|
33
|
+
// If already authorized or captured, nothing to do
|
|
34
|
+
const currentStatus = String(session.status || "");
|
|
35
|
+
if (currentStatus === "authorized" || currentStatus === "captured") {
|
|
36
|
+
console.info("[paypal-complete] session already in terminal status:", currentStatus);
|
|
37
|
+
return res.json({ success: true, session_id: session.id, status: currentStatus });
|
|
38
|
+
}
|
|
48
39
|
const paymentModule = req.scope.resolve(utils_1.Modules.PAYMENT);
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
});
|
|
56
|
-
|
|
40
|
+
// Read LIVE session data from DB — gets the latest state written by capture-order
|
|
41
|
+
// (avoids overwriting authorization_id / capture_id that capture-order just saved)
|
|
42
|
+
const [liveSession] = await paymentModule.listPaymentSessions({ id: [session.id] }, { take: 1 });
|
|
43
|
+
const liveData = (liveSession?.data || {});
|
|
44
|
+
// Determine payment action from settings
|
|
45
|
+
const paypal = req.scope.resolve("paypal_onboarding");
|
|
46
|
+
const settings = await paypal.getSettings().catch(() => ({}));
|
|
47
|
+
const settingsData = settings && typeof settings === "object" && "data" in settings
|
|
48
|
+
? (settings.data ?? {})
|
|
49
|
+
: {};
|
|
50
|
+
const additionalSettings = (settingsData.additional_settings || {});
|
|
51
|
+
const paymentAction = typeof additionalSettings.paymentAction === "string"
|
|
52
|
+
? additionalSettings.paymentAction
|
|
53
|
+
: "capture";
|
|
54
|
+
const timestampKey = paymentAction === "authorize" ? "authorized_at" : "captured_at";
|
|
55
|
+
// Only write timestamp if not already present — avoids overwriting capture-order's data
|
|
56
|
+
if (!liveData[timestampKey]) {
|
|
57
|
+
await paymentModule.updatePaymentSession({
|
|
58
|
+
id: session.id,
|
|
59
|
+
data: {
|
|
60
|
+
...liveData,
|
|
61
|
+
[timestampKey]: new Date().toISOString(),
|
|
62
|
+
},
|
|
63
|
+
amount: liveSession?.amount ?? session.amount,
|
|
64
|
+
currency_code: liveSession?.currency_code ?? session.currency_code,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
// Trigger Medusa's payment state machine — the only correct way to move
|
|
68
|
+
// a session from "pending" → "authorized".
|
|
69
|
+
// Calls the provider's authorizePayment() which checks for
|
|
70
|
+
// authorization_id / authorized_at in data and returns status: "authorized".
|
|
71
|
+
try {
|
|
72
|
+
await paymentModule.authorizePaymentSession(session.id, {});
|
|
73
|
+
console.info("[paypal-complete] authorizePaymentSession succeeded for session", session.id);
|
|
74
|
+
}
|
|
75
|
+
catch (e) {
|
|
76
|
+
// Throws if session is already authorized/captured — that's expected and fine
|
|
77
|
+
console.warn("[paypal-complete] authorizePaymentSession non-fatal:", e?.message);
|
|
78
|
+
}
|
|
57
79
|
return res.json({ success: true, session_id: session.id });
|
|
58
80
|
}
|
|
59
81
|
catch (e) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route.js","sourceRoot":"","sources":["../../../../../../src/api/store/paypal-complete/route.ts"],"names":[],"mappings":";;AAKA,
|
|
1
|
+
{"version":3,"file":"route.js","sourceRoot":"","sources":["../../../../../../src/api/store/paypal-complete/route.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paypal-webhook-retry.d.ts","sourceRoot":"","sources":["../../../../src/jobs/paypal-webhook-retry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAA;AAUhE,wBAA8B,kBAAkB,CAAC,SAAS,EAAE,eAAe,
|
|
1
|
+
{"version":3,"file":"paypal-webhook-retry.d.ts","sourceRoot":"","sources":["../../../../src/jobs/paypal-webhook-retry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAA;AAUhE,wBAA8B,kBAAkB,CAAC,SAAS,EAAE,eAAe,iBAqI1E;AAED,eAAO,MAAM,MAAM;;;CAGlB,CAAA"}
|