Development of Pre-Order Functionality for 1C-Bitrix
Product hasn't arrived at warehouse yet, but product card already in catalog. Standard Bitrix behavior — "Out of Stock" button and notification of arrival. This loses hot customer: he wants to buy now, not receive email next week. Pre-order solves the task: customer places order for unavailable product, locks in price and place in queue, store gets predictable demand.
How Pre-Order Differs from "Notify on Arrival"
catalog.subscribe module in Bitrix — stock availability subscription. User leaves email, on CATALOG_AVAILABLE = Y change receives letter. No order, no price lock, no queue.
Pre-order — full order with special status. Product reserved for customer, payment can be full, partial (deposit), or delayed. When product arrives — order moves to processing.
Mechanics at Catalog Level
Pre-order management starts with product property. Create iblock property PREORDER_AVAILABLE (type: list, values: Y/N). It determines if product available for pre-order when CATALOG_AVAILABLE = N.
In catalog.element template, button logic changes:
- If
CATALOG_AVAILABLE = Y— standard "Buy". - If
CATALOG_AVAILABLE = NandPREORDER_AVAILABLE = Y— "Pre-order" button. - If both
N— "Out of Stock" + subscription.
"Pre-order" button adds product to cart with marker. Store marker in basket element property: \Bitrix\Sale\BasketItem::setField('PROPS', ...) — add property IS_PREORDER = Y.
Stock Check Bypass
Main technical problem: Bitrix won't add zero-stock product to cart. Method \Bitrix\Catalog\Product\Basket::addProduct() checks CATALOG_AVAILABLE and returns error.
Two approaches:
1. Virtual pre-order warehouse. Create separate warehouse in Store → Warehouses named "Pre-order". When product marked available for pre-order — set quantity on this warehouse equal to pre-order limit (e.g., 100). Product becomes CATALOG_AVAILABLE = Y, but real warehouse empty. On order processing, manager sees product reserved on "Pre-order" warehouse and understands situation.
Advantage: no core modification needed. Works with standard checkout. Disadvantage: distorts stock in reports, requires discipline in 1C exchange.
2. Event Handler. Subscribe to OnBeforeBasketAdd or OnSaleBasketItemBeforeSaved and intercept stock check. If product marked PREORDER_AVAILABLE = Y — bypass stock validation. This approach cleaner but requires testing with each Bitrix update, as stock check mechanism changed between sale module versions.
Order Statuses
For pre-orders, create additional statuses in Store → Order Statuses:
| Code | Name | Description |
|---|---|---|
| PP | Pre-order accepted | Order created, product unavailable |
| PW | Awaiting delivery | Product ordered from supplier |
| PR | Product arrived | Can move to assembly |
Automation of PP → PR transition implemented via OnStoreProductUpdate handler. On stock change in main warehouse, check for orders in PP status with this product. If stock sufficient — change status to PR and send customer notification.
Pre-Order Payment
Three strategies:
Full Prepayment. Customer pays immediately. Simple scheme but risky for buyer — if delivery fails, refund needed.
Deposit. On pre-order checkout, create payment for fixed amount (e.g., 10-20% of value). Implemented via custom cart rule or creating two Payment in order: first — deposit (active), second — remainder (deferred). Method \Bitrix\Sale\Payment::setField('SUM', $depositAmount).
Payment on Arrival. Order created without payment. When product arrives — manager activates payment, customer gets payment link. For online payment use \Bitrix\Sale\PaySystem\Service::initiatePay() method, generating payment form.
Limits and Queue
Without limits pre-order becomes problem: 500 customers pre-ordered, delivery — 50 units. Limit set via product property PREORDER_LIMIT and checked on cart addition. Current pre-order count counted by query to b_sale_basket with filter by property IS_PREORDER = Y and binding to incomplete orders.
Queue formed by order creation date. On product arrival, priority given to early orders. Implemented by sorting ORDER BY DATE_INSERT ASC when selecting pre-orders to move to PR status.
Timelines
| Scale | What's Included | Timeline |
|---|---|---|
| Basic | Pre-order button, virtual warehouse, statuses | 4-5 days |
| Full | Deposit, automatic status changes, limits, notifications, 1C integration | 8-12 days |







