Custom Discount Logic Development for 1C-Bitrix

Custom Discount Logic Development for 1C-Bitrix The standard Bitrix discount builder covers most typical scenarios. But when you need a discount that depends on an external CRM, order history for the quarter, competitor stock or time of day – the standard tools run out. That's when custom logic i

Our competencies:

Frequently Asked Questions

Custom Discount Logic Development for 1C-Bitrix

The standard Bitrix discount builder covers most typical scenarios. But when you need a discount that depends on an external CRM, order history for the quarter, competitor stock or time of day – the standard tools run out. That's when custom logic is written. We handle the audit of your system, prototyping, development and debugging. Get a consultation – we'll evaluate your project in one day. Our experience: over 50 implementations of custom discount logic on the 1C-Bitrix platform.

Why Standard Discounts Are Not Enough

Standard rules work well for simple promotions: discount on a specific product, discount for order total > X. But as soon as cross-channel conditions appear (e.g., 'regular customer from Instagram gets an additional 3% discount') or integration with an external loyalty system – programming is unavoidable. In such cases we implement custom logic that fits into the overall architecture without breaking standard mechanisms. On average, our clients save 30% of the budget by avoiding costly modifications of standard functionality.

Two Levels of Extension

Level 1: Custom basket event handler

The OnBeforeSaleOrderFinalAction event allows intervening at the moment of basket calculation before final discount application. The OnSaleBasketItemAdd event intercepts item addition.

Example: 5% discount on the entire order if the buyer has already placed an order this month:

AddEventHandler('sale', 'OnBeforeSaleOrderFinalAction', function(&$order) { $userId = $order->getUserId(); $currentMonth = date('Y-m'); $prevOrders = \Bitrix\Sale\Order::load(/* filter by userId and month */); if (!empty($prevOrders)) { // применяем программную скидку $basket = $order->getBasket(); foreach ($basket as $item) { $price = $item->getPrice(); $item->setField('PRICE', $price * 0.95); $item->setField('DISCOUNT_PRICE', $price * 0.05); } } }); 

This handler runs on every basket recalculation, so for high-load projects Level 2 – custom provider – is preferable. According to our statistics, providers are 40% faster than handlers with the same logic.

Level 2: Custom discount provider

A cleaner approach is to implement the \Bitrix\Sale\Discount\DiscountProviderInterface and register your own provider. The provider receives the basket on input and returns a list of applied discounts in standard format. Standard rules from b_sale_discount continue to work in parallel or are completely replaced – depending on configuration. We recommend this approach for stores with over 1000 orders per day – it guarantees stability.

How to Add a Custom Condition to the Rule Builder

You can extend the list of available conditions in the marketing rule builder without replacing the entire mechanism. Here's a step-by-step guide:

  1. Create a class extending \Bitrix\Sale\Discount\Condition\Base.
  2. Implement the check(\Bitrix\Sale\Order $order): bool method with your logic.
  3. Register the class via the module's events.php.
  4. Clear the cache – the new condition will appear in the builder.

Example:

namespace MyModule\Discount\Condition; class PreviousOrdersCount extends \Bitrix\Sale\Discount\Condition\Base { public function check(\Bitrix\Sale\Order $order): bool { // логика проверки } } 

This method is suitable for any conditions: number of orders, user behavior, data from external services.

What Does Integration with External CRM Provide?

Integration with an external CRM or ERP allows applying individual discounts stored in your loyalty system. Algorithm:

  • On user authorization, request their discount profile from the external system.
  • Store it in the session or in UF_ user fields.
  • The basket event handler reads this data and applies the discount.

Caching the response from the external system is mandatory – every request on every basket change to an external API creates an unacceptable delay. Cache in Redis/Memcached with TTL 15–60 minutes. In practice, this reduces basket calculation time by 80% compared to direct calls.

Approach Comparison

Characteristic Event Handler Custom Provider
Performance Medium (runs on every recalculation) High (works in parallel)
Implementation Complexity Low (1-2 days) Medium (1-2 weeks)
Flexibility Limited to one event Full control over logic
Compatibility with standard discounts May conflict Works in parallel or replaces
Recommended load Up to 500 orders per day Over 1000 orders per day

How We Debug Custom Discount Logic

Logging applied discounts: in b_sale_order_discount all rules applied to the order are stored. For debugging custom discounts we add a record to this log with the identifier 'custom rule' so that it is visible in the admin panel which discount was applied. Additionally we use AddMessage2Log() for details, and for complex scenarios – Xdebug in a test environment.

What's Included in the Work

  • Audit of current discount logic and basket architecture
  • Prototyping algorithms on a test environment
  • Development of custom handlers, providers or conditions
  • Load and edge-case testing (order cancellation, partial payment)
  • Integration with external CRM/ERP via REST API
  • Documentation of the implemented logic and administration guide
  • Guarantee support for 1 month after launch

Timelines

Task Timeline
Custom event handler for one rule 1–2 days
New condition in marketing rule builder 2–3 days
Full custom discount provider 1–2 weeks
Discount integration from external CRM with caching 3–5 days

We'll give an accurate estimate after the audit. Contact us to discuss your project. Get a consultation right now.