Skip to content

Commit 59c1a78

Browse files
committed
Merge remote-tracking branch 'mainline/2.4-develop' into PWA-805-group
2 parents d441705 + 6cb92ae commit 59c1a78

File tree

17 files changed

+610
-109
lines changed

17 files changed

+610
-109
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
11+
<actionGroup name="StorefrontGoToCustomerOrderDetailsPageActionGroup">
12+
<annotations>
13+
<description>Navigate to storefront order details page</description>
14+
</annotations>
15+
<arguments>
16+
<argument name="orderId" type="string"/>
17+
<argument name="orderNumber" type="string"/>
18+
</arguments>
19+
<amOnPage url="{{StorefrontCustomerOrderViewPage.url(orderId)}}" stepKey="goToOrdersPage"/>
20+
<waitForPageLoad stepKey="waitForPageLoad"/>
21+
<waitForText selector="{{StorefrontCustomerAccountMainSection.pageTitle}}" userInput="{{orderNumber}}" stepKey="verifyOrderNo"/>
22+
</actionGroup>
23+
</actionGroups>
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
11+
<actionGroup name="StorefrontVerifyCustomerOrderDataActionGroup">
12+
<annotations>
13+
<description>Verify a customer's order details on the view order page on the storefront</description>
14+
</annotations>
15+
<arguments>
16+
<argument name="createdDate" type="string"/>
17+
<argument name="productName" type="string"/>
18+
<argument name="grandTotal" type="string"/>
19+
<argument name="orderPlacedBy" type="string"/>
20+
<argument name="paymentMethod" type="string"/>
21+
</arguments>
22+
<waitForText selector="{{StorefrontCustomerOrderViewSection.paymentMethod}}" userInput="{{paymentMethod}}" stepKey="storefrontVerifyPaymentMethod"/>
23+
<waitForText selector="{{StorefrontCustomerOrderViewSection.createdDate}}" userInput="{{createdDate}}" stepKey="storefrontVerifyOrderCreatedDate"/>
24+
<waitForText selector="{{StorefrontCustomerOrderViewSection.orderPlacedBy}}" userInput="{{orderPlacedBy}}" stepKey="storefrontVerifyOrderPlacedBy"/>
25+
<waitForText selector="{{StorefrontCustomerOrderViewSection.productName}}" userInput="{{productName}}" stepKey="storefrontVerifyProductName"/>
26+
<waitForText selector="{{StorefrontCustomerOrderViewSection.grandTotal}}" userInput="{{grandTotal}}" stepKey="storefrontVerifyGrandTotal"/>
27+
28+
</actionGroup>
29+
</actionGroups>

app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerOrderViewSection.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,9 @@
1818
<element name="billingAddress" type="text" selector=".box.box-order-billing-address"/>
1919
<element name="orderStatusInGrid" type="text" selector="//td[contains(.,'{{orderId}}')]/../td[contains(.,'{{status}}')]" parameterized="true"/>
2020
<element name="pager" type="block" selector=".pager"/>
21+
<element name="createdDate" type="text" selector=".block-order-details-comments .comment-date"/>
22+
<element name="orderPlacedBy" type="text" selector=".block-order-details-comments .comment-content"/>
23+
<element name="productName" type="text" selector="//td[@data-th='Product Name']"/>
24+
<element name="grandTotal" type="text" selector="//tr[@class='grand_total']//td[@data-th='Grand Total']"/>
2125
</section>
2226
</sections>
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\PaypalGraphQl\Model\Plugin\Cart\PayflowPro;
9+
10+
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
11+
use Magento\Paypal\Model\Config;
12+
use Magento\Quote\Model\Quote;
13+
use Magento\QuoteGraphQl\Model\Cart\Payment\AdditionalDataProviderPool;
14+
use Magento\Sales\Model\Order\Payment\Repository as PaymentRepository;
15+
use Magento\PaypalGraphQl\Observer\PayflowProSetCcData;
16+
17+
/**
18+
* Set additionalInformation on payment for PayflowPro method
19+
*/
20+
class SetPaymentMethodOnCart
21+
{
22+
/**
23+
* @var PaymentRepository
24+
*/
25+
private $paymentRepository;
26+
27+
/**
28+
* @var AdditionalDataProviderPool
29+
*/
30+
private $additionalDataProviderPool;
31+
32+
/**
33+
* @param PaymentRepository $paymentRepository
34+
* @param AdditionalDataProviderPool $additionalDataProviderPool
35+
*/
36+
public function __construct(
37+
PaymentRepository $paymentRepository,
38+
AdditionalDataProviderPool $additionalDataProviderPool
39+
) {
40+
$this->paymentRepository = $paymentRepository;
41+
$this->additionalDataProviderPool = $additionalDataProviderPool;
42+
}
43+
44+
/**
45+
* Set redirect URL paths on payment additionalInformation
46+
*
47+
* @param \Magento\QuoteGraphQl\Model\Cart\SetPaymentMethodOnCart $subject
48+
* @param mixed $result
49+
* @param Quote $cart
50+
* @param array $paymentData
51+
* @return void
52+
* @throws GraphQlInputException
53+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
54+
*/
55+
public function afterExecute(
56+
\Magento\QuoteGraphQl\Model\Cart\SetPaymentMethodOnCart $subject,
57+
$result,
58+
Quote $cart,
59+
array $paymentData
60+
): void {
61+
$paymentData = $this->additionalDataProviderPool->getData(Config::METHOD_PAYFLOWPRO, $paymentData);
62+
$cartCustomerId = (int)$cart->getCustomerId();
63+
if ($cartCustomerId === 0 &&
64+
array_key_exists(PayflowProSetCcData::IS_ACTIVE_PAYMENT_TOKEN_ENABLER, $paymentData)) {
65+
$payment = $cart->getPayment();
66+
$payment->unsAdditionalInformation(PayflowProSetCcData::IS_ACTIVE_PAYMENT_TOKEN_ENABLER);
67+
$payment->save();
68+
}
69+
}
70+
}

app/code/Magento/PaypalGraphQl/Model/Resolver/PayflowProResponse.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,9 @@ public function resolve(
126126
$this->parameters->fromString(urldecode($paypalPayload));
127127
$data = $this->parameters->toArray();
128128
try {
129-
$do = $this->dataObjectFactory->create(['data' => array_change_key_case($data, CASE_LOWER)]);
130-
$this->responseValidator->validate($do, $this->transparent);
131-
$this->transaction->savePaymentInQuote($do, $cart->getId());
129+
$response = $this->transaction->getResponseObject($data);
130+
$this->responseValidator->validate($response, $this->transparent);
131+
$this->transaction->savePaymentInQuote($response, $cart->getId());
132132
} catch (LocalizedException $exception) {
133133
$parameters['error'] = true;
134134
$parameters['error_msg'] = $exception->getMessage();
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
namespace Magento\PaypalGraphQl\Observer;
10+
11+
use Magento\Framework\App\Config\ScopeConfigInterface;
12+
use Magento\Framework\Event\Observer;
13+
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
14+
use Magento\Payment\Observer\AbstractDataAssignObserver;
15+
use Magento\Quote\Api\Data\PaymentInterface;
16+
17+
/**
18+
* Class PayflowProSetCcData set CcData to quote payment
19+
* @SuppressWarnings(PHPMD.CookieAndSessionMisuse)
20+
*/
21+
class PayflowProSetCcData extends AbstractDataAssignObserver
22+
{
23+
const XML_PATH_PAYMENT_PAYFLOWPRO_CC_VAULT_ACTIVE = "payment/payflowpro_cc_vault/active";
24+
const IS_ACTIVE_PAYMENT_TOKEN_ENABLER = "is_active_payment_token_enabler";
25+
26+
/**
27+
* Core store config
28+
*
29+
* @var ScopeConfigInterface
30+
*/
31+
private $scopeConfig;
32+
33+
/**
34+
* @param ScopeConfigInterface $scopeConfig
35+
*/
36+
public function __construct(
37+
ScopeConfigInterface $scopeConfig
38+
) {
39+
$this->scopeConfig = $scopeConfig;
40+
}
41+
42+
/**
43+
* Set CcData
44+
*
45+
* @param Observer $observer
46+
*
47+
* @throws GraphQlInputException
48+
*/
49+
public function execute(Observer $observer)
50+
{
51+
$dataObject = $this->readDataArgument($observer);
52+
$additionalData = $dataObject->getData(PaymentInterface::KEY_ADDITIONAL_DATA);
53+
$paymentModel = $this->readPaymentModelArgument($observer);
54+
55+
if (!isset($additionalData['cc_details'])) {
56+
return;
57+
}
58+
59+
if ($this->isPayflowProVaultEnable()) {
60+
if (!isset($additionalData[self::IS_ACTIVE_PAYMENT_TOKEN_ENABLER])) {
61+
$paymentModel->setData(self::IS_ACTIVE_PAYMENT_TOKEN_ENABLER, false);
62+
}
63+
64+
$paymentModel->setData(
65+
self::IS_ACTIVE_PAYMENT_TOKEN_ENABLER,
66+
$additionalData[self::IS_ACTIVE_PAYMENT_TOKEN_ENABLER]
67+
);
68+
} else {
69+
$paymentModel->setData(self::IS_ACTIVE_PAYMENT_TOKEN_ENABLER, false);
70+
}
71+
72+
$ccData = $additionalData['cc_details'];
73+
$paymentModel->setCcType($ccData['cc_type']);
74+
$paymentModel->setCcExpYear($ccData['cc_exp_year']);
75+
$paymentModel->setCcExpMonth($ccData['cc_exp_month']);
76+
$paymentModel->setCcLast4($ccData['cc_last_4']);
77+
}
78+
79+
/**
80+
* Check if payflowpro vault is enable
81+
*
82+
* @return bool
83+
*/
84+
private function isPayflowProVaultEnable()
85+
{
86+
return (bool)$this->scopeConfig->getValue(self::XML_PATH_PAYMENT_PAYFLOWPRO_CC_VAULT_ACTIVE);
87+
}
88+
}

app/code/Magento/PaypalGraphQl/composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
"magento/module-store": "*"
1717
},
1818
"suggest": {
19-
"magento/module-graph-ql": "*"
19+
"magento/module-graph-ql": "*",
20+
"magento/module-store-graph-ql": "*"
2021
},
2122
"type": "magento2-module",
2223
"license": [

app/code/Magento/PaypalGraphQl/etc/graphql/di.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
</type>
1212
<type name="Magento\QuoteGraphQl\Model\Cart\SetPaymentMethodOnCart">
1313
<plugin name="hosted_pro_payment_method" type="Magento\PaypalGraphQl\Model\Plugin\Cart\HostedPro\SetPaymentMethodOnCart"/>
14+
<plugin name="payflowpro_payment_method" type="Magento\PaypalGraphQl\Model\Plugin\Cart\PayflowPro\SetPaymentMethodOnCart"/>
1415
</type>
1516
<type name="Magento\Paypal\Model\Payflowlink">
1617
<plugin name="payflow_link_update_redirect_urls" type="Magento\PaypalGraphQl\Model\Plugin\Payflowlink"/>
@@ -53,4 +54,12 @@
5354
</argument>
5455
</arguments>
5556
</type>
57+
58+
<type name="Magento\StoreGraphQl\Model\Resolver\Store\StoreConfigDataProvider">
59+
<arguments>
60+
<argument name="extendedConfigData" xsi:type="array">
61+
<item name="payment_payflowpro_cc_vault_active" xsi:type="string">payment/payflowpro_cc_vault/active</item>
62+
</argument>
63+
</arguments>
64+
</type>
5665
</config>

app/code/Magento/PaypalGraphQl/etc/graphql/events.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,7 @@
1212
<event name="payment_method_assign_data_payflow_advanced">
1313
<observer name="payflow_advanced_data_assigner" instance="Magento\PaypalGraphQl\Observer\PayflowLinkSetAdditionalData"/>
1414
</event>
15+
<event name="payment_method_assign_data_payflowpro">
16+
<observer name="payflowpro_cc_data_assigner" instance="Magento\PaypalGraphQl\Observer\PayflowProSetCcData" />
17+
</event>
1518
</config>

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ input PayflowProTokenInput @doc(description:"Input required to fetch payment tok
102102

103103
input PayflowProInput @doc(description:"Required input for Payflow Pro and Payments Pro payment methods.") {
104104
cc_details: CreditCardDetailsInput! @doc(description: "Required input for credit card related information")
105+
is_active_payment_token_enabler: Boolean @doc(description:"States whether details about the customer's credit/debit card should be tokenized for later usage. Required only if Vault is enabled for PayPal Payflow Pro payment integration.")
105106
}
106107

107108
input CreditCardDetailsInput @doc(description:"Required fields for Payflow Pro and Payments Pro credit card payments") {
@@ -141,3 +142,7 @@ input PayflowProResponseInput @doc(description:"Input required to complete payme
141142
type PayflowProResponseOutput {
142143
cart: Cart!
143144
}
145+
146+
type StoreConfig {
147+
payment_payflowpro_cc_vault_active: String @doc(description: "Payflow Pro vault status.")
148+
}

0 commit comments

Comments
 (0)