Question

I tried to create order programmatically with flat rate shipping method with the help of below code. Here, order created successfully but shipping method and rates not apply to order.

use Magento\Framework\App\Bootstrap;
require __DIR__ . '/../app/bootstrap.php';
$params = $_SERVER;
$bootstrap = Bootstrap::create(BP, $params);
$objectManager = $bootstrap->getObjectManager();
$state = $objectManager->get('Magento\Framework\App\State');
$state->setAreaCode('frontend');


$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$storeManager = $objectManager->get('\Magento\Store\Model\StoreManagerInterface');
$store = $storeManager->getStore(5);
$storeCode = $store->getCode();
$storeManager->setCurrentStore($storeCode);

$coreSession = $objectManager->create('\Magento\Framework\Session\SessionManagerInterface');
$coreSession->setIsFailOrder('YES');    //  Biggest patch because we have to create order with archive status and also follow PCI compliance.

$orderData=[
    'currency_id'  => 'USD',
    'email'        => 'helloworld@mageplaza.com', //buyer email id
    'shipping_address' =>[
        'firstname'    => 'John', //address Details
        'lastname'     => 'Doe',
        'street' => '123 Demo',
        'city' => 'Mageplaza',
        'country_id' => 'US',
        'region' => 43, //'xxx',
        'postcode' => '10019',
        'telephone' => '0123456789',
        'fax' => '32423',
        'save_in_address_book' => 1
    ],
   'items'=> [ //array of product which order you want to create
        ['product_id' => '5', 'qty'=> 2]
    ]
];


$store = $storeManager->getStore();
$websiteId = $storeManager->getStore()->getWebsiteId();
$customer = $objectManager->create('Magento\Customer\Model\Customer');
$customer->setWebsiteId($websiteId);
$customer->loadByEmail($orderData['email']);// load customet by email address

if(!$customer->getEntityId()){
    //If not avilable then create this customer 
    $customer->setWebsiteId($websiteId)
            ->setStore($store)
            ->setFirstname($orderData['shipping_address']['firstname'])
            ->setLastname($orderData['shipping_address']['lastname'])
            ->setEmail($orderData['email']) 
            ->setPassword($orderData['email']);
    $customer->save();
}

$quote = $objectManager->create('Magento\Quote\Model\Quote');
$quote->setStore($store); //set store for which you create quote
// if you have allready buyer id then you can load customer directly 
$customerRepository = $objectManager->create('Magento\Customer\Api\CustomerRepositoryInterface');
$customer = $customerRepository->getById($customer->getEntityId());
$quote->assignCustomer($customer); //Assign quote to customer

//add items in quote
$product = $objectManager->create('Magento\Catalog\Model\Product');
foreach($orderData['items'] as $item){
    $product = $product->load($item['product_id']);
    $product->setPrice($product->getPrice());
    $quote->addProduct(
        $product,
        intval($item['qty'])
    );
}

//Set Address to quote
$quote->getBillingAddress()->addData($orderData['shipping_address']);
$quote->getShippingAddress()->addData($orderData['shipping_address']);

// Collect Rates and Set Shipping & Payment Method
$shippingRate = $objectManager->get('Magento\Quote\Model\Quote\Address\Rate');
$shippingRate->setCode('flatrate_flatrate')->getPrice(0);

$shippingAddress = $quote->getShippingAddress();
$shippingAddress->setCollectShippingRates(true)
                ->collectShippingRates()
                ->setShippingMethod('flatrate_flatrate'); //shipping method
$quote->getShippingAddress()->addShippingRate($shippingRate);


$shoppingCartPriceRule = $objectManager->create('Magento\SalesRule\Model\Rule');
$rule = $shoppingCartPriceRule->load(9);
$rule->setDiscountAmount('7')->save();
$quote->setCouponCode('amazoncode');

$quote->setPaymentMethod('cashondelivery'); //payment method
$quote->setInventoryProcessed(false); //not effetc inventory
$quote->save(); //Now Save quote and your quote is ready

// Set Sales Order Payment
$quote->getPayment()->importData(['method' => 'cashondelivery']);

// Collect Totals & Save Quote
$quote->collectTotals()->save();

// Create Order From Quote
$quoteManagement = $objectManager->create('Magento\Quote\Model\QuoteManagement');
$order = $quoteManagement->submit($quote);
$order->setEmailSent(0);

$payment = $order->getPayment();
$payment->setMethod('authorizenet_acceptjs'); // Assuming 'test' is updated payment method
$payment->save();
$order->setState('new');
$order->setStatus('archive');
$order->setEmailSent(0);
$order->save();
$incrementId = $order->getRealOrderId();
$custoemrName = $order->getCustomerName();
$coreSession->unsIsFailOrder();
echo $incrementId;exit;

enter image description here

Please help me how to assign shipping method and rates to order?

Regards Hiren Shah

Était-ce utile?

La solution

please use below code it working fine in my store

https://drops.meetanshi.com/GAWATQ

ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
ini_set('memory_limit', '5G');
error_reporting(E_ALL);

use Magento\Framework\App\Bootstrap;

require 'app/bootstrap.php';
$bootstrap = Bootstrap::create(BP, $_SERVER);
$objectManager = $bootstrap->getObjectManager();
$state = $objectManager->get('Magento\Framework\App\State');
$state->setAreaCode('frontend');

$fileFactory = $objectManager->create('Magento\Framework\App\Response\Http\FileFactory');


$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$storeManager = $objectManager->get('\Magento\Store\Model\StoreManagerInterface');
$store = $storeManager->getStore(1);
$storeCode = $store->getCode();
$storeManager->setCurrentStore($storeCode);

$coreSession = $objectManager->create('\Magento\Framework\Session\SessionManagerInterface');
$coreSession->setIsFailOrder('YES');    //  Biggest patch because we have to create order with archive status and also follow PCI compliance.

$orderData = [
    'currency_id' => 'INR',
    'email' => 'helloworld@mageplaza.com', //buyer email id
    'shipping_address' => [
        'firstname' => 'John', //address Details
        'lastname' => 'Doe',
        'street' => '123 Demo',
        'city' => 'Mageplaza',
        'country_id' => 'IN',
        'region' => 544, //'xxx',
        'postcode' => '10019',
        'telephone' => '0123456789',
        'fax' => '32423',
        'save_in_address_book' => 1
    ],
    'items' => [ //array of product which order you want to create
        ['product_id' => '1', 'qty' => 2]
    ]
];

try {


    $store = $storeManager->getStore();
    $websiteId = $storeManager->getStore()->getWebsiteId();
    $customer = $objectManager->create('Magento\Customer\Model\Customer');
    $customer->setWebsiteId($websiteId);
    $customer->loadByEmail($orderData['email']);// load customet by email address

    if (!$customer->getEntityId()) {
        //If not avilable then create this customer
        $customer->setWebsiteId($websiteId)
            ->setStore($store)
            ->setFirstname($orderData['shipping_address']['firstname'])
            ->setLastname($orderData['shipping_address']['lastname'])
            ->setEmail($orderData['email'])
            ->setPassword($orderData['email']);
        $customer->save();
    }

    $quote = $objectManager->create('Magento\Quote\Model\Quote');
    $quote->setStore($store); //set store for which you create quote
// if you have allready buyer id then you can load customer directly
    $customerRepository = $objectManager->create('Magento\Customer\Api\CustomerRepositoryInterface');
    $customer = $customerRepository->getById($customer->getEntityId());
    $quote->assignCustomer($customer); //Assign quote to customer

//add items in quote
    $product = $objectManager->create('Magento\Catalog\Model\Product');
    foreach ($orderData['items'] as $item) {
        $product = $product->load($item['product_id']);
        $product->setPrice($product->getPrice());
        $quote->addProduct(
            $product,
            intval($item['qty'])
        );
    }

//Set Address to quote
    $quote->getBillingAddress()->addData($orderData['shipping_address']);
    $quote->getShippingAddress()->addData($orderData['shipping_address']);

    $shippingAddress = $quote->getShippingAddress();
    $shippingAddress->setCollectShippingRates(true)->collectShippingRates()->setShippingMethod('freeshipping_freeshipping ');
    $quote->setPaymentMethod('cashondelivery');
    $quote->setInventoryProcessed(false);
    $quote->save();

// Set Sales Order Payment
    $quote->getPayment()->importData(['method' => 'cashondelivery']);

// Collect Totals & Save Quote
    $quote->collectTotals()->save();

// Create Order From Quote
    $quoteManagement = $objectManager->create('Magento\Quote\Model\QuoteManagement');
    $order = $quoteManagement->submit($quote);
    $order->setEmailSent(0);

    $payment = $order->getPayment();
    $payment->setMethod('authorizenet_acceptjs'); // Assuming 'test' is updated payment method
    $payment->save();
    $order->setState('new');
    $order->setStatus('archive');
    $order->setEmailSent(0);
    $order->save();
    $incrementId = $order->getRealOrderId();
    $custoemrName = $order->getCustomerName();
    $coreSession->unsIsFailOrder();
    echo $incrementId;
} catch (\Exception $e) {
    echo 'error:-  ' . $e->getMessage();
}

Autres conseils

I was having the same issue and found that you need to use this model

$shippingQuoteRate = $objectManager->get('\Magento\Quote\Model\Quote\Address\Rate');

then you need to set the quote_shipping_rate parameters. The values can be found in the the database table quote_shipping_rate

Here is my complete working:

$orderData =[
'currency_id'  => 'USD',
'email'        => trim($email), //buyer email id
'shipping_address' =>[
    'firstname'    => trim($first_name), //address Details
    'lastname'     => trim($last_name),
    'street' => $formattedAddress['address'],
    'city' => $formattedAddress['city'],
    'country_id' => $formattedAddress['country'],
    'region' => $formattedAddress['state'],
    'postcode' => $formattedAddress['zip'],
    'telephone' => trim($phone),
    'save_in_address_book' => 1
],
'items'=> [
    //array of product which order you want to create
    ['product_id'=>$productId,'qty'=>1,'price'=>$productPriceById]
]
];

Then here is my method using objectmanager

$bootstrap = Bootstrap::create(BP, $_SERVER);

$obj = $bootstrap->getObjectManager();
  
$state = $obj->get('Magento\Framework\App\State');
$state->setAreaCode('frontend');

$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
  
$storeManager = $objectManager->get('\Magento\Store\Model\StoreManagerInterface');
$store = $storeManager->getStore();
$websiteId = $storeManager->getStore()->getWebsiteId();

$customerFactory = $objectManager->get('\Magento\Customer\Model\CustomerFactory')->create();

/**
 * check whether the email address is already registered or not
 */
$customer = $customerFactory->setWebsiteId($websiteId)->loadByEmail($orderData['email']);
if (!$customer->getId()) {
    try {
        $customer = $objectManager->get('\Magento\Customer\Model\CustomerFactory')->create();
        $customer->setWebsiteId($websiteId);
        $customer->setEmail($orderData['email']);
        $customer->setFirstname($orderData['shipping_address']['firstname']);
        $customer->setLastname($orderData['shipping_address']['lastname']);
        $customer->setPassword($orderData['email']);
        $customer->save();
  
        $customer->setConfirmation(null);
        $customer->save();

        $customAddress = $objectManager->get('\Magento\Customer\Model\AddressFactory')->create();
        $customAddress->setData($orderData['shipping_address'])
                      ->setCustomerId($customer->getId())
                      ->setIsDefaultBilling('1')
                      ->setIsDefaultShipping('1')
                      ->setSaveInAddressBook('1');
        $customAddress->save();  
    } catch (Exception $e) {
        echo $e->getMessage();
    }
}

$customer = $objectManager->get('\Magento\Customer\Api\CustomerRepositoryInterface')->getById($customer->getId());
try {

    $quoteFactory = $objectManager->get('\Magento\Quote\Model\QuoteFactory')->create();
    $shippingQuoteRate = $objectManager->get('\Magento\Quote\Model\Quote\Address\Rate');
    $quoteFactory->setStore($store);
    $quoteFactory->setCurrency();
    $quoteFactory->assignCustomer($customer);
    foreach ($orderData['items'] as $item) {
        $product = $objectManager->get('\Magento\Catalog\Model\ProductRepository')->getById($item['product_id']);// get product by product id 
        $quoteFactory->addProduct($product, intval($item['qty']));  // add products to quote
    }
  
    /*
    * Set Address to quote
    */
    $quoteFactory->getBillingAddress()->addData($orderData['shipping_address']);
    $quoteFactory->getShippingAddress()->addData($orderData['shipping_address']);

    /*
    * Collect Rates and Set Shipping & Payment Method
    * You can get this information from the database table `quote_shipping_rate`
    */
    $shippingRateCarrier = 'usps';
    $shippingRateCarrierTitle = 'United States Postal Service';
    $shippingRateCode = 'usps_0_FCP';
    $shippingRateMethod = '0_FCP';
    $shippingRatePrice = '9.95';
    $shippingRateMethodTitle = 'First-Class Package Service - Retail';

    $shippingAddress = $quoteFactory->getShippingAddress();

    $shippingQuoteRate->setCarrier($shippingRateCarrier);
    $shippingQuoteRate->setCarrierTitle($shippingRateCarrierTitle);
    $shippingQuoteRate->setCode($shippingRateCode);
    $shippingQuoteRate->setMethod($shippingRateMethod);
    $shippingQuoteRate->setPrice($shippingRatePrice);
    $shippingQuoteRate->setMethodTitle($shippingRateMethodTitle);

    $shippingAddress->setCollectShippingRates(true)
                    ->collectShippingRates()
                    ->setShippingMethod($shippingRateCode); //shipping method
    $quoteFactory->getShippingAddress()->addShippingRate($shippingQuoteRate);

    $quoteFactory->setPaymentMethod('purchaseorder'); //payment method
    $quoteFactory->setInventoryProcessed(false);
    $quoteFactory->save();

    /*
    * Set Sales Order Payment
    */
    $quoteFactory->getPayment()->importData(['method' => 'purchaseorder','po_number' => $orderNo]);

    /*
    * Collect Totals & Save Quote
    */
    $quoteFactory->collectTotals()->save();

    /*
    * Create Order From Quote
    */
    
    $order = $objectManager->get('\Magento\Quote\Model\QuoteManagement')->submit($quoteFactory);
    $order->setEmailSent(0);
    $payment = $order->getPayment();
    $payment->setMethod('purchaseorder'); // Assuming 'purchaseorder' is updated payment method
    $payment->setPoNumber($orderNo);
    $payment->save();
    $order->setState('new');
    $order->setStatus('pending');
    
    $order->setEmailSent(0);
    
    $order->save();

    echo "<br/>Order Created<br/>";
} catch (Exception $e) {
    echo $e->getMessage();
}

Below code works perfectly.

<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
ini_set('memory_limit', '5G');
error_reporting(E_ALL);

use Magento\Framework\App\Bootstrap;

require __DIR__ . '/../app/bootstrap.php';
$params = $_SERVER;
$bootstrap = Bootstrap::create(BP, $params);
$objectManager = $bootstrap->getObjectManager();
$state = $objectManager->get('Magento\Framework\App\State');
$state->setAreaCode('frontend');

$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$storeManager = $objectManager->get('\Magento\Store\Model\StoreManagerInterface');
$store = $storeManager->getStore(5);    //  Set particular store if multi-store available
$storeCode = $store->getCode();
$storeManager->setCurrentStore($storeCode);

$orderData = [
    'currency_id' => 'USD',
    'email' => 'helloworld@mageplaza.com', //buyer email id
    'shipping_address' => [
        'firstname' => 'John', //address Details
        'lastname' => 'Doe',
        'street' => '123 Demo',
        'city' => 'New York',
        'country_id' => 'US',
        'region' => 43, //'xxx',
        'postcode' => '10001',
        'telephone' => '0123456789',
        'fax' => '32423',
        'save_in_address_book' => 1
    ],
    'items' => [ //array of product which order you want to create
        ['product_id' => '1', 'qty' => 2]
    ]
];

try {

    $store = $storeManager->getStore();
    $websiteId = $storeManager->getStore()->getWebsiteId();
    $customer = $objectManager->create('Magento\Customer\Model\Customer');
    $customer->setWebsiteId($websiteId);
    $customer->loadByEmail($orderData['email']);// load customet by email address

    if (!$customer->getEntityId()) {
        //If not avilable then create this customer
        $customer->setWebsiteId($websiteId)
            ->setStore($store)
            ->setFirstname($orderData['shipping_address']['firstname'])
            ->setLastname($orderData['shipping_address']['lastname'])
            ->setEmail($orderData['email'])
            ->setPassword($orderData['email']);
        $customer->save();
    }

    $quote = $objectManager->create('Magento\Quote\Model\Quote');
    $quote->setStore($store); //set store for which you create quote
    $quote->setStoreId($store->getId());

    $customerRepository = $objectManager->create('Magento\Customer\Api\CustomerRepositoryInterface');
    $customer = $customerRepository->getById($customer->getEntityId());
    $quote->assignCustomer($customer); //Assign quote to customer

    $product = $objectManager->create('Magento\Catalog\Model\Product');
    foreach ($orderData['items'] as $item) {
        $product = $product->load($item['product_id']);
        $product->setPrice($product->getPrice());
        $quote->addProduct(
            $product,
            intval($item['qty'])
        );
    }

    $billingAddressData = $quote->getBillingAddress()->addData($orderData['shipping_address']);
    $shippingAddressData = $quote->getShippingAddress()->addData($orderData['shipping_address']);

    //Collect shipping rates on quote
    $shippingAddressData->setCollectShippingRates(true)->collectShippingRates();

    $shoppingCartPriceRule = $objectManager->create('Magento\SalesRule\Model\Rule');
    $rule = $shoppingCartPriceRule->load(9);
    $discountamt = 10;  //($discount > 0)?$discount:0;
    $rule->setDiscountAmount($discountamt)->save();
    $quote->setCouponCode('amazoncode');

    $shippingAddressData->setCollectShippingRates(true);
    $shippingAddressData->setShippingMethod('uspsstandard_uspsstandard')->setPaymentMethod('cashondelivery');   //  Custom shipping method same like faltrate_flatrate
    $quote->setInventoryProcessed(false);
    $quote->save();

    $quote->getPayment()->importData(['method' => 'cashondelivery']);

    $quote->collectTotals()->save();

    $quoteManagement = $objectManager->create('Magento\Quote\Model\QuoteManagement');
    $order = $quoteManagement->submit($quote);
    $order->setEmailSent(0);

    $payment = $order->getPayment();
    $payment->setMethod('authorizenet_acceptjs'); // Assuming 'test' is updated payment method
    $payment->save();
    $order->setState('new');
    $order->setStatus('archive');
    $order->setEmailSent(0);
    $order->save();
    $incrementId = $order->getRealOrderId();
    $custoemrName = $order->getCustomerName();
    echo $incrementId;
} catch (\Exception $e) {
    echo 'error:-  ' . $e->getMessage();
}

?>

The code you are trying to do should always be in a command object.

http://www.rosenborgsolutions.com/phpunit-magento-command.php

The code like below is really unclean and wrong way to program in magento

// This way to code is wrong
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
ini_set('memory_limit', '5G');
error_reporting(E_ALL);

use Magento\Framework\App\Bootstrap;

require 'app/bootstrap.php';
$bootstrap = Bootstrap::create(BP, $_SERVER);
$objectManager = $bootstrap->getObjectManager();
$state = $objectManager->get('Magento\Framework\App\State');
$state->setAreaCode('frontend');
Licencié sous: CC-BY-SA avec attribution
Non affilié à magento.stackexchange
scroll top