1C-Bitrix Integration with Mailchimp
Mailchimp is the most widely used Western ESP, featuring a powerful API and mature automation tools. For Russian-language projects, its use is justified when working with an international audience or when the client already runs their marketing through Mailchimp.
Mailchimp API v3
Mailchimp provides REST API v3. The base URL depends on the account's data center: https://us1.api.mailchimp.com/3.0/ (replace us1 with your account's data center — it is shown in the URL after login).
Authentication uses Basic Auth: any string as the username, API key as the password (from Account → API Keys).
Adding a subscriber to an Audience (list)
class MailchimpClient {
private string $apiKey;
private string $dataCenter;
private string $listId;
public function __construct() {
$this->apiKey = COption::GetOptionString('site', 'mailchimp_api_key');
$this->dataCenter = explode('-', $this->apiKey)[1]; // us1, us2, etc.
$this->listId = COption::GetOptionString('site', 'mailchimp_list_id');
}
public function upsertMember(string $email, array $mergeFields = [], array $tags = []): array {
$subscriberHash = md5(strtolower($email));
$url = "https://{$this->dataCenter}.api.mailchimp.com/3.0/lists/{$this->listId}/members/{$subscriberHash}";
$http = new \Bitrix\Main\Web\HttpClient();
$http->setHeader('Authorization', 'Basic ' . base64_encode('anystring:' . $this->apiKey));
$http->setHeader('Content-Type', 'application/json');
$data = [
'email_address' => $email,
'status_if_new' => 'subscribed', // do not overwrite the status of unsubscribed members
'merge_fields' => $mergeFields, // FNAME, LNAME, PHONE, CITY, etc.
'tags' => $tags,
];
// PUT — creates or updates (upsert)
$response = $http->query(HttpClient::HTTP_PUT, $url, json_encode($data));
return json_decode($response, true);
}
}
The PUT /members/{hash} method acts as an upsert — it creates a new subscriber or updates an existing one by the email hash. This prevents duplicates.
Merge fields and tags
Merge fields — custom audience fields in Mailchimp. Standard fields: FNAME, LNAME. Create additional ones in the audience settings:
| Merge tag | Type | Source in Bitrix |
|---|---|---|
FNAME |
Text | USER.NAME |
LNAME |
Text | USER.LAST_NAME |
PHONE |
Phone | USER.PERSONAL_PHONE |
CITY |
Text | Profile property |
ORDERS |
Number | Order count |
LTV |
Number | Total order value |
Tags — free labels for segmentation. Synchronized with Bitrix user groups (b_user_group):
// Get Mailchimp tags for a user
function getUserMailchimpTags(int $userId): array {
$tags = [];
$groups = CUser::GetUserGroup($userId);
$tagMap = ['9' => 'buyer', '12' => 'vip', '15' => 'wholesale'];
foreach ($groups as $groupId) {
if (isset($tagMap[$groupId])) $tags[] = $tagMap[$groupId];
}
return $tags;
}
Case: abandoned cart
Situation. An electronics e-commerce store with a 18% cart conversion rate. Goal: automatically send an email with the cart contents 1 hour after items are added, if the order has not been placed.
Implementation. Bitrix stores carts of unregistered users in b_sale_basket. On cart save (OnSaleBasketSaved), schedule an agent for 1 hour later:
AddEventHandler('sale', 'OnSaleBasketSaved', function($basket) {
$userId = $basket->getFUserId();
// Agent will check in one hour — if no order was placed, push to Mailchimp
CAgent::AddAgent(
'AbandonedCartAgent::check(' . $userId . ');',
'my_module', 'N', 3600 // after 3600 seconds
);
});
The agent checks: if no order was created, it passes the cart data to Mailchimp via POST /lists/{id}/members/{hash}/events — the abandoned_cart event triggers the automation in Mailchimp.
Handling the unsubscribe webhook
Mailchimp sends a POST to the configured URL on unsubscribe or bounce:
// /bitrix/tools/mailchimp_webhook.php
$data = $_POST;
if ($data['type'] === 'unsubscribe') {
$email = $data['data']['email'];
// Update status in Bitrix
$mailchimp->updateLocalSubscription($email, 'unsubscribed');
}
if ($data['type'] === 'cleaned') {
// Hard bounce — address is invalid
$mailchimp->markEmailInvalid($data['data']['email']);
}
| Task | Effort |
|---|---|
| API client + basic synchronization | 4–6 h |
| Merge fields + tags by group | 3–4 h |
| Abandoned cart automation | 6–8 h |
| Unsubscribe and bounce webhooks | 3–4 h |







