Product Reservation at a Specific Store in 1C-Bitrix
Reservation allows a customer to hold a product at the chosen store until payment or an in-store visit. The stock is reduced virtually — other customers see a lower quantity, even though the product is physically still on the shelf. This is a separate task from BOPIS: a product can be reserved without a subsequent online order, simply to "set it aside" for a visit.
Reservation Model in Bitrix
Bitrix has a built-in reservation mechanism via the b_catalog_store_product_reserve table. Fields:
-
STORE_ID— warehouse ID fromb_catalog_store -
PRODUCT_ID— product ID -
AMOUNT— reserved quantity -
ORDER_ID— link to an order (if the reservation comes from an order) -
DATE_RESERVE— reservation creation date -
DATE_RESERVE_END— reservation expiry date
Available quantity = b_catalog_store_product.AMOUNT − SUM(b_catalog_store_product_reserve.AMOUNT) for the given warehouse and product.
Creating a Reservation via API
CModule::IncludeModule('catalog');
$result = CCatalogStoreProductReserve::Add([
'STORE_ID' => $storeId,
'PRODUCT_ID' => $productId,
'AMOUNT' => $quantity,
'DATE_RESERVE' => new CDBDateTime(),
'DATE_RESERVE_END' => new CDBDateTime(time() + 86400 * 3), // 3 days
]);
When the reservation is released (expired or cancelled by the customer), CCatalogStoreProductReserve::Delete($reserveId) is called.
Reservation Form on the Website
A "Reserve in Store" button is placed on the product card. The form includes:
- Store selection from a list with current stock levels
- Quantity (with available stock validation)
- Contact details (name, phone number) for notification
- Reservation duration (typically 24–48 hours)
Query for available stock at a specific warehouse:
$available = CCatalogStoreProduct::GetList(
[],
['STORE_ID' => $storeId, 'PRODUCT_ID' => $productId],
false, false,
['AMOUNT']
)->Fetch()['AMOUNT'];
$reserved = array_sum(array_column(
CCatalogStoreProductReserve::GetList(
[], ['STORE_ID' => $storeId, 'PRODUCT_ID' => $productId]
)->fetchAll(), 'AMOUNT'
));
$canReserve = $available - $reserved;
Notifications Along the Reservation Lifecycle
| Event | Recipient | Channel |
|---|---|---|
| Reservation created | Customer | SMS + email |
| Reservation created | Store manager | |
| Reservation expiring in 2 hours | Customer | SMS |
| Reservation released (expired) | Manager | system notification |
Reminders are implemented via an agent that checks DATE_RESERVE_END every 30 minutes and sends notifications via CEvent::Send() or an SMS gateway.
Automatic Reservation Release
Agent for releasing expired reservations:
$expiredReserves = CCatalogStoreProductReserve::GetList(
[],
['<DATE_RESERVE_END' => date('Y-m-d H:i:s')]
);
while ($reserve = $expiredReserves->Fetch()) {
CCatalogStoreProductReserve::Delete($reserve['ID']);
// Notify manager
}
Admin Interface
The store manager should see a list of active reservations for their warehouse: product, quantity, customer contact, and expiry. The interface is built on AdminListTable or as a separate page in the "Warehouses" section.
What Is Included in the Setup
- Reservation form with store selection and stock validation
- Creating the reservation via
CCatalogStoreProductReserve::Add() - Agent for automatic release of expired reservations
- Notifications to customer and manager via SMS and email
- Admin interface for managing reservations for staff

