@goweekdays/core 2.5.0 → 2.6.0
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/CHANGELOG.md +6 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +49 -53
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +49 -53
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -1
package/dist/index.mjs
CHANGED
|
@@ -6355,6 +6355,9 @@ import {
|
|
|
6355
6355
|
CheckoutPaymentIntent,
|
|
6356
6356
|
OrderApplicationContextUserAction
|
|
6357
6357
|
} from "@paypal/paypal-server-sdk";
|
|
6358
|
+
import crypto3 from "crypto";
|
|
6359
|
+
import crc32 from "buffer-crc32";
|
|
6360
|
+
var certCache = /* @__PURE__ */ new Map();
|
|
6358
6361
|
function usePaypalService() {
|
|
6359
6362
|
const paypalClient = new Client({
|
|
6360
6363
|
clientCredentialsAuthCredentials: {
|
|
@@ -6396,61 +6399,42 @@ function usePaypalService() {
|
|
|
6396
6399
|
function captureOrder(id) {
|
|
6397
6400
|
return new OrdersController(paypalClient).captureOrder({ id });
|
|
6398
6401
|
}
|
|
6399
|
-
async function
|
|
6400
|
-
const
|
|
6401
|
-
|
|
6402
|
+
async function downloadAndCacheCert(url) {
|
|
6403
|
+
const cachedCert = certCache.get(url);
|
|
6404
|
+
if (cachedCert) {
|
|
6405
|
+
return cachedCert;
|
|
6406
|
+
}
|
|
6407
|
+
const response = await fetch(url);
|
|
6408
|
+
if (!response.ok) {
|
|
6409
|
+
throw new Error(
|
|
6410
|
+
`Failed to download PayPal certificate: ${response.statusText}`
|
|
6411
|
+
);
|
|
6412
|
+
}
|
|
6413
|
+
const certPem = await response.text();
|
|
6414
|
+
certCache.set(url, certPem);
|
|
6415
|
+
return certPem;
|
|
6416
|
+
}
|
|
6417
|
+
async function verifyWebhook(rawBody, headers, webhookId = PAYPAL_WEBHOOK_ID) {
|
|
6402
6418
|
const transmissionId = headers["paypal-transmission-id"];
|
|
6419
|
+
const timeStamp = headers["paypal-transmission-time"];
|
|
6420
|
+
const certUrl = headers["paypal-cert-url"];
|
|
6403
6421
|
const transmissionSig = headers["paypal-transmission-sig"];
|
|
6404
|
-
|
|
6405
|
-
|
|
6406
|
-
return {
|
|
6407
|
-
verified: false,
|
|
6408
|
-
verificationStatus: "FAILURE"
|
|
6409
|
-
};
|
|
6410
|
-
}
|
|
6411
|
-
const auth = Buffer.from(
|
|
6412
|
-
`${PAYPAL_CLIENT_ID}:${PAYPAL_CLIENT_SECRET}`
|
|
6413
|
-
).toString("base64");
|
|
6414
|
-
const tokenResponse = await fetch(`${PAYPAL_API_URL}/v1/oauth2/token`, {
|
|
6415
|
-
method: "POST",
|
|
6416
|
-
headers: {
|
|
6417
|
-
Authorization: `Basic ${auth}`,
|
|
6418
|
-
"Content-Type": "application/x-www-form-urlencoded"
|
|
6419
|
-
},
|
|
6420
|
-
body: "grant_type=client_credentials"
|
|
6421
|
-
});
|
|
6422
|
-
if (!tokenResponse.ok) {
|
|
6423
|
-
throw new Error("Failed to obtain PayPal access token");
|
|
6422
|
+
if (!transmissionId || !timeStamp || !certUrl || !transmissionSig) {
|
|
6423
|
+
return false;
|
|
6424
6424
|
}
|
|
6425
|
-
const
|
|
6426
|
-
const
|
|
6427
|
-
const
|
|
6428
|
-
|
|
6429
|
-
|
|
6430
|
-
|
|
6431
|
-
|
|
6432
|
-
|
|
6433
|
-
|
|
6434
|
-
|
|
6435
|
-
|
|
6436
|
-
|
|
6437
|
-
cert_url: certUrl,
|
|
6438
|
-
transmission_id: transmissionId,
|
|
6439
|
-
transmission_sig: transmissionSig,
|
|
6440
|
-
transmission_time: transmissionTime,
|
|
6441
|
-
webhook_id: webhookId,
|
|
6442
|
-
webhook_event: body
|
|
6443
|
-
})
|
|
6444
|
-
}
|
|
6445
|
-
);
|
|
6446
|
-
if (!verifyResponse.ok) {
|
|
6447
|
-
throw new Error("Failed to verify PayPal webhook signature");
|
|
6425
|
+
const eventBuffer = Buffer.isBuffer(rawBody) ? rawBody : Buffer.from(rawBody);
|
|
6426
|
+
const crcValue = parseInt("0x" + crc32(eventBuffer).toString("hex"));
|
|
6427
|
+
const message = `${transmissionId}|${timeStamp}|${webhookId}|${crcValue}`;
|
|
6428
|
+
try {
|
|
6429
|
+
const certPem = await downloadAndCacheCert(certUrl);
|
|
6430
|
+
const signatureBuffer = Buffer.from(transmissionSig, "base64");
|
|
6431
|
+
const verifier = crypto3.createVerify("SHA256");
|
|
6432
|
+
verifier.update(message);
|
|
6433
|
+
return verifier.verify(certPem, signatureBuffer);
|
|
6434
|
+
} catch (error) {
|
|
6435
|
+
console.error("PayPal webhook verification error:", error);
|
|
6436
|
+
throw new Error("Failed to verify PayPal webhook signature.");
|
|
6448
6437
|
}
|
|
6449
|
-
const verifyData = await verifyResponse.json();
|
|
6450
|
-
return {
|
|
6451
|
-
verified: verifyData.verification_status === "SUCCESS",
|
|
6452
|
-
verificationStatus: verifyData.verification_status
|
|
6453
|
-
};
|
|
6454
6438
|
}
|
|
6455
6439
|
return {
|
|
6456
6440
|
addOrder,
|
|
@@ -9873,9 +9857,21 @@ function useUtilController() {
|
|
|
9873
9857
|
}
|
|
9874
9858
|
}
|
|
9875
9859
|
}
|
|
9860
|
+
const { verifyWebhook } = usePaypalService();
|
|
9876
9861
|
async function paypalWebhook(req, res, next) {
|
|
9877
|
-
console.log(req
|
|
9878
|
-
|
|
9862
|
+
console.log(req);
|
|
9863
|
+
try {
|
|
9864
|
+
await verifyWebhook(req.body, req.headers, PAYPAL_WEBHOOK_ID);
|
|
9865
|
+
res.status(200).send("OK");
|
|
9866
|
+
return;
|
|
9867
|
+
} catch (error) {
|
|
9868
|
+
logger28.log({
|
|
9869
|
+
level: "error",
|
|
9870
|
+
message: "PayPal webhook verification failed"
|
|
9871
|
+
});
|
|
9872
|
+
res.status(400).send("Invalid webhook");
|
|
9873
|
+
return;
|
|
9874
|
+
}
|
|
9879
9875
|
}
|
|
9880
9876
|
return {
|
|
9881
9877
|
healthCheck,
|