Checkout Development with Vue.js for 1C-Bitrix
Checkout is the stage with the highest abandonment rate. The standard bitrix:sale.order.ajax is a multi-step form with step reloads. A Vue checkout enables a single-page flow with instant delivery cost updates, live validation, and progress saving.
Vue Checkout Architecture
Checkout is a sequence of steps sharing a common state. Three implementation approaches:
Multi-step wizard — <component :is="currentStep"> switches between components: StepDelivery → StepPayment → StepConfirm. State is kept in a single Pinia store.
Single-page accordion — all sections are visible, completed ones collapse. More comfortable on mobile.
Hybrid — the first screen for unregistered users (contacts + address), the second for everyone (delivery + payment + summary).
API for Order Creation
Bitrix creates orders via \Bitrix\Sale\Order:
$order = \Bitrix\Sale\Order::create(SITE_ID, $userId);
$order->setPersonTypeId($personTypeId);
// Order properties (name, phone, email)
$propertyCollection = $order->getPropertyCollection();
$propertyCollection->getItemByOrderPropertyCode('NAME')?->setValue($name);
// Delivery
$shipment = $order->getShipmentCollection()->createItem();
$shipment->setFields([
'DELIVERY_ID' => $deliveryId,
'DELIVERY_LOCATION' => $locationCode,
]);
// Payment
$payment = $order->getPaymentCollection()->createItem();
$payment->setFields(['PAY_SYSTEM_ID' => $paySystemId]);
$order->save();
Wrapped in a controller that accepts JSON from Vue.
Real-Time Delivery Cost Calculation
When the address or order parameters change — recalculate delivery cost without saving:
// Calculation method without creating an order
$deliveryCalculator = new \Bitrix\Sale\Delivery\Calculator($order);
$result = $deliveryCalculator->calculate($deliveryId);
Vue requests recalculation on every address change (with a 500 ms debounce).
Validation and Error Handling
Server-side validation + client-side with vee-validate or native Vue:
const rules = {
phone: (v) => /^\+7\d{10}$/.test(v) || 'Enter a number in the format +7XXXXXXXXXX',
email: (v) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v) || 'Invalid email',
};
Server errors (order.save() returns \Bitrix\Main\Result with errorCollection) are mapped to form fields.
Progress Saving
When the user leaves the page — save to localStorage:
watch(() => checkoutStore.$state, (state) => {
localStorage.setItem('checkout-draft', JSON.stringify(state));
}, { deep: true });
On return — restore. Clear after a successful order.
Real-World Case
A pet supplies store with a high mobile audience. The standard Bitrix checkout had 4 steps with reloads; on mobile, some data was lost when switching tabs (the form reset). A Vue checkout in accordion format, state in Pinia + localStorage: data is not lost even when taking a phone call. Address autocomplete via DaData with an AddressSuggest.vue component. Mobile conversion increased significantly — per the client's internal A/B test data.
Delivery Timelines
| Option | Timeline |
|---|---|
| Basic single-page checkout | 6 to 10 business days |
| With DaData integration and delivery recalculation | 10 to 15 business days |
| With multiple payer types (individual/legal entity) and subscription | 15 to 20 business days |







