Skip to main content

Public Donation Page

Public Donation Page

Component Files: src/features/events/components/PublicDonationPage.tsx, src/features/donors/components/DonorLandingPage.tsx, src/features/donors/components/DonorLandingEmbeddedCheckout.tsx Canonical Route: https://donate.alignmint.app/{org-key-or-prefix}/{nonprofit-slug}/{page-slug} Access Level: Public Last Updated: July 24, 2026

Overview

This is the live donor-facing route for custom giving pages. It loads a published donor_pages record, resolves organization and Stripe state, renders the donation experience, and initializes payment through the create-payment-intent edge function.

Page Resolution

Primary load path: 1. Parse org-key-or-prefix, nonprofit-slug, and page-slug 2. Call get-public-donation-page 3. Build a DonorLandingPageConfig 4. Render the public donation page

Fallback path: 1. Call fetchDonorPageBySlug 2. Load stats, Stripe state, and admin contact info client-side 3. Build the same DonorLandingPageConfig

Availability rules

  • only published pages resolve
  • inactive organizations are blocked by both the public edge function and the fallback slug query
  • ambiguous slug matches return an explicit error instead of guessing

Payment Flow

The live flow uses embedded Stripe PaymentElement, not a new-tab Stripe Checkout redirect.

1. Donor selects an amount 2. Donor can choose one-time or monthly recurring giving 3. Donor can optionally cover processing fees 4. The page calls create-payment-intent 5. DonorLandingEmbeddedCheckout lazy-loads Stripe React components once a clientSecret exists 6. Payment completes inline 7. Webhooks create the donation record and downstream bookkeeping side effects

Inactive fund enforcement

  • create-payment-intent and create-checkout-session reject inactive organizations (inactive_org_blocked)
  • stripe-webhook donation insert paths skip non-active orgs
  • database trigger donations_block_inactive_org_writes rejects any direct donation insert for inactive orgs

Purpose / Fund Attribution

  • organizationId must be the real organization UUID
  • purposeId is optional and flows into payment-intent metadata
  • the public config uses organization_id from the donor page record, not the donor page id

Media Rules

  • Hero images render as images
  • Hero videos from YouTube / Vimeo / VideoBlast render as embeds
  • Uploaded media files now render with a native <video> player instead of an iframe

Embed Mode

URL format

https://donate.alignmint.app/{org-key-or-prefix}/{nonprofit-slug}/{page-slug}?embed=true

Current embed behavior

  • transparent page background
  • postMessage height updates from the child iframe
  • optional color customization via URL params
  • recurring giving and purpose selectors supported
  • Stripe remains embedded inline

Recommended host listener

window.addEventListener('message', (e) => {
  if (e.data?.type === 'alignmint-donation-resize') {
    const iframe = document.querySelector('iframe[src*="donate.alignmint.app"]');
    if (iframe) {
      iframe.style.height = `${e.data.height}px`;
    }
  }
});

The generated embed snippet from the manager also includes:

  • allow="payment *; publickey-credentials-get *"

Performance Notes

  • main.tsx does not eagerly load the authenticated app shell for /donate/*
  • Stripe React components are lazy-loaded only when the donor opens the payment step
  • the edge function path replaces several client-side round trips on first load

Donor-Facing Error States

  • invalid URL
  • page not found / unavailable
  • ambiguous URL
  • failed page load
  • Stripe not connected for the target org

The public route now uses less misleading titles for load failures versus unavailable pages.

Related Files

  • src/lib/db/marketing.ts
  • supabase/functions/get-public-donation-page/index.ts
  • supabase/functions/create-payment-intent/index.ts
  • src/lib/donorPageUrls.ts

Related Documentation


Synced from IFMmvp-Frontend documentation: pages/donor-hub/10-PUBLIC-DONATION-PAGE.md

Ready to Get Started?

See how Alignmint can simplify your nonprofit's operations. Schedule a free demo with our team and we'll walk you through everything.

Questions? Email us at steven@getalignmint.org

Ready to get started?Start Plus Trial