Magento2 Place Order 代码执行逻辑分析

前台js执行逻辑

点击页面的 Place Order 按钮执行下面default.js中的 placeOrder 方法

vendor/magento/module-checkout/view/frontend/web/js/view/payment/default.js

placeOrder: function (data, event) {
var self = this;

if (event) {
event.preventDefault();
}

console.log('placeOrder');
console.log(this.getData());


if (this.validate() &&
additionalValidators.validate() &&
this.isPlaceOrderActionAllowed() === true
) {
this.isPlaceOrderActionAllowed(false);

this.getPlaceOrderDeferredObject()
.done(
function () {
self.afterPlaceOrder();

if (self.redirectAfterPlaceOrder) {
redirectOnSuccessAction.execute();
}
}
).always(
function () {
self.isPlaceOrderActionAllowed(true);
}
);

return true;
}

return false;
},

其中重要方法是 getPlaceOrderDeferredObject

getPlaceOrderDeferredObject: function () {
return $.when(
placeOrderAction(this.getData(), this.messageContainer)
);
},

其中 placeOrderAction 调用 vendor/magento/module-checkout/view/frontend/web/js/action/place-order.js

/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

/**
 * @api
 */
define([
    'Magento_Checkout/js/model/quote',
    'Magento_Checkout/js/model/url-builder',
    'Magento_Customer/js/model/customer',
    'Magento_Checkout/js/model/place-order'
], function (quote, urlBuilder, customer, placeOrderService) {
    'use strict';

    return function (paymentData, messageContainer) {
        var serviceUrl, payload;

        payload = {
            cartId: quote.getQuoteId(),
            billingAddress: quote.billingAddress(),
            paymentMethod: paymentData
        };

        if (customer.isLoggedIn()) {
            serviceUrl = urlBuilder.createUrl('/carts/mine/payment-information', {});
        } else {
            serviceUrl = urlBuilder.createUrl('/guest-carts/:quoteId/payment-information', {
                quoteId: quote.getQuoteId()
            });
            payload.email = quote.guestEmail;
        }

        return placeOrderService(serviceUrl, payload, messageContainer);
    };
});

后台php执行逻辑

登录用户执行:/carts/mine/payment-information

未登录用户执行:/guest-carts/:quoteId/payment-information

上面url定义在vendor/magento/module-checkout/etc/webapi.xml

<route url="/V1/carts/mine/payment-information" method="POST">
    <service class="Magento\Checkout\Api\PaymentInformationManagementInterface" method="savePaymentInformationAndPlaceOrder"/>
    <resources>
        <resource ref="self" />
    </resources>
    <data>
        <parameter name="cartId" force="true">%cart_id%</parameter>
    </data>
</route>

(1) 核心属性

属性说明
url="/V1/carts/mine/payment-information"API 端点路径,mine 表示当前用户的购物车
method="POST"仅接受 POST 请求

(2) 关键节点

节点作用
<service class="...PaymentInformationManagementInterface" method="savePaymentInformationAndPlaceOrder"/>绑定到 PaymentInformationManagementInterface 的 savePaymentInformationAndPlaceOrder 方法
<resources><resource ref="self" /></resources>权限控制:仅允许操作当前用户的购物车(需登录认证)
<data><parameter name="cartId" force="true">%cart_id%</parameter></data>
  1. 后端处理
    • 框架自动将 %cart_id% 替换为当前用户的购物车 ID。
    • 调用 PaymentInformationManagementInterface::savePaymentInformationAndPlaceOrder($cartId, $paymentMethod, $billingAddress)

上面接口是由“Magento\Checkout\Model\PaymentInformationManagement”来实现的。配置在

vendor/magento/module-checkout/etc/di.xml

即:vendor/magento/module-checkout/Model/PaymentInformationManagement.php的 savePaymentInformationAndPlaceOrder 方法

发表评论