Conversion Process
Quote to Order Converter
namespace Magento\Quote\Model\Quote\Order\Convert;
class Converter
{
public function __construct(
private \Magento\Sales\Api\OrderRepositoryInterface $orderRepository,
private \Magento\Sales\Api\Data\OrderItemInterfaceFactory $orderItemFactory,
private \Magento\Quote\Api\Data\CartInterface $quote
) {}
public function convert(
\Magento\Quote\Api\Data\CartInterface $quote
): \Magento\Sales\Api\Data\OrderInterface {
// Create order from quote data
$order = $this->orderFactory->create();
// Transfer quote data to order
$order->setEntityId($quote->getId());
$order->setIncrementId($quote->getReservedOrderId());
$order->setStoreId($quote->getStoreId());
$order->setCustomerId($quote->getCustomerId());
$order->setCustomerEmail($quote->getCustomerEmail());
$order->setCustomerGroupId($quote->getCustomerGroupId());
// Transfer addresses
$order->setBillingAddress($this->convertAddress($quote->getBillingAddress()));
$order->setShippingAddress($this->convertAddress($quote->getShippingAddress()));
// Transfer payment
$order->setPayment($this->convertPayment($quote->getPayment()));
// Convert items
foreach ($quote->getItems() as $quoteItem) {
$orderItem = $this->convertItem($quoteItem);
$order->addItem($orderItem);
}
// Transfer totals
$this->transferTotals($quote, $order);
return $order;
}
}
Order Item Mapping
Quote Item to Order Item
private function convertItem(
\Magento\Quote\Api\Data\CartItemInterface $quoteItem
): \Magento\Sales\Api\Data\OrderItemInterface {
$orderItem = $this->orderItemFactory->create();
// Map quote item fields to order item
$orderItem->setProductId($quoteItem->getProductId());
$orderItem->setSku($quoteItem->getSku());
$orderItem->setName($quoteItem->getName());
$orderItem->setQtyOrdered($quoteItem->getQty());
$orderItem->setPrice($quoteItem->getPrice());
$orderItem->setBasePrice($quoteItem->getBasePrice());
$orderItem->setRowTotal($quoteItem->getRowTotal());
$orderItem->setBaseRowTotal($quoteItem->getBaseRowTotal());
$orderItem->setDiscountAmount($quoteItem->getDiscountAmount());
$orderItem->setBaseDiscountAmount($quoteItem->getBaseDiscountAmount());
$orderItem->setTaxAmount($quoteItem->getTaxAmount());
$orderItem->setBaseTaxAmount($quoteItem->getBaseTaxAmount());
// Store quote item ID for reference
$orderItem->setQuoteItemId($quoteItem->getId());
// Copy options
$orderItem->setProductOptions($quoteItem->getProductOptions());
// Parent item for configurable/bundle
if ($quoteItem->getParentItem()) {
$orderItem->setParentItem($this->convertItem($quoteItem->getParentItem()));
}
return $orderItem;
}
Item Type Mapping
// Product type handling during conversion
$itemType = $quoteItem->getProductType();
switch ($itemType) {
case 'configurable':
// Parent item stores configurable options
// Children are the actual simple products
$orderItem->setProductType('configurable');
break;
case 'bundle':
// Bundle options stored on parent
$orderItem->setProductType('bundle');
break;
case 'grouped':
// Each associated product is a separate item
$orderItem->setProductType('grouped');
break;
default:
$orderItem->setProductType('simple');
}
Order Totals Transfer
Totals Transfer
private function transferTotals(
\Magento\Quote\Api\Data\CartInterface $quote,
\Magento\Sales\Api\Data\OrderInterface $order
): void {
$shippingAddress = $quote->getShippingAddress();
// Transfer all totals
$order->setSubtotal($shippingAddress->getSubtotal());
$order->setBaseSubtotal($shippingAddress->getBaseSubtotal());
$order->setDiscountAmount($shippingAddress->getDiscountAmount());
$order->setBaseDiscountAmount($shippingAddress->getBaseDiscountAmount());
$order->setShippingAmount($shippingAddress->getShippingAmount());
$order->setBaseShippingAmount($shippingAddress->getBaseShippingAmount());
$order->setTaxAmount($shippingAddress->getTaxAmount());
$order->setBaseTaxAmount($shippingAddress->getBaseTaxAmount());
$order->setGrandTotal($shippingAddress->getGrandTotal());
$order->setBaseGrandTotal($shippingAddress->getBaseGrandTotal());
// Shipping details
$order->setShippingDescription($shippingAddress->getShippingDescription());
$order->setShippingMethod($shippingAddress->getShippingMethod());
// Coupon information
$order->setCouponCode($quote->getCouponCode());
$order->setDiscountDescription($shippingAddress->getDiscountDescription());
}
Currency Handling
// Base vs store currency
$order->setCurrencyCode($quote->getStore()->getCurrentCurrencyCode());
$order->setBaseCurrencyCode($quote->getStore()->getBaseCurrencyCode());
$order->setStoreCurrencyCode($quote->getStore()->getBaseCurrencyCode());
// Exchange rate
$order->setExchangeRate($quote->getStore()->convertPrice(1));
Conversion Errors and Rollback
Error Handling
try {
$order = $this->converter->convert($quote);
$this->orderRepository->save($order);
} catch (\Exception $e) {
// Rollback: restore inventory
$this->inventoryReservation->cancelReservation($order);
// Log error
$this->logger->critical('Quote to order conversion failed:', [
'quote_id' => $quote->getId(),
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString(),
]);
// Restore quote state
$quote->setIsActive(1);
$quote->save();
throw new \Magento\Framework\Exception\LocalizedException(
__('Order placement failed. Please try again.')
);
}
Quote State After Conversion
// After successful conversion
$quote->setIsActive(0);
$quote->setReservedOrderId(null);
$quote->save();
// Quote is kept for reference but marked inactive
// Can be used for reorder or history
Quiz
1. What data transfers from quote to order?
2. What happens to the quote after conversion?
3. How are configurable product options preserved?
Flashcards
Question
Quote to order conversion steps?
Click to reveal answer
Answer
Create order → transfer data → convert items → transfer totals → save
Question
What preserves product options?
Click to reveal answer
Answer
Order item product_options field stores configurable/bundle options
Question
Quote state after conversion?
Click to reveal answer
Answer
is_active = 0 (inactive), reserved_order_id cleared
Question
Conversion failure handling?
Click to reveal answer
Answer
Rollback inventory, restore quote, throw exception
Revision Notes
Key Takeaways
- 1. Quote to order transfers all data: items, addresses, payment, totals
- 2. Each quote item maps to an order item with full price/tax details
- 3. Totals include subtotal, discounts, shipping, tax, and grand total
- 4. Quote is deactivated after successful conversion but retained
- 5. Conversion errors trigger inventory rollback and quote restoration
Interview Tips
- • Describe the complete data flow from quote to order
- • Explain how configurable options are preserved in order items
- • Discuss error handling and rollback strategies during conversion
Cheat Sheet
Quote → Order Conversion:
Order data: store, customer, addresses
Items: product_id, sku, qty, price, options
Totals: subtotal, discount, shipping, tax, grand
Post-Conversion:
Quote: is_active=0, reserved_order_id=null
Order: created with incremented ID
Error Handling:
Inventory rollback + quote restoration