Skip to content

Donor Endpoints

Donor endpoints serve the miranda.gives portal. They require Supabase authentication with the donor role in the JWT’s app_metadata.roles.

All endpoints are prefixed with /api/donor and use the middleware stack: auth.supabase:relaxed, role:donor.

Donors authenticate via Supabase and must have "donor" in their JWT app_metadata.roles array:

Terminal window
curl -X GET https://app.miranda.foundation/api/donor/profile \
-H "Authorization: Bearer {supabase_jwt_with_donor_role}"
MethodPathDescription
GET/donor/impactGet the donor’s impact summary

Returns aggregate giving data across all foundations the donor supports.

MethodPathDescription
GET/donor/donationsList the donor’s donation history
POST/donor/donationsMake a new donation

Creates a donation through the DonationService::processDonorDonation() flow:

{
"foundation_id": "uuid",
"amount": 50.00,
"payment_method_id": "pm_abc123",
"save_payment_method": true,
"donor_covers_fees": false,
"donation_page_id": "uuid"
}

Returns:

{
"donation": { "id": "uuid", "amount": 5000, "status": "pending", ... },
"client_secret": "pi_xxx_secret_yyy",
"status": "requires_confirmation"
}

The client_secret is used by Stripe.js on the frontend to confirm the payment if the PaymentIntent requires further action.

MethodPathDescription
GET/donor/foundationsList foundations the donor supports

Returns all foundations where the donor has a DonorFoundationLink, including giving stats per foundation.

MethodPathDescription
GET/donor/recurringList active recurring subscriptions
PATCH/donor/recurring/{id}Update a recurring donation (amount, interval, pause, cancel)
MethodPathDescription
GET/donor/newslettersList newsletter subscriptions across foundations
PATCH/donor/newsletters/{foundationId}Update newsletter preferences for a foundation
MethodPathDescription
GET/donor/profileGet donor profile
PATCH/donor/profileUpdate donor profile
MethodPathDescription
GET/donor/payment-methodsList saved payment methods
POST/donor/payment-methodsSave a new payment method
DELETE/donor/payment-methods/{id}Remove a payment method

Returns saved cards from the donor’s platform Stripe Customer:

[
{
"id": "pm_abc123",
"brand": "visa",
"last4": "4242",
"exp_month": 12,
"exp_year": 2027
}
]

Payment methods are stored on Miranda’s platform Stripe account (not on individual foundation connected accounts), so donors can use saved cards across any foundation.

MethodPathDescription
POST/donor/applicationsSubmit a scholarship application

Donors can submit applications to any scholarship that is in accepting status.

The donor portal uses a two-layer Stripe model:

  1. Layer 1 (Platform): The donor’s Stripe Customer lives on Miranda’s platform account. Payment methods are attached here.
  2. Layer 2 (Destination): When a donation is made, a PaymentIntent is created on the platform account with transfer_data.destination routing funds to the foundation’s connected account.

This means:

  • Donors manage one set of payment methods across all foundations
  • Each foundation receives funds directly in their connected Stripe account
  • Miranda collects the platform fee via application_fee_amount