Integration of 1C-Bitrix with the Webpay payment system (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
    1173
  • 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
    745
  • 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 Webpay payment system (Belarus)

Webpay is a Belarusian payment gateway working through Priorbank. Accepts Visa, MasterCard, BELKART cards. Integration is implemented through redirect to Webpay secure form with signed parameters.

How it works

The store forms a POST request to Webpay form with all order parameters and signature. The buyer pays on bank side. Webpay notifies the store via POST on notify_url and redirects the buyer.

Test environment: https://trial.webpay.by/ Live environment: https://payment.webpay.by/

Request parameters and signature

$wsb_storeid    = $this->getBusinessValue($payment, 'WEBPAY_STORE_ID');
$wsb_seed       = md5(microtime() . rand());  // random salt for each request
$wsb_currency_id = 'BYR';  // or 'BYN', 'USD', 'EUR' — clarify with bank
$wsb_order_num  = $payment->getOrder()->getId();
$wsb_total      = number_format($payment->getSum(), 2, '.', '');
$wsb_test       = $isTest ? 1 : 0;

// Signature: MD5 of concatenated parameters
$seedBody = $wsb_seed
    . $wsb_storeid
    . $wsb_order_num
    . $wsb_test
    . $wsb_currency_id
    . $wsb_total
    . $secretKey;
$wsb_signature = md5($seedBody);

// Form for POST submission
?>
<form method="POST" action="https://payment.webpay.by/" id="webpay-form">
    <input type="hidden" name="*scart" value="">
    <input type="hidden" name="wsb_version" value="2">
    <input type="hidden" name="wsb_storeid" value="<?= $wsb_storeid ?>">
    <input type="hidden" name="wsb_order_num" value="<?= $wsb_order_num ?>">
    <input type="hidden" name="wsb_currency_id" value="<?= $wsb_currency_id ?>">
    <input type="hidden" name="wsb_seed" value="<?= $wsb_seed ?>">
    <input type="hidden" name="wsb_signature" value="<?= $wsb_signature ?>">
    <input type="hidden" name="wsb_total" value="<?= $wsb_total ?>">
    <input type="hidden" name="wsb_test" value="<?= $wsb_test ?>">
    <input type="hidden" name="wsb_notify_url" value="<?= $notifyUrl ?>">
    <input type="hidden" name="wsb_return_url" value="<?= $returnUrl ?>">
    <input type="hidden" name="wsb_cancel_return_url" value="<?= $cancelUrl ?>">
</form>
<script>document.getElementById('webpay-form').submit();</script>

Order items

Webpay accepts order items (optional but recommended for correct display in personal account):

// Add items via input name="wsb_invoice_item_name[N]"
$basketItems = $payment->getOrder()->getBasket();
$i = 1;
foreach ($basketItems as $item) {
    // wsb_invoice_item_name[1], wsb_invoice_item_count[1], wsb_invoice_item_price[1]
    echo '<input type="hidden" name="wsb_invoice_item_name[' . $i . ']" value="' . htmlspecialchars($item->getField('NAME')) . '">';
    echo '<input type="hidden" name="wsb_invoice_item_count[' . $i . ']" value="' . $item->getQuantity() . '">';
    echo '<input type="hidden" name="wsb_invoice_item_price[' . $i . ']" value="' . number_format($item->getPrice(), 2, '.', '') . '">';
    $i++;
}

Processing notify_url

Webpay sends POST with payment result:

$orderNum       = $_POST['wsb_order_num'];
$transactionId  = $_POST['wsb_transaction_id'];
$paymentStatus  = $_POST['wsb_payment_type'];  // 'success' or 'failed'

// Signature check from Webpay
$receivedSig    = $_POST['wsb_signature'];
$expectedSig    = md5(
    $_POST['wsb_transaction_id']
    . $_POST['wsb_order_num']
    . $_POST['wsb_test']
    . $_POST['wsb_currency_id']
    . $_POST['wsb_total']
    . $secretKey
);

if (strtolower($receivedSig) !== strtolower($expectedSig)) {
    http_response_code(400);
    exit('bad signature');
}

if ($paymentStatus === 'success') {
    $order = \Bitrix\Sale\Order::loadByAccountNumber($orderNum);
    // Confirm payment: $payment->setPaid('Y'), $order->save()
}

Specifics of Belarusian payments

Webpay historically uses BYR (Belarusian rubles in old format) and BYN (denominated rubles from 2016). Clarify with the bank which currency code your contract uses. BYN is current, BYR may appear in old integrations.

Webpay doesn't support automatic fiscalization via API — receipts need to be formed independently via cash register software or integrated separately.

Testing

In test mode (wsb_test=1) any card data is accepted. Test card: 4200000000000000. Notifications in test mode come with parameter wsb_test=1 — check handler for both modes.

Development timeline

Task Timeline
Form generation + notify_url processing 1–2 days
Testing and debugging 0.5 day