Skip to main content

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 to POST 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

When real_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 uses designations with { id, amountDesignated } and a customFields object; real-time uses giftDesignations with { projectId, amount } and a customFields array.

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 separate Fee, CurrencyCode, or GiftStatus fields in the payload.

Pull (Virtuous → WeGive)

Gifts are pulled via POST 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.