{% sw_include '@PayonePayment/storefront/component/checkout/paypal-button.html.twig' %}
{% endblock %}
{% endif %}
+
+ {% if constant('PayonePayment\\PaymentMethod\\PayonePaypalV2Express::UUID') in activePayonePaymentMethodIds %}
+ {% block utilities_offcanvas_payone_paypal_v2_express_button %}
+
+ {% sw_include '@PayonePayment/storefront/component/checkout/paypal-v2-button.html.twig' %}
+
+ {% endblock %}
+ {% endif %}
{% endif %}
{% if page.extensions.payoneAmazonPayExpressButton %}
diff --git a/src/Resources/views/storefront/component/checkout/paypal-v2-button.html.twig b/src/Resources/views/storefront/component/checkout/paypal-v2-button.html.twig
new file mode 100644
index 000000000..0f5ba939f
--- /dev/null
+++ b/src/Resources/views/storefront/component/checkout/paypal-v2-button.html.twig
@@ -0,0 +1,13 @@
+{% block component_payone_paypal_v2_button %}
+ {# @var \PayonePayment\Storefront\Struct\PayPalV2ExpressButtonData paypalButtonOptions #}
+ {% set paypalButtonOptions = page.extensions[constant('PayonePayment\\Storefront\\Struct\\PayPalV2ExpressButtonData::EXTENSION_NAME')] %}
+
+ {% block component_payone_paypal_v2_button_container %}
+ {% if paypalButtonOptions %}
+
@@ -13,5 +13,15 @@
{% endblock %}
{% endif %}
+
+ {% if constant('PayonePayment\\PaymentMethod\\PayonePaypalV2Express::UUID') in activePayonePaymentMethodIds %}
+ {% block page_checkout_address_payone_paypal_v2_express_button %}
+
+
+ {% sw_include '@PayonePayment/storefront/component/checkout/paypal-v2-button.html.twig' %}
+
+
+ {% endblock %}
+ {% endif %}
{% endif %}
{% endblock %}
diff --git a/src/Resources/views/storefront/page/checkout/cart/index.html.twig b/src/Resources/views/storefront/page/checkout/cart/index.html.twig
index 7b064c75b..31d90ee30 100644
--- a/src/Resources/views/storefront/page/checkout/cart/index.html.twig
+++ b/src/Resources/views/storefront/page/checkout/cart/index.html.twig
@@ -4,7 +4,7 @@
{{ parent() }}
{% if not context.customer %}
- {% if constant('PayonePayment\\PaymentMethod\\PayonePaypalExpress::UUID') in activePaymentPaymentMethods %}
+ {% if constant('PayonePayment\\PaymentMethod\\PayonePaypalExpress::UUID') in activePayonePaymentMethodIds %}
{% block page_checkout_payone_paypal_express_button %}
{% endblock %}
{% endif %}
+
+ {% if constant('PayonePayment\\PaymentMethod\\PayonePaypalV2Express::UUID') in activePayonePaymentMethodIds %}
+ {% block page_checkout_payone_paypal_v2_express_button %}
+
+ {% sw_include '@PayonePayment/storefront/component/checkout/paypal-v2-button.html.twig' %}
+
+ {% endblock %}
+ {% endif %}
{% endif %}
{% block page_checkout_payone_amazonpay_express_button %}
diff --git a/src/Storefront/Controller/GenericExpressController.php b/src/Storefront/Controller/GenericExpressController.php
index e59334d06..a96a0d0bb 100644
--- a/src/Storefront/Controller/GenericExpressController.php
+++ b/src/Storefront/Controller/GenericExpressController.php
@@ -22,6 +22,7 @@
use Shopware\Core\System\SalesChannel\SalesChannel\SalesChannelContextSwitcher;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Storefront\Controller\StorefrontController;
+use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
@@ -46,6 +47,51 @@ public function __construct(
) {
}
+ #[Route(
+ path: '/payone/express-checkout/create-session/{paymentMethodId}',
+ name: 'frontend.account.payone.express-checkout.generic.create-session',
+ options: ['seo' => false],
+ defaults: ['XmlHttpRequest' => true],
+ methods: ['GET']
+ )]
+ public function createSessionAction(SalesChannelContext $context, string $paymentMethodId): Response
+ {
+ if (!\array_key_exists($paymentMethodId, PaymentHandlerGroups::GENERIC_EXPRESS)) {
+ throw $this->createNotFoundException();
+ }
+
+ $cart = $this->cartService->getCart($context->getToken(), $context);
+
+ $salesChannelDataBag = new DataBag([
+ SalesChannelContextService::PAYMENT_METHOD_ID => $paymentMethodId,
+ ]);
+
+ $this->salesChannelContextSwitcher->update($salesChannelDataBag, $context);
+
+ $setRequest = $this->requestParameterFactory->getRequestParameter(
+ new CreateExpressCheckoutSessionStruct(
+ $context,
+ PaymentHandlerGroups::GENERIC_EXPRESS[$paymentMethodId]
+ )
+ );
+
+ try {
+ $response = $this->client->request($setRequest);
+ } catch (PayoneRequestException) {
+ throw new RuntimeException($this->trans('PayonePayment.errorMessages.genericError'));
+ }
+
+ if (!isset($response['addpaydata']['orderId'])) {
+ throw new RuntimeException('generic express checkout: No orderId has been given for payment method id ' . $paymentMethodId);
+ }
+
+ $this->cartExtensionService->addCartExtensionForExpressCheckout($cart, $context, $paymentMethodId, $response['workorderid']);
+
+ return new JsonResponse([
+ 'orderId' => $response['addpaydata']['orderId'],
+ ]);
+ }
+
#[Route(
path: '/payone/express-checkout/redirect/{paymentMethodId}',
name: 'frontend.account.payone.express-checkout.generic.redirect',
diff --git a/src/Storefront/Struct/PayPalV2ExpressButtonData.php b/src/Storefront/Struct/PayPalV2ExpressButtonData.php
new file mode 100644
index 000000000..71c4313a3
--- /dev/null
+++ b/src/Storefront/Struct/PayPalV2ExpressButtonData.php
@@ -0,0 +1,82 @@
+sandbox;
+ }
+
+ public function getClientId(): string
+ {
+ return $this->clientId;
+ }
+
+ public function getMerchantId(): string
+ {
+ return $this->merchantId;
+ }
+
+ public function getCurrency(): string
+ {
+ return $this->currency;
+ }
+
+ public function getLocale(): string
+ {
+ return $this->locale;
+ }
+
+ public function isShowPayLaterButton(): bool
+ {
+ return $this->showPayLaterButton;
+ }
+
+ public function getCreateCheckoutSessionUrl(): string
+ {
+ return $this->createCheckoutSessionUrl;
+ }
+
+ public function getOnApproveRedirectUrl(): string
+ {
+ return $this->onApproveRedirectUrl;
+ }
+
+ public function getOnCancelRedirectUrl(): string
+ {
+ return $this->onCancelRedirectUrl;
+ }
+
+ public function getOnErrorRedirectUrl(): string
+ {
+ return $this->onErrorRedirectUrl;
+ }
+}
diff --git a/tests/Components/GenericExpressCheckout/CustomerRegistrationUtilTest.php b/tests/Components/GenericExpressCheckout/CustomerRegistrationUtilTest.php
index d6e77bff6..2451cefcc 100644
--- a/tests/Components/GenericExpressCheckout/CustomerRegistrationUtilTest.php
+++ b/tests/Components/GenericExpressCheckout/CustomerRegistrationUtilTest.php
@@ -17,7 +17,7 @@ class CustomerRegistrationUtilTest extends TestCase
{
use PayoneTestBehavior;
- public function testIfAllRequiredKeysArePresentAndHaveValidValues(): void
+ public function testItReturnsCorrectDataWhenBillingDataIsMissingInResponse(): void
{
/** @var CustomerRegistrationUtil $util */
$util = $this->getContainer()->get(CustomerRegistrationUtil::class);
@@ -34,7 +34,7 @@ public function testIfAllRequiredKeysArePresentAndHaveValidValues(): void
'shipping_city' => 'Berlin',
'shipping_state' => 'Ohio',
'shipping_country' => 'DE',
- 'telephonenumber' => '0123456789',
+ 'shipping_telephonenumber' => '0123456789',
],
], Context::createDefaultContext())->all();
@@ -48,6 +48,7 @@ public function testIfAllRequiredKeysArePresentAndHaveValidValues(): void
static::assertEquals('Mustermann', $data['lastName']);
static::assertArrayHasKey('acceptedDataProtection', $data);
static::assertTrue($data['acceptedDataProtection'], '`acceptedDataProtection` should be always `true`.');
+ static::assertArrayNotHasKey('shippingAddress', $data, 'shipping address should not be present, because it would be the same as billing address');
static::assertArrayHasKey('billingAddress', $data); // values of it will be tested in other tests
static::assertArrayHasKey('salutationId', $data['billingAddress']);
static::assertArrayHasKey('firstName', $data['billingAddress']);
@@ -60,7 +61,11 @@ public function testIfAllRequiredKeysArePresentAndHaveValidValues(): void
static::assertArrayHasKey('phone', $data['billingAddress']);
}
- public function testWithOnlyShippingAddress(): void
+ /**
+ * @dataProvider billingAddressDataProvider
+ * @testdox It returns correct data when shipping data is missing in response and billing data is available with prefix "$billingPrefix"
+ */
+ public function testItReturnsCorrectDataWhenShippingDataIsMissingInResponse(string $billingPrefix): void
{
/** @var CustomerRegistrationUtil $util */
$util = $this->getContainer()->get(CustomerRegistrationUtil::class);
@@ -68,16 +73,16 @@ public function testWithOnlyShippingAddress(): void
$data = $util->getCustomerDataBagFromGetCheckoutSessionResponse([
'addpaydata' => [
'email' => 'test@localhost.local',
- 'telephonenumber' => '0123456789',
- 'shipping_firstname' => 'Max',
- 'shipping_lastname' => 'Mustermann',
- 'shipping_company' => 'my-company',
- 'shipping_street' => 'pay-street 123',
- 'shipping_addressaddition' => 'c/o Petra',
- 'shipping_zip' => '65432',
- 'shipping_city' => 'Berlin',
- 'shipping_state' => 'Ohio',
- 'shipping_country' => 'DE',
+ $billingPrefix . 'telephonenumber' => '0123456789',
+ $billingPrefix . 'firstname' => 'Max',
+ $billingPrefix . 'lastname' => 'Mustermann',
+ $billingPrefix . 'company' => 'my-company',
+ $billingPrefix . 'street' => 'pay-street 123',
+ $billingPrefix . 'addressaddition' => 'c/o Petra',
+ $billingPrefix . 'zip' => '65432',
+ $billingPrefix . 'city' => 'Berlin',
+ $billingPrefix . 'state' => 'Ohio',
+ $billingPrefix . 'country' => 'DE',
],
], Context::createDefaultContext())->all();
@@ -95,7 +100,11 @@ public function testWithOnlyShippingAddress(): void
static::assertEquals('0123456789', $data['billingAddress']['phone']);
}
- public function testWithNoSpecificAddress(): void
+ /**
+ * @dataProvider billingAddressDataProvider
+ * @testdox It returns correct data when different shipping and billing (with prefix "$billingPrefix") are available in response
+ */
+ public function testItReturnsCorrectDataWhenDifferentShippingAndBillingAreAvailableInResponse(string $billingPrefix): void
{
/** @var CustomerRegistrationUtil $util */
$util = $this->getContainer()->get(CustomerRegistrationUtil::class);
@@ -103,21 +112,33 @@ public function testWithNoSpecificAddress(): void
$data = $util->getCustomerDataBagFromGetCheckoutSessionResponse([
'addpaydata' => [
'email' => 'test@localhost.local',
- 'telephonenumber' => '0123456789',
- 'firstname' => 'Max',
- 'lastname' => 'Mustermann',
- 'company' => 'my-company',
- 'street' => 'pay-street 123',
- 'addressaddition' => 'c/o Petra',
- 'zip' => '65432',
- 'city' => 'Berlin',
- 'state' => 'Ohio',
- 'country' => 'DE',
+
+ $billingPrefix . 'telephonenumber' => '0123456789',
+ $billingPrefix . 'firstname' => 'Max',
+ $billingPrefix . 'lastname' => 'Mustermann',
+ $billingPrefix . 'company' => 'my-company',
+ $billingPrefix . 'street' => 'pay-street 123',
+ $billingPrefix . 'addressaddition' => 'c/o Petra',
+ $billingPrefix . 'zip' => '65432',
+ $billingPrefix . 'city' => 'Berlin',
+ $billingPrefix . 'state' => 'Ohio',
+ $billingPrefix . 'country' => 'DE',
+
+ 'shipping_telephonenumber' => '0123456789',
+ 'shipping_firstname' => 'Petra',
+ 'shipping_lastname' => 'Musterfrau',
+ 'shipping_company' => 'your-company',
+ 'shipping_street' => 'refund-street 123',
+ 'shipping_addressaddition' => 'c/o Max',
+ 'shipping_zip' => '98765',
+ 'shipping_city' => 'Köln',
+ 'shipping_state' => 'New York',
+ 'shipping_country' => 'AT',
],
], Context::createDefaultContext())->all();
static::assertArrayHasKey('billingAddress', $data);
- static::assertArrayNotHasKey('shippingAddress', $data, 'shipping address should not be present, because it would be the same as billing address');
+ static::assertArrayHasKey('shippingAddress', $data);
static::assertEquals('Max', $data['billingAddress']['firstName']);
static::assertEquals('Mustermann', $data['billingAddress']['lastName']);
static::assertEquals('my-company', $data['billingAddress']['company']);
@@ -125,15 +146,25 @@ public function testWithNoSpecificAddress(): void
static::assertEquals('c/o Petra', $data['billingAddress']['additionalAddressLine1']);
static::assertEquals('65432', $data['billingAddress']['zipcode']);
static::assertEquals('Berlin', $data['billingAddress']['city']);
-
static::assertTrue(Uuid::isValid($data['billingAddress']['countryId']), $data['billingAddress']['countryId'] . ' should be a valid UUID');
static::assertEquals('0123456789', $data['billingAddress']['phone']);
+
+ static::assertEquals('Petra', $data['shippingAddress']['firstName']);
+ static::assertEquals('Musterfrau', $data['shippingAddress']['lastName']);
+ static::assertEquals('your-company', $data['shippingAddress']['company']);
+ static::assertEquals('refund-street 123', $data['shippingAddress']['street']);
+ static::assertEquals('c/o Max', $data['shippingAddress']['additionalAddressLine1']);
+ static::assertEquals('98765', $data['shippingAddress']['zipcode']);
+ static::assertEquals('Köln', $data['shippingAddress']['city']);
+ static::assertTrue(Uuid::isValid($data['shippingAddress']['countryId']), $data['shippingAddress']['countryId'] . ' should be a valid UUID');
+ static::assertEquals('0123456789', $data['shippingAddress']['phone']);
}
/**
* @dataProvider billingAddressDataProvider
+ * @testdox It returns correct data when same shipping and billing (with prefix "$billingPrefix") are available in response
*/
- public function testWithBillingAddress(string $billingPrefix): void
+ public function testItReturnsCorrectDataWhenSameShippingAndBillingAreAvailableInResponse(string $billingPrefix): void
{
/** @var CustomerRegistrationUtil $util */
$util = $this->getContainer()->get(CustomerRegistrationUtil::class);
@@ -141,7 +172,8 @@ public function testWithBillingAddress(string $billingPrefix): void
$data = $util->getCustomerDataBagFromGetCheckoutSessionResponse([
'addpaydata' => [
'email' => 'test@localhost.local',
- 'telephonenumber' => '0123456789',
+
+ $billingPrefix . 'telephonenumber' => '0123456789',
$billingPrefix . 'firstname' => 'Max',
$billingPrefix . 'lastname' => 'Mustermann',
$billingPrefix . 'company' => 'my-company',
@@ -151,6 +183,17 @@ public function testWithBillingAddress(string $billingPrefix): void
$billingPrefix . 'city' => 'Berlin',
$billingPrefix . 'state' => 'Ohio',
$billingPrefix . 'country' => 'DE',
+
+ 'shipping_telephonenumber' => '0123456789',
+ 'shipping_firstname' => 'Max',
+ 'shipping_lastname' => 'Mustermann',
+ 'shipping_company' => 'my-company',
+ 'shipping_street' => 'pay-street 123',
+ 'shipping_addressaddition' => 'c/o Petra',
+ 'shipping_zip' => '65432',
+ 'shipping_city' => 'Berlin',
+ 'shipping_state' => 'Ohio',
+ 'shipping_country' => 'DE',
],
], Context::createDefaultContext())->all();
@@ -163,15 +206,15 @@ public function testWithBillingAddress(string $billingPrefix): void
static::assertEquals('c/o Petra', $data['billingAddress']['additionalAddressLine1']);
static::assertEquals('65432', $data['billingAddress']['zipcode']);
static::assertEquals('Berlin', $data['billingAddress']['city']);
-
static::assertTrue(Uuid::isValid($data['billingAddress']['countryId']), $data['billingAddress']['countryId'] . ' should be a valid UUID');
static::assertEquals('0123456789', $data['billingAddress']['phone']);
}
/**
* @dataProvider billingAddressDataProvider
+ * @testdox It returns correct data when billing company (with prefix "$billingPrefix") is available in response
*/
- public function testWithBillingAndShippingAddress(string $billingPrefix): void
+ public function testItReturnsCorrectDataWhenBillingCompanyIsAvailableInResponse(string $billingPrefix): void
{
/** @var CustomerRegistrationUtil $util */
$util = $this->getContainer()->get(CustomerRegistrationUtil::class);
@@ -179,8 +222,8 @@ public function testWithBillingAndShippingAddress(string $billingPrefix): void
$data = $util->getCustomerDataBagFromGetCheckoutSessionResponse([
'addpaydata' => [
'email' => 'test@localhost.local',
- 'telephonenumber' => '0123456789',
+ $billingPrefix . 'telephonenumber' => '0123456789',
$billingPrefix . 'firstname' => 'Max',
$billingPrefix . 'lastname' => 'Mustermann',
$billingPrefix . 'company' => 'my-company',
@@ -190,46 +233,19 @@ public function testWithBillingAndShippingAddress(string $billingPrefix): void
$billingPrefix . 'city' => 'Berlin',
$billingPrefix . 'state' => 'Ohio',
$billingPrefix . 'country' => 'DE',
-
- 'shipping_firstname' => 'Petra',
- 'shipping_lastname' => 'Musterfrau',
- 'shipping_company' => 'your-company',
- 'shipping_street' => 'refund-street 123',
- 'shipping_addressaddition' => 'c/o Max',
- 'shipping_zip' => '98765',
- 'shipping_city' => 'Köln',
- 'shipping_state' => 'New York',
- 'shipping_country' => 'AT',
],
], Context::createDefaultContext())->all();
static::assertArrayHasKey('billingAddress', $data);
- static::assertArrayHasKey('shippingAddress', $data);
- static::assertEquals('Max', $data['billingAddress']['firstName']);
- static::assertEquals('Mustermann', $data['billingAddress']['lastName']);
static::assertEquals('my-company', $data['billingAddress']['company']);
- static::assertEquals('pay-street 123', $data['billingAddress']['street']);
- static::assertEquals('c/o Petra', $data['billingAddress']['additionalAddressLine1']);
- static::assertEquals('65432', $data['billingAddress']['zipcode']);
- static::assertEquals('Berlin', $data['billingAddress']['city']);
- static::assertTrue(Uuid::isValid($data['billingAddress']['countryId']), $data['billingAddress']['countryId'] . ' should be a valid UUID');
- static::assertEquals('0123456789', $data['billingAddress']['phone']);
-
- static::assertEquals('Petra', $data['shippingAddress']['firstName']);
- static::assertEquals('Musterfrau', $data['shippingAddress']['lastName']);
- static::assertEquals('your-company', $data['shippingAddress']['company']);
- static::assertEquals('refund-street 123', $data['shippingAddress']['street']);
- static::assertEquals('c/o Max', $data['shippingAddress']['additionalAddressLine1']);
- static::assertEquals('98765', $data['shippingAddress']['zipcode']);
- static::assertEquals('Köln', $data['shippingAddress']['city']);
- static::assertTrue(Uuid::isValid($data['shippingAddress']['countryId']), $data['shippingAddress']['countryId'] . ' should be a valid UUID');
- static::assertEquals('0123456789', $data['shippingAddress']['phone']);
+ static::assertEquals(CustomerEntity::ACCOUNT_TYPE_BUSINESS, $data['accountType']);
}
/**
* @dataProvider billingAddressDataProvider
+ * @testdox It returns correct data when no billing company (with prefix "$billingPrefix") is available in response
*/
- public function testWithBillingCompany(string $billingPrefix): void
+ public function testItReturnsCorrectDataWhenNoBillingCompanyIsAvailableInResponse(string $billingPrefix): void
{
/** @var CustomerRegistrationUtil $util */
$util = $this->getContainer()->get(CustomerRegistrationUtil::class);
@@ -237,11 +253,10 @@ public function testWithBillingCompany(string $billingPrefix): void
$data = $util->getCustomerDataBagFromGetCheckoutSessionResponse([
'addpaydata' => [
'email' => 'test@localhost.local',
- 'telephonenumber' => '0123456789',
+ $billingPrefix . 'telephonenumber' => '0123456789',
$billingPrefix . 'firstname' => 'Max',
$billingPrefix . 'lastname' => 'Mustermann',
- $billingPrefix . 'company' => 'my-company',
$billingPrefix . 'street' => 'pay-street 123',
$billingPrefix . 'addressaddition' => 'c/o Petra',
$billingPrefix . 'zip' => '65432',
@@ -252,43 +267,96 @@ public function testWithBillingCompany(string $billingPrefix): void
], Context::createDefaultContext())->all();
static::assertArrayHasKey('billingAddress', $data);
- static::assertEquals('my-company', $data['billingAddress']['company']);
- static::assertEquals(CustomerEntity::ACCOUNT_TYPE_BUSINESS, $data['accountType']);
+ static::assertNull($data['billingAddress']['company'] ?? null);
+ static::assertEquals(CustomerEntity::ACCOUNT_TYPE_PRIVATE, $data['accountType']);
+ }
+
+ public function testItReturnsCorrectNameDataForPayPalV1(): void
+ {
+ /** @var CustomerRegistrationUtil $util */
+ $util = $this->getContainer()->get(CustomerRegistrationUtil::class);
+
+ $data = $util->getCustomerDataBagFromGetCheckoutSessionResponse([
+ 'addpaydata' => [
+ 'email' => 'test@localhost.local',
+
+ 'telephonenumber' => '0123456789',
+ 'lastname' => 'Petra Musterfrau',
+ 'street' => 'pay-street 123',
+ 'addressaddition' => 'c/o Petra',
+ 'zip' => '65432',
+ 'city' => 'Berlin',
+ 'state' => 'Ohio',
+ 'country' => 'DE',
+
+ 'shipping_telephonenumber' => '0123456789',
+ 'shipping_firstname' => 'Petra',
+ 'shipping_lastname' => 'Musterfrau',
+ 'shipping_company' => 'your-company',
+ 'shipping_street' => 'refund-street 123',
+ 'shipping_addressaddition' => 'c/o Max',
+ 'shipping_zip' => '98765',
+ 'shipping_city' => 'Köln',
+ 'shipping_state' => 'New York',
+ 'shipping_country' => 'AT',
+ ],
+ ], Context::createDefaultContext())->all();
+
+ static::assertArrayHasKey('billingAddress', $data);
+ static::assertArrayHasKey('firstName', $data);
+ static::assertArrayHasKey('lastName', $data);
+ static::assertEquals('Petra', $data['firstName']);
+ static::assertEquals('Musterfrau', $data['lastName']);
+
+ static::assertArrayHasKey('firstName', $data['billingAddress']);
+ static::assertArrayHasKey('lastName', $data['billingAddress']);
+ static::assertEquals('Petra', $data['billingAddress']['firstName']);
+ static::assertEquals('Musterfrau', $data['billingAddress']['lastName']);
}
/**
* @dataProvider billingAddressDataProvider
+ * @testdox It throws exception if billing (with prefix "$billingPrefix") and shipping address are incomplete
*/
- public function testWithoutBillingCompany(string $billingPrefix): void
+ public function testItThrowsExceptionIfBillingAndShippingAddressAreIncomplete(string $billingPrefix): void
{
/** @var CustomerRegistrationUtil $util */
$util = $this->getContainer()->get(CustomerRegistrationUtil::class);
- $data = $util->getCustomerDataBagFromGetCheckoutSessionResponse([
+ $this->expectException(\RuntimeException::class);
+
+ $util->getCustomerDataBagFromGetCheckoutSessionResponse([
'addpaydata' => [
'email' => 'test@localhost.local',
- 'telephonenumber' => '0123456789',
+ // Street and city missing
+ $billingPrefix . 'telephonenumber' => '0123456789',
$billingPrefix . 'firstname' => 'Max',
$billingPrefix . 'lastname' => 'Mustermann',
- $billingPrefix . 'street' => 'pay-street 123',
+ $billingPrefix . 'company' => 'my-company',
$billingPrefix . 'addressaddition' => 'c/o Petra',
$billingPrefix . 'zip' => '65432',
- $billingPrefix . 'city' => 'Berlin',
$billingPrefix . 'state' => 'Ohio',
$billingPrefix . 'country' => 'DE',
+
+ // Firstname and lastname missing
+ 'shipping_telephonenumber' => '0123456789',
+ 'shipping_company' => 'my-company',
+ 'shipping_street' => 'pay-street 123',
+ 'shipping_addressaddition' => 'c/o Petra',
+ 'shipping_zip' => '65432',
+ 'shipping_city' => 'Berlin',
+ 'shipping_state' => 'Ohio',
+ 'shipping_country' => 'DE',
],
], Context::createDefaultContext())->all();
-
- static::assertArrayHasKey('billingAddress', $data);
- static::assertNull($data['billingAddress']['company'] ?? null);
- static::assertEquals(CustomerEntity::ACCOUNT_TYPE_PRIVATE, $data['accountType']);
}
/**
* @dataProvider billingAddressDataProvider
+ * @testdox It takes complete shipping address as billing address if billing address (with prefix "$billingPrefix") is incomplete
*/
- public function testWithShippingCompany(string $billingPrefix): void
+ public function testItTakesCompleteShippingAddressAsBillingAddressIfBillingAddressIsIncomplete(string $billingPrefix): void
{
/** @var CustomerRegistrationUtil $util */
$util = $this->getContainer()->get(CustomerRegistrationUtil::class);
@@ -296,17 +364,19 @@ public function testWithShippingCompany(string $billingPrefix): void
$data = $util->getCustomerDataBagFromGetCheckoutSessionResponse([
'addpaydata' => [
'email' => 'test@localhost.local',
- 'telephonenumber' => '0123456789',
+ // Street and city missing
+ $billingPrefix . 'telephonenumber' => '0123456789',
$billingPrefix . 'firstname' => 'Max',
$billingPrefix . 'lastname' => 'Mustermann',
- $billingPrefix . 'street' => 'pay-street 123',
+ $billingPrefix . 'company' => 'my-company',
$billingPrefix . 'addressaddition' => 'c/o Petra',
$billingPrefix . 'zip' => '65432',
- $billingPrefix . 'city' => 'Berlin',
$billingPrefix . 'state' => 'Ohio',
$billingPrefix . 'country' => 'DE',
+ // Complete
+ 'shipping_telephonenumber' => '0123456789',
'shipping_firstname' => 'Petra',
'shipping_lastname' => 'Musterfrau',
'shipping_company' => 'your-company',
@@ -320,14 +390,19 @@ public function testWithShippingCompany(string $billingPrefix): void
], Context::createDefaultContext())->all();
static::assertArrayHasKey('billingAddress', $data);
- static::assertNull($data['billingAddress']['company'] ?? null, 'billing-company should be null and the the fallback to the shipping-company should not used.');
- static::assertEquals(CustomerEntity::ACCOUNT_TYPE_PRIVATE, $data['accountType']);
-
- static::assertArrayHasKey('shippingAddress', $data);
- static::assertEquals('your-company', $data['shippingAddress']['company']);
+ static::assertArrayNotHasKey('shippingAddress', $data, 'shipping address should not be present, because it would be the same as billing address');
+ static::assertEquals('Petra', $data['billingAddress']['firstName']);
+ static::assertEquals('Musterfrau', $data['billingAddress']['lastName']);
+ static::assertEquals('your-company', $data['billingAddress']['company']);
+ static::assertEquals('refund-street 123', $data['billingAddress']['street']);
+ static::assertEquals('c/o Max', $data['billingAddress']['additionalAddressLine1']);
+ static::assertEquals('98765', $data['billingAddress']['zipcode']);
+ static::assertEquals('Köln', $data['billingAddress']['city']);
+ static::assertTrue(Uuid::isValid($data['billingAddress']['countryId']), $data['billingAddress']['countryId'] . ' should be a valid UUID');
+ static::assertEquals('0123456789', $data['billingAddress']['phone']);
}
- public function testIfPayPalFirstnameGotCorrectlyExtracted(): void
+ public function testItRemovesShippingAddressIfShippingAddressIsIncomplete(): void
{
/** @var CustomerRegistrationUtil $util */
$util = $this->getContainer()->get(CustomerRegistrationUtil::class);
@@ -335,9 +410,11 @@ public function testIfPayPalFirstnameGotCorrectlyExtracted(): void
$data = $util->getCustomerDataBagFromGetCheckoutSessionResponse([
'addpaydata' => [
'email' => 'test@localhost.local',
- 'telephonenumber' => '0123456789',
- 'lastname' => 'Petra Musterfrau',
+ // Complete
+ 'telephonenumber' => '0123456789',
+ 'firstname' => 'Petra',
+ 'lastname' => 'Musterfrau',
'street' => 'pay-street 123',
'addressaddition' => 'c/o Petra',
'zip' => '65432',
@@ -345,8 +422,8 @@ public function testIfPayPalFirstnameGotCorrectlyExtracted(): void
'state' => 'Ohio',
'country' => 'DE',
- 'shipping_firstname' => 'Petra',
- 'shipping_lastname' => 'Musterfrau',
+ // Firstname and lastname missing
+ 'shipping_telephonenumber' => '0123456789',
'shipping_company' => 'your-company',
'shipping_street' => 'refund-street 123',
'shipping_addressaddition' => 'c/o Max',
@@ -358,15 +435,7 @@ public function testIfPayPalFirstnameGotCorrectlyExtracted(): void
], Context::createDefaultContext())->all();
static::assertArrayHasKey('billingAddress', $data);
- static::assertArrayHasKey('firstName', $data);
- static::assertArrayHasKey('lastName', $data);
- static::assertEquals('Petra', $data['firstName']);
- static::assertEquals('Musterfrau', $data['lastName']);
-
- static::assertArrayHasKey('firstName', $data['billingAddress']);
- static::assertArrayHasKey('lastName', $data['billingAddress']);
- static::assertEquals('Petra', $data['billingAddress']['firstName']);
- static::assertEquals('Musterfrau', $data['billingAddress']['lastName']);
+ static::assertArrayNotHasKey('shippingAddress', $data, 'shipping address should not be present, because it was incomplete');
}
protected static function billingAddressDataProvider(): array
diff --git a/tests/Components/Helper/ActivePaymentMethodsLoaderTest.php b/tests/Components/Helper/ActivePaymentMethodsLoaderTest.php
new file mode 100644
index 000000000..bfa25ab7b
--- /dev/null
+++ b/tests/Components/Helper/ActivePaymentMethodsLoaderTest.php
@@ -0,0 +1,196 @@
+createSalesChannelContextWithLoggedInCustomerAndWithNavigation();
+
+ $cacheItem = $this->createMock(CacheItemInterface::class);
+ $cacheItem->expects(static::exactly(2))->method('get')->willReturnOnConsecutiveCalls(null, $activePaymentMethodIds);
+ $cacheItem->expects(static::once())->method('set')->with(static::equalTo($activePaymentMethodIds));
+
+ $cachePool = $this->createMock(CacheItemPoolInterface::class);
+ $cachePool
+ ->expects(static::once())
+ ->method('getItem')
+ ->with(
+ static::equalTo('payone_payment.active_payment_methods.' . $salesChannelContext->getSalesChannelId())
+ )
+ ->willReturn($cacheItem)
+ ;
+ $cachePool
+ ->expects(static::once())
+ ->method('save')
+ ->with(
+ static::equalTo($cacheItem)
+ )
+ ;
+
+ $idSearchResult = $this->createMock(IdSearchResult::class);
+ $idSearchResult
+ ->expects(static::once())
+ ->method('getIds')
+ ->willReturn($activePaymentMethodIds)
+ ;
+
+ $paymentMethodRepository = $this->createMock(SalesChannelRepository::class);
+ $paymentMethodRepository
+ ->expects(static::once())
+ ->method('searchIds')
+ ->with(
+ static::callback(static function (Criteria $criteria) {
+ $hasHandlerIdentifierFilter = false;
+ $hasActiveFilter = false;
+
+ foreach ($criteria->getFilters() as $filter) {
+ if ($filter instanceof ContainsFilter && $filter->getField() === 'handlerIdentifier' && $filter->getValue() === 'PayonePayment') {
+ $hasHandlerIdentifierFilter = true;
+ }
+ if ($filter instanceof EqualsFilter && $filter->getField() === 'active' && $filter->getValue() === true) {
+ $hasActiveFilter = true;
+ }
+ }
+
+ static::assertTrue($hasHandlerIdentifierFilter);
+ static::assertTrue($hasActiveFilter);
+
+ return true;
+ }),
+ static::isInstanceOf(SalesChannelContext::class)
+ )
+ ->willReturn($idSearchResult)
+ ;
+
+ $salesChannelRepository = $this->createMock(EntityRepository::class);
+
+ $activePaymentMethodsLoader = new ActivePaymentMethodsLoader(
+ $cachePool,
+ $paymentMethodRepository,
+ $salesChannelRepository
+ );
+
+ $result = $activePaymentMethodsLoader->getActivePaymentMethodIds($salesChannelContext);
+
+ static::assertSame($activePaymentMethodIds, $result);
+ }
+
+ public function testItReturnsCorrectPaymentMethodIdsWithExistingCacheItem(): void
+ {
+ $activePaymentMethodIds = [
+ Uuid::randomHex(),
+ Uuid::randomHex(),
+ ];
+
+ $salesChannelContext = $this->createSalesChannelContextWithLoggedInCustomerAndWithNavigation();
+
+ $cacheItem = $this->createMock(CacheItemInterface::class);
+ $cacheItem->expects(static::exactly(2))->method('get')->willReturn($activePaymentMethodIds);
+ $cacheItem->expects(static::never())->method('set');
+
+ $cachePool = $this->createMock(CacheItemPoolInterface::class);
+ $cachePool
+ ->expects(static::once())
+ ->method('getItem')
+ ->with(
+ static::equalTo('payone_payment.active_payment_methods.' . $salesChannelContext->getSalesChannelId())
+ )
+ ->willReturn($cacheItem)
+ ;
+ $cachePool
+ ->expects(static::never())
+ ->method('save')
+ ;
+
+ $paymentMethodRepository = $this->createMock(SalesChannelRepository::class);
+ $paymentMethodRepository
+ ->expects(static::never())
+ ->method('searchIds')
+ ;
+
+ $salesChannelRepository = $this->createMock(EntityRepository::class);
+
+ $activePaymentMethodsLoader = new ActivePaymentMethodsLoader(
+ $cachePool,
+ $paymentMethodRepository,
+ $salesChannelRepository
+ );
+
+ $result = $activePaymentMethodsLoader->getActivePaymentMethodIds($salesChannelContext);
+
+ static::assertSame($activePaymentMethodIds, $result);
+ }
+
+ public function testItClearsCacheItems(): void
+ {
+ $salesChannelIds = [
+ Uuid::randomHex(),
+ Uuid::randomHex(),
+ ];
+
+ $salesChannelContext = $this->createSalesChannelContextWithLoggedInCustomerAndWithNavigation();
+
+ $cachePool = $this->createMock(CacheItemPoolInterface::class);
+ $cachePool
+ ->expects(static::once())
+ ->method('deleteItems')
+ ->with(
+ static::equalTo([
+ 'payone_payment.active_payment_methods.' . $salesChannelIds[0],
+ 'payone_payment.active_payment_methods.' . $salesChannelIds[1],
+ ])
+ )
+ ;
+
+ $paymentMethodRepository = $this->createMock(SalesChannelRepository::class);
+
+ $idSearchResult = $this->createMock(IdSearchResult::class);
+ $idSearchResult
+ ->expects(static::once())
+ ->method('getIds')
+ ->willReturn($salesChannelIds)
+ ;
+
+ $salesChannelRepository = $this->createMock(EntityRepository::class);
+ $salesChannelRepository
+ ->expects(static::once())
+ ->method('searchIds')
+ ->willReturn($idSearchResult)
+ ;
+
+ $activePaymentMethodsLoader = new ActivePaymentMethodsLoader(
+ $cachePool,
+ $paymentMethodRepository,
+ $salesChannelRepository
+ );
+
+ $activePaymentMethodsLoader->clearCache($salesChannelContext->getContext());
+ }
+}
diff --git a/tests/Components/RedirectHandler/RedirectHandlerTest.php b/tests/Components/RedirectHandler/RedirectHandlerTest.php
index d0cacedd4..5c4aba764 100644
--- a/tests/Components/RedirectHandler/RedirectHandlerTest.php
+++ b/tests/Components/RedirectHandler/RedirectHandlerTest.php
@@ -16,6 +16,7 @@
class RedirectHandlerTest extends TestCase
{
use KernelTestBehaviour;
+ private const APP_SECRET = 's$cretf0rt3st';
public function testItEncodesUrlWithoutDatabase(): void
{
@@ -33,7 +34,7 @@ public function testItEncodesUrlWithoutDatabase(): void
$redirectHandler = new RedirectHandler(
$connection,
$router,
- $this->getContainer()->getParameter('env.app_secret')
+ self::APP_SECRET
);
$url = $redirectHandler->encode('the-url');
@@ -52,7 +53,7 @@ public function testItEncodesUrlWithDatabase(): array
$redirectHandler = new RedirectHandler(
$connection,
$router,
- $this->getContainer()->getParameter('env.app_secret')
+ self::APP_SECRET
);
$originalUrl = 'the-url';
@@ -83,7 +84,7 @@ public function testItDecodesHashWithDatabase(array $data): void
$redirectHandler = new RedirectHandler(
$connection,
$router,
- $this->getContainer()->getParameter('env.app_secret')
+ self::APP_SECRET
);
$originalUrl = $redirectHandler->decode($data['hash']);
@@ -120,7 +121,7 @@ public function testItThrowsExceptionOnDecodingWithMissingUrl(): void
$redirectHandler = new RedirectHandler(
$connection,
$router,
- $this->getContainer()->getParameter('env.app_secret')
+ self::APP_SECRET
);
$this->expectException(\RuntimeException::class);
@@ -140,7 +141,7 @@ public function testItCleansUpOldUrls(): void
$redirectHandler = new RedirectHandler(
$connection,
$router,
- $this->getContainer()->getParameter('env.app_secret')
+ self::APP_SECRET
);
$redirectHandler->encode('the-url-1');
diff --git a/tests/EventListener/PayPalV2ExpressEventListenerTest.php b/tests/EventListener/PayPalV2ExpressEventListenerTest.php
new file mode 100644
index 000000000..56937b7a0
--- /dev/null
+++ b/tests/EventListener/PayPalV2ExpressEventListenerTest.php
@@ -0,0 +1,224 @@
+ $eventClass
+ * @param class-string
$pageClass
+ */
+ public function testItAddsExpressButtonDataExtension(string $eventClass, string $pageClass): void
+ {
+ $activePaymentMethodIds = [
+ Uuid::randomHex(),
+ PayonePaypalV2Express::UUID,
+ ];
+
+ $salesChannelContext = $this->createSalesChannelContextWithLoggedInCustomerAndWithNavigation();
+ $salesChannelContext->getCurrency()->setIsoCode('EUR');
+
+ $request = $this->getRequestWithSession([]);
+ $request->setLocale('de-DE');
+
+ $configuration = new Configuration([
+ 'transactionMode' => 'test',
+ 'paypalV2ExpressPayPalMerchantId' => 'the-merchant-id',
+ 'paypalV2ExpressShowPayLaterButton' => false,
+ ]);
+
+ $activePaymentMethodsLoader = $this->createMock(ActivePaymentMethodsLoaderInterface::class);
+ $activePaymentMethodsLoader
+ ->expects(static::once())
+ ->method('getActivePaymentMethodIds')
+ ->with(
+ static::equalTo($salesChannelContext)
+ )
+ ->willReturn($activePaymentMethodIds)
+ ;
+
+ $configReader = $this->createMock(ConfigReaderInterface::class);
+ $configReader
+ ->expects(static::once())
+ ->method('read')
+ ->with(
+ static::equalTo($salesChannelContext->getSalesChannelId())
+ )
+ ->willReturn($configuration)
+ ;
+
+ $router = $this->createMock(RouterInterface::class);
+ $logger = $this->createMock(LoggerInterface::class);
+
+ $listener = new PayPalV2ExpressEventListener(
+ $activePaymentMethodsLoader,
+ $configReader,
+ $router,
+ $logger
+ );
+
+ $page = new $pageClass();
+ $event = new $eventClass($page, $salesChannelContext, $request);
+
+ $listener->addExpressCheckoutDataToPage($event);
+
+ $extension = $page->getExtension(PayPalV2ExpressButtonData::EXTENSION_NAME);
+
+ static::assertInstanceOf(PayPalV2ExpressButtonData::class, $extension);
+ static::assertTrue($extension->isSandbox());
+ static::assertSame('EUR', $extension->getCurrency());
+ static::assertSame('de_DE', $extension->getLocale());
+ static::assertFalse($extension->isShowPayLaterButton());
+ }
+
+ public function testItNotAddsExpressButtonDataExtensionBecausePaymentMethodIsNotActive(): void
+ {
+ $activePaymentMethodIds = [
+ Uuid::randomHex(),
+ Uuid::randomHex(),
+ ];
+
+ $salesChannelContext = $this->createSalesChannelContextWithLoggedInCustomerAndWithNavigation();
+ $salesChannelContext->getCurrency()->setIsoCode('EUR');
+
+ $request = $this->getRequestWithSession([]);
+ $request->setLocale('de-DE');
+
+ $activePaymentMethodsLoader = $this->createMock(ActivePaymentMethodsLoaderInterface::class);
+ $activePaymentMethodsLoader
+ ->expects(static::once())
+ ->method('getActivePaymentMethodIds')
+ ->with(
+ static::equalTo($salesChannelContext)
+ )
+ ->willReturn($activePaymentMethodIds)
+ ;
+
+ $configReader = $this->createMock(ConfigReaderInterface::class);
+ $configReader
+ ->expects(static::never())
+ ->method('read')
+ ;
+
+ $router = $this->createMock(RouterInterface::class);
+ $logger = $this->createMock(LoggerInterface::class);
+
+ $listener = new PayPalV2ExpressEventListener(
+ $activePaymentMethodsLoader,
+ $configReader,
+ $router,
+ $logger
+ );
+
+ $page = new CheckoutCartPage();
+ $event = new CheckoutCartPageLoadedEvent($page, $salesChannelContext, $request);
+
+ $listener->addExpressCheckoutDataToPage($event);
+
+ $extension = $page->getExtension(PayPalV2ExpressButtonData::EXTENSION_NAME);
+
+ static::assertNull($extension);
+ }
+
+ public function testItNotAddsExpressButtonDataExtensionBecauseMerchantIdIsMissingInLiveMode(): void
+ {
+ $activePaymentMethodIds = [
+ Uuid::randomHex(),
+ PayonePaypalV2Express::UUID,
+ ];
+
+ $salesChannelContext = $this->createSalesChannelContextWithLoggedInCustomerAndWithNavigation();
+ $salesChannelContext->getCurrency()->setIsoCode('EUR');
+
+ $request = $this->getRequestWithSession([]);
+ $request->setLocale('de-DE');
+
+ $configuration = new Configuration([
+ 'transactionMode' => 'live',
+ 'paypalV2ExpressPayPalMerchantId' => '',
+ 'paypalV2ExpressShowPayLaterButton' => false,
+ ]);
+
+ $activePaymentMethodsLoader = $this->createMock(ActivePaymentMethodsLoaderInterface::class);
+ $activePaymentMethodsLoader
+ ->expects(static::once())
+ ->method('getActivePaymentMethodIds')
+ ->with(
+ static::equalTo($salesChannelContext)
+ )
+ ->willReturn($activePaymentMethodIds)
+ ;
+
+ $configReader = $this->createMock(ConfigReaderInterface::class);
+ $configReader
+ ->expects(static::once())
+ ->method('read')
+ ->with(
+ static::equalTo($salesChannelContext->getSalesChannelId())
+ )
+ ->willReturn($configuration)
+ ;
+
+ $router = $this->createMock(RouterInterface::class);
+
+ $logger = $this->createMock(LoggerInterface::class);
+ $logger
+ ->expects(static::once())
+ ->method('warning')
+ ;
+
+ $listener = new PayPalV2ExpressEventListener(
+ $activePaymentMethodsLoader,
+ $configReader,
+ $router,
+ $logger
+ );
+
+ $page = new CheckoutCartPage();
+ $event = new CheckoutCartPageLoadedEvent($page, $salesChannelContext, $request);
+
+ $listener->addExpressCheckoutDataToPage($event);
+
+ $extension = $page->getExtension(PayPalV2ExpressButtonData::EXTENSION_NAME);
+
+ static::assertNull($extension);
+ }
+
+ protected static function subscribedEventClasses(): array
+ {
+ return [
+ [CheckoutCartPageLoadedEvent::class, CheckoutCartPage::class],
+ [CheckoutRegisterPageLoadedEvent::class, CheckoutRegisterPage::class],
+ [OffcanvasCartPageLoadedEvent::class, OffcanvasCartPage::class],
+ ];
+ }
+}
diff --git a/tests/Functional/Payment/PaypalV2Express/CreateCheckoutSessionRequestParametersTest.php b/tests/Functional/Payment/PaypalV2Express/CreateCheckoutSessionRequestParametersTest.php
new file mode 100644
index 000000000..1fda03d2c
--- /dev/null
+++ b/tests/Functional/Payment/PaypalV2Express/CreateCheckoutSessionRequestParametersTest.php
@@ -0,0 +1,49 @@
+getContainer()->get(RequestParameterFactory::class);
+
+ $context = $this->createSalesChannelContextWithLoggedInCustomerAndWithNavigation();
+ // cart got stored automatically in the CartService, which is reused in the plugin
+ $this->createCartWithProduct($context);
+
+ $requestParams = $factory->getRequestParameter(new CreateExpressCheckoutSessionStruct(
+ $context,
+ PayonePaypalV2ExpressPaymentHandler::class
+ ));
+
+ static::assertArrayHasKey('clearingtype', $requestParams);
+ static::assertEquals('wlt', $requestParams['clearingtype']);
+ static::assertArrayHasKey('wallettype', $requestParams);
+ static::assertEquals('PAL', $requestParams['wallettype']);
+ static::assertArrayHasKey('amount', $requestParams);
+ static::assertEquals(Constants::DEFAULT_PRODUCT_PRICE * 100, $requestParams['amount']);
+ static::assertArrayHasKey('currency', $requestParams);
+ static::assertArrayHasKey('add_paydata[action]', $requestParams);
+ static::assertEquals('setexpresscheckout', $requestParams['add_paydata[action]']);
+ static::assertArrayHasKey('successurl', $requestParams);
+ static::assertArrayHasKey('backurl', $requestParams);
+ static::assertArrayHasKey('errorurl', $requestParams);
+ }
+}
diff --git a/tests/Functional/Payment/PaypalV2Express/GetCheckoutSessionRequestParametersTest.php b/tests/Functional/Payment/PaypalV2Express/GetCheckoutSessionRequestParametersTest.php
new file mode 100644
index 000000000..d58c95c13
--- /dev/null
+++ b/tests/Functional/Payment/PaypalV2Express/GetCheckoutSessionRequestParametersTest.php
@@ -0,0 +1,39 @@
+getContainer()->get(RequestParameterFactory::class);
+
+ $context = $this->createSalesChannelContext();
+
+ $requestParams = $factory->getRequestParameter(new GetCheckoutSessionStruct(
+ $context,
+ 'woi-123456',
+ PayonePaypalV2ExpressPaymentHandler::class
+ ));
+
+ static::assertArrayHasKey('clearingtype', $requestParams);
+ static::assertEquals('wlt', $requestParams['clearingtype']);
+ static::assertArrayHasKey('wallettype', $requestParams);
+ static::assertEquals('PAL', $requestParams['wallettype']);
+ static::assertArrayHasKey('add_paydata[action]', $requestParams);
+ static::assertEquals('getexpresscheckoutdetails', $requestParams['add_paydata[action]']);
+ static::assertArrayHasKey('workorderid', $requestParams);
+ static::assertEquals('woi-123456', $requestParams['workorderid']);
+ }
+}
diff --git a/tests/PaymentHandler/PayonePaypalV2PaymentHandlerTest.php b/tests/PaymentHandler/PayonePaypalV2PaymentHandlerTest.php
new file mode 100644
index 000000000..ce898612e
--- /dev/null
+++ b/tests/PaymentHandler/PayonePaypalV2PaymentHandlerTest.php
@@ -0,0 +1,107 @@
+createSalesChannelContextWithLoggedInCustomerAndWithNavigation();
+ $dataBag = new RequestDataBag();
+
+ $client = $this->createMock(PayoneClientInterface::class);
+ $client->expects(static::once())->method('request')->willReturn(
+ [
+ 'status' => 'test-status',
+ 'txid' => '',
+ 'userid' => '',
+ ]
+ );
+
+ $requestFactory = $this->createMock(RequestParameterFactory::class);
+ $requestFactory->expects(static::once())->method('getRequestParameter')->willReturn(
+ [
+ 'request' => '',
+ 'successurl' => 'test-url',
+ ]
+ );
+
+ $paymentHandler = $this->getPaymentHandler($client, $dataBag, $requestFactory);
+ $paymentTransaction = $this->getPaymentTransaction(
+ $this->getRandomOrder($salesChannelContext),
+ PayonePaypalV2PaymentHandler::class
+ );
+
+ $response = $this->performPayment($paymentHandler, $paymentTransaction, $dataBag, $salesChannelContext);
+
+ static::assertSame('test-url', $response->getTargetUrl());
+ }
+
+ private function getPaymentHandler(
+ PayoneClientInterface $client,
+ RequestDataBag $dataBag,
+ RequestParameterFactory $requestFactory
+ ): PayonePaypalV2PaymentHandler {
+ $translator = $this->getContainer()->get('translator');
+ $configReader = new ConfigReaderMock([
+ 'paypalV2AuthorizationMethod' => 'authorization',
+ ]);
+
+ $orderActionLogDataHandler = $this->createMock(OrderActionLogDataHandlerInterface::class);
+ $orderActionLogDataHandler->expects(static::once())->method('createOrderActionLog');
+
+ return new PayonePaypalV2PaymentHandler(
+ $configReader,
+ $this->createMock(EntityRepository::class),
+ $this->getRequestStack($dataBag),
+ $client,
+ $translator,
+ new TransactionDataHandler($this->createMock(EntityRepository::class), new CurrencyPrecision()),
+ $orderActionLogDataHandler,
+ new PaymentStateHandler($translator),
+ $requestFactory,
+ $this->createMock(CustomerDataPersistor::class)
+ );
+ }
+
+ private function performPayment(
+ PayonePaypalV2PaymentHandler $paymentHandler,
+ PaymentTransaction $paymentTransaction,
+ RequestDataBag $dataBag,
+ SalesChannelContext $salesChannelContext
+ ): RedirectResponse {
+ return $paymentHandler->pay(
+ new AsyncPaymentTransactionStruct(
+ $paymentTransaction->getOrderTransaction(),
+ $paymentTransaction->getOrder(),
+ ''
+ ),
+ $dataBag,
+ $salesChannelContext
+ );
+ }
+}
diff --git a/tests/Payone/RequestParameter/Builder/PaypalV2/AuthorizeRequestParameterBuilderTest.php b/tests/Payone/RequestParameter/Builder/PaypalV2/AuthorizeRequestParameterBuilderTest.php
new file mode 100644
index 000000000..b5a46807d
--- /dev/null
+++ b/tests/Payone/RequestParameter/Builder/PaypalV2/AuthorizeRequestParameterBuilderTest.php
@@ -0,0 +1,56 @@
+getPaymentTransactionStruct(
+ new RequestDataBag([]),
+ $this->getValidPaymentHandler(),
+ $this->getValidRequestAction()
+ );
+
+ $builder = $this->getContainer()->get($this->getParameterBuilder());
+ $parameters = $builder->getRequestParameter($struct);
+
+ Assert::assertArraySubset(
+ [
+ 'clearingtype' => AbstractRequestParameterBuilder::CLEARING_TYPE_WALLET,
+ 'request' => $this->getValidRequestAction(),
+ 'wallettype' => 'PAL',
+ ],
+ $parameters
+ );
+ }
+
+ protected function getParameterBuilder(): string
+ {
+ return AuthorizeRequestParameterBuilder::class;
+ }
+
+ protected function getValidPaymentHandler(): string
+ {
+ return PayonePaypalV2PaymentHandler::class;
+ }
+
+ protected function getValidRequestAction(): string
+ {
+ return AbstractRequestParameterBuilder::REQUEST_ACTION_AUTHORIZE;
+ }
+}