FundraiserOne Contact Sync Integration
Overview
A per-organisation integration that syncs registration entities from Tahua to FundraiserOne (F1) as contacts. When a registration is submitted or an approved registration is updated, the corresponding F1 contact record is created or updated automatically.
Architecture
The integration follows the same pattern as the existing Xero, Accredo, QuickBooks, and Slack integrations:
Integration concern (
FundraiserOneIntegration) on Organisation — stores API key (encrypted via SimpleEncryption), base URL, and enabled flag in thesettingshash columnAPI client (
FundraiserOneClient) — Faraday-based HTTP client authenticating viaSecretKeyheader againstPUT /api/v1/Customer/Integration log (
FundraiserOneLog) — STI subclass ofIntegrationLog, automatically visible in the admin integration logs UISync job (
FundraiserOne::SyncContactJob) — builds the payload, calls upsert, stores the returnedContactIDon the registration entity, and logs success/failure
Payload Mapping
Each registration entity is synced as a single F1 contact. The payload is built by FundraiserOnePayloadBuilder:
Fixed mappings from User (account owner) and RegistrationEntity:
User.first_name/last_name/title/emailtoFirstName/LastName/Title/EmailRegistrationEntity.nametoOrganisationRegistrationEntity.idtoReferenceId(used for deduplication)
Configurable mappings from registration form fields — each form field can be assigned an F1 target field (e.g. BusinessPhone, Email, Region, PostalAddressCity) via the form builder UI. The builder reads all fields with a fundraiser_one_field value and maps their input values into the payload.
Contact type is set per registration type via the fundraiser_one_contact_type column (e.g. "Individual", "Organisation"), allowing orgs with multiple applicant types to send the correct value.
Sync Triggers
Registration submitted
SyncContactJob enqueued immediately
Approved registration updated (field edit)
SyncContactJob enqueued with a 30-second debounce (Redis SET NX) to coalesce rapid field edits into a single API call
The debounce uses an atomic Redis key (f1_sync_pending[org_id][entity_id]) with a TTL. The first change sets the key and schedules a delayed job; subsequent changes within the window are no-ops. The job clears the key on execution so future edits can trigger a new sync.
Per-Field Form Builder Mapping
Rather than configuring field mappings at the organisation level, each form field can be assigned an F1 target field directly in the form builder. A dropdown in the field context bar lets admins select which F1 field (if any) a form field maps to. This is stored as fundraiser_one_field on the field record.
Organisation Setup
Configuration is done via Rails console:
Admin UI
Registration type edit modal: shows a "FundraiserOne Contact Type" text field when the integration is enabled
Applicant show page and registered provider show page: display the F1 Contact ID when present
Integration logs: all sync attempts (success and failure) appear in admin settings > integration logs
Error Handling
API errors raise
FundraiserOneApiError, logged toFundraiserOneLogand reported to Rollbar, then re-raised for Sidekiq retryUnexpected errors are logged and reported but not re-raised (to avoid infinite retry loops)
Last updated
Was this helpful?