Настройка Craft Commerce для інтернет-магазина
Craft Commerce — комерційний плагін для CMS Craft CMS, побудований на Yii2 PHP-фреймворку. На відміну від монолітних платформ, Craft Commerce не навязує тему або структуру каталога: всі будується через гнучку систему полів, секцій та Twig-шаблонів. Це робить його вибором для нестандартних каталогів, складних кастомних атрибутів та headless-архітектур.
Архітектура Craft Commerce
Craft Commerce працює поверх Craft CMS і використовує:
- Elements — базовий тип даних (Products — це Elements з розширеними полями)
- Field Layout — конструктор полів без жорсткої схеми
- Twig — шаблонізатор з повним доступом до PHP API
- GraphQL — опціональний API для headless-режиму (Craft Pro)
- Queue — Redis/Database черга для фонових задач
Ключові сутності Commerce:
Product Types → Products → Variants
↓
Sales / Discounts
↓
Line Items → Order → Transaction
Встановлення та настройка
# Створення проекту через Craft Starter
composer create-project craftcms/craft mystore
cd mystore
# Встановлення Commerce
composer require craftcms/commerce
# Застосування міграцій
php craft setup
php craft migrate/all
php craft commerce/install
Настройка .env:
CRAFT_ENVIRONMENT=production
SECURITY_KEY=your-256-bit-key
DB_DRIVER=mysql
DB_SERVER=127.0.0.1
DB_PORT=3306
DB_DATABASE=craftstore
DB_USER=craftuser
DB_PASSWORD=securepassword
DB_TABLE_PREFIX=craft_
# Commerce-специфічні настройки
STRIPE_PUBLISHABLE_KEY=pk_live_xxx
STRIPE_SECRET_KEY=sk_live_xxx
Типи товарів
В Commerce немає єдиної схеми товару — кожен Product Type визначає власну структуру полів:
// craft/config/project/commerce-productTypes.yaml
productTypes:
clothing:
name: Clothing
handle: clothing
hasVariants: true
hasVariantTitleField: false
titleFormat: '{product.title} — {size.label} / {color.label}'
hasDimensions: true
taxCategory: standard
shippingCategory: standard
variantFieldLayouts:
- fields:
- sku
- price
- stock
Створення Product Type програмно:
use craft\commerce\elements\Product;
use craft\commerce\models\ProductType;
$productType = new ProductType();
$productType->name = 'Clothing';
$productType->handle = 'clothing';
$productType->hasVariants = true;
$productType->hasDimensions = true;
Craft::$app->getPlugins()->getPlugin('commerce')
->getProductTypes()
->saveProductType($productType);
Варіанти та матриця атрибутів
Craft Commerce підтримує варіанти як окремі Elements з повним набором полів:
{# templates/shop/product.twig #}
{% set product = craft.products.id(productId).one() %}
<h1>{{ product.title }}</h1>
{# Матриця вариантів для одежди #}
{% set variantMatrix = {} %}
{% for variant in product.variants %}
{% set size = variant.size.label %}
{% set color = variant.color.label %}
{% set variantMatrix = variantMatrix | merge({
(size): (variantMatrix[size] ?? {}) | merge({
(color): {
id: variant.id,
price: variant.price | commerceCurrency('USD'),
stock: variant.hasUnlimitedStock ? '∞' : variant.stock,
sku: variant.sku,
}
})
}) %}
{% endfor %}
<div x-data="variantSelector({{ variantMatrix | json_encode }})">
{# Alpine.js компонент вибору варіанта #}
</div>
Корзина та оформлення замовлення
Craft Commerce використовує сесію для корзини. Базові операції:
{# Додавання в корзину #}
<form method="post">
{{ csrfInput() }}
{{ actionInput('commerce/cart/update-cart') }}
{{ hiddenInput('purchasableId', variant.id) }}
{{ hiddenInput('qty', 1) }}
{{ redirectInput('/shop/cart') }}
<button type="submit">В корзину</button>
</form>
{# Отримання корзини #}
{% set cart = craft.commerce.carts.cart %}
{% for item in cart.lineItems %}
<div>{{ item.purchasable.title }} × {{ item.qty }} = {{ item.subtotal | commerceCurrency }}</div>
{% endfor %}
<strong>Всього: {{ cart.totalPrice | commerceCurrency }}</strong>
Контролер замовлення (PHP):
// Кастомний контролер для обробки замовлення
namespace modules\store\controllers;
use craft\commerce\Plugin as Commerce;
use craft\web\Controller;
class CheckoutController extends Controller
{
public function actionComplete(): \yii\web\Response
{
$this->requirePostRequest();
$order = Commerce::getInstance()->getCarts()->getCart();
// Додавання кастомних даних до замовлення
$order->setFieldValue('deliveryNote', $this->request->getBodyParam('deliveryNote'));
if (!Craft::$app->getElements()->saveElement($order)) {
return $this->asFailure('Не удалося зберегти замовлення');
}
return $this->redirect('/shop/order-confirmation?number=' . $order->number);
}
}
Платіжні шлюзи
Craft Commerce підтримує кілька gateway-плагінів:
# Stripe
composer require craftcms/commerce-stripe
# PayPal
composer require craftcms/commerce-paypal
# Braintree
composer require craftcms/commerce-braintree
Конфігурація gateway через config/commerce-gateways.php:
return [
'stripe' => [
'type' => \craft\commerce\stripe\gateways\PaymentIntents::class,
'name' => 'Stripe',
'publishableKey' => getenv('STRIPE_PUBLISHABLE_KEY'),
'apiKey' => getenv('STRIPE_SECRET_KEY'),
'webhookSigningSecret' => getenv('STRIPE_WEBHOOK_SECRET'),
'testMode' => getenv('CRAFT_ENVIRONMENT') !== 'production',
],
];
GraphQL API для headless
Craft Pro + Commerce дає повноцінний GraphQL API:
# Запрос продуктів з варіантами
query ShopProducts($type: [String], $limit: Int, $offset: Int) {
products(type: $type, limit: $limit, offset: $offset) {
id
title
slug
variants {
id
sku
price
stock
... on clothing_Variant {
size { label value }
color { label value }
}
}
images: featuredImage {
url(width: 800, height: 800, format: "webp")
alt
}
}
}
Промо-акції та скидки
Craft Commerce розділяє Sales (скидки на ціни) та Discounts (купони та автоматичні скидки):
use craft\commerce\models\Sale;
$sale = new Sale();
$sale->name = 'Літня розпродаж';
$sale->description = 'Скидка 20% на всю літню колекцію';
$sale->apply = Sale::APPLY_BY_PERCENT;
$sale->applyAmount = -0.20; // -20%
$sale->allProducts = false;
$sale->categoryIds = [5, 8]; // ID категорій
$sale->dateFrom = new \DateTime('2024-06-01');
$sale->dateTo = new \DateTime('2024-08-31');
$sale->enabled = true;
Commerce::getInstance()->getSales()->saveSale($sale);
Мультивалютність
Craft Commerce Pro підтримує мультивалютність нативно:
// config/commerce.php
return [
'paymentCurrencies' => [
'USD' => ['rate' => 1],
'EUR' => ['rate' => 0.92],
'RUB' => ['rate' => 90.5],
'UAH' => ['rate' => 37.2],
],
];
{# Переключатель валюти #}
{% set currentCurrency = craft.commerce.paymentCurrencies.primaryPaymentCurrency %}
<form method="post">
{{ csrfInput() }}
{{ actionInput('commerce/payment-currencies/set') }}
<select name="currency" onchange="this.form.submit()">
{% for currency in craft.commerce.paymentCurrencies.allPaymentCurrencies %}
<option value="{{ currency.iso }}" {{ currency.iso == currentCurrency.iso ? 'selected' }}>
{{ currency.iso }} — {{ currency.symbol }}
</option>
{% endfor %}
</select>
</form>
Продуктивність та кешування
Craft CMS використовує власний Data Cache + Element Query Cache. Для сторінок товарів:
{# Кешування запроса на 1 годину #}
{% cache globally using key 'product-' ~ product.id for 1 hour %}
{# Дорогостоящий запрос з варіантами, зображеннями, пов'язаними товарами #}
{% include '_partials/product-full' with { product: product } %}
{% endcache %}
Конфігурація Redis для Element Cache:
// config/app.php
return [
'components' => [
'cache' => [
'class' => yii\redis\Cache::class,
'redis' => [
'hostname' => '127.0.0.1',
'port' => 6379,
'database' => 1,
],
'defaultDuration' => 3600,
],
],
];
Терміни настройки
- Базова встановлення + 1 Product Type + оформлення замовлення: 1–2 тижні
- Повноцінний магазин з 3–5 типами товарів, скидками, мультивалютністю: 4–6 тижнів
- Headless-магазин (Craft GraphQL + Next.js frontend): 6–10 тижнів
- Міграція з іншої платформи в Craft Commerce: 4–8 тижнів (залежить від об'єму каталога та складності бізнес-логіки)







