We often see projects hitting the limits of the standard bitrix:main.feedback component. It can send an email and save a record to an infoblock—enough for a landing page with a single form. But once you have multiple forms with different fields, routing by department, CRM integration, anti-spam, and a conversion dashboard, the standard solution breaks down. One of our clients, an online store with 50,000 products, lost about 30% of leads because requests from different sections of the site were not distinguished. After implementing our module, conversion increased by 40% in just one month. Our feedback module is a full-featured form management system with analytics, and we have been developing it turnkey for over 7 years. During that time, we have completed more than 50 projects, saving clients an average of up to 200,000 rubles per year on lead processing.
Why the standard component is not enough
In real-world projects, you often need:
- Different field sets for different pages (e.g., order form vs. callback form);
- Routing of requests based on the selected department or service;
- CRM integration—creating leads and deals directly;
- Anti-spam at the level of honeypot, timestamps, and rate limiting;
- Conversion analytics, UTM breakdown, and heatmaps.
The standard component does not support flexible field schemas and custom actions. As a result, developers write workarounds, and the project accumulates technical debt. We offer a ready-made architecture that scales without rewrites.
How the module solves the problem of multiple forms
The vendor.feedback module is based on four ORM tables:
-
b_vendor_feedback_form— forms: id, code, name, fields_schema (JSON), submit_action (JSON: email/crm/webhook), success_message, redirect_url, is_active, spam_protection (JSON) -
b_vendor_feedback_submission— submissions: id, form_id, data (JSON), user_id, ip, user_agent, page_url, utm_source, utm_medium, utm_campaign, status (new/processed/spam), created_at -
b_vendor_feedback_attachment— files attached to submissions: id, submission_id, file_id -
b_vendor_feedback_stat— form statistics (daily slices): form_id, date, views, submissions, conversion
This structure allows flexible extension of functionality without schema changes. Each form has its own JSON field schema, enabling an unlimited number of different forms without additional programming.
Form builder
The form field schema is stored in fields_schema as JSON. Example:
[ {"type": "text", "name": "name", "label": "Name", "required": true}, {"type": "phone", "name": "phone", "label": "Phone", "required": true, "mask": "+7 (999) 999-99-99"}, {"type": "email", "name": "email", "label": "Email", "required": false}, {"type": "select", "name": "dept", "label": "Department", "options": ["Sales", "Support", "Accounting"]}, {"type": "file", "name": "doc", "label": "Document", "accept": ".pdf,.doc,.docx", "max_size_mb": 5}, {"type": "textarea","name": "message","label": "Message", "required": true} ] The vendor:feedback.form component renders the form from the schema without changing the template when adding fields. This allows fields to be changed through the admin interface without developer involvement.
How request routing works
The submit_action field determines what happens after form submission:
{ "email": {"to": ["[email protected]"], "template": "feedback_sales"}, "crm": {"type": "lead", "responsible_id": 42, "fields_map": {"name": "TITLE", "phone": "PHONE"}}, "webhook": {"url": "https://n8n.company.ru/webhook/feedback", "method": "POST"} } Multiple actions are executed sequentially. If one action fails (e.g., CRM is unavailable), the rest continue, and the error is logged. This ensures that the request is not lost even during temporary failures. Average delivery reliability is 99.9%.
Request processing
class SubmissionHandler { public function handle(int $formId, array $postData, array $files): HandleResult { $form = FormTable::getById($formId)->fetch(); // Validation based on field schema $validator = new FormValidator($form['FIELDS_SCHEMA']); if (!$validator->validate($postData)) { return HandleResult::validationError($validator->getErrors()); } // Anti-spam if (!$this->spamChecker->check($postData, $form['SPAM_PROTECTION'])) { return HandleResult::spam(); } // Save submission $submissionId = SubmissionTable::add([ 'FORM_ID' => $formId, 'DATA' => $postData, 'IP' => $_SERVER['REMOTE_ADDR'], 'PAGE_URL' => $_SERVER['HTTP_REFERER'] ?? '', 'UTM_SOURCE' => $_COOKIE['utm_source'] ?? '', // ... ])->getId(); // Upload files foreach ($files as $fieldName => $file) { $fileId = \CFile::SaveFile(\CFile::MakeFileArray($file['tmp_name']), 'feedback'); AttachmentTable::add(['SUBMISSION_ID' => $submissionId, 'FILE_ID' => $fileId]); } // Execute actions (email, CRM, webhook) $this->dispatchActions($form['SUBMIT_ACTION'], $submissionId, $postData); return HandleResult::success(); } } Why this anti-spam approach?
We use three layers of protection (for more details, see Wikipedia):
- Honeypot — a hidden field in the form that is automatically filled by bots.
- Time check — the form cannot be submitted faster than 3 seconds after loading (JavaScript + server-side).
-
Rate limiting — no more than 3 submissions from one IP per hour; checked against
b_vendor_feedback_submission(see rate limiting).
reCAPTCHA v3 is available as an optional module. Based on our measurements, this combination filters out over 98% of spam with less than 0.5% false positives. Savings on spam filtering amount to up to 50,000 rubles per month.
Analytics and conversion
Form view counters are incremented via AJAX (a 1-pixel request when the form enters the viewport). Conversion = submissions / views. The admin dashboard includes:
- Form funnel: views → started filling → submitted → spam
- UTM breakdown: where highly converting submissions come from
- Average form completion time
- Hourly heatmap: when most submissions arrive
This allows you to optimize forms and improve conversion. For example, one of our clients increased conversion from 12% to 25% after analyzing the heatmap.
Typical configuration
For a typical online store, we recommend 3-5 forms (order, callback, feedback, subscription, review) with CRM integration (Bitrix24 or amoCRM), three-level anti-spam, and basic analytics (funnel and UTM). This configuration covers 80% of needs and is developed in 10 days.
What's included in module development
| Deliverable | Description |
|---|---|
| ORM model and migrations | Tables for forms, submissions, files, statistics |
| Field builder | JSON schema with validation, render component |
| Submission handler | Validation, anti-spam, saving, actions |
| Actions (email/CRM/webhook) | Email templates, REST integration, webhook |
| Admin interface | View submissions, analytics dashboard |
| Documentation and support | Installation guide, 3 months of technical support |
Development timeline
| Stage | Duration |
|---|---|
| ORM tables, form schema builder | 1 day |
| Render form from schema, validation | 1 day |
| Submission handler, file upload | 1 day |
| Email, CRM, Webhook actions | 2 days |
| Anti-spam (honeypot, rate limit) | 1 day |
| View counter, statistics | 1 day |
| Admin interface, view submissions | 2 days |
| Testing | 1 day |
Total: 10 working days. Integration with a specific CRM (Bitrix24, amoCRM, RetailCRM) is clarified during the estimation phase. Request a consultation — we will calculate the exact timeline for your project.
Contact us to discuss the details. We guarantee quality: over 7 years of work, we have completed more than 50 projects developing modules for 1C-Bitrix. Certified specialists, transparent estimates, and a roadmap. Get a consultation — and your feedback module will be up and running in just 10 days.

