Gradeful
CoursesPricingAbout

How Gradeful connects

Raw markdown

Checkout

Live path is Whish. Homepage/pricing CTAs go to /checkout?plan=. How this grants user_access and lands on dashboard: 00-how-everything-connects.md.

Plans (source lib/payments/catalog.ts; live overlays via getPaymentPlans() apply to homepage, pricing, and checkout charges):

URL slugNamePriceCoursesDays
focusFocus$101120
balanceBalance$172120
fullloadFull Load$25up to 6120
crunchCrunch$14up to 421

PAGE: /checkout Purpose: Pick courses, collect details, start Whish payment. Access: logged-in. Missing/invalid ?plan= → /pricing. No session → /login?next=/checkout?plan=…. Entry points: Homepage Get Focus / Get Balance / Cover my semester / Prep for Finals; pricing same labels; course detail Get access → with &course={courses.id}; payment failure Return to checkout.

SECTION: Header Copy: Logo alt Gradeful Data shown: static

ELEMENT: Gradeful (logo) Action: navigate Destination: / Writes to: none Reads from: none

ELEMENT: Contact us Action: navigate Destination: /contact Writes to: none Reads from: none

ELEMENT: Back to plans Action: navigate Destination: /pricing Writes to: none Reads from: none

SECTION: Step indicator Copy: Your course Your details Payment Data shown: current step (1–2 in UI; payment is Whish, not a third in-app step)

SECTION: Step 1 — course picker Copy by plan: coursePickerCopy in lib/payments/catalog.ts Focus: Which course do you need? You're getting 1 course — choose the one you need most. Balance: Which courses do you need? You're getting 2 courses — pick them now. Full Load: Which courses are you taking? Pick up to 6 courses. The plan covers what you select — not the whole catalog. Crunch: Which courses are you sitting? Pick up to 4 exam courses. You don't need to upload a schedule. Search placeholder: Search by code — e.g. MATH201 Status: Loading courses… No courses found. Courses couldn't be loaded. Refresh and try again. Data shown: courses (is_active=true) with course_packs and universities; optional initialCourseId from ?course=

ELEMENT: Search by code (input) Action: toggle Destination: none (filters list) Writes to: none Reads from: courses.code, courses.title

ELEMENT: Selected course chip (code + remove) Action: toggle Destination: none (deselect) Writes to: none Reads from: courses.code

ELEMENT: Course row (university, code, optional {n} cr, title) Action: toggle Destination: none (select/deselect) Writes to: none Reads from: courses.*, universities.short_name, credit hours on the course Client limits: You can only pick 1 course on Focus You can only pick 2 courses on Balance You can pick up to {n} courses.

ELEMENT: Try again Action: toggle Destination: none (reload courses) Writes to: none Reads from: visible when load failed

ELEMENT: Continue Action: toggle Destination: step 2 Writes to: none (client state + sessionStorage gradeful.checkout.plan) Reads from: selection validity

SECTION: Step 2 — details Copy: Order summary shows plan name, included line, price, duration, selected courses. Empty No courses selected. No registered-credits or screenshot fields. Included lines: Focus 1 course · all content types /1 course Full semester · 120 days; Balance 2 courses · all content types /2 courses; Full Load / Crunch The courses you pick · all content types /your courses; Crunch duration 21-day sprint. Fields: Full name placeholder Your name (prefilled from profile, editable, does not write profiles); Signed-in email readonly This is the email on your Gradeful account. It can't be changed here. empty No email on this account; University hidden/read-only when profile already has AUB/LAU, else Select university / AUB / LAU / Other; WhatsApp (optional) +961 XX XXX XXX Optional, for account support. Payment uses the phone you enter on Whish.; institution email hidden when login already matches campus, else shown for receipt; checkbox personal tutoring-access sentence plus CHECKOUT_INDEPENDENCE_ACK. Footnote: You'll continue to a secure payment page to complete the purchase. Need help? Data shown: Auth email; selected courses; PLANS price

ELEMENT: Change courses Action: toggle Destination: step 1 Writes to: none Reads from: none

ELEMENT: Full name Action: toggle Destination: none Writes to: orders.name Reads from: none Error: Full name is required.

ELEMENT: Signed-in email (readonly) Action: none Destination: none Writes to: none Reads from: Auth email Error: Sign in to continue checkout.

ELEMENT: University Action: toggle Destination: none Writes to: orders.university Reads from: none Error: Select your university.

ELEMENT: WhatsApp number Action: toggle Destination: none Writes to: orders.whatsapp Reads from: none Error: WhatsApp number is required.

ELEMENT: Your uni email Action: toggle Destination: none Writes to: orders.email (this is the uni email, not Auth email) Reads from: none Errors: Your uni email is required. Use a university email ending in .edu.

ELEMENT: I understand this material is for personal study only... Action: toggle Destination: none Writes to: none (must be true to submit) Reads from: none Error: You must agree to continue.

ELEMENT: Continue to secure payment / Preparing secure payment… Action: submit Destination: Whish collectUrl (window.location.assign) Writes to: orders via POST /api/payments/whish/create (user_id, name, email, university, plan, course_ids, registered_credits null, whatsapp, status=pending, payment_provider=whish, payment_status=pending, external_id, amount from live plan, currency=USD, collect_url, provider_metadata.durationDays, provider_metadata.catalogPrice) Reads from: form + Auth session Errors: An order was already submitted recently. Please wait and try again. Checkout is temporarily unavailable. Please try again shortly. Payment could not be started. Please try again. Unable to connect. Please check your connection. plus server error ≤160 chars. 401 → login with checkout next.

ELEMENT: Contact us Action: navigate Destination: /contact Writes to: none Reads from: none

API errors from create (also shown when returned): Sign in to continue checkout. Invalid request. Checkout details are incomplete. Use your AUB or LAU email for this payment. It is not your login. Selected courses are not available. One or more selected courses are not available for purchase. You already have access to those courses. Open them from My courses instead of paying again. Order could not be created. Try again. Something went wrong. Please try again. Entitlement: Remove duplicate courses and try again. Select at least one course for this plan. Select 1 course for this plan. Select {n} courses for this plan. You can pick up to {n} courses.


PAGE: /checkout/payment/success Purpose: Return from Whish; poll until paid/failed/timeout. Arriving here does not mean paid by itself. Access: logged-in (else login with next = this URL). Query orderId (UUID). Entry points: Whish redirect after collect.

SECTION: PaymentReturnStatus (variant success) Copy by state: invalid-order: We couldn't find that payment Open checkout again from your plan, or return to pricing to start over. paid: Payment confirmed Access is ready. You can open your courses now. Reference {8-char} failed: Payment wasn't completed No access was granted. You can try payment again, or return to checkout to start over. pending: We're confirming your payment Whish is still processing your payment. Keep this page open. If you haven't finished paying, you can return to Whish. This is not a failed payment. unavailable (timeout): We couldn't confirm the payment yet We haven't confirmed this payment yet. That doesn't mean it failed. If you already paid, wait a minute and refresh, or contact support. If you haven't finished on Whish, you can continue there. unavailable (other): We could not verify your payment right now. That doesn't mean it failed. Continue on Whish if you still need to pay, or contact support if you were charged. checking: Checking payment status Hang tight — we're verifying with the payment provider. Hint: Arriving here doesn't confirm payment by itself — we verify status securely. Data shown: GET /api/payments/whish/status?orderId= → orders; reconcile may write user_access

ELEMENT: Return to pricing Action: navigate Destination: /pricing Writes to: none Reads from: none

ELEMENT: Go to my courses Action: navigate Destination: /dashboard Writes to: none Reads from: shown when accessGranted / paid

ELEMENT: Continue payment on Whish Action: external link Destination: Whish collectUrl / resumePaymentUrl Writes to: none Reads from: orders.collect_url

ELEMENT: Return to checkout Action: navigate Destination: /checkout with remembered plan Writes to: none Reads from: sessionStorage plan

ELEMENT: Contact Whish support Action: external link Destination: https://www.whish.money/contact-us Writes to: none Reads from: none

Poll may call reconcileWhishOrder → grantAccess → user_access. New grants do not insert schedule_verifications.


PAGE: /checkout/payment/failure Purpose: Same status poll as success; copy hint differs. Access: logged-in Entry points: Whish failure redirect.

SECTION: PaymentReturnStatus (variant failure) Copy: Same state machine as success. Hint: Arriving here doesn't mean the payment permanently failed — we verify status securely. Data shown: same as success ELEMENT: same buttons as /checkout/payment/success

Gradeful

Course-specific study packs for AUB and LAU students. Built for focused self-study.

Gradeful is an independent study-support service. Universities named on this site are listed only so you can match a Gradeful pack to the course you are taking. Those universities do not provide, sponsor, or endorse Gradeful, and Gradeful does not claim access to their official materials or assessments.

© 2026 Gradeful.

Platform

HomeCoursesPricing

Policies

Privacy PolicyTerms of ServiceRefund PolicyAcademic Integrity