Installation Add the package via Composer:
composer require sylius/order
Publish the migration (if using Doctrine):
php bin/console doctrine:migrations:diff
php bin/console doctrine:migrations:migrate
First Use Case: Creating an Order
use Sylius\Component\Order\Model\OrderInterface;
use Sylius\Component\Order\Model\OrderItemInterface;
// Create an order
$order = $orderFactory->createNew();
$order->setCurrencyCode('USD');
// Add an item
$item = $orderFactory->createOrderItem();
$item->setProductVariant($variant);
$item->setQuantity(2);
$order->addItem($item);
// Persist (via Doctrine or your ORM)
$entityManager->persist($order);
$entityManager->flush();
Where to Look First
Sylius\Component\Order\Model\Order, OrderItem, AdjustmentSylius\Component\Order\Factory\OrderFactoryInterfacetests/ directory for usage examples.Order Creation & Management
OrderFactory to create orders and items.$order->setCustomer($customer);
$order->setShippingAddress($shippingAddress);
Adjustments (Fees/Discounts)
$adjustment = $adjustmentFactory->createShippingAdjustment();
$adjustment->setAmount(5.99);
$order->addAdjustment($adjustment);
AdjustmentType (e.g., Sylius\Component\Order\Model\AdjustmentInterface::TYPE_SHIPPING) for categorization.Order States & Transitions
Sylius\Component\Order\Model\OrderStates) for workflows:
$order->setState(OrderInterface::STATE_CART);
$order->setState(OrderInterface::STATE_COMPLETED);
Order Numbering
OrderNumberGenerator:
# config/packages/sylius_order.yaml
sylius_order:
order_number_generator:
pattern: 'ORD-{year}-{sequence}'
API/Serialization
use Sylius\Component\Order\Serializer\OrderSerializer;
$serializer = new OrderSerializer();
$data = $serializer->serialize($order, 'json');
OrderEvents (e.g., OrderCreated, OrderStateChanged) for side effects.@Assert\GreaterThan(0) for quantities).OrderFactory and OrderRepository in unit tests:
$this->orderFactory = $this->createMock(OrderFactoryInterface::class);
$this->orderFactory->method('createNew')->willReturn($order);
Adjustment Precision
bcmath or gmp for financial calculations:
$total = bcadd($order->getSubtotal(), $order->getTotalAdjustments(), 2);
State Transitions
CART → SHIPPED directly). Use Symfony Workflow for constraints:
# config/workflows/order_workflow.yaml
supports:
- Sylius\Component\Order\Model\OrderInterface
places:
cart:
initial: true
transitions:
checkout: completed
Order Number Collisions
// Custom generator example
$generator = new UuidOrderNumberGenerator();
$order->setNumber($generator->generate());
Lazy-Loading Pitfalls
N+1 queries when accessing collections (e.g., order->getItems()). Use DQL or repository methods:
$items = $orderRepository->findItemsByOrder($order);
Adjustment Calculation Issues
foreach ($order->getAdjustments() as $adjustment) {
$this->logger->debug('Adjustment: ', [
'type' => $adjustment->getType(),
'amount' => $adjustment->getAmount(),
]);
}
AdjustmentType constants match your use case.State Machine Errors
OrderStates for valid transitions. Use:
$this->order->getStateMachine()->can($order, 'transition_name');
Custom Adjustment Types
AdjustmentInterface or create subclasses:
class LoyaltyDiscountAdjustment implements AdjustmentInterface
{
public function getType(): string
{
return self::TYPE_LOYALTY_DISCOUNT;
}
}
Order Number Generators
OrderNumberGeneratorInterface:
class CustomOrderNumberGenerator implements OrderNumberGeneratorInterface
{
public function generate(): string
{
return 'CUST-' . Str::upper(Random::string(8));
}
}
Order Factories
OrderFactory to inject custom logic:
class CustomOrderFactory implements OrderFactoryInterface
{
public function createNew(): OrderInterface
{
$order = parent::createNew();
$order->setChannel($this->channelResolver->resolve());
return $order;
}
}
Event Subscribers
OrderCompleted):
use Sylius\Component\Order\Event\OrderCompletedEvent;
$eventDispatcher->addListener(OrderCompletedEvent::NAME, function (OrderCompletedEvent $event) {
$this->mailer->send(new OrderConfirmationEmail($event->getOrder()));
});
Order and OrderItem entities are properly mapped. Example:
# config/packages/doctrine.yaml
orm:
mappings:
SyliusOrder:
type: attribute
prefix: 'Sylius\Component\Order\Model'
dir: '%kernel.project_dir%/vendor/sylius/order/src/Model'
config/packages/framework.yaml:
framework:
workflows:
order_workflow: '@sylius_order.workflow.order'
How can I help you explore Laravel packages today?