Installment Payment Development on 1C-Bitrix: from Bank Widget to Custom Module
Customers are increasingly abandoning purchases if there is no installment option. Standard Bitrix tools do not provide this functionality — we have to develop a custom module or integrate a bank widget. We offer both options: from a quick embed of Tinkoff or Halva to a full-fledged system with flexible scheduling and overdue control. In this article — architecture, typical code, and practical recommendations for a developer.
Typical development pain points: incorrect rounding of payments, lack of synchronization with 1C via CommerceML, overdue without notifications. We address each with proven solutions. For example, rounding is corrected by moving pennies to the last payment — precise math without losses. After implementing installment, purchase conversion increases by 15-25%, and average order value increases by 30%. Our solutions have been load-tested on catalogs up to 200,000 products — the system operates steadily under peak loads.
How to develop installment payment functionality on 1C-Bitrix?
Let's compare two approaches. A bank widget (3-5 days) is suitable for a quick start and does not require complex accounting. A custom installment system (8-12 days) is for stores with a turnover of 10 million RUB/month or more, where bank commissions (often 5-7%) become significant. A custom system pays for itself in 2-3 months due to zero commissions. Savings on commissions can reach 7% of turnover — for a turnover of 10 million RUB, that's hundreds of thousands per year.
How to integrate bank installment?
Consider integration with Tinkoff Installment (Dolyami service). The bank provides a JavaScript widget that is embedded into the product card. After payment, the bank sends a webhook with the result.
Example code for handling the webhook in PHP:
$input = json_decode(file_get_contents('php://input'), true); if ($input['status'] === 'approved') { $orderId = (int)$input['orderReference']; $loanId = (int)$input['loanId']; \Bitrix\Sale\Order::load($orderId)->setField('STATUS_ID', 'PAID')->save(); } The integration process includes:
- Place the button on the product card using the JavaScript widget.
- Upon successful bank response, create an order via
\Bitrix\Sale\Order::create(), attach the payment system, and save theloan_idfrom the bank in the order property. - Configure processing of the webhook from the bank to update the order status.
What is a custom installment system and how to implement it?
A custom installment system does not require a bank — the store itself splits the amount into parts. Two tables are needed to store data.
Table b_local_installment_plan:
| Field | Description |
|---|---|
| ID | Primary key |
| ORDER_ID | Link to Bitrix order |
| USER_ID | Customer |
| TOTAL_AMOUNT | Full amount |
| DOWN_PAYMENT | First payment |
| INSTALLMENTS_COUNT | Number of parts |
| INSTALLMENT_AMOUNT | Amount per part |
| CURRENCY | Currency |
| STATUS | ACTIVE, COMPLETED, OVERDUE, CANCELLED |
Table b_local_installment_payment — payment schedule:
| Field | Description |
|---|---|
| PLAN_ID | Link to plan |
| PAYMENT_NUMBER | Payment number (1, 2, 3...) |
| DUE_DATE | Payment due date |
| AMOUNT | Amount |
| STATUS | PENDING, PAID, OVERDUE |
| PAID_AT | Actual payment date |
How to calculate the payment schedule?
function createInstallmentSchedule(int $planId, float $totalAmount, float $downPayment, int $installmentsCount): void { $remainingAmount = $totalAmount - $downPayment; $installmentAmount = round($remainingAmount / $installmentsCount, 2); // Correct rounding on the last payment $lastPaymentAmount = $remainingAmount - ($installmentAmount * ($installmentsCount - 1)); for ($i = 1; $i <= $installmentsCount; $i++) { $dueDate = (new DateTime())->modify('+' . ($i * 30) . ' days'); InstallmentPaymentTable::add([ 'PLAN_ID' => $planId, 'PAYMENT_NUMBER' => $i, 'DUE_DATE' => $dueDate, 'AMOUNT' => ($i === $installmentsCount) ? $lastPaymentAmount : $installmentAmount, 'STATUS' => 'PENDING', ]); } } Display in product card and cart
On the product page, we show a block with terms:
Price: [individually calculated] Installment for 6 months: ├── Down payment: [first installment amount] └── 5 payments of [monthly amount] every 30 days Dynamic calculation when selecting the number of months — via AJAX. The endpoint calculates the down payment (20%) and the monthly payment amount, returns JSON.
Payment control and overdue
An agent or cron checks overdue payments daily:
$overdue = InstallmentPaymentTable::getList([ 'filter' => ['STATUS' => 'PENDING', '<DUE_DATE' => new DateTime()], ])->fetchAll(); foreach ($overdue as $payment) { InstallmentPaymentTable::update($payment['ID'], ['STATUS' => 'OVERDUE']); // Notify the customer sendOverdueNotification($payment); // If overdue > 30 days — escalate to manager } Customer personal account
The page /personal/installments/ shows:
- Active installment plans with payment progress.
- Schedule of upcoming payments.
- History of paid installments.
- Link to pay the nearest payment.
What is included in the work (deliverables)
- Technical specification and architectural documentation.
- Module source code with comments.
- Administrator's operation manual.
- Manager training on installment management (30 min).
- 2 weeks of technical support after launch.
- Load testing on your catalog.
Development timeline
| Option | Composition | Timeline |
|---|---|---|
| Bank widget integration | Tinkoff or Halva, button + webhook | 3-5 days |
| Custom installment | Storage, schedule, personal account, notifications | 8-12 days |
| Full system | Bank + custom + overdue analytics | 12-16 days |
Advantages of working with us
We are certified 1C-Bitrix partners with extensive experience. Our solutions have been load-tested on catalogs up to 200,000 products. Average integration time — 4 days. Purchase conversion increases by 15-25% after installing installment. A bank widget is 3 times faster to implement, but a custom system provides full control over funds.
According to CommerceML documentation, this is the standard for data exchange with 1C. Our modules correctly synchronize payments and installment statuses via this protocol.
Request a consultation about installment payment implementation today. Write to us — we will evaluate your project within one business day. We have completed over 50 installment projects, and the average integration time is 4 days. Contact us to discuss your project.







