Order Placement Flow
Place Order Service
namespace Magento\Checkout\Model;
class PlaceOrder
{
public function __construct(
private \Magento\Quote\Api\CartRepositoryInterface $cartRepository,
private \Magento\Quote\Api\CartManagementInterface $cartManagement,
private \Magento\Quote\Model\QuoteFactory $quoteFactory
) {}
public function execute(int $cartId): int
{
$cart = $this->cartRepository->get($cartId);
// Validate cart
$this->validateCart($cart);
// Reserve order ID
$cart->reserveOrderId();
// Convert quote to order
$orderId = $this->cartManagement->placeOrder($cartId);
return $orderId;
}
private function validateCart(\Magento\Quote\Api\Data\CartInterface $cart): void
{
if ($cart->getItemsCount() === 0) {
throw new \Magento\Framework\Exception\LocalizedException(
__('Cart is empty')
);
}
if (!$cart->getShippingAddress()->getShippingMethod()) {
throw new \Magento\Framework\Exception\LocalizedException(
__('Shipping method not selected')
);
}
if (!$cart->getPayment()->getMethod()) {
throw new \Magento\Framework\Exception\LocalizedException(
__('Payment method not selected')
);
}
}
}
Inventory Reservation
Inventory Reservation System
// Magento\InventoryReservation\Model\ReservationFactory
namespace Magento\Inventory\Api\ReservationServiceInterface;
interface ReservationServiceInterface
{
/**
* Create inventory reservation
*/
public function create(
string $sku,
int $stockId,
float $quantity,
string $reservationId
): void;
}
Reservation During Order Placement
// During order creation, inventory is reserved
namespace Magento\Sales\Model\Service\Order;
class InventoryReservation
{
public function __construct(
private \Magento\Inventory\Api\ReservationServiceInterface $reservationService,
private \Magento\Inventory\Api\StockResolverInterface $stockResolver
) {}
public function reserve(
\Magento\Sales\Api\Data\OrderInterface $order
): void {
foreach ($order->getItems() as $item) {
$stockId = $this->stockResolver->execute(
$item->getWebsiteId()
)->getStockId();
$this->reservationService->create(
$item->getSku(),
$stockId,
-$item->getQtyOrdered(),
sprintf('order:%s:items:%s', $order->getIncrementId(), $item->getItemId())
);
}
}
}
Reservation Cleanup
// Cancel reservation when order is cancelled
public function cancelReservation(\Magento\Sales\Api\Data\OrderInterface $order): void
{
foreach ($order->getItems() as $item) {
$this->reservationService->create(
$item->getSku(),
$stockId,
$item->getQtyOrdered(), // Positive to release
sprintf('order:%s:cancel', $order->getIncrementId())
);
}
}
Payment Processing
Payment During Order Placement
namespace Magento\Quote\Model\QuoteManagement;
class PaymentProcessor
{
public function process(
\Magento\Quote\Model\Quote $quote,
\Magento\Sales\Api\Data\OrderInterface $order
): void {
$payment = $order->getPayment();
$paymentMethod = $quote->getPayment()->getMethod();
// Get payment method instance
$method = $this->paymentMethodPool->getMethod($paymentMethod);
// Process based on action type
switch ($method->getConfigData('payment_action')) {
case 'authorize':
$method->authorize($payment, $order->getGrandTotal());
break;
case 'authorize_capture':
$method->order($payment, $order->getGrandTotal());
break;
}
// Set order status
$order->setStatus($method->getConfigData('order_status'));
}
}
Payment Error Handling
try {
$orderId = $this->placeOrder->execute($cartId);
} catch (\Magento\Framework\Exception\PaymentException $e) {
// Payment failed - restore inventory
$this->inventoryReservation->cancelReservation($order);
// Log error
$this->logger->error('Payment failed: ' . $e->getMessage());
throw new \Magento\Framework\Exception\LocalizedException(
__('Payment processing failed: %1', $e->getMessage())
);
} catch (\Exception $e) {
// General error
$this->logger->critical($e);
throw $e;
}
Complete Order Placement
Quote to Order Conversion
// Full order placement flow
public function placeOrder(int $cartId): int
{
$cart = $this->cartRepository->get($cartId);
// 1. Validate cart items
$this->validateItems($cart);
// 2. Reserve order ID
$cart->reserveOrderId();
// 3. Collect totals
$cart->collectTotals();
// 4. Create order from quote
$order = $this->quoteToOrderConverter->convert($cart);
// 5. Process payment
$this->paymentProcessor->process($cart, $order);
// 6. Reserve inventory
$this->inventoryReservation->reserve($order);
// 7. Save order
$this->orderRepository->save($order);
// 8. Send order confirmation email
$this->orderEmailSender->send($order);
// 9. Deactivate quote
$cart->setIsActive(0)->save();
return $order->getEntityId();
}
Guest Order Placement
// Guest order with email
POST /rest/V1/guest-carts/{cartId}/payment-information
{
"paymentMethod": {
"method": "checkmo"
},
"billingAddress": {
"firstname": "Guest",
"lastname": "Customer",
"email": "guest@example.com",
"street": ["123 Main St"],
"city": "New York",
"region_id": 43,
"postcode": "10001",
"country_id": "US",
"telephone": "555-1234"
}
}
Quiz
1. What happens to inventory when an order is placed?
2. What is the order of operations during order placement?
3. What happens if payment fails during order placement?
Flashcards
Question
Order placement first step?
Click to reveal answer
Answer
Validate cart (items, shipping method, payment method)
Question
What is inventory reservation?
Click to reveal answer
Answer
Decrementing stock when order is placed to prevent overselling
Question
Payment processing order?
Click to reveal answer
Answer
authorize (hold) or authorize_capture (collect) based on config
Question
Post-order actions?
Click to reveal answer
Answer
Send email, deactivate quote, log order
Revision Notes
Key Takeaways
- 1. Order placement validates cart, reserves ID, processes payment, and saves order
- 2. Inventory is reserved during order placement to prevent overselling
- 3. Payment methods support authorize-only or authorize-capture actions
- 4. Failed payments trigger inventory reservation cleanup
- 5. Guest orders use email as identifier instead of customer ID
Interview Tips
- • Describe the complete order placement flow from cart to order
- • Explain how inventory reservation prevents overselling
- • Discuss error handling when payment processing fails
Cheat Sheet
Order Placement Flow:
1. Validate cart
2. Reserve order ID
3. Collect totals
4. Convert quote to order
5. Process payment
6. Reserve inventory
7. Save order
8. Send email
9. Deactivate quote
Inventory:
Reserve on order: negative qty
Release on cancel: positive qty
Payment:
authorize → hold funds
authorize_capture → collect funds