Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/meenalsingh0/GradGather/llms.txt

Use this file to discover all available pages before exploring further.

GradGather’s donation portal lets alumni turn goodwill into direct financial support for university clubs, scholarships, and social initiatives. The portal lists active campaigns at /donation, then routes contributors through a PayPal-powered checkout. The integration uses the paypal-rest-sdk and supports both sandbox testing and live production modes, controlled entirely through environment variables.

Donation Campaigns

The campaigns page is served at GET /donation and renders donation.hbs. Five campaigns are currently listed, each presented as a .donation-card with a title, a description, and a Donate Now button.
// src/index.js
app.get("/donation", (req, res) => {
  res.render("donation");
});

Hackhound Club Hackathon

Support the Hackhound Club in organizing the annual hackathon. Your donation will help cover event costs, participant swag, and more.

Green Earth Initiative

Contribute to environmental conservation with the Green Earth Initiative. Funds will be used for tree planting and waste reduction programs.

Literacy for All Campaign

Help improve literacy rates by supporting the Literacy for All Campaign. Donations will fund educational resources and training programs.

Tech for Kids Foundation

Support the Tech for Kids Foundation in providing technology and educational resources to underprivileged children.

Veterans Support Fund

Assist veterans in transitioning back to civilian life. Your donation will aid in job training and mental health services.
Clicking Donate Now on any campaign card calls the donate(eventName) JavaScript function, which logs the campaign name to the console and redirects the browser to /paymentGateway:
// tempelates/donation.hbs — donate button handler
function donate(eventName) {
  console.log("Donating to: " + eventName);
  window.location.href = "/paymentGateway";
}

Payment Flow

The full end-to-end PayPal payment sequence involves five routes spread across the front-end redirect and the PayPal REST API callbacks:
1

User clicks Donate Now

The donate(eventName) function is called with the campaign name. The browser is redirected to GET /paymentGateway.
2

Payment Gateway page rendered

/paymentGateway renders paymentGateway.hbs, which presents a form where the user enters an amount and selects a payment gateway (PayPal, Stripe, Razorpay, or PayU). Submitting the form sends a POST request to /pay.
The paymentGateway.hbs form displays four gateway options — PayPal, Stripe, Razorpay, and PayU — but paymentController.js only implements the PayPal flow. Selecting any other gateway and submitting the form will not produce a working checkout. Only the PayPal path is wired up end-to-end.
3

PayPal payment created

The POST /pay handler in paymentController.js calls paypal.payment.create() with the create_payment_json payload. On success, it iterates over the returned links and redirects the user to PayPal’s approval_url.
4

User approves on PayPal

The user logs in to their PayPal account (or guest checkout) and approves the payment. PayPal redirects back to the return_urlhttp://localhost:3000/success — appending PayerID and paymentId as query parameters.
5

Payment executed on success callback

GET /success calls paypal.payment.execute(paymentId, execute_payment_json) using the query parameters from PayPal. On a successful execution the success.hbs view is rendered.
6

Payment cancelled

If the user cancels on PayPal, they are redirected to GET /cancel, which renders the cancel.hbs view.

Routes Reference

MethodPathDescription
GET/donationDonation campaigns listing
GET/paymentGatewayPayPal checkout page
POST/payInitiate PayPal payment
GET/successPayment success callback
GET/cancelPayment cancel callback

PayPal Configuration

The paypal-rest-sdk is configured in src/controllers/paymentController.js using three environment variables:
// src/controllers/paymentController.js — PayPal configuration
const paypal = require('paypal-rest-sdk');

const { PAYPAL_MODE, PAYPAL_CLIENT_KEY, PAYPAL_SECRET_KEY } = process.env;

paypal.configure({
  'mode': PAYPAL_MODE,           // 'sandbox' or 'live'
  'client_id': PAYPAL_CLIENT_KEY,
  'client_secret': PAYPAL_SECRET_KEY
});
Environment VariableDescription
PAYPAL_MODEsandbox for testing, live for production
PAYPAL_CLIENT_KEYPayPal REST API Client ID
PAYPAL_SECRET_KEYPayPal REST API Secret Key
To obtain sandbox credentials, log in to the PayPal Developer Portal, navigate to My Apps & Credentials, and create a new app under the Sandbox tab. The portal provides a Client ID and Secret you can use directly in your .env file with PAYPAL_MODE=sandbox. Switch both the credentials and the mode to live when deploying to production.

Payment Payload

The create_payment_json object sent to paypal.payment.create() defines the payment intent, redirect URLs, item details, and total amount:
// src/controllers/paymentController.js — create_payment_json
const create_payment_json = {
  "intent": "sale",
  "payer": {
    "payment_method": "paypal"
  },
  "redirect_urls": {
    "return_url": "http://localhost:3000/success",
    "cancel_url": "http://localhost:3000/cancel"
  },
  "transactions": [{
    "item_list": {
      "items": [{
        "name": "Book",
        "sku": "001",
        "price": "25.00",
        "currency": "USD",
        "quantity": 1
      }]
    },
    "amount": {
      "currency": "USD",
      "total": "25.00"
    },
    "description": "Hat for the best team ever"
  }]
};
The payment amount is hardcoded to $25.00 USD in paymentController.js. For a production deployment, update the payProduct handler to read the amount from req.body.amount (which is already submitted by the paymentGateway.hbs form) and pass it dynamically into both the create_payment_json item price/total and the execute_payment_json total. Also update the item name and description fields to reflect the actual donation campaign selected.
The success callback constructs its own execute_payment_json using the PayerID returned by PayPal and the same hardcoded total:
// src/controllers/paymentController.js — execute_payment_json
const execute_payment_json = {
  "payer_id": payerId,
  "transactions": [{
    "amount": {
      "currency": "USD",
      "total": "25.00"
    }
  }]
};

paypal.payment.execute(paymentId, execute_payment_json, function (error, payment) {
  if (error) {
    console.log(error.response);
    throw error;
  } else {
    console.log(JSON.stringify(payment));
    res.render('success');
  }
});

Build docs developers (and LLMs) love