Development of a loan calculator on 1C-Bitrix

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 a Credit Calculator on 1C-Bitrix

A credit calculator solves the task more simply than a mortgage one: there is no down payment, no property insurance, but it has its own specifics — types of credit products (consumer loan, car loan, cash loan), bank commissions, early repayment. For business the calculator is especially important: it helps the client understand the affordability of a purchase and eliminates the main objection "it's too expensive."

Credit product types in the calculator

Type Calculation specifics
Consumer loan Annuity or differentiated, rate range by amount/term
Car loan Comprehensive insurance mandatory, trade-in possible as a down payment
Cash loan Minimum documentation, higher rate
POS loan (in-store) Often 0% from the bank, but with a store commission
Targeted loan Rate depends on product category

Calculation formulas

Annuity payment (equal payments, standard for most loans):

function calcAnnuity(amount, annualRate, termMonths) {
    if (annualRate === 0) {
        return amount / termMonths;
    }
    const r = annualRate / 12 / 100;
    return amount * r * Math.pow(1 + r, termMonths) / (Math.pow(1 + r, termMonths) - 1);
}

Differentiated payment (decreasing — first payments are higher, total overpayment is lower):

function calcDifferentiated(amount, annualRate, termMonths, monthNumber) {
    const r = annualRate / 12 / 100;
    const principalPart = amount / termMonths;
    const remainingDebt = amount - principalPart * (monthNumber - 1);
    const interestPart  = remainingDebt * r;
    return {
        payment:   principalPart + interestPart,
        principal: principalPart,
        interest:  interestPart,
    };
}

Server-side implementation in PHP

Server-side calculation is needed for validation and passing data to CRM:

namespace MyProject\Services;

class CreditCalculator
{
    public static function calculate(
        float $amount,
        float $annualRate,
        int   $termMonths,
        string $type = 'annuity',
        float $commissionPercent = 0
    ): array {
        $commission = $amount * ($commissionPercent / 100);

        if ($type === 'annuity') {
            $monthlyRate = $annualRate / 12 / 100;
            if ($monthlyRate > 0) {
                $payment = $amount * $monthlyRate
                    * pow(1 + $monthlyRate, $termMonths)
                    / (pow(1 + $monthlyRate, $termMonths) - 1);
            } else {
                $payment = $amount / $termMonths;
            }
            $totalPayment  = $payment * $termMonths;
            $totalInterest = $totalPayment - $amount;
        } else {
            // Differentiated — sum all payments
            $totalPayment = 0;
            $totalInterest = 0;
            $monthlyRate = $annualRate / 12 / 100;
            $principalPart = $amount / $termMonths;
            $remaining = $amount;
            $maxPayment = 0;

            for ($m = 1; $m <= $termMonths; $m++) {
                $interestPart   = $remaining * $monthlyRate;
                $monthPayment   = $principalPart + $interestPart;
                $totalPayment  += $monthPayment;
                $totalInterest += $interestPart;
                $remaining     -= $principalPart;
                $maxPayment     = max($maxPayment, $monthPayment);
            }
            $payment = $maxPayment; // first (maximum) payment
        }

        return [
            'amount'         => $amount,
            'first_payment'  => round($payment, 2),
            'total_payment'  => round($totalPayment + $commission, 2),
            'total_interest' => round($totalInterest, 2),
            'commission'     => round($commission, 2),
            'overpayment'    => round($totalInterest + $commission, 2),
            'effective_rate' => self::calcEffectiveRate($amount, $payment, $termMonths),
        ];
    }

    private static function calcEffectiveRate(float $amount, float $payment, int $termMonths): float
    {
        // Approximation via iteration (APR — Annual Percentage Rate)
        $rate = 0.01;
        for ($i = 0; $i < 1000; $i++) {
            $pv = $payment * (1 - pow(1 + $rate, -$termMonths)) / $rate;
            if (abs($pv - $amount) < 0.01) break;
            $rate += ($pv > $amount) ? 0.00001 : -0.00001;
        }
        return round($rate * 12 * 100, 2);
    }
}

Configuring conditions via the admin interface

Credit conditions are stored in an HL block CreditConditions:

Field Type Description
UF_BANK_NAME String Bank / product name
UF_AMOUNT_FROM Float Minimum amount
UF_AMOUNT_TO Float Maximum amount
UF_TERM_FROM Int Minimum term (months)
UF_TERM_TO Int Maximum term (months)
UF_RATE Float Interest rate
UF_COMMISSION Float Commission (%)
UF_CALC_TYPE Enum annuity / differentiated

When entering an amount and term, the system automatically finds matching conditions and displays options.

Early repayment

The client asks: "If I repay part early in month three, how much will I save?" — this is a separate calculation:

public static function withEarlyRepayment(
    float $loanAmount,
    float $annualRate,
    int   $termMonths,
    int   $repaymentMonth,
    float $repaymentAmount,
    string $repaymentType = 'reduce_payment' // or 'reduce_term'
): array {
    // Before early repayment
    $schedule1 = self::buildSchedule($loanAmount, $annualRate, $termMonths);

    // Remaining debt after N months
    $remainingDebt = $schedule1[$repaymentMonth - 1]['balance'] - $repaymentAmount;

    if ($repaymentType === 'reduce_term') {
        // Same payment — term decreases
        $newTerm = self::calcTerm($remainingDebt, $annualRate, $schedule1[0]['payment']);
        $schedule2 = self::buildSchedule($remainingDebt, $annualRate, $newTerm);
    } else {
        // Same term — payment decreases
        $newTermMonths = $termMonths - $repaymentMonth;
        $schedule2 = self::buildSchedule($remainingDebt, $annualRate, $newTermMonths);
    }

    return [
        'original_total'   => array_sum(array_column($schedule1, 'interest')),
        'new_total_interest' => array_sum(array_column($schedule2, 'interest')),
        'savings'          => /* difference */,
    ];
}

Timelines

Task Timeline
Basic calculator (annuity, request form) 4–7 days
Full calculator (both payment types, multiple conditions, APR) 2–3 weeks
Calculator with early repayment, offer comparison, history 3–5 weeks

A credit calculator lowers the entry barrier: the client sees a specific monthly payment figure and compares it to their own capabilities before even talking to a manager. Conversion to an application among visitors who used the calculator is on average 2–3 times higher.