Salesforce

The ActionKit Salesforce app creates an automatic one- or two-way sync between ActionKit and Salesforce. You can use the sync to transfer data about users (Salesforce contacts), one-time donations (Salesforce opportunities) and recurring donations (Salesforce recurring donations and opportunities).

The sync uses settings in ActionKit configuration and the Salesforce ActionKit app, reports in ActionKit categorized as salesforce_sync and salesforce_donation_sync, as well as the field mappings in ActionKit to determine the directionality and data synced.

Object Model

The ActionKit Salesforce app uses the following standard and custom Salesforce objects. It also creates custom fields on these objects:

  • Contacts (standard)
    • ActionKit ID
    • ActionKit Opt In
    • ActionKit URL
    • From ActionKit
  • Opportunities (standard)
    • ActionKit ID
    • From ActionKit
  • Recurring Donations (through NPSP)
    • ActionKit ID
    • From ActionKit

From ActionKit on all objects should not be added to a display; it's read-only and for internal use.

See ActionKit's Salesforce table documentation. The app also pushes data to action, donation, and user tables in ActionKit.

NPSP

In order to sync your ActionKit instance to Salesforce, you need to be using Salesforce's Nonprofit Success Pack, aka NPSP (install here). Don't forget to go through the post-install checklist.

Setup in Salesforce

You'll need to create a separate Salesforce user with the email address ActionKit_Walkers@ngpvan.com with system administrator permissions and send us the login information. We'll use this account to hook up the ActionKit Salesforce app.

Then you'll be able to configure the settings in ActionKit, first to set which objects sync and in which direction(s), then to map specific fields related to each object you want to sync and finally to specify which users and donations will sync.

Setup in ActionKit

In ActionKit Settings (the cog wheel icon, top right of the screen) select "CONFIGURE ACTIONKIT" to get to the CONFIG screen. Scroll down to "Integration Settings" find "Salesforce" and click "Edit".

https://s3.amazonaws.com/clientcon/images/salesforce-config-1.png

You’ll see options for managing the sync settings for Users, One-Time Donations, Recurring Donations. For each area you can choose which direction you want data to flow:

From ActionKit to Salesforce, from Salesforce to ActionKit, or both.

https://s3.amazonaws.com/clientcon/images/salesforce-config-2.png

You can also configure your API Call Limit Percentage and notification emails for when the sync pauses on this page. See API Calls below.

Syncing Users

If you enable the User sync from ActionKit to Salesforce, information about Users who are eligible for sync will transfer to Salesforce for any fields you specify in the User field mapping.

To be eligible, the User must have a value for their last name (this is a Salesforce requirement) and either meet the criteria in your Salesforce Sync Report (more on how to set that up below) or have met the criteria and been included in the sync previously.

Once a User is included in the sync, their Salesforce ID is recorded in ActionKit in the core_salesforceusermap table and displayed on the user record. Any updates to fields you’ve mapped will transfer from ActionKit to Salesforce for Users with a Salesforce ID, even if that user no longers meet the Salesforce Sync Report criteria. If you must disable updates for a specific ActionKit user who is already in the sync, contact support.

The ActionKit to Salesforce sync runs automatically, sending data for any newly eligible or previously included user whose record has changed in the previous 10 minutes.

For users currently in the sync, it's possible to trigger an immediate sync from their user profile. The Salesforce heading of the User Details section shows Salesforce mappings for the user and includes a link to Sync Now. Clicking that and confirming the popup will trigger an immediate sync to SalesForce.

If you enable the User sync from Salesforce to ActionKit, information about Contacts who are eligible will transfer to ActionKit for fields defined in the User field mapping. Salesforce Contacts will be subscribed to your default mailing list in ActionKit the first time they are included in the sync.

To be eligible for the sync, the Salesforce Contact must not be marked DNC or deceased, must have an email address and must have the "ActionKit Opt In" box checked on their Salesforce record. By checking this box, you are confirming that this person wants to receive emails from your organization. There is no way to add a Salesforce Contact to the sync without subscribing the corresponding User in ActionKit. Further subscription management must be done through ActionKit.

You cannot uncheck the "ActionKit Opt In". To unsubscribe a User, search for them on ActionKit's Users Tab. Click through to their User record and click "Unsubscribe".

Once the Salesforce ID has been saved in ActionKit, updates for any fields you include in the User field mapping will continue to sync to ActionKit, except for updates to contacts who are marked DNC or deceased. This is true even if the User has bounced or unsubscribed in ActionKit. This keeps address and donation data in sync in case the User becomes mailable in ActionKit again -- otherwise you would have to manually sync any changes made in the interim.

If a contact in the sync is subsequently marked DNC or deceased, then the corresponding User will be unsubscribed. Taking action in ActionKit will not clear a DNC flag in Salesforce. If an action does subscribe an User sync'd to a DNC contact, then the sync will soon unsubscribe the User again.

The Salesforce to ActionKit sync is triggered whenever the contact record is updated in Salesforce and happens in very close to real time.

The core_salesforceusermap table shows ActionKit users that have been mapped to Salesforce contacts and shows the originating system for new users or contacts. The users in this table may not match the users found by the sync report. Any users made eligible since the sync was last run won't be in the map yet and users who once met, but no longer meet the criteria of the sync report will be in the map.

User Matching

When the sync is triggered in either direction, email addresses are used to match Users with Contacts. Where matches occur, fields are copied over between records as defined in the User Mapping.

For Users and Contacts that were not previously mapped, IDs are also exchanged between the two systems.

Updates are not applied to Contacts that were previously mapped to a different User.

Note

To change email addresses for a user or contact, you must first update the user's email in ActionKit then the contact's email in Salesforce.

Removing Users from the Sync

It is possible to manually remove a user from the sync. On the user profile page, the Salesforce heading of the User Details section shows Salesforce mappings for a user and includes a link to Disconnect User. Clicking that and confirming the popup will remove the user from the sync. Note that this only disconnects the user, it doesn't delete the SalesForce contact or orders imported from SalesForce.

Disconnecting a user might be desirable when you're obstructed by these constraints:

  • A SalesForce contact can only ever receive updates to biographical data from a single ActionKit user.
  • Once a user's been added to the sync, they're always in the sync. Even if they unsubscribe or no longer match your user sync reports.

This might be an issue if you have a contact with multiple email addresses mapped to multiple ActionKit users, but the wrong user is sync'ing to the contact.

In that case, you could delete the contact from SalesForce and have the sync recreate it. For that to work, only the desired user should remain in the sync. You'd need to disconnect other users mapped to the contact, and if necessary exclude the users from your User Sync reports so they're no longer eligible to sync.

New Users and Contacts

When a new User is created in ActionKit through the Salesforce sync, that User is subscribed to your default mailing list. To avoid harming your email sender reputation, it's very important that you only include Salesforce Contacts in the sync who expect to receive email communications from your organization.

The User Source is salesforce for new users created by the sync. Created_at is set to the timestamp shown under Created By on the contact record.

Data for any fields in your mapping that are bi-directional, or Salesforce to ActionKit, will be saved in ActionKit for the new User.

When a new Contact is created in Salesforce through the sync from ActionKit, an Account Household is also created using your default Account household naming settings. Created By is set to your ActionKit API Salesforce User and the timestamp reflects the time of the sync. Data for any bi-directional or ActionKit to Salesforce fields included in your mapping will transfer to Salesforce (see note below).

https://s3.amazonaws.com/clientcon/images/editor-2018-07-20-2.png

User Field Mapping

You can select fields, match them to fields in the other system and set the direction of the data flow for each pair. Email address and last name are required and the mapping for those fields cannot be changed. We provide default mapping for other fields, which you can edit or delete. You can also add additional fields, including custom fields from either system.

Warning

Both ActionKit and Salesforce have restricted fields which cannot be overwritten and fields that require specific values or formatting. Because the fields are customizable on both ends, we can't account for all possible variations. You'll get an error and you won't be able to save if we can tell a mapping is bad, but it is still possible to select options that will break the sync. See User Field Mapping Considerations for details.

For each field you map you can select:

  • Bi-directional the most recent value from either system is used
  • ActionKit to Salesforce Only the value from ActionKit, even if it's blank, always overwrites the Salesforce value
  • Salesforce to ActionKit Only the value from Salesforce, even if it's blank, always overwrites the ActionKit value

Our recommended ActionKit User Field Mapping looks like this:

https://s3.amazonaws.com/clientcon/images/editor-2018-07-20-24.png

To add additional mappings, under "Add New" select the category (user, custom or location) in the box on the left. Then select from the drop down to the right of this. The "user" options include fields from the core_user and core_phone tables, as well as list_membership. The latter is a derived field that provides a semicolon-separated list of the names of the mailing lists the user is subscribed to. This field can be mapped to a picklist in Salesforce to see all of a user's subscriptions in a convenient display.

Map ActionKit custom user fields by clicking "custom" and choosing from a list of all your ActionKit custom User fields. Select the corresponding Salesforce field. All of your custom Salesforce Contact object fields are available for mapping.

https://s3.amazonaws.com/clientcon/images/editor-2018-07-20-4.png

Similarly, you can add User fields from the core_location table by selecting "location". You then have options like us_district and can choose which Salesforce Contact field to map your User location data. These should be set to "ActionKit to Salesforce only".

https://s3.amazonaws.com/clientcon/images/editor-2018-07-20-5.png
User Field Mapping Considerations

The field type and the data in the field will determine which can be synced and in which direction. We've added validation that errors if the fields you select can't be written to:

https://s3.amazonaws.com/clientcon/images/user_mapping_not_allowed.png

Or, if the values in one system don't meet the requirements in the other:

https://s3.amazonaws.com/clientcon/images/editor-2019-01-28.png

However, it is still possible to end up with a bad mapping, which can break your sync. You can protect against one possible cause by ensuring that you don't include a field in the mapping and later change the data in the field so it's inconsistent with the requirements. Once a field is in your mapping, review any changes to the data type or values to make sure they work with the sync.

Notes on specific mapping options follow:

  • Pay special attention if you add a new mapping using a newly created field. The validation checks for existing values that can't be written to the other system, which means that a new field, with no values, has nothing to validate. You can map a text field for favorite color in one system to a date field in the other and it won't fail when you create the mapping, but values will not transfer. This will not break the sync but you won't see the data you expect.
  • Understand how custom field validation works in ActionKit. While you can define Field Types for custom fields, the data is not validated for all possible avenues of entry. For example, if you set a custom user field to type 'Date' in ActionKit, this stops you from entering non-date values on the user record in the admin. This does not stop a user from entering non-date values in the same field on an action page unless you've applied custom validation when creating the page. If the ActionKit field type is "list" or "list with other", a non-matching value from Salesforce will transfer. In the display on the user record in ActionKit, ‘no longer a valid option’ will be appended. Think about how you'll use the ActionKit field and what you can do to keep the data clean when you're mapping to a restricted field type. Mapping to text fields of unlimited size is always safe.
  • Understand how field types work in Salesforce.
    • The sync cannot write to fields with the data type Lookup in Salesforce.
    • The sync can write to fields with the type picklist in Salesforce. For restricted picklists, ActionKit field values must exactly match the values defined in your Salesforce instance before adding the mapping.
    • The sync can write to fields with the type checkbox in Salesforce. A checkbox field in Salesforce transfers a "1" if checked to any field it's mapped to in ActionKit. Checkbox and boolean fields in ActionKit can both be mapped to checkbox fields in Salesforce.
    • Only map ActionKit fields that can have variable length to unlimited text fields in Salesforce. If the Salesforce field cannot hold the ActionKit-supplied value (for example, if ActionKit supplies 75 characters and the Salesforce can only hold 50 characters) from an action the sync will fail. It can only be fixed by removing the mapping.
  • If the State and Country Picklists feature is enabled in Salesforce, ActionKit state fields should map to mailing state code fields in Salesforce.
  • The location fields in ActionKit and the lat/long fields in Salesforce are calculated. That means they cannot be overwritten by the other system.
  • Plus4 is automatically appended to zip when it's transferred to Salesforce if zip is included in your mapping.

See Limitations and Workarounds for additional details on mapping options.

User Sync Reports

You set the criteria in ActionKit for which Users are eligible to be synced to Salesforce.

Reports tagged “salesforce_sync” are used to define the criteria. From the ActionKit Salesforce Integration Settings screen, click on "User Sync Reports" to view a list of reports with this tag.

https://s3.amazonaws.com/clientcon/images/editor-2018-07-20.png

ActionKit ships with one built-in report with this tag. This report returns only subscribed users.

The suggested Salesforce sync report is: SELECT id FROM core_user WHERE subscription_status='subscribed'

https://s3.amazonaws.com/clientcon/images/editor-2018-07-20-48.png

We automatically exclude users with no last name from the sync because Salesforce does not allow contacts with no last name.

Remember, your ActionKit report(s) sets the criteria for who is added to the sync. Once a User is included in the sync they cannot be removed, even if they no longer meet the criteria.

Creating Sync Reports

To create your own report, use a Query Report, with SQL or the query builder. Your report must return a list of just ActionKit User IDs. Tag your report salesforce_sync.

You can delete or edit these reports and/or add your own reports and you can use the query builder as usual. For example, if you’d like to only include subscribed ActionKit Users who have also made a donation, your selections would look like this:

https://s3.amazonaws.com/clientcon/images/editor-2018-07-20-22.png

Syncing One-Time Donations (Orders)

If you’ve enabled the donation sync in either direction, information about eligible individual gifts will transfer as you specify. Only successful, one-time donations that meet the criteria in your Donation Sync Report (described below) are included. If you are using our default Donation Sync Report, when a user or contact is initially added to the sync, historical donation records will sync for included users. Remember, only donations for users/contacts who are in the map are synced.

We designate the contact who maps to the ActionKit donor as the opportunity's primary contact so that donor gets the hard credit regardless of their role in the household in Salesforce.

Full refunds in either system will sync to the other.

Partial refunds in ActionKit will sync to Salesforce by creating a written-off (negative) payment in the amount of the refund and updating the Opportunity amount.

You must prompt refunds in the system where the donation originated.

Warning

If you delete a donation in ActionKit, you should also delete the opportunity in SF or the sync will recreate the donation in AK.

One-Time Donation Field Mapping

Follow the link from the ActionKit configuration screen → Integration Settings → Salesforce "Edit" to customize mapping for donations. Click on "Order Field Mapping".

The date and amount of the order automatically sync to the corresponding fields in Salesforce.

The top section is where you set field mappings for ActionKit to Salesforce. The default fields are:

https://s3.amazonaws.com/clientcon/images/sf-order-mapping-full.png
  • StageName is the value that successful, completed ActionKit orders should be set to in Salesforce. The dropdown shows the available picklist options for the "Stage" field in your Salesforce instance.
  • ReversedStageName is the stage for reversed ActionKit orders in Salesforce.
  • RecordType this dropdown also shows the available Record Types (i.e. Donation, In-Kind, Grant). You may want to add a Record Type for your Salesforce instance for ActionKit donations if you want different page layouts or intend to trigger different behaviors in Salesforce for ActionKit donations.
  • Campaign is an optional field. If you would like to specify a Salesforce Campaign for each ActionKit donation, start by creating a Custom Page Field in ActionKit. Then under ‘Custom Page Fields’ on the Action Basics screen when you create your donation page, select the field you created and enter the appropriate Salesforce Campaign ID. You’ll need to look up the Salesforce campaign ID, which is part of the URL on the campaign screen.
  • Trans ID is the Salesforce field that will hold the transaction ID from the payment gateway (found in the trans_id field in the core_transaction table). This will be used to match existing opportunities in Salesforce to ActionKit Orders to prevent syncing duplicate records.

The second section is for mapping the Salesforce Opportunity fields to ActionKit Orders.

  • Donation Account donations from Salesforce must use an Import Stub Account (a payment account that allows you to sync external donations in ActionKit, but doesn't process them). You cannot use the standard payment account because these donations were not processed through ActionKit.
  • Source defines the value to be saved to the source field in the core_action table in ActionKit for every donation added via the sync.

The last section is for Custom Mappings, which can be set to one-way or bi-directional for standard or custom fields that you'd like to carry over from one system to the other.

https://s3.amazonaws.com/clientcon/images/sf-mapping-types.png

The same considerations detailed under User Field Mapping Considerations apply here.

Custom mappings fall into several categories:
  • Action has fields from core_action, including the source of the donation action. This does not include custom action fields.
  • Page has fields from core_page, including the page name, title and tags. This does not include custom page fields.
  • Transaction has fields from core_transaction, including the account and trans_id from the merchant vendor.
  • Order has fields from core_order, including the account (same as transaction) and the amount and created_at date (mapping for both built in).
  • Custom has custom action fields.

See more on ActionKit's data structure.

Syncing Recurring Donations (Orders)

If you’ve enabled the recurring sync in either direction, information about eligible recurring commitments and payments toward that commitment will transfer as you specify. Eligibility is determined by the Donation Sync Report mentioned for one-time donations and the default report includes all recurring donations.

Recurring Donations are a custom object in the NPSP application, not a built-in Salesforce data object.

When you add a new recurring donation in the Salesforce, an opportunity will be created along with forecast payments (child records of Opportunities).

Note

Forecast payments will be created for the next 12 months by default. You can set the number of forecast payments in the Recurring Donations section of NPSP settings. While the value can be set to 0, a NPSP bug does cause the occasional creation of unexpected pledges.

By default, the Stage for each forecast payment is set to Pledged. As payments are processed, you change the status on the payment to Closed Won (or whatever status indicates a successful donation in your Salesforce instance).

If you’ve enabled the direction of the sync from Salesforce to ActionKit (or set it to bi-directional), we create a new recurring order in ActionKit corresponding to the recurring opportunity from Salesforce. Then when payments on the opportunities go from Pledged to Closed Won we add a row to core_transaction in ActionKit, associated with the ActionKit order id.

If you’ve enabled the direction of the sync from ActionKit to Salesforce (or set it to bi-directional), a new recurring opportunity is created in Salesforce when a recurring order is added to ActionKit. Then Salesforce creates the related payments with the Stage set to Pledged just as if the donation was added directly in Salesforce. As payments are made in ActionKit, the stage of the corresponding payment in Salesforce is changed to your successful payment stage, usually Closed Won.

When sync'ing an existing recurring donation to Salesforce for the first time, NPSP creates pledges for any past periods where no payment was made. By default, we regularly check for and change past pledges to future pledges. Pledges are not a requirement for the ActionKit sync, and may be deleted if desired.

To create a new recurring opportunity in Salesforce, you need to make sure it is set up correctly. We recommend following NPSP settings for recurring donations.

Note

If you need to change the amount or duration of an existing recurring donation in Salesforce, be sure to follow NPSP instructions.

Recurring Field Mapping

Since Recurring Donations are a separate object from Opportunities in Salesforce, you must set the mapping, even for fields that you've already mapped under the Order Field Mapping.

https://s3.amazonaws.com/clientcon/images/sf-recurring-mapping.png

ActionKit to Salesforce

  • Recurring Profile ID is the Salesforce field to hold the recurring profile ID from the payment gateway. This will be used to match existing opportunities in Salesforce to ActionKit Orders to prevent syncing duplicate records.

Salesforce to ActionKit

  • Donation Account is the stub donation account for recurring donations from Salesforce. Donations from Salesforce must use an Import Stub Account (a payment account that helps to sync external donations in ActionKit, but doesn't process them). You cannot use the standard payment account because these donations were not processed through ActionKit. You can use the same stub account for one time and recurring donations. If you’d like to use separate stub accounts, request a new stub through Support.
  • Source identifies where recurring donations created in Salesforce originated from. We suggest using "salesforce".

Changes to your recurring donation must be made in the originating system.

The last section is for Custom Mappings, you can set this to be a one-way or bi-directional sync for standard or custom fields that you'd like to carry over from one system to the other.

https://s3.amazonaws.com/clientcon/images/sf-mapping-types.png
Custom mappings fall into several categories:
  • Action has fields from core_action, including the source of the donation action. This does not include custom action fields.
  • Page has fields from core_page, including the page name, title and tags. This does not include custom page fields.
  • Recurring has fields from core_orderrecurring, including status, account, start and period.
  • Order has fields from core_order, including the account (same as recurring) and the amount and created_at date (mapping for both built in).
  • Custom has custom action fields.

See more on ActionKit's data structure.

Donation Sync Reports

Unless you have a specific category of donations you don't want sent to Salesforce, you shouldn't edit the Donation Sync Report. The default report includes all one-time donations and recurring payments so these will transfer to Salesforce for any user in the sync.

If you do want to limit the donations to be synced, you can edit the existing report tagged salesforce_donation_sync, or add your own. If you have already imported some ActionKit donations into Salesforce without recording the transaction_id (for one time) or the recurring_id (for recurring) in Salesforce, you may want to exclude the donations you've imported from the sync. ActionKit will create duplicate donations unless the unique identifiers are already in Salesforce.

The reports must select two columns: order_id and transaction_id. Order_id is always required. A transaction_id is optional for onetime and recurring donations, and is required for recurring payments. Remember, the Donation Sync Report only applies to donations from users who are in the sync.

$0 Donations

$0 donations in ActionKit, such as from free products orders, don't match the built-in donation sync report because they don't have a sale record in the core_transaction table of the ActionKit database.

To sync these orders to Salesforce, you'll need a sync report that matches orders without transactions. The built-in donation sync report can be adapted as so by changing the join on core_transaction from an inner join to a left join.

Because $0 donations don't have a transaction, they're not covered by duplicate donations checks. When sync'ing a $0 donation to Salesforce for the first time, ActionKit doesn't check if another instance already exists in Salesforce.

Changes to the user sync reports may also be necessary if they've been customized to filter for donors.

Mapping Edits

When you change your field mappings for users, orders or recurring orders, the changes do not apply retroactively. For example, if you add a custom userfield to your mapping, users who already have a value for that field in ActionKit will not have the value transferred automatically. Only future entries in the field will transfer. You can force the sync by importing users whose records have changed -- a new action prompts ActionKit to update all mapped fields. Make sure to test your new mapping when you apply it; invalid mapping can break the sync. See User Field Mapping Considerations for details.

API Calls

The sync tracks Salesforce API calls used and shuts off once we hit a designated percentage (defaults to 40%). If you'd like to change the limit, let us know through support.

..You can configure this limit on the Salesforce Integration Settings page. Once your Salesforce org is below its API call limit, it will start again.You can also configure email notifications for when the sync pauses after hitting the API call limit on the Salesforce Integration Settings page.

You can use the table below to estimate API calls for given actions. Actual usage will fall between the bulk and single call counts because the sync will run with whatever is available every 10 minutes instead of waiting for a minimum number.

Object + Action Calls for 1 Calls for 100
Contact Create 11 19
Contact Update 8 21
Opportunity Create 20 42
Opportunity Create w/ Campaign ID 23 638
Opportunity + Contact Create 24 338
Recurring Donation Create 22 630

Clean-Up Processes

Missed Information (hourly): The sync will occasionally miss information due to Salesforce limits or brief connectivity outages between Salesforce and ActionKit. This hourly cleaner checks for missed information and ensures data integrity.

Recurring Donation Naming: This cleaner addresses common naming issues for pledged opportunities in Salesforce that are part of recurring donations.

Limitations and Workarounds

Please let us know through support if you're having difficulty implementing a workaround or have other Salesforce questions.

Warning

We are not Salesforce experts; please test any workaround and talk with your Salesforce expert before proceeding.

For unsupported mapping choices

If you need to set a lookup field in SF based on a field value in ActionKit, or you don't want to setup a mapping using a field that's values are likely to change over time, the following option can be used to set the field value in Salesforce.

Note

Process Builder processes may cause errors if not created correctly. Talk with your Salesforce consultant, learn about process builder in Salesforce Trailhead, or both, before continuing.

First, create a text field to hold the ActionKit-supplied value. This text field will be used behind the scenes; once you're done testing, you'll want to hide it from page layouts. The text field should be at least 256 characters long. (Going over the character limit will cause the sync to fail.)

For the purposes of this example, we'll use a picklist mapping and assume there's already an entity picklist field on your Salesforce opportunity object to hold the C3/C4 designation for the donation. Create a text field called ActionKit_entity that ActionKit can write to.

  • Go to process builder and create a new process on the opportunity object
  • For The process starts when, select A record changes and save the process.
  • Click + Add Object and select Opportunity. The process should start when the opportunity is created because you want the update to run when an ActionKit field is filled in.
  • Click + Add Criteria. Set the filter conditions to ActionKit_entity is not blank.
  • Click + Add Action. Use the action type Update Records, and select the opportunity. Add the criteria for the action ActionKit_entity equals c3. Set new field value entity to c3.
  • Repeat adding actions to the original criteria node for each text value/picklist value pair.
  • Save the process and activate it.
  • Test the process.

To make changes to the process, clone it and save as a new version of the process.

Capture an ActionKit Custom Page Field in a Donation

ActionKit's custom page fields don't map directly to Salesforce. You can, however, pass the custom page field through a hidden custom action field and then map that custom action field to Salesforce. In effect, you're copying the custom page field into a custom action field each time an action happens on the page.

First, set up the custom page field in ActionKit and the corresponding field in Salesforce. The Salesforce field should be on the opportunity object and should be the type text.

In ActionKit, you'll go to the templateset editor for your primary templateset and insert something like this in the donate.html template inside the <form> tags. When your page field exists, you're filling in the custom page field as the value of a hidden action field. Repeat this step for each templateset that has donation pages.

{% if page.custom_fields.your_field %}
    <input type="hidden" name="action_your_field" value="{{ page.custom_fields.your_field }}">
{% endif %}

At this point, make a test donation to make sure the page field's value is ending up in a custom action field for the donation. The test also pulls the custom action field name into the available action fields for mapping. It won't sync to Salesforce yet.

Finally, you'll add it to your mapping under order mapping and/or recurring mapping, as appropriate. Map the custom action field to the Salesforce field you set up to hold its value. Run another test to make sure it's sending the data from ActionKit to Salesforce.

Using Validation Rules

Validation rules may prevent ActionKit from updating the fields or objects they apply to. If you have validation rules in place, you may need to use NPSP settings or ActionKit custom action fields to bring in the needed information before it's validated by the rule.

Recurring donations can be particularly tricky because NPSP creates the child opportunities based on the recurring donation's values. The recurring donation therefore needs to pass any required values into its child opportunity.

  • Go to NPSP Settings > Recurring Donations > Recurring Donation Custom Field Mapping
  • Add a new custom field mapping
  • Map the recurring donation field to the opportunity field

Duplicate Matching

To ensure you're not creating duplicate Contacts and Accounts in Salesforce you may want to fine tune your matching rules (what criteria defines a match) and your duplicate rules (what to do with a match when it's found).

We recommend making sure that your matching rules contain a match for email addresses and turning off the duplicate rules for Contacts and Accounts. Duplicate rules provide the option to allow or stop Salesforce from creating a new record for the same person. Duplicate rules can also be set to alert and/or report any suspected duplicates.

Note

Duplicate rules set to Alert will temporarily break the sync if Salesforce finds a duplicate.

You have several options for managing duplicates that can be used individually or together:
  • Modify your duplicate rules to "Report" checked, but "Alert" unchecked.
  • Set duplicate rules to run for all Salesforce users except the ActionKit API User.
  • Merge duplicates directly through the NPSP de-duplication feature, using the record with the ActionKit ID as the master.

Never Subscribed Donors

If you have an opt-in checkbox on your donation page, including the built-in one we provide for Canadian users, you may have donors who are never subscribed. You may want to include a salesforce_sync report for never subscribed donors and include subscription status in your mapping in order to feed all donors into Salesforce. More narrowly, you could include Canadian donors with never subscribed status in your sync.

Sync Templating

ActionKit uses templates to build a payload for calling the Salesforce API. These templates are customizeable, and developers familiar with the Salesforce API can customize the templates to handle the unique cases that arise in a Salesforce org.

There are four templates:

  • User
  • Opportunity
  • Recurring donation
  • Recurring Payment

These templates are used for both creating and updating records in Salesforce. The templates get the necessary context to build a payload, detailed below.

Context

The context passed to a sync template always includes:

  • action: create or update. The recurring payment template also supports a pledge_conversion action, when the sync converts a pledged recurring payment in Salesforce to a successful payment.

  • field_mappings: a list, comprised of dictionaries with the keys mapping and value.

    • mapping is an instance of either SalesForceFieldMap, SalesForceOrderFieldMap, or SalesForceRecurringOrderFieldMap.
    • value: Renders as a a JSON encoded string value.

Additional context may be available depending on the action and template:

  • salesforce_id: for updates, the Id of the object to update

  • order object: for opportunity, recurring donation, and recurring payment templates.

  • user object: available in user templates

  • payment: transaction object, available in the recurring payment template.

    Warning

    While customizing templates, be careful not to remove the From ActionKit field. This is used to prevent updates from echoing between ActionKit and Salesforce.

Safety

Data from the field_mappings object is already encoded for use in JSON.

JSON encoding is NOT applied to data pulled from other objects, such as user, order, etc. Any data from these objects that could include user-provided data, such as name or custom fields, must be quoted and escaped with |escapejs e.g. "{{ user.source|escapejs }}" or "{{user.custom_fields.favorite_color|escapejs}}"

Testing Template Customizations

To test template changes, we suggest calling the sync_user REST API endpoint.

Call the API endpoint with use_bulk=1 to initiate a sync of the user to Salesforce using a Bulk Data Load Job. The API response will report any errors assembling and delivering the payload to Salesforce.

Currently this endpoint only sync's user data. In the future we plan to expand this to orders and payments, and also enable use with users not already in the sync.

The "Sync User" link on user profiles will also trigger a sync using the Bulk Data Load Job, but unlike the API call it doesn't provide error details.

Customization Examples

Some examples include:

  • Sync user source to a Salesforce contact field:
"actionkit_user_source__c": "{{user.source|escapejs}}",
  • Special handling of a troublesome field:
{% if user.custom_fields.favorite_color in 'green,orange,blue' %}
  "favorite_color_picklist__c": "{{user.custom_fields.favorite_color|escapejs}}"
{% endif %}
  • Sync to a particular Salesforce Contact
{% if user.custom_fields.salesforce_contact_override %}
  "Id": "{{user.custom_fields.salesforce_contact_override|escapejs}}"
{% else %}
  "Id": "{{contact_id}}"
{% endif %}

In the future it will also be possible to customize handling of users that don't have a last name. Currently there's a hard-coded suppression of users without a last name. We plan to make the handling configurable.

Troubleshooting

If you're trying to understand why the sync isn't working as expected, the two best places to start are the Salesforce Integration Settings page and the Salesforce Sync Dashboard report.

  • Review the Salesforce Integration Settings page (click the Users tab then Manage Salesforce Sync) to confirm that the sync is enabled and configured to send data.
  • Review the Salesforce Sync Dashboard report (salesforce_sync_dash). This report lists users that recently failed to sync, as well as recent transactions and donations that did successfully sync.

Below are steps for troubleshooting the sync of each data type.

ActionKit User Not Syncing to Salesforce

  • Confirm the user has a last name in ActionKit. This is a Salesforce requirement for Contacts.
  • Confirm that the user matches a User Sync Report in ActionKit.
  • Check the user profile page in ActionKit for alerts on sync failures for this user. Note that we always wait 3 hours before trying to sync a user again after a failure.

ActionKit Donation Not Syncing to Salesforce

  • Confirm the ActionKit user associated with the donation has synced to Salesforce.
  • Confirm that the donation matches a Donation Sync Report in ActionKit.

For donations that have already in the sync with Salesforce, note that we'll only update donation amount and status.

Salesforce Contact Not Syncing to ActionKit

  • Confirm that the contact's ActionKit Opt-In field is checked.
  • Confirm that staff working in Salesforce have been assigned a permission set of either ActionKit Standard User or ActionKit Opt-In User.

Salesforce Opportunity or Recurring Donation Not Syncing to ActionKit

  • Confirm that the opportunity's contact has been sync'd to ActionKit.

Advanced Troubleshooting - Sync Data and Salesforce Errors

Once these basics have been checked, the next most common reason for data missing from Salesforce is a field incompatibility. For example, data in an ActionKit that is too long for the mapped Salesforce field.

For data types other than recurring donations, you can see the raw sync data sent from ActionKit as well as Salesforce's response in Salesforce's Bulk Data Load Jobs. This is part of Salesforce's Setup UI.

Bulk Data Load Jobs are organized by data type and operation. For any given run of the ActionKit to Salesforce sync, there’ll usually be query/insert/update jobs for contacts, opportunities, and recurring donations. Update and insert jobs have batches, and each batch has one or more rows corresponding to object from ActionKit. When individual rows fail, Salesforce often reports a useful.

When an entire job fails the errors are less helpful. ActionKit Support may be able to provide more details of why a particular job died.