Development of a 1C-Bitrix review and rating module

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
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1175
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Website development for FIXPER company
    811
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Development based on Bitrix, Bitrix24, 1C for the company Development of an Online Appointment Booking Widget for a Medical Center
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Development based on 1C Enterprise for MIRSANBEL
    747
  • image_crm_dolbimby_434_0.webp
    Website development on CRM Bitrix24 for DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Development based on Bitrix24 for the company TECHNOTORGKOMPLEKS
    976

Reviews and Ratings Module Development for 1C-Bitrix

Bitrix includes the bitrix:catalog.element.vote component for voting and bitrix:forum with element binding — these are the standard building blocks for reviews. The result is predictable: a forum without moderation, ratings without purchase verification, and no structured data for Schema.org. A full-featured reviews module is a different story: verified reviews, multi-criteria ratings, moderation, seller replies, and aggregated stars in microdata.

Data Model

Module vendor.reviews:

  • b_vendor_review — reviews: id, entity_type (product/service/company), entity_id, user_id, author_name, author_email, order_id, title, body, pros, cons, rating (1-5), status (pending/approved/rejected/spam), is_verified_purchase, created_at, updated_at
  • b_vendor_review_criteria — rating criteria: id, entity_type, name, sort
  • b_vendor_review_rating — per-criteria ratings: id, review_id, criteria_id, value
  • b_vendor_review_vote — "helpful/not helpful" votes: id, review_id, user_id, ip, value (1/-1), created_at
  • b_vendor_review_reply — admin replies: id, review_id, author_id, body, created_at

Purchase Verification

The most valuable element of a review is the "verified buyer" badge. Verification is done against b_sale_order:

public function isVerifiedPurchase(int $userId, int $productId): bool
{
    // Look for a paid order from this user containing this product
    $order = \Bitrix\Sale\Internals\BasketTable::getList([
        'select' => ['ORDER_ID'],
        'filter' => [
            '=PRODUCT_ID' => $productId,
            '=ORDER.USER_ID'    => $userId,
            '=ORDER.PAYED'      => 'Y',
            '=ORDER.CANCELED'   => 'N',
        ],
        'limit' => 1,
    ])->fetch();

    return (bool)$order;
}

When submitting a review, order_id can be passed explicitly — then verification is unambiguous. Without order_id — verification is done against any paid order containing this product.

Moderation

All reviews are created with pending status and enter the moderation queue. Two modes are available:

  • Manual moderation — a moderator approves or rejects each review
  • Auto-approval — reviews from verified buyers are published automatically; others go into the queue

The spam filter uses simple heuristics: links in the review body, uppercase threshold, duplicate texts, stop words. Suspicious reviews receive spam status.

class SpamDetector
{
    public function check(string $text): SpamResult
    {
        if (preg_match('/https?:\/\//i', $text)) return SpamResult::spam('Links are not allowed');
        if (similar_text($text, $this->getLastReview($text)) > 80) return SpamResult::spam('Duplicate');
        foreach ($this->stopWords as $word) {
            if (mb_stripos($text, $word) !== false) return SpamResult::suspicious();
        }
        return SpamResult::clean();
    }
}

Multi-Criteria Rating

Multiple rating criteria can be defined for products (for example: "Quality", "Matches Description", "Delivery Speed"). The final rating is the average across all criteria:

SELECT
    entity_id,
    AVG(rr.value) AS avg_rating,
    COUNT(DISTINCT r.id) AS review_count
FROM b_vendor_review r
JOIN b_vendor_review_rating rr ON rr.review_id = r.id
WHERE r.entity_type = 'product'
  AND r.status = 'approved'
GROUP BY entity_id;

Aggregated data is cached with the tag review_entity_{entity_id} and invalidated when a new review is approved.

Schema.org Microdata

For SEO impact, the aggregated rating must be included in the microdata:

<div itemscope itemtype="https://schema.org/Product">
  <span itemprop="name">Product Name</span>
  <div itemprop="aggregateRating" itemscope itemtype="https://schema.org/AggregateRating">
    <span itemprop="ratingValue">4.7</span>
    <span itemprop="reviewCount">143</span>
  </div>
</div>

The vendor:reviews.aggregate component generates this block from cached data.

Helpfulness Voting

Users can mark a review as "helpful" or "not helpful". Anti-manipulation protection:

  • One vote per IP per day
  • Authenticated users — one vote per review, permanent
  • Helpfulness rating influences the display order of reviews

Development Timeline

Stage Duration
ORM tables, review model 1 day
Purchase verification, sale integration 1 day
Moderation, spam filter 2 days
Multi-criteria rating, aggregation 1 day
Schema.org microdata 0.5 days
Helpfulness voting 0.5 days
Seller replies, notifications 1 day
Site components 2 days
Admin interface + moderation queue 1 day
Testing 1 day

Total: 11 working days. Importing reviews from Yandex.Market or other platforms — additional 1–2 days.