Skip to content

Commit

Permalink
PPI-1056 - Refactor payment handlers to AbstractPaymentHandlers
Browse files Browse the repository at this point in the history
  • Loading branch information
mstegmeyer committed Feb 1, 2025
1 parent 6a415fd commit b4f8e97
Show file tree
Hide file tree
Showing 73 changed files with 908 additions and 3,304 deletions.
5 changes: 0 additions & 5 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,6 @@ parameters:
count: 1
path: src/Checkout/ExpressCheckout/Service/ExpressCustomerService.php

-
message: "#^Mixed variable in a `\\$session\\-\\>getFlashBag\\(\\)\\-\\>\\.\\.\\.\\(\\)` can skip important errors\\. Make sure the type is known$#"
count: 1
path: src/Checkout/Payment/Method/PUIHandler.php

-
message: "#^Usage of ALTER TABLE \\.\\. AFTER is disallowed in migrations to avoid implicit temporary table usage\\.$#"
count: 1
Expand Down
26 changes: 0 additions & 26 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
Expand Up @@ -76,32 +76,6 @@ parameters:
- src/Pos/Schedule/AbstractSyncTaskHandler.php
- src/Reporting/ScheduledTask/TurnoverReportingTaskHandler.php

- # ignore shopware v6.7 payment handlers refactor deprecations
message: '#tag:v6.7.0 -.*PaymentTransactionStruct#'
paths:
- src/Checkout/Card/*Validator.php
- src/Checkout/Card/CardValidatorInterface.php
- src/Checkout/Payment/**/*Handler.php
- src/Checkout/Payment/PayPalPaymentHandler.php
- src/Checkout/Payment/Service/VaultTokenService.php
- src/OrdersApi/Builder/*Builder.php
- src/PaymentsApi/Builder/OrderPaymentBuilderInterface.php
- src/PaymentsApi/Builder/*Builder.php
- src/PaymentsApi/Patch/*.php

- # ignore shopware v6.7 payment handlers refactor deprecations
message: '#.*tag:v6.7.0 - will be removed, (extend AbstractPaymentHandler)|(use `build`) instead#'
paths:
- src/Checkout/Payment/**/*Handler.php
- src/Checkout/Payment/PayPalPaymentHandler.php
- src/Checkout/SalesChannel/CreateOrderRoute.php
- src/Webhook/Handler/VaultPaymentTokenCreated.php

- # ignore shopware v6.7 payment handlers refactor deprecations
message: '#Swag\\PayPal\\Pos\\Payment\\PosPayment#'
paths:
- tests/Pos/Util/InformationDefaultServiceTest.php

- # ignore shopware v6.7 native type deprecations
message: '#.*tag:v6.7.0 - Will be natively typed|Native type for property ".*" is missing#'
paths:
Expand Down
8 changes: 4 additions & 4 deletions src/Checkout/Card/ACDCValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@

namespace Swag\PayPal\Checkout\Card;

use Shopware\Core\Checkout\Payment\Cart\SyncPaymentTransactionStruct;
use Shopware\Core\Checkout\Order\Aggregate\OrderTransaction\OrderTransactionEntity;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\Log\Package;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Swag\PayPal\Checkout\Exception\MissingPayloadException;
use Swag\PayPal\RestApi\V2\Api\Order;

Expand All @@ -21,7 +21,7 @@ class ACDCValidator extends AbstractCardValidator implements CardValidatorInterf
*
* @see https://developer.paypal.com/docs/checkout/advanced/customize/3d-secure/response-parameters/
*/
public function validate(Order $order, SyncPaymentTransactionStruct $transaction, SalesChannelContext $salesChannelContext): bool
public function validate(Order $order, OrderTransactionEntity $transaction, Context $context): bool
{
$card = $order->getPaymentSource()?->getCard();

Expand All @@ -33,6 +33,6 @@ public function validate(Order $order, SyncPaymentTransactionStruct $transaction
return true;
}

return $this->validateAuthenticationResult($card->getAuthenticationResult(), $salesChannelContext);
return $this->validateAuthenticationResult($card->getAuthenticationResult(), $transaction->getOrder()?->getSalesChannelId());
}
}
5 changes: 2 additions & 3 deletions src/Checkout/Card/AbstractCardValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
namespace Swag\PayPal\Checkout\Card;

use Shopware\Core\Framework\Log\Package;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Swag\PayPal\RestApi\V2\Api\Order\PaymentSource\Card\AuthenticationResult;
use Swag\PayPal\Setting\Settings;
Expand All @@ -24,14 +23,14 @@ public function __construct(
) {
}

protected function validateAuthenticationResult(AuthenticationResult $authenticationResult, SalesChannelContext $salesChannelContext): bool
protected function validateAuthenticationResult(AuthenticationResult $authenticationResult, ?string $salesChannelId): bool
{
if ($authenticationResult->getLiabilityShift() === self::LIABILITY_SHIFT_POSSIBLE
|| $authenticationResult->getLiabilityShift() === self::LIABILITY_SHIFT_YES) {
return true;
}

if ($this->systemConfigService->getBool(Settings::ACDC_FORCE_3DS, $salesChannelContext->getSalesChannelId())) {
if ($this->systemConfigService->getBool(Settings::ACDC_FORCE_3DS, $salesChannelId)) {
return false;
}

Expand Down
6 changes: 3 additions & 3 deletions src/Checkout/Card/ApplePayValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@

namespace Swag\PayPal\Checkout\Card;

use Shopware\Core\Checkout\Payment\Cart\SyncPaymentTransactionStruct;
use Shopware\Core\Checkout\Order\Aggregate\OrderTransaction\OrderTransactionEntity;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\Log\Package;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Swag\PayPal\Checkout\Exception\MissingPayloadException;
use Swag\PayPal\RestApi\V2\Api\Order;

#[Package('checkout')]
class ApplePayValidator extends AbstractCardValidator
{
public function validate(Order $order, SyncPaymentTransactionStruct $transaction, SalesChannelContext $salesChannelContext): bool
public function validate(Order $order, OrderTransactionEntity $transaction, Context $context): bool
{
$card = $order->getPaymentSource()?->getApplePay()?->getCard();

Expand Down
6 changes: 3 additions & 3 deletions src/Checkout/Card/CardValidatorInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@

namespace Swag\PayPal\Checkout\Card;

use Shopware\Core\Checkout\Payment\Cart\SyncPaymentTransactionStruct;
use Shopware\Core\Checkout\Order\Aggregate\OrderTransaction\OrderTransactionEntity;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\Log\Package;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Swag\PayPal\RestApi\V2\Api\Order;

#[Package('checkout')]
Expand All @@ -35,5 +35,5 @@ interface CardValidatorInterface
public const AUTHENTICATION_STATUS_INFORMATION_ONLY = 'I';
public const AUTHENTICATION_STATUS_DECOUPLED = 'D';

public function validate(Order $order, SyncPaymentTransactionStruct $transaction, SalesChannelContext $salesChannelContext): bool;
public function validate(Order $order, OrderTransactionEntity $transaction, Context $context): bool;
}
8 changes: 4 additions & 4 deletions src/Checkout/Card/GooglePayValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@

namespace Swag\PayPal\Checkout\Card;

use Shopware\Core\Checkout\Payment\Cart\SyncPaymentTransactionStruct;
use Shopware\Core\Checkout\Order\Aggregate\OrderTransaction\OrderTransactionEntity;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\Log\Package;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Swag\PayPal\Checkout\Exception\MissingPayloadException;
use Swag\PayPal\RestApi\V2\Api\Order;

Expand All @@ -21,7 +21,7 @@ class GooglePayValidator extends AbstractCardValidator implements CardValidatorI
*
* @see https://developer.paypal.com/docs/checkout/advanced/customize/3d-secure/response-parameters/
*/
public function validate(Order $order, SyncPaymentTransactionStruct $transaction, SalesChannelContext $salesChannelContext): bool
public function validate(Order $order, OrderTransactionEntity $transaction, Context $context): bool
{
$card = $order->getPaymentSource()?->getGooglePay()?->getCard();

Expand All @@ -33,6 +33,6 @@ public function validate(Order $order, SyncPaymentTransactionStruct $transaction
return true;
}

return $this->validateAuthenticationResult($card->getAuthenticationResult(), $salesChannelContext);
return $this->validateAuthenticationResult($card->getAuthenticationResult(), $transaction->getOrder()?->getSalesChannelId());
}
}
32 changes: 32 additions & 0 deletions src/Checkout/CheckoutException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php declare(strict_types=1);
/*
* (c) shopware AG <[email protected]>
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Swag\PayPal\Checkout\Exception;

use Shopware\Core\Checkout\Payment\Cart\PaymentHandler\AbstractPaymentHandler;
use Shopware\Core\Checkout\Payment\PaymentException;
use Shopware\Core\Framework\Log\Package;
use Symfony\Component\HttpFoundation\Response;

#[Package('checkout')]

Check failure on line 15 in src/Checkout/CheckoutException.php

View workflow job for this annotation

GitHub Actions / phpstan (trunk)

Class like namespace "Swag\PayPal\Checkout\Exception" does not follow PSR-4 configuration in composer.json
class CheckoutException extends PaymentException
{
public const PREPARED_ORDER_REQUIRED = 'PREPARED_ORDER_REQUIRED';

/**
* @param class-string<AbstractPaymentHandler> $paymentHandler
*/
public static function preparedOrderRequired(string $paymentHandler): self
{
return new self(
Response::HTTP_BAD_REQUEST,
self::PREPARED_ORDER_REQUIRED,
'PayPal Order ID does not exist in the request. The payment method {{ paymentHandler }} requires a prepared PayPal order.',
['paymentHandler' => $paymentHandler],
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Swag\PayPal\Checkout\ExpressCheckout\ExpressCheckoutData;
use Swag\PayPal\Checkout\ExpressCheckout\Service\ExpressCustomerService;
use Swag\PayPal\Checkout\Payment\PayPalPaymentHandler;
use Swag\PayPal\RestApi\V2\Resource\OrderResource;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
Expand All @@ -30,6 +29,7 @@
class ExpressPrepareCheckoutRoute extends AbstractExpressPrepareCheckoutRoute
{
public const PAYPAL_EXPRESS_CHECKOUT_CART_EXTENSION_ID = 'payPalEcsCartData';
public const PAYPAL_REQUEST_PARAMETER_TOKEN = 'token';

/**
* @internal
Expand Down Expand Up @@ -72,10 +72,10 @@ public function prepareCheckout(SalesChannelContext $salesChannelContext, Reques
{
try {
$this->logger->debug('Started', ['request' => $request->request->all()]);
$paypalOrderId = $request->request->get(PayPalPaymentHandler::PAYPAL_REQUEST_PARAMETER_TOKEN);
$paypalOrderId = $request->request->get(self::PAYPAL_REQUEST_PARAMETER_TOKEN);

if (!\is_string($paypalOrderId)) {
throw RoutingException::missingRequestParameter(PayPalPaymentHandler::PAYPAL_REQUEST_PARAMETER_TOKEN);
throw RoutingException::missingRequestParameter(self::PAYPAL_REQUEST_PARAMETER_TOKEN);
}

$paypalOrder = $this->orderResource->get($paypalOrderId, $salesChannelContext->getSalesChannel()->getId());
Expand Down
71 changes: 34 additions & 37 deletions src/Checkout/PUI/Service/PUICustomerDataService.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,68 +7,65 @@

namespace Swag\PayPal\Checkout\PUI\Service;

use Shopware\Core\Checkout\Order\OrderEntity;
use Shopware\Core\Checkout\Payment\Cart\PaymentTransactionStruct;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\Log\Package;
use Shopware\Core\Framework\Validation\DataBag\DataBag;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Symfony\Component\HttpFoundation\ParameterBag;
use Symfony\Component\HttpFoundation\Request;

#[Package('checkout')]
class PUICustomerDataService
{
public const PUI_CUSTOMER_DATA_BIRTHDAY = 'payPalPuiCustomerBirthday';
public const PUI_CUSTOMER_DATA_PHONE_NUMBER = 'payPalPuiCustomerPhoneNumber';

private EntityRepository $orderAddressRepository;

private EntityRepository $customerRepository;

/**
* @internal
*/
public function __construct(
EntityRepository $orderAddressRepository,
EntityRepository $customerRepository,
private readonly EntityRepository $orderAddressRepository,
private readonly EntityRepository $customerRepository,
) {
$this->orderAddressRepository = $orderAddressRepository;
$this->customerRepository = $customerRepository;
}

public function checkForCustomerData(OrderEntity $order, DataBag $dataBag, SalesChannelContext $salesChannelContext): void
public function checkForCustomerData(PaymentTransactionStruct $transaction, Request $request, Context $context): void
{
$birthday = $this->getBirthday($dataBag);
$phoneNumber = $dataBag->get(self::PUI_CUSTOMER_DATA_PHONE_NUMBER);
$customer = $salesChannelContext->getCustomer();

if ($birthday && $customer !== null) {
$this->customerRepository->update([[
'id' => $customer->getId(),
'birthday' => $birthday,
]], $salesChannelContext->getContext());

$customer->setBirthday($birthday);
$birthday = $this->getBirthday($request);
$phoneNumber = $request->request->get(self::PUI_CUSTOMER_DATA_PHONE_NUMBER);

if ($birthday) {
$customerCriteria = new Criteria();
$customerCriteria->addFilter(new EqualsFilter('orderCustomers.order.transactions.id', $transaction->getOrderTransactionId()));
$customerId = $this->customerRepository->searchIds($customerCriteria, $context)->firstId();

if ($customerId !== null) {
$this->customerRepository->update([[
'id' => $customerId,
'birthday' => $birthday,
]], $context);
}
}

if ($phoneNumber) {
$this->orderAddressRepository->update([[
'id' => $order->getBillingAddressId(),
'phoneNumber' => $phoneNumber,
]], $salesChannelContext->getContext());

$billingAddress = $order->getBillingAddress();
if ($billingAddress !== null) {
$billingAddress->setPhoneNumber($phoneNumber);
$addressCriteria = new Criteria();
$addressCriteria->addFilter(new EqualsFilter('order.transactions.id', $transaction->getOrderTransactionId()));
$billingAddressId = $this->orderAddressRepository->searchIds($addressCriteria, $context)->firstId();

if ($billingAddressId !== null) {
$this->orderAddressRepository->update([[
'id' => $billingAddressId,
'phoneNumber' => $phoneNumber,
]], $context);
}
}
}

private function getBirthday(DataBag $dataBag): ?\DateTimeInterface
private function getBirthday(Request $request): ?\DateTimeInterface
{
$birthdayArray = $dataBag->get(self::PUI_CUSTOMER_DATA_BIRTHDAY);

if (!($birthdayArray instanceof DataBag)) {
return null;
}
$birthdayArray = new ParameterBag($request->request->all(self::PUI_CUSTOMER_DATA_BIRTHDAY));

$birthdayDay = $birthdayArray->getDigits('day');
$birthdayMonth = $birthdayArray->getDigits('month');
Expand Down
Loading

0 comments on commit b4f8e97

Please sign in to comment.