RFQ (Request for Quotation) Feature Development on 1C-Bitrix
On B2B sites, prices are often not published openly: they depend on volume, region, contract terms, or are simply managed manually. Instead of a "Buy" button, you need a "Request a Quote" button — RFQ (Request for Quotation). The standard 1C-Bitrix sale module is not suited for this task: it is designed for public pricing and immediate payment. RFQ is a separate process: request → manager processing → quotation → negotiation → order.
Process architecture
An RFQ request goes through several statuses: new → processing → quoted → accepted → rejected → ordered. After the accepted status, the customer can place an order at the agreed price through the standard sale module.
Request table bl_rfq:
CREATE TABLE bl_rfq (
id SERIAL PRIMARY KEY,
user_id INT REFERENCES b_user(ID),
status VARCHAR(30) DEFAULT 'new',
manager_id INT,
comment TEXT,
manager_note TEXT,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW(),
expires_at TIMESTAMP,
order_id INT
);
Request line items bl_rfq_items:
CREATE TABLE bl_rfq_items (
id SERIAL PRIMARY KEY,
rfq_id INT REFERENCES bl_rfq(id) ON DELETE CASCADE,
product_id INT NOT NULL, -- infoblock element ID
sku_id INT, -- trade offer ID
quantity NUMERIC(10,3),
unit VARCHAR(20),
price_requested NUMERIC(12,2), -- price requested by the customer (optional)
price_quoted NUMERIC(12,2), -- price quoted by the manager
comment TEXT
);
RFQ add-to-request interface
The "Request a Quote" button replaces the "Add to Cart" button on product cards — or coexists with it if some products have a public price.
Display logic: in result_modifier.php of the catalog.element component, check the product property PROPERTY_PRICE_ON_REQUEST or the absence of a price in $arResult['ITEM_PRICES']:
$showRFQ = ($arResult['ITEM_PRICES'][0]['PRICE'] ?? 0) === 0
|| $arResult['ITEM']['PROPERTIES']['PRICE_ON_REQUEST']['VALUE'] === 'Y';
$arResult['SHOW_RFQ'] = $showRFQ;
The button sends an AJAX request with product_id, sku_id, quantity to the RfqController::addItemAction() controller.
RFQ cart
The customer can add multiple items before submitting — similar to a cart, but for quotes. Data is stored in the session ($_SESSION['RFQ_ITEMS']) or in the bl_rfq table with draft status. When the request is submitted, the status changes to new and the manager receives a notification.
CRM processing and notifications
When a request transitions to new status, a lead or deal is created in the CRM via \Bitrix\Crm\LeadTable::add() or the REST API crm.deal.add. Product line items from bl_rfq_items are added to the deal via crm.deal.productrows.set.
Manager notification — via \Bitrix\Im\Notify::send() (internal Bitrix24 notifications) and email via \Bitrix\Main\Mail\Event::send() with the event template RFQ_NEW_REQUEST.
Issuing a quotation and converting to an order
The manager fills in price_quoted for each line item in the admin interface and sets the status to quoted. The customer receives an email with a link to their account, where they can see the quotation. On clicking "Accept" — status becomes accepted, after which an order is created in b_sale_order with fixed prices via CSaleOrder::Add() with forced PRICE passed per line item.
Case study: industrial equipment distributor
Situation: 4,000 SKUs with no public prices; managers processed requests via email manually, response time 2–3 days.
Implementation:
- RFQ cart with the ability to add multiple products
- Automatic deal creation in Bitrix24 CRM on request submission
- Customer account with request history and statuses
- Email notifications to manager (immediately) and customer (on status change)
- One-click conversion of an accepted quotation to an order
Result: request processing time reduced to 4 hours; managers stopped losing requests in their inboxes.
| Stage | Duration |
|---|---|
| Schema and state machine design | 2 days |
| Backend: tables, controllers, agents | 4 days |
| Frontend: button, RFQ cart, customer account | 4 days |
| CRM integration | 2 days |
| Email notifications and testing | 2 days |
What is included in development
- RFQ state machine and data model design
- "Add to Cart" button replacement/augmentation for products without a public price
- RFQ cart with AJAX line item management
- Admin interface for processing requests and setting prices
- Integration with the Bitrix24 CRM module (deals, product line items)
- Request history section in the customer account







