资料一:
I’ll use following data for create quote and order
$tempOrder=[ 'currency_id' => 'USD', 'email' => 'test@webkul.com', //buyer email id 'shipping_address' =>[ 'firstname' => 'jhon', //address Details 'lastname' => 'Deo', 'street' => 'xxxxx', 'city' => 'xxxxx', 'country_id' => 'IN', 'region' => 'xxx', 'postcode' => '43244', 'telephone' => '52332', 'fax' => '32423', 'save_in_address_book' => 1 ], 'items'=> [ //array of product which order you want to create ['product_id'=>'1','qty'=>1], ['product_id'=>'2','qty'=>2] ] ];
I’ll write order create function in module helper file
<?php namespace YourNameSpace\ModuleName\Helper; class Data extends \Magento\Framework\App\Helper\AbstractHelper { /** * @param Magento\Framework\App\Helper\Context $context * @param Magento\Store\Model\StoreManagerInterface $storeManager * @param Magento\Catalog\Model\Product $product, * @param Magento\Quote\Api\CartRepositoryInterface $cartRepositoryInterface, * @param Magento\Quote\Api\CartManagementInterface $cartManagementInterface, * @param Magento\Customer\Model\CustomerFactory $customerFactory, * @param Magento\Customer\Api\CustomerRepositoryInterface $customerRepository, * @param Magento\Sales\Model\Order $order */ public function __construct( \Magento\Framework\App\Helper\Context $context, \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Catalog\Model\Product $product, \Magento\Quote\Api\CartRepositoryInterface $cartRepositoryInterface, \Magento\Quote\Api\CartManagementInterface $cartManagementInterface, \Magento\Customer\Model\CustomerFactory $customerFactory, \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository, \Magento\Sales\Model\Order $order ) { $this->_storeManager = $storeManager; $this->_product = $product; $this->cartRepositoryInterface = $cartRepositoryInterface; $this->cartManagementInterface = $cartManagementInterface; $this->customerFactory = $customerFactory; $this->customerRepository = $customerRepository; $this->order = $order; parent::__construct($context); } /** * Create Order On Your Store * * @param array $orderData * @return array * */ public function createMageOrder($orderData) { $store=$this->_storeManager->getStore(); $websiteId = $this->_storeManager->getStore()->getWebsiteId(); $customer=$this->customerFactory->create(); $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(); } $cartId = $this->cartManagementInterface->createEmptyCart(); //Create empty cart $quote = $this->cartRepositoryInterface->get($cartId); // load empty cart quote $quote->setStore($store); // if you have allready buyer id then you can load customer directly $customer= $this->customerRepository->getById($customer->getEntityId()); $quote->setCurrency(); $quote->assignCustomer($customer); //Assign quote to customer //add items in quote foreach($orderData['items'] as $item){ $product=$this->_product->load($item['product_id']); $product->setPrice($item['price']); $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 $shippingAddress=$quote->getShippingAddress(); $shippingAddress->setCollectShippingRates(true) ->collectShippingRates() ->setShippingMethod('freeshipping_freeshipping'); //shipping method $quote->setPaymentMethod('checkmo'); //payment method $quote->setInventoryProcessed(false); //not effetc inventory // Set Sales Order Payment $quote->getPayment()->importData(['method' => 'checkmo']); $quote->save(); //Now Save quote and your quote is ready // Collect Totals $quote->collectTotals(); // Create Order From Quote $quote = $this->cartRepositoryInterface->get($quote->getId()); $orderId = $this->cartManagementInterface->placeOrder($quote->getId()); $order = $this->order->load($orderId); $order->setEmailSent(0); $increment_id = $order->getRealOrderId(); if($order->getEntityId()){ $result['order_id']= $order->getRealOrderId(); }else{ $result=['error'=>1,'msg'=>'Your custom message']; } return $result; } } ?>
Now using this method you can crate quote and order in magento2 programmatically.
Thanks ? .
资料二:
I am developing a Payment Gateway which the payment will be done by redirecting the browser to the bank website and payment would be done there and after a success it will be redirected back to the website
I could be able to redirect using the JavaScript code in payment renderer successfully but the problem is that the order will not be placed before the redirection to the bank
How to make the order and get the Order_ID before sending the user to the bank
The following is my js Code that redirects the user to a sepecific controller that handles the redirection
continueToMellat: function () {
//update payment method information if additional data was changed
$.mage.redirect(url.build('redirect/redirect'));
this.selectPaymentMethod();
setPaymentMethodAction(this.messageContainer);
return false;
}
Answers
I could be able to place order before redirecting by changing the code to the following, this will place the order before sending to the payment gateway I am now trying to get the order id of which the user has just ordered
continueToMellat: function () {
if (this.validate() && additionalValidators.validate()) {
this.isPlaceOrderActionAllowed(false);
this.getPlaceOrderDeferredObject()
.fail(
function () {
self.isPlaceOrderActionAllowed(true);
}
).done(
function () {
self.afterPlaceOrder();
if (self.redirectAfterPlaceOrder) {
redirectOnSuccessAction.execute();
}
}
);
}
//update payment method information if additional data was changed
$.mage.redirect(url.build('redirect/redirect'));
this.selectPaymentMethod();
setPaymentMethodAction(this.messageContainer);
return false;
}
You could maybe use the cart ID : getQuoteId() like used in
//vendor/magento/module-checkout/view/frontend/web/js/action/get-payment-information.js
define([
'jquery',
'Magento_Checkout/js/model/quote',
...
], function ($, quote, ...) {
'use strict';
return function (deferred, messageContainer) {
var serviceUrl;
deferred = deferred || $.Deferred();
/**
* Checkout for guest and registered customer.
*/
if (!customer.isLoggedIn()) {
serviceUrl = urlBuilder.createUrl('/guest-carts/:cartId/payment-information', {
cartId: quote.getQuoteId()
});
}
though the order increment Id can be reserved in server before passing to client processing :
__construct(\Magento\Checkout\Model\Session $checkoutSession){
$this->quote = $checkoutSession->getQuote();
}
...
$this->quote->reserveOrderId();
$orderId = $this->quote->getReservedOrderId();
参考1: https://webkul.com/blog/create-quote-and-order-programmatically-in-magento2/
参考2: https://stackoverflow.com/questions/42989047/magento-2-place-order-before-sending-to-payment-gateway