Project Mapping
WeGive Funds map to Virtuous Projects. This mapping is intentionally minimal: push is create-only, and pull carries a handful of fields plus archival logic.Record Model
Push (WeGive → Virtuous)
Funds are pushed withPOST Project only when they don’t yet have a virtuous_id. Once a Fund is linked to a Virtuous Project, the integration does not update it — push is create-only.
The returned
id is stored as the Fund’s virtuous_id. No goal, description, or project-type fields are sent.
Pull (Virtuous → WeGive)
Projects are pulled viaPOST Project/Query (1000 per page, filtered by the configured pull_by date) and imported as Funds, matched on virtuous_id:
Archival
A pulled Project is soft-deleted (archived) in WeGive when an archival rule is enabled and the matching Virtuous flag is false:
If none of the enabled rules match, the Fund is restored (its
deleted_at is cleared).
Not-public funds: confidential mode instead of archival
Whensync_not_public_funds is enabled, a Project with isPublic: false doesn’t get archived by the archive_funds_when_not_public rule above — instead it syncs as a confidential WeGive fund:
nameis set to the real (internal) Virtuous project name, not the donor-facing onemasked_nameis set to the project’s Online Display Name, if it has oneconfidentialis set totruehide_from_donorsis set totruewhenever the project is also not available online, has no Online Display Name to mask with, or the integration’snot_public_fund_modeisn’t set to “visible masked”
A fund with no Online Display Name to mask behind fails closed — it becomes fully donor-inaccessible via WeGive’s own fund-access gate, regardless of what
not_public_fund_mode is set to.masked_name/confidential flags clear automatically on the next pull — but hide_from_donors is left alone, since unhiding a fund is treated as a deliberate staff action, not something a sync should do on its own.
This reflects the integration as implemented in app/Integrations/Virtuous.php.