Setting up BOPIS (Buy Online Pick up In Store) in 1C-Bitrix

Our company is engaged in the development, support and maintenance of Bitrix and Bitrix24 solutions of any complexity. From simple one-page sites to complex online stores, CRM systems with 1C and telephony integration. The experience of developers is confirmed by certificates from the vendor.
Our competencies:
Development stages

BOPIS (Buy Online Pick up In Store) Setup for 1C-Bitrix

BOPIS is a scenario in which a customer places an order online but picks it up at a physical store. It sounds simple, but behind it lies an integration of several modules: warehouse management, store geolocation, stock reservation, and order-ready notifications.

Bitrix Components for BOPIS

In Bitrix, BOPIS is built on three standard modules:

sale — order management. Delivery methods are created via CSaleDelivery::Add(). A separate delivery method with zero cost and type PICKUP is created for in-store pickup.

catalog — warehouse management. Warehouses (pickup stores) are stored in b_catalog_store. Stock levels by warehouse are in b_catalog_store_product. Key fields: STORE_ID, PRODUCT_ID, AMOUNT.

sale.location — locations. Linking stores to cities via b_sale_location and b_sale_location_service.

Data Model for a Store Network

Each physical store is set up as a warehouse in b_catalog_store:

  • TITLE — store name
  • ADDRESS — address displayed to the customer
  • GPS_N, GPS_S — coordinates for the map
  • PHONE — contact phone number
  • SCHEDULE — working hours (free text or JSON structure)
  • IMAGE_ID — link to a store photo from b_file

Working hours are more conveniently stored as JSON in a separate UF field UF_SCHEDULE_JSON:

{"mon": "10:00-21:00", "tue": "10:00-21:00", "sun": "11:00-20:00"}

Store Selection at Checkout

On the checkout page, the customer sees a map or list of stores with current stock for the selected product. Stock availability query:

$storeData = CCatalogStoreProduct::GetList(
    ['STORE_ID' => 'ASC'],
    ['PRODUCT_ID' => $productId, '>AMOUNT' => 0],
    false,
    false,
    ['STORE_ID', 'AMOUNT']
);

The list of warehouses with non-zero stock is displayed on a map via Yandex Maps API or Leaflet. Coordinates are taken from b_catalog_store.GPS_N and b_catalog_store.GPS_S.

Stock Reservation When a Store Is Selected

When a specific store is selected and the order is placed, the stock in b_catalog_store_product is reduced by the order quantity. In Bitrix this happens automatically upon write-off through the catalog module, if the reservation settings are enabled:

Settings → Online Store → Settings → Reservation and Shipment → "Reserve on checkout"

But for BOPIS, reservation must be linked to a specific warehouse (store). This requires customization: in the standard OnSaleOrderSaved event handler, logic is added to reserve stock specifically from the warehouse chosen by the customer. The warehouse is passed via the order property STORE_ID.

Ready-for-Pickup Notification

Changing the order status to "Ready for Pickup" (a custom status, e.g. READY_PICKUP) sends an SMS and/or email to the customer. Handler:

AddEventHandler('sale', 'OnSaleStatusOrder', function($orderId, $statusId) {
    if ($statusId === 'READY_PICKUP') {
        // Send SMS via gateway
        // Send email via CEvent::Send()
    }
});

What Is Included in the Setup

  • Creating store warehouses in b_catalog_store with coordinates and schedule
  • Configuring the "In-store Pickup" delivery method in the sale module
  • Store selection component with map and stock display
  • Reserving stock at a specific warehouse on order placement
  • Custom "Ready for Pickup" order status and notifications on status change
  • Admin interface for store staff (order status change)