Appearance
Are you an LLM? You can read better optimized documentation at /flows/integration/IN-13-newsletter.md for this page in Markdown format
Newsletter Integrations (Mailchimp, Manago, Moosend, Apifon)
Flow ID: IN-13 | Module(s):
ecommercen/libraries/,src/Manago/,src/Moosend/,src/Apifon/| Complexity: High
Business Overview
Ecommercen integrates with four newsletter and marketing automation platforms to manage subscriber lists and track customer behavior. All integrations are triggered at two key customer touchpoints:
- Checkout -- Newsletter consent checkboxes during order completion subscribe or update the customer in the configured provider.
- Registration -- Account creation can automatically subscribe the customer.
Each provider has a distinct API style and feature set, but they share a common pattern: subscriber data is pushed from Ecommercen to the external platform (never pulled). The platform choice is per-client, configured via Registry settings.
| Provider | API Style | Key Features |
|---|---|---|
| Mailchimp | REST (Marketing API v3) | Two lists (site/checkout), interest groups, tags, double opt-in |
| Manago | REST (SHA-signed) | Contact upsert with consent, purchase events, product recommendations |
| Moosend | REST (API v3) | Subscribe with custom fields, contact existence check |
| Apifon | REST (OAuth2) | SMS + Viber messaging, subscriber list management |
API Reference
Mailchimp (Adv_Mailchimp_Api)
| Method | Description |
|---|---|
getAllLists($count, $offset) | Fetch all audience lists |
addMemberToList($listId, $data) | Subscribe a member to a list |
getCategoriesAndGroups($listId) | Fetch interest categories and groups for a list |
getListTags($listId) | Fetch tags for a list (includes custom site/checkout tags) |
getAllListsWithGroupsAndInterests() | Combined fetch: all lists with their groups, interests, and tags |
Manago (Advisable\Manago\Manago)
| Method | Parameters | Description |
|---|---|---|
contactExists($email) | string | Check if contact exists, returns contactId or null |
saveContact($contact, $consentGiven, $visitorIp) | array, bool, string | Upsert contact with consent details |
addEvent($userId, $userOptChoice, $eventData) | array, bool, array | Add purchase/behavior event to contact |
getRecommendations($endpoint, $params) | string, array | Fetch product recommendations for a contact |
getMaxCostSeconds() | -- | Returns max timeout for deferred task budget |
Moosend (Advisable\Moosend\Moosend)
| Method | Parameters | Description |
|---|---|---|
subscribe($listId, $subscribers) | string, array | Subscribe contacts with custom fields |
contactExists($listId, $email) | string, string | Check if contact exists in a list |
Apifon (Advisable\Apifon\Apifon) -- Newsletter Features
| Method | Parameters | Description |
|---|---|---|
subscribe($data) | array (to, email, firstName, lastName) | Add subscriber to configured list |
Note: Apifon also handles SMS/Viber messaging -- see IN-14 SMS Integrations.
Code Flow
Mailchimp Subscription at Checkout
Customer completes checkout with newsletter checkbox checked
-> Adv_checkout / Adv_order controller
-> Load Mailchimp library (namespace: Mailchimp\Adv_Mailchimp_Api)
-> initializeConfig():
- API_KEY, SERVER_PREFIX from Registry (MAILCHIMP group)
- SUBSCRIBE_AS_PENDING flag for double opt-in
- Custom tag names for site vs checkout subscriptions
-> addMemberToList($listId, [
'email_address' => $email,
'status' => $mailchimpSubscribeAsPending ? 'pending' : 'subscribed',
'merge_fields' => ['FNAME' => ..., 'LNAME' => ...],
'tags' => [$customCheckoutTag]
])
-> MailchimpMarketing\ApiClient handles REST call to Mailchimp API v3Manago Contact Sync
Customer registers or completes checkout
-> Controller loads Manago via DI: di()->get(Manago::class)
-> Manago::__construct(Registry, ?CircuitBreaker):
- Builds SHA1 signature: sha1(API_KEY + CLIENT_ID + API_SECRET)
- Sets requestTime = time() * 1000
-> saveContact($contact, $consentGiven, $visitorIp):
- POST to {API_BASE_URL}/contact/upsert
- Includes: clientId, apiKey, sha, requestTime, owner, contact data
- Consent details: consentName, agreementDate, ip, consentDescriptionId
- Double opt-in: useApiDoubleOptIn = true
- Consent flags: consentAccept/optOut based on $consentGiven
-> On successful order, addEvent() tracks purchase:
- POST to {API_BASE_URL}/v2/contact/addContactExtEvent
- Includes: contactEvent data with order details
- forceOptIn/forceOptOut based on customer preferenceManago Product Recommendations
Product page or recommendation widget
-> Manago::getRecommendations($endpoint, $params)
- POST to {API_BASE_URL}/recommendation/{endpoint}
- Params include shopName from registry
- Returns productIds array
- Circuit breaker protected: skips call if circuit is openMoosend Subscription
Customer action triggers subscribe
-> Moosend::__construct(Registry):
- API_KEY from Registry (MOOSEND group)
- Guzzle client with 2-second timeout
-> subscribe($listId, $subscribers):
- POST to subscribers/{listId}/subscribe.json?apikey={key}
- JSON body with subscriber data and custom fields
- Returns bool based on Code === 0 and no ErrorApifon Subscriber Management
Customer opts in for notifications
-> Apifon::__construct(Registry):
- Reads APIFON.* registry keys
- OAuth2 authentication on first call
-> subscribe($data):
- Check: enabled, subscribeToListEnabled
- authenticate(): POST to ids.apifon.com/oauth2/token (client_credentials)
- getList(): GET list details, validate required fields (FIRST_NAME, LAST_NAME)
- POST to /services/api/v1/list/{listId}/subscriber
- Body: destination, status=SUBSCRIBED, email, email_status=SUBSCRIBED, subscriber_fields
- HTTP 201 or 409 treated as success (409 = already exists)Architecture
ecommercen/libraries/
Adv_Mailchimp_Api.php # Mailchimp Marketing API v3 wrapper
src/Manago/
Manago.php # Manago REST API client with SHA-signed requests
src/Moosend/
Moosend.php # Moosend API v3 REST client
src/Apifon/
Apifon.php # Apifon OAuth2 + SMS/Viber/Subscriber API
ecommercen/feeds/controllers/
AdvManagoXml.php # Manago product feed (extends AdvGoogleCatalog)
application/modules/eshop/controllers/
Mailchimp.php # Admin Mailchimp management controller
application/controllers/
Manago.php # Client-level Manago controllerDependencies
| Class | External Dependency | Auth Method |
|---|---|---|
Adv_Mailchimp_Api | mailchimp-marketing-php SDK | API Key + Server Prefix |
Manago | Guzzle HTTP | SHA1(API_KEY + CLIENT_ID + API_SECRET) signature |
Moosend | Guzzle HTTP | API Key in query string |
Apifon | Guzzle HTTP | OAuth2 client_credentials + Bearer token |
Fault Tolerance
- Manago uses
CircuitBreaker(optional). When circuit is open, API calls return empty results without making network requests. Success/failure is recorded after each call. - Moosend has a 2-second request timeout.
- Apifon authenticates lazily (on first API call) and caches the access token for the request lifecycle.
Data Model
Manago Product Feed
The AdvManagoXml feed controller (extending AdvGoogleCatalog) exports products in Google Shopping XML format with Manago-specific ID prefixes (productIdToManagoId()). It includes a category field with the first parent category name.
Registry Keys Used
All provider settings are stored in the registry table and accessed via $this->registry->value('GROUP', 'KEY').
Configuration
Mailchimp (Registry)
| Group | Key | Description |
|---|---|---|
MAILCHIMP | ENABLED | Enable/disable Mailchimp integration |
MAILCHIMP | API_KEY | Marketing API key |
MAILCHIMP | SERVER_PREFIX | API server prefix (e.g., us19) |
MAILCHIMP | SUBSCRIBE_AS_PENDING | Double opt-in (pending) vs direct subscribe |
MAILCHIMP | CUSTOM_SITE_TAG_NAME | Tag name for site-originating subscriptions |
MAILCHIMP | CUSTOM_CHECKOUT_TAG_NAME | Tag name for checkout-originating subscriptions |
MAILCHIMP | SITE_TAG | Tag ID for site subscriptions |
MAILCHIMP | CHECKOUT_TAG | Tag ID for checkout subscriptions |
Manago (Registry)
| Group | Key | Description |
|---|---|---|
MANAGO | API_KEY | API authentication key |
MANAGO | CLIENT_ID | Client identifier |
MANAGO | API_SECRET | API secret for SHA signature |
MANAGO | API_BASE_URL | API base URL |
MANAGO | USER_ACCOUNT_EMAIL | Owner email for API requests |
MANAGO | CONSENT_NAME | GDPR consent name |
MANAGO | CONSENT_DESCRIPTION_ID | Consent description identifier |
MANAGO | TIMEOUT | Request timeout in seconds |
MANAGO | SHOP_NAME | Shop name for recommendations |
MANAGO | DEBUG_CALL | Enable request/response logging |
MANAGO | PRODUCT_ID_PREFIX_MANAGO | Product ID prefix for feed |
Moosend (Registry)
| Group | Key | Description |
|---|---|---|
MOOSEND | API_KEY | API authentication key |
Apifon (Registry)
| Group | Key | Description |
|---|---|---|
APIFON | ENABLED | Enable/disable Apifon integration |
APIFON | API_TOKEN | OAuth2 client_id |
APIFON | API_KEY | OAuth2 client_secret |
APIFON | SENDER_ID | SMS sender ID |
APIFON | TTL | Viber message TTL before SMS fallback |
APIFON | ENABLE_IM | Enable Viber instant messaging channel |
APIFON | SUBSCRIBE_TO_LIST_ENABLED | Enable subscriber list management |
APIFON | SUBSCRIBER_LIST_ID | Target subscriber list ID |
Client Extension Points
Mailchimp
- Override
application/libraries/Mailchimp_Api.phpto extendAdv_Mailchimp_Apiwith custom list logic. - Override
application/modules/eshop/controllers/Mailchimp.phpfor admin panel customization. - Two-list pattern: Configure separate Mailchimp lists for site newsletter signups vs checkout signups, with different tags applied to each.
Manago
- Override the DI container registration to inject custom
CircuitBreakerconfiguration. - Override
application/controllers/Manago.phpfor client-specific controller behavior. - The
AdvManagoXmlfeed can be overridden via the standard feed extension pattern. - Product ID prefix (
PRODUCT_ID_PREFIX_MANAGO) allows per-client ID namespacing.
Moosend
- The
Moosendclass is instantiated directly (not via DI), so client overrides require controller-level changes. - Custom fields in the
subscribe()payload are defined by the calling controller.
Apifon
- All configuration is registry-based, making it fully configurable per client without code changes.
- Subscriber list field validation (
FIRST_NAME,LAST_NAME) is checked dynamically against the Apifon list schema.
Business Rules
- Double opt-in: Mailchimp supports
SUBSCRIBE_AS_PENDINGfor GDPR-compliant double opt-in. When enabled, subscribers receive a confirmation email before being activated. - Consent tracking: Manago records explicit consent details (consent name, agreement date, IP address) for GDPR compliance. The
consentAccept/optOutflags are set based on the customer's explicit choice. - Two-list Mailchimp pattern: Sites can maintain separate audiences for newsletter signups (site footer) and checkout signups, with different tags to distinguish origin.
- Manago SHA signature: Every API request is signed with
SHA1(API_KEY + CLIENT_ID + API_SECRET)and timestamped. This prevents request tampering. - Manago recommendations: Product recommendations from Manago are used alongside internal recommendation engines. The circuit breaker ensures that recommendation failures do not impact page load times.
- Moosend deduplication: The
contactExists()check allows controllers to avoid duplicate subscription attempts. - Apifon 409 handling: HTTP 409 (Conflict) responses from the subscriber endpoint are treated as success, indicating the subscriber already exists.
- Provider selection: The active newsletter provider is a per-client choice configured via Registry settings. Multiple providers can be active simultaneously (e.g., Mailchimp for email + Apifon for SMS/Viber).
Related Flows
- CF-06 Order Preview / Checkout -- Newsletter consent checkboxes during checkout
- CF-10 Customer Auth -- Subscriber sync on registration
- IN-14 SMS Integrations -- Apifon SMS/Viber messaging capabilities
- IN-01 Feed Generation -- Manago product feed (AdvManagoXml)
- AD-13 Settings -- Admin configuration for newsletter providers
- SY-26 Circuit Breaker -- Manago is protected by a circuit breaker; when open, API calls return empty results without network requests