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:
- The store sends a request to create a payment session
- Receives a
redirect_url— a link for the buyer to follow - The buyer confirms the installment in the bank's interface
- The bank redirects the buyer back to the store's
return_url - 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 |







