Developing 1C-Bitrix product subscription functionality

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

Development of Product Subscription Functionality for 1C-Bitrix

Online store sells consumables: coffee, pet food, filters, household chemicals. Customer buys the same thing every two to four weeks. Without subscription, he goes through full order cycle every time — or switches to competitor with auto-repeat. 1C-Bitrix has no built-in subscription module. Build it on base of sale, catalog and custom module linking periodicity to automatic order creation.

Solution Architecture

Subscription is not just "repeat order". It's separate entity with own lifecycle: creation, active phase, pause, cancellation, resumption. Store it conveniently in separate table, e.g. b_subscription_order:

Field Type Purpose
ID int Primary key
USER_ID int User binding
BASKET_DATA text Serialized cart composition
PERIOD_DAYS int Repetition interval in days
NEXT_DATE datetime Next order date
STATUS enum ACTIVE, PAUSED, CANCELLED
PAY_SYSTEM_ID int Payment system
DELIVERY_ID int Delivery service
PERSON_TYPE_ID int Payer type
DISCOUNT_PERCENT decimal Subscriber discount

For table interaction, create ORM-class, inheriting from \Bitrix\Main\ORM\Data\DataManager. Gives standard methods getList(), add(), update(), delete() and D7 filter capability.

Automatic Order Creation

Core of functionality — agent or cron task running daily (or more) and checking records with STATUS = ACTIVE and NEXT_DATE <= NOW().

Processing algorithm for one subscription:

  1. Deserialize BASKET_DATA, verify each product exists via \Bitrix\Catalog\ProductTable::getList().
  2. Check stock: \CCatalogStoreProduct::GetList() or \Bitrix\Catalog\StoreProductTable. If out of stock — skip item and notify customer.
  3. Create basket: \Bitrix\Sale\Basket::create(), add BasketItem for each position.
  4. Apply subscriber discount via custom cart rule or direct price change in BasketItem::setField('CUSTOM_PRICE', 'Y') + BasketItem::setField('PRICE', $discountedPrice).
  5. Create order: \Bitrix\Sale\Order::create(), bind basket, set PERSON_TYPE_ID, fill order properties from saved profile.
  6. Bind delivery and payment: \Bitrix\Sale\Shipment::create(), \Bitrix\Sale\Payment::create().
  7. Save order: $order->save().
  8. Update NEXT_DATE to NEXT_DATE + PERIOD_DAYS.

Critically important to wrap each subscription in try/catch and log errors. One failure shouldn't stop processing of rest.

Agent vs Cron choice. Bitrix agents (\CAgent) convenient but execute in user hit context (unless cron_events configured). For subscription unacceptable: order creation is heavy operation. Recommend separate PHP script called from crontab:

*/30 * * * * /usr/bin/php /home/bitrix/www/local/cron/subscription_process.php

Script includes prologue (/bitrix/modules/main/include/prolog_before.php), then processes subscriptions in batches of 50.

Subscription Management in Personal Account

User must see active subscriptions, change frequency, composition, pause. Implemented via custom component in /personal/subscriptions/. Component uses ORM subscription class and renders form with fields:

  • Product list with ability to remove item or change quantity.
  • Period selection: 7 / 14 / 21 / 30 days.
  • "Pause" and "Cancel" buttons.
  • Next delivery date with shift option.

On composition change, BASKET_DATA recalculated. On pause, STATUS switches to PAUSED, agent skips record.

Recurring Payments

Subscription without automatic charging — half-measure. Customer gets order with "Awaiting payment" status and must pay manually. Full subscription requires recurring payments.

Recurring payments not all payment systems support. From common: YooKassa (method createPayment with saved method payment_method_id parameter), CloudPayments (recurrent via API post-requests). In Bitrix, recurrent implemented via custom payment system handler, inheriting \Bitrix\Sale\PaySystem\BaseServiceHandler.

Logic: on first payment, save payment method token in b_subscription_order.PAY_TOKEN. On auto order creation — initiate charge via payment system API. If charge fails — mark order as unpaid and send customer email.

Implementation Timelines

Scale Contents Timeline
Basic Subscription without autopay, personal account management, agent 5-7 days
Full Recurring payments, notifications, subscription analytics 8-12 days

Notifications

Minimal email event set:

  • SUBSCRIPTION_CREATED — subscription creation confirmation.
  • SUBSCRIPTION_ORDER_CREATED — notification of new subscription order.
  • SUBSCRIPTION_ITEM_OUT_OF_STOCK — product from subscription out of stock.
  • SUBSCRIPTION_PAYMENT_FAILED — automatic charge error.
  • SUBSCRIPTION_REMINDER — reminder 1-2 days before next order (allows composition change).

Email templates created in Settings → Email Events with event type bound to site.