Account Object Mapping
This document details the real mapping between Neon CRM account objects and WeGive donor records, based onNeonIntegration::generateAccountParams() and SyncNeon::processAccount().
Individual Account Mapping
Core Identity Fields
There is no computed
name (firstName + " " + lastName) sent to Neon — name is a WeGive-internal display field, not part of the account push payload.Contact Information
Communication Preferences
Neon’s API itself may expect
"GIVEN"/"NOT_GIVEN"/"UNKNOWN" string enums for consent fields — WeGive sends its own raw boolean value for email/sms regardless. Whether Neon’s API coerces this correctly on its end isn’t something WeGive verifies.Integration Fields
Login Block
Company Account Mapping
Core Identity Fields
There is no separate business-phone/business-email field distinct from the individual structure — company accounts reuse the same
primaryContact object, with firstName sent as null. There’s also no “company classification”/industry field mapped.Contact Information
Integration Fields
Company accounts don’t get a
login block — the login key is only ever added conditionally, but in the actual code both account types share the same primaryContact structure and neither has explicit login suppression logic distinguishing individual from company; in practice the login block is present for both account types as generated (see the Login Block warning above).Address Within the Account Push
The account push’sprimaryContact.addresses array (this is the only address data that actually reaches Neon today — see the note above) includes, for the mailing address:
For individual donors only, a second address entry is included if
billingAddress exists, with the same field set (address lines, city, zip, state) — but no isPrimaryAddress flag is set on it, and no phone/fax fields are included on either entry.
Data Transformations
Name Processing
- First/last names mapped separately for individuals — no computed display name sent
- Company accounts map WeGive’s
namefield directly
Username Generation
preg_replace('/\PL/u', '', $donorProfile->name)— strips everything that isn’t a Unicode letter (spaces, digits, punctuation), keeping only letters."John Smith"becomes"JohnSmith".
- Up to 3 emails sent (
email_1/email_2/email_3) — no format validation is performed by WeGive before sending; any rejection would be a Neon-side API error - No “primary email” logic beyond
email_1mapping toemail1— there’s no separate designation
Communication Preferences
- Sent as raw WeGive booleans (see the warning above) — not translated to Neon’s
GIVEN/NOT_GIVEN/UNKNOWNenum strings
Synchronization Behavior
Account Creation/Update (Push)
- If
neon_account_id/neon_idalready set →PUT /accounts/{accountId}(update) - Otherwise →
POST /accounts(create) - On create, if Neon returns error code
10012(duplicate account), search Neon by email and link the existing account instead of retrying create - There is no “last modified wins”/timestamp-based conflict resolution — push always sends WeGive’s current state; whichever side calls last simply overwrites what Neon has for the mapped fields
Import from Neon CRM (Pull)
POST /accounts/searchwith aAccount Last Modified Date > (last sync - 1 day)filter, plusEmail 1 NOT_BLANKandFirst Name NOT_BLANKfilters- Match to an existing WeGive
Userby exact email - No match → create a new
User(random password, viaHash::make(Str::random())) +Donor+Login - If a
Donormatching the pulled account already exists, onlyneon_account_idand the mailing/billing address are refreshed — first/last name, email, and consent fields are not re-imported on subsequent pulls once the donor already exists
Custom Field Mapping
The default seededNeonMappingRule records for accounts:
Adding Custom Mappings
Error Handling
Best Practices
Data Quality
- Keep donor emails valid and populated — pull skips accounts without an email entirely
- Understand that a donor’s first/last name and email won’t re-sync from Neon once a
Donoralready exists in WeGive — only the address refreshes on later pulls
Integration Management
- Check Sentry (not the WeGive dashboard) for account sync failures — there’s no dedicated sync-status view for this integration
- Be aware of this known issue if you’re considering re-enabling Neon donor-portal login features for any org
API Examples
Creating an Individual Account
This example reflects real payload shape — including the hardcoded literal password, and
consent.email/consent.sms as raw booleans rather than Neon-style enum strings.