Configuring Cashback Accrual for Purchases in 1C-Bitrix
Cashback accrual is one component of a cashback system that can be configured even without full custom development. 1C-Bitrix has a built-in bonus points mechanism through the sale module. If requirements are simple (a fixed percentage on all purchases, without category-based rules), this can be launched using standard tooling.
1C-Bitrix Built-in Bonus Mechanism
1C-Bitrix stores bonus points in the following tables:
-
b_sale_user_account— user account -
b_sale_account_user_balance— account balance
Management via \Bitrix\Sale\PersonalBonus (D7) or CSaleUserAccount (legacy API).
Configuration in the admin panel: Store → Cumulative Discounts → Bonuses.
Accrual via Order Payment Event
If the standard mechanism does not meet requirements, programmatic accrual:
\Bitrix\Main\EventManager::getInstance()->addEventHandler(
'sale',
'OnSaleOrderPaid',
function (\Bitrix\Main\Event $event) {
$order = $event->getParameter('ENTITY');
$userId = $order->getUserId();
$total = $order->getPrice();
// Cashback percentage from settings
$percent = (float)\Bitrix\Main\Config\Option::get(
'local.cashback', 'base_percent', '3'
);
$cashback = round($total * $percent / 100, 2);
if ($cashback <= 0) {
return;
}
\Local\Cashback\AccountManager::earn(
$userId,
$cashback,
"Cashback {$percent}% for order #{$order->getId()}",
$order->getId()
);
}
);
Accrual Only for Confirmed Orders
To avoid accruing cashback for returned orders, use a two-step accrual process:
- On order creation — transaction with
pendingstatus - On transition to "Fulfilled" — confirmation (status
confirmed) - On cancellation — annulment of pending transactions
// Confirm accrual on order fulfillment
$em->addEventHandler('sale', 'OnSaleOrderStatusChange', function ($event) {
$order = $event->getParameter('ENTITY');
if ($order->getField('STATUS_ID') === 'F') {
\Local\Cashback\AccountManager::confirmByOrderId($order->getId());
} elseif ($order->getField('STATUS_ID') === 'X') {
\Local\Cashback\AccountManager::cancelByOrderId($order->getId());
}
});
Displaying Cashback on the Product Page
The customer sees "You will earn 45 cashback" before placing an order — this increases conversion.
// In the product page template
$price = \CPrice::GetBasePrice($elementId);
$percent = (float)\Bitrix\Main\Config\Option::get('local.cashback', 'base_percent', '3');
$cashbackPreview = $price ? round($price['PRICE'] * $percent / 100, 0) : 0;
<?php if ($cashbackPreview > 0): ?>
<div class="cashback-preview">
Cashback: <strong><?= $cashbackPreview ?></strong>
</div>
<?php endif; ?>
Exclusions from Accrual
Products, categories, or brands excluded from cashback accrual (already discounted items, zero-margin products):
function isExcludedFromCashback(int $productId): bool
{
$props = \CIBlockElement::GetProperty(
CATALOG_IBLOCK_ID, $productId,
[], ['CODE' => 'CASHBACK_EXCLUDED']
)->Fetch();
return $props && $props['VALUE'] === 'Y';
}
The CASHBACK_EXCLUDED Yes/No property is added to the catalog and set by a manager manually or during import from 1C.
Implementation Timeline
Payment event handler with accrual, two-step confirmation, cashback display on the product page, exclusions — 1–2 business days.







