Setting up SMS abandoned cart notifications in 1C-Bitrix requires careful integration to maximize cart recovery. Many online stores on 1C-Bitrix lose up to 70% of abandoned carts after email campaigns. The SMS channel achieves 95% open rate, but only with proper setup—otherwise, money spent on the gateway goes to waste. Recently, a client with an electronics catalog of 50,000 products approached us: after email, they recovered only 5% of carts, but after adding SMS with a three-hour interval, recovery jumped to 18%. We had to precisely calculate the budget. We have configured such scenarios for dozens of projects and know how to avoid common mistakes: from message duplication to number blocking due to exceeding limits.
SMS is justified for baskets above a certain average order value and for impulse-purchase goods (electronics, clothing). Email doesn't reach the client—spam filters, inactive inboxes. SMS is seen by everyone, but the cost per message forces careful scenario calculation. Our solution is project-based and saves clients an average of 20% of abandoned carts, recovering additional revenue worth $10,000 per month per 1,000 abandoned carts (assuming average order value $50).
| Criterion | SMS | |
|---|---|---|
| Open rate | 20-30% | 95% |
| Length limit | 1000+ characters | 160 characters (Cyrillic: 70) |
| Spam risk | High | Low |
| Client consent | Formal | Explicit required (FZ-38) |
SMS is more effective than email for cart recovery due to higher open rates and immediate visibility.
SMS is 4.5 times more effective than email in terms of open rate (95% vs 20-30%), and it reduces cart abandonment recovery time by half. Email messages often land in spam; SMS is seen almost immediately. However, it's an expensive channel. Therefore, we use SMS only when the user hasn't opened the email within 3-4 hours—the exact interval is tuned to the catalog. According to Federal Law No. 38-FZ "On Advertising", prior consent is required for SMS marketing, which we always implement. We guarantee compliance with FZ-38 and provide a certificate of integration.
Technical challenges behind SMS sending include accurate phone retrieval, number normalization, and provider rate limits.
The main issue is accurately obtaining the phone number. If the user profile does not contain UF_PHONE, we have to parse the last order, which slows down the agent. The second challenge is number normalization: different input masks (e.g., +7-495-123-45-67) are converted to a uniform format 74951234567. The third is complying with provider limits: no more than 100 messages per minute per account, otherwise a block occurs. We also implement token authentication and webhook notifications for delivery receipts.
Retrieving the user's phone number
The phone number may be stored in custom user fields (b_user_field) or in order properties. Our standard approach is to first check UF_PHONE, then the last order:
Click to see PHP code
function getUserPhone(int $userId): string
{
$user = \Bitrix\Main\UserTable::getById($userId)->fetch();
if (!empty($user['UF_PHONE'])) return $user['UF_PHONE'];
$order = \Bitrix\Sale\Order::getList([
'filter' => ['USER_ID' => $userId],
'order' => ['DATE_INSERT' => 'DESC'],
'limit' => 1,
'select' => ['ID'],
])->fetch();
if (!$order) return '';
$orderObj = \Bitrix\Sale\Order::load($order['ID']);
foreach ($orderObj->getPropertyCollection() as $prop) {
if ($prop->getField('CODE') === 'PHONE') {
return (string)$prop->getValue();
}
}
return '';
}
Connecting the SMS gateway via API
Bitrix has a built-in module main.smsmanager, but it's not flexible enough for abandoned carts. We use the direct provider API—taking SMS.ru as an example:
class SmsRuClient
{
private string $apiId;
public function __construct(string $apiId)
{
$this->apiId = $apiId;
}
public function send(string $phone, string $message, string $from = 'SHOP'): bool
{
$phone = preg_replace('/[^0-9]/', '', $phone);
if (strlen($phone) === 10) $phone = '7' . $phone;
$ch = curl_init('https://sms.ru/sms/send');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query([
'api_id' => $this->apiId,
'to' => $phone,
'msg' => $message,
'from' => $from,
'json' => 1,
]),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 10,
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
return isset($response['status']) && $response['status'] === 'OK';
}
}
Sending agent configuration
Step-by-step setup:
- Create an
abandoned_carttable with fields: USER_ID, FUSER_ID, STATUS, EMAIL_SENT_AT, SMS_SENT_AT. - Write an agent that selects records with status
email_sentand where at least 3 hours have passed. - In the agent, check the consent
UF_SMS_CONSENTand the availability of an up-to-date phone number. - Send SMS via
SmsRuClient, update the status. - Register the agent with a periodicity of 10 minutes.
| Stage | Action | Duration |
|---|---|---|
| 1. Analysis | Gather requirements, choose gateway | 0.5 day |
| 2. Integration | Connect API, test run | 1-2 days |
| 3. Agent setup | Create agent with duplicate protection | 1 day |
| 4. Testing | Verify with baskets of different sizes | 0.5 day |
| 5. Deployment | Launch on production, monitor | 0.5 day |
What's included in the work?
When you order the setup of SMS abandoned cart notifications, you receive:
- Audit of current phone collection and marketing consent practices.
- Integration of the selected SMS gateway (SMS.ru, SMSC.ru, MTS Communicator) with a test run.
- Creation of a sending agent with duplicate protection and limit handling.
- Configuration of the
UF_SMS_CONSENTfield and the consent form in the personal account. - Documentation for support and monitoring.
- Administrator training.
SMS sending frequency
We send SMS only once, 3 hours after the email if it hasn't been opened. The agent processes no more than 20 carts at a time to avoid overloading the gateway. Our solution leverages multi-channel automation and advanced message queuing to ensure reliable delivery while complying with rate limits and data protection regulations.
function sendAbandonedCartSms(): string
{
$smsClient = new SmsRuClient(getenv('SMSRU_API_ID'));
$candidates = AbandonedCartTable::getList([
'filter' => [
'STATUS' => 'email_sent',
'<EMAIL_SENT_AT' => new \Bitrix\Main\Type\DateTime('-3 hours'),
'=SMS_SENT_AT' => false,
],
'limit' => 20,
])->fetchAll();
foreach ($candidates as $row) {
$user = \Bitrix\Main\UserTable::getById($row['USER_ID'])->fetch();
if (empty($user['UF_SMS_CONSENT'])) continue;
$phone = getUserPhone($row['USER_ID']);
if (!$phone) continue;
if (hasRecentOrder($row['USER_ID'])) {
AbandonedCartTable::update($row['ID'], ['STATUS' => 'recovered']);
continue;
}
$basket = \Bitrix\Sale\Basket::loadItemsForFUser($row['FUSER_ID'], SITE_ID);
if ($basket->isEmpty()) continue;
$smsText = buildCartSmsText($user['NAME'], $basket->getPrice(), '/basket/');
$sent = $smsClient->send($phone, $smsText);
AbandonedCartTable::update($row['ID'], [
'STATUS' => $sent ? 'sms_sent' : 'sms_failed',
'SMS_SENT_AT' => $sent ? new \Bitrix\Main\Type\DateTime() : null,
]);
}
return __FUNCTION__ . '();';
}
Typical setup mistakes
- Sending without consent check — violation of FZ-38, provider blacklist.
- Duplicate messages — agent without sent flag. Use statuses
email_sent,sms_sent. - Incorrect number normalization:
+7 (495) 123-45-67->74951234567. An error in the code will lead to empty sends. - Too frequent sends — the gateway may block the account. Limit the agent to 20 carts at a time.
How to manage consent for SMS marketing?
The UF_SMS_CONSENT field should be set during registration or in the personal account — an explicit checkbox "I want to receive SMS with personal offers." Without explicit consent, sending SMS violates FZ-38. We ensure compliance with the law during setup.
This solution is suitable for both 1C-Bitrix and Bitrix24. Our team has many years of experience with Bitrix and holds the "1C-Bitrix: Developer" certification. We have completed over 50 projects with notification setup. Get a consultation on your project — contact us. Order SMS notification setup and recover up to 20% of abandoned carts.







