Integrating 1C-Bitrix with CloudPayments

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

Integration of 1C-Bitrix with CloudPayments Payment System

CloudPayments is a Russian payment gateway with a JS payment widget that embeds in a page without redirect. Customers enter card details directly on the store page — higher conversion than redirect. API is REST-based, supports recurring payments, 3-D Secure, and holds.

Integration Architecture

CloudPayments offers two payment options:

Checkout Widget — JS widget, form opens in popup or inline on store page. Card data goes directly to CloudPayments (PCI DSS), only transaction token goes to store server.

API without redirect — store collects card data itself and passes to API. Requires PCI DSS certification — rarely used.

Standard approach for Bitrix — Checkout Widget.

Connecting the Widget

On order checkout page:

<script src="https://widget.cloudpayments.ru/bundles/cloudpayments.js"></script>

<script>
var widget = new cp.CloudPayments({language: 'ru-RU'});
widget.pay('auth',  // 'auth' — two-stage, 'charge' — one-stage
    {
        publicId: 'pk_XXXXX',
        description: 'Payment for order #<?= $orderId ?>',
        amount: <?= $amount ?>,
        currency: 'RUB',
        invoiceId: '<?= $orderId ?>',
        accountId: '<?= $userId ?>',
        skin: 'mini',
        data: {
            orderId: '<?= $orderId ?>',
            csrfToken: '<?= bitrix_sessid() ?>',
        }
    },
    {
        onSuccess: function(options) {
            // Payment succeeded — notify server
            fetch('/bitrix/tools/sale_ps_result.php', {
                method: 'POST',
                body: JSON.stringify({ orderId: options.invoiceId }),
            });
        },
        onFail: function(reason, options) {
            console.error('Payment failed:', reason);
        }
    }
);
</script>

In Bitrix, the widget is connected in the template of the bitrix:sale.order.checkout component or in result_modifier.php.

Server Processing: check and pay Notifications

CloudPayments sends two notifications to server:

Check — before debit. Store should respond with {"code":0} if order exists, or non-zero code to cancel.

Pay — after successful debit. Payment confirmation.

Notification handler (/local/payment/cloudpayments/callback.php):

$data = json_decode(file_get_contents('php://input'), true);

// HMAC signature verification
$hmac = base64_encode(hash_hmac('sha256', file_get_contents('php://input'), $apiSecret, true));
if ($hmac !== $_SERVER['HTTP_CONTENT_HMAC']) {
    http_response_code(403);
    exit;
}

$invoiceId = $data['InvoiceId'];  // our orderId
$status    = $data['Status'];     // 'Completed', 'Cancelled', etc.

if ($status === 'Completed') {
    // Find payment by orderId, confirm
    $order = \Bitrix\Sale\Order::loadByAccountNumber($invoiceId);
    $paymentCollection = $order->getPaymentCollection();
    foreach ($paymentCollection as $payment) {
        if ($payment->getPaySystem()->getField('CODE') === 'cloudpayments') {
            $payment->setPaid('Y');
        }
    }
    $order->save();
}

header('Content-Type: application/json');
echo json_encode(['code' => 0]);

Signature verification is mandatory. CloudPayments passes HMAC SHA-256 in the Content-HMAC header. Without verification, an attacker can confirm payment with a fake POST.

Recurring Payments

CloudPayments supports subscriptions: on first payment, a card token is created (Token), subsequent debits are made without customer participation:

// First payment with token saving — via widget with createReceipt parameter
// Subsequent payments via API
$response = $this->apiRequest('payments/tokens/charge', [
    'Amount'      => 999,
    'Currency'    => 'RUB',
    'InvoiceId'   => $subscriptionId,
    'AccountId'   => $userId,
    'Token'       => $savedToken,
    'Description' => 'Subscription for February',
]);

Fiscalization

CloudPayments integrates with online cash registers via cloudPayments.CustomerReceipt parameters in widget request. You pass array of order items, VAT rate, tax system. CloudPayments forms receipt via connected register.

Development Timeline

Task Duration
Basic integration: widget + check/pay callbacks 2–3 days
Two-stage payments (auth + confirm) +1 day
Recurring payments +2–3 days
Fiscalization +1–2 days
Testing and debugging 1 day