Chuyển hướng cổng thanh toán API Magento 2 REST


7

Tôi đang tạo một cửa hàng Magento 2 bán các sản phẩm ảo, trang web này có thanh toán trực tiếp tại trang sản phẩm. Các khách hàng sẽ không bao giờ mua nhiều hơn 1 sản phẩm cùng một lúc.

Việc thanh toán này sử dụng ajax callsnhằm vào API REST cho các bước trong giao dịch mua.

Cho đến nay tôi có thể tạo giỏ hàng mới, thêm sản phẩm, đặt địa chỉ thanh toán, đặt phương thức thanh toán, thu thập tổng số và đặt hàng. NHƯNG! Một trong những phương thức thanh toán chúng tôi sử dụng là cổng thẻ tín dụng bên ngoài . Tôi đã tạo một mô-đun phương thức thanh toán tùy chỉnh cho việc này và nó có thể được giải quyết thông qua các API. Tuy nhiên, phản hồi mà tôi nhận được từ "placeOrder()"lệnh gọi API chỉ chứa thứ tự entity_id.

Trực giác của tôi nói với tôi rằng tùy thuộc vào phương thức thanh toán, một lệnh gọi API như vậy sẽ thêm một cái gì đó vào phản hồi để nói với giao diện rằng sẽ có một chuyển hướng.

Tôi có thể đã bỏ lỡ điều gì đó, có thể một cuộc gọi API nên được thực hiện trước đó placeorderđể xử lý thanh toán và sau đó trong trường hợp chuyển hướng thực hiện placeordertại url gọi lại?

Có ai có ý tưởng về việc này được cho là như thế nào không?


Phản hồi của placeOrdersẽ chỉ chứa ID đơn hàng, không có gì phụ thuộc vào phương thức thanh toán.
Alex Paliarush

1
Tôi biết, nhưng nơi nào trong luồng sẽ là nơi hợp lý để tải thông tin xác thực phương thức thanh toán và gửi chúng cho khách hàng javascript? Vì vậy, yêu cầu bài thích hợp cho phương thức thanh toán có thể được thực hiện. Sau khi đặt hàng hay trước? Magento có một cuộc gọi api đặc biệt cho một người mỏng như thế này hay tôi nên tự viết?
nenne

Câu trả lời:


3

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-informationhoặc /V1/carts/mine/payment-informationbạn có thể:

  1. Nếu cổng thanh toán của bạn yêu cầu GETchuyể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.

  2. Nếu chuyển hướng của bạn thực sự cần phải là một POSTyê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_CheckoutExtnhư 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_Checkoutvào sequencethẻ 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\PaymentInformationManagementInterfacetrô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.xmlhoặc tốt hơn trong việc etc/webapi/di.xmlxá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.xmlvớ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.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.