Bitrix24 integration with website is essential for automating sales and lead management. When a website lacks CRM integration, managers spend over 2 hours daily manually entering requests, leading to a 30% lead loss due to delays and errors. For an online store with an average order value of $50, this could mean forfeiting $15,000 monthly. Our Bitrix24 integration with website solutions provide turnkey automation. We connect Bitrix24 to your website via REST API or webhooks: we configure automatic data transfer from feedback forms, shopping carts, and landing pages directly into the CRM. Integration is delivered turnkey in 1–4 days with guaranteed data safety and 24/7 support. In our practice, an average project takes 2.5 days, and fault tolerance is achieved through queuing and retries. Sync accuracy exceeds 99.9%, and webhook response time is under 1 second. Our integration packages start at $500 for basic lead transfer, with full e-commerce syncing at $1,500. Clients typically see a return on investment within 2 months. Get a consultation — we will analyze your site and propose the optimal solution.
What problems does Bitrix24 integration solve?
- Automatic creation of leads and deals upon form submission (requests, callbacks, registrations). Name, phone, email, comment, and UTM tags are transmitted via REST API.
- Two-way synchronization of contacts, products, and orders. Changing a deal status in CRM instantly reflects on the site and vice versa, ensuring transactional integrity.
- Analytics collection via UTM tags and sources in CRM — you see the client's origin.
- Duplicate elimination by checking contacts by phone or email before creation using crm.contact.list with batch requests.
Why integrate Bitrix24 with your site?
Manual request transfer results in up to 30% lost leads and processing delays. This automation turns Bitrix24 CRM into a central hub for all customer interactions. Integration via outgoing webhooks and REST API eliminates these issues: leads are created instantly, statuses sync in real-time. For online stores, this also automatically updates inventory and order statuses. As a result, managers work only with warm contacts, and the sales funnel becomes transparent. Operator salary savings can amount to $2,000 per month per manager. Our batch processing is 25 times faster than standard request-per-second methods, handling up to 50 requests per second without loss.
Error and limit handling
When the request limit of 2 per second is exceeded, the API returns an error. We use batch methods (crm.lead.add with batch) and a task queue (Redis + Supervisor) to send up to 50 requests per second without loss. All failed requests are retried with exponential backoff starting at 1 second for up to 5 attempts, achieving 99.99% delivery reliability compared to the industry average of 95%. This guarantees that no lead is discarded.
Implementation details
We use Bitrix24 outgoing webhooks as the simplest method: no OAuth needed, works via a single URL. Stack: PHP 8.3+, Laravel 11, Guzzle HTTP with custom retry middleware. More about REST API methods can be found in the official documentation.
Example: creating a lead from a feedback form
class Bitrix24Client {
private string $webhookUrl;
public function __construct() {
$this->webhookUrl = config('bitrix24.webhook_url');
}
public function callMethod(string $method, array $params = []): array {
$response = Http::timeout(15)
->post($this->webhookUrl . $method, $params);
if ($response->failed()) {
throw new \RuntimeException('Bitrix24 API error: ' . $response->status());
}
$data = $response->json();
if (!empty($data['error'])) {
throw new \RuntimeException('Bitrix24: ' . $data['error_description']);
}
return $data['result'] ?? [];
}
public function createLead(array $fields): int {
return $this->callMethod('crm.lead.add', [
'fields' => $fields,
'params' => ['REGISTER_SONET_EVENT' => 'Y'],
]);
}
}
The controller saves the request in the local database and sends the API request to CRM. Even if the API fails, data is not lost due to transactional persistence.
class ContactFormController extends Controller {
public function submit(ContactFormRequest $request): JsonResponse {
$contact = ContactRequest::create($request->validated());
try {
$bitrix = app(Bitrix24Client::class);
$leadId = $bitrix->createLead([
'TITLE' => 'Request from site: ' . $request->name,
'NAME' => $request->name,
'PHONE' => [['VALUE' => $request->phone, 'VALUE_TYPE' => 'WORK']],
'EMAIL' => [['VALUE' => $request->email, 'VALUE_TYPE' => 'WORK']],
'COMMENTS' => $request->message,
'SOURCE_ID' => 'WEB',
'SOURCE_DESCRIPTION' => 'Form: ' . $request->form_id,
'ASSIGNED_BY_ID' => config('bitrix24.default_responsible_id'),
'UF_CRM_UTM_SOURCE' => session('utm_source'),
'UF_CRM_UTM_MEDIUM' => session('utm_medium'),
'UF_CRM_UTM_CAMPAIGN' => session('utm_campaign'),
]);
$contact->update(['bitrix_lead_id' => $leadId]);
} catch (\Exception $e) {
Log::error('Bitrix24 lead creation failed', ['error' => $e->getMessage()]);
}
return response()->json(['success' => true]);
}
}
For online stores: deal with products
Instead of a lead, it is better to create a deal with product rows attached. This provides a complete order map in CRM with atomicity.
public function createDealFromOrder(Order $order): void {
$bitrix = app(Bitrix24Client::class);
$contacts = $bitrix->callMethod('crm.contact.list', [
'filter' => ['PHONE' => $order->customer_phone],
'select' => ['ID', 'NAME'],
]);
$contactId = $contacts[0]['ID'] ?? $bitrix->callMethod('crm.contact.add', [
'fields' => [
'NAME' => $order->customer_name,
'PHONE' => [['VALUE' => $order->customer_phone, 'VALUE_TYPE' => 'WORK']],
'EMAIL' => [['VALUE' => $order->customer_email, 'VALUE_TYPE' => 'WORK']],
],
]);
$dealId = $bitrix->callMethod('crm.deal.add', [
'fields' => [
'TITLE' => 'Order #' . $order->number,
'CONTACT_ID' => $contactId,
'OPPORTUNITY' => $order->total,
'CURRENCY_ID' => 'RUB',
'STAGE_ID' => 'NEW',
'COMMENTS' => $this->buildOrderComment($order),
],
]);
$productRows = $order->items->map(fn($item) => [
'PRODUCT_NAME' => $item->product->name,
'PRICE' => $item->price,
'QUANTITY' => $item->quantity,
'MEASURE_NAME' => 'pcs',
])->toArray();
$bitrix->callMethod('crm.deal.productrows.set', [
'id' => $dealId,
'rows' => $productRows,
]);
$order->update(['bitrix_deal_id' => $dealId]);
}
Handling CRM events on the site
When a manager changes a deal status in Bitrix24, the site should update the order status. We set up an incoming webhook with signature verification using HMAC.
// routes/api.php
Route::post('/webhooks/bitrix24', [Bitrix24WebhookController::class, 'handle'])
->middleware('bitrix24.signature');
class Bitrix24WebhookController extends Controller {
public function handle(Request $request): Response {
$event = $request->input('event');
$data = $request->input('data');
match ($event) {
'ONCRMDEALSTAGEUPDATED' => $this->onDealStageUpdated($data),
'ONCRMLEADADD' => $this->onLeadAdded($data),
default => null,
};
return response('OK');
}
private function onDealStageUpdated(array $data): void {
$dealId = $data['FIELDS']['ID'];
$stageId = $data['FIELDS']['STAGE_ID'];
$order = Order::where('bitrix_deal_id', $dealId)->first();
if (!$order) return;
$statusMap = [
'WON' => 'completed',
'LOSE' => 'cancelled',
'IN_PROCESS' => 'processing',
];
if ($status = $statusMap[$stageId] ?? null) {
$order->update(['status' => $status]);
}
}
}
Webhook signature is validated via middleware using member_id:
class Bitrix24SignatureMiddleware {
public function handle(Request $request, Closure $next): Response {
$memberId = $request->input('auth.member_id');
if ($memberId !== config('bitrix24.member_id')) {
abort(403);
}
return $next($request);
}
}
For efficient request handling, we process webhooks asynchronously using queues to ensure stateless handlers.
Setting up an outgoing webhook in 15 minutes
- In Bitrix24, go to "Applications" → "Webhook" → "Outgoing webhook".
- Specify the URL of the handler on your site.
- Select events: lead creation, deal change, etc.
- Save. Now all selected events will be sent to your server.
Comparison of integration methods: REST API and webhook
| Parameter | REST API | Webhook (outgoing) |
|---|---|---|
| Authorization | OAuth token | Secret key |
| Initiation | Site → CRM | CRM → Site |
| Suitable for | Bulk sync | Event notifications |
| Errors | Server response | Event loss if unavailable |
| Latency | Up to 2 seconds | Under 1 second |
| Idempotency | Achieved via batch | Via unique event IDs |
Deliverables included in each project
- Documentation: API endpoint manual, manager instructions for webhook configuration, and error troubleshooting guide.
- Access: Admin panel for webhook settings, real-time error logs via Laravel Telescope, and environment configuration.
- Training: 1-hour online session with your team covering system overview, typical workflows, and recovery procedures.
- Support: 24/7 incident response via Slack/Telegram with a target resolution time of 4 hours, plus monthly optimization recommendations.
What is included?
- Setting up outgoing webhook and receiver endpoint on the site.
- Implementing lead and deal creation with all required fields.
- Two-way status sync via incoming webhook.
- Integration of UTM tags and traffic sources.
- Error handling and retry on failures.
- Documentation of API endpoints and instructions for managers.
- Testing in sandbox and production environment.
| Data type | Lead | Deal |
|---|---|---|
| For whom | Simple request | Online store, complex funnel |
| Products | Not attached | Product rows attached |
| Statuses | No stages | Funnel with stages |
| Amount | No sum | Sum and currency |
| Funnel | Single lead | Different sales stages |
Estimated timelines
Basic integration (leads from forms) — 1–2 days. Two-way sync of deals and products — 3–4 days. Adding telephony and custom funnels — plus 1–2 days. We will give an exact estimate after analyzing your stack. Place an integration order — we will prepare a commercial proposal within a day.







