Die Tatsache, dass dieser Endpunkt das Ergebnis des Aufrufs als einzelnes int anstelle von mindestens einem Objekt mit Auftrags-ID und Erweiterungsattribut definiert, ist schrecklich und wird sich wahrscheinlich nicht ändern. Wir werden sehen, was das Magento-Team für 2.3 erwartet, wenn es seine eigene PWA einführt und hoffentlich einen neuen Endpunkt mit besserer Unterstützung für Erweiterungen von Drittanbietern erstellt. Im Moment gibt es jedoch zwei Möglichkeiten:
Angenommen, Sie stellen eine Anfrage an /V1/guest-carts/:cartId/payment-information
oder /V1/carts/mine/payment-information
Sie können:
Wenn für Ihr Zahlungsgateway eine GET
Umleitung erforderlich ist, haken Sie einfach nach Magento\Checkout\Api\PaymentInformationManagementInterface::savePaymentInformationAndPlaceOrder()
und legen Sie die Umleitungs-URL entsprechend Ihren Anforderungen fest. Magento sollte den Weiterleitungsheader erkennen.
Wenn Ihre Umleitung tatsächlich eine POST
Anforderung sein muss, müssen Sie die Definition des Endpunkts überschreiben und eine eigene Schnittstelle bereitstellen, die ein vernünftigeres Ergebnis deklariert, das Sie im Browser verarbeiten können. Dies erfordert jedoch, dass auch native Magento-Klassen abgedeckt werden. Wenn Sie an dem Projekt für einen einzelnen Client arbeiten, funktioniert dies möglicherweise.
Erstellen Sie Ihr eigenes Modul, dh. Vendor_CheckoutExt
als separates Komponistenmodul oder in app/code/Vendor/CheckoutExt
. Stellen Sie sicher, dass Sie Magento_Checkout
dem sequence
Tag hinzufügen , module.xml
damit Ihre Definition nach Magento 1 gelesen wird.
In etc/webapi.xml
setzen Sie eine Definition wie:
<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>
Erstellen Sie eine Schnittstelle Vendor\CheckoutExt\Api\PaymentInformationManagementInterface
, die so aussieht
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
);
}
Erstellen Sie nun eine Schnittstelle für die Antwort
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
);
}
Wir haben Schnittstellen bereit, damit das Rest-API-Modul es zur Vorbereitung der Ausgabe verwenden kann. Jetzt müssen wir sie irgendwie implementieren, damit die Anfrage tatsächlich funktioniert. Hier gibt es zwei Möglichkeiten: Sie können entweder einfach die ursprüngliche bevorzugen und die Ausgabe mit dem Plugin vorbereiten oder selbst implementieren. Lassen Sie uns mit der ersten Option fortfahren, in etc/di.xml
oder besser in etc/webapi/di.xml
Präferenz definieren
<preference for="Vendor\CheckoutExt\Api\PaymentInformationManagementInterface" type="\Magento\Checkout\Model\PaymentInformationManagement" />
Dies funktioniert, da unsere Schnittstelle das native Magento One erweitert und wir die Funktionsdefinition nicht geändert haben, sondern nur das, was von der Funktion zurückgegeben werden soll. Die Magento-Klasse gibt jedoch eine einfache Ganzzahl zurück, und nur weil wir andere Ausgaben definiert haben, wird Magento diese nicht generieren. Wir müssen dazu. Implementieren wir also zuerst eine Klasse, die wir in der Antwort verwenden werden
<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);
}
}
Und das letzte Puzzleteil ist das Plugin, das nach dem Aufruf der ursprünglichen Bestellmethode verknüpft wird, um die zurückgegebene Ganzzahl in das von uns benötigte Objekt umzuwandeln. Wieder in di.xml
definieren
<type name="Magento\Checkout\Api\PaymentInformationManagementInterface">
<plugin name="vendorCheckoutExtSaveOrderResultPlugin" type="Vendor\CheckoutExt\Plugin\Checkout\PaymentInformationManagement" sortOrder="1" />
</type>
Und der Plugin-Code
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;
}
}
Das Ergebnis ist nun das Objekt, das extension_attributes implementiert. In Ihrem benutzerdefinierten Zahlungs-API-Modul können Sie ein ähnliches Plugin definieren. Stellen Sie einfach sicher, dass sortOrder höher als das oben genannte ist, damit Sie bereits ein Vendor\CheckoutExt\Api\Data\ResultInterface
Objekt als Argument erhalten.
Im Zahlungsmodul Datei erstellen etc/extension_attributes.xml
mit
<?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>
Erstellen Sie eine Schnittstelle und deren Implementierung gemäß Ihren Anforderungen und im 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;
}
}
Jetzt ist die Antwort richtig json mit extension_attributes, die Sie überprüfen und einbinden können. Möglicherweise müssen einige andere Elemente standardmäßig als Magento-Seite zur Erfolgsseite umgeleitet werden. Sie müssen daher sicherstellen, dass Sie sie deaktivieren, wenn Sie Ihre Weiterleitung vorbereiten. Ähnliche Überschreibungen müssen auch für Klassen vorgenommen werden, die das Auschecken von Gästen durchführen.
placeOrder
wird nur die Bestellnummer enthalten, nichts abhängig von der Zahlungsmethode.