CharityEngine GTM Event Listener
Track CharityEngine donation form interactions in GTM. Monitor donation started, payment step, and successful gift events with ce_event_name and donationAmount variables.
charityenginedonationsnonprofitfundraisinggtmga4giving
Event fired
ce_quick_action_form_eventKey variable
ce_event_nameCharityEngine
Overview
CharityEngine is an all-in-one nonprofit CRM and fundraising platform with embeddable donation forms. This listener tracks the full donation funnel, from form view through completed gift, using CharityEngine's native JavaScript event API.
Event fired: ce_quick_action_form_event
Variable: ce_event_name
Common Use Cases
- Track completed donations as GA4
purchaseevents with donation amount - Measure donation funnel drop-off at each step
- Fire Google Ads conversion tags on successful gift
- Build remarketing audiences from donors vs. form viewers
Tracked Events
| ce_event_name | Description |
|---|---|
donation form viewed | Embedded form loaded and visible |
donation started | Donor begins filling out form |
payment step reached | Payment details section opened |
donation completed | Gift successfully processed |
donation failed | Payment attempt failed |
recurring selected | Donor opts into recurring giving |
Installation
html
<!-- GTM Custom HTML Tag: CharityEngine Donation Listener -->
<script>
(function() {
function cePush(action, extra) {
window.dataLayer = window.dataLayer || [];
window.dataLayer.push(Object.assign({
'event': 'ce_quick_action_form_event',
'ce_event_name': action
}, extra || {}));
}
// CharityEngine fires events on the window object
window.addEventListener('message', function(e) {
if (!e.data || typeof e.data !== 'object') return;
if (!e.data.type || e.data.type.indexOf('ce_') !== 0) return;
var data = e.data;
switch (data.type) {
case 'ce_form_loaded':
cePush('donation form viewed', {
ceFormId: data.formId,
ceCampaign: data.campaign
});
break;
case 'ce_gift_started':
cePush('donation started', {
ceFormId: data.formId,
ceDonationAmount: data.amount,
ceFrequency: data.frequency || 'one-time'
});
break;
case 'ce_payment_step':
cePush('payment step reached', {
ceFormId: data.formId,
ceDonationAmount: data.amount
});
break;
case 'ce_gift_complete':
cePush('donation completed', {
ceFormId: data.formId,
ceTransactionId: data.transactionId,
ceDonationAmount: data.amount,
ceDonorEmail: data.email,
ceFrequency: data.frequency || 'one-time',
ceCampaign: data.campaign,
ceFund: data.fund
});
break;
case 'ce_gift_failed':
cePush('donation failed', {
ceFormId: data.formId,
ceErrorCode: data.errorCode
});
break;
case 'ce_recurring_selected':
cePush('recurring selected', {
ceFormId: data.formId,
ceFrequency: data.frequency,
ceDonationAmount: data.amount
});
break;
}
});
})();
</script>Data Layer Output
Donation Completed
json
{
"event": "ce_quick_action_form_event",
"ce_event_name": "donation completed",
"ceFormId": "form_abc123",
"ceTransactionId": "txn_987654",
"ceDonationAmount": "50.00",
"ceDonorEmail": "donor@example.com",
"ceFrequency": "monthly",
"ceCampaign": "spring-fundraiser-2024",
"ceFund": "general-fund"
}Donation Started
json
{
"event": "ce_quick_action_form_event",
"ce_event_name": "donation started",
"ceFormId": "form_abc123",
"ceDonationAmount": "25.00",
"ceFrequency": "one-time"
}Triggers to Create
| Trigger | Event | Condition |
|---|---|---|
| CE – Donation Completed | ce_quick_action_form_event | ce_event_name = donation completed |
| CE – Donation Started | ce_quick_action_form_event | ce_event_name = donation started |
| CE – Donation Failed | ce_quick_action_form_event | ce_event_name = donation failed |
| CE – Recurring Selected | ce_quick_action_form_event | ce_event_name = recurring selected |
Variables to Capture
| Variable Name | DL Key | Example |
|---|---|---|
| DLV – CE Event | ce_event_name | "donation completed" |
| DLV – CE Amount | ceDonationAmount | "50.00" |
| DLV – CE Transaction ID | ceTransactionId | "txn_987654" |
| DLV – CE Frequency | ceFrequency | "monthly" |
| DLV – CE Campaign | ceCampaign | "spring-fundraiser-2024" |
| DLV – CE Email | ceDonorEmail | "donor@example.com" |
GA4 Mapping
| GA4 Event | Trigger | Parameters |
|---|---|---|
purchase | donation completed | transaction_id, value, currency, items |
begin_checkout | payment step reached | value |
add_to_cart | donation started | value (donation amount) |
sign_up | recurring selected | method: "recurring_donation" |
GA4 Purchase Tag Configuration
javascript
// GA4 Configuration tag, Donation as Purchase
// Trigger: CE – Donation Completed
{
transaction_id: {{DLV - CE Transaction ID}},
value: {{DLV - CE Amount}},
currency: "USD",
items: [{
item_name: "Donation - " + {{DLV - CE Campaign}},
item_category: {{DLV - CE Frequency}},
price: {{DLV - CE Amount}},
quantity: 1
}]
}Google Ads Conversion
For Google Ads, create a conversion action for "Donation" and fire it on the CE – Donation Completed trigger:
Conversion Value: {{DLV - CE Amount}}
Currency: USD
Transaction ID: {{DLV - CE Transaction ID}}
Debugging
| Problem | Cause | Fix |
|---|---|---|
| No events in dataLayer | Form in iframe, wrong origin filter | Check e.origin matches CharityEngine domain |
ce_event_name undefined | Wrong event key | Log e.data.type to confirm event format |
| Amount shows as undefined | API version difference | Add console.log to inspect e.data structure |
| Events fire twice | Listener added twice | Wrap in a guard: if (window._ceListenerAttached) return; |
Best Practices
- Track recurring vs. one-time separately, recurring donors have 3-5x higher lifetime value; segment them in GA4 from day one
- Pass transaction ID to avoid duplicate conversions, CharityEngine may send confirmation on multiple page loads
- Use Enhanced Conversions, hash
ceDonorEmailfor better Google Ads attribution on donation completions - Create a GA4 custom dimension for
ceFrequency, enables recurring vs. one-time analysis in Explore reports
Related Listeners
- Calendly, for tracking fundraising calls scheduled via Calendly
- HubSpot Form, for capturing donation interest forms before the gift