npsp__General_Accounting_Unit__c (NPSP standard object)WeGive Model: Fund
Overview
This document describes how fund/designation data syncs between WeGive and Salesforce. In Salesforce NPSP, funds are called “General Accounting Units” (GAUs) and represent designations or funds to which donations can be allocated. Important Note: Some organizations may use a custom fund object instead of the standard NPSP GAU object. Thefund_api_name setting in the integration configuration determines which Salesforce object is used. This documentation covers the standard NPSP implementation.
How Fund Data Syncs
Direction
- Import from Salesforce - Data imports from Salesforce into WeGive only
- Export to Salesforce - Data exports from WeGive to Salesforce only
- Both Ways - Data syncs in both directions
Mapping Types
- Configurable - Can be customized via integration settings
- Hard-coded - Built into the integration logic and cannot be changed
Sync Triggers
From WeGive to Salesforce (Export)
Fund data is exported from WeGive to Salesforce when:- Fund Created: A new fund is created in WeGive
- Fund Updated: An existing fund is modified in WeGive (e.g., name changed, description updated, active status changed)
From Salesforce to WeGive (Import)
Fund data is imported from Salesforce to WeGive based on:- Last Modified Date: WeGive periodically polls Salesforce for GAUs that have been modified since the last sync
- Sync Frequency: The integration checks for updated GAUs on a scheduled basis (frequency varies by integration configuration)
- Modified Field Tracking: Only GAUs with a
LastModifiedDatenewer than the last successful sync are pulled into WeGive
- Creating a new GAU in Salesforce will import it to WeGive on the next sync cycle
- Updating an existing GAU in Salesforce will trigger an import to WeGive on the next sync cycle
- The sync is based on Salesforce’s
LastModifiedDatefield, not individual field changes
Sync Process Overview
Fund-Level Synchronization
WeGive syncs funds at the General Accounting Unit level in Salesforce, maintaining fund definitions, descriptions, and active status. Funds are used for allocating donations to specific purposes, programs, or designations.Pulling Data from Salesforce
When pulling data from Salesforce, WeGive queries General Accounting Units based on the last modified date and any specific filtering criteria. The integration pulls comprehensive data from the GAU record, including all standard and custom fields that have been mapped. The import process includes:- Fund Identification: Creates or updates the corresponding WeGive Fund record
- Active Status: Maintains whether the fund is currently active for donations
- Custom Fields: Imports any custom fields configured through mapping rules
- Metadata: Preserves created date and other tracking information
Pushing Data to Salesforce
When a Fund is created or updated in WeGive, the integration compiles a payload for the Salesforce GAU object. This payload includes all mapped fields and ensures that the GAU record is properly created or updated in Salesforce. The integration handles:- Standard Fields: Name, description, active status
- Custom Fields: Any organization-specific fields configured through mapping rules
- Data Type Conversion: Properly formats data types (e.g., boolean values for active status)
General Accounting Unit Field Mappings
| Salesforce Field | WeGive Field | WeGive API Field | Direction | Type | Notes |
|---|---|---|---|---|---|
| Id | Salesforce ID | salesforce_id | Import from Salesforce | Hard-coded | Salesforce’s unique identifier for this fund |
| Name | Fund Name | name | Both Ways | Configurable import / Hard-coded export | Display name of the fund |
| npsp__Description__c | Description | description | Both Ways | Configurable | Detailed description of the fund purpose |
| npsp__Active__c | Active Status | active | Both Ways | Configurable | Whether the fund is currently active |
| CreatedDate | Created At | created_at | Import from Salesforce | Hard-coded | When the fund was created |
Active Status Handling
Theactive field is converted to a boolean value during import:
- If the value can be validated as a boolean, it’s set to
trueorfalse - This ensures consistent active/inactive status across both systems
- Inactive funds typically cannot be selected for new donations but remain for historical reporting
Fund Allocations
Funds work in conjunction with the Allocation object:- Transactions can have allocations to one or more funds
- Recurring Donations can have allocations to one or more funds
- Allocations specify either a fixed amount or percentage going to each fund
- See the Allocation documentation for details on how donations are allocated to funds
Integration with Donations
When a transaction or recurring donation has a fund assigned:- The
fund_idfield on the transaction/recurring donation links to the WeGive fund - In Salesforce, this is represented through Allocation records
- If fund allocations are NOT enabled, a single allocation is created linking the Opportunity to the GAU
- If fund allocations ARE enabled, multiple allocations can exist per Opportunity/Recurring Donation
Fund Matching & Create/Update Logic
When WeGive Exports a Fund to Salesforce
The integration uses the following logic to determine whether to create a new GAU or update an existing one: Step 1: Check for Existing Salesforce Fund ID- If the WeGive fund has a
salesforce_id: The integration UPDATES the existing GAU record in Salesforce - If no
salesforce_idexists: The integration CREATES a new GAU record in Salesforce
When Salesforce Exports a Fund to WeGive
Step 1: Check for Existing WeGive Fund- The integration searches for an existing fund by
salesforce_id - If found, it updates that fund
- If not found, it creates a new fund
- All mapped fields are imported from the GAU record
- Boolean values (like active status) are properly converted
- Custom field values are processed through the custom fields system
Why This Matters
This matching logic ensures:- Each WeGive fund maps to exactly one Salesforce GAU record
- Fund definitions remain consistent across both systems
- Historical allocations continue to reference the correct fund
- No duplicate funds are created during sync operations
Integration Rules
Organizations can create custom mapping rules for funds to handle:- Additional custom fields on the GAU object
- Organization-specific fund tracking fields
- Custom reporting or categorization fields
neon_mapping_rules table with:
crm= ‘salesforce’integration= ‘fund’level= ‘import’, ‘export’, or ‘both’
GAU Allocation (Fund Allocation) - Field Mapping
Salesforce Object:npsp__Allocation__c (NPSP standard object)WeGive Model: FundAllocation
Overview
GAU Allocations represent how donations (Opportunities) or recurring donations are allocated to specific funds (General Accounting Units). This allows a single donation to be split across multiple funds, with each allocation specifying either a dollar amount or percentage going to each fund. Organization Setting Required: Fund allocations must be enabled in the organization settings (enable_fund_allocations = true) for allocation syncing to occur. If disabled, the integration uses the legacy single-fund approach where the fund is directly assigned to the transaction.
How Allocation Data Syncs
Direction
- Import from Salesforce - Data imports from Salesforce into WeGive only
- Export to Salesforce - Data exports from WeGive to Salesforce only
- Both Ways - Data syncs in both directions
Mapping Types
- Hard-coded - Built into the integration logic and cannot be changed
Sync Triggers
From WeGive to Salesforce (Export)
Allocation data is exported from WeGive to Salesforce when:- Transaction Created/Updated: When a transaction with fund allocations is created or updated
- Recurring Donation Created/Updated: When a recurring donation with fund allocations is created or updated
- Allocation Modified: When an allocation amount is changed
- Allocation Deleted: When an allocation is removed
- Creates new allocations that don’t exist in Salesforce
- Updates existing allocations if amounts have changed
- Deletes allocations in Salesforce that no longer exist in WeGive
From Salesforce to WeGive (Import)
Allocation data is imported from Salesforce to WeGive based on:- Last Modified Date: WeGive periodically polls Salesforce for Allocations that have been modified since the last sync
- Parent Record Sync: When importing Opportunities or Recurring Donations, allocations can be included via subquery (if enabled)
- Deleted Allocations: The integration tracks deleted allocations via
IsDeleted = truequeries
- Creating a new Allocation in Salesforce will import it to WeGive on the next sync cycle
- Updating an existing Allocation in Salesforce will trigger an import to WeGive on the next sync cycle
- Deleting an Allocation in Salesforce will remove it from WeGive on the next sync cycle
Sync Process Overview
Allocation-Level Synchronization
WeGive syncs fund allocations at the individual Allocation record level, maintaining the relationship between donations (or recurring donations) and the specific funds they support.Pulling Data from Salesforce
Standard Pull Process: When pulling allocation data from Salesforce as a separate query, WeGive:- Queries
npsp__Allocation__crecords based on last modified date - Loads related transactions and recurring donations that match the Opportunity/Recurring Donation IDs
- Loads funds (GAUs) that match the allocation records
- Creates or updates FundAllocation records in WeGive
Pushing Data to Salesforce
When a transaction or recurring donation with allocations is pushed to Salesforce, the integration:- Ensures Prerequisites Exist:
- Fund must have a
salesforce_id - Transaction must have a
salesforce_id(for transaction allocations) - Recurring Donation must have a
salesforce_id(for recurring donation allocations)
- Fund must have a
- Queries Existing Allocations:
- Fetches all current allocations in Salesforce for the parent record
- Compares with WeGive allocations
- Synchronizes Allocations:
- Creates new allocations that don’t exist in Salesforce
- Updates existing allocations if amounts have changed
- Deletes allocations in Salesforce that no longer exist in WeGive
| Salesforce Field | WeGive Field | WeGive API Field | Direction | Type | Notes |
|---|---|---|---|---|---|
| Id | Salesforce ID | salesforce_id | Import from Salesforce | Hard-coded | Salesforce’s unique identifier for this allocation |
| npsp__Opportunity__c | Transaction Salesforce ID | allocatable.salesforce_id | Both Ways | Hard-coded | Links to Opportunity (for transaction allocations) |
| npsp__Recurring_Donation__c | Recurring Donation Salesforce ID | allocatable.salesforce_id | Both Ways | Hard-coded | Links to Recurring Donation (for recurring allocations) |
| npsp__General_Accounting_Unit__c | Fund Salesforce ID | fund.salesforce_id | Both Ways | Hard-coded | Links to the GAU (fund) |
| npsp__Amount__c | Amount | amount | Both Ways | Hard-coded | Dollar amount allocated (WeGive stores in cents) |
| npsp__Percent__c | Percentage | (calculated) | Import from Salesforce | Hard-coded | Percentage of total (imported but not exported) |
Prerequisites for Creating Allocations
Before creating an allocation in Salesforce, the integration ensures:- Fund exists: The fund must have a
salesforce_id- the integration will automatically push the fund if needed - Parent record exists: The transaction or recurring donation must have a
salesforce_id - Allocatable amount is valid: The amount must be greater than zero
Allocation Matching & Create/Update Logic
When WeGive Exports Allocations to Salesforce
The integration uses a “sync to match” approach: Step 1: Query Existing Allocations- Fetch all allocations in Salesforce for the parent record (Opportunity or Recurring Donation)
- Track their Salesforce IDs
- If it has a
salesforce_id: UPDATE the existing allocation in Salesforce - If it has no
salesforce_id: CREATE a new allocation in Salesforce - Track which Salesforce IDs should be kept
- Any Salesforce allocations not in the “keep” list are DELETED
- This ensures removed allocations in WeGive are removed in Salesforce
When Salesforce Exports Allocations to WeGive
Step 1: Find Allocatable Record The integration determines which record this allocation belongs to:- If
npsp__Opportunity__cis set: Search for transaction with thatsalesforce_id - If
npsp__Recurring_Donation__cis set: Search for recurring donation with thatsalesforce_id - If neither parent is found, throw an exception
- Search for existing allocation by
salesforce_id - If not found, create new FundAllocation
- Search for fund with matching
salesforce_idfromnpsp__General_Accounting_Unit__c - If fund not found, throw an exception
- Set the amount (convert from dollars to cents)
- Associate with fund, allocatable, and donor
- Save the allocation
Deleted Allocations from Salesforce
The integration handles deleted allocations through a separate query:- Queries allocations where
IsDeleted = true - Finds matching allocations in WeGive by
salesforce_id - Deletes the WeGive allocation
Why This Matters
This logic ensures:- Allocations are always in sync with their parent transaction or recurring donation
- Changes in fund allocations (adding, removing, modifying) are reflected in both systems
- Deleted allocations are properly removed
- No orphaned or duplicate allocations exist
Integration Rules
Currently, allocation field mappings are entirely hard-coded. There are no configurable mapping rules for allocations, as the data structure is standardized across NPSP implementations.Required Fields
For WeGive to Salesforce:- Parent record reference (either
npsp__Opportunity__cornpsp__Recurring_Donation__c) - Fund reference (
npsp__General_Accounting_Unit__c) - Amount (
npsp__Amount__c)
- Id (Salesforce ID)
- Parent record reference (one of the above)
- Fund reference
- Amount
Usage Examples
Example 1: Single Allocation
A $100 donation entirely to the “Building Fund”:- WeGive: One FundAllocation record with amount = 10000 (cents), fund_id = X
- Salesforce: One Allocation record with npsp__Amount__c = 100, npsp__General_Accounting_Unit__c = GAU_ID
Example 2: Split Allocation
A $100 donation split between two funds:- WeGive:
- FundAllocation 1: amount = 6000 (cents), fund_id = X (General Fund)
- FundAllocation 2: amount = 4000 (cents), fund_id = Y (Music Fund)
- Salesforce:
- Allocation 1: npsp__Amount__c = 60, npsp__General_Accounting_Unit__c = GAU_X
- Allocation 2: npsp__Amount__c = 40, npsp__General_Accounting_Unit__c = GAU_Y
Example 3: Recurring Donation with Allocations
A $50/month recurring donation split between funds:- WeGive:
- ScheduledDonation with two FundAllocation records
- Each allocation specifies the amount per installment
- Salesforce:
- npe03__Recurring_Donation__c with two Allocation records
- Each Opportunity created by the recurring donation inherits these allocations
Troubleshooting
Allocations not syncing:- Verify
enable_fund_allocations = truein organization settings - Check that the parent transaction/recurring donation has a
salesforce_id - Ensure all funds have
salesforce_idvalues
- WeGive stores amounts in cents, Salesforce in dollars - verify conversion
- Check for rounding issues with percentage-based allocations
- Ensure the sum of allocations doesn’t exceed the transaction amount
- The integration deletes allocations on both sides during sync
- If an allocation reappears, check for competing sync processes
- Verify the “deleted allocations” query is running
- Ensure all funds referenced in allocations exist in both systems
- Verify funds have valid
salesforce_idvalues - Check that fund sync is working properly
- Verify the transaction or recurring donation exists in WeGive
- Check that the parent record has a valid
salesforce_id - Ensure the allocation is linked to either an Opportunity or Recurring Donation (not both)
Best Practices
- Enable fund allocations if your organization needs to track donations across multiple funds
- Create funds first before creating transactions with allocations
- Use consistent fund structures across both systems
- Verify allocation totals - the sum of allocations should equal (or be less than) the transaction amount
- Monitor sync logs for allocation-related errors
- Test allocation changes in a sandbox before deploying to production
- Document fund purposes so staff know which fund to use for different donation types
- Train staff on how allocations work and when to use them
- Use subqueries when possible - including allocations in Opportunity queries reduces API usage
- Clean up orphaned allocations - if a transaction is deleted, ensure allocations are cleaned up too
Understanding the “Sync to Match” Approach
The integration uses a sophisticated “sync to match” approach for allocations:- On every transaction/recurring donation push, the integration:
- Queries all existing allocations in Salesforce for that record
- Compares them with the allocations in WeGive
- Creates, updates, or deletes allocations to match WeGive exactly
- This approach ensures:
- No duplicate allocations
- No orphaned allocations
- Allocations always reflect the current state in WeGive
- Changes to allocations are immediately reflected in Salesforce
- Why this matters:
- If you change an allocation amount in WeGive, it updates in Salesforce
- If you remove an allocation in WeGive, it’s deleted in Salesforce
- If you add an allocation in WeGive, it’s created in Salesforce
- All of this happens automatically when the parent record syncs