Address Handling
Quote Address Model
// Magento\Quote\Model\Quote\Address
namespace Magento\Quote\Model\Quote\Address;
class Address extends \Magento\Framework\DataObject implements
\Magento\Quote\Api\Data\AddressInterface
{
/**
* Address types
*/
const TYPE_SHIPPING = 'shipping';
const TYPE_BILLING = 'billing';
public function getAddressType(): string
{
return $this->getData('address_type');
}
public function getCountryId(): string
{
return $this->getData('country_id');
}
public function getRegion(): ?\Magento\Directory\Api\Data\RegionInterface
{
return $this->getData('region');
}
public function getPostcode(): ?string
{
return $this->getData('postcode');
}
}
Setting Addresses on Quote
namespace Vendor\Checkout\Service;
class AddressManager
{
public function __construct(
private \Magento\Quote\Api\CartRepositoryInterface $cartRepository
) {}
public function setShippingAddress(
int $cartId,
array $addressData
): void {
$quote = $this->cartRepository->get($cartId);
$address = $quote->getShippingAddress();
$address->addData([
'firstname' => $addressData['firstname'],
'lastname' => $addressData['lastname'],
'street' => $addressData['street'],
'city' => $addressData['city'],
'region' => $addressData['region'],
'region_id' => $addressData['region_id'],
'postcode' => $addressData['postcode'],
'country_id' => $addressData['country_id'],
'telephone' => $addressData['telephone'],
'email' => $addressData['email'],
]);
$this->cartRepository->save($quote);
}
public function setBillingAddress(int $cartId, array $addressData): void
{
$quote = $this->cartRepository->get($cartId);
$billingAddress = $quote->getBillingAddress();
$billingAddress->addData($addressData);
// Same as shipping checkbox
if (!empty($addressData['same_as_shipping'])) {
$quote->getShippingAddress()->setSameAsBilling(1);
}
$this->cartRepository->save($quote);
}
}
Shipping Method Selection
Shipping Method Assignment
namespace Vendor\Checkout\Service;
class ShippingManager
{
public function __construct(
private \Magento\Quote\Api\CartRepositoryInterface $cartRepository,
private \Magento\Shipping\Model\Rate\ResultFactory $rateResultFactory
) {}
public function collectShippingRates(
int $cartId,
string $addressId = 'shipping'
): array {
$quote = $this->cartRepository->get($cartId);
$address = $quote->getShippingAddress();
$rates = $address->collectShippingRates()->getGroupedAllShippingRates();
$availableMethods = [];
foreach ($rates as $carrierRates) {
foreach ($carrierRates as $rate) {
$availableMethods[] = [
'carrier' => $rate->getCarrier(),
'method' => $rate->getMethod(),
'carrier_title' => $rate->getCarrierTitle(),
'method_title' => $rate->getMethodTitle(),
'price' => $rate->getPrice(),
];
}
}
return $availableMethods;
}
public function setShippingMethod(
int $cartId,
string $carrierCode,
string $methodCode
): void {
$quote = $this->cartRepository->get($cartId);
$address = $quote->getShippingAddress();
$address->setShippingMethod($carrierCode . '_' . $methodCode);
$address->setCollectShippingRates(true);
$address->collectShippingRates()->save();
$this->cartRepository->save($quote);
}
}
Payment Method Selection
Payment Method Assignment
namespace Vendor\Checkout\Service;
class PaymentManager
{
public function __construct(
private \Magento\Quote\Api\CartRepositoryInterface $cartRepository
) {}
public function setPaymentMethod(
int $cartId,
string $methodCode,
array $additionalData = []
): void {
$quote = $this->cartRepository->get($cartId);
$payment = $quote->getPayment();
$payment->setMethod($methodCode);
$payment->addData($additionalData);
$this->cartRepository->save($quote);
}
public function getAvailablePaymentMethods(
int $cartId
): array {
$quote = $this->cartRepository->get($cartId);
$methods = $quote->getPayment()->getAvailableMethods();
$result = [];
foreach ($methods as $method) {
$result[] = [
'code' => $method->getCode(),
'title' => $method->getTitle(),
];
}
return $result;
}
}
Checkout Step Data Flow
Checkout Data Persistence
// REST API: Set shipping address and method
POST /rest/V1/carts/mine/shipping-information
{
"addressInformation": {
"shipping_address": {
"firstname": "John",
"lastname": "Doe",
"street": ["123 Main St"],
"city": "New York",
"region_id": 43,
"postcode": "10001",
"country_id": "US",
"telephone": "555-1234"
},
"shipping_method_code": "flatrate",
"shipping_carrier_code": "flatrate"
}
}
// REST API: Set payment method and place order
POST /rest/V1/carts/mine/payment-information
{
"paymentMethod": {
"method": "checkmo"
},
"billingAddress": {
"firstname": "John",
"lastname": "Doe",
"street": ["123 Main St"],
"city": "New York",
"region_id": 43,
"postcode": "10001",
"country_id": "US",
"telephone": "555-1234"
}
}
Checkout Session State
// Quote holds all checkout state
$quote = $this->cartRepository->get($cartId);
// Shipping info
$shippingAddress = $quote->getShippingAddress();
$shippingMethod = $shippingAddress->getShippingMethod();
$shippingRates = $shippingAddress->getAllShippingRates();
// Payment info
$payment = $quote->getPayment();
$paymentMethod = $payment->getMethod();
$paymentData = $payment->getData();
// Recalculate totals after changes
$quote->collectTotals();
Quiz
1. How is the shipping method stored on the quote?
2. How do you get available shipping rates?
3. What happens when 'same as shipping' is set?
Flashcards
Question
How to set shipping method?
Click to reveal answer
Answer
$address->setShippingMethod('carriercode_methodcode')
Question
Where are shipping rates collected?
Click to reveal answer
Answer
$address->collectShippingRates()
Question
Payment method storage?
Click to reveal answer
Answer
$quote->getPayment()->setMethod('method_code')
Question
Address types?
Click to reveal answer
Answer
TYPE_SHIPPING and TYPE_BILLING on Quote\Address
Revision Notes
Key Takeaways
- 1. Quote addresses (shipping/billing) store customer address data during checkout
- 2. Shipping methods are collected based on address and cart contents
- 3. Payment methods are set on the quote's payment object
- 4. All checkout data persists on the quote until order placement
- 5. collectTotals() must be called after address or method changes
Interview Tips
- • Describe the flow: address → shipping rates → method selection → payment → totals
- • Explain how shipping rate calculation depends on address and cart weight/price
- • Discuss the separation of concerns between shipping and payment in checkout
Cheat Sheet
Shipping & Payment:
Address: $quote->getShippingAddress()->addData([...])
Rates: $address->collectShippingRates()
Method: $address->setShippingMethod('flatrate_flatrate')
Payment: $quote->getPayment()->setMethod('checkmo')
Totals: $quote->collectTotals()
REST APIs:
POST /V1/carts/mine/shipping-information
POST /V1/carts/mine/payment-information