Normalize user-facing payment method to cash/card/eft/voucher
Per feedback, stop trying to surface every gateway-reported wallet type (apple_pay, google_pay, yoco, ...) as its own filter/display value on the user payment history page. Both /mypayments and /mypayments/methods now fold anything outside the four manual-entry methods into "card", both in the returned data and in the filter query, so Apple Pay/Google Pay payments show up under Card. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -349,6 +349,17 @@ const getPayments = async (req, res) => {
|
||||
}
|
||||
};
|
||||
|
||||
// Payment.method is free-text — online checkouts get tagged with whatever wallet type the
|
||||
// gateway reports (apple_pay, google_pay, yoco, ...), not just the manual-entry methods below.
|
||||
// For the user-facing dashboard we don't want to expose every raw gateway string, so anything
|
||||
// that isn't one of the methods staff can manually choose is just shown/filtered as "card".
|
||||
const USER_FACING_METHODS = ['cash', 'card', 'eft', 'voucher'];
|
||||
|
||||
function normalizeUserMethod(method) {
|
||||
const m = String(method || '').toLowerCase();
|
||||
return USER_FACING_METHODS.includes(m) ? m : 'card';
|
||||
}
|
||||
|
||||
// @desc Get user payments (paginated, excludes donations, supports date range/method/kind filters)
|
||||
// @route GET /api/payments/mypayments
|
||||
// @access Private
|
||||
@@ -369,7 +380,17 @@ const getUserPayments = async (req, res) => {
|
||||
};
|
||||
|
||||
if (req.query.method) {
|
||||
where.method = { equals: String(req.query.method), mode: 'insensitive' };
|
||||
const requested = normalizeUserMethod(req.query.method);
|
||||
if (requested === 'card') {
|
||||
// "Card" also covers every gateway-reported method that isn't one of the other
|
||||
// explicit buckets (apple_pay, google_pay, yoco, etc.) — match anything NOT in those.
|
||||
where.NOT = {
|
||||
OR: USER_FACING_METHODS.filter(m => m !== 'card')
|
||||
.map(m => ({ method: { equals: m, mode: 'insensitive' } }))
|
||||
};
|
||||
} else {
|
||||
where.method = { equals: requested, mode: 'insensitive' };
|
||||
}
|
||||
}
|
||||
|
||||
if (req.query.kind === 'refund') {
|
||||
@@ -399,15 +420,18 @@ const getUserPayments = async (req, res) => {
|
||||
prisma.payment.count({ where })
|
||||
]);
|
||||
|
||||
res.json({ data: payments, total, page, limit, pages: Math.ceil(total / limit) });
|
||||
// Normalize the displayed method so the dashboard never shows a raw gateway string.
|
||||
const normalizedPayments = payments.map(p => ({ ...p, method: normalizeUserMethod(p.method) }));
|
||||
|
||||
res.json({ data: normalizedPayments, total, page, limit, pages: Math.ceil(total / limit) });
|
||||
} catch (error) {
|
||||
res.status(res.statusCode === 200 ? 400 : res.statusCode).json({ message: safeErrorMessage(error) });
|
||||
}
|
||||
};
|
||||
|
||||
// @desc Get the distinct payment methods actually present in the user's own payments,
|
||||
// so the dashboard filter never has to guess at gateway-reported values
|
||||
// (e.g. apple_pay, google_pay) — it only ever offers what's really there.
|
||||
// @desc Get the payment method options actually present in the user's own payments (normalized
|
||||
// to the user-facing set — see normalizeUserMethod), so the dashboard filter only ever
|
||||
// offers methods that exist for this user.
|
||||
// @route GET /api/payments/mypayments/methods
|
||||
// @access Private
|
||||
const getUserPaymentMethods = async (req, res) => {
|
||||
@@ -422,11 +446,13 @@ const getUserPaymentMethods = async (req, res) => {
|
||||
]
|
||||
},
|
||||
distinct: ['method'],
|
||||
select: { method: true },
|
||||
orderBy: { method: 'asc' }
|
||||
select: { method: true }
|
||||
});
|
||||
|
||||
res.json({ methods: rows.map(r => r.method).filter(Boolean) });
|
||||
const present = new Set(rows.map(r => normalizeUserMethod(r.method)));
|
||||
const methods = USER_FACING_METHODS.filter(m => present.has(m));
|
||||
|
||||
res.json({ methods });
|
||||
} catch (error) {
|
||||
res.status(res.statusCode === 200 ? 400 : res.statusCode).json({ message: safeErrorMessage(error) });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user