Skip to content

Commit a8c60a5

Browse files
committed
magento/graphql-ce#716: [Checkout] Set Payment Method and Place Order Mutation
1 parent a5feb01 commit a8c60a5

File tree

10 files changed

+80
-75
lines changed

10 files changed

+80
-75
lines changed

app/code/Magento/AuthorizenetGraphQl/Model/AuthorizenetDataProvider.php

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,13 @@
99

1010
use Magento\QuoteGraphQl\Model\Cart\Payment\AdditionalDataProviderInterface;
1111
use Magento\Framework\Stdlib\ArrayManager;
12-
use Magento\Framework\GraphQL\DataObjectConverter;
1312

1413
/**
1514
* DataProvider Model for Authorizenet
1615
*/
1716
class AuthorizenetDataProvider implements AdditionalDataProviderInterface
1817
{
19-
private const PATH_ADDITIONAL_DATA = 'input/payment_method/additional_data/authorizenet_acceptjs';
18+
private const PATH_ADDITIONAL_DATA = 'authorizenet_acceptjs';
2019

2120
/**
2221
* @var ArrayManager
@@ -36,12 +35,12 @@ public function __construct(
3635
/**
3736
* Return additional data
3837
*
39-
* @param array $args
38+
* @param array $data
4039
* @return array
4140
*/
42-
public function getData(array $args): array
41+
public function getData(array $data): array
4342
{
44-
$additionalData = $this->arrayManager->get(static::PATH_ADDITIONAL_DATA, $args) ?? [];
43+
$additionalData = $this->arrayManager->get(static::PATH_ADDITIONAL_DATA, $data) ?? [];
4544
foreach ($additionalData as $key => $value) {
4645
$additionalData[$this->snakeCaseToCamelCase($key)] = $value;
4746
unset($additionalData[$key]);

app/code/Magento/QuoteGraphQl/Model/Cart/Payment/AdditionalDataProviderInterface.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ interface AdditionalDataProviderInterface
1515
/**
1616
* Return Additional Data
1717
*
18-
* @param array $args
18+
* @param array $data
1919
* @return array
2020
*/
21-
public function getData(array $args): array;
21+
public function getData(array $data): array;
2222
}

app/code/Magento/QuoteGraphQl/Model/Cart/Payment/AdditionalDataProviderPool.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,14 @@ public function __construct(array $dataProviders = [])
2929
* Return additional data for the payment method
3030
*
3131
* @param string $methodCode
32-
* @param array $args
32+
* @param array $data
3333
* @return array
3434
*/
35-
public function getData(string $methodCode, array $args): array
35+
public function getData(string $methodCode, array $data): array
3636
{
3737
$additionalData = [];
3838
if (isset($this->dataProviders[$methodCode])) {
39-
$additionalData = $this->dataProviders[$methodCode]->getData($args);
39+
$additionalData = $this->dataProviders[$methodCode]->getData($data);
4040
}
4141

4242
return $additionalData;

app/code/Magento/QuoteGraphQl/Model/Cart/SetPaymentMethodOnCart.php

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Magento\Quote\Api\Data\PaymentInterfaceFactory;
1616
use Magento\Quote\Api\PaymentMethodManagementInterface;
1717
use Magento\Quote\Model\Quote;
18+
use Magento\QuoteGraphQl\Model\Cart\Payment\AdditionalDataProviderPool;
1819

1920
class SetPaymentMethodOnCart
2021
{
@@ -28,27 +29,45 @@ class SetPaymentMethodOnCart
2829
*/
2930
private $paymentFactory;
3031

32+
/**
33+
* @var AdditionalDataProviderPool
34+
*/
35+
private $additionalDataProviderPool;
36+
3137
/**
3238
* @param PaymentMethodManagementInterface $paymentMethodManagement
3339
* @param PaymentInterfaceFactory $paymentFactory
40+
* @param AdditionalDataProviderPool $additionalDataProviderPool
3441
*/
3542
public function __construct(
3643
PaymentMethodManagementInterface $paymentMethodManagement,
37-
PaymentInterfaceFactory $paymentFactory
44+
PaymentInterfaceFactory $paymentFactory,
45+
AdditionalDataProviderPool $additionalDataProviderPool
3846
) {
3947
$this->paymentMethodManagement = $paymentMethodManagement;
4048
$this->paymentFactory = $paymentFactory;
49+
$this->additionalDataProviderPool = $additionalDataProviderPool;
4150
}
4251

43-
public function execute(array $paymentData, Quote $cart): Quote
52+
/**
53+
* Set payment method on cart
54+
*
55+
* @param Quote $cart
56+
* @param array $paymentData
57+
* @throws GraphQlInputException
58+
* @throws GraphQlNoSuchEntityException
59+
*/
60+
public function execute(Quote $cart, array $paymentData): void
4461
{
4562
if (!isset($paymentData['code']) || empty($paymentData['code'])) {
4663
throw new GraphQlInputException(__('Required parameter "code" for "payment_method" is missing.'));
4764
}
4865
$paymentMethodCode = $paymentData['code'];
4966

5067
$poNumber = $paymentData['purchase_order_number'] ?? null;
51-
$additionalData = $paymentData['additional_data'] ?? [];
68+
$additionalData = isset($paymentData['additional_data'])
69+
? $this->additionalDataProviderPool->getData($paymentMethodCode, $paymentData['additional_data'])
70+
: [];
5271

5372
$payment = $this->paymentFactory->create([
5473
'data' => [
@@ -65,7 +84,5 @@ public function execute(array $paymentData, Quote $cart): Quote
6584
} catch (LocalizedException $e) {
6685
throw new GraphQlInputException(__($e->getMessage()), $e);
6786
}
68-
69-
return $cart;
7087
}
7188
}

app/code/Magento/QuoteGraphQl/Model/Resolver/PlaceOrder.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,9 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value
6565

6666
$cart = $this->getCartForUser->execute($maskedCartId, $context->getUserId());
6767

68-
if ($context->getUserId() === 0) {
68+
if ((int)$context->getUserId() === 0) {
6969
if (!$cart->getCustomerEmail()) {
70-
throw new GraphQlInputException(__("Guest email for cart is missing. Please enter"));
70+
throw new GraphQlInputException(__("Guest email for cart is missing."));
7171
}
7272
$cart->setCheckoutMethod(CartManagementInterface::METHOD_GUEST);
7373
}

app/code/Magento/QuoteGraphQl/Model/Resolver/SetPaymentAndPlaceOrder.php

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
1717
use Magento\Quote\Api\CartManagementInterface;
1818
use Magento\QuoteGraphQl\Model\Cart\GetCartForUser;
19+
use Magento\QuoteGraphQl\Model\Cart\SetPaymentMethodOnCart;
1920
use Magento\Sales\Api\OrderRepositoryInterface;
2021

2122
/**
@@ -39,21 +40,21 @@ class SetPaymentAndPlaceOrder implements ResolverInterface
3940
private $orderRepository;
4041

4142
/**
42-
* @var \Magento\QuoteGraphQl\Model\Cart\SetPaymentMethodOnCart
43+
* @var SetPaymentMethodOnCart
4344
*/
4445
private $setPaymentMethodOnCart;
4546

4647
/**
4748
* @param GetCartForUser $getCartForUser
4849
* @param CartManagementInterface $cartManagement
4950
* @param OrderRepositoryInterface $orderRepository
50-
* @param \Magento\QuoteGraphQl\Model\Cart\SetPaymentMethodOnCart $setPaymentMethodOnCart
51+
* @param SetPaymentMethodOnCart $setPaymentMethodOnCart
5152
*/
5253
public function __construct(
5354
GetCartForUser $getCartForUser,
5455
CartManagementInterface $cartManagement,
5556
OrderRepositoryInterface $orderRepository,
56-
\Magento\QuoteGraphQl\Model\Cart\SetPaymentMethodOnCart $setPaymentMethodOnCart
57+
SetPaymentMethodOnCart $setPaymentMethodOnCart
5758
) {
5859
$this->getCartForUser = $getCartForUser;
5960
$this->cartManagement = $cartManagement;
@@ -77,11 +78,11 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value
7778
$paymentData = $args['input']['payment_method'];
7879

7980
$cart = $this->getCartForUser->execute($maskedCartId, $context->getUserId());
80-
$cart = $this->setPaymentMethodOnCart->execute($paymentData, $cart);
81+
$this->setPaymentMethodOnCart->execute($cart, $paymentData);
8182

82-
if ($context->getUserId() === 0) {
83+
if ((int)$context->getUserId() === 0) {
8384
if (!$cart->getCustomerEmail()) {
84-
throw new GraphQlInputException(__("Guest email for cart is missing. Please enter"));
85+
throw new GraphQlInputException(__("Guest email for cart is missing."));
8586
}
8687
$cart->setCheckoutMethod(CartManagementInterface::METHOD_GUEST);
8788
}

app/code/Magento/QuoteGraphQl/Model/Resolver/SetPaymentMethodOnCart.php

Lines changed: 8 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,12 @@
77

88
namespace Magento\QuoteGraphQl\Model\Resolver;
99

10-
use Magento\Framework\Exception\LocalizedException;
11-
use Magento\Framework\Exception\NoSuchEntityException;
1210
use Magento\Framework\GraphQl\Config\Element\Field;
1311
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
14-
use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException;
1512
use Magento\Framework\GraphQl\Query\ResolverInterface;
1613
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
17-
use Magento\Quote\Api\Data\PaymentInterface;
1814
use Magento\QuoteGraphQl\Model\Cart\GetCartForUser;
19-
use Magento\Quote\Api\Data\PaymentInterfaceFactory;
20-
use Magento\Quote\Api\PaymentMethodManagementInterface;
21-
use Magento\QuoteGraphQl\Model\Cart\Payment\AdditionalDataProviderPool;
22-
use Magento\Framework\App\ObjectManager;
15+
use Magento\QuoteGraphQl\Model\Cart\SetPaymentMethodOnCart as SetPaymentMethodOnCartModel;
2316

2417
/**
2518
* Mutation resolver for setting payment method for shopping cart
@@ -32,37 +25,20 @@ class SetPaymentMethodOnCart implements ResolverInterface
3225
private $getCartForUser;
3326

3427
/**
35-
* @var PaymentMethodManagementInterface
28+
* @var SetPaymentMethodOnCartModel
3629
*/
37-
private $paymentMethodManagement;
38-
39-
/**
40-
* @var PaymentInterfaceFactory
41-
*/
42-
private $paymentFactory;
43-
44-
/**
45-
* @var AdditionalDataProviderPool
46-
*/
47-
private $additionalDataProviderPool;
30+
private $setPaymentMethodOnCart;
4831

4932
/**
5033
* @param GetCartForUser $getCartForUser
51-
* @param PaymentMethodManagementInterface $paymentMethodManagement
52-
* @param PaymentInterfaceFactory $paymentFactory
53-
* @param AdditionalDataProviderPool $additionalDataProviderPool
34+
* @param SetPaymentMethodOnCartModel $setPaymentMethodOnCart
5435
*/
5536
public function __construct(
5637
GetCartForUser $getCartForUser,
57-
PaymentMethodManagementInterface $paymentMethodManagement,
58-
PaymentInterfaceFactory $paymentFactory,
59-
AdditionalDataProviderPool $additionalDataProviderPool = null
38+
SetPaymentMethodOnCartModel $setPaymentMethodOnCart
6039
) {
6140
$this->getCartForUser = $getCartForUser;
62-
$this->paymentMethodManagement = $paymentMethodManagement;
63-
$this->paymentFactory = $paymentFactory;
64-
$this->additionalDataProviderPool = $additionalDataProviderPool
65-
?: ObjectManager::getInstance()->get(AdditionalDataProviderPool::class);
41+
$this->setPaymentMethodOnCart = $setPaymentMethodOnCart;
6642
}
6743

6844
/**
@@ -78,28 +54,10 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value
7854
if (!isset($args['input']['payment_method']['code']) || empty($args['input']['payment_method']['code'])) {
7955
throw new GraphQlInputException(__('Required parameter "code" for "payment_method" is missing.'));
8056
}
81-
$paymentMethodCode = $args['input']['payment_method']['code'];
82-
83-
$poNumber = $args['input']['payment_method']['purchase_order_number'] ?? null;
84-
$additionalData = $this->additionalDataProviderPool->getData($paymentMethodCode, $args) ?? [];
57+
$paymentData = $args['input']['payment_method'];
8558

8659
$cart = $this->getCartForUser->execute($maskedCartId, $context->getUserId());
87-
$payment = $this->paymentFactory->create(
88-
[
89-
'data' => [
90-
PaymentInterface::KEY_METHOD => $paymentMethodCode,
91-
PaymentInterface::KEY_PO_NUMBER => $poNumber,
92-
PaymentInterface::KEY_ADDITIONAL_DATA => $additionalData,
93-
]]
94-
);
95-
96-
try {
97-
$this->paymentMethodManagement->set($cart->getId(), $payment);
98-
} catch (NoSuchEntityException $e) {
99-
throw new GraphQlNoSuchEntityException(__($e->getMessage()), $e);
100-
} catch (LocalizedException $e) {
101-
throw new GraphQlInputException(__($e->getMessage()), $e);
102-
}
60+
$this->setPaymentMethodOnCart->execute($cart, $paymentData);
10361

10462
return [
10563
'cart' => [

app/code/Magento/QuoteGraphQl/etc/schema.graphqls

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ type Mutation {
1818
setShippingMethodsOnCart(input: SetShippingMethodsOnCartInput): SetShippingMethodsOnCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\SetShippingMethodsOnCart")
1919
setPaymentMethodOnCart(input: SetPaymentMethodOnCartInput): SetPaymentMethodOnCartOutput @resolver(class: "Magento\\QuoteGraphQl\\Model\\Resolver\\SetPaymentMethodOnCart")
2020
setGuestEmailOnCart(input: SetGuestEmailOnCartInput): SetGuestEmailOnCartOutput @resolver(class: "Magento\\QuoteGraphQl\\Model\\Resolver\\SetGuestEmailOnCart")
21-
setPaymentMethodAndPlaceOrder(input: SetPaymentMethodOnCartInput): PlaceOrderOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\SetPaymentAndPlaceOrder")
21+
setPaymentMethodAndPlaceOrder(input: SetPaymentMethodAndPlaceOrderInput): PlaceOrderOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\SetPaymentAndPlaceOrder")
2222
placeOrder(input: PlaceOrderInput): PlaceOrderOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\PlaceOrder")
2323
}
2424

@@ -120,6 +120,11 @@ input ShippingMethodInput {
120120
method_code: String!
121121
}
122122

123+
input SetPaymentMethodAndPlaceOrderInput {
124+
cart_id: String!
125+
payment_method: PaymentMethodInput!
126+
}
127+
123128
input PlaceOrderInput {
124129
cart_id: String!
125130
}

dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/PlaceOrderTest.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,14 +118,16 @@ public function testPlaceOrderIfCartIdIsMissed()
118118
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_billing_address.php
119119
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_flatrate_shipping_method.php
120120
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_checkmo_payment_method.php
121+
*
122+
* @expectedException \Exception
123+
* @expectedExceptionMessage Guest email for cart is missing.
121124
*/
122125
public function testPlaceOrderWithNoEmail()
123126
{
124127
$reservedOrderId = 'test_quote';
125128
$maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute($reservedOrderId);
126129
$query = $this->getQuery($maskedQuoteId);
127130

128-
self::expectExceptionMessage("Guest email for cart is missing. Please enter");
129131
$this->graphQlMutation($query);
130132
}
131133

dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetPaymentMethodAndPlaceOrderTest.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,29 @@ public function testSetPaymentOnNonExistentCart()
144144
$this->graphQlMutation($query);
145145
}
146146

147+
/**
148+
* @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php
149+
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/enable_offline_shipping_methods.php
150+
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/enable_offline_payment_methods.php
151+
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php
152+
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php
153+
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php
154+
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_billing_address.php
155+
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_flatrate_shipping_method.php
156+
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_checkmo_payment_method.php
157+
*
158+
* @expectedException \Exception
159+
* @expectedExceptionMessage Guest email for cart is missing.
160+
*/
161+
public function testPlaceOrderWithNoEmail()
162+
{
163+
$methodCode = Checkmo::PAYMENT_METHOD_CHECKMO_CODE;
164+
$maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote');
165+
$query = $this->getQuery($maskedQuoteId, $methodCode);
166+
167+
$this->graphQlMutation($query);
168+
}
169+
147170
/**
148171
* _security
149172
* @magentoApiDataFixture Magento/Customer/_files/customer.php

0 commit comments

Comments
 (0)