Thực tế là điểm cuối này xác định kết quả của cuộc gọi là int đơn thay vì ít nhất là đối tượng có id thứ tự và thuộc tính mở rộng là khủng khiếp và có thể sẽ không thay đổi. Chúng ta sẽ thấy nhóm Magento sẽ ra sao cho 2.3 khi họ sẽ giới thiệu PWA của riêng họ và hy vọng tạo điểm cuối mới với sự hỗ trợ tốt hơn cho các tiện ích mở rộng của bên thứ 3. Ngay bây giờ tuy nhiên có 2 khả năng để làm:
Giả sử bạn đang thực hiện một yêu cầu /V1/guest-carts/:cartId/payment-information
hoặc /V1/carts/mine/payment-information
bạn có thể:
Nếu cổng thanh toán của bạn yêu cầu GET
chuyển hướng, chỉ cần móc sau Magento\Checkout\Api\PaymentInformationManagementInterface::savePaymentInformationAndPlaceOrder()
và đặt url chuyển hướng theo nhu cầu của bạn. Magento nên nhận ra tiêu đề chuyển hướng.
Nếu chuyển hướng của bạn thực sự cần phải là một POST
yêu cầu, bạn cần ghi đè định nghĩa của điểm cuối và cung cấp giao diện của riêng bạn, điều này sẽ khai báo kết quả hợp lý hơn mà bạn sẽ có thể xử lý trong trình duyệt. Tuy nhiên, điều này sẽ yêu cầu đảm bảo các lớp Magento bản địa cũng được bảo hiểm. Nếu bạn đang làm việc trên dự án cho một khách hàng, điều này có thể hoạt động.
Tạo mô-đun của riêng bạn, tức là. Vendor_CheckoutExt
như mô-đun soạn nhạc riêng biệt hoặc trong app/code/Vendor/CheckoutExt
. Hãy chắc chắn để thêm Magento_Checkout
vào sequence
thẻ module.xml
để định nghĩa của bạn sẽ được đọc sau một magento.
Trong etc/webapi.xml
đưa ra một định nghĩa như sau:
<route url="/V1/carts/mine/payment-information" method="POST">
<service class="Vendor\CheckoutExt\Api\PaymentInformationManagementInterface" method="savePaymentInformationAndPlaceOrder"/>
<resources>
<resource ref="self" />
</resources>
<data>
<parameter name="cartId" force="true">%cart_id%</parameter>
</data>
</route>
Tạo một giao diện Vendor\CheckoutExt\Api\PaymentInformationManagementInterface
trông giống như
namespace Vendor\CheckoutExt\Api;
use Magento\Checkout\Api\PaymentInformationManagementInterface as MagentoPaymentInformationManagementInterface;
interface PaymentInformationManagementInterface extends MagentoPaymentInformationManagementInterface
{
/**
* Set payment information and place order for a specified cart.
*
* @param int $cartId
* @param \Magento\Quote\Api\Data\PaymentInterface $paymentMethod
* @param \Magento\Quote\Api\Data\AddressInterface|null $billingAddress
* @throws \Magento\Framework\Exception\CouldNotSaveException
* @return \Vendor\CheckoutExt\Api\Data\ResultInterface place order result data.
*/
public function savePaymentInformationAndPlaceOrder(
$cartId,
\Magento\Quote\Api\Data\PaymentInterface $paymentMethod,
\Magento\Quote\Api\Data\AddressInterface $billingAddress = null
);
}
Bây giờ tạo giao diện cho phản hồi
namespace Vendor\CheckoutExt\Api\Data;
interface ResultInterface
{
/**
* @param string $orderId
* @return Vendor\CheckoutExt\Api\Data\ResultInterface
*/
public function setOrderId($orderId);
/**
* @return string
*/
public function getOrderId();
/**
* Retrieve existing extension attributes object or create a new one.
*
* @return Vendor\CheckoutExt\Api\Data\ResultInterface
*/
public function getExtensionAttributes();
/**
* Set an extension attributes object.
*
* @param Vendor\CheckoutExt\Api\Data\ResultExtensionInterface $extensionAttributes
* @return $this
*/
public function setExtensionAttributes(
Vendor\CheckoutExt\Api\Data\ResultExtensionInterface $extensionAttributes
);
}
Chúng tôi có sẵn giao diện để mô-đun api còn lại sẽ có thể sử dụng nó để chuẩn bị đầu ra. Bây giờ chúng ta cần thực hiện chúng bằng cách nào đó để thực sự làm cho yêu cầu hoạt động. Ở đây có 2 khả năng, bạn có thể chỉ cần tạo một ưu tiên cho cái ban đầu và chuẩn bị đầu ra bằng cách sử dụng plugin hoặc tự thực hiện nó. Hãy đi với tùy chọn đầu tiên, trong etc/di.xml
hoặc tốt hơn trong việc etc/webapi/di.xml
xác định tùy chọn
<preference for="Vendor\CheckoutExt\Api\PaymentInformationManagementInterface" type="\Magento\Checkout\Model\PaymentInformationManagement" />
Điều này sẽ hoạt động vì giao diện của chúng tôi mở rộng Magento gốc và chúng tôi đã không thay đổi định nghĩa hàm, chỉ những gì sẽ được trả về từ hàm. Nhưng lớp Magento trả về số nguyên đơn giản và chỉ vì chúng tôi đã định nghĩa đầu ra khác Magento sẽ không tạo ra nó. Chúng ta cần phải làm điều này. Vì vậy, trước tiên hãy thực hiện lớp mà chúng ta sẽ sử dụng trong phản hồi
<preference for="Vendor\CheckoutExt\Api\Data\ResultInterface" type="Vendor\CheckoutExt\Model\Data\OrderResponse" />
namespace Vendor\CheckoutExt\Model\Data;
use Vendor\CheckoutExt\Api\Data\ResultInterface;
use Vendor\CheckoutExt\Api\Data\ResultExtensionInterface;
use Magento\Framework\Model\AbstractExtensibleModel;
class Result extends AbstractExtensibleModel implements ResultInterface
{
/**
* @param string $orderId
* @return \Vendor\CheckoutExt\Api\Data\ResultInterface
*/
public function setOrderId($orderId)
{
return $this->setData(self::ORDER_ID, $orderId);
}
/**
* @return string
*/
public function getOrderId()
{
return $this->_getData(self::ORDER_ID);
}
/**
* @param string $incrementId
* @return \Vendor\CheckoutExt\Api\Data\ResultInterface
*/
public function setOrderRealId($incrementId)
{
return $this->setData(self::ORDER_REAL_ID, $incrementId);
}
/**
* @return string
*/
public function getOrderRealId()
{
return $this->_getData(self::ORDER_REAL_ID);
}
/**
* @return \Vendor\CheckoutExt\Api\Data\ResultExtensionInterface
*/
public function getExtensionAttributes()
{
$extensionAttributes = $this->_getExtensionAttributes();
if (!$extensionAttributes) {
/** @var ResultExtensionInterface $extensionAttributes */
$extensionAttributes = $this->extensionAttributesFactory->create(ResultInterface::class);
}
return $extensionAttributes;
}
/**
* @param \Vendor\CheckoutExt\Api\Data\ResultExtensionInterface $extensionAttributes
* @return \Vendor\CheckoutExt\Api\Data\ResultInterface
*/
public function setExtensionAttributes(ResultExtensionInterface $extensionAttributes)
{
return $this->_setExtensionAttributes($extensionAttributes);
}
}
Và phần cuối cùng của câu đố là plugin sẽ móc nối sau khi phương thức đặt hàng ban đầu được gọi để thay đổi số nguyên trả về thành đối tượng chúng ta cần. Một lần nữa trong di.xml
định nghĩa
<type name="Magento\Checkout\Api\PaymentInformationManagementInterface">
<plugin name="vendorCheckoutExtSaveOrderResultPlugin" type="Vendor\CheckoutExt\Plugin\Checkout\PaymentInformationManagement" sortOrder="1" />
</type>
Và mã plugin
namespace Vendor\CheckoutExt\Plugin\Checkout;
use Vendor\CheckoutExt\Api\Data\ResultInterface;
use Vendor\CheckoutExt\Api\Data\ResultInterfaceFactory;
use Magento\Checkout\Api\PaymentInformationManagementInterface;
class PaymentInformationManagement
{
/** @var ResultFactory */
private $resultFactory;
/**
* @param ResultInterfaceFactory $resultFactory
*/
public function __construct(ResultInterfaceFactory $resultFactory)
{
$this->resultFactory = $resultFactory;
}
/**
* @param PaymentInformationManagementInterface $subject
* @param int $orderId
* @return ResultInterface
*/
public function afterSavePaymentInformationAndPlaceOrder(
PaymentInformationManagementInterface $subject,
$orderId
) {
/** @var ResultInterface $obj */
$obj = $this->resultFactory->create();
$obj->setOrderId($orderId);
return $obj;
}
}
Vì vậy, bây giờ kết quả là đối tượng thực hiện phần mở rộng. Trong mô-đun api thanh toán tùy chỉnh của bạn, bạn có thể xác định plugin tương tự, chỉ cần đảm bảo sortOrder có cao hơn mức trên để bạn có thể lấy Vendor\CheckoutExt\Api\Data\ResultInterface
đối tượng làm đối số.
Trong mô-đun thanh toán tạo tập tin etc/extension_attributes.xml
với
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd">
<extension_attributes for="Vendor\ChecoutExt\Api\Data\ResultInterface">
<attribute code="my_payment_gateway_data" type="Vendor\CustomPayment\Api\Data\RedirectInterface" />
</extension_attributes>
</config>
Tạo giao diện và cách thực hiện theo nhu cầu của bạn và trong plugin
namespace Vendor\CustomPayment\Plugin\Checkout;
use Vendor\CustomPayment\Api\Data\RedirectInterface;
use Vendor\CustomPayment\Api\Data\RedirectInterfaceFactory;
use Vendor\CheckoutExt\Api\Data\ResultInterface;
use Magento\Checkout\Api\PaymentInformationManagementInterface;
class PaymentInformationManagement
{
/** @var RedirectInterfaceFactory */
private $redirectFactory;
/**
* @param RedirectInterfaceFactory $redirectFactory
*/
public function __construct(RedirectInterfaceFactory $redirectFactory)
{
$this->redirectFactory = $redirectFactory;
}
/**
* @param PaymentInformationManagementInterface $subject
* @param ResultInterface $orderId
* @return ResultInterface
*/
public function afterSavePaymentInformationAndPlaceOrder(
PaymentInformationManagementInterface $subject,
$orderId
) {
/** @var ResultInterface $obj */
$redirect = $this->redirectFactory->create();
$extensionAttributes = $orderId->getExtensionAttributes();
$extensionAttributes->setMyPaymentGatewayData($redirect);
$orderId->setExtensionAttributes($extensionAttributes);
return $orderId;
}
}
Bây giờ phản hồi là json thích hợp với extension_attribut trong đó bạn có thể kiểm tra và nối vào. Có thể có một số yếu tố khác để trình bày dưới dạng magento theo mặc định chuyển hướng đến trang thành công, vì vậy bạn cần đảm bảo rằng bạn đã tắt nó khi chuẩn bị chuyển hướng của mình. Cũng ghi đè tương tự cần phải được thực hiện cho các lớp xử lý kiểm tra khách.
placeOrder
sẽ chỉ chứa ID đơn hàng, không có gì phụ thuộc vào phương thức thanh toán.