====== Toweringmedia Constant Contact Extension for Magento 2 ======
===== Extension Overview =====
The Toweringmedia Constant Contact Extension connects Magento 2 customers and newsletter subscribers with Constant Contact through secure, bidirectional synchronization. It uses OAuth 2.0, queue-based outbound processing, scheduled inbound polling, and configurable conflict resolution to keep subscription data synchronized reliably without slowing Magento operations.
===== Product Information =====
**Product Name:** [[https://toweringmedia.com/toweringmedia-constant-contact-magento-2|Toweringmedia Constant Contact Extension for Magento 2]]
**Support & Updates:** 12 months included
===== Key Features =====
* Bidirectional synchronization between Magento customers, newsletter subscribers, and Constant Contact
* Secure Constant Contact API v3 integration using OAuth 2.0
* Database-backed queue for reliable outbound synchronization
* Scheduled inbound contact polling with synchronization checkpoints
* Magento Wins, Constant Contact Wins, and Newest Wins conflict-resolution options
* Automatic retry with exponential backoff for temporary API failures
* Loop prevention and idempotent processing to reduce duplicate synchronization
* Encrypted storage of OAuth access and refresh tokens
* Magento Admin controls for connecting, disconnecting, testing, and monitoring synchronization
* Manual synchronization and dry-run testing through Magento CLI commands
===== Installation =====
Please refer to the installation guide in the following article: [[https://toweringmedia.com/installation|https://toweringmedia.com/installation]]
===== Requirements =====
Before configuring the extension, ensure the following requirements are available:
* A supported Magento 2 installation
* An active Constant Contact account
* A Constant Contact developer application with an API Key and Client Secret
* The exact Magento OAuth callback URL registered in the Constant Contact developer portal
* HTTPS enabled for the Magento Admin URL
* Magento cron configured and running correctly
* Constant Contact list membership IDs for synchronization
* Magento Admin access for extension configuration
* Outbound server access to the Constant Contact API endpoints
===== Admin Configuration =====
After installing and enabling the extension, go to:
**Magento Admin > Stores > Configuration > Customers > Constant Contact (Towering Media)**
==== General Settings ====
* Enable or disable the Constant Contact integration.
* Enable the required outbound and inbound synchronization options.
* Select the appropriate website or store-view scope before saving configuration values.
==== OAuth Configuration ====
Enter the credentials generated from your Constant Contact developer application:
* API Key / Client ID
* Client Secret
* Redirect URI Override - leave empty to use the automatically generated Magento callback URL, or enter the exact registered callback URL when required.
The default callback URL follows this format:
https://your-domain.com/{admin_path}/constantcontact/oauth/callback
The callback URL configured in Magento must exactly match the URL registered in the Constant Contact developer portal.
==== Connect Constant Contact ====
After saving the OAuth credentials:
- Click **Connect**.
- Sign in to the required Constant Contact account.
- Approve the requested permissions.
- Constant Contact redirects back to Magento Admin.
- Confirm that the connection status shows as connected.
Access and refresh tokens are stored using Magento's encryption service.
==== Synchronization Settings ====
Configure the following synchronization options:
* Magento customer synchronization
* Magento newsletter-subscriber synchronization
* Outbound queue processing
* Scheduled inbound contact polling
* Constant Contact list membership IDs
* Synchronization batch or processing settings, where available
==== Conflict Resolution ====
Select how subscription conflicts between Magento and Constant Contact should be handled:
* **Magento Wins** - Magento is treated as the preferred source.
* **Constant Contact Wins** - Constant Contact membership is treated as the preferred source.
* **Newest Wins** - The most recently updated state is used.
Choose this setting carefully according to the store's subscription-management workflow.
==== Test the Connection ====
Click **API Smoke Test** to confirm that:
* OAuth authentication is valid.
* Magento can communicate with Constant Contact API v3.
* The configured account and tokens are working.
==== Disconnect ====
Use **Disconnect** when you need to remove the current Constant Contact authorization. After disconnecting, automatic synchronization cannot continue until the account is connected again.
===== Basic Usage and What to Expect =====
After the Constant Contact account is connected and synchronization settings are saved, the extension works automatically through Magento observers, the synchronization queue, and scheduled cron jobs.
==== Normal Synchronization Flow ====
* A Magento customer or newsletter-subscriber record is created or updated.
* The extension adds a synchronization request to its database-backed outbound queue.
* Magento cron or the synchronization CLI processes the queued request and sends the update to Constant Contact.
* The scheduled inbound process retrieves Constant Contact contact membership changes using synchronization checkpoints.
* Magento applies the configured conflict-resolution rule and records the result in the synchronization logs.
==== What to Expect ====
* Synchronization is asynchronous. Changes may not appear in Constant Contact or Magento immediately because they are processed by cron.
* Reliable Magento cron execution is required for automatic outbound queue processing and inbound polling.
* Temporary API failures and rate-limit responses are retried automatically using exponential backoff.
* Permanent errors are marked as failed and remain available for administrative review.
* Idempotent processing and synchronization hashes help prevent duplicate work and update loops.
* The selected conflict-resolution mode determines which subscription state is kept when Magento and Constant Contact disagree.
* Initial processing or large contact lists may take longer and may require batch-size or cron-frequency adjustments.
==== Monitoring Synchronization ====
Use the read-only synchronization queue and log grids in Magento Admin to review pending, processing, retry, completed, or failed operations. If a change has not synchronized, first confirm that cron is running, the OAuth connection is active, and the configured Constant Contact list membership IDs are correct.
==== Manual and Dry-Run Processing ====
Administrators can use the Magento CLI synchronization command for controlled manual processing. Dry-run mode can be used to validate the synchronization flow without applying live changes.
php bin/magento toweringmedia:constantcontact:sync --dry-run
==== Important Limitations ====
* Inbound synchronization primarily reconciles Magento newsletter subscription status. Customer information is updated only where supported and linked by the integration.
* The extension uses scheduled polling rather than Constant Contact webhooks.
* Campaign sending, journeys, ecommerce catalog synchronization, and storefront signup widgets are not included.
* Disconnecting the Constant Contact account stops synchronization until the account is authorized again.
===== Validation Checklist =====
After configuration, complete these checks before relying on automatic synchronization:
* Confirm that the ''Toweringmedia_ConstantContact'' module is enabled.
* Confirm that the extension settings are saved under the intended website or store scope.
* Verify that the OAuth callback URL exactly matches the URL configured in the Constant Contact developer application.
* Confirm that Magento Admin shows the Constant Contact account as connected.
* Run **API Smoke Test** and confirm that it completes successfully.
* Confirm that Magento cron is installed and running reliably.
* Test outbound synchronization by updating a Magento customer or newsletter subscriber, then verify that the queue item is processed and the Constant Contact list membership is updated.
* Test inbound synchronization by changing a contact's Constant Contact list membership, then verify that Magento reconciles the newsletter subscription status after the next polling cycle.
* Verify that the selected conflict-resolution mode produces the expected result when Magento and Constant Contact contain different subscription states.
* Review the synchronization queue and log grids for unexpected failures or a growing retry backlog.
* Run ''php bin/magento toweringmedia:constantcontact:sync --dry-run'' and confirm that it completes without unexpected errors.
* Confirm that application logs do not expose OAuth access tokens, refresh tokens, or the Client Secret.
===== Troubleshooting =====
Use the following checks when synchronization or authorization does not work as expected.
==== Constant Contact Does Not Connect ====
* Confirm that the API Key / Client ID and Client Secret are correct.
* Verify that the callback URL in Magento exactly matches the redirect URI registered in the Constant Contact developer application, including the protocol, domain, and Magento Admin path.
* Confirm that the Magento Admin URL uses HTTPS, save the configuration, and try **Connect** again.
==== API Smoke Test Fails ====
* Confirm that the account still shows as connected and that the configured Constant Contact account is active.
* Disconnect and reconnect the account if the authorization has expired or been revoked.
* Confirm that the Magento server can make outbound HTTPS requests to Constant Contact API endpoints.
==== Magento Changes Are Not Reaching Constant Contact ====
* Confirm that customer or newsletter-subscriber synchronization is enabled for the correct configuration scope.
* Verify that Magento cron is running and processing the outbound queue.
* Review the synchronization queue and logs for pending, retry, or failed items.
* Run ''php bin/magento toweringmedia:constantcontact:sync --dry-run'' to check the synchronization flow without applying live changes.
==== Constant Contact Changes Are Not Appearing in Magento ====
* Confirm that inbound synchronization is enabled and that the correct Constant Contact list membership IDs are configured.
* Allow time for the next scheduled polling cycle; inbound changes are not received through webhooks.
* Confirm that cron is running and review the synchronization logs for polling or checkpoint errors.
* Remember that inbound synchronization primarily reconciles newsletter subscription status; customer data is updated only where supported and linked.
==== Items Remain in Retry or Failed Status ====
* Temporary rate-limit and server errors are retried automatically with exponential backoff, so processing may be delayed during an API outage.
* Permanent API errors are marked as failed. Review the logged error, correct invalid configuration or contact data, and process the synchronization again.
* If the retry backlog continues to grow, confirm API availability, OAuth status, cron frequency, and processing settings.
==== Subscription Status Changes Unexpectedly ====
* Review the selected Magento Wins, Constant Contact Wins, or Newest Wins conflict-resolution mode.
* Confirm which system should be the preferred source for subscription changes, then save the appropriate mode at the correct configuration scope.
* Review synchronization timestamps and logs to determine which update was applied.
==== Before Contacting Support ====
* Record the Magento version, extension version, affected store or website scope, and approximate time of the issue.
* Include the relevant queue status and sanitized synchronization-log message.
* Never share OAuth access tokens, refresh tokens, authorization codes, or the Client Secret in screenshots or support messages.
===== Support =====
* [[mailto:support@toweringmedia.com|support@toweringmedia.com]]
* [[https://toweringmedia.com/magento-maintenance-support|Magento maintenance and support]]
===== Related Magento 2 docs =====
* [[https://toweringmedia.com/pub/docs/doku.php?id=magento2:extensions:start|Magento 2 extension index]]
* [[https://toweringmedia.com/pub/docs/doku.php?id=magento2:extensions:start|Global docs home]]