---
title: "Building a Donor Engagement Agent: Donation Processing, Receipts, and Thank-You Messages"
description: "Learn how to build an AI agent that processes donations, generates tax-deductible receipts, sends personalized thank-you messages, and manages recurring giving programs for nonprofits."
canonical: https://callsphere.ai/blog/building-donor-engagement-agent-donation-processing-receipts-thank-you
category: "Learn Agentic AI"
tags: ["Nonprofit AI", "Donor Management", "Payment Integration", "Agentic AI", "Python"]
author: "CallSphere Team"
published: 2026-03-17T00:00:00.000Z
updated: 2026-05-06T01:02:44.951Z
---

# Building a Donor Engagement Agent: Donation Processing, Receipts, and Thank-You Messages

> Learn how to build an AI agent that processes donations, generates tax-deductible receipts, sends personalized thank-you messages, and manages recurring giving programs for nonprofits.

## Why Donor Engagement Needs an Agentic Approach

Nonprofits live and die by their donor relationships. A first-time donor who receives a generic confirmation email is far less likely to give again than one who receives a timely, personalized acknowledgment that connects their gift to a specific impact. Yet most small nonprofits lack the staff to deliver that level of engagement consistently.

An AI donor engagement agent can handle the full lifecycle: accepting donations through payment APIs, generating compliant tax receipts, crafting personalized thank-you messages based on donor history, and managing recurring giving schedules. The agent operates autonomously for routine transactions while escalating edge cases to human staff.

## Designing the Donor Data Model

Before building the agent, define the data structures that represent donors and their contributions.

```mermaid
sequenceDiagram
    autonumber
    participant Caller as Caller
    participant Agent as CallSphere Agent
    participant API as CRM API
    participant DB as CRM Database
    participant Webhook as Webhook Listener
    Caller->>Agent: Inbound call begins
    Agent->>Agent: STT plus intent detection
    Agent->>API: Lookup contact by phone
    API->>DB: Read contact record
    DB-->>API: Contact and history
    API-->>Agent: Personalized context
    Agent->>API: Create call activity
    Agent->>API: Update deal stage
    API->>Webhook: Outbound webhook fires
    Webhook-->>Agent: Confirmed
    Agent->>Caller: Spoken confirmation
```

```python
from dataclasses import dataclass, field
from datetime import datetime, date
from enum import Enum
from typing import Optional
from uuid import uuid4

class DonationType(Enum):
    ONE_TIME = "one_time"
    RECURRING_MONTHLY = "recurring_monthly"
    RECURRING_ANNUAL = "recurring_annual"
    IN_KIND = "in_kind"

class DonationStatus(Enum):
    PENDING = "pending"
    COMPLETED = "completed"
    FAILED = "failed"
    REFUNDED = "refunded"

@dataclass
class Donor:
    donor_id: str = field(default_factory=lambda: str(uuid4()))
    first_name: str = ""
    last_name: str = ""
    email: str = ""
    phone: Optional[str] = None
    total_lifetime_giving: float = 0.0
    first_gift_date: Optional[date] = None
    last_gift_date: Optional[date] = None
    gift_count: int = 0
    is_recurring: bool = False
    preferred_fund: Optional[str] = None
    communication_preference: str = "email"

@dataclass
class Donation:
    donation_id: str = field(default_factory=lambda: str(uuid4()))
    donor_id: str = ""
    amount: float = 0.0
    donation_type: DonationType = DonationType.ONE_TIME
    status: DonationStatus = DonationStatus.PENDING
    fund_designation: str = "General Fund"
    payment_method: str = "card"
    transaction_ref: Optional[str] = None
    receipt_number: Optional[str] = None
    created_at: datetime = field(default_factory=datetime.utcnow)
    is_tax_deductible: bool = True
```

## Building the Payment Processing Tool

The agent needs a tool that integrates with a payment processor. Here we use Stripe as an example, wrapping the API call so the agent can invoke it as a tool.

```python
import stripe
from agents import Agent, Runner, function_tool

stripe.api_key = os.environ["STRIPE_SECRET_KEY"]

@function_tool
async def process_donation(
    donor_email: str,
    amount_cents: int,
    fund: str,
    payment_method_id: str,
    is_recurring: bool = False,
) -> dict:
    """Process a donation payment through Stripe."""
    try:
        if is_recurring:
            customer = stripe.Customer.create(
                email=donor_email,
                payment_method=payment_method_id,
                invoice_settings={
                    "default_payment_method": payment_method_id
                },
            )
            subscription = stripe.Subscription.create(
                customer=customer.id,
                items=[{"price": os.environ["STRIPE_RECURRING_PRICE_ID"]}],
                metadata={"fund": fund},
            )
            return {
                "status": "active",
                "subscription_id": subscription.id,
                "donor_email": donor_email,
            }

        intent = stripe.PaymentIntent.create(
            amount=amount_cents,
            currency="usd",
            payment_method=payment_method_id,
            confirm=True,
            receipt_email=donor_email,
            metadata={"fund": fund},
        )
        return {
            "status": intent.status,
            "transaction_id": intent.id,
            "amount": amount_cents / 100,
        }
    except stripe.error.StripeError as e:
        return {"status": "failed", "error": str(e)}
```

## Generating Tax-Deductible Receipts

Nonprofits must issue receipts that meet IRS requirements. The agent generates these automatically after a successful payment.

```python
@function_tool
async def generate_receipt(
    donor_name: str,
    donor_email: str,
    amount: float,
    donation_date: str,
    fund: str,
    transaction_id: str,
    org_ein: str = "12-3456789",
) -> dict:
    """Generate an IRS-compliant donation receipt."""
    receipt_number = f"RCP-{datetime.utcnow().strftime('%Y%m%d')}-{transaction_id[:8]}"

    receipt_text = (
        f"OFFICIAL DONATION RECEIPT\n"
        f"Receipt #: {receipt_number}\n"
        f"Organization: Hope Community Foundation\n"
        f"EIN: {org_ein}\n\n"
        f"Donor: {donor_name}\n"
        f"Date: {donation_date}\n"
        f"Amount: ${amount:.2f}\n"
        f"Designation: {fund}\n"
        f"Transaction ID: {transaction_id}\n\n"
        f"No goods or services were provided in exchange "
        f"for this contribution. This receipt may be used "
        f"for tax deduction purposes."
    )

    return {
        "receipt_number": receipt_number,
        "receipt_text": receipt_text,
        "donor_email": donor_email,
    }
```

## Personalizing Thank-You Messages

The agent crafts thank-you messages that reference the donor's history and the specific impact of their gift.

```python
@function_tool
async def lookup_donor_history(donor_email: str) -> dict:
    """Retrieve donor history for personalized messaging."""
    # In production, query your donor database
    return {
        "first_name": "Sarah",
        "total_lifetime_giving": 2500.00,
        "gift_count": 8,
        "first_gift_date": "2024-06-15",
        "preferred_fund": "Youth Programs",
        "is_recurring": True,
    }

@function_tool
async def send_thank_you(
    donor_email: str,
    subject: str,
    message_body: str,
) -> dict:
    """Send a personalized thank-you email to the donor."""
    # In production, use SendGrid, SES, or similar
    print(f"Sending to {donor_email}: {subject}")
    return {"status": "sent", "recipient": donor_email}
```

## Assembling the Donor Engagement Agent

Wire the tools together into a single agent with instructions that guide its behavior across the full donation lifecycle.

```python
donor_agent = Agent(
    name="Donor Engagement Agent",
    instructions="""You are a donor engagement agent for Hope
Community Foundation. Your responsibilities:

1. Process donations via the payment tool
2. Generate IRS-compliant receipts for every gift
3. Look up donor history to personalize thank-you messages
4. For recurring donors, acknowledge their ongoing commitment
5. For first-time donors, welcome them warmly
6. Always confirm the fund designation before processing
7. If a payment fails, offer to retry or suggest alternatives
8. Never store or repeat full payment card details""",
    tools=[
        process_donation,
        generate_receipt,
        lookup_donor_history,
        send_thank_you,
    ],
)

result = Runner.run_sync(
    donor_agent,
    "Sarah at sarah@example.com wants to donate $100 to Youth Programs "
    "using payment method pm_card_visa. Please process the donation, "
    "generate a receipt, and send a personalized thank-you.",
)
print(result.final_output)
```

The agent will call each tool in sequence: process the payment, generate the receipt, look up Sarah's history, then compose and send a thank-you that references her eight previous gifts and ongoing support.

## FAQ

### How does the agent handle failed payments?

The agent checks the payment status returned by Stripe. If the status is `failed`, it informs the donor with a clear message and suggests retrying with a different payment method. The agent never stores card details itself — it works only with tokenized payment method IDs from Stripe.

### Can this agent handle in-kind donations?

Yes. You can add a separate tool for logging in-kind donations that skips the payment processing step but still generates a receipt. The receipt for in-kind gifts should describe the donated item rather than listing a dollar amount, since the IRS requires the donor to determine fair market value.

### How do you ensure receipt compliance across states?

The receipt template includes the organization's EIN, a statement that no goods or services were exchanged, and the exact donation amount and date. For gifts over $250, the IRS requires a written acknowledgment, which this agent provides automatically. State-specific requirements can be added as conditional logic in the receipt generation tool.

---

#NonprofitAI #DonorManagement #PaymentIntegration #AgenticAI #Python #LearnAI #AIEngineering

---

Source: https://callsphere.ai/blog/building-donor-engagement-agent-donation-processing-receipts-thank-you
