Gift Mapping
WeGive Transactions map to Virtuous Gifts. There are two push paths with slightly different payload shapes — a batch importer and a real-time single-gift path — plus a pull path. This page documents each exactly.Which transactions are sent
Before any push, the integration decides whether a transaction should go to Virtuous:Push — batch path
The batch importer sends transactions toPOST v2/Gift/Transactions in chunks of 100, with createImport: true. Each transaction becomes one entry:
After a successful batch send, each transaction’s
virtuous_id is set to a synthetic batch ID like btch_WeGive_Import (not a real Gift ID).
Push — real-time single path
Whenreal_time is enabled, individual transactions are sent to POST Gift (and updated with PUT Gift/{id}). The payload is similar but the shapes differ from the batch path:
On create, the returned Gift
id is stored as the transaction’s virtuous_id. On update, the integration GETs the existing gift, overwrites the WeGive-owned fields (amount, description, segment, tax/private flags, notes, designations, custom fields), and PUTs it back. Designation updates use Virtuous’s diff protocol: every existing designation is marked Delete and the desired set is appended as Add, achieving replace semantics.
The two paths differ deliberately: batch usesdesignationswith{ id, amountDesignated }and acustomFieldsobject; real-time usesgiftDesignationswith{ projectId, amount }and acustomFieldsarray.
Payment method (giftType)
giftType is set for four payment signals, checked in this order — payment_type takes priority over source_type. Anything else is sent without a giftType:
Amounts
WeGive stores amounts in cents; Virtuous in dollars. Amounts are divided by 100 on push (and multiplied by 100 on pull). There are no separateFee, CurrencyCode, or GiftStatus fields in the payload.
Pull (Virtuous → WeGive)
Gifts are pulled viaPOST Gift/Query/FullGift (1000 per page, filtered by the configured pull_by date). Each record is imported as a Transaction:
Matching: a pulled gift is matched first by
virtuous_id, then by the wg_id custom field (which links back to the original WeGive transaction); otherwise a new transaction is created.
Owner resolution: a company donor (by virtuous_contact_id, no individual) is tried first; otherwise the donor is matched by contactIndividualId, falling back to the Contact’s primary individual.
Designations: the owning fund is taken from the first giftDesignations entry’s projectId; the campaign from segmentId. When fund allocations are enabled, allocations are reconciled to WeGive from the gift’s giftDesignations (projectId → fund, amountDesignated * 100 → amount). Recurring-gift linkage is not restored on pull.
This reflects the integration as implemented in app/Integrations/Virtuous.php.