Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
Hooks.Events.add("afterCoreInit", () => {
const currentMigrationVersion = Migrations._getControl().version;
const highestAvailableVersion = Migrations._list[Migrations._list.length - 1].version;
// Checks to ensure the app is running against a DB at the right migration state. Running the app
// with a wrong DB state will cause the app to malfunction
if (currentMigrationVersion > highestAvailableVersion) {
Logger.fatal(`You are running a Reaction install with migration version (${highestAvailableVersion}) below your current DB migration state (${currentMigrationVersion})`);
Logger.fatal(`Upgrade to a version of Reaction containing migration ${currentMigrationVersion} or higher.`);
Logger.fatal("If you really want to downgrade to this version, you should restore your DB to a previous state from your backup.");
process.exit(0);
} else if (!Meteor.isAppTest) {
try {
Migrations.migrateTo("latest");
} catch (error) {
Logger.error("Error while migrating", error);
// Make sure the migration control record is unlocked so they can attempt to run again next time
Migrations.unlock();
}
}
});
const { name } = payment;
const { canRefund, functions } = getPaymentMethodConfigByName(name);
if (!canRefund) throw new ReactionError("invalid", "Refunding not supported");
const context = Promise.await(getGraphQLContextInMeteorMethod(authUserId));
// Get total amount not yet refunded
const allRefundsBefore = Promise.await(functions.listRefunds(context, payment));
const refundTotalBefore = allRefundsBefore.reduce((sum, refund) => sum + refund.amount, 0);
const amountNotYetRefunded = payment.amount - refundTotalBefore;
const amountToRefund = Math.min(amountNotYetRefunded, amount);
const result = Promise.await(functions.createRefund(context, payment, amountToRefund));
if (!result.saved) {
Logger.fatal("Attempt to refund payment failed", order._id, paymentId, result.error);
throw new ReactionError("Attempt to refund payment failed", result.error);
}
// List refunds to see if we've now refunded the full amount of this payment
const allRefunds = Promise.await(functions.listRefunds(context, payment));
const refundTotal = allRefunds.reduce((sum, refund) => sum + refund.amount, 0);
// There could be JS math errors so we round to 3 decimal places when comparing
const isFullyRefunded = accounting.toFixed(refundTotal, 3) === accounting.toFixed(payment.amount, 3);
const updateResult = Orders.update(
{
"_id": orderId,
"payments._id": paymentId
},
{
"shipping.$.payment.metadata": metadata
},
$push: {
"shipping.$.payment.transactions": result
}
}
);
// event onOrderPaymentCaptured used for confirmation hooks
// ie: confirmShippingMethodForOrder is triggered here
Hooks.Events.run("onOrderPaymentCaptured", orderId);
return { error, result };
}
if (result && result.error) {
Logger.fatal("Failed to capture transaction.", order, transactionId, result.error);
} else {
Logger.fatal("Failed to capture transaction.", order, transactionId, error);
}
Orders.update(
{
"_id": orderId,
"shipping._id": groupId
},
{
$set: {
"shipping.$.payment.mode": "capture",
"shipping.$.payment.status": "error"
},
$push: {
"shipping.$.payment.transactions": result
$push: {
"billing.$.paymentMethod.transactions": result
}
}
);
// event onOrderPaymentCaptured used for confirmation hooks
// ie: confirmShippingMethodForOrder is triggered here
Hooks.Events.run("onOrderPaymentCaptured", orderId);
return { error, result };
}
if (result && result.error) {
Logger.fatal("Failed to capture transaction.", order, paymentMethod.transactionId, result.error);
} else {
Logger.fatal("Failed to capture transaction.", order, paymentMethod.transactionId, error);
}
Orders.update(
{
"_id": orderId,
"billing.paymentMethod.transactionId": transactionId
},
{
$set: {
"billing.$.paymentMethod.mode": "capture",
"billing.$.paymentMethod.status": "error"
},
$push: {
"billing.$.paymentMethod.transactions": result
}
}
}, (e) => {
Logger.fatal(e);
}));
return fut.wait();
response: refundResult
};
} else {
result = {
saved: false,
response: refundResult
};
Logger.warn("Stripe call succeeded but refund not issued");
}
} catch (error) {
Logger.error(error);
result = {
saved: false,
error: `Cannot issue refund: ${error.message}`
};
Logger.fatal("Stripe call failed, refund was not issued", error.message);
}
return result;
}
Meteor.call("orders/refunds/create", order._id, paymentId, Number(amount), false, (error, result) => {
if (error) {
Logger.fatal("Attempt for refund transaction failed", order._id, paymentId, error);
fut.return({
refund: false,
error
});
}
if (result) {
refundItems.forEach((refundItem) => {
orderQuantityAdjust(orderId, refundItem);
});
let refundedStatus = "refunded";
if (quantity < originalQuantity) {
refundedStatus = "partialRefund";
}
order._id,
paymentMethod.transactionId,
result.error
);
throw new Meteor.Error("Attempt to de-authorize transaction failed", result.error);
}
} else if (orderMode === "capture") {
result = Meteor.call(`${processor}/refund/create`, paymentMethod, amount);
query = {
$push: {
"billing.$.paymentMethod.transactions": result
}
};
if (result.saved === false) {
Logger.fatal("Attempt for refund transaction failed", order._id, paymentMethod.transactionId, result.error);
throw new Meteor.Error("Attempt to refund transaction failed", result.error);
}
}
Orders.update(
{
"_id": orderId,
"billing.shopId": Reaction.getShopId(),
"billing.paymentMethod.transactionId": transactionId
},
{
$set: {
"billing.$.paymentMethod.status": "refunded"
},
...query
}
amount: paymentMethod.amount
};
let result;
try {
const refundResult = PayflowproApi.apiCall.captureCharge(paymentCaptureDetails);
Logger.debug(refundResult);
result = refundResult;
} catch (error) {
Logger.error(error);
result = {
saved: false,
error: `Cannot Capture Payment: ${error.message}`
};
Logger.fatal("PayPal PayFlow call failed, payment was not captured");
}
return result;
}
response: refundResult
};
} else {
result = {
saved: false,
response: refundResult
};
Logger.warn("Stripe call succeeded but refund not issued");
}
} catch (error) {
Logger.error(error);
result = {
saved: false,
error: `Cannot issue refund: ${error.message}`
};
Logger.fatal("Stripe call failed, refund was not issued", error.message);
}
return result;
}