このエンドポイントが呼び出しの結果を少なくとも注文IDと拡張属性を持つオブジェクトではなく単一のintとして定義するという事実はひどいものであり、おそらく変更されません。Magentoチームが独自にPWAを導入し、サードパーティの拡張機能をより適切にサポートする新しいエンドポイントを作成できるようになると、2.3で何が実現するかがわかります。現時点では、2つの方法があります。
あなたがリクエストをしていると仮定します、/V1/guest-carts/:cartId/payment-information
または/V1/carts/mine/payment-information
あなたができること:
支払いゲートウェイがGET
リダイレクトを必要とする場合は、単にフックMagento\Checkout\Api\PaymentInformationManagementInterface::savePaymentInformationAndPlaceOrder()
して、必要に応じてリダイレクトURLを設定します。Magentoはリダイレクトヘッダーを認識する必要があります。
リダイレクトが実際にPOST
リクエストである必要がある場合は、エンドポイントの定義をオーバーライドし、ブラウザで処理できるより妥当な結果を宣言する独自のインターフェースを提供する必要があります。ただし、これにはネイティブのMagentoクラスもカバーされていることを確認する必要があります。単一クライアントのプロジェクトで作業している場合、これでうまくいくかもしれません。
独自のモジュールを作成します。Vendor_CheckoutExt
別作曲モジュールまたは同様にapp/code/Vendor/CheckoutExt
。必ずタグに追加Magento_Checkout
してくださいsequence
module.xml
て、定義がmagentoの後に読み込まれるようにしてください。
次のetc/webapi.xml
ような定義を入れます:
<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>
次のVendor\CheckoutExt\Api\PaymentInformationManagementInterface
ようなインターフェースを作成する
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
);
}
次に、応答用のインターフェースを作成します
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
);
}
インターフェースの準備ができているので、残りのapiモジュールはそれを使用して出力を準備できます。次に、実際にリクエストを機能させるために、なんらかの方法でそれらを実装する必要があります。ここでは2つの可能性があります。単純に元の設定を選択し、プラグインを使用して出力を準備するか、それ自体を実装します。さんがに、最初のオプションで行こうetc/di.xml
か、より良いでetc/webapi/di.xml
プリファレンスを定義します
<preference for="Vendor\CheckoutExt\Api\PaymentInformationManagementInterface" type="\Magento\Checkout\Model\PaymentInformationManagement" />
これが機能するのは、インターフェースがネイティブMagentoを拡張し、関数定義を変更せず、関数から返されるものだけを変更するためです。しかし、Magentoクラスは単純な整数を返します。他の出力を定義したからといって、Magentoはそれを生成しません。これをする必要があります。それではまず、レスポンスで使用するクラスを実装しましょう
<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);
}
}
そしてパズルの最後のピースは、返された整数を必要なオブジェクトに変更するために元の注文メソッドが呼び出された後にフックするプラグインです。再びdi.xml
定義する
<type name="Magento\Checkout\Api\PaymentInformationManagementInterface">
<plugin name="vendorCheckoutExtSaveOrderResultPlugin" type="Vendor\CheckoutExt\Plugin\Checkout\PaymentInformationManagement" sortOrder="1" />
</type>
そしてプラグインコード
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;
}
}
したがって、結果はextension_attributesを実装するオブジェクトになります。カスタム支払いAPIモジュールで同様のプラグインを定義できます。sortOrderが上記のものよりも高いことを確認してください。Vendor\CheckoutExt\Api\Data\ResultInterface
オブジェクトを引数としてます。
支払いモジュールでファイルetc/extension_attributes.xml
を作成します
<?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>
必要に応じてプラグインでインターフェースとその実装を作成する
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;
}
}
これで、応答はextension_attributesが含まれた適切なjsonになり、チェックしてフックすることができます。デフォルトで成功ページへのリダイレクトでmagentoとしてカバーする他のいくつかの要素があるかもしれないので、リダイレクトを準備するときにそれを無効にすることを確認する必要があります。ゲストのチェックアウトを処理するクラスについても、同様の上書きを行う必要があります。
placeOrder
は注文IDのみが含まれ、支払い方法に依存しません。