mirror of
https://github.com/rgrgogu/new_starr.git
synced 2026-09-27 00:12:54 +08:00
purchase / checkout flow
Signed-off-by: Kenneth Obsequio <k80308392@gmail.com>
This commit is contained in:
@@ -76,13 +76,17 @@ exports.captureCourseOrder = async (req, res) => {
|
||||
const { order_id } = req.body;
|
||||
if (!order_id) return R.error(res, 'order_id is required.', 400);
|
||||
|
||||
const purchase = await mdl_CoursePurchase.findOne({
|
||||
// Matched on provider_payload.order_id, not just "most recent pending" —
|
||||
// see tiers.controller.js#captureOrder for why picking by recency alone
|
||||
// can miss an older order that PayPal legitimately approved.
|
||||
const pendingPurchases = await mdl_CoursePurchase.findAll({
|
||||
where: { user_id: req.user.user_id, status: 'pending' },
|
||||
include: [{ model: mdl_Product, as: 'product' }],
|
||||
order: [['createdAt', 'DESC']],
|
||||
});
|
||||
const purchase = pendingPurchases.find((p) => p.provider_payload?.order_id === order_id);
|
||||
|
||||
if (!purchase || purchase.provider_payload?.order_id !== order_id)
|
||||
if (!purchase)
|
||||
return R.error(res, 'Pending purchase not found.', 404);
|
||||
|
||||
let captureData;
|
||||
@@ -144,12 +148,14 @@ exports.cancelCourseOrder = async (req, res) => {
|
||||
const { order_id } = req.body;
|
||||
if (!order_id) return R.error(res, 'order_id is required.', 400);
|
||||
|
||||
const purchase = await mdl_CoursePurchase.findOne({
|
||||
// See captureCourseOrder above for why this matches on order_id instead of recency.
|
||||
const pendingPurchases = await mdl_CoursePurchase.findAll({
|
||||
where: { user_id: req.user.user_id, status: 'pending' },
|
||||
order: [['createdAt', 'DESC']],
|
||||
});
|
||||
const purchase = pendingPurchases.find((p) => p.provider_payload?.order_id === order_id);
|
||||
|
||||
if (!purchase || purchase.provider_payload?.order_id !== order_id)
|
||||
if (!purchase)
|
||||
return R.error(res, 'Pending purchase not found.', 404);
|
||||
|
||||
await purchase.update({
|
||||
|
||||
@@ -310,13 +310,19 @@ exports.captureOrder = async (req, res) => {
|
||||
const { order_id } = req.body;
|
||||
if (!order_id) return R.error(res, 'order_id is required.', 400);
|
||||
|
||||
const payment = await mdl_Payments.findOne({
|
||||
// Matched on provider_payload.order_id, not just "most recent pending" —
|
||||
// a user can have more than one pending payment at once (e.g. abandoned
|
||||
// Plan A via browser-back instead of PayPal's cancel button, then started
|
||||
// checkout on Plan B); picking by recency would miss an older order that
|
||||
// PayPal legitimately approved.
|
||||
const pendingPayments = await mdl_Payments.findAll({
|
||||
where: { status: 'pending', user_id: req.user.user_id },
|
||||
include: [{ model: mdl_TierPlans, as: 'plan' }],
|
||||
order: [['createdAt', 'DESC']],
|
||||
});
|
||||
const payment = pendingPayments.find((p) => p.provider_payload?.order_id === order_id);
|
||||
|
||||
if (!payment || payment.provider_payload?.order_id !== order_id)
|
||||
if (!payment)
|
||||
return R.error(res, 'Pending payment not found.', 404);
|
||||
|
||||
// Guard: plan was deactivated while user was on PayPal's approval page
|
||||
@@ -433,12 +439,14 @@ exports.cancelOrder = async (req, res) => {
|
||||
const { order_id } = req.body;
|
||||
if (!order_id) return R.error(res, 'order_id is required.', 400);
|
||||
|
||||
const payment = await mdl_Payments.findOne({
|
||||
// See captureOrder above for why this matches on order_id instead of recency.
|
||||
const pendingPayments = await mdl_Payments.findAll({
|
||||
where: { user_id: req.user.user_id, status: 'pending' },
|
||||
order: [['createdAt', 'DESC']],
|
||||
});
|
||||
const payment = pendingPayments.find((p) => p.provider_payload?.order_id === order_id);
|
||||
|
||||
if (!payment || payment.provider_payload?.order_id !== order_id)
|
||||
if (!payment)
|
||||
return R.error(res, 'Pending payment not found.', 404);
|
||||
|
||||
await payment.update({
|
||||
|
||||
Reference in New Issue
Block a user