1C-Bitrix integration with Halva installment plan (Belarus)

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
    1181
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Website development for FIXPER company
    813
  • 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

Integration of 1C-Bitrix with the Khalva Installment Service (Belarus)

"Khalva" in Belarus is the installment card from Belarusbank. The buyer pays in interest-free installments over 3 to 24 months; the store receives the money immediately (minus the bank's commission). To connect it to a Bitrix-based site, you need to implement a payment system handler that initiates payment through the Belarusbank API and processes the result.

Technical Details of Khalva (Belarusbank)

Belarusbank provides an API for partners. The flow:

  1. The store sends a request to create a payment session
  2. Receives a redirect_url — a link for the buyer to follow
  3. The buyer confirms the installment in the bank's interface
  4. The bank redirects the buyer back to the store's return_url
  5. The bank sends a confirmation webhook to the notification_url

Parameters to clarify with the bank at onboarding: API endpoint, request format (typically REST/JSON), authentication method (token or certificate), test and production environments.

Bitrix Payment System Handler

Create the handler in /local/php_interface/include/sale_payment/halva_belarus/:

File .description.php:

$PAYSYSTEM_SORT = 150;
$PAYSYSTEM_NAME = 'Khalva (Belarusbank, installment)';
$PAYSYSTEM_IS_CASH = 'N';

Handler class:

class HalvaBelarusHandler extends \Bitrix\Sale\PaySystem\ServiceHandler
{
    public function initiatePay(
        \Bitrix\Sale\Payment $payment,
        \Bitrix\Main\Request $request = null
    ) {
        $order = $payment->getOrder();
        $installmentMonths = $this->getBusinessValue($payment, 'INSTALLMENT_MONTHS');

        $sessionData = [
            'merchant_id'    => $this->getBusinessValue($payment, 'MERCHANT_ID'),
            'order_id'       => $order->getId(),
            'amount'         => $payment->getSum(),
            'currency'       => 'BYN',
            'installment'    => (int)$installmentMonths,
            'description'    => 'Order #' . $order->getId(),
            'return_url'     => $this->getSuccessUrl($payment),
            'cancel_url'     => $this->getFailUrl($payment),
            'notification_url' => $this->getNotificationUrl($payment),
            'customer_name'  => $order->getPropertyValueByCode('NAME'),
            'customer_phone' => $order->getPropertyValueByCode('PHONE'),
        ];

        $response = $this->callApi('POST', '/v1/payments/create', $sessionData);

        if (empty($response['redirect_url'])) {
            $this->createError('Error creating Khalva payment session');
            return \Bitrix\Sale\PaySystem\ServiceResult::create()->setRedirectUrl('/');
        }

        $this->savePaymentId($payment, $response['payment_id']);

        $result = new \Bitrix\Sale\PaySystem\ServiceResult();
        $result->setPaymentUrl($response['redirect_url']);
        return $result;
    }
}

Handling Bank Notifications

The bank sends a POST request to notification_url on successful payment or rejection:

public function processRequest(
    \Bitrix\Sale\Payment $payment,
    \Bitrix\Main\Request $request
): \Bitrix\Sale\PaySystem\ServiceResult {
    $result = new \Bitrix\Sale\PaySystem\ServiceResult();

    // Signature verification (method depends on the bank: HMAC or RSA)
    if (!$this->verifySignature($request)) {
        $result->addError(new \Bitrix\Main\Error('Invalid request signature'));
        return $result;
    }

    $status = $request->get('status');
    $paymentId = $request->get('payment_id');

    // Compare payment_id with the saved value
    $savedPaymentId = $this->getPaymentIdFromStorage($payment);
    if ($paymentId !== $savedPaymentId) {
        $result->addError(new \Bitrix\Main\Error('payment_id mismatch'));
        return $result;
    }

    if ($status === 'SUCCESS' || $status === 'APPROVED') {
        $result->setOperationType(\Bitrix\Sale\PaySystem\ServiceResult::MONEY_COMING);
        $payment->setPaid('Y');
    } elseif ($status === 'CANCEL' || $status === 'REJECTED') {
        $result->setOperationType(\Bitrix\Sale\PaySystem\ServiceResult::MONEY_COMING);
        // Do not mark as paid — order remains in pending status
    }

    return $result;
}

Admin Panel Configuration

The payment system is registered in Bitrix via Store → Settings → Payment Systems → Add. Handler parameters:

Parameter Description
MERCHANT_ID Store ID in the Belarusbank system
API_TOKEN Authorization token
INSTALLMENT_MONTHS Number of installment months (list: 3, 6, 12, 24)
TEST_MODE Test mode (Y/N)
API_URL API URL (test / production)

Order Amount Restrictions

The minimum amount for a Khalva (Belarusbank) installment is specified in the bank agreement. Add a check in the handler:

public function isAvailable(\Bitrix\Sale\PayableItemCollection $basket): bool
{
    $total = $basket->getPrice();
    $min   = (float)\Bitrix\Main\Config\Option::get('halva_belarus', 'min_amount', 50);
    return $total >= $min;
}

Timeline

Phase Duration
Test API connection setup 1 day
Payment system handler (initiatePay) 2 days
Notification handler + signature verification 2 days
Refunds via API 1 day
Testing in the bank's test environment 2 days
Total 8–10 days