Skip to content

add payment project integration#1994

Merged
adarshm11 merged 26 commits into
devfrom
pending-payment
Jan 27, 2026
Merged

add payment project integration#1994
adarshm11 merged 26 commits into
devfrom
pending-payment

Conversation

@tiffany-tran07

@tiffany-tran07 tiffany-tran07 commented Jan 6, 2026

Copy link
Copy Markdown
Contributor

for issue #1965

Comment thread api/main_endpoints/models/MembershipPayment.js
Comment thread api/main_endpoints/models/MembershipPayment.js Outdated
Co-authored-by: adarsh <110150037+adarshm11@users.noreply.github.com>
Comment thread api/main_endpoints/models/MembershipPayment.js Outdated
Comment thread api/main_endpoints/models/MembershipPayment.js Outdated
Comment thread api/main_endpoints/models/MembershipPayment.js Outdated

@charred-70 charred-70 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm tuffany is also my hero

* initial commit

* fixed spacing

* fixed spacing 2

* fixed spacing 2

* updated logic and merged find and Verify functions

* fix spacing

* refactor: improve payment verification and rejection logic

* fix

* refactor: improve error handling in membership payment verification and rejection

* fix

* final fixes

* final fixes

* refactored updateMembershipExpiration

* fix spacing
@adarshm11 adarshm11 changed the title added membership payment schema added membership payment validation Jan 7, 2026
* i pray i fixed my origin

* added instructions

* fixed import error

* fixed template formatting

* made function to call email route

---------

Co-authored-by: Charlynn Nguyen <charred@Charlynns-MacBook-Pro.local>
@adarshm11 adarshm11 changed the title added membership payment validation add payment project integration Jan 15, 2026

@evanugarte evanugarte left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we split this into 3 prs

  1. the changes to the email code
  2. backend changes
  3. react changes

return resolve({
from: user,
to: recipient,
subject: 'SCE Membership Confirmation',

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we put the code in the subject too

Your SCE Membership Code is ...

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment on lines +7 to +10
createdAt: {
type: Date,
default: Date.now
},

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does mongodb already store this field? this might work

const mySchema = new mongoose.Schema({
  name: String,
  // other fields...
}, {
  timestamps: true
});

Comment thread api/main_endpoints/util/membershipPaymentQueries.js
Comment on lines +49 to +61
if (amount < 20){
const rejected = await rejectPayment(paymentId);
if (rejected === null){
logger.error('Error rejecting payment with ID:', paymentId);
return res.status(SERVER_ERROR).send('Error rejecting payment.');
}
if (rejected === false){
logger.error('No payment found to reject with ID:', paymentId);
return res.status(NOT_FOUND).send('No payment found to reject.');
}
logger.info('Payment rejected due to insufficient amount. Payment ID:', paymentId);
return res.status(BAD_REQUEST).send('Payment amount insufficient.');
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we dont need this

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


const confirmationCode = crypto.randomBytes(4).toString('hex').toUpperCase();
const newPayment = {
userId: null,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
userId: null,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment thread api/main_endpoints/util/emailHelpers.js Outdated
Comment on lines +43 to +49
async function membershipConfirmationCode(confirmCode, email) {
return new Promise((resolve) => {
axios
.post(`${MAILER_API_URL}/Mailer/sendMembershipConfirmationCode`, {
recipientEmail: email,
confirmationCode: confirmCode
})

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
async function membershipConfirmationCode(confirmCode, email) {
return new Promise((resolve) => {
axios
.post(`${MAILER_API_URL}/Mailer/sendMembershipConfirmationCode`, {
recipientEmail: email,
confirmationCode: confirmCode
})
async function membershipConfirmationCode(confirmationCode, recipientEmail) {
return new Promise((resolve) => {
axios
.post(`${MAILER_API_URL}/Mailer/sendMembershipConfirmationCode`, {
recipientEmail,
confirmationCode,
})

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment on lines +22 to +29
router.post('/verifyMembership', async (req, res) => {
const decoded = await decodeToken(req, membershipState.PENDING);
if (decoded.status !== OK) {
return res.sendStatus(decoded.status);
}

const { confirmationCode } = req.body;
const userId = decoded.token._id;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we rate limit this by user email, we dont have to solve that rn, just open an issue like using the decoded email from the token, if theres more than 5 requests in the past 30 min, send 429 or something

const [confirmationCode, setConfirmationCode] = useState('');
const { user } = useSCE();

const INPUT_CLASS_NAME = 'indent-2 block w-full rounded-md border-0 py-1.5 bg-white text-black shadow-sm ring-1 ring-inset ring-gray-300 placeholder-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6';

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move this above the function

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

confirmationCode,
);
if (apiResponse.error) {
bannerCallback('Unable to verify membership. Please try again later.');

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

include the http code in the title? in case they take a screenshot and post in the discord?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

bannerCallback('Unable to verify membership. Please try again later.');
return;
}
bannerCallback('Congrats, you confirmed your membership!');

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we add the date like

you are now a member (expiration DATE_GOES_HERE)

like could the api return the date that the expiration is, if the code worked

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

expiration date already shows on their profile when membership is confirmed vro

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as soon as the modal closes, is the profile page updated or do they need to refresh

Comment on lines +28 to +50
<dialog id="verify-membership-modal" className="modal modal-bottom sm:modal-middle">
<div className="modal-box">
<h3 className="font-bold text-lg">Verify Membership</h3>
{accessLevel > 0 ? (
<>
<p className="text-sm text-gray-500 mt-2">
You are already verified!!!
</p>
<div className="modal-action">
<form method="dialog">
<div className="px-4 py-3 sm:flex sm:flex-row-reverse sm:px-6">
<button
className="btn inline-flex w-full justify-center rounded-md px-3 py-2 text-sm font-semibold shadow-sm ring-1 ring-inset sm:w-auto"
>
Close
</button>
</div>
</form>
</div>
</>
) : (
<>
<p className="text-sm text-gray-500 mt-2">

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (something) {

return dialog_goes_here
}

return p_class_etc_goes_here

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

holy nitpick ✌️

const { findVerifyPayment, storePayment } = require('../util/membershipPaymentQueries.js');
const { decodeToken } = require('../util/token-functions.js');
const { membershipPayment = {} } = require('../../config/config.json');
const { API_KEY = 'TUFFANYCHAR' } = membershipPayment;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

be sure to update config example json to include this field

Comment on lines +82 to +83
if (amount < 20) {
return res.status(BAD_REQUEST).send('Payment amount must be at least $20.');

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we dont need this? like the validation should happen before we call this api

we should assume that an incoming request with a valid api key means we are trying to store a payment of the correct amount

Comment thread api/main_endpoints/util/userHelpers.js Outdated
return true;
} catch (error) {
logger.error('Error updating membership:', error);
return null;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets return false instead of null

true if worked, false if didnt work for any reason

return resolve({
from: user,
to: recipient,
subject: 'SCE Membership Confirmation: Your SCE Membership Code Is...',

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i meant like put the code in the subject

sorry that wasnt clear

Suggested change
subject: 'SCE Membership Confirmation: Your SCE Membership Code Is...',
subject: `Your SCE Membership Code Is ${confirmCode}`,

bannerCallback('Unable to verify membership. Please try again later.');
return;
}
bannerCallback('Congrats, you confirmed your membership!');

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as soon as the modal closes, is the profile page updated or do they need to refresh

}

function modalContent() {
if (accessLevel > 0) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use the membership state enum in

const membershipState = {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also how about we dont even show the modal button if the user is a valid member?

what do you think

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good idea mr evan ugarte ❤️‍🩹

@adarshm11
adarshm11 merged commit 5758b5b into dev Jan 27, 2026
4 checks passed
@adarshm11
adarshm11 deleted the pending-payment branch January 27, 2026 00:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants