Integration Nuances
This document outlines important behaviors, limitations, and considerations when using the WeGive Planning Center integration, including specific features of the People and Giving modules.Authentication Behaviors
OAuth 2.0 Flow
Authentication Process:- Initial OAuth authorization redirects to Planning Center
- User grants permission for the ‘people giving’ scope
- Authorization code exchanged for access and refresh tokens
- Every API call checks token expiry first; if expired, the access token is refreshed proactively before the call is made
- If the refresh call itself fails (e.g. the refresh token was revoked), it throws — there’s no automatic re-authorization flow; a human has to reconnect the integration
Legacy Authentication
Basic Auth Process:- Uses Application ID and Personal Access Token, sent as HTTP Basic Auth
- Same scope access as OAuth (people and giving)
There’s no built-in migration tool between legacy and OAuth authentication — switching means reconfiguring the integration with new credentials.
Data Flow Behaviors
Daily Batch Processing
WeGive Import Batches:- One scheduled job (
command:generate-planning-center-batches, daily at 8:01 AM) creates a batch for the previous day’s transactions - Batch name format:
WeGive Import MM/DD/YYYY - Every run also does a separate “missing” catch-up batch covering all transactions that still have no
planning_center_id, regardless of date - A batch auto-commits after all transactions in it are processed
- Transactions are selected by
succeeded_atfalling in the target day’s range, not any other processing timestamp - A batch with zero eligible transactions is logged as
ignored, not created in Planning Center at all - If
createTransactionsBatch()throws partway through, the whole batch’s changes are rolled back: anyplanning_center_ids set during that run are cleared and the partial batch is deleted in Planning Center - Pulling (donors, funds, and transactions from Planning Center) runs on a separate daily schedule (
command:pull-integrations planning_center, once per day, no fixed time configured) — it is not tied to the 8:01 AM push job and doesn’t run at “8:15 AM”
Fund Assignment Logic
Priority Order for Fund Assignment (fixed, not configurable):- Specific Fund: Use the fund linked on the WeGive transaction, if it has a
planning_center_id - Default Fund: Fall back to the integration’s configured
default_fund_id - Oldest Fund Fallback: Fall back to the destination organization’s oldest fund that has a
planning_center_id - Skip: If none resolve, the transaction throws
Unknown Fund Sourceand is skipped (reported to Sentry, not a batch failure)
- A Planning Center fund whose
visibilitybecomeshiddenis soft-deleted in WeGive automatically on pull - Fund visibility does not sync bidirectionally — when WeGive pushes a fund it always creates it with a fixed
visibility: everywhere - Fund push is find-or-create by name only: an existing Planning Center fund is never updated after the initial match/create, so later WeGive-side name/description edits don’t propagate
Contact Management Behaviors
Person Record Matching
Matching isplanning_center_id-only — there is no email or name-based matching. A donor that hasn’t already been linked to a Planning Center person (via a stored planning_center_id) will always create a new person record on push, even if a matching person already exists in Planning Center.
Contact Information Handling:
- Up to 3 emails (
email_1/email_2/email_3) and 2 phone numbers (mobile_phone/office_phone) are pulled by position, not by any semantic “primary” designation - One mailing address is synced per contact
Family and Household Relationships
There’s no household/family-relationship sync in this integration — WeGive donors and Planning Center people are synced as independent individual records with no family/household linkage.
Payment Source Management
WeGive Payment Source
Single Payment Source Strategy:- All WeGive transactions post to a single Planning Center payment source named “WeGive,” found by name or created automatically on first use
- The original payment method (card vs. ACH) is sent as the donation’s own
payment_methodattribute, not tracked via multiple payment sources
API Rate Limiting and Performance
Planning Center API Limits
Rate Limiting:- Planning Center’s own limit is 70 requests per 20 seconds
- WeGive’s integration proactively throttles to this internally: it sleeps for 20 seconds after every 70th request, rather than waiting for a 429 response
Large Data Set Handling
- Pull operations for donors, funds, and transactions all paginate through the Planning Center API 100 records at a time
- There’s no separate checkpoint/resume system beyond the normal
updated_at-range pagination
Error Handling and Recovery
Automatic Error Recovery
Retry Logic (GET requests only):- GET requests made via the integration’s retry-wrapped HTTP client are retried up to 3 times on transient failures (HTTP 408/429/500/502/503/504, or connection-level errors), with exponential backoff honoring a server
Retry-Afterheader when present - Mutating requests (POST/PUT/PATCH/DELETE) — creating a donor, fund, or donation — are not automatically retried; a failure there is caught and reported to Sentry, not retried
- A single transaction’s push failure is caught per-transaction inside the batch loop and reported to Sentry — the loop continues to the next transaction, so one bad transaction doesn’t fail the whole batch
- A failure in the batch-level setup (looking up/creating the batch or payment source) fails the entire batch and triggers the rollback described above
Common Error Scenarios
Authentication Errors:- Token expiration is handled automatically via proactive refresh
- If the refresh token itself is invalid, the batch/pull run fails with an
error-executionlog — there’s no automatic re-authentication
- Missing fund resolution (
Unknown Fund Source) causes that transaction to be skipped, not the whole batch - Non-positive transaction amounts are silently skipped (Planning Center’s API requires positive amounts)
Sync Timing and Scheduling
Automated Operations
- 8:01 AM daily: Push batch generation for the previous day’s transactions, plus a missing-transactions catch-up batch
- Once daily (no fixed time): Pull donors/funds/transactions from Planning Center
- There is no continuous/real-time transaction push —
pushTransaction()is a literal no-op stub; only donor and fund pushes happen in real time (inline, as part of the batch build and elsewhere)
Fund and Designation Behaviors
Fund Creation and Management
- A fund push automatically creates the fund in Planning Center if no name match exists — this isn’t optional or configurable
- Fund
descriptionis set on create only; it isn’t kept in sync afterward
Split/Multi-Fund Gifts
Each donation sent to Planning Center includes exactly one fund designation — split gifts across multiple funds aren’t supported by this integration.
Recurring Gift Coordination
There’s no recurring-gift sync between WeGive scheduled donations and Planning Center recurring gifts in this integration — Planning Center recurring-donation IDs aren’t referenced anywhere in
PlanningCenter.php.Best Practices
Data Management
- Monitor
integration_logsregularly — none of the failure modes above (batch rollback, per-transaction fund-resolution skip, auth failure) surface to the customer-facing dashboard - Set a valid
default_fund_idto avoidUnknown Fund Sourceskips - Link donors to their existing Planning Center person before their first push, if avoiding duplicate contact creation matters
Troubleshooting Preparation
- Check
integration_logs(status = 'error-execution'for auth/setup failures) and Sentry (Unknown Fund Sourcefor per-transaction fund-resolution failures) — these are the only places these failures are visible